IoSetCompletionRoutine-Funktion (wdm.h)
Die IoSetCompletionRoutine-Routine registriert eine IoCompletion-Routine , die aufgerufen wird, wenn der Treiber der nächstniedrigen Ebene den angeforderten Vorgang für den angegebenen IRP abgeschlossen hat.
Syntax
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
);
Parameter
[in] Irp
Zeiger auf den IRP , den der Treiber verarbeitet.
[in, optional] CompletionRoutine
Gibt den Einstiegspunkt für die vom Treiber bereitgestellte IoCompletion-Routine an, die aufgerufen wird, wenn der nächstniedrige Treiber das Paket abschließt.
[in, optional] Context
Zeiger auf einen vom Treiber bestimmten Kontext, der an die IoCompletion-Routine übergeben werden soll. Kontextinformationen müssen im nicht ausgelagerten Arbeitsspeicher gespeichert werden, da die IoCompletion-Routine unter IRQL <= DISPATCH_LEVEL aufgerufen wird.
[in] InvokeOnSuccess
Gibt an, ob die Vervollständigungsroutine aufgerufen wird, wenn die IRP mit einem erfolgreichen status Wert in der IO_STATUS_BLOCK-Struktur des IRP abgeschlossen wird, basierend auf den Ergebnissen des NT_SUCCESS Makros (siehe Verwenden von NTSTATUS-Werten).
[in] InvokeOnError
Gibt an, ob die Vervollständigungsroutine aufgerufen wird, wenn der IRP mit einem nicht erfolgreichen status-Wert in der IO_STATUS_BLOCK-Struktur des IRP abgeschlossen wird.
[in] InvokeOnCancel
Gibt an, ob die Vervollständigungsroutine aufgerufen wird, wenn ein Treiber oder der Kernel IoCancelIrp aufgerufen hat, um die IRP abzubrechen.
Rückgabewert
Keine
Bemerkungen
Nur ein Treiber, der garantieren kann, dass er nicht entladen wird, bevor seine Vervollständigungsroutine abgeschlossen ist, kann IoSetCompletionRoutine verwenden. Andernfalls muss der Treiber IoSetCompletionRoutineEx verwenden, wodurch verhindert wird, dass der Treiber entladen wird, bis seine Vervollständigungsroutine ausgeführt wird.
Diese Routine legt die Übertragungsadresse der IoCompletion-Routine im angegebenen IRP fest. Der Treiber der niedrigsten Ebene in einer Kette von Mehrschichttreibern kann diese Routine nicht aufrufen.
IoSetCompletionRoutine registriert die angegebene Routine, die aufgerufen werden soll, wenn der Treiber der nächstniedrigen Ebene den angeforderten Vorgang auf eine oder alle der folgenden Arten abgeschlossen hat:
Mit einem Erfolg status Wert
Mit einem nicht erfolgreichen status Wert
Durch Abbrechen der IRP
In der Regel wird der E/A-status-Block vom zugrunde liegenden Gerätetreiber festgelegt. Sie wird gelesen, aber nicht von IoCompletion-Routinen höherer Treiber geändert.
Übergeordnete Treiber, die IRP mit IoAllocateIrp oder IoBuildAsynchronousFsdRequest zuordnen, müssen diese Routine aufrufen, wobei alle InvokeOnXxx-Parameter auf TRUE festgelegt sind, bevor sie das vom Treiber zugewiesene IRP an IoCallDriver übergeben. Wenn die IoCompletion-Routine mit einem solchen IRP aufgerufen wird, müssen die vom Treiber zugewiesenen IRP und alle anderen Ressourcen, die der Treiber für die Anforderung eingerichtet hat, wie z. B. MDLs mit IoBuildPartialMdl, freigeben. Ein solcher Treiber sollte STATUS_MORE_PROCESSING_REQUIRED zurückgeben, wenn er IoFreeIrp aufruft , um die Vervollständigungsverarbeitung des E/A-Managers für die vom Treiber zugewiesene IRP zu überwachen.
Nicht-PnP-Treiber, die möglicherweise entladen werden, bevor ihre IoCompletion-Routinen ausgeführt werden, sollten stattdessen IoSetCompletionRoutineEx verwenden.