EX_CALLBACK_FUNCTION Rückruffunktion (wdm.h)
Die RegistryCallback-Routine eines Filtertreibers kann einen Registrierungsvorgang überwachen, blockieren oder ändern.
Syntax
EX_CALLBACK_FUNCTION ExCallbackFunction;
NTSTATUS ExCallbackFunction(
[in] PVOID CallbackContext,
[in, optional] PVOID Argument1,
[in, optional] PVOID Argument2
)
{...}
Parameter
[in] CallbackContext
Der Wert, den der Treiber bei der Registrierung dieser RegistryCallback-Routine als Context-Parameter an CmRegisterCallback oder CmRegisterCallbackEx übergeben hat.
[in, optional] Argument1
Ein REG_NOTIFY_CLASS typisierter Wert, der den Typ des registrierungsvorgangs angibt, der ausgeführt wird und ob die RegistryCallback-Routine vor oder nach dem Ausführen des Registrierungsvorgangs aufgerufen wird.
[in, optional] Argument2
Ein Zeiger auf eine Struktur, die Informationen enthält, die für den Typ des Registrierungsvorgangs spezifisch sind. Der Strukturtyp hängt vom REG_NOTIFY_CLASS typisierten Wert für Argument1 ab, wie in der folgenden Tabelle dargestellt. Informationen dazu, welche REG_NOTIFY_CLASS typisierten Werte für welche Betriebssystemversionen verfügbar sind, finden Sie unter REG_NOTIFY_CLASS.
Ab Windows 7 ist die tatsächliche Datenstruktur, die übergeben wird, wenn die Notify-Klasse RegNtPreCreateKeyEx oder RegNtPreOpenKeyEx lautet, die V1-Version dieser Struktur, REG_CREATE_KEY_INFORMATION_V1 bzw. REG_OPEN_KEY_INFORMATION_V1. Überprüfen Sie das Reservierte Element, um die Version der Struktur zu ermitteln.
Versionsnummer | Strukturname |
---|---|
0 | REG_CREATE_KEY_INFORMATION und REG_OPEN_KEY_INFORMATION |
1 | REG_CREATE_KEY_INFORMATION_V1 und REG_OPEN_KEY_INFORMATION_V1 |
Rückgabewert
Weitere Informationen dazu, wann eine RegistryCallback-Routine jeden dieser status Werte zurückgeben sollte, finden Sie unter Filtern von Registrierungsaufrufen.
Hinweise
Um über Registrierungsvorgänge benachrichtigt zu werden, kann eine Kernelmoduskomponente (z. B. die Treiberkomponente eines Antivirensoftwarepakets) CmRegisterCallback oder CmRegisterCallbackEx aufrufen, um eine RegistryCallback-Routine zu registrieren.
Die RegistryCallback-Routine kann den Inhalt der Eingabe- und Ausgabepuffer überprüfen, die für Registrierungsvorgänge bereitgestellt werden. Ein Registrierungsvorgang kann von einer Anwendung im Benutzermodus initiiert werden, die eine Registrierungsroutine im Benutzermodus aufruft (z. B. RegCreateKeyEx oder RegOpenKeyEx) oder von einem Treiber, der eine Registrierungsroutine im Kernelmodus aufruft (z. B. ZwCreateKey oder ZwOpenKey). Ein Eingabepuffer ist ein vom Initiator bereitgestellter Speicherpuffer, aus dem die Registrierung Eingabedaten für den Vorgang liest. Ein Ausgabepuffer ist ein vom Initiator bereitgestellter Puffer, in den die Registrierung vom Initiator angeforderte Ausgabedaten schreibt.
Vor dem Aufrufen der RegistryCallback-Routine testet der Kernel (zur Überprüfung der Ausrichtung und Barrierefreiheit) alle Member der Argument2-Strukturen , die auf Ausgabepuffer im Benutzermodusspeicher verweisen, erfasst jedoch keine Ausgabepuffer im Benutzermodus im Systemspeicher. Die Rückrufroutine muss jeden Zugriff auf einen Ausgabepuffer in einen Try-Block/mit Ausnahme einschließen. Wenn die Rückrufroutine einen Ausgabepufferzeiger an eine Systemroutine (z. B. ZwOpenKey) übergeben muss und sich der Puffer im Arbeitsspeicher im Benutzermodus befindet, muss die Rückrufroutine zuerst den Puffer erfassen.
Die Behandlung von Eingabepuffern hängt von der Windows-Version ab. Ab Windows 8 erfasst der Kernel alle Eingabepuffer, auf die elemente der Argument2-Strukturen im Systemspeicher verweisen, bevor die RegistryCallback-Routine aufgerufen wird. In Versionen von Windows vor Windows 8 testet der Kernel alle Member der Argument2-Strukturen, die auf Eingabepuffer im Benutzermodusspeicher verweisen, erfasst jedoch nur einige dieser Puffer im Systemspeicher. In diesen früheren Versionen von Windows muss die Rückrufroutine jeden Zugriff auf einen Eingabepuffer in einen Try-Block/mit Ausnahme eines Blocks einschließen. Wenn die Rückrufroutine außerdem einen Eingabepufferzeiger an eine Systemroutine (z. B. ZwOpenKey) übergeben muss und sich der Puffer im Arbeitsspeicher im Benutzermodus befindet, muss die Rückrufroutine zuerst den Puffer erfassen.
In der folgenden Tabelle sind die Anforderungen für Pufferzugriffe durch die RegistryCallback-Routine zusammengefasst.
Puffertyp | Windows-Version | Pufferzeiger an Rückrufroutine übergeben | Sicher, dass die Rückrufroutine direkt darauf zugreifen kann? | Sichere Übergabe an Systemroutinen (z. B . ZwOpenKey)? |
---|---|---|---|---|
Benutzermoduseingabe | Windows 8 und höher | Verweist auf erfasste Daten. | Yes | Yes |
Benutzermoduseingabe | Windows 7 und früher | Verweist auf erfasste Daten oder den ursprünglichen Benutzermoduspuffer. | Nein. Muss unter try/except gelesen werden. | Nein. Muss Kernelspeicher zuordnen, Daten aus dem ursprünglichen Puffer unter try/except kopieren und die kopierten Daten an die Systemroutine übergeben. |
Ausgabe im Benutzermodus | All | Verweist auf den ursprünglichen Puffer im Benutzermodus. | Nein. Muss unter try/except geschrieben werden. | Nein. Muss Kernelspeicher zuweisen, Kernelspeicher an die Systemroutine übergeben und die Ergebnisse unter try/except wieder in den ursprünglichen Puffer kopieren. |
Ein- und Ausgabe im Kernelmodus | All | Verweist auf den ursprünglichen Kernelmoduspuffer. | Yes | Yes |
Weitere Informationen zu RegistryCallback-Routinen und Registrierungsfiltertreibern finden Sie unter Filtern von Registrierungsaufrufen.
Ein RegistryCallback wird unter IRQL = PASSIVE_LEVEL und im Kontext des Threads ausgeführt, der den Registrierungsvorgang ausführt.
Beispiele
Um eine RegistryCallback-Rückrufroutine zu definieren, müssen Sie zunächst eine Funktionsdeklaration bereitstellen, die den Typ der Rückrufroutine identifiziert, die Sie definieren. Windows bietet eine Reihe von Rückruffunktionstypen für Treiber. Das Deklarieren einer Funktion mithilfe der Rückruffunktionstypen hilft der Codeanalyse für Treiber, der statischen Treiberüberprüfung (Static Driver Verifier , SDV) und anderen Überprüfungstools, Fehler zu finden, und es ist eine Voraussetzung für das Schreiben von Treibern für das Windows-Betriebssystem.
Um beispielsweise eine RegistryCallback-Rückrufroutine mit dem Namen MyRegistryCallback
zu definieren, verwenden Sie den typ EX_CALLBACK_FUNCTION, wie in diesem Codebeispiel gezeigt:
EX_CALLBACK_FUNCTION MyRegistryCallback;
Implementieren Sie dann Ihre Rückrufroutine wie folgt:
_Use_decl_annotations_
NTSTATUS
MyRegistryCallback(
PVOID CallbackContext,
PVOID Argument1,
PVOID Argument2
)
{
// Function body
}
Der EX_CALLBACK_FUNCTION Funktionstyp ist in der Headerdatei Wdm.h definiert. Um Fehler beim Ausführen der Codeanalysetools genauer zu identifizieren, fügen Sie der Funktionsdefinition die Use_decl_annotations Anmerkung hinzu. Die Use_decl_annotations Anmerkung stellt sicher, dass die Anmerkungen verwendet werden, die auf den EX_CALLBACK_FUNCTION Funktionstyp in der Headerdatei angewendet werden. Weitere Informationen zu den Anforderungen für Funktionsdeklarationen finden Sie unter Deklarieren von Funktionen mithilfe von Funktionsrollentypen für WDM-Treiber. Informationen zu Use_decl_annotations finden Sie unter Verhalten von Funktionen mit Anmerkungen.
Anforderungen
Anforderung | Wert |
---|---|
Unterstützte Mindestversion (Client) | Wird ab Windows XP unterstützt (siehe Abschnitt Rückgabewert). |
Zielplattform | Desktop |
Header | wdm.h (einschließlich Wdm.h, Ntddk.h, Ntifs.h) |
IRQL | Wird bei PASSIVE_LEVEL aufgerufen (siehe Abschnitt Hinweise). |