[英]How to distinguish devmgmt's Disable and Uninstall from within my Windows driver code?
我正在研究WDK7的Microsoft Toaster示例代码,我发现了一个微妙的问题。
现在在Windows 7上尝试编译的驱动程序(WDM busenum和WDM featured1)。
在README的指导下, enum -p 1
添加了一个烤面包机设备,然后,我打开设备管理器(devmgmt),找到设备, 卸载它。
这将破坏烤面包机devnode(我相信);
我们可以看到ToasterDevice01节点现在从设备管理器中消失。 !devnode 0 1
显示烤面包机devnode仍然存在,State = DeviceNodeUninitialized(0x301),Previous State = DeviceNodeRemoved(0x312)。
然后,我执行enum -p 1
尝试再次添加设备。 但我收到错误0x57(ERROR_INVALID_PARAMETER)。
我调试源代码并找出原因: buspdo.c
不区分devmgmt的Disable和Uninstall操作。 他的代码逻辑是:
enum -u 1
),它会调用Bus_DestroyPdo()
这是正确的行为。 Bus_DestroyPdo()
这也是正确的。 问题是 ,当最终用户从devmgmt执行卸载时,它遵循禁用路径。 现在发生了一些不好的事情:Windows删除了烤面包机devnode,但是烤面包机总线驱动程序没有销毁相应的PDO,因此,当下次用户执行enum -p 1
,烤面包机总线驱动程序Bus_PlugInDevice()
将带有SerialNo的烤箱设备归咎于== 1已经存在,因此用户请求失败。
顺便说一句:Toaster的KMDF版本表现出类似的问题(今天只尝试了静态枚举版本)
现在我的问题很明确:我如何区分禁用和卸载,我应该在总线驱动程序或子设备驱动程序中进行此操作吗? 也欢迎使用KMDF版本的答案。
现在我可以得出结论。 我们的客户端驱动程序无法区分从设备管理器中禁用和卸载。 这是微软的设计。
为了进行区分,我们需要应用层的帮助。 为子设备提供CoInstaller,并且当CoInstaller获取DIF_REMOVE通知(这是devmgmt执行卸载的结果)时,将自定义IOCTL(例如IOCTL_UNPLUG_MY_CHILD)发送到内核驱动程序,以便内核驱动程序拔出相应的子驱动程序。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.