
28.09.2007, 00:33
|
|
Постоянный
Регистрация: 27.08.2006
Сообщений: 367
С нами:
10370602
Репутация:
472
|
|
Тут указаны примеры для разных методов:
Код:
stack = IoGetCurrentlrpStackLocation (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.TypeInputBuffer;
InLength = irpStack->Parameters.DeviceIoControl.InputBufferLength;
OutBuffer = Irp->UserBuffer;
OutLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
break;
Также обязательно прочитай:
При использовании буферизованного метода, Диспетчер ввода/вывода выделяет в системной невыгружаемой памяти промежуточный буфер, размер которого равен максимальному из размеров буферов InBuffer и OutBuffer. Если при запросе был определен InBuffer и его длина не нулевая, содержание InBuffer копируется в промежуточный буфер. В любом случае, адрес промежуточного буфера помещается в IRP в поле Associatedlrp.SystemBuffer. Затем IRP, содержащий запрос, передается драйверу.
Данные, находящиеся в промежуточном буфере, могут читаться и перезаписываться драйвером. Затем драйвер размещает в промежуточном буфере данные, которые нужно вернуть в OutBuffer.
При завершении запроса ввода/вывода, если OutBuffer был определен при запросе ввода/вывода и его длина не нулевая, Диспетчер ввода/вывода копирует из промежуточного буфера в OutBuffer столько байтов, сколько было указано в поле 1гр->IoStatus.Information. После этого, как и при любом буферизированном запросе Ввода/вывода, Диспетчер ввода/вывода освобождает промежуточный буфер.
При использовании методов METHOD_IN_DIRECT и METHOD_OUT_ DIRECT, буфер InBuffer, если он определен в запросе ввода/вывода и его длина не нулевая, обрабатывается в точности так же, как и при буферизованном вводе/выводе. В этом случае выделяется промежуточный буфер, в него копируется InBuffer, указатель на промежуточный буфер помещается в IRP в поле Associatedlrp.SystemBuffer.
Буфер OutBuffer, если он определен в запросе ввода/вывода и его длина не нулевая, обрабатывается в соответствии с прямым вводом/выводом. В этом случае адрес проверяется на возможность доступа (запись или чтение), производится закрепление физических страниц в памяти, и создается таблица описания памяти MDL, описывающая OutBuffer. Указатель на MDL передается в поле Irp->MdlAddress.
При использовании метода METHOD_NEITHER, оба буфера передаются в соответствии с методом Neither. To есть, не производится проверка доступности памяти, не выделяются промежуточные буфера и не создаются MDL. В пакете IRP передаются виртуальные адреса буферов в пространстве памяти инициатора запроса ввода/вывода. Адрес буфера OutBuffer передается в фиксированной части IRP в поле Irp-
>UserBuffer, адрес буфера InBuffer передается в стеке размещения ввода/вывода в поле stack->Parameters.DeviceControl.TypeInputBuffer.
Последний раз редактировалось Ni0x; 28.09.2007 в 15:49..
|
|
|