前一篇Pnp管理器(1)提到了总线上设备变化时,将产生Pnp消息并在Pnp管理器个组件间流动。消息传递的最终目的是通知某个组件加载驱动。本文看一下Pnp管理器收到消息后加载驱动的流程。
当PnpEventThread函数从等待阻塞中返回,判断如果是添加设备则创建一个DeviceInstallParams* Params变量
typedef struct { #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED SLIST_ENTRY ListEntry; #else LIST_ENTRY ListEntry; #endif WCHAR DeviceIds[1]; } DeviceInstallParams;
前面设备树结构变更时,获得了设备的ID,现在将这个ID填入Params变量,并加入DeviceInstallListHead链表,然后通知Pnp管理器的DeviceInstallThread内核线程为新设备安装驱动。和PnpEventThread一样DeviceInstallThread也是IO管理器初始化时创建的线程,周而复始的等待事件hDeviceInstallListNotEmpty被触发。
static VOID CALLBACK ServiceMain(DWORD argc, LPTSTR *argv) { ... hThread = CreateThread(NULL, 0, PnpEventThread, NULL, 0, &dwThreadId); if (hThread != NULL) CloseHandle(hThread); hThread = CreateThread(NULL, 0, DeviceInstallThread, NULL, 0, &dwThreadId); ... }
当DeviceInstallThread线程从阻塞中返回,从DeviceInstallListHead队列中获得PnpEventThread线程中加入的DeviceInstallParams项,然后调用InstallDevice开始安装驱动
static DWORD WINAPI DeviceInstallThread(LPVOID lpParameter) { while (TRUE) { if ((BOOL)IsListEmpty(&DeviceInstallListHead)) ListEntry = NULL; else ListEntry = RemoveHeadList(&DeviceInstallListHead); //从DeviceInstallListHead队列中获得PnpEventThread线程中加入的DeviceInstallParams项 //ListEntry 收到通知时从阻塞中返回将进入到else分支,否则进入if分支 //继续等待 if (ListEntry == NULL) { SetEvent(hNoPendingInstalls); WaitForSingleObject(hDeviceInstallListNotEmpty, INFINITE); } else { ResetEvent(hNoPendingInstalls); Params = CONTAINING_RECORD(ListEntry, DeviceInstallParams, ListEntry); InstallDevice(Params->DeviceIds, setupActive); } } }
ReactOS0.33中DevInstall的实现比较简单:从newdev.dll中搜索DevInstallW函数,然后向DevInstallW输入DevID就算完成驱动的安装了。看这个函数的接口形式有点像windows的UpdateDriverForPlugAndPlayDevices。后面有时间我就写篇关于用UpdateDriverForPlugAndPlayDevices驱动安装的博文
时间: 2024-10-27 19:12:30