驱动开发中,AddDevice是如何被调用的

dahuatttt 2009-05-24 01:00:58
看了下DDK中带的过滤驱动(2600\src\storage\filters\diskperf\diskperf.c),在DriverObject->DriverExtension->AddDevice中指定了AddDevice函数入口。但是该DriverEntry中只做了MajorFunction入口的指定,没有创建任何device object。既没有自己的CDO或者PDO,也没有Attach到别的设备对象上,那这个驱动怎么可能被识别和被管理呢。它的AddDevice怎么会被调用到呢。
...全文
2329 54 打赏 收藏 转发到动态 举报
写回复
用AI写文章
54 条回复
切换为时间正序
请发表友善的回复…
发表回复
tasselno1 2011-09-25
  • 打赏
  • 举报
回复
[Quote=引用 51 楼 skyair624 的回复:]

干,搞了个通宵~~
对于WDM驱动,刚刚试验了下,每次安装INF就会引起相关的AddDevice函数被调用,这种关联机理猜测为:PnP管理器通过VernderID和ProductID去搜索 更匹配的INF文件,然后通过INF中的记录定位关联的驱动,然后就可以知道这个AddDevice了(若有多个INF匹配的话,需要手动选择,《windows驱动技术详解》第364页也间接的说明了多个INF存在情……
[/Quote]

[Quote=引用 52 楼 redchairman 的回复:]

这个驱动被加载的时候PDO已经创建了
操作系统启动加载一个驱动的顺序:
1.注册表Enum下枚举所有设备。
2.为每一个枚举到的设备创建PDO,并查找设备对应的服务(service注册表)。
3.服务注册表中查找驱动信息,然后加载驱动,也就是调用DriverEntry。
[/Quote]

[Quote=引用 53 楼 rock178 的回复:]

应该是:先加载总线的驱动-->总线驱动程序枚举总线上的设备-->PnP管理器为枚举到的设备创建PDO-->从注册表里面得到这个PDO的各个驱动程序和加载顺序(加载顺序由INF文件写入注册表的)-->然后依次加载驱动程序,在此过程中调用AddDevice(),同时建立与下层设备的连接和驱动程序和这个设备的连接 -->依次类推直到把这个设备加载完成
[/Quote]

这几楼应该差不多都是正确的,53楼说的好详细。。

我有疑问,比如我有两个一样的鼠标,安装时选择相同驱动程序,那么加载时DriverEntry调用几次?IO管理器对这两个鼠标设备创建了几个DriverObject?
rock178 2011-09-18
  • 打赏
  • 举报
回复
应该是:先加载总线的驱动-->总线驱动程序枚举总线上的设备-->PnP管理器为枚举到的设备创建PDO-->从注册表里面得到这个PDO的各个驱动程序和加载顺序(加载顺序由INF文件写入注册表的)-->然后依次加载驱动程序,在此过程中调用AddDevice(),同时建立与下层设备的连接和驱动程序和这个设备的连接 -->依次类推直到把这个设备加载完成

非知名码农 2011-06-20
  • 打赏
  • 举报
回复
这个驱动被加载的时候PDO已经创建了
操作系统启动加载一个驱动的顺序:
1.注册表Enum下枚举所有设备。
2.为每一个枚举到的设备创建PDO,并查找设备对应的服务(service注册表)。
3.服务注册表中查找驱动信息,然后加载驱动,也就是调用DriverEntry。
skyair624 2011-06-15
  • 打赏
  • 举报
回复
干,搞了个通宵~~
对于WDM驱动,刚刚试验了下,每次安装INF就会引起相关的AddDevice函数被调用,这种关联机理猜测为:PnP管理器通过VernderID和ProductID去搜索 更匹配的INF文件,然后通过INF中的记录定位关联的驱动,然后就可以知道这个AddDevice了(若有多个INF匹配的话,需要手动选择,《windows驱动技术详解》第364页也间接的说明了多个INF存在情况下的处理方式),调用AddDevice前先确定是否”这个驱动“已经加载过了,若加载过则直接调用AddDevice,否则先”调用DriverEntry加载驱动“再调用AddDevice安装设备。
另外:
1. INF中写注册表目的是,在”设备管理器“查看当前设备时显示”版本,名称“等,驱动程序信息,貌似没有其他作用。
2. INF中拷贝sys到system32/drivers里是为了加载驱动,这个路径是驱动加载的默认路径
3.AddDevice从早起的NT式驱动DriverEntry中分离出来的原因猜测:功能相同的2种设备可能被同时插到一台PC上,如果,他们在DriverEntry中都要创建以”\Device\NNN“的话,那么只有第一个创建的可以成功,也就是这里名字出现冲突,比如,一台电脑接入了2个鼠标,无论是NT还是WDM形式驱动,后者肯定安装失败,因此MS引入GUID避免”设备名称(不是驱动名称)“碰撞(到这里大部分内容是资料上介绍的,有一部分是我自己举例或补充的),既然出现了,多个物理设备共享同一个”驱动“创建的”设备“,那么就有必要单独创建”设备“了,但是之前的 创建设备代码 跟 驱动对象初始化代码 同在DriverEntry中(驱动初始化时调用),那么初始化只需要1次,所以这里 DriverEntry 就 和 AddDevice 分家了。
skyair624 2011-06-15
  • 打赏
  • 举报
回复
《Windows驱动开发技术详解》第78页 第362页
g20062558 2011-04-20
  • 打赏
  • 举报
回复
The AddDevice routine is responsible for creating functional device objects (FDO) or filter device objects (filter DO) for devices enumerated by the Plug and Play (PnP) manager.【MSDN AddDevice】

真正触发diskperf AddDevice例程的是应用层的操作,如读写磁盘
g20062558 2011-04-20
  • 打赏
  • 举报
回复
本想来找答案的,想知道PNP管理器何时调用AddDevice,结果大家说了半天,还是没搞清楚

对于lz的问题我的理解是:

1、过滤驱动程序的inf文件中存有驱动的相关信息,安装驱动时这些信息(驱动类型,安装层级等)会被写入注册表。

2、当PNP管理器为一个设备(如Disk)加载(注意是加载,不是安装)驱动程序时,它根据注册表中的信息来确定驱动程序,包括过滤驱动程序,然后调用驱动程序的AddDevice例程,创建设备对象,并将其附载到设备栈中。

详见【潘爱民 《Windows内核原理与实现》P434-P436】重点是435倒数两段,436第一段


当然,非即插即用驱动程序和文件系统驱动程序(包括文件系统过滤驱动)不是这样,它们有另外的实现方式。


希望对你有帮助
kid0220 2011-03-17
  • 打赏
  • 举报
回复
[Quote=引用 45 楼 graphicswe 的回复:]
楼上的说来说去,还是没有一个人较深入的了解系统到底是如何调用AddDevice的,有的不太懂也跟着风讲,看这样贴子,费心又费力。
[/Quote]

严重同意,和楼主有同样的疑问,看了这个帖子疑问还是没完全弄清楚。
在《windows驱动开发技术详解》里面,帆哥说是通过VID和PID来决定的(在你的inf文件里面)。
当插入一个物理设备时,如果该物理设备的VID和PID与你的驱动的相吻合,你的驱动就会被加载。
设备的VID和PID可以在设备管理器那里看到。
自己做实验时,VID和PID与驱动一致了但驱动没加载,nnd,不知道是怎么回事......
lxcsyh 2010-02-06
  • 打赏
  • 举报
回复
是在注册表的HKLM\CurrentControlSet\Control\Class下面注册过吧应该。
graphicswe 2009-11-21
  • 打赏
  • 举报
回复
楼上的说来说去,还是没有一个人较深入的了解系统到底是如何调用AddDevice的,有的不太懂也跟着风讲,看这样贴子,费心又费力。
tomsheep 2009-11-11
  • 打赏
  • 举报
回复
mark
liuyinandabendan 2009-08-30
  • 打赏
  • 举报
回复
AddDevice是一个被动添加过程,wdm式的驱动与nt式的驱动不同,nt式的驱动可以有我们自己来决定是否想某一个设备上挂接过滤设备,而wdm式的驱动只要总线上枚举出设备就会调用adddevice为它挂接过滤设备,当然我们自己定义的adddevice也可不进行挂接过滤设备的过程,但是adddevice 依然会被调用。
ufo1cn 2009-08-28
  • 打赏
  • 举报
回复
PnP管理器有一个内建的驱动程序,它与一个实际不存在的根总线相对应。根总线概念性地把计算机与所有那些不能用电子方式声明自己存在的设备连接起来,这包括主硬件总线(如PCI)。根总线驱动程序从注册表中获取有关计算机的信息。而这些关于计算机本身的注册表信息是由Windows 2000系统安装程序初始化的。安装程序通过运行一个精心制作的硬件检测程序以及向用户提出一些适当的问题来获取这些信息。所以,根总线驱动程序有足够的信息为主总线创建PDO。

然后,主总线的功能驱动程序用电子方式枚举自己的硬件

总线功能驱动在IRP_MN_QUERY_DEVICE_RELATIONS中创建PDO返回或诸如IoReportDetectedDevice之类的方法通知操作系统非PnP设备,但是没有给出PDO,操作系统会创建PDO, 然后操作系统根据注册表信息依次载入驱动. 一些驱动会枚举注册表(由端口驱动等创建),取得要操作的下层设备对象.


WDM驱动是根据inf文件写注册表的,Pnp会根据注册表记录信息和总线驱动或下层驱动报告的电子签名信息匹配性,来调用你的驱动的AddDevice函数.PDO就是这个驱动(总线或下层)创建的下层设备对象

这是我的理解.


QQ_456 2009-08-27
  • 打赏
  • 举报
回复
up
littlefish636 2009-05-25
  • 打赏
  • 举报
回复
学习
alan001 2009-05-25
  • 打赏
  • 举报
回复
UP
terran_ye 2009-05-25
  • 打赏
  • 举报
回复
inf文件不是有个GUID吗。注意这个GUID
dahuatttt 2009-05-25
  • 打赏
  • 举报
回复
[Quote=引用 38 楼 goodname 的回复:]
网上有一本
《Programming the Microsoft Windows driver model》的中文版

你可以下载来看看
[/Quote]
恩,谢谢!
goodname 2009-05-25
  • 打赏
  • 举报
回复
网上有一本
《Programming the Microsoft Windows driver model》的中文版

你可以下载来看看
dahuatttt 2009-05-25
  • 打赏
  • 举报
回复
翻遍了Windows2000设备驱动程序设计指南 和 文件系统内幕,都没找到这做法的解释。我都崩溃好多天了。毛德操的windows内核情景分析书里,作者也有个关于AddDevice的问题。我觉得这里问题不少。。。
加载更多回复(34)

70,038

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧