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


Добавление трассировки программного обеспечения WPP в драйвер Windows

Чтобы использовать трассировку программного обеспечения WPP в поставщике трассировки, таком как драйвер в режиме ядра или приложение в пользовательском режиме, необходимо добавить код (или инструментировать) исходные файлы драйвера и изменить проект драйвера. В этом разделе описаны эти действия.

Совет Самый простой способ добавить трассировку WPP в драйвер — использовать один из шаблонов драйвера KMDF или UMDF в Visual Studio. Если вы используете шаблоны, большая часть кода, который необходимо добавить, уже выполнена. В Visual Studio выберите Файл > Новый > проект, а затем выберите проект WDF Драйвера Windows (в пользовательском режиме или режиме ядра). Макросы WPP определяются в файле заголовка Trace.h, который входит в состав проекта. Если вы используете один из шаблонов, можно перейти к шагу 5.

Шаг 1. Определение GUID элемента управления и флагов трассировки

Каждый поставщик трассировки (например, драйвер или приложение пользовательского режима) должен быть уникальным. Для этого добавьте макрос WPP_CONTROL_GUIDS , который определяет GUID элемента управления, идентификатор и флаги трассировки. Это делается для того, чтобы можно было определить и контролировать, когда и что требуется отслеживать. Хотя каждый драйвер обычно имеет отдельный GUID элемента управления, драйвер может иметь несколько GUID элемента управления или несколько драйверов могут совместно использовать один GUID элемента управления.

Для удобства макрос WPP_CONTROL_GUIDS обычно определяется в общем файле заголовка. Файл заголовка должен быть включен (#include) в любой исходный файл, который планируется инструментировать для трассировки.

Чтобы добавить макрос WPP_CONTROL_GUIDS в драйвер, выполните приведенные далее действия.

  1. Добавьте новый файл заголовка C++ в проект Visual Studio, который можно использовать для определения макросов трассировки WPP. Например, выберите и удерживайте (или щелкните правой кнопкой мыши) драйвер в Обозреватель решений, а затем выберите Добавить > новый элемент. Сохраните файл (например, как Trace.h).

  2. Добавьте макрос WPP_CONTROL_GUIDS , чтобы указать понятное имя для поставщика трассировки, определить GUID элемента управления и определить флаги трассировки, которые можно использовать для определения определенных сообщений трассировки.

    Макрос WPP_CONTROL_GUIDS имеет следующий синтаксис:

    Синтаксис для WPP_CONTROL_GUIDS

    #define WPP_CONTROL_GUIDS \
        WPP_DEFINE_CONTROL_GUID(GUIDFriendlyName, (ControlGUID),  \
            WPP_DEFINE_BIT(NameOfTraceFlag1)  \
            WPP_DEFINE_BIT(NameOfTraceFlag2)  \
            .............................   \
            .............................   \
            WPP_DEFINE_BIT(NameOfTraceFlag31) \
            )
    

    Например, следующий код использует myDriverTraceGuid в качестве GUIDFriendlyName. Обратите внимание, что формат ControlGUID немного отличается от стандартной формы шестнадцатеричного идентификатора GUID из 32 цифр. ControlGUID содержит пять полей, но они разделены запятыми и заключены в скобки вместо обычных дефисов и фигурных скобок. Например, укажите ((84bdb2e9,829e,41b3,b891,02f454bc2bd7) вместо {84bdb2e9-829e-41b3-b891-02f454bc2bd7}.

    Пример оператора WPP_CONTROL_GUIDS

    #define WPP_CONTROL_GUIDS                                              \
        WPP_DEFINE_CONTROL_GUID(                                           \
            myDriverTraceGuid, (84bdb2e9,829e,41b3,b891,02f454bc2bd7), \
            WPP_DEFINE_BIT(MYDRIVER_ALL_INFO)        /* bit  0 = 0x00000001 */ \
            WPP_DEFINE_BIT(TRACE_DRIVER)             /* bit  1 = 0x00000002 */ \
            WPP_DEFINE_BIT(TRACE_DEVICE)             /* bit  2 = 0x00000004 */ \
            WPP_DEFINE_BIT(TRACE_QUEUE)              /* bit  3 = 0x00000008 */ \
            )                             
    

    Совет Этот фрагмент кода можно скопировать в файл заголовка. Обязательно измените GUID элемента управления и понятное имя. Для создания GUID элемента управления можно использовать GUIDgen.exe. Guidgen.exe входит в состав Visual Studio (средства > создать GUID). Можно также использовать средство Uuidgen.exe, доступное в окне командной строки Visual Studio (для получения дополнительных сведений введитеuuidgen.exe /? ).

  3. Определите флаги трассировки для поставщика трассировки.

    Элементы WPP_DEFINE_BIT макроса WPP_CONTROL_GUIDS определяют флаги трассировки для поставщика трассировки. Как правило, флаги представляют все более подробные уровни отчетности, но флаги можно использовать любым способом в качестве условий для создания сообщений трассировки. В примере WPP_CONTROL_GUIDS WPP_DEFINE_BIT определяет четыре флага трассировки (MYDRIVER_ALL_INFO, TRACE_DRIVER, TRACE_DEVICE и TRACE_QUEUE).

    Можно определить до 31 флага трассировки. WPP присваивает битовые значения элементам в порядке их отображения, например бит 0 (0x1), бит 1 (0x2), бит 2 (0x4), бит 3 (0x8) и т. д. Флаги трассировки используются при добавлении функций сообщений трассировки в исходный код (описано в разделе Шаг 5. Инструментирование кода драйвера для создания сообщений трассировки в соответствующих точках).

    Примечание С помощью флагов трассировки можно управлять отслеживанием определенных компонентов (например, определенных запросов ввода-вывода или действий объектов устройства или драйвера). Вы добавляете флаг трассировки в инструкцию сообщения трассировки (например, DoTraceMessage (TRACE_DRIVER, "Hello World!\n"). При создании сеанса трассировки с контроллером трассировки, например Tracelog, вы указываете параметр -flag , используемый для поставщика трассировки в этом сеансе. В этом случае флагом является бит 1 (0x1), соответствующий флагу TRACE_DRIVER. При запуске сеанса трассировки все сообщения трассировки, указывающие этот флаг трассировки, записываются в журнал.

Шаг 2. Выбор функций сообщений трассировки, которые вы планируете использовать, и определение макросов WPP для этих функций

Как и функция отладочной печати, функция сообщений трассировки — это функция (или макрос), добавляемая в код для записи сообщений трассировки.

Выбор функции сообщения трассировки

  1. Функция сообщения трассировки по умолчанию — макрос DoTraceMessage . Если вы используете функцию по умолчанию, вы можете управлять моментом создания сообщений с помощью значений флага трассировки для поставщика. Значения флагов трассировки — это флаги, определенные при создании GUID элемента управления на шаге 1. Если вы используете DoTraceMessage, макросы WPP по умолчанию уже определены (WPP_LEVEL_ENABLED и WPP_LEVEL_LOGGER), поэтому вы можете пропустить оставшуюся часть этого шага и перейти к шагу 5.

  2. Если вы используете один из шаблонов KMDF или UMDF, функция TraceEvents и необходимые макросы WPP уже определены для включения этой функции, поэтому вы можете перейти к шагу 5.

  3. Если вы создаете собственную функцию сообщений трассировки или преобразуете существующую функцию печати отладки, перейдите к остальной части этого шага.

Создание или настройка функции сообщений трассировки

  1. Если вы используете пользовательские функции сообщений трассировки или хотите преобразовать отладочные функции печати (например, KdPrint) для создания сообщений трассировки, необходимо определить макросы WPP, которые идентифицируют и активируют функции сообщений трассировки в поставщике трассировки. Поместите эти макросы в файл заголовка Trace.h, добавленный в проект.

  2. Определите макросы WPP, чтобы включить функцию трассировки.

    Каждая используемая функция сообщения трассировки должна иметь соответствующую пару макросов. Эти макросы идентифицируют поставщика трассировки и указывают условия, которые создают сообщения. Обычно определяется пара макросов , WPP_<условие>_LOGGER и WPP_<условие>_ENABLED с точки зрения макросов по умолчанию WPP_LEVEL_ENABLED и WPP_LEVEL_LOGGER.

Каждая используемая функция сообщения трассировки должна иметь соответствующую пару макросов. Эти макросы идентифицируют поставщика трассировки и указывают условия, которые создают сообщения. Обычно определяется пара макросов , WPP_<условие>_LOGGER и WPP_<условие>_ENABLED с точки зрения макросов по умолчанию WPP_LEVEL_ENABLED и WPP_LEVEL_LOGGER.

Термин Описание

WPP_CONDITIONS_LOGGER

Используется для поиска сеанса трассировки, связанного с поставщиком, и возвращает дескриптор сеансу.

WPP_УСЛОВИЯ_ENABLED

Используется для определения того, включено ли ведение журнала с указанным условием.

Для макросов WPP, которые вы определяете, условия представляют условия, поддерживаемые функцией сообщений трассировки, в порядке их отображения в списке параметров функции, разделенных символами подчеркивания. Например, функция сообщений трассировки по умолчанию DoTraceMessage поддерживает только флаг трассировки в качестве условия, поэтому в именах макросов есть только один параметр (WPP_LEVEL_ENABLED).

Примечание К сожалению, имена макросов по умолчанию (WPP_LEVEL_ENABLED и WPP_LEVEL_LOGGER) указывают на параметр Уровень трассировки , но фактически они ссылаются на флаг трассировки.

Если вы используете пользовательскую функцию сообщений трассировки, можно задать дополнительные квалификаторы, такие как уровень трассировки. Уровень трассировки определяется в файле Evntrace.h, а уровни трассировки обеспечивают удобный способ классификации сообщений трассировки как сообщений об ошибках, предупреждениях и информационных сообщениях.

Например, можно добавить следующий фрагмент кода в файл заголовка, добавленный в проект. В следующем коде определяются пользовательские макросы WPP для функции сообщений трассировки, которая поддерживает параметры уровня трассировки и флага трассировки в качестве условий для создания сообщений трассировки. Макрос WPP_LEVEL_FLAGS_ENABLED возвращает значение TRUE, если ведение журнала включено для указанного значения FLAGS и значение параметра LEVEL больше или равно аргументу уровня, используемому в вызове функции сообщения трассировки.

#define WPP_LEVEL_FLAGS_LOGGER(lvl,flags) \
           WPP_LEVEL_LOGGER(flags)

#define WPP_LEVEL_FLAGS_ENABLED(lvl, flags) \
           (WPP_LEVEL_ENABLED(flags) && WPP_CONTROL(WPP_BIT_ ## flags).Level >= lvl)

Затем необходимо указать пользовательские функции трассировки в блоке конфигурации WPP (begin_wpp конфигурации и end_wpp). Например, если вы используете шаблон для проектов драйвера UMDF или KMDF в Visual Studio, шаблон определяет макросы WPP для пользовательской функции сообщений трассировки с именем TraceEvents. Макрофункла TraceEvents использует уровень трассировки и флаг трассировки в качестве условий для создания сообщений. Если вы определили макрос WPP_LEVEL_FLAGS_ENABLED в файле заголовка Trace.h, можно добавить следующее определение макроса.

//
// This comment block is scanned by the trace preprocessor to define the 
// TraceEvents function.
//
// begin_wpp config
// FUNC TraceEvents(LEVEL, FLAGS, MSG, ...);
// end_wpp
//

Вы также можете преобразовать существующие отладочные инструкции печати в инструкции сообщений трассировки, добавив аналогичное объявление FUNC в блок конфигурации WPP. Например, в следующем примере добавляется код для преобразования существующих инструкций KdPrint . Объявление FUNC также глобально определяет KdPrint для использования указанного уровня трассировки и флага {LEVEL=TRACE_LEVEL_INFORMATION, FLAGS=TRACE_DRIVER}. Вместо отправки выходных данных в отладчик инструкции отладочной печати отправляются в журнал трассировки.

//
// This comment block is scanned by the trace preprocessor to define the
// TraceEvents function and conversion for KdPrint. Note the double parentheses for the KdPrint message, for compatibility with the KdPrint function.
//
// begin_wpp config
// FUNC TraceEvents(LEVEL, FLAGS, MSG, ...);
// FUNC KdPrint{LEVEL=TRACE_LEVEL_INFORMATION, FLAGS=TRACE_DRIVER}((MSG, ...));
// end_wpp
//

Примечание Если вы хотите преобразовать KdPrintEx в функцию сообщений трассировки, необходимо выполнить несколько дополнительных действий. По сравнению с KdPrint функция KdPrintEx принимает два дополнительных аргумента. Чтобы преобразовать функцию KdPrintEx , необходимо определить WPP_DEFINE_BIT для ComponentID, а также пользовательские макросы WPP_<condition>_LOGGER и WPP_<condition>_ENABLED . Второй параметр для KdPrintEx указывает, что уровень аналогичен значениям уровня трассировки , поэтому их необязательно переопределить.


#define WPP_CONTROL_GUIDS                                              \
    WPP_DEFINE_CONTROL_GUID(\
    myDriverTraceGuid, (11C3AAE4, 0D88, 41b3, 43BD, AC38BF747E19), \    /* change GUID for your provider */
        WPP_DEFINE_BIT(MYDRIVER_ALL_INFO)        /* bit  0 = 0x00000001 */ \
        WPP_DEFINE_BIT(TRACE_DRIVER)             /* bit  1 = 0x00000002 */ \
        WPP_DEFINE_BIT(TRACE_DEVICE)             /* bit  2 = 0x00000004 */ \
        WPP_DEFINE_BIT(TRACE_QUEUE)              /* bit  3 = 0x00000008 */ \
        WPP_DEFINE_BIT(DPFLTR_IHVDRIVER_ID)      /* bit  4 = 0x00000010 */\         /* Added for the ComponentID param of KdPrintEx */
    )

#define WPP_Flags_LEVEL_LOGGER(Flags, level)                                  \
    WPP_LEVEL_LOGGER(Flags)

#define WPP_Flags_LEVEL_ENABLED(Flags, level)                                 \
    (WPP_LEVEL_ENABLED(Flags) && \
    WPP_CONTROL(WPP_BIT_ ## Flags).Level >= level)



//
// This comment block is scanned by the trace preprocessor to convert the KdPrintEx function.
// Note the double parentheses for the KdPrint message, for compatiblility with the KdPrintEx function.
//
// begin_wpp config
// FUNC KdPrintEx((Flags, LEVEL, MSG, ...));   
// end_wpp
//

Шаг 3. Включите связанные файлы заголовков трассировки (.h и .tmh) в исходные файлы C или C++

Если вы определили GUID элемента управления и флаги трассировки для драйвера в файле заголовка (например, trace.h), необходимо включить файл заголовка в исходные файлы, где будет инициализировать и выгружать WPP (шаг 4) или вызывать функции сообщений трассировки.

Кроме того, необходимо добавить инструкцию #include для файла заголовка сообщения трассировки (TMH). При сборке драйвера или приложения препроцессор WPP создает файлы заголовков сообщений трассировки (TMH) для каждого исходного файла, содержащего функции сообщений трассировки.

/* -- driver.c  - include the *.tmh file that is generated by WPP --*/

#include "trace.h"     /* file that defines WPP_CONFIG_GUIDS and trace flags */
#include "driver.tmh"  /* this file is auto-generated */

Шаг 4. Добавление макросов в соответствующие функции обратного вызова для инициализации и очистки WPP

Инициализация WPP в записи драйвера

  • Добавьте макрос WPP_INIT_TRACING в подпрограмму DriverEntry драйвера в режиме ядра или драйвера UMDF 2.0 или в подпрограмму DLLMain драйвера пользовательского режима (UMDF 1.x) или приложения.

Очистка ресурсов WPP при выходе драйвера

  • Добавьте макрос WPP_CLEANUP в подпрограмму выгрузки драйвера (например, DriverContextCleanup или DriverUnload) драйвера режима ядра или драйвера UMDF 2.0.

    Для драйвера пользовательского режима (UMDF 1.x) или приложения добавьте макрос WPP_CLEANUP в подпрограмму DLLMain .

    Также следует добавить макрос WPP_CLEANUP в подпрограмму DriverEntry в случае сбоя DriverEntry . Например, в случае сбоя DriverEntry подпрограмма выгрузки драйвера не будет вызываться. См. вызов WdfDriverCreate в следующем примере.

Пример драйвера в режиме ядра с использованием WPP_INIT_TRACING и WPP_CLEANUP в DriverEntry


NTSTATUS
DriverEntry(
    _In_ PDRIVER_OBJECT  DriverObject,
    _In_ PUNICODE_STRING RegistryPath
    )
{  

          //  ... 

                //
    // Initialize WPP Tracing in DriverEntry
    //
    WPP_INIT_TRACING( DriverObject, RegistryPath );

                //  ...


 //
    // Create a framework driver object to represent our driver.
    //
    status = WdfDriverCreate(
        DriverObject,
        RegistryPath,
        &attributes, // Driver Object Attributes
        &config,          // Driver Config Info
        WDF_NO_HANDLE // hDriver
        );

    if (!NT_SUCCESS(status)) {

        TraceEvents(TRACE_LEVEL_ERROR, DBG_INIT,
                "WdfDriverCreate failed with status 0x%x\n", status);
        //
        // Cleanup tracing here because DriverContextCleanup will not be called
        // as we have failed to create WDFDRIVER object itself.
        // Please note that if you return failure from DriverEntry after the
        // WDFDRIVER object is created successfully, you don't have to
        // call WPP cleanup because in those cases DriverContextCleanup
        // will be executed when the framework deletes the DriverObject.
        //
        WPP_CLEANUP(DriverObject);

    }

                return status;

}

Пример драйвера в режиме ядра с использованием WPP_CLEANUP в DriverContextCleanup



VOID
DriverContextCleanup(
       PDRIVER_OBJECT DriverObject
       )
{
    // ...

    // Clean up WPP resources on unload
    //
    WPP_CLEANUP(DriverObject);

   // ...

}

Пример для драйвера UMDF 2.0 с использованием WPP_INIT_TRACING в DriverEntry


/
// Driver specific #defines in trace header file (trace.h)
//
#define MYDRIVER_TRACING_ID      L"Microsoft\\UMDF2.0\\UMDF2_0Driver1 V1.0"

 // Initialize WPP Tracing in the DriverEntry routine
 //
    WPP_INIT_TRACING( MYDRIVER_TRACING_ID );

Пример использования в драйвере UMDF 1.0 макросов WPP_INIT_TRACING и WPP_CLEANUP в DLLMain

/
// Driver specific #defines in trace header file (for example, trace.h)
//
#define MYDRIVER_TRACING_ID      L"Microsoft\\UMDF1.X\\UMDF1_XDriver1"


//
// DLL Entry Point - UMDF 1.0 example in the source file where you implement the DLL exports.
// 

extern "C"
BOOL
WINAPI
DllMain(
    HINSTANCE hInstance,
    DWORD dwReason,
    LPVOID lpReserved
    )
{
    if (dwReason == DLL_PROCESS_ATTACH) {
        WPP_INIT_TRACING(MYDRIVER_TRACING_ID);              // Initialize WPP tracing

        g_hInstance = hInstance;
        DisableThreadLibraryCalls(hInstance);

    } else if (dwReason == DLL_PROCESS_DETACH) {
        WPP_CLEANUP();                                                                                                              // Deactivate and cleanup WPP tracing
    }

    return _AtlModule.DllMain(dwReason, lpReserved);
}

Шаг 5. Инструментирование кода драйвера для создания сообщений трассировки в соответствующих точках

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

Примеры функций сообщений трассировки Назначение
DoTraceMessage

Это функция сообщений трассировки по умолчанию. Преимущество использования DoTraceMessage заключается в том, что функция уже определена. Вы можете использовать флаги трассировки, указанные в макросе WPP_CONFIG_GUIDS. Недостаток использования DoTraceMessage заключается в том, что функция принимает только один условный параметр, то есть флаги трассировки. Если вы хотите использовать уровни трассировки, регистрируются только сообщения об ошибках или предупреждениях, можно использовать макрос DoDebugTrace или TraceEvents, в котором используются как флаги трассировки, так и уровни трассировки.

TraceEvents

Если вы создаете драйвер с помощью шаблонов WDF в Visual Studio, это функция сообщений трассировки по умолчанию. Преимущество использования TraceEvents заключается в том, что функция сообщения трассировки, флаги трассировки и уровень трассировки уже определены для вас. Кроме того, шаблоны также включают инструментирование, которое записывает сообщения в файл журнала при входе и выходе функции.

KdPrint, KdPrintEx, DbgPrint, DbgPrintEx

Преимущество использования отладочных функций печати заключается в том, что вам не нужно изменять существующие отладочные инструкции печати. Вы можете легко переключиться с просмотра сообщений в отладчике на запись сообщений трассировки в файл. Если вы настроили функцию сообщений трассировки так, чтобы она включала одну из отладочных функций печати, больше не нужно выполнять никаких действий. При создании сеанса трассировки с помощью Logman, Tracelog или другого контроллера трассировки достаточно указать флаги и уровни для поставщика. Все отладочные инструкции печати, соответствующие заданным условиям, печатаются в журнале.

Использование инструкций DoTraceMessage

  1. Добавьте макрос DoTraceMessage в код, как в отладочную процедуру печати. Макрос DoTraceMessage принимает 3 параметра: уровень флага (TraceFlagName), который определяет условие при записи сообщения трассировки, строку сообщения и список необязательных переменных.

    DoTraceMessage(TraceFlagName, Message, [VariableList... ]
    

    Например, следующий оператор DoTraceMessage записывает имя функции, содержащей инструкцию DoTraceMessage , когда флаг TRACE_DRIVER, как определено в WPP_CONTROL_GUIDS, включен для сеанса трассировки.

         DoTraceMessage( TRACE_DRIVER, "\nEntering %!FUNC!" );
    
    

    В примере используется предопределенная строка для выполняемой в данный момент функции (%FUNC!). Дополнительные сведения о строках спецификации определенного формата WPP см. в статье Что такое строки спецификации расширенного формата WPP?

  2. Чтобы создать сообщение трассировки, создайте сеанс трассировки для поставщика трассировки с помощью Logman или Tracelog и укажите флаг трассировки, который задает флаг TRACE_DRIVER (бит 1, 0x2).

//
//  DoTraceMessage examples
// 

     ...

// writes the name of the function that contains the trace statement when the flag, TRACE_DRIVER (bit 1, 0x2), 
// as defined in WPP_CONTROL_GUIDS, is enabled for the trace session.

     DoTraceMessage( TRACE_DRIVER, "\nEntering %!FUNC!" );

     ...

// writes the name of the function, the line number, and the error code 

      DoTraceMessage(
            TRACE_DRIVER,
            "[%s] Failed at %d (error code= %d)\n",
            __FUNCTION__,
            __LINE__,
            dwLastError);

Если вы используете шаблоны драйверов Windows в Visual Studio, макрос TraceEvents определяется в файле заголовка Trace.h.

Использование инструкций TraceEvents

  1. Добавьте макрос TraceEvents в код, как в отладочную процедуру печати. Макрос TraceEvents принимает следующие параметры: уровень трассировки (Level) и флаг трассировки (флаги), которые определяют условие при записи сообщения трассировки, строку сообщения и список необязательных переменных.

    TraceEvents(Level, Flags, Message, [VariableList... ]
    

    Например, следующая инструкция TraceEvents записывает имя функции, содержащей инструкцию TraceEvents, при выполнении условий, указанных в параметрах Уровень трассировки и Флаг трассировки. Уровень трассировки является целочисленным значением; Трассировка будет выполняться на уровне трассировки или ниже, заданном для этого сеанса трассировки. TRACE_LEVEL_INFORMATION определяется в Evntrace.h и имеет значение 4. Флаг TRACE_DRIVER (бит 1, 0x2) определен в WPP_CONTROL_GUIDS. Если этот TRACE_DRIVER бит задан для сеанса трассировки и уровень трассировки равен 4 или больше, TraceEvents записывает сообщение трассировки.

            TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Entry");
    
    

    В примере используется предопределенная строка для выполняемой в данный момент функции (%FUNC!). Дополнительные сведения о строках спецификации определенного формата WPP см. в статье Что такое строки спецификации расширенного формата WPP?

  2. Чтобы создать сообщение трассировки, создайте сеанс трассировки для поставщика трассировки с помощью Logman или Tracelog. Укажите уровень трассировки TRACE_LEVEL_INFORMATION (4) или более поздней версии, а также уровень трассировки, который задает бит TRACE_DRIVER (бит 1, 0x2).

//
//  TraceEvents examples
// 


    TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Entry");

//


    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT,
                       "OSRUSBFX2 Driver Sample - Driver Framework Edition.\n");

    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT,
                "Built %s %s\n", __DATE__, __TIME__);

Шаг 6. Изменение проекта Visual Studio для запуска препроцессора WPP и сборки решения

WDK обеспечивает поддержку препроцессора WPP, что позволяет запускать препроцессор с помощью Visual Studio и среды MSBuild.

Запуск препроцессора WPP

  1. Выберите и удерживайте (или щелкните правой кнопкой мыши) проект драйвера в разделе Решения Обозреватель и выберите Свойства.
  2. На странице свойств проекта выберите Свойства конфигурации и трассировка WPP.
  3. В разделе Общие установите для параметра Запуск WPP значение Да.
  4. В разделе Командная строка добавьте все дополнительные параметры для настройки поведения трассировки. Сведения о том, что можно добавить, см. в разделе Препроцессор WPP.
  5. Создайте проект или решение для целевой конфигурации и платформы. См. раздел Создание драйвера с помощью WDK.

Сведения о процессе сборки см. в разделе Задача TraceWPP и среда сборки WDK и Visual Studio.

Вы также можете запустить препроцессор отдельно от среды сборки с помощью средства TraceWPP (TraceWPP.exe). Это средство находится в подкаталоге bin/x86 и bin/x64 WDK.

Шаг 7. Запуск сеанса трассировки для записи и проверки сообщений трассировки

Чтобы убедиться, что трассировка WPP настроена правильно, необходимо установить драйвер или приложение на тестовом компьютере, а затем создать сеанс трассировки для записи сообщений трассировки. Вы можете создать сеанс трассировки для поставщика трассировки, используя любой контроллер трассировки, например Logman, Tracelog или TraceView. Сообщения можно записать в файл журнала или отправить в отладчик ядра. В зависимости от используемой функции сообщений трассировки необходимо обязательно указать флаги трассировки и уровни трассировки, которые будут создавать сообщения.

Например, если вы используете уровни трассировки, определенные в Evntrace.h, и хотите записать TRACE_LEVEL_INFORMATION (4) или более поздней версии, необходимо задать уровень 4. При установке уровня 4 для сеанса трассировки все информационные сообщения (4), предупреждения (3), ошибки (2) и критические (1) сообщения также будут записываться при условии, что выполняются и другие условия, такие как флаги трассировки.

Чтобы убедиться, что все сообщения созданы, можно просто установить максимальные значения уровня трассировки и флагов трассировки, чтобы все сообщения были созданы. Флаги трассировки используют битовую маску (ULONG), поэтому можно задать все биты (например, 0xFFFFFFFF). Уровни трассировки представлены байтовой величиной. Например, если вы используете Logman, можно указать, 0xFF для всех уровней.

(Пример) Запуск сеанса трассировки с помощью Logman

logman create trace "myWPP_session" -p {11C3AAE4-0D88-41b3-43BD-AC38BF747E19} 0xffffffff 0xff -o c:\DriverTest\TraceFile.etl 

logman start "myWPP_session"

logman stop "myWPP_session"

(Пример) Запуск сеанса трассировки с помощью TraceLog

tracelog -start MyTrace -guid  MyProvider.guid -f d:\traces\testtrace.etl -flag 2 -level 0xFFFF

Команда Tracelog включает параметр -f для указания имени и расположения файла журнала трассировки событий. Он включает параметр -flag для указания набора флагов и параметр -level для указания параметра уровня. Эти параметры можно опустить, но некоторые поставщики трассировки не создают сообщения трассировки, если не задан флаг или уровень. Уровень трассировки определяется в файле Evntrace.h, а уровни трассировки обеспечивают удобный способ классификации сообщений трассировки как критических, сообщений об ошибках, предупреждений и информационных сообщений.