
- •Лекция №7-8. Подсистема в/в. Пакеты запросов ввода/вывода (irp). [7.1] Подсистема в/в и её характеристики.
- •[7.2] Структура irp
- •[7.2.1] Поля в Фиксированной части irp.
- •[7.2.2.] Поля в Стеке размещения Ввода - вывода irp.
- •[7.3] Описание Буфера Данных
- •[7.4] Коды Функции Ввода - вывода
- •[8.1] Передача данных посредством irp и диспетчерские точки входа драйвера
- •[8.1.1] Запросы чтения и записи irp_mj_read и irp_mj_write [8.1.1.1] Определение метода передачи буфера для запросов чтения-записи
- •[8.1.1.2] Получение буфера
- •[8.1.1.3] Завершение запроса в/в
- •[8.1.1.4] Пример обработки запросов чтения/записи
- •[8.1.2.1] Пояснения по использованию
- •[8.1.2.2] Задание кода управления вводом/выводом (ioctl)
- •[8.1.2.3] Получение буфера
- •[8.1.2.4] Завершение запроса в/в
- •[8.1.2.5] Пример обработки
[8.1.2.3] Получение буфера
При использовании буферизованного метода, Диспетчер в/в выделяет в системной невыгружаемой памяти промежуточный буфер, размер которого равен максимальному из размеров буферов InBuffer и OutBuffer. Если при запросе был определен InBuffer, и его длина не нулевая, содержание InBuffer копируется в промежуточный буфер. В любом случае, адрес промежуточного буфера помещается в IRP в поле AssociatedIrp.SystemBuffer. Затем IRP, содержащий запрос, передается драйверу.
Данные, находящиеся в промежуточном буфере, могут читаться и перезаписываться драйвером. Затем драйвер размещает в промежуточном буфере данные, которые нужно вернуть в OutBuffer.
При завершении запроса в/в, если OutBuffer был определен при запросе в/в и его длина не нулевая, Диспетчер в/в копирует из промежуточного буфера в OutBuffer столько байтов, сколько было указано в поле Irp->IoStatus.Information. После этого, как и при любом буферизированным запросе Ввода - вывода, Диспетчер в/в освобождает промежуточный буфер.
При использовании методов METHOD_IN_DIRECT и METHOD_OUT_DIRECT, буфер InBuffer, если он определен в запросе в/в и его длина не нулевая, обрабатывается в точности так же, как и при буферизованном в/в. В этом случае выделяется промежуточный буфер, в него копируется InBuffer, указатель на промежуточный буфер помещается в IRP в поле AssociatedIrp.SystemBuffer.
Буфер OutBuffer, если он определен в запросе в/в и его длина не нулевая, обрабатывается в соответствии с прямым в/в. В этом случае адрес проверяется на возможность доступа (запись или чтение), производится закрепление физических страниц в памяти, и создается таблица описания памяти MDL, описывающая OutBuffer. Указатель на MDL передается в поле Irp->MdlAddress.
При использовании метода METHOD_NEITHER, оба буфера передаются в соответствии с методом Neither. Т.е., не производится проверка доступности памяти, не выделяются промежуточные буфера и не создаются MDL. В пакете IRP передаются виртуальные адреса буферов в пространстве памяти инициатора запроса в/в. Адрес буфера OutBuffer передается в фиксированной части IRP в поле Irp->UserBuffer, адрес буфера InBuffer передается в стеке размещения в/в в поле
stack->Parameters.DeviceControl.Type3InputBuffer
Положение буферов показано в следующей таблице
|
METHOD_BUFFERED |
METHOD_IN_DIRECT |
METHOD_OUT_DIRECT |
METHOD_NEITHER |
||
InBuffer |
Метод передачи |
Buffered I/O |
Buffered I/O |
Buffered I/O |
Виртуальный адрес инициатора запроса |
|
Если существует, то где расположен |
Адрес промежуточного буфера в фиксированной части IRP в поле Irp->AssociatedIrp.SystemBuffer |
В стеке размещения в/в виртуальный адрес инициатора запроса в Parameters. DeviceIoControl. Type3InputBuffer |
||||
Длина |
Длина в байтах в поле Parameters.DeviceIoControl.InputBufferLength в текущем стеке размещения в/в. |
|||||
OutBuffer |
Метод передачи |
Buffered I/O |
Direct I/O |
Direct I/O |
Виртуальный адрес инициатора запроса |
|
Если существует, то где расположен |
Адрес промежуточного буфера в фиксированной части IRP в поле Irp->AssociatedIrp.SystemBuffer |
MDL, адрес в Irp->MdlAddress |
MDL, адрес в Irp->MdlAddress |
Виртуальный адрес инициатора запроса в Irp->UserBuffer |
||
Длина |
Длина в байтах в поле Parameters.DeviceIoControl.OutputBufferLength в текущем стеке размещения в/в. |