Jump to content

    
Sign in to follow this  
kernel32ddl

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

Recommended Posts

Возникла необходимость расширить набор команд для 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 или драйверу хаба для приема/передачи данных с/на устройство?

Share this post


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

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

Share this post


Link to post
Share on other sites

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

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);

Share this post


Link to post
Share on other sites
Сначала делаю так:

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 уже принимать дополнительные запросы на обработку сверху.

Share this post


Link to post
Share on other sites
Ну и правильно IoCreateSymbolicLink ругается. Объекта-то с devName в системе-то нету.

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

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

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

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this