Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Учебное пособие 3000377.doc
Скачиваний:
29
Добавлен:
30.04.2022
Размер:
2.52 Mб
Скачать

3.2. Объекты подсистемы ввода-вывода

При разработке операционной системы Windows широко использовались принципы объектно-ориентированной технологии программирования. Подсистема ввода-вывода не является исключением. Ее работа основана на взаимодействии следующих программных объектов:

  • объект файл (file object)

  • объект устройство (device object)

  • объект драйвер (driver object)

  • объект пакет запроса ввода-вывода (Input-output Request Packet, IRP)

  • объект блок стека запроса ввода вывода (IRP stack block)

Рассмотрим структуру и назначение этих объектов более внимательно.

Объект файл

Объект файл представлен экземпляром структуры FILE_OBJECT. Отметим некоторые поля этой структуры:

  • PDEVICE_OBJECT DeviceObject – указатель на объект-устройство, содержащее файл (или на устройство ввода-вывода, адресуемое через файловый интерфейс);

  • UNICODE_STRING FileName – имя файла;

  • LARGE_INTEGER CurrentByteOffset – смещение от начала файла (используется только для синхронных на пользовательском уровне операций ввода-вывода с настоящими файлами);

  • BOOLEAN ReadAccess, WriteAccess, DeleteAccess – флаги разрешенного доступа;

  • BOOLEAN SharedRead, SharedWrite, SharedDelete – флаги разрешенных видов совместного доступа.

В рамках рассматриваемой темы, наиболее интересно поле DeviceObject, указывающее на объект устройство, сопоставленное с данным файлом.

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

Объект устройство представлен в системе экземпляром структуры DEVICE_OBJECT. Отметим некоторые поля этой структуры:

  • LONG ReferenceCount – счетчик ссылок на данный объект;

  • PDRIVER_OBJECT DriverObject – указатель на объект драйвер, управляющий данным устройством;

  • PDEVICE_OBJECT NextDevice – указатель на следующее устройство в списке устройств, управляемых одним и тем же драйвером;

  • PDEVICE_OBJECT AttachedDevice – указатель на присоединенное устройство, которое должно продолжить обработку запроса при использовании многоуровневой структуры драйверов (например, функциональный драйвер может ссылаться на виртуальное устройство, сопоставленное с драйвером-фильтром нижнего уровня);

  • PIRP CurrentIrp – указатель на текущий пакет запроса ввода-вывода, обрабатываемый драйвером;

  • PVOID DeviceExtention – указатель на внешнюю область памяти, выделенную драйвером и сопоставленную с объектом устройство для хранения специфичных для драйвера и устройства данных.

Таким образом, объект устройство связывает объект файл с драйвером, пакетом запроса ввода-вывода и следующим устройством в стеке обработки запроса при многоуровневой обработке запроса ввода-вывода несколькими драйверами.

Объект драйвер

Объект драйвер представлен в системе экземпляром структуры DRIVER_OBJECT. Отметим некоторые поля этой структуры:

  • PDEVICE_OBJECT DeviceObject – начало списка устройств, управляемых данным драйвером;

  • PVOID DriverStart – точка входа в программу драйвера, взятая из файла образа драйвера; указывает на процедуру, выполняющую начальную инициализацию драйвера, включая сохранение в структуре DRIVER_OBJECT точек входа в процедуры драйвера;

  • UNICODE_STRING DriverName – имя файла с образом драйвера;

  • PDRIVER_UNLOAD DriverUnload – точка входа в процедуру выгрузки драйвера, выполняющую освобождение всех ресурсов;

  • PDRIVER_DISPATCH MajorFunction[] – массив адресов вхождения в процедуры драйвера.

Прежде всего, объект драйвер хранит адреса процедур, предоставляемых операционной системе драйвером для организации интерфейса доступа к устройству. Точки входа в процедуры драйвера называются диспетчерскими процедурами. Они хранятся в массиве MajorFunction и определенные следующим образом:

typedef NTSTATUS (*PDRIVER_DISPATCH) (PDEVICE_OBJECT, PIRP);

Таким образом, диспетчерская процедура получает указатель на пакет запроса ввода-вывода, хранящий код операции и параметры, и на объект устройство, к которому адресован запрос. Указание устройства необходимо, поскольку один и тот же драйвер может управлять несколькими устройствами.

Для каждого числового значения индекса массива MajorFunction определено символическое имя, позволяющее проще идентифицировать процедуры драйвера. В частности, определены следующие символические имена:

#define IRP_MJ_CREATE 0 #define IRP_MJ_CLOSE 2 #define IRP_MJ_READ 3 #define IRP_MJ_WRITE 4 #define IRP_MJ_DEVICE_CONTROL 14 #define IRP_MJ_PNP 27