Перевести драйвер на WDM с IoRegisterDeviceInterface
От: Alexiski  
Дата: 16.08.05 09:04
Оценка:
Есть legacy драйвер, ни к какому железу не привязанный. Соответственно, устанавливается и стартует через SCManager, после чего прямо в DriverEntry создается FDO и SymbolicLink к нему. Все работает.

Возникла необходимость перехода на WDM с использованием интерфейса. Выползли проблемы:

1) При попытке выполнить IoRegisterDeviceInterface прямо на FDO — недопустимая операция с устройством (правильно, так и должно быть, судя по раскопкам этот путь в корне неверный, привожу только для полноты картины)
2) При попытке найти какой-нибудь левый PDO и подключиться к нему — та же картина. Вопрос: Можно ли найти и использовать левый PDO ?
3) При попытке сделать как положено, т. е. вынести создание устройства в AddDevice — AddDevice не вызывается, драйвер не запускается с сообщением "все устройства, связанные с данной службой остановлены". Вопрос: Как заставить вызываться AddDevice ?

PS. Можно ли обойти указанные проблемы, если устанавливать драйвер через inf ? Там, вроде, можно прописать интерфейсы сразу. Но избавит ли это от вызова IoRegisterDeviceInterface ?
Re: Перевести драйвер на WDM с IoRegisterDeviceInterface
От: straightener Россия  
Дата: 16.08.05 09:52
Оценка:
Здравствуйте, Alexiski, Вы писали:

A>Есть legacy драйвер, ни к какому железу не привязанный. Соответственно, устанавливается и стартует через SCManager, после чего прямо в DriverEntry создается FDO и SymbolicLink к нему. Все работает.


A>Возникла необходимость перехода на WDM с использованием интерфейса. Выползли проблемы:


A>1) При попытке выполнить IoRegisterDeviceInterface прямо на FDO — недопустимая операция с устройством (правильно, так и должно быть, судя по раскопкам этот путь в корне неверный, привожу только для полноты картины)

При регистрации интерфейса в девноде проверяется флаг DNF_LEGACY_RESOURCE_DEVICENODE (или DNF_LEGACY_DRIVER, точно не помню, но это не важно), следовательно для legacy-драйвера интерфейс зарегистрировать нельзя.
A>2) При попытке найти какой-нибудь левый PDO и подключиться к нему — та же картина. Вопрос: Можно ли найти и использовать левый PDO ?
Этот как же Вы ищете "левый" PDO, расскажите пожалуйста? Но даже если на секунду предположить, что использовался чужой PDO, то следует учесть, что "имя" интерфейса и симлинк содержат компоненты InstancePath (лежит в девноде, указатель на которую есть в PDO) и результат может Вас сильно озадачить Следовательно, забыть эту ересь! (Хотя в системе иногда существуют неиспользуемые более PDO, но это скорее баг, а не фича и использование ее — это путь самурая Неуловимого Джо (т.е. сложно и совершенно не нужно)
A>3) При попытке сделать как положено, т. е. вынести создание устройства в AddDevice — AddDevice не вызывается, драйвер не запускается с сообщением "все устройства, связанные с данной службой остановлены". Вопрос: Как заставить вызываться AddDevice ?
Вам нужно превратить свой legacy драйвер в root-enumerated, тогда pnp менеджер "примет его за своего" и любезно создаст PDO, который будет только Ваш и больше ничей, и AddDevice начнет вызываться со страшной силой Пример такого драйвера — busenum от тостера, он root-enumerated, правда сам является енумератором, т.е. содержит много лишнего для Вас кода, но я думаю Вы справитесь с его анализом. Особое внимание уделите его установке и структуре инфа, я уверен на 90%, что Ваши сложности из-за неправильной установки.
Последнее дополнение: поскольку ваш девайс становится плагнплэйным не забудьте реализовать поддержку хотя-бы IRP_MJ_PNP.

A>PS. Можно ли обойти указанные проблемы, если устанавливать драйвер через inf ?

Да, но не в том смысле, который Вы подразумеваете.
A> Там, вроде, можно прописать интерфейсы сразу. Но избавит ли это от вызова IoRegisterDeviceInterface ?
Видимо избавит (ни разу не регистрировал интерфейсы из инфа), но IoSetDeviceInterfaceState (симлинк создается в результате этого вызова) за вас никто делать не будет.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Re[2]: Перевести драйвер на WDM с IoRegisterDeviceInterface
От: straightener Россия  
Дата: 16.08.05 10:30
Оценка:
S>При регистрации интерфейса в девноде проверяется флаг DNF_LEGACY_RESOURCE_DEVICENODE (или DNF_LEGACY_DRIVER, точно не помню, но это не важно), следовательно для legacy-драйвера интерфейс зарегистрировать нельзя.
Маленькая поправка: Ваш девайс вообще не имеет девноды, поэтому даже до проверки флагов не дойдет, раньше рюхнется. Кстати, и PDO и девнода для legacy драйвера все же создается, но достать ее проблематично, т.к. такой сценарий их использования системой не предусмотрен.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Re: Перевести драйвер на WDM с IoRegisterDeviceInterface
От: Maxim S. Shatskih Россия  
Дата: 17.08.05 08:18
Оценка:
Здравствуйте, Alexiski, Вы писали:

A>Есть legacy драйвер, ни к какому железу не привязанный. Соответственно, устанавливается и стартует через SCManager, после чего прямо в DriverEntry создается FDO и SymbolicLink к нему. Все работает.

A>Возникла необходимость перехода на WDM с использованием интерфейса.

Зачем. Переносить такой драйвер на WDM — как правило глупость, от излишне чешущихся рук у PMов. Он и без WDM нормально работать будет.

Может, еще и INF файл к этому драйверу писать?

Да, кстати. PDO создаются на лету вызовом IoReportDetectedDevice со всеми нулями и NULLами в параметрах.
Занимайтесь LoveCraftом, а не WarCraftом!
Re[3]: Перевести драйвер на WDM с IoRegisterDeviceInterface
От: Maxim S. Shatskih Россия  
Дата: 17.08.05 08:24
Оценка:
Совершенно верно. IoRegisterDeviceInterface требует PDO, коего у legacy драйвера нет по определению.

PDO получается двумя способами:
а) возврат указателя на устройство в ответе на MN_QUERY_RELATIONS/BusRelations
б) IoReportDetectedDevice (для software-only устройств — в параметры передать все нули). Такой вызов создаст временный PDO "на лету".

Путь а) требует bus driverа, который бы такое сделал. Практически все bus drivers в системе — строят этот ответ на основне инфы, снятой с железа. Единственное (почти что) исключение — это root enumerator, который перечисляет ноды в реестре. Ноду можно создать вызовом SetupDiCreateDeviceInstance (кажется, он так назывался), или же установив INF.

Еще раз — делать такое для software-only модуля вряд ли оправдано. Одна лишь необходимость INF файла — та еще радость. Неоправданное усложнение задачи, оно же "овердизайн".

S>Маленькая поправка: Ваш девайс вообще не имеет девноды, поэтому даже до проверки

>флагов не дойдет, раньше рюхнется. Кстати, и PDO и девнода для legacy драйвера

А можно доказательство этого утверждения — с помощью WinDbg, WinObj или тому подобных тулов?

Легаси драйвер вообще не имеет отношения ни к PnP, ни к power management.
Занимайтесь LoveCraftом, а не WarCraftом!
Re[2]: Перевести драйвер на WDM с IoRegisterDeviceInterface
От: Аноним  
Дата: 17.08.05 09:08
Оценка:
Здравствуйте, Maxim S. Shatskih, Вы писали:

MSS>Зачем. Переносить такой драйвер на WDM — как правило глупость, от излишне чешущихся рук у PMов. Он и без WDM нормально работать будет.


Это часть большого проекта, где присутствуют реальные драйвера реального железа. А сей драйвер — в некотором роде их программный эмулятор для некоторых режимов работы. Проект уже переполз на WDM, весь прикладной софт работатет через интерфейсы, деваться некуда — нужно реализовывать интерфейс. Кстати, я не думал, что это будет так сложно по сравнению с символической ссылкой.

MSS>Может, еще и INF файл к этому драйверу писать?


Вот не хотелось бы.. Но в принципе — почему бы нет ?

MSS>Да, кстати. PDO создаются на лету вызовом IoReportDetectedDevice со всеми нулями и NULLами в параметрах.


Вот этот путь представляется наиболее перспективным. Сейчас пойду проверять.
Есть ли тут какие-нибудь подводные камни ?
Re[4]: Перевести драйвер на WDM с IoRegisterDeviceInterface
От: straightener Россия  
Дата: 17.08.05 09:25
Оценка:
Здравствуйте, Maxim S. Shatskih, Вы писали:

MSS>Совершенно верно. IoRegisterDeviceInterface требует PDO, коего у legacy драйвера нет по определению.


MSS>PDO получается двумя способами:

MSS>а) возврат указателя на устройство в ответе на MN_QUERY_RELATIONS/BusRelations
MSS>б) IoReportDetectedDevice (для software-only устройств — в параметры передать все нули). Такой вызов создаст временный PDO "на лету".
Точно, вариант о котором я забыл. Спасибо, напомнили. Фактически создает root-enumerated device.

MSS>Путь а) требует bus driverа, который бы такое сделал. Практически все bus drivers в системе — строят этот ответ на основне инфы, снятой с железа. Единственное (почти что) исключение — это root enumerator, который перечисляет ноды в реестре. Ноду можно создать вызовом SetupDiCreateDeviceInstance (кажется, он так назывался), или же установив INF.

В результате все сведется к NtPlugPlayControl, с кодом InitializeDevice и InstancePath в качестве параметра (о проблемах непосредственного использования данной функции я осведомлен)

MSS>Еще раз — делать такое для software-only модуля вряд ли оправдано. Одна лишь необходимость INF файла — та еще радость. Неоправданное усложнение задачи, оно же "овердизайн".



S>>Маленькая поправка: Ваш девайс вообще не имеет девноды, поэтому даже до проверки

>>флагов не дойдет, раньше рюхнется. Кстати, и PDO и девнода для legacy драйвера

MSS>А можно доказательство этого утверждения — с помощью WinDbg, WinObj или тому подобных тулов?

!devnode 0 1
Dumping IopRootDeviceNode (= 0x89504ee0)
DevNode 0x89504ee0 for PDO 0x89504020
InstancePath is "HTREE\ROOT\0"
State = DeviceNodeStarted (0x308)
Previous State = DeviceNodeEnumerateCompletion (0x30d)
.bla
.bla
.bla
DevNode 0x8953e008 for PDO 0x89504170
InstancePath is "Root\LEGACY_BEEP\0000"
ServiceName is "Beep"
State = DeviceNodeStarted (0x308)
Previous State = DeviceNodeEnumerateCompletion (0x30d)

формальная нода. Статус ее исправно возвращается, регистрация с ее помощью делается, т.е. она даже не совсем мертвенькая
MSS>Легаси драйвер вообще не имеет отношения ни к PnP, ни к power management.
ну тут можно придраться — см. выше + можно поспорить, где кончается юрисдикция io менеджера и начинается pnp (Шютка с долей серьезности)
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Re[3]: Перевести драйвер на WDM с IoRegisterDeviceInterface
От: straightener Россия  
Дата: 17.08.05 09:39
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Здравствуйте, Maxim S. Shatskih, Вы писали:


MSS>>Может, еще и INF файл к этому драйверу писать?


А>Вот не хотелось бы.. Но в принципе — почему бы нет ?

Лучше бы да Хотя тут пробегала последовательность вызова SetupDi* для создание root-enumerated девайсов.

MSS>>Да, кстати. PDO создаются на лету вызовом IoReportDetectedDevice со всеми нулями и NULLами в параметрах.


А>Вот этот путь представляется наиболее перспективным. Сейчас пойду проверять.

На мой взгляд перспективности особой нет, просто еще один не лучший способ создать root-enumerated device.
А>Есть ли тут какие-нибудь подводные камни ?
Внимательное чтение Comments для этой функции избавит от большинства из них. А также несколько испортит впечатление о перспективности.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Re[3]: Перевести драйвер на WDM с IoRegisterDeviceInterface
От: Maxim S. Shatskih Россия  
Дата: 17.08.05 10:06
Оценка:
А>Это часть большого проекта, где присутствуют реальные драйвера реального железа. А сей драйвер — в некотором роде их программный эмулятор для некоторых режимов работы. Проект

Тогда — root-enumerated devnode. Как сделать — см. Toaster. Про IoReportDetectedDevice забудем.
Занимайтесь LoveCraftом, а не WarCraftом!
Re[5]: Перевести драйвер на WDM с IoRegisterDeviceInterface
От: Maxim S. Shatskih Россия  
Дата: 17.08.05 10:12
Оценка:
S>Точно, вариант о котором я забыл. Спасибо, напомнили. Фактически создает root-
>enumerated device.

Ага, временную только, и ключ в реестре у нее становится волатильный вроде как.

S>!devnode 0 1

S>Dumping IopRootDeviceNode (= 0x89504ee0)

Праматерь всего PnPшного дерева.

При чем тут legacy модули? они вообще не имеют отношения к PnPшному дереву.
Занимайтесь LoveCraftом, а не WarCraftом!
Re[4]: Перевести драйвер на WDM с IoRegisterDeviceInterface
От: Maxim S. Shatskih Россия  
Дата: 17.08.05 10:13
Оценка:
S>Внимательное чтение Comments для этой функции избавит от большинства из них. А также

IoReportDetectedDevice используется (насколько я помню) volume managerами для создания девнод \Device\HarddiskVolume%d.
Занимайтесь LoveCraftом, а не WarCraftом!
Re[6]: Перевести драйвер на WDM с IoRegisterDeviceInterface
От: straightener Россия  
Дата: 17.08.05 10:36
Оценка:
Здравствуйте, Maxim S. Shatskih, Вы писали:

S>>Точно, вариант о котором я забыл. Спасибо, напомнили. Фактически создает root-

>>enumerated device.

MSS>Ага, временную только, и ключ в реестре у нее становится волатильный вроде как.

Хм, точно не знаю пока, но фраза в комментах:

Drivers only need to call IoReportDetectedDevice the first time they are loaded because the PnP Manager caches the reported information. Drivers that use this routine should store a flag in the registry to indicate whether or not they have already done device detection.

Говорит, что keynode остается жить до принудительного убиения и при следующем буте root-enumerator создаст девайс сам.

S>>!devnode 0 1

S>>Dumping IopRootDeviceNode (= 0x89504ee0)

MSS>Праматерь всего PnPшного дерева.


MSS>При чем тут legacy модули? они вообще не имеют отношения к PnPшному дереву.

!devnode 0 1 показывает devtree я конечно мог бы засандалить сюда весь вывод этой команды, но решил ограничиться двумя записями. Повторяю:
Dumping IopRootDeviceNode (= 0x89504ee0)
DevNode 0x89504ee0 for PDO 0x89504020
InstancePath is "HTREE\ROOT\0"
State = DeviceNodeStarted (0x308)
Previous State = DeviceNodeEnumerateCompletion (0x30d)
.bla
.bla
.bla
DevNode 0x8953e008 for PDO 0x89504170
InstancePath is "Root\LEGACY_BEEP\0000"
ServiceName is "Beep"
State = DeviceNodeStarted (0x308)
Previous State = DeviceNodeEnumerateCompletion (0x30d)

Последняя нода для драйвера beep, она является дитем рутовой ноды, если смущает рутовая нода я ее могу убрать...
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Re[4]: Перевести драйвер на WDM с IoRegisterDeviceInterface
От: straightener Россия  
Дата: 17.08.05 10:36
Оценка:
Здравствуйте, Maxim S. Shatskih, Вы писали:

А>>Это часть большого проекта, где присутствуют реальные драйвера реального железа. А сей драйвер — в некотором роде их программный эмулятор для некоторых режимов работы. Проект


MSS>Тогда — root-enumerated devnode. Как сделать — см. Toaster. Про IoReportDetectedDevice забудем.

И тут мы снова вернулись к тостеру.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Re[7]: Перевести драйвер на WDM с IoRegisterDeviceInterface
От: Maxim S. Shatskih Россия  
Дата: 17.08.05 10:51
Оценка:
S>Drivers only need to call IoReportDetectedDevice the first time they are loaded because the PnP Manager caches the reported information. Drivers that use this routine should store a flag in the registry to indicate whether or not they have already done device detection.

Это если в параметрах не NULL, т.е. если указаны хардварные ресурсы.

S>[b] DevNode 0x8953e008 for PDO 0x89504170

S> InstancePath is "Root\LEGACY_BEEP\0000"

Ну, возможно. Правда, я не верю, что этот "для порядку" созданный объект хоть как-то связан с реальным драйвером beep.
Занимайтесь LoveCraftом, а не WarCraftом!
Re[8]: Перевести драйвер на WDM с IoRegisterDeviceInterface
От: straightener Россия  
Дата: 17.08.05 12:36
Оценка:
Здравствуйте, Maxim S. Shatskih, Вы писали:

S>>Drivers only need to call IoReportDetectedDevice the first time they are loaded because the PnP Manager caches the reported information. Drivers that use this routine should store a flag in the registry to indicate whether or not they have already done device detection.


MSS>Это если в параметрах не NULL, т.е. если указаны хардварные ресурсы.

Да пофиг ресурсы, кейнода останется все равно (CreateOptions=0 в ZwCreateKey, проверено)

S>>[b] DevNode 0x8953e008 for PDO 0x89504170

S>> InstancePath is "Root\LEGACY_BEEP\0000"

MSS>Ну, возможно. Правда, я не верю, что этот "для порядку" созданный объект хоть как-то связан с реальным драйвером beep.

Драйвер может быть даже задизейблин, а нода все равно создастся.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Re: Перевести драйвер на WDM с IoRegisterDeviceInterface
От: Alexiski  
Дата: 17.08.05 22:42
Оценка:
Спасибо всем откликнувшимся, все заработало.

Пробовал через IoReportDetectedDevice — действительно, информация нежелательно сохраняется, после перезагрузки система принялась искать драйвер устройства. В конечном итоге написал inf.

Неудобно только, что я не могу теперь этот драйвер программно остановить/запустить. Пришлось сделать дополнительный интерфейс, а через него включать/выключать основной.
Re[2]: Перевести драйвер на WDM с IoRegisterDeviceInterface
От: straightener Россия  
Дата: 18.08.05 08:52
Оценка:
Здравствуйте, Alexiski, Вы писали:

A>Пробовал через IoReportDetectedDevice — действительно, информация нежелательно сохраняется, после перезагрузки система принялась искать драйвер устройства. В конечном итоге написал inf.

Интересно, кому я говорил внимательно читать комментарии к функции?
A driver writer must provide an INF file that matches any of the specified hardware IDs or compatible IDs. The INF file should specify the original driver that called IoReportDetectedDevice as the driver to load for those IDs. The system uses this information to rebuild the driver stack for the device, for example on restart.

A>Неудобно только, что я не могу теперь этот драйвер программно остановить/запустить. Пришлось сделать дополнительный интерфейс, а через него включать/выключать основной.

А enable/disable девайса использовать не кошерно? Стоит покурить функции SetupDi*, а конкретней, кажися, SetupDiChangeState, точно не помню...
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Re[3]: Перевести драйвер на WDM с IoRegisterDeviceInterface
От: Maxim S. Shatskih Россия  
Дата: 18.08.05 09:03
Оценка:
S>А enable/disable девайса использовать не кошерно? Стоит покурить функции SetupDi*, а конкретней, кажися, SetupDiChangeState, точно не помню...

SetupDiCallClassInstaller с правильным кодом операции. Пример есть, называется DEVCON — это command-line Device Manager.
Занимайтесь LoveCraftом, а не WarCraftом!
Re[4]: Перевести драйвер на WDM с IoRegisterDeviceInterface
От: straightener Россия  
Дата: 18.08.05 09:41
Оценка:
Здравствуйте, Maxim S. Shatskih, Вы писали:

S>>А enable/disable девайса использовать не кошерно? Стоит покурить функции SetupDi*, а конкретней, кажися, SetupDiChangeState, точно не помню...


MSS>SetupDiCallClassInstaller с правильным кодом операции. Пример есть, называется DEVCON — это command-line Device Manager.

Знаем, знаем, много кода было передрано с него. А код DIF_PROPERTYCHANGE (SetupDiChangeState его default handler).
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.