tigerL
驱动小牛
驱动小牛
  • 注册日期2003-12-24
  • 最后登录2008-10-28
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望23点
  • 贡献值0点
  • 好评度19点
  • 原创分0分
  • 专家分0分
阅读:11489回复:48

协作安装程序应用一例 (欢迎进来瞧瞧!)

楼主#
更多 发布于:2004-11-12 22:07
所谓“协作安装程序”,在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组件,使其自动为我们的设备
安装驱动程序。

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

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

[编辑 -  11/12/04 by  tigerL]

最新喜欢:

viscarviscar kb219kb219
省元坊
hellowdf
驱动牛犊
驱动牛犊
  • 注册日期2010-03-09
  • 最后登录2010-06-12
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望11点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2010-05-26 14:49
顶,至少了解有这么一种手段是可以用来做这么一种事情的
lj2505
驱动牛犊
驱动牛犊
  • 注册日期2010-03-05
  • 最后登录2011-09-02
  • 粉丝0
  • 关注0
  • 积分2分
  • 威望21点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2010-03-05 16:10
学习!
ccchhh
驱动牛犊
驱动牛犊
  • 注册日期2007-11-16
  • 最后登录2010-03-18
  • 粉丝0
  • 关注0
  • 积分9分
  • 威望71点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2009-06-29 14:28
先试试再说吧,谢谢了
zhutq
驱动牛犊
驱动牛犊
  • 注册日期2009-05-08
  • 最后登录2010-02-21
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望11点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2009-05-20 11:14
好帖!!!!!
zhangxiao8252
驱动牛犊
驱动牛犊
  • 注册日期2009-04-25
  • 最后登录2012-05-16
  • 粉丝0
  • 关注0
  • 积分12分
  • 威望101点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2009-05-07 10:52
回 42楼(lynnhou) 的帖子
我的coinstaller写好了,但是在INF里面注册一直没成功,能给我发下你的实例代码吗?zhangxiao8252@sina.com
minotaurking
驱动牛犊
驱动牛犊
  • 注册日期2002-03-08
  • 最后登录2009-09-28
  • 粉丝0
  • 关注0
  • 积分4分
  • 威望40点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2009-05-06 17:39
发现在xp下不用定义新的setup class也可以。但在2000下面,ports是可以的,但同样的方法,modem仍然始终会弹出数字签名的对话框,不知道是为什么。
lynnhou
驱动牛犊
驱动牛犊
  • 注册日期2008-11-19
  • 最后登录2009-06-11
  • 粉丝0
  • 关注0
  • 积分4分
  • 威望32点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2009-04-15 10:04
恩,经过2天的努力,我也实现了。第一次做DRIVER,没有这个帖子真不知道如何解决这个问题。谢谢楼主的帖子,对我帮助很大。
lynnhou
驱动牛犊
驱动牛犊
  • 注册日期2008-11-19
  • 最后登录2009-06-11
  • 粉丝0
  • 关注0
  • 积分4分
  • 威望32点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2009-04-13 16:45
回 40楼(leproto) 的帖子
能请问你是做的USB的案子吗?
如果是,请问如何如作者所说:“最后,要提醒一点:必须为我们的usb设备定义一个新的设备setup类,然后将我们的协作安装程序注册为这个setup类的类协作安装程序。”
怎样定义一个新的设备的SETUP类呢?
leproto
驱动牛犊
驱动牛犊
  • 注册日期2007-11-20
  • 最后登录2012-05-16
  • 粉丝0
  • 关注0
  • 积分13分
  • 威望122点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2009-01-20 15:06
不错, 我实现了, 确实很强大的说, 牛!
wangwen916
驱动牛犊
驱动牛犊
  • 注册日期2004-11-30
  • 最后登录2010-12-24
  • 粉丝0
  • 关注0
  • 积分12分
  • 威望102点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2009-01-06 00:23
就是没看到例....
MOSQUITO
bygreen
驱动牛犊
驱动牛犊
  • 注册日期2005-06-26
  • 最后登录2014-03-28
  • 粉丝0
  • 关注0
  • 积分5分
  • 威望16点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2008-11-11 10:53
有实例就更好了
CAOYUANYUE
驱动牛犊
驱动牛犊
  • 注册日期2008-11-06
  • 最后登录2008-11-06
  • 粉丝0
  • 关注0
  • 积分8分
  • 威望9点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2008-11-06 15:51
瞒天过海,呵呵,我喜欢
驱网无线,快乐无限
zhoujiamurong
驱动小牛
驱动小牛
  • 注册日期2006-03-20
  • 最后登录2009-05-06
  • 粉丝4
  • 关注0
  • 积分1081分
  • 威望360点
  • 贡献值0点
  • 好评度215点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2008-09-18 16:10
大哥,我的Class 就是Modem ,不要也不能注册新的类,如何关联协助安装DLL呢?
xbzjackey
驱动小牛
驱动小牛
  • 注册日期2002-12-27
  • 最后登录2016-01-07
  • 粉丝0
  • 关注0
  • 积分5分
  • 威望34点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2008-07-31 15:36
bmwbk, 你的问题解决了吗?
回答好的不要忘了给分哦。。。
gaojingfeng
驱动牛犊
驱动牛犊
  • 注册日期2007-04-29
  • 最后登录2013-02-17
  • 粉丝0
  • 关注0
  • 积分4分
  • 威望17点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
15楼#
发布于:2008-07-16 11:26
我也是注册不成功啊,急需一份inf做个参考,谢谢啦
prince321
驱动牛犊
驱动牛犊
  • 注册日期2008-06-12
  • 最后登录2010-01-04
  • 粉丝0
  • 关注0
  • 积分2分
  • 威望12点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
16楼#
发布于:2008-06-13 11:58
inf里注册不成功...
谁能把INF文件里面的代码发出来看看?
shnk3000
驱动牛犊
驱动牛犊
  • 注册日期2007-05-13
  • 最后登录2011-01-19
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望53点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
17楼#
发布于:2008-06-10 14:50
不错,可做参考!
zhangbeizhou
驱动牛犊
驱动牛犊
  • 注册日期2007-05-29
  • 最后登录2009-04-03
  • 粉丝0
  • 关注0
  • 积分4分
  • 威望24点
  • 贡献值0点
  • 好评度11点
  • 原创分0分
  • 专家分0分
18楼#
发布于:2008-06-04 15:09
多谢分享~!!!
nicm
驱动牛犊
驱动牛犊
  • 注册日期2008-04-21
  • 最后登录2008-05-26
  • 粉丝0
  • 关注0
  • 积分90分
  • 威望10点
  • 贡献值0点
  • 好评度9点
  • 原创分0分
  • 专家分0分
19楼#
发布于:2008-04-21 16:02
本人新手,正在做USB驱动安装包,可否提供源码,
谢谢!
nichuming@hotmail.com
驱网无线,快乐无限
上一页
游客

返回顶部