IoSetCompletionRoutine-Funktion (wdm.h)
Die IoSetCompletionRoutine Routine registriert eine IoCompletion- Routine, die aufgerufen wird, wenn der nächste Treiber auf niedrigerer Ebene den angeforderten Vorgang für das angegebene 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
Zeigen Sie auf die IRP-, die der Treiber verarbeitet.
[in, optional] CompletionRoutine
Gibt den Einstiegspunkt für die vom Treiber bereitgestellte IoCompletion Routine an, die aufgerufen wird, wenn der nächste niedrigere Treiber das Paket abgeschlossen.
[in, optional] Context
Zeiger auf einen treiberbestimmten Kontext, der an die IoCompletion Routine übergeben werden soll. Kontextinformationen müssen im nicht ausgelagerten Speicher gespeichert werden, da die IoCompletion- Routine bei IRQL-<= DISPATCH_LEVEL aufgerufen wird.
[in] InvokeOnSuccess
Gibt an, ob die Abschlussroutine aufgerufen wird, wenn das IRP mit einem Erfolgsstatuswert in der IO_STATUS_BLOCK Struktur des IRP basierend auf den Ergebnissen des NT_SUCCESS-Makros abgeschlossen wird (siehe Verwenden von NTSTATUS-Werten).
[in] InvokeOnError
Gibt an, ob die Vervollständigungsroutine aufgerufen wird, wenn das IRP mit einem Statuswert ohne Erfolg in der IO_STATUS_BLOCK-Struktur des IRP abgeschlossen wird.
[in] InvokeOnCancel
Gibt an, ob die Abschlussroutine aufgerufen wird, wenn ein Treiber oder der Kernel IoCancelIrp- aufgerufen hat, um das IRP abzubrechen.
Rückgabewert
Nichts
Bemerkungen
Nur ein Treiber, der garantieren kann, dass er nicht entladen wird, bevor die Fertigstellungsroutine abgeschlossen ist, kann IoSetCompletionRoutineverwendet werden. Andernfalls muss der Treiber IoSetCompletionRoutineExverwenden, wodurch verhindert wird, dass der Treiber entladen wird, bis seine Abschlussroutine ausgeführt wird.
Diese Routine legt die Übertragungsadresse der IoCompletion Routine im angegebenen IRP fest. Der Treiber auf der niedrigsten Ebene in einer Kette von mehrstufigen Treibern kann diese Routine nicht aufrufen.
IoSetCompletionRoutine registriert die angegebene Routine, die aufgerufen werden soll, wenn der nächste Treiber auf niedrigerer Ebene den angeforderten Vorgang auf eine oder alle folgenden Arten abgeschlossen hat:
Mit einem Erfolgsstatuswert
Mit einem Statuswert ohne Erfolg
Durch Abbrechen des IRP
Normalerweise wird der E/A-Statusblock vom zugrunde liegenden Gerätetreiber festgelegt. Sie wird gelesen, aber nicht durch die IoCompletion Routinen von Treibern auf höherer Ebene geändert.
Höhere Treiber, die IRP mit IoAllocateIrp oder IoBuildAsynchronousFsdRequest zuweisen, müssen diese Routine mit allen InvokeOn-Xxx-Parametern aufrufen, die auf TRUE- festgelegt sind, bevor sie das vom Treiber zugewiesene IRP an IoCallDriverübergeben. Wenn die IoCompletion Routine mit einem solchen IRP aufgerufen wird, muss sie die vom Treiber zugewiesenen IRP und alle anderen Ressourcen freigeben, die der Treiber für die Anforderung eingerichtet hat, z. B. MDLs mit IoBuildPartialMdl. Ein solcher Treiber sollte STATUS_MORE_PROCESSING_REQUIRED zurückgeben, wenn er IoFreeIrp- aufruft, um die Vervollständigungsverarbeitung des E/A-Managers für das vom Treiber zugewiesene IRP abzublenden.
Nicht-PnP-Treiber, die möglicherweise vor der Ausführung ihrer IoCompletion- Routinen entladen werden, sollten stattdessen IoSetCompletionRoutineEx- verwenden.