Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
223
Добавлен:
20.02.2016
Размер:
168.45 Кб
Скачать

[8.1.1.3] Завершение запроса в/в

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

[8.1.1.4] Пример обработки запросов чтения/записи

Пример обработки запросов чтения/записи. Получение адреса буфера для чтения/записи и его длины. Такой код вставляется в обработчик диспетчерских функций MajorFunction[IRP_MJ_READ], MajorFunction[IRP_MJ_WRITE].

//получение адреса буфера для чтения/записи

//в случае буферизованного в/в

BufferAddress = Irp->AssociatedIrp.SystemBuffer;

//в случае прямого в/в

BufferAddress = MmGetSystemAddressForMdl( Irp->MdlAddress );

//вслучаеNeither i/o

BufferAddress = Irp->AssociatedIrp.UserBuffer;

//получение длины буфера для чтения/записи

stack = = IoGetCurrentIrpStackLocation( Irp );

BufferLength = stack->Parameters.Read.Length;

[8.1.2] Irp_mj_device_controLиIrp_mj_internal_device_control [8.1.2.1] Пояснения по использованию

Как говорилось выше, точка входа драйвера IRP_MJ_DEVICE_CONTROL вызывается при вызове пользовательской программой функции DeviceIoControl(). Прототип этой функции показан на рис.:

BOOL DeviceIoControl(

HANDLE hDevice, // описатель открытого устройства

DWORD dwIoControlCode, // контрольный код запрашиваемой операции

LPVOID lpInBuffer, // адрес буфера со входными данными

DWORD nInBufferSize, // размер входного буфера

LPVOID IpOutBuffer, // адрес буфера для приема выходных данных

DWORD nOutBufferSize, // размер выходного буфера

LPDWORD IpBytesReturnedy // адрес переменной для получения числа реально

// переданных байтов данных

LPOVERLAPPED IpOverlapped // адрес структуры для обеспечения асинхронности в/в

);

Рис. .Прототип функции DeviceIoControl().

Зачемнуженirp_mj_device_control?Когда драйвер поддерживает определенный тип устройства, такое устройство обычно имеет набор специализированных возможностей, которые могут управляться через драйвер. Эти возможности не могут быть задействованы использованием стандартных кодов функций irp_mj_create, irp_mj_close, irp_mj_read и irp_mj_write. Например, драйвер устройства для лентопротяжного устройства SCSI должен обеспечить механизм, который дает возможность пользователям послать запрос на стирание ленты. Такие зависящие от устройства запросы описываются, используя главный функциональный код irp_mj_device_control. Устройство обычно может принимать несколько разнотипных команд. Для драйвера тип такой команды указывается Кодом Управления ввода-вывода (IOCTL), который передается как часть запроса в/в.

Возвращаясь к функции DeviceIoControl(), код управления в/в (IOCTL) указывается во втором параметре этой функции. Код управления в/в имеет специальный формат, указывающий метод передачи буфера и другую информацию. Этот формат будет рассмотрен в следующем разделе.

Путаница может возникнуть при задании буфера для в/в. Как видно из прототипа функции DeviceIoControl(), она может передавать 2 буфера (3 и 5 параметры). Несмотря на названия буферов – входной и выходной буфер – выходной буфер может быть использован как для передачи данных в драйвер, так и для приема данных из драйвера. Разница будет в используемом методе передачи буфера. Использование буферов будет подробно рассмотрено в разделе “Получение буфера”.

Соседние файлы в папке Лабы по драйверам