IoGetRelatedDeviceObject学习

PDEVICE_OBJECT
IoGetRelatedDeviceObject(
    IN PFILE_OBJECT FileObject
    )

/*++

Routine Description:

    This routine returns a pointer to the actual device object than an I/O
    Request Packet (IRP) should be given to based on the specified file
    object.

    N.B. - Callers of this function must ensure no device object is
    attaching or detaching from this stack for the duration of this call.
    This is because the database lock is *not* held!

Arguments:

    FileObject - Pointer to the file object representing the open file.

Return Value:

    The return value is a pointer to the device object for the driver to
    whom the request is to be given.

--*/

{
    PDEVICE_OBJECT deviceObject;

    //
    // If the file object was taken out against the mounted file system, it
    // will have a Vpb. Traverse it to get to the DeviceObject. Note that in
    // this case we should never follow FileObject->DeviceObject, as that
    // mapping may be invalid after a forced dismount.
    //

    if (FileObject->Vpb != NULL && FileObject->Vpb->DeviceObject != NULL) {

        ASSERT(!(FileObject->Flags & FO_DIRECT_DEVICE_OPEN));
        deviceObject = FileObject->Vpb->DeviceObject;


        //
        // If a driver opened a disk device using direct device open and
        // later on it uses IoGetRelatedTargetDeviceObject to find the
        // device object it wants to send an IRP then it should not get the
        // filesystem device object. This is so that if the device object is in the
        // process of being mounted then vpb is not stable.
        //

    } else if (!(FileObject->Flags & FO_DIRECT_DEVICE_OPEN) &&
               FileObject->DeviceObject->Vpb != NULL &&
               FileObject->DeviceObject->Vpb->DeviceObject != NULL) {

            deviceObject = FileObject->DeviceObject->Vpb->DeviceObject;

    //
    // This is a direct open against the device stack (and there is no mounted
    // file system to strain the IRPs through).
    //

    } else {

        deviceObject = FileObject->DeviceObject;
    }

    ASSERT( deviceObject != NULL );

    //
    // Check to see whether or not the device has any associated devices.
    // If so, return the highest level device; otherwise, return a pointer
    // to the device object itself.
    //

    if (deviceObject->AttachedDevice != NULL) {
        if (FileObject->Flags & FO_FILE_OBJECT_HAS_EXTENSION) {

            PIOP_FILE_OBJECT_EXTENSION  fileObjectExtension =
                (PIOP_FILE_OBJECT_EXTENSION)(FileObject + 1);

            ASSERT(!(FileObject->Flags & FO_DIRECT_DEVICE_OPEN));

            if (fileObjectExtension->TopDeviceObjectHint != NULL &&
                IopVerifyDeviceObjectOnStack(deviceObject, fileObjectExtension->TopDeviceObjectHint)) {
                return fileObjectExtension->TopDeviceObjectHint;
            }
        }
        deviceObject = IoGetAttachedDevice( deviceObject );
    }

    return deviceObject;
}

 

 

这个也是网上很普及的东西了。传入开启设备或者文件产生的文件对象 获得文件对象对应的设备所在的设备堆栈的最顶层设备。

根据 FileObject->Vpb != NULL && FileObject->Vpb->DeviceObject != NULL
(!(FileObject->Flags & FO_DIRECT_DEVICE_OPEN
来判断设备对象的获取方式。
FILE_DEVICE_DISK等磁盘设备类型,如果卷设备挂载完成,则fileobject->vpb是存在的,那么获取到fileobject->vpb->deviceobject,。
如果卷设备挂载进行中,那么fileobject->vpb可能不存在,返回fileobject->devieobject->vpb->deviceobject。


对于非磁盘设备等设备类型 上述两种条件是无法满足的 函数获取文件对象结构中的设备对象。

 

 

然后通过不断轮询设备的AttachedDevice   直到为NULL 获取设备堆栈中最顶层设备(IoGetAttachedDevice)

获取文件对象的fileObjectExtension 
验证这个设备
fileObjectExtension->TopDeviceObjectHint != NULL &&
  IopVerifyDeviceObjectOnStack()

然后返回获得的设备对象

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值