Получение буфера

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

Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: