Иллюстрированный самоучитель по программированию систем защиты

Диспетчерские точки входа драйвера

При использовании метода METHOD_NEITHER, оба буфера передаются в соответствии с методом Neither. То есть, не производится проверка доступности памяти, не выделяются промежуточные буфера и не создаются MDL. В пакете IRP передаются виртуальные адреса буферов в пространстве памяти инициатора запроса ввода/вывода. Адрес буфера OutBuffer передается в фиксированной части IRP в поле Irp › UserBuffer, адрес буфера InBuffer передается в стеке размещения ввода/вывода в поле stack › Parameters.DeviceControl.Type3InputBuffer.

Положение буферов показано в таблице 7.

Таблица 7. Положение буферов.

  METHOD BUFFERED METHOD IN DIRECT METHOD OUT DIRECT METHOD NEITHER
InBuffer Метод передачи Buffered I/O Buffered I/O Buffered I/O Виртуальный адрес инициатора запроса
Если существует, то где расположен Адрес промежуточного буфера в фиксированной части IRP в поле Irp › AssociatedIrp.SystemBuffer В стеке размещения ввода/вывода виртуальный адрес инициатора запроса в Parame ters.DeviceloControl. TypeSInputBuffer
Длина Длина в байтах в поле Parameters.DeviceloControl.InputBuffer Length в текущем стеке размещения ввода/вывода.
Out Buffer Метод передачи Buffered I/O Direct I/O Direct I/O Виртуальный адрес инициатора запроса
Если существует, то где расположен Адрес промежуточного буфера в фиксированной части IRP в поле Irp › Associate-dlrp.SystemB uffer MDL, адрес в Irp › MdlAd – dress MDL, адрес в Irp › MdlAd – dress Виртуальный адрес инициатора запроса в Irp › UserBuffer
Длина Длина в байтах в поле Parameters.DeviceloControl.OutputBufferLength в текущем стеке размещения ввода/вывода.

Для завершения запроса IRP необходимо установить поле Irp › IoStatus.Information равным числу прочитанных/записанных в буфер байт. В случае буферизованного ввода/вывода это поле укажет Диспетчеру ввода/вывода, сколько байт нужно скопировать из промежуточного буфера в невыгружаемой области системного адресного пространства в пользовательский буфер.

Пример обработки

Пример получения адресов и длин буферов в диспетчерской функции драйвера, обрабатывающей функциональные коды IRP_MJ_CREATE, IRP_MJ_CLOSE и IRP_MJ_DEVICE_CONTROL:

stack = loGetCurrentlrpStackLocation (Irp); switch (pIrpStack › MajorFunction) {
case IRP_MJ_CREATE: case IRP_MJ_CLOSE: break;
case IRP_MJ_DEVICE_CONTROL:
switch (stack › Parameters.DeviceloControl.loControlCode) { case IOCTL_MY_BUFFERED:
InBuffer = Irp › AssociatedIrp.SystemBuffer;
InLength = stack › Parameters.DeviceloControl.InputBuffer.Length;
OutBuffer = Irp › AssociatedIrp.SystemBuffer;
OutLength = stack › Parameters.DeviceloControl.OutputBufferLength; case IOCTL_MY_IN_DIRECT:
//OutBuffer доступен только для чтения InBuffer = Irp › AssociatedIrp.SystemBuffer;
InLength = stack › Parameters.DeviceloControl.InputBufferLength;
OutBuffer = MmGetSystemAddressForMdl(Irp › MdlAddress);
OutLength = stack › Parameters.DeviceloControl.OutputBufferLength; break; case IOCTL_MY_OUT_DIRECT:
//OutBuffer доступен для чтения/записи InBuffer = Irp › AssociatedIrp.SystemBuffer;
InLength = stack › Parameters.DeviceloControl.InputBufferLength;
OutBuffer = MmGetSystemAddressForMdl(Irp › MdlAddress
);
OutLength = stack › Parameters.DeviceloControl.OutputBufferLength; break;
case IOCTL_MY_NEITHER:
InBuffer = irpStack › Parameters.DeviceloControl.Type3InputBuffer;
InLength = irpStack › Parameters.DeviceIoControl.InputBufferLength; OutBuffer = Irp › UserBuffer;
OutLength = irpStack › Parameters.Device!oControl.OutputBufferLength; break;
Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.