Pnp管理器(2)

前一篇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

Pnp管理器(2)的相关文章

PNP管理器简析--基于ReactOS0.33

CSDN上转悠了一圈发现关于PNP管理的文章不多.那就由我献个丑,记录自己对PNP管理器的看法. pnp管理器被描写叙述为向内核和应用程序提供关于设备拔插的通知,凭感觉,pnp管理器应该是个线程函数等待设备通知.搜索ReactOS发现有这么个函数符合这个功能: static DWORD WINAPI PnpEventThread(LPVOID lpParameter) {     PPLUGPLAY_EVENT_BLOCK PnpEvent; ... PnpEvent = HeapAlloc(G

MQ队列管理器搭建(一)

多应用单MQ使用场景 如上图所示,MQ独立安装,或者与其中一个应用同处一机.Application1与Application2要进行通信,但因为跨系统,所以引入中间件来实现需求. Application1需要连接MQ,并将消息放入队列Queue中,Application2同样连接MQ,监听在Queue队列上,一旦发现有消息进入则取出该消息进行处理. 下面将给出创建队列管理器和队列的示例: 定义队列管理器名称为Qm1,本地队列名称为Queue,服务器连接通道CHAN_SERVER_CON,监听端口

Keeweb-Linux的密码管理器

如今,我们依赖于越来越多的线上服务.我们每注册一个线上服务,就要设置一个密码:如此,我们就不得不记住数以百计的密码.这样对于每个人来说,都很容易忘记密码.那么,下面兄弟连(www.lampbrother.net )将在本文中为大家介绍 Keeweb,Keeweb是一款 Linux 下的密码管理器,可以为你离线或在线地安全存储所有的密码. 当谈及 Linux 密码管理器时,我们会发现有很多这样的软件.我们已经在 LinuxAndUbuntu 上讨论过像 Keepass 和 Encryptr,一个基

Altium原理图中利用封装管理器批量修改元器件封装

批量修改封装,或者别人拿来原理图让我们画板时,发现封装全不对.如果原理图中同样封装的器件很多时,那么批量修改封装将大大减少你的工作量.下面将我批量修改封装的方法共享给大家. 在原理图界面,打开封装管理器:快捷键T-G,如图,在Design Item ID下选择需要修改的元器件ID,这个ID在设计原理图就确定了,不可以随便改变.如果全局修改本类别的元器件选择这个选项.也可以根据需求选择其他选项.如图,选中需要更改的PC814,并全选. 在图的右下角有Add添加按钮,添加封装,如图: 这时在窗口可以

【IOS开发之Objective-C】书签管理器项目

1.项目 新建一个书签管理器的项目,可以存储书签的网址.中文名.星级.访问量和权限信息,具有增.删.改.查和排序的功能. 2.找对象,抽象类 书签管理器,书签管理器,书签管理器--  多读几次书是不是就找到了对象,书签和管理器.书签包含网址.中文名和星级等信息:管理器里面有书签.那么我就可以抽象出两个类了,一个是书签类,一个是管理器类. 我们在书签管理器里面增.删.改.查和排序书签,在书签里面保存书签具有的属性数据. 3.对象的属性和行为分析 书签管理器的存储关系的分析: 4.类的实现 1.书签

多图片上传管理器

MyCnCart多图片上传图片管理器是您解决MyCnCart后台图片管理的优选方案,具有支持一次性上传多个图片,可以记住浏览器最近打开的文件夹,拖放式上传图片,重定义图片大小,旋转图片,检索图片等众多功能. 特色: 多图片选择上传: 多图片拖放式上传 (支持火狐. Safari.谷歌浏览器Chrome等): 多图片选择并赋予某产品: 键盘快捷键: 列示或网格式文件显示: 根据 A-Z, Z-A排序: 快速浏览图片: 重定义大小.旋转或修剪图片: 不覆盖任何文件: 不需要任何外部文件: 不使用Fl

安全类工具制作第006篇:服务管理器

一.前言 服务是一种在操作系统启动的时候就会启动的进程.在操作系统启动时会有两种程序随着系统启动,一种是普通的Win32程序,另一种则是驱动程序.正是基于服务的这种特性,恶意程序往往也会将自身伪装成正常的服务来实现自启动.因此在反病毒的过程中,还是很有必要对服务项进行查看并管理的. 服务管理器的开发原理与之前所讨论的注册表管理器和进程管理器是类似的,主要也是枚举服务并将其显示在"List Control"控件中.而对于服务的管理,是通过服务相关的API函数来实现的.有了本系列之前几篇文

QT开发(二十一)——QT布局管理器

QT开发(二十一)--QT布局管理器 一.布局管理器简介 QT中使用绝对定位的布局方式无法自适应窗口的变化. QT中提供了对界面组件进行布局管理的类,用于对界面组件进行管理,能够自动排列窗口中的界面组件,窗口大小变化后自动更新界面组件的大小. QLayout是QT中布局管理器的抽象基类,通过对QLayout的继承,实现了功能各异且互补的布局管理器. 布局管理器不是界面组件,而是界面组件的定位策略. 任意容器类型的组件都可以指定布局管理器. 同一个布局管理器管理中的组件拥有相同的父组件,在设置布局

[Noi2015]软件包管理器

题目描述 Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从软件源下载软件包,同时自动解决所有的依赖(即下载安装这个软件包的安装所依赖的其它软件包),完成所有的配置.Debian/Ubuntu使用的apt-get,Fedora/CentOS使用的yum,以及OSX下可用的homebrew都是优秀的软件包管理器. 你决定设计你自己的软件包管理器.不可避免地,你要解决软件包之间的依赖问题.如果软件包A依赖软件包B,那