Сразу прошу прощение за ламерство: на сях не программирую и понятия о модели драйверов у меня пока что только зачаточные. Просто возникла одна проблема, которую я пытаюсь решить. Ее суть: Имеется некий драйвер-фильтр класса (lower filter). Судя по всему, не-WDM-ный. Он необходим для функционирования одной программы, чьи запросы через драйвер класса этот фильтр модифицирует при необходимости. Старая версия программы прекрасно работала в такой связке. Новая же версия также нормально работает, но только до запроса IRP_MJ_PNP/IRP_MN_QUERY_DEVICE_RELATIONS/TargetDeviceRelation (в старой версии проги его вообще не было). Далее начинаются чудеса, т.е. проблемы, заканчивающиеся постепенным зависанием компа (в течение 2-3-х секунд). Насколько я понимаю, по этому запросу ("Query Device Relations") прога (через свой драйвер) получает информацию о всех драйверах, входящих в данный стэк драйверов. Есть подозрение, что она пытается отключить все (в том числе и нужный мне) драйвер-фильтры. Но поскольку интересующий меня фильтр скорее всего не может быть подключен/отключен "на лету" (после инсталляции/денисталляции этого фильтра обязательно требуется перезагрузка), то насильственное его отключение и приводит к зависанию. Собственно, вопросы: Есть ли возможность скрыть нужный мне драйвер-фильтр ? Желательно, без его модификации (исходников нет и не предвидится). Сам он запрос "Query Device Relations" не обрабатывает, пропускает дальше (skipped), что, впрочем, вполне допустимо, судя по некоторым докам. Например, возможно ли ввести дополнительный lower драйвер-фильтр, который бы скрывал (удалял из запроса "Query Device Relations" соответствующую инфу) и себя, и все остальные фильтры (или только нужный мне) ? Можно ли сделать такой скрывающий драйвер-фильтр универсальным для различных стэков драйверов ? ( думаю, подключить его в нужное место при необходимости сам смогу, занеся соответствующие данные в реестр). Может такое чудо (или нечто подобное) уже существует в природе ? (у меня самого не хватит знаний такой продукт написать). Еще раз соори за нубизм. И заранее спасибо за все ответы и советы по теме.
Нет, там только указатель на PDO. Этот запрос все фильтры и FDO скипают, а PDO (самый нижний в стеке) обрабатывает его примерно так: Код (Text): NTSTATUS QueryRelations( PDEVICE_OBJECT pPDO, PIRP pIrp ) { NTSTATUS status = pIrp->IoStatus.Status; PIO_STACK_LOCATION pIoStack = IoGetCurrentIrpStackLocation( pIrp ); if ( TargetDeviceRelation == pIoStack->Parameters.QueryDeviceRelations.Type ) { PDEVICE_RELATIONS prel = (PDEVICE_RELATIONS) \ ExAllocatePool( PagedPool, sizeof(DEVICE_RELATIONS) ); if ( NULL == prel ) { status = STATUS_INSUFFICIENT_RESOURCES; } else { prel->Count = 1; // всегда 1 prel->Objects[0] = pPDO; // всегда указатель на PDO ObReferenceObject( pPDO ); pIrp->IoStatus.Information = (ULONG_PTR) prel; status = STATUS_SUCCESS; } } pIrp->IoStatus.Status = status; IoCompleteRequest( pIrp, IO_NO_INCREMENT ); return status; } Судя по всему проблема не в этом. Теоретически, можно сделать почти всё что угодно. Хотя описание достаточно подробное, но всё равно корень проблемы не виден. Я бы подключив отладчик и дизассемблер, попытался точно выяснить кто чего там у кого запрашивает и что после этого делает.
Four-F Спасибо огромное за ответ! Кое-что прояснилось. А вообще, существуют ли способы защитить драйвер-фильтры от преждевременной выгрузки ? К сожалению, отладчиками и дизассемблерами не владею. Пользуюсь IRPtrace'ом. Но и с его помощью, похоже, удалось выяснить виновника "исчезновения" фильтров: Похоже, один из двух драйверов, с которым работало приложение, как раз занимается отключением фильтров (аtksgt.sуs посредством Device Ctrl > IRP_MJ_DEVICE_CONTROL). Но вопрос, как с таким самоуправством бороться, пока остается без ответа... ЗЫ: Прикрепляю к посту полный достаточно подробный лог IRP-трэйса, мало ли кого заинтересует. ЗЗЫ: Что-то не прикрепляется. Скачать можно отсюда. (73кб)
Вобщем помочь тут сложно. Судя по логу, lirsgt и atksgt - это CDO (Control Device Object), которые создают драйверы lirsgt.sys и atksgt.sys, соответственно. Это так называемые legacy драйвера. Они создают один единственный Device Object, который болтается сам по себе. Это не фильтр, ни в какой стек он не садится и нужен для доступа user-mode приложения к ядру. Опять же судя по логу ( хотя судить тут о чём-либо очень трудно ), IRP_MN_QUERY_DEVICE_RELATIONS/TargetDeviceRelation появляется там из-за того, что приложение регисрируется на получение уведомления о PnP-related событиях. Registering for Device Notification http://msdn2.microsoft.com/en-us/library/aa363432.aspx Detecting Media Insertion or Removal http://msdn2.microsoft.com/en-us/library/aa363215.aspx Processing a Request to Remove a Device http://msdn2.microsoft.com/en-us/library/aa363427.aspx Вот такой вот код приведет к посылке IRP_MN_QUERY_DEVICE_RELATIONS/TargetDeviceRelation в стек флопа (можешь попробовать). Если заменить букву на соответствующую CD-ROM, то TargetDeviceRelation полетит в стек сидюка (как у тебя в логе). Код (Text): DEV_BROADCAST_HANDLE dbh; ZeroMemory( &dbh, sizeof(dbh) ); dbh.dbch_size = sizeof(DEV_BROADCAST_HANDLE); dbh.dbch_devicetype = DBT_DEVTYP_HANDLE; dbh.dbch_handle = CreateFile("\\\\.\\A:", GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); dbh.dbch_hdevnotify = RegisterDeviceNotification( hWnd, &dbh, DEVICE_NOTIFY_WINDOW_HANDLE ); Дальше идет какой-то обмен IRP_MJ_DEVICE_CONTROL с lirsgt и atksgt и чтение цд-рома. Вот собственно и всё. Что там происходит дальше - хз. Так что IRP_MN_QUERY_DEVICE_RELATIONS/TargetDeviceRelation сам по себе тут наверное не при чём. Проблема в последствиях. А возможно TargetDeviceRelation вообще не имеет никакого отношения к проблеме. В таком случае, шансы на успех предприятия, IMHO, стремяться к 0
Four-F То что эти драйвера -- не фильтры, понятно (т.к. через них не проходил ни один запрос к сидирому). Фильтр в примере был один: imapi. И его бесцеремонно отключили. Вот это уже интересно. Т.е. все махинации приложения с чужими драйверами проходят через эти два драйвера, если я правильно понял. Еще вчера хотел убрать IRP_MN_QUERY_DEVICE_RELATIONS из названия темы. Но такая возможность у движка форума отсутствует. Вопрос можно поставить более общё: Можно ли какими-либо средствами (лучше стандартными) воспрепятствовать исключению драйвер-фильтра из стека драйверов ? ( *скрыть его каким-нибудь образом *запретить другим драйверам отключать его *разработать доп драйвер, который обратно подключал бы только-что отключенный фильтр ). Ну, я подозревал это. В принципе, можно перенести топик в раздел "для начинающих". Если кому-то все же захочется разобраться, как же все-таки приложению удается отключить драйвер-фильтры и можно ли этому воспрепятствовать, то могу выслать нужные файлы по мылу (~8мб). Может поможете найти противоядие...
Единственное, что можно сказать - они нужны приложению для получения какой-либо специфической инфы или манипуляций, а что именно - хз. Никаких стандартных средств против исключения фильтра из стека нет.
Four-F Спасибо за ответы. И за долготерпение. Получается, что единственный способ избежать отключения драйвера-фильтра -- внедрить его функции в основной драйвер (класса/шины) ? Мдя, а для этого нужно иметь как минимум все их исходники... ЗЫ: Очередной глупый вопрос: Может возможно (хотя бы теоретически) из двух образов драйверов (основного и фильтра, предназначенного для него) скомпоновать один ? (не имея исходников и не прибегая к дизассемблированию) Например, создать некий псевдодрайвер-оболочку, который для системы будет видеться как основной драйвер (класса, например), но который будет передавать IRP-пакеты на обработку сначала настоящему основному драйверу, а затем его фильтру. А итоговый результат продвигать дальше по стеку драйверов. Только не смейтесь.
Смотрю лог того же irptrace'a - при подключении устройства драйвер-фильтр получает только запросы IRP_MN_QUERY_DEVICE_RELATIONS. Запросы IRP_MN_QUERY_ID, IRP_MN_QUERY_DEVICE_TEXT поступают только при старте винды. Соответствующий вопрос: как можно отловить идентификационную строку устройства (например, "USB FlashDrive Silicon Power") при его подключении?[/