Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции / Лекция № 10 Драйверы устройств в MS Windows.ppt
Скачиваний:
11
Добавлен:
07.08.2024
Размер:
425.98 Кб
Скачать

Драйверы устройств в Windows NT

Инструментарий для разработки драйверов для Windows: 1.Microsoft DDK (Driver Development Kit). В DDK не входит полноценная интегрированная среда разработки­ (Integrated Development Environment, IDE) – основный инструмент.

2.Есть пакеты разработки драйверов­ и от третьих фирм: WinDriver или NuMega Driver Studio, например. Но у них есть отличия базиса функций Microsoft (порой довольно большие) и масса других мелких неудобств. Так что DDK — лучший вариант.

3.Для написания­ драйверов с использованием новейших технологий и нововведений Microsoft — априори KMDF и UMDF.

4.Если же писать драйверы исключительно на ассемблере, то подойдет KmdKit (KerneiMode Driver Development Kit) для MASM32. Правда, этот пакет только для Windows 2000/ХР.

Структура простейшего драйвера режима ядра в Windows NT

DDK предназначен для разработки драйверов на языке C. Здесь речь пойдет о разработке драйвера режима ядра на ассемблере. А программисту на ассемблере без DDK также не обойтись:

во-первых, понадобится документация, во-вторых, библиотечные файлы,

в-третьих, заголовочные файлы (правда их придется переводить на синтаксис понятный ассемблеру), в-четвертых, конечно же, примеры исходных кодов драйверов (исходники, разумеется, написаны на C).

Самые необходимые определения констант и структур в синтаксисе ассемблера masm, содержащие их включаемые файлы, а также многое другое, можно найти в KmdKit.

Структура простейшего драйвера режима ядра в Windows NT

Фактически драйвер можно представить как довольно-таки обычную DLL-библиотеку уровня ядра.

Таким образом, далее можно представить драйвер просто как набор процедур, периодически вызываемых внешними программами­.

Несмотря на то, что процедуры драйверов для разных устройств сильно отличаются, есть общая структура и общие функции для всех драйверов­. Главные из них составляют так называемый "скелет", на основе которого строится любой драйвер — каким бы сложным он ни был.

Структура простейшего драйвера режима ядра в Windows NT

Как и у любого выполнимого модуля, у драйвера должна быть точка входа, на которую система передаст управление после загрузки драйвера в память. Как и полагается, в программе на ассемблере точкой входа является первая инструкция, обозначенная меткой указанной в директиве end, и это функция инициализации драйвера:

DriverEntry proc pDriverObject:PDRIVER_OBJECT, pusRegistryPath:PUNICODE_STRING

.

.

.

DriverEntry endp

DriverEntry — ключевая функция драйвера. Ее главные задачи — произвести­ все необходимые действия по инициализации и определить точки входа для остальных функций драйвера. Эта функция вызывается при загрузке драйвера. Вышеприведенный код — прототип этой функции.

Структура простейшего драйвера режима ядра в Windows NT

Как видно, она принимает два аргумента — два указателя. Первый аргумент — указатель на объект DriverObject типа

PDRIVER_OBJECT.

Он

позволяет

функции

DriverEntry

определить указатели

на функции

Dispatch,

Startio, а также

на функцию выгрузки драйвера в объекте драйвера.

 

Windows является объектно-ориентированной системой. Поэтому, понятие объект распространяется на все, что только можно, и что нельзя тоже. И драйверы не являются исключением. Загружая драйвер, система создает объект "драйвер" (driver object), представляющий для нее образ драйвера в памяти. Через этот объект система управляет драйвером. Звучит красиво, но не дает никакого представления о том, что же в действительности происходит.

Структура простейшего драйвера режима ядра в Windows NT

Если отбросить всю эту объектно-ориентированную мишуру, то станет очевидно, что объект "драйвер" представляет собой обыкновенную структуру данных типа DRIVER_OBJECT (определена в \include\w2k\ntddk.inc). Некоторые поля этой структуры заполняет система, некоторые придется заполнять программисту. Обращаясь к этой структуре, система и управляет драйвером.

Аргумент­ RegistryPath передает функции DriverEntry указатель на раздел реестра с параметрами инициализации драйвера.

При выходе из функции надо вернуть системе некое значение, указывающее на то, как прошла инициализация драйвера. Если вернуть STATUS_SUCCESS, то инициализация считается успешной, и драйвер остается в памяти. Любое другое значение указывает на ошибку, и в этом случае драйвер выгружается системой.

Структура простейшего драйвера режима ядра в Windows NT

Каждый драйвер имеет хотя бы одну процедуру Dispatch:

DispatchRoutine proc stdcall pDeviceObject:PDEVICE_OBJECT, pIrp:PIRP

.

.

.

DispatchRoutine endp

pDeviceObject - указатель на объект "устройство" (структура DE- VICE_OBJECT). Если драйвер обслуживает несколько устройств, то по параметру определяется, к какому устройству пришел запрос. pIrp - указатель на пакет запроса ввода-вывода (структура IRP). Диспетчер ввода-вывода создает IRP. Через pIrp драйверу передается указатель на IRP. Получив IRP, драйвер выполняет указанную операцию и возвращает его диспетчеру, чтобы тот, либо завершил операцию, либо передал пакет другому драйверу для дальнейшей обработки. Завершать IRP или передавать его дальше решает сам

Структура простейшего драйвера режима ядра в Windows NT

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

Если драйвер устройства не может завершить все возможные запросы ввода/вывода в его Dispatch- процедуре, он должен иметь процедуру StartIo:

StartIo proc stdcall pDeviceObject:PDEVICE_OBJECT, pIrp:PIRP

.

.

.

StartIo endp

Структура простейшего драйвера режима ядра в Windows NT

Драйвер должен иметь процедуру DriverUnload, если он может быть выгружен в процессе работы системы:

DriverUnload proc pDriverObject:PDRIVER_OBJECT

.

.

.

DriverUnload endp

Здесь, конечно, перечислено далеко не все и не полностью (на это есть справочники), а только необходимая база, минимально достаточная для понимания примера простейшего драйвера.

Пример. Драйвер beeper – звук из системного динамика

Задача этого драйвера, сгенерировать на системном

динамике звук определенной частоты и завершить свою работу.

Структура простейшего драйвера режима ядра в Windows NT

.386

.model flat

option casemap:none

include \masm32\include\w2k\ntstatus.inc include \masm32\include\w2k\ntddk.inc include \masm32\include\w2k\hal.inc includelib \masm32\lib\w2k\hal.lib

.code

DriverEntry proc pDriverObject:PDRIVER_OBJECT, pusRegistryPath:PUNICODE_STRING cli

mov al, 10110110b out 43h, al

mov eax, 7FFFH out 42h, al mov al, ah

out 42h, al in al, 61h or al, 11b out 61h, al sti

mov ecx, 1800000h delay: loop delay

cli

in al, 61h

and al, 11111100b out 61h, al

sti

mov eax, STATUS_DEVICE_CONFIGURATION_ERROR ret

DriverEntry endp end DriverEntry