TraceLogging per driver e componenti in modalità kernel
Questo argomento descrive come usare l'API TraceLogging da driver e componenti in modalità kernel.
Prerequisiti:
- Windows 10
- Visual Studio 2013 (o versioni successive)
- Windows 10 SDK
- Windows Driver Kit (WDK) per Windows 10
Includere i file di intestazione TraceLogging
Per usare l'API TraceLogging, includere il file di intestazione TraceLoggingProvider.h. L'altro file di intestazione dell'API TraceLogging, TraceLoggingActivity.h, è disponibile solo per l'uso nei driver in modalità utente scritti in C++.
#include <wdm.h>
#include <TraceLoggingProvider.h>
Nota
Il file wdm.h è necessario per TraceLoggingProvider.h quando si sviluppano driver in modalità kernel.
Dichiarare il driver come provider TraceLogging
Aggiungere la macro TRACELOGGING_DECLARE_PROVIDER per dichiarare la variabile di handle del provider. La macro ha la sintassi:
TRACELOGGING_DECLARE_PROVIDER(hProviderVariableName)
Nell'esempio seguente l'istruzione TraceLogging dichiara la variabile denominata g_hProvider.
TRACELOGGING_DECLARE_PROVIDER(g_hProvider);
La variabile dichiarata con TRACELOGGING_DECLARE_PROVIDER diventa l'handle al provider quando si chiama la macro TRACELOGGING_DEFINE_PROVIDER più avanti nel codice.
Nota
È possibile inserire questa macro in un file di intestazione in modo che l'handle per il provider TraceLogging sia disponibile a livello globale.
Aggiungere la macro TRACELOGGING_DEFINE_PROVIDER e specificare un nome per il provider di traccia e l'handle del provider di traccia. L'handle è la variabile dichiarata nel passaggio 1. La sintassi della macro è:
TRACELOGGING_DEFINE_PROVIDER(hProviderVariableName, "ProviderName", providerId [,option])
Ad esempio, l'istruzione seguente definisce un provider denominato MyTraceLoggingProviderKM e lo assegna all'handle g_hProvider. Il parametro providerId è il GUID del provider ETW.
TRACELOGGING_DEFINE_PROVIDER(g_hProvider, "MyTraceLoggingProviderKM", (0xb3864c38, 0x4273, 0x58c5, 0x54, 0x5b, 0x8b, 0x36, 0x08, 0x34, 0x34, 0x71));
La macro TRACELOGGING_DEFINE_PROVIDER alloca l'archiviazione per un provider e definisce una variabile corrispondente che rappresenta l'handle globale per il provider. Il nome del provider deve essere un valore letterale stringa (non una variabile) e non deve contenere caratteri '\0'. L'handle e le copie dell'handle sono validi finché l'handle originale è nell'ambito.
Quando si crea per la prima volta l'handle con la macro TRACELOGGING_DEFINE_PROVIDER , il provider si trova nello stato non registrato. In questo stato, il provider ignorerà tutte le chiamate di scrittura di traccia fino a quando non viene registrato.
Nota
Per la modalità kernel, tenere presente che, mentre i metadati del provider vengono archiviati in modo esplicito in TLG_METADATA_SEGMENT (con estensione rdata), le variabili create per l'handle (ad esempio, g_hProvider) e il nome del provider (ad esempio, "MyTraceLoggingProviderKM") non vengono assegnati in modo esplicito a un segmento e useranno i segmenti impliciti correnti.
La macro TRACELOGGING_DEFINE_PROVIDER prevede che le variabili passate siano nel pool non di paging. In caso contrario, il chiamante deve impostare il segmento di dati tramite #pragma data_seg (per uniqueVarName) o il segmento const tramite #pragma const_seg (per g_hMyProvider) prima di chiamare la macro TRACELOGGING_DEFINE_PROVIDER .
Registrare il driver con TraceLogging
Nella funzione DriverEntry è necessario registrare il provider TraceLogging. Per registrare il provider con TraceLogging, aggiungere la macro TraceLoggingRegister a DriverEntry:
// Register the TraceLogging provider in the DriverEntry method.
TraceLoggingRegister(g_hProvider);
Annullare la registrazione del provider nella routine di scaricamento o pulizia del driver
Nella funzione DriverUnload o cleanup annullare la registrazione del provider TraceLogging.
// Stop TraceLogging and unregister the provider
TraceLoggingUnregister(g_hProvider);
Registrare gli eventi nel codice
TraceLogging fornisce macro per la registrazione degli eventi.
La macro di base è TraceLoggingWrite. Questa macro ha la sintassi seguente:
TraceLoggingWrite(g_hProvider, "EventName", args...)
Dove g_hProvider è l'handle per il provider definito e "EventName" è un valore letterale stringa (non una variabile) usato per identificare l'evento specifico. Analogamente a printf o DbgPrint, la macro TraceLoggingWrite supporta un numero variabile di parametri aggiuntivi (fino a 99). I parametri (args) devono essere macro wrapper TraceLogging, ad esempio TraceLoggingLevel, TraceLoggingInt32 o TraceLoggingString. Le macro wrapper TraceLogging sono definite in TraceLoggingProvider.h.
Nota
Se si usa C++, è possibile utilizzare la macro wrapper TraceLoggingValue per regolare automaticamente il tipo. Se si scrive il driver in C, è necessario usare le macro di campo specifiche del tipo, ad esempio TraceLoggingInt32 o TraceLoggingUnicodeString.
L'esempio seguente registra un evento per il provider g_hProvider. L'evento è denominato "MyDriverEntryEvent". La macro usa i wrapper TraceLoggingPointer e TraceLoggingUnicodeString per scrivere il puntatore nell'oggetto driver e nel percorso del Registro di sistema nel log di traccia. Il wrapper TraceLoggingUnicodeString accetta un nome facoltativo. In questo esempio "RegPath" è il nome del valore RegistryPath. Se non viene specificato alcun nome, il valore viene usato come nome.
TraceLoggingWrite(
g_hProvider,
"MyDriverEntryEvent",
TraceLoggingPointer(DriverObject),
TraceLoggingUnicodeString(RegistryPath, "RegPath"));
);
Se si instrumenta un driver in modalità kernel (in C), si collega a TraceLoggingProvider.h ed è possibile usare le macro TraceLoggingWrite, TraceLoggingWriteActivity o TraceLoggingActivityMarker . Per esempi di registrazione di traccia, vedere Esempi di traceLogging.
Se si instrumenta un driver o un componente scritto in C++, è possibile collegarsi a TraceLoggingProvider.h e TraceLoggingActivity.h. Quando si collega all'intestazione C++, è possibile registrare gli eventi con le macro TraceLoggingWriteStart, TraceLoggingWriteStop e TraceLoggingWriteTagged .
Per esempi di come acquisire e visualizzare i dati TraceLogging, vedere Acquisire e visualizzare i dati TraceLogging.