Функции, адреса которых записаны в массиве MajorFunctions, вызываются диспетчером ввода / вывода для обработки соответствующих запросов от клиентского драйвера (пользовательских приложений или модулей уровня ядра). Эти запросы оформляются в виде специальных структур – IRP пакетов.
При любом запросе Диспетчер формирует IRP. память для структуры IRP выделяется в нестраничной памяти. В IRP записывается код операции ввода вывода. Пакет IRP состоит из заголовка, который имеет постоянный размер и стека IRP. Стек имеет переменную длину.
Заголовок IRP пакета:
§ Поле IoStatus типа IO _ STATUS _ BLOCK содержит два подполя
§ Status содержит значение, которое устанавливает драйвер после обработки пакета.
§ В Information чаще всего помещается число переданных или полученных байт.
§ Поле AssociatedIrp . SystemBuffer типа void * содержит указатель на системный буфер для случая если устройство поддерживает буферизованный ввод / вывод.
§ Поле MdlAddress типа PMDL содержит указатель на MDL список, если устройство поддерживает прямой ввод вывод.
§ Поле UserBuffer типа void * содержит адрес пользовательского буфера для ввода / вывода.
§ Типа Cancel типа BOOLEAN – это индикатор того, что пакет IRP должен быть аннулирован.
Стек IRP пакета
Основное значение ячеек стека IRP пакета состоит в том, чтобы хранить функциональный код и параметры запроса на ввод / вывод. Для запроса, который адресован драйверу самого нижнего уровня, соответствующий IRP пакет имеет только одну ячейку стека. Для запроса, который послан драйверу верхнего уровня, Диспетчер ввода / вывода создает пакет IRP с несколькими стековыми ячейками – по одной для каждого FDO.
Каждая ячейка стека IRP содержит:
§ MajorFunction типа UCHAR – это код, описывающий назначение операции
§ MinorFunction типа UCHAR – это код, описывающий суб-код операции
§ DeviceObject типа PDEVICE _ OBJECT – это указатель на объект устройства, которому был адресован данный запрос IRP
§ FileObject типа PFILE _ OBJECT – файловый объект для данного запроса
Диспетчер ввода / вывода использует поле MajorFunction для того, чтобы извлечь из массива MajorFunction нужную для обработки запроса процедуру.
Каждая процедура обработки IRP пакетов должна в качестве параметров иметь:
§ Указатель на объект устройства, для которого предназначен IRP запрос
§ Указатель на пакет IRP, описывающий этот запрос
Возвращает такая функция значение типа NTSTATUS, содержащее результат обработки.
Функция обработки пакетов IRP _ MJ _ DEVICE _ CONTROL
Эти функции позволяют обрабатывать расширенные запросы от клиентов пользовательского режима. Такой запрос может быть сформирован посредством вызова функции DeviceIoControl. Каждый IOCTL запрос имеет свой код. Этот код передается как параметр функции DeviceIoControl. Код IOCTL – это 32‑битное число.
Запросы IOCTL служат чаще всего для обмена данными между драйвером и приложением. Для передачи данных в Windows предусмотрены 4 способа
§ METHOD_BUFFERED
Входной пользовательский буфер копируется в системный, а по окончании обработки системный копируется в в выходной пользовательский буфер.
§ METHOD_IN_DIRECT и METHOD_OUT_DIRECT
Необходимые страницы пользовательского буфера загружаются с диска в оперативную память и блокируются. И с помощью DMA осуществляется передача данных между устройством и пользователем.
§ METHOD_NEITHER
При данном методе передачи не производится проверка доступности памяти, не выделяются промежуточные буфера и не создаются MDL. В пакете IRP передаются виртуальные адреса буферов в пространстве памяти инициатора запроса ввода / вывода.
Дата: 2019-05-29, просмотров: 247.