Перейти к содержанию
    

Драйвер-фильтр USB

Возникла необходимость расширить набор команд для USB флэшки.

Ситуация следующая.

Имеется USB флэшка собственного изготовления. Помимо стандартных Mass Storage команд необходимо добавить свою, предназначенную для служебных целей (прием изображения с сенсора отпечатка пальца).

По началу использовали очень простое решение - открывали флэшку как файл и осуществляли запись и чтение (т.е прямое обращение к диску) через избыточные сектора на ней (я специально подобрал кол-во секторов во флэши чтобы при форматировании оставалось 3 избыточных сектора).

В WinXP данное решение более-менее прокатывало, а вот в Win2k начались серьезные глюки. Win2k по умолчанию использует механизм отложенный записи, который нам не удалось отключить, и из-за этого при приеме/передачи служебных данный(чтении/записи нашего избыточного сектора) происходили огромные задержки которые сделали практически невозможной работу с устройством.

Затем появилась мысль написать свой собственный драйвер-фильтр для флэшки, который бы просто пропускал все стандартные запросы вниз по стеку и умел бы обрабатывать пару моих IOCTL для приема/передачи данных.

Почитал Солдатова, Сорокину, Агурова и принялся за дело. Взял /src/wdm/usb/filter (из DDK).

Посчитал, что достаточно будет создать символическую ссылку на драйвер, добавить обработку своих IOCTL и при помощи CreateFile и DeviceIoControl "общаться" со своим устройством.

Однако при попытке создания символической ссылки на драйвер при помощи функции IoCreateSymbolicLink происходила ошибка.

В описании на данную функцию в DDK я обнаружил, что она не предназначена для использования в WDM драйверах и в драйверах фильтрах в частности, и что необходимо для этих целей использовать функцию IoRegisterDeviceInterface. Для данной функции я так и не смог найти более менее понятного примера использования.

 

Так вот, возникает вопрос, каким образом можно решить данную задачу, и вообще обязательно ли писать свой драйвер для этих целей? Нужно ли писать именно драйвер фильтр или же можно написать “легаси” драйвер или класс драйвер (в котором можно использовать IoCreateSymbolicLink) и подключить его к драйверу шины “в параллель” с USBSTOR.SYS? Или же каким-нибудь образом обращаться из user mode к существующему драйверу в системе, например, USBSTOR.SYS или драйверу хаба для приема/передачи данных с/на устройство?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Однако при попытке создания символической ссылки на драйвер при помощи функции IoCreateSymbolicLink происходила ошибка.

Какой device object давали в качестве аргумента? Возможно причина в том, что FDO не должен быть конкретно именованным. Но никто не мешает создать дополнительный теневой devobj и привязать ссылку к нему.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Сначала делаю так:

RtlInitUnicodeString( &devName, L"\\Device\\BIOFILTER" );
status = IoCreateDevice(    driverObj, 
                                sizeof(struct DEVICE_EXTENSION),
                                NULL,
                                //&devName,         // name for this device
                                FILE_DEVICE_UNKNOWN, 
                                FILE_AUTOGENERATED_DEVICE_NAME,// device characteristics
                                (BOOLEAN) FALSE,    // not exclusive
                                &filterDevObj);        // our device object

А затем так:

RtlInitUnicodeString( &symLinkName, L"\\DosDevices\\BIOFILTER" );
status = IoCreateSymbolicLink(&symLinkName, &devName);

Потом так:

        /*
         *  Initialize device extension for new device object
         */
        devExt = (struct DEVICE_EXTENSION *)filterDevObj->DeviceExtension;
        RtlZeroMemory(devExt, sizeof(struct DEVICE_EXTENSION));
        devExt->signature = DEVICE_EXTENSION_SIGNATURE;
        devExt->state = STATE_INITIALIZED;
        devExt->filterDevObj = filterDevObj;
        devExt->physicalDevObj = physicalDevObj;
        
        devExt->pendingActionCount = 0;
        KeInitializeEvent(&devExt->removeEvent, NotificationEvent, FALSE);
#ifdef HANDLE_DEVICE_USAGE
        KeInitializeEvent(&devExt->deviceUsageNotificationEvent, SynchronizationEvent, TRUE);
#endif // HANDLE_DEVICE_USAGE
        devExt->topDevObj = IoAttachDeviceToDeviceStack(filterDevObj, physicalDevObj);

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Сначала делаю так:

RtlInitUnicodeString( &devName, L"\\Device\\BIOFILTER" );
status = IoCreateDevice(    driverObj, 
                                sizeof(struct DEVICE_EXTENSION),
                                NULL,
                                //&devName,         // name for this device
                                FILE_DEVICE_UNKNOWN, 
                                FILE_AUTOGENERATED_DEVICE_NAME,// device characteristics
                                (BOOLEAN) FALSE,    // not exclusive
                                &filterDevObj);        // our device object

А затем так:

RtlInitUnicodeString( &symLinkName, L"\\DosDevices\\BIOFILTER" );
status = IoCreateSymbolicLink(&symLinkName, &devName);

Потом так:

Ну и правильно IoCreateSymbolicLink ругается. Объекта-то с devName в системе-то нету.

Попробуйте в IoCreateDevice вместо NULL указать требуемый DevName, флажок FILE_AUTOGENERATED_DEVICE_NAME не указывать. Я не уверен, что этот devObj потом

можно использовать как фильтровый - то есть с стеку он скорее всего из-за именованности не приаттачится. То есть Вам придется создать именованный devObj и обычный неименованный filterDevObj. filterDevObj включить в стек и работать как обычно фильтром, а на devObj уже принимать дополнительные запросы на обработку сверху.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну и правильно IoCreateSymbolicLink ругается. Объекта-то с devName в системе-то нету.

Попробуйте в IoCreateDevice вместо NULL указать требуемый DevName, флажок FILE_AUTOGENERATED_DEVICE_NAME не указывать. Я не уверен, что этот devObj потом

можно использовать как фильтровый - то есть с стеку он скорее всего из-за именованности не приаттачится. То есть Вам придется создать именованный devObj и обычный неименованный filterDevObj. filterDevObj включить в стек и работать как обычно фильтром, а на devObj уже принимать дополнительные запросы на обработку сверху.

Ясно, спасибо, буду разбираться!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...