USBPcap прикрепляется как верхний фильтр для всех концентраторов корней. Он делает это, добавляя запись UpperFilters для класса {36FC9E60-C465-11CF-8056-444553540000}. Затем в функции AddDevice я получаю PDO и получаю список идентификаторов оборудования. Затем список проверяется на записи USB \ ROOT_HUB и USB \ ROOT_HUB20. Если он находится в списке, устройство считается Root Hub, иначе нет. Исходный код для функции выше доступен в github: https://github.com/desowin/usbpcap/blob/master/USBPcapDriver/USBPcapHelperFunctions.c#L725WDM: данное устройство FDO/PDO определяет, есть ли USB-корневой концентратор
Это решение не очень хорошо работает с USB 3.0 Root Hubs. Поскольку существует множество разных драйверов для контроллеров USB 3.0, плавающих вокруг, нет стандартной записи USB \ ROOT_HUB30. В основном каждый драйвер имеет свой собственный идентификатор оборудования. Я бы предпочел избегать составления списка идентификаторов оборудования для всех корневых концентраторов.
Я хотел бы знать, есть ли способ надежно определить, является ли устройство корневым центром, не полагаясь только на аппаратные идентификаторы.
Я думал о проверке наличия GUID_DEVINTERFACE_USB_HUB и его родительского GUID_DEVINTERFACE_USB_HOST_CONTROLLER, но я не знаю, как (и если) это можно сделать в режиме ядра внутри функции, вызванной обратным вызовом AddDevice.