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


Завершение IRP в подпрограмме диспетчеризации

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

  1. Задает элементы Status и Information блока состояния ввода-вывода IRP с соответствующими значениями, как правило:

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

      Если драйвер более низкого уровня возвращает STATUS_PENDING, драйвер более высокого уровня не должен вызывать IoCompleteRequest для IRP, за одним исключением: драйвер более высокого уровня может использовать событие для синхронизации между своей подпрограммой IoCompletion и подпрограммой диспетчеризации. В этом случае подпрограмма IoCompletion сообщает о событии и возвращает STATUS_MORE_PROCESSING_REQUIRED. Подпрограмма диспетчеризации ожидает события, а затем вызывает IoCompleteRequest для завершения IRP.

    • При выполнении запроса на передачу данных, например запроса на чтение или запись, устанавливается число успешно переданных байтов.

    • Он задает значение Information , которое изменяется в зависимости от конкретного запроса для других irps, которые он завершает с помощью STATUS_SUCCESS.

    • Он задает значение Information , которое изменяется в зависимости от конкретного запроса для IRP, который завершается с предупреждением STATUS_XXX. Например, для параметра Information будет задано количество байтов, переданных для такого предупреждения, как STATUS_BUFFER_OVERFLOW.

    • Обычно для запросов, завершающихся с ошибкой STATUS_XXX, задается значение нулю.

  2. Вызывает IoCompleteRequest с IRP и PriorityBoost = IO_NO_INCREMENT.

  3. Возвращает соответствующий STATUS_XXX, который уже задан в блоке состояния ввода-вывода. Обратите внимание, что вызов IoCompleteRequest делает данное IRP недоступным вызывающему объекту, поэтому возвращаемое значение из подпрограммы диспетчеризации не может быть задано из блока состояния ввода-вывода уже завершенного IRP.

Следуйте этому руководству по реализации для вызова IoCompleteRequest с IRP:

Перед вызовом IoCompleteRequest всегда отпускайте все блокировки спина, удерживаемые драйвером.

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