Создание драйверов. Часть 1
В данной статье мне хотелось бы показать, как создавать драйвера, если Вам необходима теоретическая информация то советую прочесть книгу Дэвида Соломона и Марка Руссиновича «Внутреннее устройство Microsoft Windows 2000». Для начала мы сделаем простой драйвер для Windows 2000, который послужит нам каркасом для дальнейших экспериментов. Для работы понадобится «Windows 2000 Driver Development Kit», именно с помощью данного пакета создаются драйвера, в его состав входят компилятор, линкер, заголовочные файлы, lib-файлы, документация, полезные инструменты и конечно множество примеров.
Для написания и редактирования исходных текстов драйверов можно воспользоваться редактором, входящим в состав MS Visual Studio или Блокнотом, незаменимым инструментом программиста. Для просмотра объектов операционной системы понадобиться программа WinObj, автором которой является Марк Руссинович, программу можно найти на сайте http://www.sysinternals.com/, так же с этого адреса можно скачать программу DebugView, которая позволяет просматривать диагностические сообщения, посылаемые функциями OutputDebugString и DbgPrint.
Начнем, создайте на диске С:\ папку и назовите её «MyFirstDriver», затем в ней папку «sys» и «loader», это нужно для того чтобы легче было работать с путями к бинарным файлам. В папке «sys» создайте три файла, с именами «makefile», «sources» и «MyFirstDriver.c». В файле «makefile» напишите следующее:
Этот файл нужен для работы программы Build. В файле «sources» напишите следующее:
TARGETNAME=MyFirstDriver
TARGETTYPE=DRIVER
TARGETPATH=obj
SOURCES=MyFirstDriver.c
Этот файл нужен для настройки процесса компиляции:
TARGETNAME – имя драйвера;
TARGETTYPE – тип бинарного файла, который мы хотим создать, может иметь следующие значения: DRIVER, GDI_DRIVER, MINIPORT, LIBRARY, DYNLINK (for DLLs).
TARGETPATH – путь для папки с временными файлами;
SOURCES – путь к файлу с исходным текстом драйвера.
Теперь переходим к исходному файлу «MyFirstDriver.c», в нем напишите следующее:
Как Вы видите драйвер очень прост и имеет основные функции:
DriverEntry – данная функция есть в каждом драйвере и является точкой входа.
Параметры:
IN PDRIVER_OBJECT DriverObject – адрес объекта драйвера;
IN PUNICODE_STRING RegistryPath – путь в реестре, где содержится информация о драйвере.
Тип возвращаемого значения NTSTATUS, на самом деле это просто тип LONG, может принимать следующие значения:
STATUS_SUCCESS – успешно;
STATUS_N – где, N – номер ошибки.
В функции DriverEntry происходит заполнение полей структуры DriverObject:
DriverUnload – здесь регистрируется функция выгрузки драйвера;
MajorFunction[IRP_MJ_CREATE] – здесь регистрируется функция обработки запросов открытия драйвера;
MajorFunction[IRP_MJ_CLOSE] — здесь регистрируется функция обработки запросов закрытия драйвера;
MajorFunction[IRP_MJ_DEVICE_CONTROL] — здесь регистрируется функция обработки IOCTLзапросов. Так же в DriverEntry создается символьная ссылка и устройство. Для вывода отладочной информации с помощью функции DbgPrint мы используем возможности условной компиляции, то есть конструкция:
#if DBG
DbgPrint(«»);
#endif
будет присутствовать только в версиях Checked.
Для компиляции запустите «Checked Build Environment»,
Появится консольное окно, далее с помощью команды «cd» перейдите в папку с файлами драйвера и наберите команду build –cZ
Теперь драйвер готов, следующим шагом будет создание программы, которая будет динамически загружать наш драйвер с помощью SCM (Service Control Manager), подробно о нем написано в MSDN`е. Для этого создайте обыкновенную консольную версию программы и поместите все файлы проекта в папку «loader», в исходнике загрузчика напишите следующее:
Перед тем как запускать программу, запустите DebugView, только после этого запускайте загрузчик драйвера.
Как Вы видите наш драйвер заработал, на этом пока все.
Как создать драйвер для windows
Ну вот мы и добрались до самого интересного — сейчас будем писать драйвер. Итак, приступим. Для удобства выполнения, всю последовательность действий по написанию драйвера я распишу по пунктам.
1. Создание директории проекта
Установив DDK, на Вашем компьютере в директории C:\WINDDK\2600.1106\ должны появиться файлы DDK. В этой директории создадим папку, в которой будут храниться наши проекты. Назовем ее, например, MyDrivers.
В папке MyDrivers создадим папку FirstDriver — тут будет находится наш первый проект драйвера.
2. Подготовка файлов проекта
В папке FirstDriver создайте пустой текстовый файл и переименуйте его под именем FirstDriver.c
При попытке переименовки со сменой расширения файла, появляется следующее предупреждение:
Не обращаем внимания на это предупреждение, и нажимаем Да. При этом наш файл примет вид:
Если же никакого предупреждения не было и переименованный файл так и остался текстовым с именем FirstDriver.c и расширением .txt, то в настройках своийств папки, которые можно найти в Пуск-> Настройка-> Панель управления-> Свойства паки уберите галочку напротив пункта «Скрывать расширения для зарегестрированных типов файлов». Попробуйте еще раз и все должно быть в порядке.
Теперь нам надо добавить еще два очень важных файла в наш проект, без которых драйвер нам не сделать. Они называются makefile и sources (обратите внимание, у них нет расширения). Их можно создать самим, но мы сделаем проще: скопируем готовые из какого либо примера проекта драйвера из DDK. Например, возьмем их из C:\WINDDK\2600.1106\src\general\cancel\sys\. Итак, копируем из указанной директории эти два файла и вставляем их в нашу папку проекта FirstDriver. Эти файлы управляют процессрм компиляции драйвера. Файл makefile оставляем без изменений, а вот sources надо подредактировать.
Открываем этот файл с помощью блокнота, и удаляем из него все что там есть и вставляем туда текст, представленный ниже. Сохранияем файл.
Первым параметром идет TARGETNAME, которому мы присвоили Port. Это значит, что когда DDK откомпилирует наш код и создаст драйвер, имя этого файла будет Port.sys Следующем параметром идет TARGETPATH, которому мы указали путь к папке нашего проекта. Если Вы устанавливали DDK в другое место, или создали пупку проекта в другой директории, здесь Вам надо это поправить на тот путь, который у Вас. Параметр TARGETTYPE пока оставлю без комментариев. В параметре SOURCES указываем, из каких файлов будет компилироваться драйвер. У нас это файл FirstDriver.c, вот мы его и указали.
Всю подготовительную работу мы сделали. Можно приступать к самой содержательной части — коду драйвера. Писать мы будем его на Си.
Еще раз напомню решаемую нами задачу: надо написать драйвер под Windows 2000, XP с помощью которого можно будет работать с портами компьютера (читать и писать данные) .
Рассмотрим код, представленный ниже. Серым цветом обозначены те участки кода, которые являются как бы шаблонными для большинства драйверов, а зеленым — код, который относится именно к нашему текущему драйверу.
Представленный код — есть код простейшего драйвера, который может только записать данные в порт и прочесть их от туда. Выглядит страшновато? Ни чего, в следующей статье будем разбираться с тем что в нем понаписано.
Как написать драйвер для Windows ?
Информация по программированию драйверов Windows . С чего начать. Где скачать DDK . Что читать.
Видимо, перед вами стоит задача взаимодействия с аппаратурой. Наверное, эта аппаратура подключена не к COM порту. Для работы с RS232 Windows API имеет практически все возможности, за исключением взаимодействия с микроконтроллерами по протоколу с девятым адресным битом, да и это возможно осуществить. А вот если требуется вывести байт данных в параллельный порт или еще куда, то тут OpenFile(«LPT». ) уже не работает. На ассемблере тоже бесполезно. Наверное все уже в курсе, что код типа [ out dx,al ] под 200 0 — XP ничего кроме ошибки не дает. Что же делать ? Надо сделать драйвер под Windows. И тут возникает вопрос, а как бы побыстрее научиться писать драйвера, а еще лучше разработать один драйвер д ля Windowsи и забыть, как о кошмарном сне. Возможно многие сочтут, что п рограммировать драйвера, а особенно отлаживать драйвера под Windows, не самое приятное занятие.
Радует, тот факт, что за последние 5 лет появилась рускоязычная литература на тему разработки драйверов ибо осваивать эту тему по документации Microsoft DDK весьма утопичное занятие.
X очется отметить книгу : « Программирование драйверов для Windows .» Автор: В.П. Солдатов . Издательство: Бином. ISBN: 5-9518-0099-4
Данная книга не содержит диска с примерами, да и вообще примерами не изобилует, зато дает очень хорошее описание архитектуры ядра Windows , и может служить хорошим стартом для освоения программирования драйверов.
Понятно, что для создания дравера необходимо инструментальное средство разработки драйверов, и чем оно мощнее, тем быстрее вы достигните цели. С амое примитивное из средств рахзработки драйверов это , это DDK, Driver Development Kit.
И вот что досадно, если в 2000-2002 году DDK 2000 можно было скачать бесплатно, то сейчас бесплатно доступна только Windows Server 2003 DDK , причем скачать нельзя, можно только получить CD по почте, при этом необходимо иметь кредитку, т.к. DDK то бесплатно, но пересылка диска будет стоить 25 $ . Деньги не великие, так что если имеете кредитку и желаете DDK 2003 , вот ссылка http://www.microsoft.com/whdc/devtools/ddk/default.mspx
Более навороченный продукт DDK Suite 3, обойдется уже в 199 $ плюс те же 25 за доставку.
Найти DDK на рынке за 60 рублей, наверное можно но сложно, слишком редко востребуемый продукт. Ну а если нет кредитки или времени на ожидание диска, не отчаивайтесь, и не благодарите 🙂
Скачивайте все файлы что там есть. Распакуете ddk.rar и запускайте ksetup.exe. Спасибо Яндексу за 67 мегабайт.
Правда писать драйвера при помощи только DDK не самый удобный на сегодня способ , а посему предлагаю обратить внимания на два продукта.
Оба по сути похожи, а именно позволяют создавать драйвера двух типов.
Работающие через некий универсальный драйвер.
Полноценные драйвера работающие в режиме ядра.
Как вы правильно догадались первый способ значительно легче и не требует от программиста глубокого понимания процессов происходящих в ядре, да вообще ни какого понимания не требует.
Мастер создания драйверов, DriverWizard ( Jungo) сгенерит код, который вы сможете вставить в свои программы и обращаться к портам в-в, памяти и даже использовать прерывания. Все очень просто: Утром установите WinDriver, вечером ваша программа будет работать с аппаратурой, но остерегайтесь WinDrivera . Покупать вы его конечно не будете, и при установке , выберете 30-дневную копию. В течении месяца все будет работать и Driver Wizard и все программы его использующие. Потом DriverWizard работать перестанет, но к тому времени вы то уже поймете, что он и не нужен. Нужн а только библиотека WINDRVR.SYS, которая и обеспечивает взаимодействие с портами Вашей программе. Так вот этот самый WINDRVR.SYS, через который будет работать ваша программа, в отличии от DriverWizarda не подает никаких признаков того, что срок истек и он больше работать не будет. Драйвер открывается как и раньше, все функции возвращают результат S UCCESS однако программа не работает, потому что драйвер пишет не то и не туда и читает не оттуда и не всегда. При этом можно подумать, что проблемы с аппаратурой, поэтому при использовании Win D r i vera лучше отыскать serial number и зарегистрировать. Слишком коварная у него система защиты.
Numega Driver Studio.имеет в своем составе аналогичный компонент: Driver Agent сгенерит все необходимое для использования универсального драйвера. Вы даже сможете создать свой файл.sys, который будет работать в составе ядра и делать там все, что вы запрограммируете, например обрабатывать прерывания. При этом вникать опять же ни во что не придется. За день разработаете свой драйвер.
Оба пакета содержат средства для написания настоящих драйверов, НО при помощи DriverStudio или WinDriver это делать значительно проще, чем при помощи только DDK , в дополнение они имеют хорошую документацию касающуюся общих вопросов драйверов, более читаемую чем в DDK . Кстати DDK для работы с ними необходимо установить.
Установив Numega Driver Works, Вы открываете студию (не Driver , а Microsoft Visual Studio ), выбираете там NewProject и видете в окне мастера рядом с
MFC App Wizard
NT/WDM Driver Wizard
Мастер за 9 шагов, сгенерит проект из которого получается драйвер и exe-шник, который этот драйвер тестирует. Кроме того в Driver Studio входит (я бы назвал это Driver Developmen Foundational Classes) набор классов, которые содержат все необходимое для разработки драйверов, так же как MFC для разработки приложений.
Ну, а если вам необходимо прочитать — записать байт в порт, не используя прерываний, так тут ни каких драйверов писать не надо, все уже написано до нас.
Универсальный драйвер, который позволяет обращаться к портам ввода-вывода. Больше он ничего не может, но в большинстве случаев можно обойтись и этим. Драйвер этот называется PortIo .sys и входит в состав примеров прилагаемых к Numega Driver Works . Я его скомпилировал, вам остается скачать и использовать. Драйвер предоставляет 4 функции: Open, Close,Read и Write. Есть тестовое приложение которое демонстрирует как эти функции использовать.
Чтобы установить драйвер надо:
- Поместить файл portio.sys в C:\WINDOWS\SYSTEM32\DRIVERS\
- Прописать его в реестре. Для XP и 2000 это делается командой regini portio.ini в результате в разделе HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services появится раздел PortIo.
В нем параметры:
ErrorControl 0x00000001 ImagePath \SystemRoot\System32\Drivers\portio.sys Type 0x00000001 Start 0x00000002 Перезагрузите систему.
Драйвер установлен можно использовать.
Смотрите тестовое приложение.