国内最全IT社区平台 联系我们 | 收藏本站
华晨云阿里云优惠2
您当前位置:首页 > php框架 > 框架设计 > Pnp管理器(2)

Pnp管理器(2)

来源:程序员人生   发布时间:2016-07-15 09:31:50 阅读次数:3567次

    前1篇Pnp管理器(1)提到了总线上装备变化时,将产生Pnp消息并在Pnp管理器个组件间活动。消息传递的终究目的是通知某个组件加载驱动。本文看1下Pnp管理器收到消息后加载驱动的流程。

    当PnpEventThread函数从等待阻塞中返回,判断如果是添加装备则创建1个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内核线程为新装备安装驱动。和PnpEventThread1样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驱动安装的博文

生活不易,码农辛苦
如果您觉得本网站对您的学习有所帮助,可以手机扫描二维码进行捐赠
程序员人生
------分隔线----------------------------
分享到:
------分隔线----------------------------
关闭
程序员人生