【发布时间】:2016-08-05 08:24:35
【问题描述】:
我正在研究来自 WDK7 的 Microsoft Toaster 示例代码,发现了一个微妙的问题。
现在在 Windows 7 上尝试编译的驱动程序(WDM busenum 和 WDM features1)。
按照自述文件的指导,enum -p 1 添加了一个烤面包机设备,然后,我打开设备管理器(devmgmt),找到该设备,卸载它。
这将破坏 toaster 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(),这是正确的行为。 - 如果烤面包机从 devmgmt 被禁用,它确实不调用
Bus_DestroyPdo(),这也是正确的。
问题是,当最终用户从 devmgmt 执行卸载时,它遵循禁用路径。现在发生了一些不好的事情:Windows删除了toaster devnode,但是toaster bus driver没有破坏相应的PDO,所以,当用户下次执行enum -p 1时,toaster bus driverBus_PlugInDevice()会归咎于SerialNo==1的toaster设备已经存在,因此用户请求失败。
顺便说一句:Toaster 的 KMDF 版本也出现类似问题(今天只尝试了静态枚举版本)
现在我的问题很清楚了:如何区分禁用和卸载,我应该在总线驱动程序还是子设备驱动程序中进行?也欢迎回答 KMDF 版本。
【问题讨论】:
-
devnode真的被毁了吗?我认为它可能仍然存在,因为 PDO 存在(PDO 包含对对应的 devnode 的引用)。当您通过设备管理器禁用然后启用设备时,示例的行为是否相同。
-
请告诉我一种能够检查 devnode 是否存在的方法(比如一些股票实用程序),谢谢。
-
我不知道有什么工具可以做到这一点。您可以使用我的工具 (github.com/MartinDrab/VrtuleTree/releases) 检查卸载后是否存在 PDO(github.com/MartinDrab/VrtuleTree/releases - 文件 -> 创建快照并查找 \Driver\
)。删除 PDO 时,内核似乎删除了 devnode 结构。 -
谢谢。我检查了你的工具和 OSR 的 DevTreeView;他们都显示烤面包机子的 PDO 仍然存在,我发现 WinDBG
!devnode 0 1显示 devnode 仍然存在。所以,我只好把这个问题搁置一旁,等以后有机会解决。