2.4.3 Рабочие процедуры обработки IRP-пакетов
Все функции, зарегистрированные в процедуре DriverEntry путём заполнения массива MajorFunction, вызываются Диспетчером ввода/вывода для обработки соответсвующих запросов от клиентов драйвера. Эти запросы всегда оформлены в виде специальных структур данных - IRP-пакетов, память под которые выделяется Диспетчером ввода/вывода в нестраничном системном пуле. Структура IRP-пакета такова, что он состоит из заголовка фиксированного размера и IRP-стека, размер которого зависит от количества объектов устройств в стеке.
2.4.3.1 Заголовок IRP пакета. Структура заголовка IRP-пакета имеет следующие поля:
Поле IoStatus типа IO_STATUS_BLOCK содержит два подполя:
Status содержит значение, которое устанавливает драйвер после обработки пакета;
В Information чаще всего помещается число переданных или полученных байт.
Поле AssociatedIrp.SystemBuffer типа PVOID содержит указатель на системный буфер для случая, если устройство поддерживает буферизованный ввод/вывод;
Поле MdlAddress типа PMDL содержит указатель на MDL-список, если устройство поддерживает прямой ввод вывод;
Поле UserBuffer типа PVOID содержит адрес пользовательского буфера для ввода/вывода;
Поле Cancel типа BOOLEAN - это индикатор того, что пакет IRP должен быть аннулирован.
2.4.3.2 Стек IRP-пакета. Основное назначение ячеек стека IRP-пакета состоит в том, чтобы хранить функциональный код и параметры запроса на ввод/вывод. Для запроса, который адресован драйверу самого нижнего уровня, соответствующий IRP пакет имеет только одну ячейку стека. Для запроса, который послан драйверу верхнего уровня, Диспетчер ввода/вывода создает пакет IRP с несколькими стековыми ячейками - по одной для каждого объекта устройства.
Каждая ячейка IRP-стека содержит:
MajorFunction типа UCHAR - это код, описывающий назначение операции;
MinorFunction типа UCHAR - это код, описывающий суб-код операции;
DeviceObject типа PDEVICE_OBJECT - это указатель на объект устройства, которому был адресован данный запрос IRP;
FileObject типа PFILE_OBJECT - файловый объект для данного запроса;
Parameters типа union - применение зависит от значения MajorFunction.
Диспетчер ввода/вывода использует поле MajorFunction для того, чтобы извлечь из массива MajorFunction нужную для обработки запроса процедуру.
Каждая процедура обработки IRP пакетов должна в качестве параметров принимать:
Указатель на объект устройства, для которого предназначен IRP запрос;
Указатель на пакет IRP, описывающий этот запрос;
2.4.3.3 Функция обработки пакетов IRP_MJ_CREATE. Данная функция предназначена для обработки запросов на получение дескриптора драйвера от пользовательских приложений или вышестоящих драйверов. Как правило, эта функция просто помечает IRP-пакет, как завершённый.
2.4.3.4 Функция обработки пакетов IRP_MJ_CLOSE. Данная функция предназначена для обработки запросов на закрытие дескриптора драйвера от пользовательских приложений или вышестоящих драйверов. Как правило, эта функция просто помечает IRP-пакет, как завершённый.
2.4.3.5 Функция обработки пакетов IRP_MJ_DEVICE_CONTROL. Данная функция позволяет обрабатывать расширенные запросы от клиентов пользовательского режима, служат чаще всего для обмена данными между приложением и драйвером. Такой запрос может быть сформирован посредством вызова функции DeviceIoControl из пользовательского режима.
Здесь используются IOCTL-коды (I/O Control code), часть из которых предопределена операционной системой, а часть может создаваться разработчиком драйвера. Такой код задаётся в запросе Диспетчером ввода/вывода при формировании IRP-пакета.
Операции драйвера, которые работают с IOCTL-запросами, часто требуют задания буферной области для размещения входных или выходных данных. Возможна такая ситуация, когда в одном запросе используются оба буффера.
Метод доступа к данным, обеспечиваемый Диспетчером ввода/вывода, определяется в IOCTL-коде. Такими методами могут быть:
METHOD_BUFFERED: входной пользовательский буфер копируется в системный, а по окончании обработки системный копируется в выходной пользовательский буфер.
METHOD_IN_DIRECT: необходимые страницы пользовательского буфера загружаются с диска в оперативную память и блокируются. Далее с помощью DMA осуществляется передача данных между устройством и пользователем.
METHOD_OUT_DIRECT: необходимые страницы пользовательского буфера загружаются с диска в оперативную память и блокируются. Далее с помощью DMA осуществляется передача данных между устройством и пользователем.
METHOD_NEITHER: при данном методе передачи не производится проверка доступности памяти, не выделяются промежуточные буфера и не создаются MDL. В IRP-пакете передаются виртуальные адреса буферов в адресном пространстве инициатора запроса ввода/вывода.
В данном случае флаги, определяющие тип буферизации в объекте устройства, не имеют значения при работе с IOCTL запросами. Механизм буферизованного обмена определяется при каждом задании значения IOCTL в специально предназначенном для этого фрагменте этой структуры данных. Данный подход обеспечивает максимальную гибкость при работе с вызовом пользовательского режима DeviceIoControl.
С точки зрения драйвера, доступ к буферным областям, содержащим данные или предназначенным для данных, осуществляется с помощью следующих полей структур [1]:
METHOD_BUFFERED |
METHOD_IN_DIRECT или METHOD_OUT_DIRECT |
METHOD_NEITHER |
||
Input Буфер с данными |
Использует буферизацию (системный буфер) Адрес буфера в системном адресном пространстве указан в pIrp->AssociatedIrp.SystemBuffer |
Клиентский виртуальный адрес в Parameters. DeviceIoControl. Type3InputBuffer |
||
Длина указана в Parameters.DeviceIoControl.InputBufferLength |
||||
Output Буфер для данных |
Использует буферизацию (системный буфер) Адрес буфера в системном адресном пространстве указан в pIrp-> AssociatedIrp. SystemBuffer |
Использует прямой доступ, клиентский буфер преобразован в MDL список, указатель на который размещен в pIrp->MdlAddress |
Клиентский виртуальный адрес в pIrp->UserBuffer |
|
Длина указана в Parameters.DeviceIoControl.OutputBufferLength |
- 1. Введение
- 2. Аналитический раздел
- 2.1 Техническое задание
- 2.2 Обзор архитектуры Windows NT 5.x
- 2.3 Классификация драйверов
- 2.4 Общая структура Legacy-драйвера
- 2.4.1 Процедура DriverEntry
- 2.4.2 Процедура DriverUnload
- 2.4.3 Рабочие процедуры обработки IRP-пакетов
- 2.4.4 ISR - процедура обработки прерываний
- 2.4.5 DPC - процедура отложенного вызова
- 3. Конструкторский раздел
- 3.1 Legacy-драйвер
- 3.1.1 Процедура DriverEntry
- 3.1.2 DriverUnload
- 3.1.3 DispatchCreate и DispatchClose
- 3.1.4 DispatchDeviceControl
- 3.2 Пользовательское приложение
- 4. Технический раздел
- 4.1 Выбор операционной системы и среды программирования
- 4.2 Интерфейс
- 4.3 Системные требования
- 3.7. Профилировщик
- Профилировщик
- 15. Производительность профилировщика основания
- 8.1.3. Использование sql Profiler (профилировщика)
- Техническая характеристика профилировщиков
- 8.16.Профилировщик .
- § Е17-17. Планировка и уплотнение основанияили выравнивающего слоя профилировщиком дс-502а (д-345а) Техническая характеристика профилировщика дс-502а (д-345а)
- Техническая характеристика профилировщиков
- Профилировщиками дс-97, дс-108