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

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Написал USB-driver - под Win7x32 не запускается, помогите.  (Прочитано 29174 раз)
0 Пользователей и 1 Гость смотрят эту тему.
chesland
Интересующийся

ua
Offline Offline

« : 27-12-2010 19:36 » 

Собрал USB-устройство на PIC18F2550. Написал к нему драйвер под WinXPx32(не полный, но рабочий)- работает(устройство определяется, конфигурируется, обменивается данными по VENDOR).
Проблема заключается в том, что под Win7x32 драйвер не запускается. Устанавливается, проходит конфигурирование, установку интерфейса... а потом установка останавливается минут на 5-10 и затем получаю сообщение типа:"windows обнаружила драйверы для устройства, но в процессе установки произошла ошибка. Устройство не может быть запущено."

Уважаемые дровописатели! Помогите чайнику. Это мой первый драйвер и первое USB-устройство. Что из них не работает, я не знаю. Но похоже, что драйвер. Т.к. устройство работает только по 0-вой конечной точке, но после установки интерфейса в USB-модуле не происходит никаких прерываний(т.е. компьютер не отсылает никаких запросов).
« Последнее редактирование: 28-12-2010 04:38 от RXL » Записан
supermaxus
Участник

ru
Offline Offline

« Ответ #1 : 27-12-2010 19:51 » 

Слышал, что начиная с win7 драйверы, вроде, надо подписывать ЭЦП. Мож в этом дело? В любом случае, Вам не помешает понять, оно тупит до входа в driverEntry, или после (см. в свой лог/отладчик)? Если до, то дело может быть и в ЭЦП, если после - см. ошибку в отладчике.
Записан
chesland
Интересующийся

ua
Offline 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
Модератор

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

« Ответ #3 : 27-12-2010 20:43 » 

а какие еще к вам IRP последними приходят?
обработчик IRP у вас реентернабельный?
насчет "последующих операциях"- не понял, вы где эти IRP_MN_QUERY_DEVICE_RELATIONS отловили, когда дальше по стеку в своем драйвере передаете? какой у него тип в Type?

PS семерка возможно более строго подходит к обработки IRP и не прощает то что сходило с рук в XP...
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
chesland
Интересующийся

ua
Offline 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
Модератор

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

« Ответ #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 уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
resource
Молодой специалист

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

« Ответ #6 : 27-12-2010 21:54 » 

chesland, интересно кем, и с каким статусом завершаются все эти 13 ирпов
Записан
Ochkarik
Модератор

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

« Ответ #7 : 27-12-2010 21:57 » 

кстати да))) особенно - кем)
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
chesland
Интересующийся

ua
Offline 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
Модератор

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

« Ответ #9 : 27-12-2010 22:24 » 

попробуйте сделать лог того, как вызывают ваш обработчик IRP, но при этом debugprint ставить сразу при входе в ваш обработчик IRP и второй непосредственно перед вашим return. таким образом увидите, не вызывают ли вас повторно после того как вы делаете IoCallDriver().
и посмотрите то, что посоветовал resource: что вы возвращаете по return и что у вас в статусе IRP-а при этом стоит.
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
chesland
Интересующийся

ua
Offline 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
Модератор

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

« Ответ #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 уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
chesland
Интересующийся

ua
Offline Offline

« Ответ #12 : 07-01-2011 21:23 » 

Мой драйвер еще не готов.
Я довел его до состояния "ЗАПУСК_OK"(вместе со своим USB-устройством).
До полноценного драйвера еще ДАЛЕКО!

Обязательно буду ставить различные предохранители(в том числе и тот, на который вы указали).
Записан
Ochkarik
Модератор

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

« Ответ #13 : 07-01-2011 22:08 » 

я просто стараюсь обратить внимание... пока отладка идет - оно вроде не до мелких нюансов, но потом возвращаться к написанному очень муторно.  да и забывается через какое то время. лучше сразу предусматривать все защиты и проверки пусть даже с запасом) хоть бы в виде пустых if-ов и пометок на будущее.
но это так... оффтопик)
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
chesland
Интересующийся

ua
Offline Offline

« Ответ #14 : 11-01-2011 17:43 » 

Добрый день/вечер/ночь... уважаемые дровописатели.
Опять я со своими дилетантскими вопросами...

Под WINx32 я свой драйвер запустил, а вот под WINx64 не получается.
И дело не в самом драйвере(я так думаю), а в том, что inf-файлы я тоже не умею(так получается) писать.

ВОПРОС состоит в следующем:
Когда я пытаюсь установить драйвер под Win7x64 и указываю на свой inf-файл, то ВИНДА пишет, что "в данной папке нет сведений для установки" моего драйвера.

Если есть у кого-то возможность, выложите, пожалуйста, простейший inf-файл для WINx64(ПРОСТЕЙШИЙ-это чтобы я в нем хоть что-нибудь понял).
Записан
Ochkarik
Модератор

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

« Ответ #15 : 11-01-2011 19:14 » 

доброго)
попробуйте покурить поиск на форуме:
https://forum.shelek.ru/index.php/topic,23414.0.html
и
https://forum.shelek.ru/index.php/topic,12433.0.html
PS простейшие файлы наверняка есть в семплах DDK)
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
chesland
Интересующийся

ua
Offline Offline

« Ответ #16 : 11-01-2011 22:20 » 

доброго)
попробуйте покурить поиск на форуме:
https://forum.shelek.ru/index.php/topic,23414.0.html
и
https://forum.shelek.ru/index.php/topic,12433.0.html
PS простейшие файлы наверняка есть в семплах DDK)
Спасибо, попробую. Позже отпишусь о результатах.

Добавлено через 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 » Записан
resource
Молодой специалист

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

« Ответ #17 : 18-01-2011 20:41 » 

Так подпишите.
http://msdn.microsoft.com/en-us/library/ff552275.aspx

Я подписываю коммерческим сертификатом, поэтому не знаю нужен вам будет кросс-сертификат или нет. Но на всякий случай
http://www.microsoft.com/whdc/driver/install/drvsign/crosscert.mspx
Записан
chesland
Интересующийся

ua
Offline Offline

« Ответ #18 : 19-01-2011 15:48 » 


Я, конечно, может, чего-то недопонял.
Сегодня целый день разбирался с этим подписыванием.
Выяснил - майкрософтовцы предлагают загнать операционку в тестовый режим, а потом самоподписывать, самосертифицировать... - т.е. потренироваться. В обычном режиме драйвер все-равно не запустится.(если я ошибаюсь, поправьте, пожалуйста).

Но в тестовый режим я и по F8 могу войти - тогда никакой подписи не нужно.

PS: Напоминаю, речь идет о WINx64.
« Последнее редактирование: 19-01-2011 15:50 от chesland » Записан
resource
Молодой специалист

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

« Ответ #19 : 20-01-2011 00:28 » 

 Мне показалось, что там речь идёт именно о тестовых сертификатах, а не о тестовом режиме. Я ни разу не генерил тестовый сертификат (поскольку есть реальный). В любом случае, даже если я всё правильно понял, вы ведь не будете распространять драйвер подписанный тестовым сертификатом. Если драйвер пишется не для себя, а для массового использования, то придётся купить сертификат и подписать.
 Имхо "линия партии" очень правильна в этом направлении. Драйверы надо подписывать. Это гут, как для пользователей, так и для разработчиков.
Записан
chesland
Интересующийся

ua
Offline Offline

« Ответ #20 : 20-01-2011 07:35 » 

"линия партии" очень правильна в этом направлении. Драйверы надо подписывать. Это гут, как для пользователей, так и для разработчиков.
По поводу "линии партии" у меня(как и у многих) есть свое "не очень хорошее мнение" - но это уже флуд.
Записан
resource
Молодой специалист

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

« Ответ #21 : 20-01-2011 20:57 » 

Ну почему же сразу флуд. Мы ведь тут не собираемся спорить кому что нравится. А своё мнение по этому вопросу вы вполне можете высказать, особенно если это что-то конструктивное, а не фразы типа "да мне просто влом этим заниматься" или "я вообще не понимаю зачем это надо".
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines