Функция IoSetCompletionRoutine (wdm.h)
Подпрограмма IoSetCompletionRoutine регистрирует подпрограмму IoCompletion , которая будет вызываться, когда драйвер следующего уровня завершит запрошенную операцию для заданного IRP.
Синтаксис
void IoSetCompletionRoutine(
[in] PIRP Irp,
[in, optional] PIO_COMPLETION_ROUTINE CompletionRoutine,
[in, optional] __drv_aliasesMem PVOID Context,
[in] BOOLEAN InvokeOnSuccess,
[in] BOOLEAN InvokeOnError,
[in] BOOLEAN InvokeOnCancel
);
Параметры
[in] Irp
Указатель на IRP , обрабатываемый драйвером.
[in, optional] CompletionRoutine
Указывает точку входа для предоставленной драйвером подпрограммы IoCompletion , которая вызывается, когда следующий ниже драйвер завершает пакет.
[in, optional] Context
Указатель на определенный драйвером контекст для передачи в подпрограмму IoCompletion . Сведения о контексте должны храниться в памяти без памяти, так как подпрограмма IoCompletion вызывается по адресу IRQL <= DISPATCH_LEVEL.
[in] InvokeOnSuccess
Указывает, вызывается ли подпрограмма завершения, если IRP завершается со значением состояния успешного выполнения в структуре IO_STATUS_BLOCK IRP на основе результатов макроса NT_SUCCESS (см . раздел Использование значений NTSTATUS).
[in] InvokeOnError
Указывает, вызывается ли подпрограмма завершения, если IRP завершается со значением состояния nonsuccess в структуре IRP IO_STATUS_BLOCK .
[in] InvokeOnCancel
Указывает, вызывается ли подпрограмма завершения, если драйвер или ядро вызывает IoCancelIrp для отмены IRP.
Возвращаемое значение
None
Remarks
IoSetCompletionRoutine может использовать только драйвер, который может гарантировать, что он не будет выгружен до завершения процедуры завершения. В противном случае драйвер должен использовать IoSetCompletionRoutineEx, что предотвращает выгрузку драйвера до выполнения процедуры завершения.
Эта подпрограмма задает адрес передачи процедуры IoCompletion в заданном IRP. Драйвер самого низкого уровня в цепочке многоуровневых драйверов не может вызвать эту подпрограмму.
IoSetCompletionRoutine регистрирует указанную подпрограмму для вызова, когда драйвер следующего уровня выполняет запрошенную операцию любым или всеми из следующих способов:
Со значением состояния успешного выполнения
Со значением состояния неуспеха
Отмена IRP
Как правило, блок состояния ввода-вывода задается базовым драйвером устройства. Он считывается, но не изменяется никакими подпрограммами IoCompletion драйверов более высокого уровня.
Драйверы более высокого уровня, которые выделяют IRP с помощью IoAllocateIrp или IoBuildAsynchronousFsdRequest , должны вызывать эту подпрограмму со всеми параметрами InvokeOnXxx, равными TRUE , прежде чем передавать выделенный драйвером IRP в IoCallDriver. Когда подпрограмма IoCompletion вызывается с таким IRP, она должна освободить выделенный драйвером IRP и любые другие ресурсы, настроенные драйвером для запроса, например mdls с IoBuildPartialMdl. Такой драйвер должен возвращать STATUS_MORE_PROCESSING_REQUIRED при вызове IoFreeIrp , чтобы предотвратить обработку завершения диспетчером ввода-вывода для выделенного драйвера IRP.
Драйверы, не относящиеся к PnP, которые могут быть выгружены перед выполнением подпрограмм IoCompletion , должны использовать IoSetCompletionRoutineEx .