TraceLogging для драйверов и компонентов в режиме ядра
В этом разделе описывается использование API TraceLogging из драйверов и компонентов режима ядра.
Предварительные требования.
- Windows 10
- Visual Studio 2013 (или более поздней версии)
- Пакет SDK для Windows 10
- Комплект драйверов 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
Добавьте макрос TRACELOGGING_DECLARE_PROVIDER , чтобы объявить переменную дескриптора поставщика. Макрос имеет синтаксис:
TRACELOGGING_DECLARE_PROVIDER(hProviderVariableName)
В следующем примере инструкция TraceLogging объявляет переменную с именем g_hProvider.
TRACELOGGING_DECLARE_PROVIDER(g_hProvider);
Переменная, объявляемая с помощью TRACELOGGING_DECLARE_PROVIDER , становится дескриптором для поставщика при вызове макроса TRACELOGGING_DEFINE_PROVIDER позже в коде.
Примечание
Этот макрос может потребоваться поместить в файл заголовка, чтобы дескриптор поставщика TraceLogging был доступен глобально.
Добавьте макрос TRACELOGGING_DEFINE_PROVIDER и укажите имя поставщика трассировки и дескриптора поставщика трассировки. Дескриптор — это переменная, объявленная на шаге 1. Синтаксис макроса:
TRACELOGGING_DEFINE_PROVIDER(hProviderVariableName, "ProviderName", providerId [,option])
Например, следующая инструкция определяет поставщик с именем MyTraceLoggingProviderKM и назначает его дескриптору g_hProvider. Параметр providerId — это GUID поставщика трассировки событий Windows.
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) или сегмент const через #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 или cleanup отмените регистрацию поставщика 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 или TraceLoggingString. Макросы-оболочки 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 Examples.
При инструментировании драйвера или компонента, написанного на C++, необходимо создать ссылку на TraceLoggingProvider.h и TraceLoggingActivity.h. При связывании с заголовком C++ события можно регистрировать с помощью макросов TraceLoggingWriteStart, TraceLoggingWriteStop и TraceLoggingWriteTagged .
Примеры записи и просмотра данных TraceLogging см. в разделе Сбор и просмотр данных TraceLogging.