TraceLogging pour les pilotes et composants en mode noyau
Cette rubrique explique comment utiliser l’API TraceLogging à partir de pilotes et de composants en mode noyau.
Prérequis :
- Windows 10
- Visual Studio 2013 (ou version ultérieure)
- SDK Windows 10
- Kit de pilotes Windows (WDK) pour Windows 10
Inclure les fichiers d’en-tête TraceLogging
Pour utiliser l’API TraceLogging, incluez le fichier d’en-tête TraceLoggingProvider.h. L’autre fichier d’en-tête de l’API TraceLogging, TraceLoggingActivity.h, est disponible uniquement pour une utilisation dans les pilotes en mode utilisateur écrits en C++.
#include <wdm.h>
#include <TraceLoggingProvider.h>
Notes
Le fichier wdm.h est requis pour TraceLoggingProvider.h lors du développement de pilotes en mode noyau.
Déclarer votre pilote en tant que fournisseur TraceLogging
Ajoutez la macro TRACELOGGING_DECLARE_PROVIDER pour déclarer la variable de handle du fournisseur. La macro a la syntaxe :
TRACELOGGING_DECLARE_PROVIDER(hProviderVariableName)
L’exemple d’instruction TraceLogging suivant déclare la variable nommée g_hProvider.
TRACELOGGING_DECLARE_PROVIDER(g_hProvider);
La variable que vous déclarez avec TRACELOGGING_DECLARE_PROVIDER devient le handle du fournisseur lorsque vous appelez la macro TRACELOGGING_DEFINE_PROVIDER plus loin dans votre code.
Notes
Vous pouvez placer cette macro dans un fichier d’en-tête afin que le handle du fournisseur TraceLogging soit disponible globalement.
Ajoutez la macro TRACELOGGING_DEFINE_PROVIDER et spécifiez un nom pour le fournisseur de trace et le handle du fournisseur de trace. Le handle est la variable que vous avez déclarée à l’étape 1. La syntaxe de la macro est :
TRACELOGGING_DEFINE_PROVIDER(hProviderVariableName, "ProviderName", providerId [,option])
Par exemple, l’instruction suivante définit un fournisseur appelé MyTraceLoggingProviderKM et l’affecte au handle g_hProvider. Le paramètre providerId est le GUID du fournisseur ETW.
TRACELOGGING_DEFINE_PROVIDER(g_hProvider, "MyTraceLoggingProviderKM", (0xb3864c38, 0x4273, 0x58c5, 0x54, 0x5b, 0x8b, 0x36, 0x08, 0x34, 0x34, 0x71));
La macro TRACELOGGING_DEFINE_PROVIDER alloue le stockage pour un fournisseur et définit une variable correspondante qui est le handle global du fournisseur. Le nom du fournisseur doit être un littéral de chaîne (et non une variable) et ne doit pas contenir de caractères « \0 ». Le handle et les copies du handle sont valides tant que le handle d’origine est dans l’étendue.
Lorsque vous créez le handle pour la première fois avec la macro TRACELOGGING_DEFINE_PROVIDER , le fournisseur est à l’état non inscrit. Dans cet état, le fournisseur ignore tous les appels d’écriture de trace jusqu’à ce qu’il soit inscrit.
Notes
Pour le mode noyau, sachez que si les métadonnées du fournisseur sont explicitement stockées dans TLG_METADATA_SEGMENT (.rdata), les variables que vous créez pour le handle (par exemple, g_hProvider) et le nom du fournisseur (par exemple, « MyTraceLoggingProviderKM ») ne sont pas explicitement affectées à un segment et utiliseront les segments implicites actuels.
La macro TRACELOGGING_DEFINE_PROVIDER s’attend à ce que les variables qui lui ont été transmises soient dans le pool non paginé. Si ce n’est pas déjà le cas, l’appelant doit définir le segment de données via #pragma data_seg (pour uniqueVarName) ou le segment const via #pragma const_seg (pour g_hMyProvider) avant d’appeler la macro TRACELOGGING_DEFINE_PROVIDER .
Inscrire le pilote avec TraceLogging
Dans votre fonction DriverEntry , vous devez inscrire le fournisseur TraceLogging. Pour inscrire le fournisseur auprès de TraceLogging, ajoutez la macro TraceLoggingRegister à DriverEntry :
// Register the TraceLogging provider in the DriverEntry method.
TraceLoggingRegister(g_hProvider);
Désinscrire le fournisseur dans la routine de déchargement ou de nettoyage du pilote
Dans votre fonction DriverUnload ou cleanup, annulez l’inscription du fournisseur TraceLogging.
// Stop TraceLogging and unregister the provider
TraceLoggingUnregister(g_hProvider);
Événements de journal dans votre code
TraceLogging fournit des macros pour la journalisation des événements.
La macro de base est TraceLoggingWrite. Cette macro a la syntaxe suivante :
TraceLoggingWrite(g_hProvider, "EventName", args...)
Où g_hProvider est le handle du fournisseur que vous avez défini et « EventName » est un littéral de chaîne (et non une variable) que vous utilisez pour identifier l’événement spécifique. Comme printf ou DbgPrint, la macro TraceLoggingWrite prend en charge un nombre variable de paramètres supplémentaires (jusqu’à 99). Les paramètres (args) doivent être des macros wrapper TraceLogging, telles que TraceLoggingLevel, TraceLoggingInt32 ou TraceLoggingString. Les macros du wrapper TraceLogging sont définies dans TraceLoggingProvider.h.
Notes
Si vous utilisez C++, vous pouvez utiliser la macro wrapper TraceLoggingValue pour ajuster automatiquement le type. Si vous écrivez votre pilote en C, vous devez utiliser les macros de champ spécifiques au type (par exemple, TraceLoggingInt32 ou TraceLoggingUnicodeString).
L’exemple suivant journalise un événement pour le fournisseur, g_hProvider. L’événement est appelé « MyDriverEntryEvent ». La macro utilise les wrappers TraceLoggingPointer et TraceLoggingUnicodeString pour écrire le pointeur vers l’objet de pilote et le chemin du Registre vers le journal de suivi. Le wrapper TraceLoggingUnicodeString prend un nom facultatif. Dans cet exemple, « RegPath » est le nom de la valeur RegistryPath. Si aucun nom n’est spécifié, la valeur est utilisée comme nom.
TraceLoggingWrite(
g_hProvider,
"MyDriverEntryEvent",
TraceLoggingPointer(DriverObject),
TraceLoggingUnicodeString(RegistryPath, "RegPath"));
);
Si vous instrumentez un pilote en mode noyau (en C), vous créez un lien vers TraceLoggingProvider.h et vous pouvez utiliser les macros TraceLoggingWrite, TraceLoggingWriteActivity ou TraceLoggingActivityMarker . Pour obtenir des exemples de journalisation des traces, consultez Exemples traceLogging.
Si vous instrumentez un pilote ou un composant écrit en C++, vous créez un lien vers TraceLoggingProvider.h et TraceLoggingActivity.h. Lorsque vous créez un lien vers l’en-tête C++, vous pouvez consigner des événements avec les macros TraceLoggingWriteStart, TraceLoggingWriteStop et TraceLoggingWriteTagged .
Pour obtenir des exemples de capture et d’affichage des données TraceLogging, consultez Capturer et afficher les données TraceLogging.