很久没有写代码了,最近简单的看了一下disk相关的东西,写了段代码share一下。
先用livekd看一下Disk.sys DriverObject的一些信息:
kd> !drvobj /driver/disk
Driver object (89885a08) is for:
/Driver/Disk
Driver Extension List: (id , addr)
(f763e3be 898858f0)
Device Object list:
8985ec68 8987fc68 8989ac68 89818ab8
然后看下这四个DeviceObject,分区数和硬盘数量不同,Device的数量也不同,我的机器只有三个分区,一块硬盘
kd> !devobj 8985ec68
Device object (8985ec68) is for:
DP(3)0×700a41e00-0xba11e0200+3 /Driver/Disk DriverObject 89885a08
Current Irp 00000000 RefCount 0 Type 00000007 Flags 000020d0
Vpb 89861b38 Dacl e1555b1c DevExt 8985ed20 DevObjExt 8985efd0 Dope 8989bad8
ExtensionFlags (0000000000)
Device queue is not busy.
kd> !devobj 8987fc68
Device object (8987fc68) is for:
DP(2)0×2002f3e00-0×500746200+2 /Driver/Disk DriverObject 89885a08
Current Irp 00000000 RefCount 0 Type 00000007 Flags 000020d0
Vpb 89862d78 Dacl e1555b1c DevExt 8987fd20 DevObjExt 8987ffd0 Dope 899260e8
ExtensionFlags (0000000000)
Device queue is not busy.
kd> !devobj 8989ac68
Device object (8989ac68) is for:
DP(1)0×7e00-0×2002e4200+1 /Driver/Disk DriverObject 89885a08
Current Irp 00000000 RefCount 0 Type 00000007 Flags 000000d0
Vpb 89886b38 Dacl e1555b1c DevExt 8989ad20 DevObjExt 8989afd0 Dope 899021a8
ExtensionFlags (0000000000)
Device queue is not busy.
kd> !devobj 89818ab8
Device object (89818ab8) is for:
DR0 /Driver/Disk DriverObject 89885a08
Current Irp 00000000 RefCount 0 Type 00000007 Flags 00000050
Vpb 89880008 Dacl e1555b1c DevExt 89818b70 DevObjExt 89818fd0 Dope 8985fbc8
ExtensionFlags (0000000000)
AttachedDevice (Upper) 89884a18*** ERROR: Module load completed but symbols could not be loaded for Apsx86.sys
/Driver/Shockprf
AttachedTo (Lower) 8989a9e8 /Driver/ACPI
Device queue is not busy.
ok,可以用下面的代码取出想要的DeviceObject
PDEVICE_OBJECT
GetDiskDeviceObject(
VOID
)
{
NTSTATUS status = STATUS_SUCCESS;
UNICODE_STRING usDiskName;
PDRIVER_OBJECT pDiskDrvObj = NULL;
PDEVICE_OBJECT pDiskDevObj = NULL;
DWORD dwLength = 0;
POBJECT_NAME_INFORMATION poni = NULL;
poni = poni;
RtlInitUnicodeString(&usDiskName, L"//Driver//Disk");
status = ObReferenceObjectByName(
&usDiskName,
0x40,
0,
0,
*IoDriverObjectType,
0,
NULL,
&pDiskDrvObj
);
if(!NT_SUCCESS(status))
{
KdPrint(("[dsv] ObReferenceObjectByName() failed./n"));
return NULL;
}
pDiskDevObj = pDiskDrvObj->DeviceObject;
if(pDiskDevObj == NULL)
{
KdPrint(("[dsv] Disk DeviceObject is NULL./n"));
ObDereferenceObject(pDiskDrvObj);
return NULL;
}
while(pDiskDevObj != NULL)
{
if(pDiskDevObj->DeviceType != FILE_DEVICE_DISK)
{
KdPrint(("[dsv] DeviceObject is NOT for Disk./n"));
pDiskDevObj = pDiskDevObj->NextDevice;
continue;
}
if( !(pDiskDevObj->Flags & DO_DEVICE_HAS_NAME) )
{
KdPrint(("[dsv] DeviceObject DO NOT has a name./n"));
pDiskDevObj = pDiskDevObj->NextDevice;
continue;
}
status = ObQueryNameString(pDiskDevObj, poni, 0, &dwLength);
if(STATUS_INFO_LENGTH_MISMATCH == status)
{
poni = (POBJECT_NAME_INFORMATION) np_malloc(dwLength);
if(NULL == poni)
{
KdPrint(("[dsv] np_malloc() failed./n"));
ObDereferenceObject(pDiskDrvObj);
return NULL;
}
status = ObQueryNameString(pDiskDevObj, poni, dwLength, &dwLength);
if(!NT_SUCCESS(status))
{
KdPrint(("[dsv] ObQueryNameString with length: %d failed./n", dwLength));
free(poni);
ObDereferenceObject(pDiskDrvObj);
return NULL;
}
}
else if( !NT_SUCCESS(status) )
{
KdPrint(("[dsv] ObQueryNameString() failed./n"));
ObDereferenceObject(pDiskDrvObj);
return NULL;
}
else
{
; // Nothing.
}
KdPrint(("[dsv] %S/n", poni->Name.Buffer));
//
// TODO: Add code here.
//
free(poni);
if(pDiskDevObj->NextDevice == NULL) break;
pDiskDevObj = pDiskDevObj->NextDevice;
}
ObDereferenceObject(pDiskDrvObj);
return pDiskDevObj;
}
还有两个例程的声明,如果装了ifs就不需要声明ObQueryNameString()了,写在下面(看我服务多周到^^)
NTSTATUS
ObQueryNameString(
IN PVOID Object,
OUT POBJECT_NAME_INFORMATION ObjectNameInfo,
IN ULONG Length,
OUT PULONG ReturnLength
);
ObReferenceObjectByName(
IN PUNICODE_STRING ObjectPath,
IN ULONG Attributes,
IN PACCESS_STATE PassedAccessState OPTIONAL,
IN ACCESS_MASK DesiredAccess OPTIONAL,
IN POBJECT_TYPE ObjectType,
IN KPROCESSOR_MODE AccessMode,
IN OUT PVOID ParseContext OPTIONAL,
OUT PVOID *ObjectPtr
);