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 返回的是这个名字对应【设备对象】