959 views
首页 > 内核编程, 技术心得 > 关于 IoGetDeviceObjectPointer

关于 IoGetDeviceObjectPointer

2010年5月19日

先看 IoGetDeviceObjectPointer() 的内部实现:

  1. 用 ZwOpenFile() 打开设备文件的 handle
  2. 用 ObReferenceObjectByHandle() 来得到 file object
  3. 用 IoGetRelatedDeviceObject() 来得到 device object
  4. 用 ZwClose() 来关闭这个 handle

WRK 1.2 源代码如下:

NTSTATUS
IoGetDeviceObjectPointer(
    IN PUNICODE_STRING ObjectName,
    IN ACCESS_MASK DesiredAccess,
    OUT PFILE_OBJECT *FileObject,
    OUT PDEVICE_OBJECT *DeviceObject
    )
{
    PFILE_OBJECT fileObject;
    OBJECT_ATTRIBUTES objectAttributes;
    HANDLE fileHandle;
    IO_STATUS_BLOCK ioStatus;
    NTSTATUS status;

    PAGED_CODE();

    //
    // Initialize the object attributes to open the device.
    //

    InitializeObjectAttributes( &objectAttributes,
                                ObjectName,
                                OBJ_KERNEL_HANDLE,
                                (HANDLE) NULL,
                                (PSECURITY_DESCRIPTOR) NULL );

    status = ZwOpenFile( &fileHandle,
                         DesiredAccess,
                         &objectAttributes,
                         &ioStatus,
                         0,
                         FILE_NON_DIRECTORY_FILE );

    if (NT_SUCCESS( status )) {

        //
        // The open operation was successful.  Dereference the file handle
        // and obtain a pointer to the device object for the handle.
        //

        status = ObReferenceObjectByHandle( fileHandle,
                                            0,
                                            IoFileObjectType,
                                            KernelMode,
                                            (PVOID *) &fileObject,
                                            NULL );
        if (NT_SUCCESS( status )) {

            *FileObject = fileObject;

            //
            // Get a pointer to the device object for this file.
            //
            *DeviceObject = IoGetRelatedDeviceObject( fileObject );
        }

        (VOID) ZwClose( fileHandle );
    }

    return status;
}

关于 IoGetRelatedDeviceObject, MSDN 上如是说:
IoGetRelatedDeviceObject

Given a file object, the IoGetRelatedDeviceObject routine returns a pointer to the corresponding device object.

Syntax

PDEVICE_OBJECT IoGetRelatedDeviceObject(
  __in  PFILE_OBJECT FileObject
);

Parameters

FileObject [in]
Pointer to the file object.

Return Value

IoGetRelatedDeviceObject returns a pointer to the device object.

Remarks

When called on a file object that represents the underlying storage device, IoGetRelatedDeviceObject returns the highest-level device object in the storage device stack. To obtain the highest-level device object in the file system driver stack, drivers must call IoGetRelatedDeviceObject on a file object that represents the file system’s driver stack, and the file system must currently be mounted. (Otherwise, the storage device stack is traversed instead of the file system stack.)

To ensure that the file system is mounted on the storage device, the driver must have specified an appropriate access mask, such as FILE_READ_DATA or FILE_WRITE_ATTRIBUTES, when opening the file or device represented by the file object. Specifying FILE_READ_ATTRIBUTES does not cause the file system to be mounted.

The caller must be running at IRQL <= DISPATCH_LEVEL. Usually, callers of this routine are running at IRQL = PASSIVE_LEVEL.

因此, 在使用 IoGetDeviceObjectPointer 函数时后, FileObject 参数用完后必须调用 ObDereferenceObject 解除引用. 而 DeviceObject 不必管它, 不能画蛇添足.

延伸阅读:
【原创】谈谈对IoGetDeviceObjectPointer的理解

内核编程, 技术心得 ,

  1. 目前还没有任何评论.
  1. 目前还没有任何 trackbacks 和 pingbacks.