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


Сводка по подпрограммам диспетчеризации чтения и записи

При реализации подпрограмм DispatchRead, DispatchWrite или DispatchReadWrite учитывайте следующие моменты:

  • Драйвер самого высокого уровня в цепочке многоуровневых драйверов отвечает за проверка параметры входящих irps чтения и записи для допустимости перед настройкой расположения стека ввода-вывода драйвера следующего нижнего уровня в IRP.

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

  • Если подпрограмма DispatchReadWrite завершает IRP с ошибкой, она должна задать элемент состояния стека ввода-вывода с соответствующим значением типа NTSTATUS, задать элемент Information равным нулю и вызвать IoCompleteRequest с IRP и PriorityBoost IO_NO_INCREMENT.

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

  • Если драйвер использует прямой ввод-вывод, может потребоваться проверка, описывает ли MDL в Irp-MdlAddress> буфер, содержащий слишком много данных (или слишком много разрывов страниц), для обработки базовым устройством в рамках одной операции передачи. В этом случае драйвер должен разделить исходный запрос на последовательность небольших операций передачи.

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

  • Подпрограмма DispatchReadWrite драйвера устройства нижнего уровня должна отложить разделение большого запроса на частичную передачу до тех пор, пока другая процедура драйвера не выпишет IRP для настройки устройства для передачи.

  • Если драйвер устройства более низкого уровня помещает IRP в очередь для чтения и записи для дальнейшей обработки собственными подпрограммами, он должен вызвать IoMarkIrpPending , прежде чем помещать IRP в очередь. Подпрограмма DispatchReadWrite также должна возвращать управление с STATUS_PENDING в этих случаях.

  • Если подпрограмма DispatchReadWrite передает IRP в более низкие драйверы, она должна настроить расположение стека ввода-вывода для следующего ниже драйвера в IRP. Указывает, устанавливает ли драйвер более высокого уровня подпрограмму IoCompletion в IRP перед его передачей с помощью IoCallDriver , зависит от структуры драйвера и элементов, наложенных на него.

    Однако драйвер более высокого уровня должен вызывать IoSetCompletionRoutine перед вызовом IoCallDriver , если он выделяет какие-либо ресурсы, такие как IRP или память. Ее подпрограмма IoCompletion должна освободить все ресурсы, выделенные драйвером, когда более низкие драйверы выполнили запрос, но до того, как подпрограмма IoCompletion вызовет IoCompleteRequest с исходным IRP.

  • Если драйвер более высокого уровня выделяет IRP для более низких драйверов, которые могут включать базовый драйвер устройства со съемным носителем, выделяющий драйвер должен установить контекст потока в каждом IRP, который он выделяет.