Объект-устройство

Диспетчер ввода/вывода определяет тип объекта - объект-устройство, используемый для представления физического, логического или виртуального устройства, чей драйвер был загружен в систему. Формат объекта-устройство определяется частично документированной структурой данных 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().