Александр Тарво - Использование NuMega DriverStudio для написания WDM-драйверов
- Название:Использование NuMega DriverStudio для написания WDM-драйверов
- Автор:
- Жанр:
- Издательство:неизвестно
- Год:неизвестен
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Александр Тарво - Использование NuMega DriverStudio для написания WDM-драйверов краткое содержание
Использование NuMega DriverStudio для написания WDM-драйверов - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
В отличие от обычного не-WDM драйвера, процедура инициализации WDM-драйвера выполняет весьма ограниченное число функций: в основном это загрузка некоторых внутренних переменных на основе данных реестра. WDM-драйвер не инициализирует ресурсы устройства при старте в вызове EntryPoint. Для этого существует объект устройства.
WDM-драйвер экспортирует метод AddDevice, который вызывается системой, если обнаружено устройство, поддерживаемое данным драйвером. Этот метод отвечает за создание объектов устройств, соответствующих системным физическим объектам устройств (Physical Device Object, PDO).
Объект драйвера может содержать дополнительные методы для реинициализации драйвера на более поздних стадиях загрузки системы. Такой подход необходим, если в системе присутствует несколько драйверов, критичных к порядку их загрузки. Впрочем, такие проблемы встречаются нечасто.
В принципе, хорошо спроектированный драйвер должен экспортировать метод Unload, который вызывается при выгрузке драйвера. Но такие случаи встречаются довольно редко.
Как было упомянуто выше, драйвер обращается к системному реестру при инициализации. Системный реестр (registry) — системная база данных, организованная в виде дерева, похожего на дерево каталогов. Каждую ветвь этого дерева (реестра) называют разделом (key), каждый лист – параметром (value). Данные, хранящиеся в реестре, могут быть разных типов: целое (integer), строка, набор байтов.
Система позволяет каждому драйверу хранить данные в реестре. Эти данные используются драйверами при старте и инициализации. Обычно драйвер хранит данные в разделе HKLM\SYSTEM\CurrentControlSet\Services\<���имя драйвера>\Parameters\.
В DriverWorks есть класс KRegistryKey, который облегчает доступ к параметрам реестра. Он имеет методы для чтения (QueryValue), записи (WriteValue), удаления (Delete) значений ключей реестра. При вызове конструктора KRegistryKey сразу указывается ключ, с которым будет связан создаваемый объект. Далее можно изменить ключ при помощи метода Reconstruct.
Объекты запроса на ввод-вывод, более известные, как пакеты запроса на ввод-вывод (I/O request packet, IRP — так мы и будем их называть в дальнейшем), предназначены для управления драйверами режима ядра.
Физически IRP представляет собой весьма сложную структуру данных, содержащую множество полей, таких как код статуса, указатель на буфер пользователя, указатель на IRP драйвера более высокого уровня, различные флаги и т.п. Многие из этих полей не используется драйверами режима ядра, но необходимы для того, чтобы IRP был функционально полным инструментом управления драйверами. Т.е. при помощи IRP можно управлять любым типом драйвера. При желании увидеть структуру IRP во всем ее великолепии — см. Win2000 DDK.
Обмен информацией и управление драйверами при помощи IRP выглядит приблизительно следующим образом: когда приложение пользователя посылает данные или пытается получить данные из устройства, диспетчер ввода-вывода формирует IRP и отправляет его драйверу, отвечающему за данное устройство. Объект драйвера получает этот IRP и перенаправляет его одному из своих объектов устройств. Объект устройства, получив пакет, может либо начать его обработку немедленно, либо поставить его в очередь, чтобы обработать этот пакет позже. Что именно сделает объект устройства, зависит от того, какой пришел IRP, от состояния объекта устройства и от состояния самого устройства. После того, как пакет будет обработан, объект устройства пошлет IRP с информацией о результате операции обратно диспетчеру ввода-вывода.
Каждый IRP описывает операцию В/В, которая может быть выполнена устройством. Для того, чтобы драйвер смог получить информацию о том, какая именно операция должна быть выполнена, IRP содержит целый набор атрибутов: старший и младший коды функции, код статуса и различные параметры: число байт, которые должны быть прочитаны, смещение и т.п. За время своего существования IRP может проходить несколько уровней иерархии драйверов устройств в системе. Поэтому в пакете резервируется место для сохранения данных и параметров, необходимых для следующего драйвера в иерархии — так называемый "стек IRP", "IRP stack location". Когда объект устройства обрабатывает запрос, то он имеет доступ только к тем участкам стека, которые предназначены для использования им или устройством более низкого уровня, которому будет перенаправлен IRP.
Рис. 3 – Интерфейс с драйвером при помощи IRP
IRP могут создаваться как диспетчером В/В, так и самими драйверами. Чаще всего это происходит при выполнении функций CreateFile, CloseFile, ReadFile, WriteFile и DeviceControl.
IRP может быть уничтожен, если необходимо отменить операцию В/В, например, при закрытии приложения. Объект IRP содержит указатель на функцию, вызываемую при уничтожении пакета.
Объекты устройств являются экземплярами класса KDevice или KPnpDevice. Эти классы являются краеугольными камнями архитектуры DriverWorks: они представляют собой как бы программный образ тех устройств, которые присутствуют в системе. Именно объекты устройств обеспечивают управление и обмен данными с внешними устройствами, управление их ресурсами — линиями прерываний, каналами ПДП, диапазонами адресов памяти, портами В/В и т.п. Когда выполняется системный вызов типа CreateFile, ReadFile, WriteFile, диспетчер В/В посылает IRP соответствующему драйверу. Но сам драйвер, вернее объект драйвера, не выполняет никаких операций по обработке этого пакета — он просто передает его объекту устройства и забывает о самом существовании этого IRP. Это естественно, ведь управление физическим устройством — не его задача, это дело соответствующего объекта устройства.
Класс KDevice является суперклассом для всех классов устройств. Но на практике он сейчас почти не используется. Чаще используют его потомка – класс KPnpDevice. Этот класс предназначен для управления PnP-устройствами, т.е. устройствами, которые конфигурируется системой. В данный момент практически все устройства являются PnP-устройствами. Появление таких устройств здорово облегчило жизнь разработчикам драйверов: использовать KPnpDevice намного проще, а часто и безопаснее, чем KDevice. Еще бы, ведь в данном случае все проблемы конфигурирования и инициализации ресурсов оборудования ложатся на широкие плечи системы.
Любой объект устройства содержит стандартные методы обработки запросов на чтение, запись и управление устройством (device control). Эти методы вызываются при вызове соответствующих функций API ReadFile(), WriteFile(), DeviceControl().
Каждый драйвер содержит минимум один объект устройства. Как было упомянуто выше, объект устройства является экземпляром класса, порожденного программистом от класса KDevice или KPnpDevice. Для придания функциональности объекту устройства разработчик драйвера может переопределять виртуальные методы суперкласса, включая те методы, которые обрабатывают различные типы IRP, а также добавлять свои свойства и методы в класс. В процессе разработки можно использовать как иерархию классов DriverStudio, так и функции DDK. Впрочем, для большинства задач без использования DDK вполне можно обойтись.
Читать дальшеИнтервал:
Закладка: