USBIP 驱动入口DriverEntry和vhci_driverUnload函数
			 2022-02-23
			  本文链接为:http://www.usbzh.com/article/detail-806.html ,欢迎转载,转载请附上本文链接。
	
			
			
			
			
		
			无论该驱动被安装几次,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;
			
			本文链接为:http://www.usbzh.com/article/detail-806.html ,欢迎转载,转载请附上本文链接。
HID人机交互QQ群:564808376   
UAC音频QQ群:218581009   
UVC相机QQ群:331552032   
BOT&UASP大容量存储QQ群:258159197   
STC-USB单片机QQ群:315457461   
USB技术交流QQ群2:580684376   
USB技术交流QQ群:952873936    
		
			USBIP解读及源码分析
			




