Создание VxD на Visual C++ без ассемблерных модулей
Страница 4. Структура и функционирование драйвера


 

Структура и функционирование драйвера

VxD представляет собой 32-разрядный исполняемый файл формата LE (Linear Executable), который является частным случаем DLL. Система может вызывать VxD тремя различными способами:

  1. Через диспетчер системных сообщений.
  2. Через таблицу обработчиков сервисных функций.
  3. Через точки входа интерфейсов прикладных программ.

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

Секции файла драйвера

Загружаемый файл драйвера стандартным образом может делиться на секции (сегменты) с различными атрибутами (резидентный, изначально загруженный, уничтожаемый и т.п.). Документация Microsoft утверждает, что секции должны иметь определенные имена, однако это сделано лишь для удобства пользования стандартным макросами и фактически система распознает лишь сами атрибуты секций.

Рекомендованы следующие имена и классы секций для модуля VxD:

  • _LTEXT, _LDATA (класс LCODE) — 32-разрядные секции резидентных кода и данных, которые должны находиться в памяти постоянно. В эти секции включаются процедуры и данные диспетчера системных сообщений, сервисных функций и API, обработчиков прерываний, а также те фрагменты драйвера, для которых нужна предельная скорость выполнения;
  • _PTEXT, _PDATA (класс PCODE) — 32-разрядные секции выгружаемых, или откачиваемых, (pageable) кода и данных, которые в процессе работы системы могут быть автоматически выгружены (paged, swapped) на диск для освобождения системной памяти. Подсистема подкачки VMM автоматически возвращает выгруженные страницы в память в момент запроса к ним, однако такие запросы допускаются только в обычном режиме работы и недопустимы при обработке прерываний или критических системных функций;
  • _ITEXT, _IDATA (класс ICODE) — 32-разрядные секции кода и данных, используемых только при инициализации драйвера. После отработки драйвером функции инициализации VMM автоматически удаляет эти секции из памяти;
  • _RTEXT (класс RCODE) — 16-разрядная секция, в которой размещаются код и данные, используемые при инициализации в реальном режиме (real mode) на этапе начальной загрузки системы. Имеет смысл только для статических драйверов.

Блок описателя драйвера

Ключевым элементом драйвера является структура данных DDB (Device Descriptor Block — блок описателя устройства), которая описывает параметры драйвера. DDB содержит следующие важнейшие поля:

  • Идентификация устройства (драйвера) — имя модуля драйвера (максимум восемь символов) и его идентификатор.
  • Версия драйвера — старший (major) и младший (minor) номера версий, определяющих функциональность драйвера (устройства).
  • Адрес процедуры диспетчера системных сообщений — адрес функции диспетчера, которая будет вызываться для обработки системных сообщений, посылаемых драйверу.
  • Адрес и размер таблицы обработчиков сервисных функций — адрес таблицы указателей (адресов) индивидуальных процедур, которые будут вызываться для выполнения сервисных функций, и количество сервисных функций, выполняемых драйвером.
  • Адреса обработчиков функций API — адреса индивидуальных процедур, которые вызываются для обработки запросов API от 16-разрядных программ (виртуальных машин DOS и программ Win16).

Символическое имя, назначенное DDB, должно быть описано в модуле драйвера в качестве первой экспортируемой точки входа (exported entry). Сам DDB должен находиться в одной секции резидентного кода вместе с диспетчером системных сообщений.

 
« Предыдущая статья   Следующая статья »