Возникла необходимость расширить набор команд для 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 сообщества по данному вопросу.
Не то чтобы не предназначена, просто по соображениям безопасности её в фильтрах не надо использовать. Во всевозможных вариантах пример использования есть в 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): NTSTATUS AddDevice( IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT pPDO ) ... status = IoRegisterDeviceInterface( pPDO, (LPGUID) &GUID_MYDEVINTERFACE, NULL, &pdx->InterfaceName ); ... } NTSTATUS DispatchPnp ( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { ... switch (stack->MinorFunction) { case IRP_MN_START_DEVICE: status = IoSetDeviceInterfaceState( &pdx->InterfaceName, TRUE ); ... case IRP_MN_REMOVE_DEVICE: case IRP_MN_SURPRISE_REMOVAL: status = IoSetDeviceInterfaceState( &pdx->InterfaceName, FALSE ); RtlFreeUnicodeString( &pdx->InterfaceName ); ... } В юзере нужно найти интерфейс через SetupAPI, а дальше тот же CreateFile и т.д. Пример см. в DDK\src\general\toaster\exe\notify. Можно. Тогда это драйвер создаст CDO (Control Device Object) и будет общаться с юзером, а затем транслировать это драйверу фильтру, но смысла нет. Проще интерфейс и фильтр.
Естественно. Спасибо за наводку, буду сейчас разбираться. Я постараюсь, но дело в том, что у нас на работе нельзя передавать сообщения с приаттаченными файлами, только со служебного ящика (а его проверяет злой чувак в ручную). Этот пример я взял из DDK 2600 (WinXP DDK SP1). В общем попробую. Кое-что обязательно пригодиться, большое спасибо. Да, кстати, как насчет варианта без драйверов? Это из разряда извращений?
С начальной задачей удалось справиться (связь с драйвером, отправка собственного 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. Можно ли как-либо обойтись без конфигурирования и заполучить хендлер на пайп? В общем не хочется делать лишних телодвижений .
Конфигурирование девайса выполняет функциональный драйвер. Фильтр не может этого делать. Если он сидит под FDO, то может только наблюдать процесс конфигурирования, но не управлять им. Насчет отлова хендлов пайпов тут немного есть. http://www.wasm.ru/forum/viewtopic.php?id=18417
вот и мне стал интересен вопрос, можно ли как-то заставить Mass Storage принимать и отвечать на дополнительный набор команд? Так, чтобы кэш системы не вмешивался в процесс обмена, или вмешательство этого кэша можно было бы распознавать и обходить? ЗЫ. Хотелось бы добиться работы с USB-устройством без прав админа, а HID слишком медленный
Народ используйте LibUsb, если не хотите писать свой драйвер. Все легко и просто. Дорабатывать это зверя нужно только в том плане, чтобы убрать лишнее. Работает параллельно со стандартным драйвером и позволяет отправлять на устройство АБСОЛЮТНО ЛЮБЫЕ команды. Добился с ним очень хороших результатов. Искать его на sourceforge.net Насчет FILE_FLAG_NO_BUFFERING это наверно первое, что делают люди, сталкивающиеся с данной проблемой...
FILE_FLAG_NO_BUFFERING ничего не дает. Драйвер написать не проблема, хочется сделать устройство, которое смогло бы работать без прав админа на любом компьютере...
Что-то я в толк не возьму. Твой MassStorage Device настолько крутой, что с ним можно работать только с административными привилегиями? Первый раз слышу о таком... Если ты о том, что некоторые операции нельзя выполнять из режима пользователя (User Mode), то одно из главных свойств драйвера как раз и заключается в том, что он может выполнять такие действия в режиме ядра (Kernel Mode), которые обычным программа не дано в принципе. Поэтому драйверу подвластно все. А libUsb это библиотека, которая позволяет вести обмен с ЛЮБЫМ USB устройством из режима пользователя, за счет того, что она устанавливает свои драйвера на USB устройства в системе.
я своему massStorage хочу прикрутить дополнительный набор команд. Но так прикрутить, чтобы этим набором команд можно было пользоваться без прав админа, а следовательно и без инсталляции драйверов которые без прав админа не поставишь. Т.е. через какой-нибудь стандартный интерфейс. Вот только HID не подходит по скорости...