Завершение IRP в подпрограмме диспетчеризации
Если входной IRP можно выполнить немедленно, подпрограмма диспетчеризации выполняет следующие действия:
Задает элементы 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, задается значение нулю.
Вызывает IoCompleteRequest с IRP и PriorityBoost = IO_NO_INCREMENT.
Возвращает соответствующий STATUS_XXX, который уже задан в блоке состояния ввода-вывода. Обратите внимание, что вызов IoCompleteRequest делает данное IRP недоступным вызывающему объекту, поэтому возвращаемое значение из подпрограммы диспетчеризации не может быть задано из блока состояния ввода-вывода уже завершенного IRP.
Следуйте этому руководству по реализации для вызова IoCompleteRequest с IRP:
Перед вызовом IoCompleteRequest всегда отпускайте все блокировки спина, удерживаемые драйвером.
Для завершения IRP требуется неопределенное количество времени, особенно в цепочке многоуровневых драйверов. Кроме того, взаимоблокировка может возникнуть, если подпрограмма IoCompletion более высокого уровня драйвера отправляет IRP обратно в более низкий драйвер, который удерживает спин-блокировку.