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()

然后返回获得的设备对象

你可能感兴趣的:(object)