chesland
Интересующийся
Offline
|
|
« : 27-12-2010 19:36 » |
|
Собрал USB-устройство на PIC18F2550. Написал к нему драйвер под WinXPx32(не полный, но рабочий)- работает(устройство определяется, конфигурируется, обменивается данными по VENDOR). Проблема заключается в том, что под Win7x32 драйвер не запускается. Устанавливается, проходит конфигурирование, установку интерфейса... а потом установка останавливается минут на 5-10 и затем получаю сообщение типа:"windows обнаружила драйверы для устройства, но в процессе установки произошла ошибка. Устройство не может быть запущено."
Уважаемые дровописатели! Помогите чайнику. Это мой первый драйвер и первое USB-устройство. Что из них не работает, я не знаю. Но похоже, что драйвер. Т.к. устройство работает только по 0-вой конечной точке, но после установки интерфейса в USB-модуле не происходит никаких прерываний(т.е. компьютер не отсылает никаких запросов).
|
|
« Последнее редактирование: 28-12-2010 04:38 от RXL »
|
Записан
|
|
|
|
supermaxus
Участник
Offline
|
|
« Ответ #1 : 27-12-2010 19:51 » |
|
Слышал, что начиная с win7 драйверы, вроде, надо подписывать ЭЦП. Мож в этом дело? В любом случае, Вам не помешает понять, оно тупит до входа в driverEntry, или после (см. в свой лог/отладчик)? Если до, то дело может быть и в ЭЦП, если после - см. ошибку в отладчике.
|
|
|
Записан
|
|
|
|
chesland
Интересующийся
Offline
|
|
« Ответ #2 : 27-12-2010 20:14 » |
|
дело в том, что в DriverEntry входит. Успешно передается управление моему драйверу. Я из драйвера запрашиваю DEVICE_DESCRIPTOR, CONFIGURATION_DESCRIPTOR(и получаю все это). Выполняю SELECT_INTERFACE - успешно(USB-устройство получает и отдает положительный ответ). Т.е. получается, что УСТРОЙСТВО - сконфигурировано. Зависает на последующих операциях(не моих - виндовых). Винда отсылает запрос:IRP_MN_QUERY_DEVICE_RELATIONS - и в Win7x32 похоже что не получает на него ответа, хотя в WinXP - проходит без вопросов. Она шлет этот запрос несколько раз(это из отладчика), затем бросает это гиблое дело и шлет другой запрос:IRP_MN_QUERY_CAPABILITIES не дождавшись ответа - повторяет эту последовательность несколько раз, а затем(вспомнил) - говорит, что установка прервана из-за превышения времени ожидания. Драйвер, кстати, висит в Диспетчере, но к устройству обратиться нельзя - "невозможно открыть устройство"
|
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #3 : 27-12-2010 20:43 » |
|
а какие еще к вам IRP последними приходят? обработчик IRP у вас реентернабельный? насчет "последующих операциях"- не понял, вы где эти IRP_MN_QUERY_DEVICE_RELATIONS отловили, когда дальше по стеку в своем драйвере передаете? какой у него тип в Type?
PS семерка возможно более строго подходит к обработки IRP и не прощает то что сходило с рук в XP...
|
|
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
chesland
Интересующийся
Offline
|
|
« Ответ #4 : 27-12-2010 21:28 » |
|
После того, как я из драйвера выполняю SELECT_INTERFACE - я выхожу, считая что устройство сконфигурировано. Но Винда в этот момент продолжает слать запросы: в WinXPx32 это: IRP_MN_QUERY_CAPABILITIES; IRP_MN_QUERY_DEVICE_RELATIONS; после этих двух запросов Виндовс бросает заниматься моим драйвером и я могу из внешнего приложения обратиться к своему устройству( открываю CreateFile, читаю - ReadFile, пишу WriteFile и закрываю CloseHandle). в Win7x32 происходит так: после SELECT_INTERFACE (устройство сконфигурировано) винда шлет запросы(даю почти копию из отладчика): 1.IRP_MN_QUERY_CAPABILITIES; 2.IRP_MN_QUERY_DEVICE_RELATIONS; 3.IRP_MN_QUERY_DEVICE_RELATIONS; 4.IRP_MN_QUERY_DEVICE_RELATIONS; 5.IRP_MN_QUERY_DEVICE_RELATIONS; 6.IRP_MN_QUERY_CAPABILITIES; 7.IRP_MN_QUERY_DEVICE_RELATIONS; 8.IRP_MN_QUERY_DEVICE_RELATIONS; 9.IRP_MN_QUERY_DEVICE_RELATIONS; 10.IRP_MN_QUERY_DEVICE_RELATIONS; 11.IRP_MN_QUERY_CAPABILITIES; 12.IRP_MN_QUERY_CAPABILITIES; 13.IRP_MN_QUERY_CAPABILITIES;
"обработчик IRP у вас реентернабельный?" - не понимаю вопроса. Что такое "реентернабельный"?
"где эти IRP_MN_QUERY_DEVICE_RELATIONS отловили?" Эти запросы отсылает PnP-менеджер - в пакете IRP: MajorFunction-[IRP_MJ_PNP] MinorFunction-[IRP_MN_QUERY_DEVICE_RELATIONS] или [IRP_MN_QUERY_CAPABILITIES];
Отлавливаю в функции обработки PnP-запросов по "default" вот текст: ............................................ pdx=(PDEVICE_EXTENSION) fdo->DeviceExtension; irpStack=IoGetCurrentIrpStackLocation(Irp); minorFunc=irpStack->MinorFunction;
switch(minorFunc) { case IRP_MN_START_DEVICE://=0x00 ........................................... break; case IRP_MN_REMOVE_DEVICE://=0x02 ........................................... break; case IRP_MN_STOP_DEVICE://=0x04 ........................................... break; default:// IoSkipCurrentIrpStackLocation(Irp); ntStatus=IoCallDriver(pdx->NextStackDevObj,Irp); break; } return ntStatus;
"семерка возможно более строго подходит к обработки IRP и не прощает то что сходило с рук в XP..." совершенно с вами согласен, вот это как раз и хотелось бы выяснить. Но дело в том, что у меня есть пример устройство(Atmega8)+driver(AVR309) "Igor Chesco" - там аналогичный текст - и представьте себе - все работает(под Win7 в том числе). А у меня под Win7 - не работает. Кстати у него("Igor Chesco") после конфигурирования устройства виндовые запросы выглядят так: 1.IRP_MN_QUERY_CAPABILITIES; 2.IRP_MN_QUERY_DEVICE_RELATIONS; и все!!!!
|
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #5 : 27-12-2010 21:50 » |
|
реентернабельные - в том смысле что допустим повторный вход в процедуру. при обработке IRP это помоему бывает: в обработчике IRP вы вызываете функцию ядра, управление она еще не вернула, но к вам приходит еще один запрос на обработку IRP. то есть в стеке вызовов "ваш код"->"ядро"->"ваш код"... хотя навряд ли в этом дело... но гляньте повнимательней, на всякий пожарный. постараюсь (но не обещаю...) глянуть на работе что у меня по ним творится. хотя у меня не USB но... еще попробуйте глянуть в сторону Device Power Capabilities. ...а вот нашел. у меня несколько иначе. NTSTATUS _CompletionRoutine( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context) { PKEVENT event;
event = (PKEVENT) Context; if (Irp->PendingReturned) KeSetEvent(event, 0, FALSE);//по XP // // We could switch on the major and minor functions of the IRP to perform // different functions, but we know that Context is an event that needs // to be set. // //KeSetEvent(event, 0, FALSE);//было в 2000 // // Allows the caller to reuse the IRP // return STATUS_MORE_PROCESSING_REQUIRED; UNREFERENCED_PARAMETER(DeviceObject); }
SendIrpSynchronously( IN PIRP Irp, IN PDEVICE_OBJECT LowerDevice) { DWORD status; KEVENT event; KeInitializeEvent( &event, NotificationEvent, FALSE);
IoCopyCurrentIrpStackLocationToNext(Irp);
IoSetCompletionRoutine( Irp, _CompletionRoutine, &event, TRUE,TRUE,TRUE);
status = IoCallDriver(LowerDevice, Irp);
if (STATUS_PENDING == status) { KeWaitForSingleObject( &event, Executive, // Waiting for reason of a driver KernelMode, // Must be kernelmode if event memory is in stack FALSE, // No allert NULL); // No timeout status = Irp->IoStatus.Status; }; return status; }
................... case IRP_MN_QUERY_CAPABILITIES:
// Check the device capabilities struct deviceCapabilities = irpStack->Parameters.DeviceCapabilities.Capabilities;
if (deviceCapabilities->Version != 1 || deviceCapabilities->Size < sizeof(DEVICE_CAPABILITIES)) { // We don't support this version. Fail the request break; }
// Pass the IRP down status = SendIrpSynchronously(Irp, devExt->LowerDeviceObject);
// Lower drivers have finished their operation, so now // we can finish ours. if (NT_SUCCESS(status)) { //***************************************************************** //***************************************************************** // TODO: Override the device capabilities // set by the underlying drivers here. //***************************************************************** //***************************************************************** }
Irp->IoStatus.Status = status; IoCompleteRequest (Irp, IO_NO_INCREMENT); return status;
default: // Pass down all the unhandled Irps. // IoSkipCurrentIrpStackLocation (Irp); status = IoCallDriver(devExt->LowerDevice, Irp); return status; };
|
|
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
resource
Молодой специалист
Offline
Пол:
|
|
« Ответ #6 : 27-12-2010 21:54 » |
|
chesland, интересно кем, и с каким статусом завершаются все эти 13 ирпов
|
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #7 : 27-12-2010 21:57 » |
|
кстати да))) особенно - кем)
|
|
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
chesland
Интересующийся
Offline
|
|
« Ответ #8 : 27-12-2010 22:09 » |
|
"реентернабельные - в том смысле что.............. " - спасибо за объяснение - я понял, что это такое. "попробуйте глянуть в сторону Device Power Capabilities" - ни одного Виндового запроса "Power"(отлавливаю все) в отладчике не видел(ни у себя ни в примере "Igor Chesco"). Я их не отсылаю... Не думаю, что в этом дело... " в стеке вызовов "ваш код"->"ядро"->"ваш код"..." - такая ситуация у меня возможна(я об этом думал), но не знаю, что при этом может произойти. Если не затруднит, поясните вкратце последствия такого события. Может это как раз ОНО!!! Добавлено через 7 минут и 33 секунды:chesland, интересно кем, и с каким статусом завершаются все эти 13 ирпов
Я еще не работал над этим. Несколько дней назад, наконец, запустил свой драйвер+устройство под WinXP - обрадовался(до создания нормального драйвера далеко, но заработало!!!). И тут - такая заковырка с Win7... Обязательно посмотрю статус и т.д. Может они вообще не завершаются(так и висят), т.к. выключить машину после установки DRV под Win7 можно только кнопками "RESET" и "POWER"
|
|
« Последнее редактирование: 27-12-2010 22:17 от chesland »
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #9 : 27-12-2010 22:24 » |
|
попробуйте сделать лог того, как вызывают ваш обработчик IRP, но при этом debugprint ставить сразу при входе в ваш обработчик IRP и второй непосредственно перед вашим return. таким образом увидите, не вызывают ли вас повторно после того как вы делаете IoCallDriver(). и посмотрите то, что посоветовал resource: что вы возвращаете по return и что у вас в статусе IRP-а при этом стоит.
|
|
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
chesland
Интересующийся
Offline
|
|
« Ответ #10 : 27-12-2010 22:38 » |
|
Все, спасибо, - пойду спать(у меня в Донецке(Украина) - время 00:30 - завтра на работу) Попробую отловить статусы завершения IRP и выяснить, нет ли повторного обращения к драйверу до завершения предыдущего IRP-пакета. Получится - отпишусь. Не получится - опять пристану ко всем.
Добавлено через 10 дней, 12 часов, 53 минуты и 30 секунд: С ПРАЗДНИКОМ ВСЕХ!
Я тут между елкой, шампанским, вином и др. все-таки смог выяснить причину, по которой под Win7 мой драйвер не запускался. Причина, конечно, в том, что я еще мало знаю про написание дров, путешествия IRP-пакетов и работу в режиме ядра. Начал опять перечитывать "Солдатова" и наткнулся на фразу приблизительно следующего содержания: "...при обработке запроса "IRP_MN_START_DEVICE" нужно сначала этот запрос передать вниз по стеку, затем ПОДОЖДАТЬ, пока СТАРТУЮТ НИЖНИЕ ДРАЙВЕРА для устанавливаемого устройства, а потом его КОНФИГУРИРОВАТЬ. Поэтому вот этот текст решил проблему: ................................................................................... case IRP_MN_START_DEVICE://=0x00 KeInitializeEvent(&startDeviceEvent, NotificationEvent, FALSE); IoCopyCurrentIrpStackLocationToNext(Irp); IoSetCompletionRoutine(Irp, IsoUsb_IrpCompletionRoutine, //функция обработки события завершения - запускается нижним драйвером &startDeviceEvent, // pass the event to the completion routine as the Context TRUE, // invoke on success TRUE, // invoke on error TRUE); // invoke on cancellation
ntStatus = IoCallDriver(pdx->NextStackDevObj,Irp); if (ntStatus == STATUS_PENDING) { waitStatus = KeWaitForSingleObject( &startDeviceEvent, Suspended, KernelMode, FALSE, NULL); } ntStatus=OnStartDevice(fdo);//МОЯ ФУНКЦИЯ КОНФИГУРИРОВАНИЯ USB-устройства Irp->IoStatus.Status = ntStatus; IoCompleteRequest (Irp,IO_NO_INCREMENT);
break; .......................................................................................
Ну и функция "IsoUsb_IrpCompletionRoutine": ...................................................................................... /////////////////////////////////////////////////////////////////////////////////////////// NTSTATUS IsoUsb_IrpCompletionRoutine(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp,IN PVOID Context) { PKEVENT event = Context;
// Set the input event KeSetEvent(event, 1, // Priority increment for waiting thread. FALSE); // Flag this call is not immediately followed by wait.
return STATUS_MORE_PROCESSING_REQUIRED; } ...
Еще раз всех с праздником!!!
|
|
« Последнее редактирование: 07-01-2011 11:32 от chesland »
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #11 : 07-01-2011 14:23 » |
|
chesland, и вам того же) но маленький нюанс. но не только у меня но и в DDK\6001.18001\src\general\toaster\filter\filter.c // If the lower driver didn't return STATUS_PENDING, we don't need to // set the event because we won't be waiting on it. // This optimization avoids grabbing the dispatcher lock, and improves perf. // if (Irp->PendingReturned == TRUE) { KeSetEvent (event, IO_NO_INCREMENT, FALSE); } так что эту проверку стоит оставить. PS хотя объяснить толком не могу, надо доку рыть... Добавлено через 2 минуты и 53 секунды:там же ВНИМАТЕЛЬНО посмотрите как обходятся со статусом возврата, думаю в toaster сделано более корректно, чем сейчас у вас.
|
|
« Последнее редактирование: 07-01-2011 14:35 от Ochkarik »
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
chesland
Интересующийся
Offline
|
|
« Ответ #12 : 07-01-2011 21:23 » |
|
Мой драйвер еще не готов. Я довел его до состояния "ЗАПУСК_OK"(вместе со своим USB-устройством). До полноценного драйвера еще ДАЛЕКО!
Обязательно буду ставить различные предохранители(в том числе и тот, на который вы указали).
|
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #13 : 07-01-2011 22:08 » |
|
я просто стараюсь обратить внимание... пока отладка идет - оно вроде не до мелких нюансов, но потом возвращаться к написанному очень муторно. да и забывается через какое то время. лучше сразу предусматривать все защиты и проверки пусть даже с запасом) хоть бы в виде пустых if-ов и пометок на будущее. но это так... оффтопик)
|
|
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
chesland
Интересующийся
Offline
|
|
« Ответ #14 : 11-01-2011 17:43 » |
|
Добрый день/вечер/ночь... уважаемые дровописатели. Опять я со своими дилетантскими вопросами...
Под WINx32 я свой драйвер запустил, а вот под WINx64 не получается. И дело не в самом драйвере(я так думаю), а в том, что inf-файлы я тоже не умею(так получается) писать.
ВОПРОС состоит в следующем: Когда я пытаюсь установить драйвер под Win7x64 и указываю на свой inf-файл, то ВИНДА пишет, что "в данной папке нет сведений для установки" моего драйвера.
Если есть у кого-то возможность, выложите, пожалуйста, простейший inf-файл для WINx64(ПРОСТЕЙШИЙ-это чтобы я в нем хоть что-нибудь понял).
|
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #15 : 11-01-2011 19:14 » |
|
|
|
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
chesland
Интересующийся
Offline
|
|
« Ответ #16 : 11-01-2011 22:20 » |
|
Спасибо, попробую. Позже отпишусь о результатах. Добавлено через 6 дней, 16 часов, 3 минуты и 27 секунд:Здравствуйте, это опять я со своим драйвером. Выяснил: Чтобы Win7x64 "поняла", что драйвер для НЕЕ, нужно: В секции [Manufacturer] добавить: ,NTamd64 Т.е. для x32 выглядит так: [Manufacturer] %MfgName%=MyCompany [MyCompany] ....................................... А для x64 должно быть вот так: [Manufacturer] %MfgName%=MyCompany,NTamd64 [MyCompany.NTamd64] ........................................... Потом пришлось установить WDK вместо DDK и скомпилить драйвер утилитой "build" для x64, а то Win7x64 писала при установке, что этот драйвер, мол, не подходит для этой операционки. Но теперь новая проблема!!! Вот что пишет винда(Win7x64): "Не удается проверить цифровую подпись драйверов, необходимых для этого устройства. При последнем изменении оборудования или программного обеспечения могла быть произведена установка неправильно подписанного или поврежденного файла либо вредоносной программы неизвестного происхождения.(Код 52)" Ну и чего с этим делать? Обойти как-то можно? Или цифровую подпись делать? Добавлено через 1 час, 44 минуты и 41 секунду://///////////////////////////////////////////////////////////////////////////////////////////////////////// //////////спустя пару часов после погугливания ///////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////// Вопрос, конечно, остается открытым... Для стадии тестирования я нашел способ обхода тестирования драйвера: 1. Перезагружаем компьютер. 2. При загрузке давим клавишу F8. 3. Выбираем пункт: “Отключение обязательной проверки подписи драйверов”. 4. Втыкаем свое USB-устройство - и даже не нужно переустанавливать драйвер - оно уже работает. Меня бепокоит, что пишут:"нельзя в x64 установить неподписанный драйвер"
|
|
« Последнее редактирование: 18-01-2011 16:08 от chesland »
|
Записан
|
|
|
|
|
chesland
Интересующийся
Offline
|
|
« Ответ #18 : 19-01-2011 15:48 » |
|
Я, конечно, может, чего-то недопонял. Сегодня целый день разбирался с этим подписыванием. Выяснил - майкрософтовцы предлагают загнать операционку в тестовый режим, а потом самоподписывать, самосертифицировать... - т.е. потренироваться. В обычном режиме драйвер все-равно не запустится.(если я ошибаюсь, поправьте, пожалуйста). Но в тестовый режим я и по F8 могу войти - тогда никакой подписи не нужно. PS: Напоминаю, речь идет о WINx64.
|
|
« Последнее редактирование: 19-01-2011 15:50 от chesland »
|
Записан
|
|
|
|
resource
Молодой специалист
Offline
Пол:
|
|
« Ответ #19 : 20-01-2011 00:28 » |
|
Мне показалось, что там речь идёт именно о тестовых сертификатах, а не о тестовом режиме. Я ни разу не генерил тестовый сертификат (поскольку есть реальный). В любом случае, даже если я всё правильно понял, вы ведь не будете распространять драйвер подписанный тестовым сертификатом. Если драйвер пишется не для себя, а для массового использования, то придётся купить сертификат и подписать. Имхо "линия партии" очень правильна в этом направлении. Драйверы надо подписывать. Это гут, как для пользователей, так и для разработчиков.
|
|
|
Записан
|
|
|
|
chesland
Интересующийся
Offline
|
|
« Ответ #20 : 20-01-2011 07:35 » |
|
"линия партии" очень правильна в этом направлении. Драйверы надо подписывать. Это гут, как для пользователей, так и для разработчиков.
По поводу "линии партии" у меня(как и у многих) есть свое "не очень хорошее мнение" - но это уже флуд.
|
|
|
Записан
|
|
|
|
resource
Молодой специалист
Offline
Пол:
|
|
« Ответ #21 : 20-01-2011 20:57 » |
|
Ну почему же сразу флуд. Мы ведь тут не собираемся спорить кому что нравится. А своё мнение по этому вопросу вы вполне можете высказать, особенно если это что-то конструктивное, а не фразы типа "да мне просто влом этим заниматься" или "я вообще не понимаю зачем это надо".
|
|
|
Записан
|
|
|
|
|