Поделиться через


TraceLogging для драйверов и компонентов, работающих в режиме ядра

В этом разделе описывается использование API TraceLogging из драйверов и компонентов в режиме ядра.

Необходимые условия:

  • Windows 10
  • Visual Studio 2013 (или более поздней версии)
  • Windows 10 SDK
  • Комплект драйверов Windows (WDK) для Windows 10

Включите заголовочные файлы TraceLogging

Чтобы использовать API TraceLogging, включите файл заголовка TraceLogging TraceLoggingProvider.h. Другой файл заголовка API TraceLogging, TraceLoggingActivity.h, доступен только для использования в драйверах пользовательского режима, написанных на C++.

#include <wdm.h>
#include <TraceLoggingProvider.h> 

Примечание.

Файл wdm.h необходим для TraceLoggingProvider.h при разработке драйверов режима ядра.

Объявите драйвер в качестве поставщика TraceLogging

  1. Добавьте макрос TRACELOGGING_DECLARE_PROVIDER, чтобы объявить переменную указателя поставщика. Макрос имеет синтаксис:

    TRACELOGGING_DECLARE_PROVIDER(hProviderVariableName)
    

    В следующем примере инструкция TraceLogging объявляет переменную с именем g_hProvider.

    TRACELOGGING_DECLARE_PROVIDER(g_hProvider);
    

    Переменная, объявленная через TRACELOGGING_DECLARE_PROVIDER, становится дескриптором поставщика при вызове макроса TRACELOGGING_DEFINE_PROVIDER позже в коде.

    Примечание.

    Этот макрос может потребоваться поместить в файл заголовка, чтобы дескриптор поставщика TraceLogging был доступен глобально.

  2. Добавьте макрос TRACELOGGING_DEFINE_PROVIDER и укажите имя поставщика трассировки и дескриптора поставщика трассировки. Дескриптор — это переменная, объявленная на шаге 1. Синтаксис макроса:

    TRACELOGGING_DEFINE_PROVIDER(hProviderVariableName, "ProviderName", providerId [,option])
    

    Например, следующая инструкция определяет поставщика MyTraceLoggingProviderKM и назначает его дескриптору g_hProvider. Параметр providerId — это GUID поставщика ETW.

    TRACELOGGING_DEFINE_PROVIDER(g_hProvider, "MyTraceLoggingProviderKM",
        (0xb3864c38, 0x4273, 0x58c5, 0x54, 0x5b, 0x8b, 0x36, 0x08, 0x34, 0x34, 0x71));
    

    Макрос TRACELOGGING_DEFINE_PROVIDER выделяет хранилище для поставщика и определяет соответствующую переменную, которая является глобальной ссылкой на поставщика. Имя поставщика должно быть строковым литералом (не переменной) и не должно содержать символы \0. Дескриптор и его копии остаются допустимыми, пока исходный дескриптор находится в пределах области видимости.

    При первом создании дескриптора с помощью макроса TRACELOGGING_DEFINE_PROVIDER провайдер находится в незарегистрированном состоянии. В этом состоянии поставщик будет игнорировать все вызовы записи трассировки, пока она не будет зарегистрирована.

    Примечание.

    Для режима ядра следует учитывать, что хотя метаданные поставщика явно хранятся в TLG_METADATA_SEGMENT (.rdata), переменные, которые вы создаете для дескриптора (например, g_hProvider), и имя поставщика (например, "MyTraceLoggingProviderKM") не получают сегмент явно и будут использовать текущие неявные сегменты.

Макрос TRACELOGGING_DEFINE_PROVIDER ожидает, что передаваемые ему переменные будут находиться в нелистируемом пуле. Если это еще не так, вызывающий объект должен задать сегмент данных через #pragma data_seg (для uniqueVarName) или сегмент константа через #pragma const_seg (для g_hMyProvider) перед вызовом макроса TRACELOGGING_DEFINE_PROVIDER .

Регистрация драйвера в TraceLogging

В функции DriverEntry необходимо зарегистрировать поставщика TraceLogging. Чтобы зарегистрировать поставщика в TraceLogging, добавьте макрос TraceLoggingRegister в DriverEntry:

// Register the TraceLogging provider in the DriverEntry method.
TraceLoggingRegister(g_hProvider);

Отмена регистрации поставщика в подпрограмме выгрузки или очистки драйвера

В функции DriverUnload или функции очистки отмените регистрацию провайдера TraceLogging.

// Stop TraceLogging and unregister the provider
TraceLoggingUnregister(g_hProvider);

Регистрируйте события в вашем коде

TraceLogging предоставляет макросы для событий ведения журнала.

Базовый макрос — TraceLoggingWrite. Этот макрос имеет следующий синтаксис:

TraceLoggingWrite(g_hProvider, "EventName", args...)

Где g_hProvider является дескриптором определенного поставщика, а "EventName" — строковый литерал (а не переменная), который используется для идентификации конкретного события. Как и printf или DbgPrint, макрос TraceLoggingWrite поддерживает переменное количество дополнительных параметров (до 99). Параметры (args) должны быть макросами оболочки TraceLogging, такими как TraceLoggingLevel, TraceLoggingInt32 или TraceLoggingStringString. Макросы оболочки TraceLogging определяются в TraceLoggingProvider.h.

Примечание.

При использовании 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 . Примеры ведения журнала трассировки см. в примерах TraceLogging.

Если вы инструктируете драйвер или компонент, написанный на C++, вы подключаете файлы TraceLoggingProvider.h и TraceLoggingActivity.h. При связывании с заголовком C++ можно регистрировать события с помощью макросов TraceLoggingWriteStart, TraceLoggingWriteStop и TraceLoggingWriteTagged .

Примеры отслеживания и просмотра данных TraceLogging см. в разделе "Запись и просмотр данных TraceLogging".