Драйвер перечислил два дочерних PDO, которые вернули идентичные идентификаторы устройств.

У меня есть драйвер шины kmdf PCI\VEN_XXXX&DEV_XXXX, который создает два статически пронумерованных PDO с серийными номерами: 217 и 218; по одному на каждый порт Ethernet. Идентификатор оборудования PDO — ROOT\MY_NIC_PORT, поэтому я могу установить на них драйвер NDIS Miniport.

Водитель автобуса проходит СДВ и Верификатор; но при перезагрузке перечисляются еще два PDO. При следующей перезагрузке я получаю повторяющийся сбой pdo.

В примере с тостером GUID класса устройства использовался как часть идентификатора оборудования. Когда я попытался, мои сетевые порты больше не отображались в диспетчере устройств.

Будут оценены любые предложения по отладке или обходные пути?

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.
************************************************************

person Dan    schedule 21.08.2017    source источник


Ответы (1)


Существует несколько версий примера шины тостера — при условии, что вы начали с этот, а затем обратите внимание, что он сохраняет список дочерних PDO в реестре. Я предполагаю, что ваш драйвер одновременно загружает PDO из реестра и пытается динамически создавать некоторые из них.

Установите точку останова на версию Bus_PlugInDevice вашего драйвера и посмотрите, как часто она вызывается. Убедитесь, что он никогда не вызывается дважды с одним и тем же идентификатором экземпляра.

Чтобы немного прояснить вопрос именования: класс настройки устройства — это GUID, который совершенно не связан с его идентификатором оборудования. Для сетевых карт, которые хотят взаимодействовать с сетевым стеком ОС, необходимо использовать класс установки NET {4d36e972-e325-11ce-bfc1-08002be10318}. Вы можете поместить все, что хотите, в свой идентификатор оборудования. Я действительно не рекомендую вам помещать туда «ROOT\», так как это можно спутать с устройством с корневым перечислением (которым ваши устройства не являются). Вместо этого вы можете использовать «yourcompany_yourdevice\port1» в качестве идентификатора оборудования.

Пока вы думаете об именах, следует отметить несколько моментов, касающихся идентификаторов оборудования:

  • После того, как вы назначите HWID, довольно сложно изменить его в будущем обновлении драйвера, не нарушая работу клиентов, которые уже установили ваше устройство. Так что пойми с первого раза.
  • После назначения идентификатора экземпляра не изменяйте и не используйте его повторно в течение всего срока службы устройства. В противном случае вы вызовете эту ошибку или заставите IP-адреса подпрыгивать / сбрасываться. В конечном итоге ОС использует идентификатор экземпляра, чтобы выяснить, к какому порту сетевой карты привязать IP-адрес.
  • Подумайте о том, что произойдет, если кто-то подключит 2 ваших устройства к системе. Убедитесь, что ваш идентификатор экземпляра уникален для всех портов. Вы можете сделать это, закодировав в Instance ID серийный номер устройства PCI (если он есть) или обратившись к шине PCI:устройству:функции.
  • Не объединяйте различные типы оборудования под одним и тем же идентификатором оборудования. Например, если расширенная версия вашего устройства поддерживает разгрузку контрольной суммы, а обычная версия — нет, вам следует использовать 2 разных идентификатора оборудования для этих двух разных устройств. В противном случае будет сложно написать один INF, содержащий ключевые слова для обоих.
person Jeffrey Tippet    schedule 23.08.2017
comment
Я подтвердил, что Bus_PlugInDevice вызывается только дважды в Bus_DoStaticEnumeration. Однако ранее существовавшие PDO не отображаются в списке WdfFdoRetrieveNextStaticChild, поэтому создаются новые. Странные вещи в !pnptriage: InstancePath — это ROOT\MY_NIC_PORT\016777217 InstancePath — это ROOT\MY_NIC_PORT\5&1cb4661&79&016777217. Есть предположения? - person Dan; 24.08.2017
comment
Он вырвал весь мой код и вернулся к примеру StatBus. Причиной был ROOT\MY_NIC_PORT. Изменение ROOT на название компании исправило это. Джефф, ты прекрасен! Спасибо - person Dan; 24.08.2017