Schreiben von Postoperation-Rückrufroutinen
Ein Dateisystem-Minifiltertreiber verwendet eine oder mehrere Rückrufroutinen nach der Operation , um E/A-Vorgänge zu filtern.
Eine Rückrufroutine nach der Operation kann eine der folgenden Aktionen ausführen:
- Erledigen Sie die Abschlussarbeiten direkt in der Postoperationsroutine. Alle Vervollständigungsarbeiten können unter IRQL <= DISPATCH_LEVEL ausgeführt werden.
- Vervollständigungsarbeiten an einem sicheren IRQL. Zurückgeben FLT_STATUS_MORE_PROCESSING_REQUIRED und Warteschlange eines Workerthreads, um die Verarbeitung bei sicherem IRQL zu ermöglichen. Wenn die Verarbeitung abgeschlossen ist, ruft der Workerthread FltCompletePendedPostOperation auf, um die Nachoperationsverarbeitung fortzusetzen.
- Abbrechen eines erfolgreichen CREATE-Vorgangs.
Rückrufroutinen nach der Operation ähneln den Vervollständigungsroutinen , die in Legacy-Dateisystemfiltertreibern verwendet werden.
Ein Minifiltertreiber registriert eine Postoperation-Rückrufroutine für einen bestimmten E/A-Vorgangstyp auf die gleiche Weise, wie er eine Rückrufroutine vor der Operation registriert, d. h. durch Speichern des Einstiegspunkts der Rückrufroutine im Member OperationRegistration der FLT_REGISTRATION Struktur, die der Minifiltertreiber als Parameter an FltRegisterFilter in seiner DriverEntry-Routine übergibt.
Minifiltertreiber empfangen nur die Typen von E/A-Vorgängen, für die sie eine Rückrufroutine für preoperation oder postoperation registriert haben. Ein Minifiltertreiber kann eine Preoperation-Rückrufroutine für einen bestimmten E/A-Vorgangstyp registrieren, ohne einen Postoperationsrückruf zu registrieren und umgekehrt.
Jede Postoperation-Rückrufroutine wird wie folgt definiert:
typedef FLT_POSTOP_CALLBACK_STATUS
(*PFLT_POST_OPERATION_CALLBACK) (
IN OUT PFLT_CALLBACK_DATA Data,
IN PCFLT_RELATED_OBJECTS FltObjects,
IN PVOID CompletionContext,
IN FLT_POST_OPERATION_FLAGS Flags
);
Wie eine Vervollständigungsroutine wird eine Rückrufroutine nach der Operation unter IRQL <= DISPATCH_LEVEL in einem beliebigen Threadkontext aufgerufen.
Da sie unter IRQL = DISPATCH_LEVEL aufgerufen werden kann, kann eine Postoperation-Rückrufroutine keine Kernelmodusroutinen aufrufen, die bei einem niedrigeren IRQL aufgerufen werden müssen, z. B. FltLockUserBuffer oder RtlCompareUnicodeString. Aus dem gleichen Grund müssen alle Datenstrukturen, die in einer Rückrufroutine nach der Operation verwendet werden, aus einem nicht auslagerten Pool zugeordnet werden.
Die folgenden Situationen sind mehrere Ausnahmen von der vorherigen Regel:
Wenn die Rückrufroutine eines Minifiltertreibers vor der Operation FLT_PREOP_SYNCHRONIZE für einen IRP-basierten E/A-Vorgang zurückgibt, wird die entsprechende Postoperation-Rückrufroutine unter IRQL <= APC_LEVEL im selben Threadkontext wie die Rückrufroutine vor der Operation aufgerufen.
Die Postoperation-Rückrufroutine für einen schnellen E/A-Vorgang wird unter IRQL = PASSIVE_LEVEL im gleichen Threadkontext wie die Rückrufroutine vor der Operation aufgerufen.
Rückrufroutinen nach der Erstellung werden unter IRQL = PASSIVE_LEVEL im Kontext des Threads aufgerufen, der den IRP_MJ_CREATE-Vorgang ausgelöst hat.
Wenn der Filter-Manager die Postoperation-Rückrufroutine eines Minifiltertreibers für einen bestimmten E/A-Vorgang aufruft, steuert der Minifiltertreiber vorübergehend den E/A-Vorgang. Der Minifiltertreiber behält dieses Steuerelement bei, bis er eine der folgenden Aktionen ausführt:
Gibt FLT_POSTOP_FINISHED_PROCESSING aus der Rückrufroutine nach der Operation zurück.
Ruft FltCompletePendedPostOperation aus einer Arbeitsroutine auf, die einen IRP-basierten E/A-Vorgang verarbeitet hat, der in der Rückrufroutine nach der Operation geschrieben wurde.
Dieser Abschnitt umfasst Folgendes:
Ausführen der Vervollständigungsverarbeitung für einen E/A-Vorgang
Ausstehen eines E/A-Vorgangs in einer Postoperation-Rückrufroutine
Fehler bei einem E/A-Vorgang in einer Postoperation-Rückrufroutine