Диспетчерские точки входа драйвера
При использовании метода 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;
