驱动程序枚举了两个返回相同设备ID的子PDO

时间:2017-08-21 20:55:20

标签: ndis kmdf wdf

我有一个kmdf总线驱动程序PCI \ VEN_XXXX& DEV_XXXX,它创建两个静态枚举的PDO,序列号为217和218;每个以太网端口一个。 PDO硬件ID为ROOT \ MY_NIC_PORT,因此我可以在它们上安装NDIS Miniport驱动程序。

总线驱动程序通过SDV和Verifier;但是,在重新启动时,会枚举另外两个PDO。在下次重启时,我得到了重复的pdo崩溃。

烤箱示例使用设备类guid作为硬件ID的一部分。当我尝试我的NIC端口不再出现在设备管理器中时。

任何调试建议或解决方法都会受到赞赏吗?

pnpCaps.LockSupported = WdfFalse;
pnpCaps.EjectSupported = WdfTrue;
pnpCaps.Removable = WdfTrue;
pnpCaps.DockDevice = WdfFalse;
pnpCaps.UniqueID = WdfTrue;
pnpCaps.SilentInstall = WdfTrue;
pnpCaps.SurpriseRemovalOK = WdfTrue;
pnpCaps.HardwareDisabled = WdfFalse;
pnpCaps.NoDisplayInUI = WdfFalse;
pnpCaps.Address = SerialNo;
pnpCaps.UINumber = SerialNo;

************************************************************
Driver Verifier detected violation:

A driver has enumerated two child PDO's that returned identical Device
ID's.

CulpritAddress = FFFFF8025ED309C4, DeviceObject1 = FFFFE3882FB2F300, 
DeviceObject2 = FFFFE3882EBF88D0.
************************************************************

1 个答案:

答案 0 :(得分:1)

烤面包机总线示例有几个版本 - 假设您从this one开始,请注意它将其子PDO列表保存在注册表中。我的猜测是你的驱动程序既从注册表加载PDO,又试图动态创建一些PDO。

在您的驱动程序版本的Bus_PlugInDevice上设置一个断点,并查看它被调用的频率。确保它永远不会被使用相同的实例ID调用2次。

要清除一些命名内容:设备设置类是与其硬件ID 完全无关的GUID。对于想要与操作系统的网络堆栈进行互操作的NIC,必须使用NET安装类{4d36e972-e325-11ce-bfc1-08002be10318}。您可以将任何想要的东西放入硬件ID中。我真的不鼓励你把" ROOT \"在那里,因为那可能与根枚举设备混淆(你的设备不是)。相反,您可以使用" yourcompany_yourdevice \ port1"作为硬件ID。

虽然您正在考虑命名事项,但有一些关于硬件ID的注意事项:

  • 分配HWID后,在未来的驱动程序更新中很难更改它,而不会破坏已安装设备的客户。所以第一次就把它弄好。
  • 分配实例ID后,请勿在设备的生命周期内更改或重复使用该实例ID。否则,您将导致此错误检查,或导致IP地址反弹/重置。操作系统最终使用实例ID来确定将IP地址绑定到的NIC端口。
  • 想想如果有人将2个设备插入系统会发生什么。确保您的实例ID在所有端口上都是唯一的。您可以通过将实例ID编码为PCI设备序列号(如果有)或通过回退到PCI总线来实现:device:function。
  • 不要在同一硬件ID下将不同的类型硬件混为一谈。例如,如果您的设备的豪华版本支持校验和卸载,但普通版本不支持 - 您应该为这两个不同的设备使用2个不同的硬件ID。否则,很难编写一个包含两个关键字的INF。