Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Как заставить шину пересчитать дочерние устройства?  (Прочитано 10773 раз)
0 Пользователей и 1 Гость смотрят эту тему.
alex_alv
Гость
« : 25-02-2009 13:47 » 

Здравствуйте!

У меня есть PCI-утройство, в которое через саму шину заливается его принципиальная схема.
В результате, после заливки прошивки, устройство становится совсем другим (с другими VendorID и DeviceID).

Как можно заставить PnP manager отправть драйверу родительской шины запрос IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / BusRelations?

Единственный способ, который работает заключается в установке следующих DeviceCapabilities:
pdc->EjectSupported=1;
pdc->Removable=1;
pdc->SurpriseRemovalOK=1;

а после загрузки прошивки вызывать IoRequestDeviceEject(pdx->Pdo);

Способ отличный, но устройство появляется в списке устройств, которые можно безопасно извлечь. После выбора устройства в этом списке, оно, естественно, удаляется и вернуть его можно только перезагрузкой системы, а это не устраивает.
Блокировка удаления в запросе IRP_MN_QUERY_REMOVE_DEVICE дает результат, но после этого драйвер невозможно обновить без перезагрузки системы.

Все остальные способы (включая IoInvalidateDeviceRelations) требуют, чтобы у меня была ссылка на объект PDO самой шины, а не моего устройства. Способа получить этот PDO я не нашел.

Кто-нибудь знает, как решается данная проблема?

Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 26-02-2009 14:15 » 

а если по pdo->NextDevice до нуля пробежаться - это не оно будет?
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
alex_alv
Гость
« Ответ #2 : 26-02-2009 14:23 » 

Спасибо за ответ!
Но это - не оно увы. Этот путь приведет к верхнему драйверу в стеке моего устройства (IoGetAttachedDeviceReference делает то же самое плюс создает референс). Скорее всего, это будет FDO моего драйвера (или фильтр надо мной).

Нижний PDO моего стека у меня тоже есть.
Но мне нужен PDO или люблй FDO из стека шины, в которую вставлено мое устройство.

Можно по PDO моего стека получить драйвер шины (тот драйвер, который создал этот PDO).

По драйверу можно пробежаться по всем DO, которые им созданы.

Но во-первых, не понятно, как отличить PDO дочерних устройств от FDO самой шины.

А во-вторых, один драйвер может управлять сразу несколькими шиными. Соответственно, он создаст несколько FDO. Как отличить из них FDO именно той шины, в которую вставлено мое устройство - не понятно.

В-третьих, бегать по DEVICE_OBJECT чужого драйвера не очень правильно, так как я не могу засинхронизировать этот процесс с процессами создания/удаления DEVICE_OBJECT-ов.
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 26-02-2009 16:30 » 

Цитата
Но во-первых, не понятно, как отличить PDO дочерних устройств от FDO самой шины.
у него NextDevice нулевое - я бегал по списку в DeviceTree. а до этого как-то в софтайсе давно смотрел. нормальный метод...

DDK3790.1830\tools\devicetree\x86\

а насчет синхронизации... почему нельзя? увеличивать число ссылок на него и все. проверять и тут же удаляться...
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
alex_alv
Гость
« Ответ #4 : 26-02-2009 16:46 » 

NextDevice нулевое только у верхнего драйвера в стеке. Верхний драйвер не обязательно будет FDO.
Более того, даже PDO может быть верхним:
Если есть устройства, к которым не загружены драйверы, то у их PDO NextDevice будет нулевым.
Если над FDO есть фильтрующий драйвер, то его NextDevice НЕ будет нулевым.

Так что нулевое значение NextDevice не является признаком PDO это или FDO. Но тем не менее есть способ вычислить, что это - PDO или FDO.
Через запрос IRP_MN_QUERY_DEVICE_RELATIONS можно узнать PDO в стеке. Соответственно, сравнение с найденным объектом даст ответ - PDO это или FDO. Но этот способ не даст ответ, чей конкретно это FDO (см. мое "во-вторых").

На счет синхронизации - не все так просто.
Требуется ходить по объектам устройства, созданных конкретным драйвером. Для этого объект драйвера указывает на первый объект устройства, созданный им, а в каждом объекте устройства есть указатель на следующий созданный данным драйвером объект. В результате, мы получаем список объектов, который может все время меняться. И просто фиксация ссылки не дает требуемой синхронизации со списком объектов вцелом хотябы из-за того, что нельзя даже сказать на какой конкретно объект нужно зафиксировать референс.

Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #5 : 26-02-2009 16:50 » 

http://www.wasm.ru/article.php?article=drvw2k15
через реестр? хотя согласен, кривоватый метод...
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
alex_alv
Гость
« Ответ #6 : 26-02-2009 16:52 » 

Спасибо, я посмотрю сегодня (пока занят другим). Но боюсь, через реестр можно получить много информации, но только не PDO и FDO. Но я посмотрю позже
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #7 : 26-02-2009 16:55 » 

ага, про синхронизацию понял... тоже у Они прочитал)
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #8 : 26-02-2009 17:01 » 

и еще ода мысль... может быть покопать в сторону функций инсталяции?  типа DiInstallDevice?
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
alex_alv
Гость
« Ответ #9 : 26-02-2009 18:20 » 

На счет реестра.
Дерево устройств - то, что мне нужно. Если получить доступ к дереву устройств, можно выяснить, кто является родительским устройством для моего устройства.

Только реестр не содержит этого дерева. Дерево строится PNP менеджером динамически в памяти компьютера, а не в реестре. Реестр просто является базой данных, в которой PNP менеджер может найти информацию о том, какой драйвер нужно загрузить для данного устройства.

Мне сам драйвер не нужен. Мне нужен объект устройства конкретной шины, в которую вставлено устройство. Найдя драйвер (я его могу найти и без реестра, как я написал выше), я не смогу получить объекта устройства этой шины.
Объект устройства можно получить из дерева устройств. Доступ к этому дереву наверное возможен из приложения, но из драйвера я не нашел способа получить доступ к этой системе структур.

Кроме того, использование реестра - это подвязка под конкретную операционную систему. Не факт, что реестр одинаково устроен например, в висте и в XP.

На счет DiInstallDevice - похожая сиутация. Мне нужен указатель на объект устройства шины в момент работы драйвера, а не в момент установки драйвера.

На счет Они - я ему лично тоже задавал данный вопрос. Вот, что он мне ответил второй раз (первый он предложил использовать IoInvalidateDeviceRelations):

> I must call IoInvalidateDeviceRelations with PCI bus PDO but I can not get
> it, I have only PDO for my PCI device, not for PCI bus device

Ah. In that case, I don't know the answer.
Записан
alex_alv
Гость
« Ответ #10 : 26-02-2009 18:31 » 

P.S. он (Они) даже не смог ответить на вопрос, как в IRP_MJ_CREATE различить, по какому из интерфейсов происходит открытие устройства, если мой драйвер зарегистрировал два (или более) интерфейсов функцией IoRegisterDeviceInterface Улыбаюсь
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines