Расширение набора команд для USB Flash

Тема в разделе "WASM.NT.KERNEL", создана пользователем kernel32ddl, 13 фев 2007.

  1. kernel32ddl

    kernel32ddl New Member

    Публикаций:
    0
    Регистрация:
    12 янв 2007
    Сообщения:
    5
    Возникла необходимость расширить набор команд для USB флэшки.
    Ситуация следующая.
    Имеется USB флэшка собственного изготовления. Помимо стандартных Mass Storage команд необходимо добавить свою, предназначенную для служебных целей (прием изображения с сенсора отпечатка пальца).
    По началу использовали очень простое решение - открывали флэшку как файл и осуществляли запись и чтение (т.е прямое обращение к диску) через избыточные сектора на ней (я специально подобрал кол-во секторов во флэши чтобы при форматировании оставалось 3 избыточных сектора).
    В WinXP данное решение более-менее прокатывало, а вот в Win2k начались серьезные глюки. Win2k по умолчанию использует механизм отложенный записи, который нам не удалось отключить, и из-за этого при приеме/передачи служебных данный(чтении/записи нашего избыточного сектора) происходили огромные задержки которые сделали практически невозможной работу с устройством.
    Затем появилась мысль написать свой собственный драйвер-фильтр для флэшки, который бы просто пропускал все стандартные запросы вниз по стеку и умел бы обрабатывать пару моих IOCTL для приема/передачи данных.
    Почитал Солдатова, Сорокину, Агурова и принялся за дело. Взял /src/wdm/usb/filter.
    Посчитал, что достаточно будет создать символическую ссылку на драйвер, добавить обработку своих IOCTL и при помощи CreateFile и DeviceIoControl "общаться" со своим устройством.
    Однако при попытке создания символической ссылки на драйвер при помощи функции IoCreateSymbolicLink происходила ошибка.
    В описании на данную функцию в DDK я обнаружил, что она не предназначена для использования в WDM драйверах и в драйверах фильтрах в частности, и что необходимо для этих целей использовать функцию IoRegisterDeviceInterface. Для данной функции я так и не смог найти более менее понятного примера использования.

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

    Solo New Member

    Публикаций:
    0
    Регистрация:
    11 июл 2003
    Сообщения:
    131
    а в первом варианте пробовал команды принудительного сброса кэша? (fflush() например)
     
  3. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    Не то чтобы не предназначена, просто по соображениям безопасности её в фильтрах не надо использовать.

    Во всевозможных вариантах пример использования есть в
    DDK\src\general\toaster\func\incomplete1
    или
    DDK\src\general\toaster\func\incomplete2
    или
    DDK\src\general\toaster\func\featured1
    или
    DDK\src\general\toaster\func\featured2

    Примерно так:

    Код (Text):
    1. NTSTATUS
    2. AddDevice(
    3.     IN PDRIVER_OBJECT DriverObject,
    4.     IN PDEVICE_OBJECT pPDO
    5.     )
    6. ...
    7.     status = IoRegisterDeviceInterface(
    8.                  pPDO, (LPGUID) &GUID_MYDEVINTERFACE, NULL, &pdx->InterfaceName );
    9. ...
    10. }
    11.  
    12. NTSTATUS
    13. DispatchPnp (
    14.     IN PDEVICE_OBJECT DeviceObject,
    15.     IN PIRP Irp
    16.     )
    17. {
    18. ...
    19. switch (stack->MinorFunction) {
    20. case IRP_MN_START_DEVICE:
    21.     status = IoSetDeviceInterfaceState( &pdx->InterfaceName, TRUE );
    22. ...
    23. case IRP_MN_REMOVE_DEVICE:
    24. case IRP_MN_SURPRISE_REMOVAL:
    25.     status = IoSetDeviceInterfaceState( &pdx->InterfaceName, FALSE );
    26.     RtlFreeUnicodeString( &pdx->InterfaceName );
    27. ...
    28. }
    В юзере нужно найти интерфейс через SetupAPI, а дальше тот же CreateFile и т.д. Пример см. в DDK\src\general\toaster\exe\notify.


    Можно. Тогда это драйвер создаст CDO (Control Device Object) и будет общаться с юзером, а затем транслировать это драйверу фильтру, но смысла нет. Проще интерфейс и фильтр.
     
  4. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
  5. kernel32ddl

    kernel32ddl New Member

    Публикаций:
    0
    Регистрация:
    12 янв 2007
    Сообщения:
    5
    Естественно.

    Спасибо за наводку, буду сейчас разбираться.

    Я постараюсь, но дело в том, что у нас на работе нельзя передавать сообщения с приаттаченными файлами, только со служебного ящика (а его проверяет злой чувак в ручную). Этот пример я взял из DDK 2600 (WinXP DDK SP1). В общем попробую.

    Кое-что обязательно пригодиться, большое спасибо.

    Да, кстати, как насчет варианта без драйверов? Это из разряда извращений?
     
  6. kernel32ddl

    kernel32ddl New Member

    Публикаций:
    0
    Регистрация:
    12 янв 2007
    Сообщения:
    5
    С начальной задачей удалось справиться (связь с драйвером, отправка собственного IOCTL), однако при помощи интерфейса ничего не получилось. Дело в том, что данный способ связи с драйвером фильтром пригоден лишь когда он (драйвер-фильтр) стоит в верхушке драйверного стека.
    Решение своей проблемы я обнаружил здесь -> http://support.microsoft.com/kb/262305. "Ларчик просто открывался" - нужно было взять \Src\General\Toaster\Filter\ и задефайнить IOCTL_INTERFACE (или же просто удалить все строки условной компиляции с этой переменной).

    Теперь у меня возник следующий вопрос. Устройство с которым собираюсь организовать обмен данными, к моменту выполнения IOCTL или Read-Write операций уже будет сконфигурировано драйвером USBSTOR.SYS (я думаю что именно этим драйвером).
    Необходимо ли мне выполнять все стандартные операции(конфигурирование, выбор интерфейса и пр.), обычно проделываемые в функциях StartDevice, StopDevice, RemoveDevice?
    В вызове функции UsbBuildInterruptOrBulkTransferRequest существует параметр hpipe, который насколько я понял как раз и инициализируется при конфигурировании устройства и храниться в DEVICE_EXTENSION. Можно ли как-либо обойтись без конфигурирования и заполучить хендлер на пайп? В общем не хочется делать лишних телодвижений :).
     
  7. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    Конфигурирование девайса выполняет функциональный драйвер. Фильтр не может этого делать. Если он сидит под FDO, то может только наблюдать процесс конфигурирования, но не управлять им.

    Насчет отлова хендлов пайпов тут немного есть.
    http://www.wasm.ru/forum/viewtopic.php?id=18417
     
  8. Solo

    Solo New Member

    Публикаций:
    0
    Регистрация:
    11 июл 2003
    Сообщения:
    131
    вот и мне стал интересен вопрос, можно ли как-то заставить Mass Storage принимать и отвечать на дополнительный набор команд? Так, чтобы кэш системы не вмешивался в процесс обмена, или вмешательство этого кэша можно было бы распознавать и обходить?

    ЗЫ. Хотелось бы добиться работы с USB-устройством без прав админа, а HID слишком медленный :dntknw:
     
  9. green

    green New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2003
    Сообщения:
    1.217
    Адрес:
    Ukraine
    Может быть, CreateFile с флагом FILE_FLAG_NO_BUFFERING пригодится?
     
  10. kernel32ddl

    kernel32ddl New Member

    Публикаций:
    0
    Регистрация:
    12 янв 2007
    Сообщения:
    5
    Народ используйте LibUsb, если не хотите писать свой драйвер. Все легко и просто. Дорабатывать это зверя нужно только в том плане, чтобы убрать лишнее. Работает параллельно со стандартным драйвером и позволяет отправлять на устройство АБСОЛЮТНО ЛЮБЫЕ команды. Добился с ним очень хороших результатов. Искать его на sourceforge.net

    Насчет FILE_FLAG_NO_BUFFERING это наверно первое, что делают люди, сталкивающиеся с данной проблемой...
     
  11. Solo

    Solo New Member

    Публикаций:
    0
    Регистрация:
    11 июл 2003
    Сообщения:
    131
    FILE_FLAG_NO_BUFFERING ничего не дает.
    Драйвер написать не проблема, хочется сделать устройство, которое смогло бы работать без прав админа на любом компьютере...
     
  12. kernel32ddl

    kernel32ddl New Member

    Публикаций:
    0
    Регистрация:
    12 янв 2007
    Сообщения:
    5
    Что-то я в толк не возьму. Твой MassStorage Device настолько крутой, что с ним можно работать только с административными привилегиями? Первый раз слышу о таком...
    Если ты о том, что некоторые операции нельзя выполнять из режима пользователя (User Mode), то одно из главных свойств драйвера как раз и заключается в том, что он может выполнять такие действия в режиме ядра (Kernel Mode), которые обычным программа не дано в принципе. Поэтому драйверу подвластно все.
    А libUsb это библиотека, которая позволяет вести обмен с ЛЮБЫМ USB устройством из режима пользователя, за счет того, что она устанавливает свои драйвера на USB устройства в системе.
     
  13. Solo

    Solo New Member

    Публикаций:
    0
    Регистрация:
    11 июл 2003
    Сообщения:
    131
    я своему massStorage хочу прикрутить дополнительный набор команд. Но так прикрутить, чтобы этим набором команд можно было пользоваться без прав админа, а следовательно и без инсталляции драйверов которые без прав админа не поставишь. Т.е. через какой-нибудь стандартный интерфейс. Вот только HID не подходит по скорости...