カーネル モード ドライバーとコンポーネント用の TraceLogging
このトピックでは、カーネル モードドライバーとコンポーネント内から TraceLogging API を使用する方法について説明します。
前提条件:
- Windows 10
- Visual Studio 2013 以降
- Windows 10 SDK
- Windows 10 用 Windows ドライバー キット (WDK)
TraceLogging ヘッダー ファイルを含める
TraceLogging API を使用するには、TraceLogging ヘッダー ファイル TraceLoggingProvider.h を含めます。 もう 1 つの TraceLogging API ヘッダー ファイル TraceLoggingActivity.h は、C++ で記述されたユーザー モード ドライバーでのみ使用できます。
#include <wdm.h>
#include <TraceLoggingProvider.h>
Note
カーネル モード ドライバーを開発するときは、TraceLoggingProvider.h に wdm.h ファイルが必要です。
ドライバーを TraceLogging プロバイダーとして宣言する
TRACELOGGING_DECLARE_PROVIDER マクロを追加して、プロバイダー ハンドル変数を宣言します。 マクロの構文は次のとおりです。
TRACELOGGING_DECLARE_PROVIDER(hProviderVariableName)
次の TraceLogging ステートメントの例では、g_hProvider との名前の変数を宣言します。
TRACELOGGING_DECLARE_PROVIDER(g_hProvider);
TRACELOGGING_DECLARE_PROVIDERで宣言する変数は、後でコードで TRACELOGGING_DEFINE_PROVIDER マクロを呼び出すときにプロバイダーへのハンドルになります。
Note
TraceLogging プロバイダーへのハンドルをグローバルに使用できるように、このマクロをヘッダー ファイルに配置できます。
TRACELOGGING_DEFINE_PROVIDER マクロを追加し、トレース プロバイダーとトレース プロバイダー ハンドルの名前を指定します。 ハンドルは、手順 1 で宣言した変数です。 マクロの構文は次のとおりです。
TRACELOGGING_DEFINE_PROVIDER(hProviderVariableName, "ProviderName", providerId [,option])
たとえば、次のステートメントは MyTraceLoggingProviderKM というプロバイダーを定義し、ハンドル g_hProvider に割り当てます。 providerId パラメーターは、ETW プロバイダーの GUID です。
TRACELOGGING_DEFINE_PROVIDER(g_hProvider, "MyTraceLoggingProviderKM", (0xb3864c38, 0x4273, 0x58c5, 0x54, 0x5b, 0x8b, 0x36, 0x08, 0x34, 0x34, 0x71));
TRACELOGGING_DEFINE_PROVIDER マクロは、プロバイダーにストレージを割り当て、プロバイダーへのグローバル ハンドルである対応する変数を定義します。 プロバイダー名は、(変数ではなく) 文字列リテラルである必要があり、'\0' 文字を含めてはなりません。 ハンドルとハンドルのコピーは、元のハンドルがスコープ内にある限り有効です。
TRACELOGGING_DEFINE_PROVIDER マクロを使用してハンドルを最初に作成すると、プロバイダーは未登録の状態になります。 この状態では、プロバイダーは登録されるまでトレース書き込み呼び出しを無視します。
Note
カーネル モードの場合、プロバイダー メタデータは明示的に TLG_METADATA_Standard Edition GMENT (.rdata) に格納されますが、ハンドル用に作成する変数 (たとえば、g_hProvider) とプロバイダーの名前 ("MyTraceLoggingProviderKM" など) は明示的にセグメントに割り当てられず、現在の暗黙的なセグメントが使用されることに注意してください。
TRACELOGGING_DEFINE_PROVIDER マクロは、渡された変数が非ページ プール内にあると想定しています。 この場合、呼び出し元は、TRACELOGGING_DEFINE_PROVIDER マクロを呼び出す前に、#pragma data_seg (uniqueVarName の場合) または #pragma const_seg (g_hMyProviderの場合) を介して const セグメントを使用してデータ セグメントを設定する必要があります。
ドライバーを TraceLogging に登録する
DriverEntry 関数では、TraceLogging プロバイダーを登録する必要があります。 プロバイダーを TraceLogging に登録するには、TraceLoggingRegister マクロを DriverEntry に追加します。
// Register the TraceLogging provider in the DriverEntry method.
TraceLoggingRegister(g_hProvider);
ドライバーのアンロードまたはクリーンアップ ルーチンでプロバイダーの登録を解除する
DriverUnload または クリーンup 関数で、TraceLogging プロバイダーの登録を解除します。
// Stop TraceLogging and unregister the provider
TraceLoggingUnregister(g_hProvider);
コード内のイベントをログに記録する
TraceLogging には、イベントをログ記録するためのマクロが用意されています。
基本的なマクロは TraceLoggingWrite です。 マクロ構文は、次のとおりです。
TraceLoggingWrite(g_hProvider, "EventName", args...)
ここで、g_hProvider は定義したプロバイダーのハンドルであり、"EventName" は、特定のイベントを識別するために使用する文字列リテラル (変数ではありません) です。 printf や DbgPrint と同様に、TraceLoggingWrite マクロでは、可変数の追加パラメーター (最大 99 個) がサポートされます。 パラメーター (引数) は、TraceLoggingLevel、TraceLoggingInt32、TraceLoggingString などの TraceLogging ラッパー マクロである必要があります。 TraceLogging ラッパー マクロは TraceLoggingProvider.h で定義されています。
Note
C++ を使用している場合は、TraceLoggingValue ラッパー マクロを使用して、型を自動的に調整できます。 C でドライバーを記述する場合は、型固有のフィールド マクロ (TraceLoggingInt32 や TraceLoggingUnicodeString など) を使用する必要があります。
次の例では、プロバイダーのイベント、g_hProvider をログに記録します。 イベントは "MyDriverEntryEvent" と呼ばれます。このマクロでは、TraceLoggingPointer ラッパーと TraceLoggingUnicodeString ラッパーを使用して、ドライバー オブジェクトへのポインターとトレース ログへのレジストリ パスを書き込みます。 TraceLoggingUnicodeString ラッパーは、省略可能な名前を受け取ります。 この例では、"RegPath" は RegistryPath 値の名前です。 名前が指定されていない場合、値が名前として使用されます。
TraceLoggingWrite(
g_hProvider,
"MyDriverEntryEvent",
TraceLoggingPointer(DriverObject),
TraceLoggingUnicodeString(RegistryPath, "RegPath"));
);
カーネル モード ドライバー (C) をインストルメント化する場合は、TraceLoggingProvider.h にリンクし、TraceLoggingWrite、TraceLoggingWriteActivity、または TraceLoggingActivityMarker マクロを使用できます。 トレース ログの例については、「トレース ログの例」を参照してください。
C++ で記述されたドライバーまたはコンポーネントをインストルメント化する場合は、TraceLoggingProvider.h と TraceLoggingActivity.h にリンクします。 C++ ヘッダーにリンクすると、TraceLoggingWriteStart、TraceLoggingWriteStop、TraceLoggingWriteTagged マクロを使用してイベントをログに記録できます。
TraceLogging データをキャプチャして表示する方法の例については、「TraceLogging データのキャプチャと表示」を参照してください。