WDM 驱动中创建的设备链表
2022-02-23
172
0
一个驱动加载后,可以根据需要创建多个设备,这些设备会以链表的形式连接起来,并且第一个设备的指针存放在DRIVER_OJECT的DeviceObject成员中。后续的设备会依次按DEVICE_OJBECT的NextDevice进行链表连接,直到最后一个为NULL.
3: kd> dt _DEVICE_OBJECT
usbip_vhci!_DEVICE_OBJECT
+0x000 Type : Int2B
+0x002 Size : Uint2B
+0x004 ReferenceCount : Int4B
+0x008 DriverObject : Ptr64 _DRIVER_OBJECT //驱动对象指针
+0x010 NextDevice : Ptr64 _DEVICE_OBJECT //下一个同级设备
+0x018 AttachedDevice : Ptr64 _DEVICE_OBJECT //下一个子级设备
+0x020 CurrentIrp : Ptr64 _IRP
+0x028 Timer : Ptr64 _IO_TIMER
+0x030 Flags : Uint4B
+0x034 Characteristics : Uint4B
+0x038 Vpb : Ptr64 _VPB
+0x040 DeviceExtension : Ptr64 Void
+0x048 DeviceType : Uint4B
+0x04c StackSize : Char
+0x050 Queue : <unnamed-tag>
+0x098 AlignmentRequirement : Uint4B
+0x0a0 DeviceQueue : _KDEVICE_QUEUE
+0x0c8 Dpc : _KDPC
+0x108 ActiveThreadCount : Uint4B
+0x110 SecurityDescriptor : Ptr64 Void
+0x118 DeviceLock : _KEVENT
+0x130 SectorSize : Uint2B
+0x132 Spare1 : Uint2B
+0x138 DeviceObjectExtension : Ptr64 _DEVOBJ_EXTENSION
+0x140 Reserved : Ptr64 Void
在以前的NT驱动卸载时,会在其卸载回调函数中会枚举该驱动中所有的DeviceOjbect,然后再删除。当然如果该DRIVER_OJBECT中创建了一个DEVICE_OBJECT,那DROVER_OJBECT中的DeviceObject就是该设备。
VOID DriverUnload(PDRIVER_OBJECT pDriverObject)
{
PDEVICE_OBJECT pNextObj = pDriverObject->DeviceObject;
while (pNextObj != NULL)
{
PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pNextObj->DeviceExtension;
//删除符号链接
UNICODE_STRING pLinkName = pDevExt->wstrSymbolicLinkName;
KdPrint(("%wZ\n",pLinkName));
IoDeleteSymbolicLink(&pLinkName);
pNextObj = pNextObj->NextDevice;
IoDeleteDevice( pDevExt->pDeviceObject );
}
}