Поделиться через


DispatchReadWrite с использованием буферизованного В/В

Любой драйвер устройства низкого уровня, который настраивает объекты устройства для буферизованного ввода-вывода, удовлетворяет запросу на чтение, возвращая данные, передаваемые с устройства в заблокированный буфер пространства системы в Irp-AssociatedIrp.SystemBuffer>. Он удовлетворяет запросу на запись путем передачи данных из того же буфера на устройство.

Следовательно, подпрограмма DispatchReadWrite такого драйвера устройства обычно выполняет следующие действия при получении запроса на передачу:

  1. Вызывает IoGetCurrentIrpStackLocation и определяет направление запроса на передачу.

  2. Проверяет допустимость параметров запроса.

    • Для запроса на чтение подпрограмма обычно проверяет значение IoStackLocation-Parameters.Read.Length> драйвера, чтобы определить, достаточно ли размер буфера для получения данных, передаваемых с устройства.

      Например, драйвер класса системной клавиатуры обрабатывает запросы на чтение, поступающие только из потока ввода пользователя Win32. Этот драйвер определяет структуру KEYBOARD_INPUT_DATA для хранения нажатий клавиш с устройства и в любой момент содержит некоторое количество таких структур во внутреннем кольцевом буфере, чтобы удовлетворять запросы на чтение по мере их поступления.

    • Для запроса на запись подпрограмма обычно проверяет значение в Parameters.Write.Length и проверяет данные в Irp-AssociatedIrp.SystemBuffer> при необходимости: то есть, если устройство принимает только структурированные пакеты данных, содержащие члены с определенными диапазонами значений.

  3. Если какие-либо параметры недопустимы, подпрограмма DispatchReadWrite немедленно завершает IRP, как уже описано в разделе «Завершение IRPs». В противном случае подпрограмма передает IRP для дальнейшей обработки другими подпрограммами драйвера, как описано в разделе "Передача IRPs вниз стека драйверов".

Драйверы устройств низкого уровня, использующие буферный ввод-вывод, обычно должны удовлетворять запросу на передачу путем чтения или записи данных размера, указанного источником запроса. Такой драйвер, скорее всего, определяет структуру данных, поступающих из или отправляемых на его устройство, и, вероятно, буферизует структурированные данные внутри себя, как это делает драйвер класса клавиатуры системы.

Драйверы, которые внутренне буферят данные, должны поддерживать запросы IRP_MJ_FLUSH_BUFFERS и запросы IRP_MJ_SHUTDOWN.

Драйвер самого высокого уровня в цепочке обычно отвечает за проверку параметров входного IRP перед передачей запроса на чтение и запись для более низких драйверов. Следовательно, многие драйверы нижнего уровня могут предположить, что их позиции в стеке ввода-вывода в IRP для операций чтения и записи имеют допустимые параметры. Если драйвер самого низкого уровня в цепочке знает о ограничениях, связанных с устройством для передачи данных, этот драйвер должен проверить допустимость параметров в расположении стека ввода-вывода.