我正在研究来自 WDK7 的 Microsoft Toaster 示例代码,我发现了一个微妙的问题。
现在在 Windows 7 上尝试编译的驱动程序(WDM busenum 和 WDM features1)。
按照自述文件的指导,enum -p 1
添加一个烤面包机设备,然后,我打开设备管理器(devmgmt),找到设备,卸载它。
这将破坏烤面包机的devnode(我相信);我们可以看到ToasterDevice01节点现在从设备管理器中消失了。!devnode 0 1
显示 toaster 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()
正确的行为。 - 如果 toaster 从 devmgmt 被禁用,它不会调用,
Bus_DestroyPdo()
这也是正确的。
问题是,当最终用户从 devmgmt 执行卸载时,它遵循禁用路径。现在发生了一些不好的事情:Windows 删除了 toaster devnode,但是 toaster bus driver 不会破坏相应的 PDO,因此,当用户下次执行时enum -p 1
,toaster bus driverBus_PlugInDevice()
会指责 SerialNo==1 的 toaster 设备已经存在,因此失败用户请求。
BTW:Toaster 的 KMDF 版本也有类似的问题(今天只尝试了静态枚举版本)
现在我的问题很清楚了:如何区分禁用和卸载,我应该在总线驱动程序还是子设备驱动程序中进行?也欢迎回答 KMDF 版本。