Опишу-ка я свои приключения с сабжем. WDF расшифровывается Windows driver foundation. В этот пакет входят две разных библиотеки: чисто Си-шная библиотека KMDF для драйверов уровня ядра и UMDF для драйверов, работающих в юзерспейсе, таких как USB и Firewire, основанная на языке Си++ (KMDF -- kernel-mode driver framework, UMDF -- user-mode driver framework). Для меня самое интересное -- это, конечно, KMDF, потому что он позволяет заменить WDM. Исключение -- Win98, на ней новая библиотека не работает.
Как следует из названия, KMDF является фреймворком ("скелет"), то есть специальной средой исполнения драйвера. Программист пишет функции на Си и подключает их к фреймворку, который автоматически вызывает их в нужные моменты. Например, функция DeviceAdd вызывается при обнаружении устройства, или функция FileCreate, которая вызывается в ответ на открытие или создание файла. Это очень похоже на обработку сообщений в WDM, но с одним важным отличием: в WDF есть работающие функции-затычки ко всем системным сообщениям, поэтому не нужно писать код для всего. Чистый WDM в этом отношении проигрывает -- по выражению с habrahabr.ru это софт, созданный в лабораториях абвера по личному указанию фюрера, драйверы в нем имеют пугающие размеры, так как должны обработать все на свете возможности.
С другой стороны, так как это надстройка над WDM, многие недостатки, свойственные ей, перекочевали в новую библиотеку. Например, глупая схема приоритетов прерываний. Из-за требований «кросс-платформенности» (которую никто никогда у Windows не видел), нельзя напрямую работать с PIC, включать и отключать отдельные прерывания, можно только управлять системным уровнем IRQL. Из-за этого многие важные функции недоступны при запрещенных прерываниях. Скажем, нельзя вызывать функцию KeSetSemaphore из процедуры обработки прерываний. И многие другие тоже нельзя вызвать, и на практике проявляется этот запрет в абсолютно непонятных и трудноотлавливаемых ошибках.
Также непонятно, зачем вообще нужны Inf-файлы. Синтаксис у них запутанный, а пользы ноль. Ведь обходится же Линукс без них! А здесь нужно скрупулезно прописывать все детали, не имея почти никакой помощи при отладке, кроме лог-файла c:\windows\setupapi.log.
Отладка драйвера тоже затруднена, потому что отладчик WinDbg.exe отличается специфическим неудобным набором команд. Но это меньшее из зол, связанных с разработкой драйверов под NT. Эффект второй системы, как ни крути.
Начинать лучше всего с
примера samples\kmdf\toaster\functional, другие примеры перегружены
ненужными вещами. Проекты компилируются командой build -ecgZ, список
файлов она читает в sources.
Если компилировать в Release, то компиляция вылетает на
warning'ах. Тут надо либо от них избавляться, либо отключить под
свою ответственность. Чтобы отключить, добавить в sources строку
MSC_WARNING_LEVEL=/w.
Первый раз драйвер можно установить по-обычному, то есть через панель управления, а потом просто заменять файл в папке \windows\system32\drivers. Перед заменой надо сделать ему unload через диспетчер устройств: щелкнуть правой кнопкой по имени устройства и выбрать пункт «отключить». Потом скопировать файл .sys в названную папку и включить его обратно.
Очень помогает в работе программа DbgPrintDump, которая позволяет читать отладочную печать прямо в окошке, без второго компьютера.
У функции WdfIoCompleteRequest, которая вызывается в конце обработки любой файловой операции, есть поле info. Его обязательно надо делать ненулевым, потому что иначе код возврата status не передается в режим пользователя (всегда возвращается STATUS_SUCCESS).
К сожалению, значительная часть старых функций сделана deprecated, и, к сожалению, микрософт слов на ветер не бросает. HalGetInterruptVector работает, но не всегда. IoConnectInterrupt с ним срабатывает через раз. Сейчас, глядишь, работает, а после перезагрузки не работает.
В общем-то, как обычно у фирмы MS: на словах все хорошо, в примерах все просто, но на деле оказывается, что от помойки избавиться все же не удалось.