协作安装程序应用一例

所谓“协作安装程序”,在ddk文档里面称作co-installer,有人将它翻译成“共同安装程序”。但是,
从ddk文档对co-installer功能的描述来看,我个人觉得翻译成“协作安装程序”更恰当些。

ddk文档对co-installer的描述:A co-installer is a Microsoft® Win32® DLL that assists in
device installation. Co-installers are called by Setup API as "helpers" for Class
Installers.简单地翻译一下:协作安装程序是一个Win32 DLL,它辅助设备的安装。协作安装程序
由Setup API调用,作为类安装程序的“助手”。

在本论坛搜索了一下有关“协作安装程序”的帖子,发现这方面的帖子很少。我想之所以这样,是因为
大家在驱动开发过程中可能很少有需要用到协作安装程序的地方。或者说本来有些地方可以使用,但可能
因为不太了解这方面的东西,所以没有想到去用它。

这儿,我想介绍一个关于协作安装程序的应用实例。

开发过USB设备驱动的朋友,不知有没有碰到过下面的问题:如果你的设备驱动程序没有经过数字签名,
那么,在XP系统下,你在每个USB口上第一次插上你的USB设备时,系统都会要求你装一次驱动程序。
这种感觉是很不好的。我们希望能像大多数USB移动盘一样,插上设备就自动安装驱动,然后就可以对
设备进行访问了。

如何让我们的USB设备插上后,系统也能自动为它安装驱动,而不需要烦劳用户手动安装呢?解决此问题
的核心技术在于编写一个类协作安装程序。

首先,有一个问题大家要清楚,USB设备第一次插到机器上的一个USB口上时,系统要为它
装一次驱动程序。我们以USB设备为例,来了解一下支持热插拔的PnP设备的安装过程:
(1)设备插入系统,USB总线驱动向内核PnP管理器报告有新设备接入系统;
(2)内核PnP管理器向USB总线驱动询问设备的具体信息,比如PID和VID等;
(3)内核PnP管理器将设备的信息报告给用户层的PnP管理器,并要求它为新设备安装驱动;
(4)用户层PnP管理器调用系统的Setup组件来为设备安装驱动;
(5)Setup使用设备VID和PID到%Windir%\\inf下寻找适合它的inf文件,并获得一个可用于设备的驱动程序列表;
(6)Setup在生成驱动程序列表的时候,会检查inf文件是否经过数字签名,如果没有经过数字签名,
Setup会将此inf文件负责安装的驱动程序设置成“不可信任的”驱动程序;
(7)Setup对驱动程序列表中的各驱动程序信息进行分析,选择最匹配设备的驱动程序进行安装;

这里,有必要提一下“不可信任的驱动程序”这个概念。这个概念在xp之后才有的,2k和98没有。在Setup
生成的驱动程序列表中,每个驱动程序的信息结构中都有一个Rank字段。在xp中,0x0 < Rank <= 0x3FFF的
驱动程序被认为是“可信任的”;0x8000 <= Rank <= 0xFFFF的驱动被认为是“不可信任的”。如果我们的
驱动程序没有经过数字签名,那么它的Rank值肯定落在0x8000到0xFFFF之间。

再回到前面的安装过程,如果驱动程序中有适合设备的“可信任”驱动程序,那么系统自动对它进行安装;
如果驱动程序列表中的所有驱动程序都是“不可信任的”,那么系统就会弹出“发现新硬件”向导,要你提
供更好的驱动程序,或者要你确认安装“不可信任的”驱动程序。这就是为什么在xp系统下,即便你在一个
USB口上已经安装了设备的驱动程序,你再换个口插上设备,系统又会提示你安装驱动程序的原因。

说了半天,我想现在各位肯定都明白过来了:影响设备驱动程序自动安装的主要原因,是因为我们的
驱动程序被系统认为是“不可信任的”。而系统判断一个驱动程序是否“可信任”,是通过驱动程序信息结
构中的Rank字段的值来判断的。那么,如果我们能把我们的驱动程序信息中的Rank值修改到“可信任”空间,
那么系统是否就会信任我们的驱动程序,而自动对它进行安装呢?答案是,有可能。我不敢说肯定可以,原因
后面会提到。但是,如何修改驱动程序信息的Rank值呢?这就要用到“协作安装程序”。

我们知道,在设备的安装过程中,Setup要向设备类安装程序、类协作安装程序和设备协作安装程序发送
“设备安装功能码”(如果有这些安装程序的话)。ddk文档中又说,类安装程序和类协作安装程序可以对
DIF_SELECTBESTCOMPATDRV请求进行处理(设备协作安装程序不可以)。在对DIF_SELECTBESTCOMPATDRV进行处理
的时候,类安装程序和类协作安装程序可以修改驱动程序列表中各驱动程序的信息。答案越来越清晰了,我们
只要写一个类协作安装程序,对DIF_SELECTBESTCOMPATDRV进行处理,修改我们想要安装的驱动程序的Rank值,
那么就可能骗过系统,使系统相信我们的驱动程序,并完成自动安装。关于编写协作安装程序的具体要求和方法,
可以参考ddk文档中的“Writing a Co-installer(编写协作安装程序)”和ddk\src\general\toaster\coinstaller。

接下来,我们来了解一下,在类协作安装程序处理DIF_SELECTBESTCOMPATDRV时,应该做哪些事情。
(1)首先,调用SetupDiEnumDriverInfo遍历驱动程序列表,获得每个驱动程序的信息――一个
SP_DRVINFO_DATA结构。
(2)接着,用(1)中获得的SP_DRVINFO_DATA作为输入参数,调用SetupDiGetDriverInstallParams,
获得驱动程序安装参数――一个SP_DRVINSTALL_PARAMS结构,其中我们想要修改的Rank赫然在列。你可以按
照自己的需要修改Rank的值,在这儿我们肯定是要把它改为0了(0表示驱动程序与设备最匹配)。
(3)最后,把修改后的SP_DRVINSTALL_PARAMS结构作为输入,调用SetupDiSetDriverInstallParams将我们修改
的值设置生效。
在类协作安装程序中只需作如此处理,便可以使Setup此后信任我们的驱动程序,从而达到我们想瞒天过海的目的。

再稍微提一下类协作安装程序的注册。协作安装程序做好了,如何使它参与到设备安装的过程中来呢?我们
必须注册它。ddk文档对此讲得非常清楚了,参看“Registering a Class Co-installer”,我就不在这儿把它翻译出来了。

最后,要提醒一点:必须为我们的usb设备定义一个新的设备setup类,然后将我们的协作安装程序注册为这个
setup类的类协作安装程序。如果我们让设备仍然属于usb setup类,并将我们的类协作安装程序注册为usb
setup类的一个协作安装程序,那么在安装过程中,Setup仍然弹出一些窗体影响我们设备的自动安装,似乎我们的小聪明
并没能瞒过它。这就是前面我说修改Rank值为“可信任”只是有可能瞒过系统而不是肯定能够瞒过系统的原因。为什么会出现
这种情况呢?从现象看,我感觉是usb setup类的类安装程序仍然发现我们的驱动程序是不可信任的。但是,Setup是以类协作
安装程序、设备协作安装程序和类安装程序的顺序调用它们的,在Setup调用usb setup类安装程序之前,我们已经修改了驱动程序的
Rank值。按理说,它应该不会发现驱动程序是不可信任的。这是一个问题,具体原因我还没有弄明白,希望有知其所以然者,能给
点提示!不管如何,通过实验我发现,只要我们定义了新的setup类,那么我们就可以骗过系统Setup组件,使其自动为我们的设备
安装驱动程序。

就写这些,有兴趣的朋友可以试一下!我不想把具体的实现过程一步一步地写出来,更不愿提供具体的实现代码。
因为我认为只要把原理和方法讲清楚了(但愿我讲得还算清楚),每个人都可以在此基础上做自己的事情。

不管各位朋友看完之后感觉如何,能夸就夸夸,该骂就骂骂,都顶一下!

转载于:https://www.cnblogs.com/spinsoft/archive/2012/05/16/2502788.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/409833.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

foxitreadersdk 打开远程文件_一种最不为人知最简单最方便的用电脑操作手机上的文件...

(声明&#xff1a;此功能&#xff0c;只适用于安桌系统的手机)由于最近一年手机上的文件经常隔三差五地提示空间已满&#xff0c;我不得不经常痛心删除一些文件&#xff0c;或者将手机上的文件&#xff0c;移到电脑端。如果想通过QQ或者微信发送单个单个文件&#xff0c;总是不…

月球-I型,月份日历生成器----基于PHP7.3

生成月份周日的类<?php class mycalendar {function __construct($year,$mon){$this->nianyue$year.-.$mon.-.01;$this->firstdaystrtotime(date($this->nianyue));$this->m intval(date(m,$this->firstday));$this->wdaylistarray();$this->lday s…

python dict遍历_Python 容器(二):字典(Dict)

Python 容器(二)&#xff1a;字典(Dict)一、字典1、定义&#xff1a;Python的字典数据类型是基于hash散列算法实现的&#xff0c;采用键值对(key:value)的形式&#xff0c;根据key的值计算value的地址&#xff0c;具有非常快的查取和插入速度。2、特点&#xff1a;1&#xff09…

论得失。。。技术方向

得失&#xff0c;一直都是人们所在意的&#xff0c;一旦得那么久开开心心&#xff0c;一旦失。就闷闷不乐&#xff0c;其实不然&#xff0c;中国的词语博大精深。一句舍得。解开了万人的心声。舍得&#xff0c;舍得&#xff0c;没舍哪来得。其实做技术也是一样。往往你在这个领…

[html] 你有了解video的x5-video-player-type这个属性吗?它的作用是什么呢?

[html] 你有了解video的x5-video-player-type这个属性吗&#xff1f;它的作用是什么呢&#xff1f; 这个属性是限制微信的X5 内核的自动播放功能个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知识。放弃很容易&#xff0c; 但坚持一定很酷。欢迎大家一起讨论 主目…

路径级别

.. 上一级 ~/根目录转载于:https://www.cnblogs.com/maomiyouai/archive/2012/05/21/2511021.html

奥特曼传奇英雄存档丢了怎么找回_热血传奇:道士最帅武器—玄天

点击“传奇私服玩家群”加个关注☀ 欢迎传奇老司机&#xff01;在这里&#xff0c;分享最新传奇资讯&#xff0c;回忆当年的传奇年代。分享最热传奇手游&#xff0c;端游&#xff0c;找回昔日组队的热血时光。记得加个关注不迷路~☀ 微信公众号&#xff1a;diyisf777热血传奇中…

.Net Core下基于Emit的打造AOP

之前的基于DispatchProxy的AOP组件&#xff0c;实现了属性注入&#xff0c;但是这个依旧有很多限制 比如不支持构造器注入&#xff0c;继承DispatchProxy的子类必须是公开类 个人有点代码洁癖&#xff0c;不喜欢这种不能控制的方式&#xff0c;就学了几天Emit&#xff0c;参考了…

[html] iOS下页面如何启动加载时显示画面图片?如何设置大小?它有什么好处?

[html] iOS下页面如何启动加载时显示画面图片&#xff1f;如何设置大小&#xff1f;它有什么好处&#xff1f; <link rel"apple-touch-startup-image" href"start.png" media"(device-width: 1536px) and (orientation: portrait)"/> IOS…

google 确定某点海拔高_“湘能楚天”牌变电站的威宁之旅(一)|高海拔下如何实现与茫茫雪原环境的共生?...

“湘能楚天”牌变电站的威宁之旅——序从湘能楚天办公楼三楼坐电梯&#xff0c;出门左转上京珠高速再转杭瑞高速&#xff0c;根据百度地图的提醒&#xff0c;行车13小时40分&#xff0c;将抵达贵州威宁黑土河&#xff0c;全程1197公里&#xff0c;再前行就到了迤那。黑土河&…

.Net Core 3.0依赖注入替换 Autofac

今天早上&#xff0c;喜庆的更新VS2019&#xff0c;终于3.0正式版了呀~ 有小伙伴问了一句Autofac怎么接入&#xff0c;因为Startup.ConfigureServices不能再把返回值改成IServiceProvider了&#xff0c;原来的替换依赖注入容器就不可行了&#xff0c;我随口说了一下Host上面.Us…

designer一直未响应 qt_未雨绸缪及时清淤 曾是内涝重灾区 这次涵洞未积水

市政工人揭开井盖排水 楚天快报见习记者吴宜芝 通讯员王艳华城区几处铁路涵洞&#xff0c;曾经是城区内涝重灾区&#xff0c;每逢下雨&#xff0c;涵洞就成了一条无法逾越的鸿沟。然而此次持续6个多小时的降雨中&#xff0c;却均未出现严重的积水&#xff0c;也未影响交通。此次…

a标签点击事件_DOM事件机制

前言本文主要介绍DOM事件级别、DOM事件模型、事件流、事件代理和Event对象常见的应用&#xff0c;希望对你们有些帮助和启发&#xff01;一、DOM事件级别DOM级别一共可以分为四个级别&#xff1a;DOM0级、DOM1级、DOM2级和DOM3级。而DOM事件分为3个级别&#xff1a;DOM 0级事件…

如何开始了解一个新知识(Vuex)

我是歌谣 放弃很容易 但是坚持一定很酷 前言 每次做开发遇到一个新的知识点 总要思索着如何去实现这个新东西 最近来大概讲讲Vuex vuex是前端用的比较多的一个东西之一 通过一张图了解一下原理 原理和vuex产生原因 看完了整个的原理之后 安装就直接过去了 就是包管理工具 …

HDU2277_变色球

/* *题目大意: * 给定a, b, c&#xff0c;代表三种不同颜色的球的个数&#xff0c;然后规定 * 如果把任意两种不同颜色的球放在一起&#xff0c;那么它们两个 * 的颜色将变成第三种颜色的球的颜色。求判断最后所有的 * 球能否变成同一种颜色&#xff0c;如果能&#xff0c;…

.Net Core 3.0下AOP试水~~

昨天躺了一下3.0的依赖注入的雷 今天顺势把AOP做了一下调整&#xff0c;比如自动化的AOP注入 默认的Program里面的CreateHostBuilder方法增加一行 public static IHostBuilder CreateHostBuilder(string[] args) >Host.CreateDefaultBuilder(args).UseServiceProviderFactor…

golang 读取文件最后一行_测试用例是开发人员最后一块遮羞布

测试用例是开发人员最后一块遮羞布最近一周写一个比较复杂的业务模块&#xff0c;越写到后面真心越心虚。操作越来越复杂了&#xff0c;代码也逐渐凌乱了起来。比如一个接口&#xff0c;传入的是一个比较复杂的大json&#xff0c;我需要解析这个大json&#xff0c;然后根据json…

android 进度条_Android仿水波纹流球进度条控制器,实现高端大气的主流特效

今天看到一个效果挺不错的&#xff0c;就模仿了下来&#xff0c;加上了一些自己想要的效果&#xff0c;感觉还不错的样子&#xff0c;所以就分享出来了&#xff0c;话不多说&#xff0c;上图CircleView这里主要是实现中心圆以及水波特效package com.lgl.circleview;import andr…

[html] iframe父页面如何获取子页面的元素?

[html] iframe父页面如何获取子页面的元素&#xff1f; 在父页面监听 onmessage&#xff0c;子页面 postMessage。$(iframe)[0].contentWindow.document.getElementByIddocument.frames[xx].document.getElementById个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知识…

怎么更换WIN7欢迎界面的背景图?

第一步&#xff1a;先单击“开端 →运转 ”&#xff0c;打开“运转 ”对话框并输入 “Regedit”&#xff08;不包含外侧引号&#xff09;&#xff1b;接着单击“确定”按钮打开注册表编辑器&#xff0c;再定位到“HKEY_LOCAL_MACHINESOFTWARE\Microsoft\Windows\CurrentVersion…