Freigeben über


Kann ich DoTraceMessage anpassen?

Ja, Sie können Ihre eigene Version des DoTraceMessage-Makros schreiben. DoTraceMessage generiert eine Ablaufverfolgungsnachricht.

Der TraceDrv-Beispieltreiber enthält ein Beispiel für die Methoden, die in diesem Thema beschrieben werden. TraceDrv ist im Repository für Windows-Treiberbeispiele auf GitHub verfügbar.

DoTraceMessage: Standardversion

Standardmäßig hat das DoTraceMessage-Makro das folgende Format:

DoTraceMessage(Flag,"Message",MessageVariables...);

In dieser Standardversion stellt Flag die Ablaufverfolgungsflags dar. Dies sind die Bedingungen, unter denen die Nachricht generiert wird. MessageVariables enthält eine durch Trennzeichen getrennte Liste von Variablen, die der Treiber definiert und in der Ablaufverfolgungsmeldung angezeigt wird. Die MessageVariables-Variablen werden mithilfe der printf-Elemente formatiert. Der WPP-Präprozessor erstellt eine Compilerdirektive aus dem DoTraceMessage-Makro. Dieses Makro fügt die Nachrichtendefinitionsinformationen und Formatierungsinformationen der PDB-Datei hinzu, die für den Ablaufverfolgungsanbieter generiert wurde, z. B. einen Kernelmodustreiber oder eine Benutzermodusanwendung.

Das DoTraceMessage-Makro wird logisch in Folgendes erweitert:

PRE macro // If defined
If (WPP_CHECK_INIT && Flag is enabled) {
 ....Call WmiTraceMessage;
}
POST macro // If defined

Betrachten Sie folgendes Codebeispiel.

DoTraceMessage(ERROR, "IOCTL = %d", ControlCode);

Dieser Aufruf generiert die Ablaufverfolgungsmeldung, wenn das ERROR-Flag aktiviert ist. Die Meldung lautet "IOCTL=%d", und MessageVariables ist der Wert von ControlCode.

Wenn die Makros pre-logging und POST-logging definiert wurden, werden sie ebenfalls erweitert. Die PRE-Makros und POST-Makros werden unter Microsoft Windows 2000 und höher unterstützt. Um die Makros verwenden zu können, müssen Sie den Treiber mithilfe des WDK erstellen. Wenn Sie einen Treiber mit einer früheren Version des Windows Driver Development Kit (DDK) erstellen, ist die PRE- und POST-Funktionalität nicht verfügbar, und die Makros werden nicht als Teil der Ablaufverfolgungsanweisung ausgeführt. Das Erstellen des Treibers mit einer früheren Version des Windows DDK verursacht möglicherweise keine Buildunterbrechung, aber der Code funktioniert nicht wie erwartet.

DoTraceMessage: Allgemeines Format

Es folgt ein allgemeines Format einer gültigen Ablaufverfolgungsmeldungsfunktion:

FunctionName(Conditions...,"Message",MessageVariables...);

Parameter, die vor der Meldung angezeigt werden, werden als Bedingungen interpretiert. Parameter, die nach der Nachricht angezeigt werden, werden als Nachrichtenvariablen interpretiert.

Bedingungen ist eine durch Trennzeichen getrennte Liste von Werten. Die Ablaufverfolgungsmeldung wird nur generiert, wenn alle Bedingungen wahr sind. Sie können jede Bedingung angeben, die im Code unterstützt wird.

Beispiel: MyTrace

Im Folgenden ist ein Beispiel für eine Ablaufverfolgungsfunktion aufgeführt. In diesem Beispiel werden Bedingungen für die Ablaufverfolgungsebene und die Unterkomponente des Anbieters hinzugefügt, der die Ablaufverfolgungsnachricht generiert.

MyDoTrace(Level, Flag, Subcomponent,"Message",MessageVariables...);

Beispiel:

MyDoTrace(TRACE_LEVEL_ERROR, VERBOSE, Network,"IOCTL = %d", ControlCode);

Die Ablaufverfolgungsebene ist die Standardebene, die in Evntrace.h definiert ist, einer öffentlichen Headerdatei, die sich im Unterverzeichnis Include des WDK befindet.

#define TRACE_LEVEL_NONE        0   // Tracing is not on
#define TRACE_LEVEL_FATAL       1   // Abnormal exit or termination
#define TRACE_LEVEL_ERROR       2   // Severe errors that need logging
#define TRACE_LEVEL_WARNING     3   // Warnings such as allocation failure
#define TRACE_LEVEL_INFORMATION 4   // Includes non-error cases(for example, Entry-Exit)
#define TRACE_LEVEL_VERBOSE     5   // Detailed traces from intermediate steps
#define TRACE_LEVEL_RESERVED6   6
#define TRACE_LEVEL_RESERVED7   7
#define TRACE_LEVEL_RESERVED8   8
#define TRACE_LEVEL_RESERVED9   9

Erstellen einer benutzerdefinierten Ablaufverfolgungsfunktion

Führen Sie die folgenden Schritte aus, um eine benutzerdefinierte Ablaufverfolgungsfunktion zu erstellen:

  • Schreiben Sie alternative Versionen der Makros, die das DoTraceMessage-Makro unterstützen.

  • Fügen Sie den Parameter -func der RUN_WPP-Anweisung hinzu, die den WPP-Präprozessor aufruft.

Schreiben von benutzerdefinierten Makros

Um eine benutzerdefinierte Ablaufverfolgungsfunktion zu erstellen, die die Bedingungen für eine Ablaufverfolgungsnachricht ändert (die Parameter, die vor der Nachricht angezeigt werden), müssen Sie alternative Versionen der Makros schreiben, die die Ablaufverfolgungsfunktionen unterstützen, WPP_LEVEL_ENABLED und WPP_LEVEL_LOGGER.

  • WPP_LEVEL_ENABLED(Flags) bestimmt, ob die Protokollierung mit dem angegebenen Flagwert aktiviert ist. Es wird TRUE oder FALSE zurückgegeben.

  • WPP_LEVEL_LOGGER(Flags) findet die Ablaufverfolgungssitzung, für die der Anbieter aktiviert ist, und gibt ein Handle an die Ablaufverfolgungssitzung zurück.

Wenn Sie beispielsweise die Ablaufverfolgungsebene einschließen möchten, definieren Sie zusätzlich zu Flags als Bedingung ein neues WPP_LEVEL_ENABLED Makro, das die Ablaufverfolgungsebene enthält. Sie können die Definition des neuen Makros auf dem Standardmakro basieren, wie im folgenden Codebeispiel gezeigt.

#define WPP_LEVEL_FLAGS_ENABLED(lvl, flags) (WPP_LEVEL_ENABLED(flags) && WPP_CONTROL(WPP_BIT_ ## flags).Level >=lvl

In der Regel ist das makro WPP_LEVEL_LOGGER nicht betroffen. In diesen Fällen können Sie das neue Makro als Standardmakro definieren. Beispiel:

#define WPP_LEVEL_FLAGS_LOGGER(lvl,flags) WPP_LEVEL_LOGGER(flags)

In einigen Fällen müssen Sie jedoch das LOGGER-Makro ändern. Sie können beispielsweise eine Ablaufverfolgungsfunktion schreiben, die nur von der Ablaufverfolgungsebene und nicht von Flags abhängt.

Im folgenden Codebeispiel wird der Flagwert im Makro durch einen Dummywert ersetzt. Beim Deklarieren der GUID-Definition des Steuerelements werden keine Flags definiert.

#define WPP_CONTROL_GUIDS \
   WPP_DEFINE_CONTROL_GUID(CtlGuid,(a044090f,3d9d,48cf,b7ee,9fb114702dc1),  \
        WPP_DEFINE_BIT(DUMMY))
#define WPP_LEVEL_LOGGER(lvl) (WPP_CONTROL(WPP_BIT_ ## DUMMY).Logger)

Hinzufügen der Funktion zu WPP

Um die benutzerdefinierte Ablaufverfolgungsfunktion zu WPP hinzuzufügen, fügen Sie den Parameter -func der RUN_WPP-Anweisung mit einer Deklaration der Funktion hinzu, wie im folgenden Codebeispiel gezeigt.

RUN_WPP=$(SOURCES) -km -func:DoTraceLevelMessage(LEVEL,FLAGS,MSG,...)

Hinweis Sie dürfen den Schalter -km nicht in der RUN_WPP-Direktive für Benutzermodusanwendungen oder Dynamic Link Libraries (DLLs) angeben.

Eine vollständige Liste der optionalen Parameter für RUN_WPP finden Sie unter WPP-Präprozessor.