Запрет/удаление устройства с не-PnP фильтром
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 04.02.20 13:19
Оценка:
Есть у меня фильтр для слежения за обменом с PnP-устройствами. Сделан в виде legacy-драйвера, который получает уведомления о новых интерфейсах через IoRegisterPlugPlayNotification, садится на стек через IoAttachDeviceToDeviceStack, и отсоединяется по IRP_MN_REMOVE_DEVICE.

С динамически отключаемыми устройствами (например, USB) все работает прекрасно — и при обычном ручном удалении, и при surprise removal, и при запрете устройства в Device Manager, вся цепочка IRP_MJ_PNP проходит нормально, и мой фильтр отсоединяется после возврата из IRP_MN_REMOVE_DEVICE.

А с "фиксированными" (например, PCI) устройствами отключение работает только по инициативе самого фильтра. Если попытаться запретить устройство в DM, то на IRP_MN_QUERY_REMOVE_DEVICE откуда-то снизу стека возвращается STATUS_DEVICE_BUSY, и до IRP_MN_REMOVE_DEVICE даже не доходит. Устройство не меняет состояния, в слове флагов выставляется NEED_RESTART, и даже после ручного отсоединения фильтра не удается устройство запретить.

Смотрел ReferenceCount в DEVICE_OBJECT — везде одни нули. То есть, все ссылки регистрируются только на уровне универсальных объектов (OBJECT_HEADER), но там их явно больше одной, и вряд ли решение принимается по этому параметру.

Само по себе наличие фильтра над объектом устройства тоже не беда — через UpperFilters/LowerFilters они навешиваются точно так же, но это не препятствует запрету устройства в любой момент, с отсоединением всех фильтров.

Какие особенности "фиксированных" устройств могут удерживать их от запрета при наличии фильтра в стеке? И что может залипать в стеке или узле устройства, что после неудачной попытки запрета и последующего отсоединения фильтра, уже не удается вернуть устройству возможность запрета до перезагрузки?
device filter ioattachdevice ioattachdevicetodevicestack removable irp_mn_remove_device irp_mn_query_remove_device status_device_busy
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.