Объект-устройство
Диспетчер ввода/вывода определяет тип объекта - объект-устройство,
используемый для представления физического, логического или виртуального устройства,
чей драйвер был загружен в систему. Формат объекта-устройство определяется частично
документированной структурой данных DEVICE_OBJECT. Хотя объект-устройство может
быть создан в любое время посредством вызова функции loCreateDeviceQ, обычно он
создается внутри DriverEntry. Объект-устройство описывает характеристики устройства,
такие как требование по выравниванию буферов и местоположение очереди устройства,
для хранения поступающих пакетов запросов ввода/вывода. Процедура инициализации
драйвера DriverEntry создает по одному объекту-устройству для каждого устройства,
управляемого данным драйвером, посредством вызова процедур, предоставляемых менеджером
ввода/вывода. Процедура инициализации драйвера должна создавать, по крайней мере,
один объект-устройство, некоторые драйверы должны создавать более одного объекта-устройства
в зависимости от уровня, на котором они располагаются в цепочке драйверов.
В каждом объекте-устройстве есть указатель на следующий объект-устройство (либо
NULL) и указатель на объект-драйвер, управляющий Данным устройством. Благодаря
этому диспетчер ввода/вывода может определить, процедуру какого драйвера он должен
вызвать при получении запроса к устройству. Диспетчер ввода/вывода поддерживает
также указатель на объект-устройство, созданный драйвером, в объекте-драйвере.
Большинство драйверов NT используют структуру данных DeviceExtension, указатель
на которую хранится в объекте-устройстве, а ее размер и содержимое определяется
при создании объекта-устройства во время инициализации драйвера. Внутренняя структура
DeviceExtension определяется разработчиками драйверов и используется для хранения
информации о состоянии устройства, некоторого контекста текущего запроса ввода/вывода,
для хранения указателей на описатели различных объектов ядра, то есть для хранения
любых данных, которые нужны драйверу. Диспетчер ввода/вывода выделяет память под
DeviceExtension из резидентной системной области памяти. Так как большинство
процедур драйверов исполняются в контексте произвольного потока, то есть потока,
оказавшегося текущим на момент вызова процедуры драйвера, то область DeviceExtension
является одним из первых мест, где драйвер хранит необходимые ему данные.
Имя устройства и символическая связь При создании объекта-устройства
также может быть указано его имя, которое будет видимо в директории «\Device»
пространства имен диспетчера объектов. Объекты- устройства используются в Windows
NT как точки входа в пространства имен, не контролируемые менеджером объектов.
Если при разборе имени объекта диспетчер объектов встречает объект-устройство,
то он вызывает метод разбора, связанный с этим устройством. Если имя не указано,
объект-устройство может быть использован только внутри драйвера и недоступен извне.
Если быть более точным, такой объект-устройство можно использовать, если иметь
указатель на описывающую его структуру. Именованный объект-устройство доступен
для использования через вызов системного сервиса NtCreateFile(). Для обращения
к именованному объекту-устройству из подсистемы Win32 посредством функции CreateFile()
должны быть предприняты дополнительные действия. Функция CreateFile() ищет имя
устройства в директории Диспетчера Объектов «\??» (NT 4.0 и Win2000), либо «\DosDevices»(NT
3.51). Поэтому в соответствующей директории, а для большей совместимости это должна
быть «\DosDevices», должен быть создан объект (символическая связь), указывающий
на имя устройства в директории «\Device». Обычно связь создается в самом драйвере,
хотя это можно сделать и из прикладной программы пользовательского режима с помощью
Win32- функции DefmeDosDevice(). |