USBIP 驱动入口DriverEntry和vhci_driverUnload函数
2022-02-23
593
0
无论该驱动被安装几次,DriverEntry和卸载函数只执行一次。
DriverEntry
Windows驱动和应用层一样,也有个入口函数,只是这个名字叫做DriverEntry。在DriverEntry中应实现的是该驱动各个IRP类类型的回调函数。
PAGEABLE NTSTATUS
DriverEntry(__in PDRIVER_OBJECT drvobj, __in PUNICODE_STRING RegistryPath)
{
KdBreakPoint();
DBGI(DBG_GENERAL, "DriverEntry: Enter\n");
ExInitializeNPagedLookasideList(&g_lookaside, NULL,NULL, 0, sizeof(struct urb_req), 'USBV', 0);
// Save the RegistryPath for WMI.
Globals.RegistryPath.MaximumLength = RegistryPath->Length + sizeof(UNICODE_NULL);
Globals.RegistryPath.Length = RegistryPath->Length;
Globals.RegistryPath.Buffer = ExAllocatePoolWithTag(PagedPool, Globals.RegistryPath.MaximumLength, USBIP_VHCI_POOL_TAG);
if (!Globals.RegistryPath.Buffer) {
ExDeleteNPagedLookasideList(&g_lookaside);
return STATUS_INSUFFICIENT_RESOURCES;
}
DBGI(DBG_GENERAL, "RegistryPath %p\r\n", RegistryPath);
RtlCopyUnicodeString(&Globals.RegistryPath, RegistryPath);
// Set entry points into the driver
drvobj->MajorFunction[IRP_MJ_CREATE] = vhci_create;
drvobj->MajorFunction[IRP_MJ_CLEANUP] = vhci_cleanup;
drvobj->MajorFunction[IRP_MJ_CLOSE] = vhci_close;
drvobj->MajorFunction[IRP_MJ_READ] = vhci_read;
drvobj->MajorFunction[IRP_MJ_WRITE] = vhci_write;
drvobj->MajorFunction[IRP_MJ_PNP] = vhci_pnp;
drvobj->MajorFunction[IRP_MJ_POWER] = vhci_power;
drvobj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = vhci_ioctl;
drvobj->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = vhci_internal_ioctl;
drvobj->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = vhci_system_control;
drvobj->DriverUnload = vhci_driverUnload;
drvobj->DriverExtension->AddDevice = vhci_add_device;
DBGI(DBG_GENERAL, "DriverEntry: Leave\n");
return STATUS_SUCCESS;
}
DriverEntry的入口函数有两个,分别为该驱动的对象指针,另一个为该驱动的服务注册表路径。如这里的注册表路径为:
\REGISTRY\MACHINE\SYSTEM\ControlSet001\Services\usbip_vhci
而驱动对象指针,可以通过windbg查看其对应的结构体
2: kd> dt _DRIVER_OBJECT 0xffffbc88`3db017d0
usbip_vhci!_DRIVER_OBJECT
+0x000 Type : 0n4
+0x002 Size : 0n336
+0x008 DeviceObject : (null)
+0x010 Flags : 2
+0x018 DriverStart : 0xfffff807`b5c30000 Void
+0x020 DriverSize : 0x1f000
+0x028 DriverSection : 0xffffbc88`3d0afb40 Void
+0x030 DriverExtension : 0xffffbc88`3db01920 _DRIVER_EXTENSION
+0x038 DriverName : _UNICODE_STRING "\Driver\usbip_vhci"
+0x048 HardwareDatabase : 0xfffff803`655c2eb8 _UNICODE_STRING "\REGISTRY\MACHINE\HARDWARE\DESCRIPTION\SYSTEM"
+0x050 FastIoDispatch : (null)
+0x058 DriverInit : 0xfffff807`b5c38050 long usbip_vhci!FxDriverEntry+0
+0x060 DriverStartIo : (null)
+0x068 DriverUnload : (null)
+0x070 MajorFunction : [28] 0xfffff803`64ebf6b4 long nt!KeInsertQueue+0
2: kd> dt _DRIVER_EXTENSION 0xffffbc88`3db01920
usbip_vhci!_DRIVER_EXTENSION
+0x000 DriverObject : 0xffffbc88`3db017d0 _DRIVER_OBJECT
+0x008 AddDevice : (null)
+0x010 Count : 0
+0x018 ServiceKeyName : _UNICODE_STRING "usbip_vhci"
可以看到其成员变量MajorFunction是一个数组,用于指示各IRP类型的回调指针。
当然这里在入口函数中将注册表存在全局变量Globals中。
typedef struct _GLOBALS
{
// Path to the driver's Services Key in the registry
UNICODE_STRING RegistryPath;
} GLOBALS;
GLOBALS Globals;
vhci_driverUnload
该函数比较简单,其功能和DriverEntry对应,用于释放DriverEntry中申请的资源,这里为注册表存储的路径
static PAGEABLE VOID
vhci_driverUnload(__in PDRIVER_OBJECT drvobj)
{
UNREFERENCED_PARAMETER(drvobj);
PAGED_CODE();
DBGI(DBG_GENERAL, "Unload\n");
ExDeleteNPagedLookasideList(&g_lookaside);
//
// All the device objects should be gone.
//
ASSERT(NULL == drvobj->DeviceObject);
//
// Here we free all the resources allocated in the DriverEntry
//
if (Globals.RegistryPath.Buffer)
ExFreePool(Globals.RegistryPath.Buffer);
}
NPAGED_LOOKASIDE_LIST
在DriverEntry和卸载函数中,可以看到也有一个变量NPAGED_LOOKASIDE_LIST,用于二级内存管理,适用于频繁的申请和释放内存。由于需要处理各种URB,故这里使用了NPAGED_LOOKASIDE_LIST
NPAGED_LOOKASIDE_LIST g_lookaside;
HID人机交互QQ群:564808376
UAC音频QQ群:218581009
UVC相机QQ群:331552032
BOT&UASP大容量存储QQ群:258159197
STC-USB单片机QQ群:315457461
USB技术交流QQ群2:580684376
USB技术交流QQ群:952873936