Использование NuMega DriverStudio для написания WDM-драйверов - [14]

Шрифт
Интервал

Итак, для установки драйвера в системе предполагается наличие в системе PCI — карточки XDSP-680. После установки карточки (или перепрограммирования ее из среды Foundation) следует перезагрузить компьютер. При загрузке компьютер обнаружит новое устройство и потребует предоставить драйвер для него. Если же не потребует — значит в системе есть более ранняя версия драйвера. Для этого надо открыть список устройств, установленных на компьютере и обновить драйвер для устройства. Для этого надо указать путь к скрипту xdsp.inf и к файлу драйвера xdsp.sys.

Если же Вы разрабатываете драйвер, который не управляет каким-либо устройством или это устройство не является PnP — необходимо просто установить драйвер стандартными средствами Windows: Пуск→Настройка→Панель управления→Установка оборудования. Когда Windows выведет полный список типов устройств и спросит, какое устройство Вы хотите установить, выберите свой тип устройства.

Если разработанный Вами драйвер не подходит под какой-либо из известных классов устройств, то "Другие устройства" также являются неплохим вариантом. Такая ситуация тоже случается нередко — мне, например, приходилось разрабатывать драйвер для программатора микроконтроллеров, подключавшегося через параллельный порт. Конечно же, он не подходил под какой-либо из известных в Windows типов устройств.

После того, как драйвер будет установлен, нужно будет проверить его функционирование. Запустите скомпилированный файл test_xdsp.exe с параметрами test_xdsp r 32 (команда прочитать 32 байта из устройства). Должно появиться сообщение, похожее на это:

>C:\XDSP\exe\objchk\i386>Test_XDSP.exe r 32

>Test application Test_XDSP starting…

>Device found, handle open.

>Reading from device – 0 bytes read from device (32 requested).

>–, –, –, –, –, –, –, –, –, –, –, –, –, –, –, –, –, –, –, –, –, –, –, –, –, –,

>–, –, –, –, –, –,

В данном случае приложение установило связь с драйвером и прочитало из него 32 байта. Функция чтения в драйвере не определена, поэтому, естественно, драйвер вернет абракадабру. Если же будет получено сообщение вида

>C:\…Projects\XDSPdrv\exe\objchk\i386>Test_XDSP.exe r 32

>Test application Test_XDSP starting…

>ERROR opening device: (2) returned from CreateFile

>Exiting…

 — то приложение не смогло установить связь с драйвером. Следует попробовать переустановить драйвер.

2.3 Наращивание функциональных возможностей драйвера.

Рассмотрим подробно текст драйвера, сгенерированного DriverWizard и внесем в него необходимые изменения.

В проекте пристствуют всего два класса:

XDSP

 класс драйвера;

XDSPDevice

 класс устройства.

Также есть несколько глобальных функций и переменных:

PNPMinorFunctionName — возвращает строку с текстовым названием кода функции IOCTL. Эта функция используется при отладке, когда надо перевести числовое значение кода IOCTL в строку с его названием.

POOLTAG DefaultPoolTag('PSDX') — используется совместно с BoundsChecker для отслеживания возможных переполнений буфера и утечек памяти.

KTrace t("XDSPdrv") — глобальный объект трассировки драйвера. Этот объект используется для вывода сообщений трассировки при работе драйвера. Использование объекта трассировки аналогично использованию класса iostream в С++. Вывод отладочных сообщений производится при помощи оператора <<. Примеры использования объекта трассировки неоднократно встречаются в тексте драйвера, например:

>t << "m_bBreakOnEntry loaded from registry, resulting value: [" << m_bBreakOnEntry << "]\n";

В данном примере объект трассировки используется для вывода строки "m_bBreakOnEntry loaded from registry, resulting value: [" и значения логической переменной m_bBreakOnEntry. Все сообщения трассировки можно прочитать в отладчике SoftIce.

Начнем анализ текста драйвера с класса XDSP (класс драйвера). В строке 31 при помощи макроса DECLARE_DRIVER_CLASS декларируется класс драйвера XDSP. Далее следует метод DriverEntry, который вызывается при инициализации драйвера:

>NTSTATUS XDSPdrv::DriverEntry(PUNICODE_STRING RegistryPath)

>//В строке RegistryPath содержится ключ реестра, в котором система хранит информацию о драйвере.

>{

> //Далее выводится трассировочное сообщение, информирующее о вызове метода DriverEntry:

> t << "In DriverEntry\n";

> //После этого драйвер создает объект Params класса KRegistryKey и считывает данные из

> //реестра для этого драйвера:

> KRegistryKey Params(RegistryPath, L"Parameters");

> //Далее производится проверка на успех:

> if ( NT_SUCCESS(Params.LastError()) ) {

>  //Текст, заключенный в макрос препроцессора DBG будет откомпилирован только в отладочной версии

>  //драйвера.

>#if DBG

>  ULONG bBreakOnEntry = FALSE;

>  // Читается значение переменной BreakOnEntry реестра:

>  Params.QueryValue(L"BreakOnEntry", &bBreakOnEntry);

>  // Если она принимает значение true,то инициировать точку останова в отладчике.

>  if (bBreakOnEntry) DbgBreakPoint();

>#endif

>  //Загрузить остальные параметры реестра.

>  LoadRegistryParameters(Params);

> }

> m_Unit = 0;

> //Вернуть успех

> return STATUS_SUCCESS;

>}

Метод LoadRegistryParameters зaгружает из реестра все остальные параметры, необходимые для драйвера. Впрочем, в нашем драйвере таковых нет, и поэтому функция не выполняет никаких полезных действий (просто загружает значение переменной m_bBreakOnEntry).