NTSTATUS
IoGetDeviceObjectPointer(
IN PUNICODE_STRING ObjectName,//设备名
IN ACCESS_MASK DesiredAccess,//期望访问权限
OUT PFILE_OBJECT *FileObject,//OUT文件对象,在驱动卸载前必须把这个文件对象解引用,可以看源码
OUT PDEVICE_OBJECT *DeviceObject//OUT设备对象
);
源码如下:
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(); //must be running at IRQL = PASSIVE_LEVEL
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 ))
{
// 文件句柄映射到文件对象
status = ObReferenceObjectByHandle( fileHandle,
0,
IoFileObjectType,
KernelMode,
(PVOID *) &fileObject,
NULL );
if (NT_SUCCESS( status ))
{
*FileObject = fileObject;
// oGetRelatedDeviceObject 获得文件对象中设备对象所在设备栈栈顶的设备对象
*DeviceObject = IoGetRelatedDeviceObject( fileObject );
}
(VOID) ZwClose( fileHandle );
}
return status;
}
可以看出几点
1.内部调用了ObReferenceObjectByHandle,所以外部需要ObDereferenceObject(文件对象)
2.DeviceObject返回的是返回的是【Attach】在这个名字对应【设备对象】所在【栈】的【栈顶设备对象指针】,如果没有Attach的设备,就是这个名字对应【设备对象】,可以通过IoGetRelatedDeviceObject看到
3.FileObject->DeviceObject 返回的是这个名字对应【设备对象】