Adicionando o Rastreamento de Software WPP a um Driver do Windows

Para usar o rastreamento de software WPP em um provedor de rastreamento, como um driver no modo kernel ou um aplicativo de modo de usuário, você precisa adicionar código (ou instrumentar) os arquivos de origem do driver e modificar o projeto do driver. Esta seção descreverá essas etapas.

Ponta A maneira mais fácil de adicionar o rastreamento do WPP ao driver é usar um dos modelos de driver KMDF ou UMDF no Visual Studio. Se você usar os modelos, grande parte do código que você precisa adicionar já está feito para você. No Visual Studio, selecione Arquivo > Novo > Projeto e, em seguida, selecione o projeto WDF do Driver do Windows (modo de usuário ou kernel). As macros do WPP são definidas no arquivo de cabeçalho Trace.h incluído como parte do projeto. Se você usar um dos modelos, poderá pular para a Etapa 5.

Etapa 1: Definir o GUID de controle e os sinalizadores de rastreamento

Cada provedor de rastreamento (como um driver ou aplicativo de modo de usuário) deve ser definido exclusivamente. Faça isso adicionando a macro WPP_CONTROL_GUIDS que define um GUID de controle, um identificador e sinalizadores de rastreamento. Isso é feito para que você possa identificar e controlar quando e o que deseja rastrear. Embora cada driver normalmente tenha um GUID de controle separado, um driver pode ter vários GUIDs de controle ou vários drivers podem compartilhar um GUID de controle.

Para conveniência, a macro WPP_CONTROL_GUIDS normalmente é definida em um arquivo de cabeçalho comum. O arquivo de cabeçalho deve ser incluído (#include) em qualquer arquivo de origem que você pretende instrumentar para rastreamento.

Para adicionar WPP_CONTROL_GUIDS macro ao driver:

  1. Adicione um novo arquivo de cabeçalho C++ ao projeto do Visual Studio que você pode usar para definir as macros de rastreamento do WPP. Por exemplo, selecione e segure (ou clique com o botão direito do mouse) no driver no Gerenciador de Soluções e selecione Adicionar > Novo Item. Salve o arquivo (como Trace.h, por exemplo).

  2. Adicione uma macro WPP_CONTROL_GUIDS para especificar o nome amigável para o provedor de rastreamento, defina um GUID de controle e defina os sinalizadores de rastreamento que você pode usar para qualificar mensagens de rastreamento específicas.

    A macro WPP_CONTROL_GUIDS tem a seguinte sintaxe:

    Sintaxe para 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) \
            )
    

    Por exemplo, o código a seguir usa myDriverTraceGuid como o GUIDFriendlyName. Observe que ControlGUID tem um formato ligeiramente diferente da forma padrão de um GUID hexadecimal de 32 dígitos. O ControlGUID tem os cinco campos, mas eles são separados por vírgulas e entre colchetes por parênteses, em vez dos hífens e chaves usuais. Por exemplo, você especifica ((84bdb2e9,829e,41b3,b891,02f454bc2bd7) em vez de {84bdb2e9-829e-41b3-b891-02f454bc2bd7}.

    Exemplo de uma instrução 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 */ \
            )                             
    

    Ponta Você pode copiar esse snippet de código em um arquivo de cabeçalho. Certifique-se de alterar o GUID de controle e o nome amigável. Você pode usar GUIDgen.exe para gerar o GUID de controle. O Guidgen.exe está incluído no Visual Studio (Guid de Criação de Ferramentas>). Você também pode usar a ferramenta Uuidgen.exe, que está disponível na janela prompt de comando do Visual Studio (digite uuidgen.exe /? para obter mais informações).

  3. Defina os Sinalizadores de Rastreamento para seu provedor de rastreamento.

    Os elementos WPP_DEFINE_BIT da macro WPP_CONTROL_GUIDS definem os sinalizadores de rastreamento para o provedor de rastreamento. Normalmente, os sinalizadores representam níveis de relatório cada vez mais detalhados, mas você pode usar sinalizadores como quiser como condições para gerar mensagens de rastreamento. No exemplo WPP_CONTROL_GUIDS, o WPP_DEFINE_BIT define quatro sinalizadores de rastreamento (MYDRIVER_ALL_INFO, TRACE_DRIVER, TRACE_DEVICE e TRACE_QUEUE).

    Você pode definir até 31 sinalizadores de rastreamento. O WPP atribui valores de bit aos elementos na ordem em que aparecem, por exemplo, bit 0 (0x1), bit 1 (0x2), bit 2 (0x4), bit 3 (0x8) e assim por diante. Você usa os sinalizadores de rastreamento ao adicionar funções de mensagem de rastreamento ao código-fonte (descrito na Etapa 5: Instrumentar o código do driver para gerar mensagens de rastreamento em pontos apropriados).

    Nota Usando os sinalizadores de rastreamento, você pode controlar quando rastrear componentes específicos (por exemplo, solicitações de E/S específicas ou atividades de objetos de dispositivo ou driver). Você adiciona o sinalizador de rastreamento à instrução de mensagem de rastreamento (por exemplo, DoTraceMessage (TRACE_DRIVER, "Hello World!\n"). Ao criar uma sessão de rastreamento com um controlador de rastreamento, como Tracelog, você especifica a opção -flag a ser usada para o provedor de rastreamento nessa sessão, nesse caso, o sinalizador é o bit 1 (0x1), que corresponde ao sinalizador TRACE_DRIVER. Quando você inicia a sessão de rastreamento, todas as mensagens de rastreamento que especificam esse sinalizador de rastreamento são gravadas no log.

Etapa 2: escolha quais funções de mensagem de rastreamento você pretende usar e defina as macros do WPP para essas funções

Como uma função de impressão de depuração, uma função de mensagem de rastreamento é uma função (ou macro) que você adiciona ao seu código para gravar mensagens de rastreamento.

Escolhendo uma função de mensagem de rastreamento

  1. A função de mensagem de rastreamento padrão é a macro DoTraceMessage . Se você usar a função padrão, poderá controlar quando gerar mensagens usando os valores de Sinalizador de Rastreamento para seu provedor. Os valores sinalizadores de rastreamento são os sinalizadores definidos quando você criou o GUID de controle na Etapa 1. Se você usar DoTraceMessage, as macros WPP padrão já serão definidas para você (WPP_LEVEL_ENABLED e WPP_LEVEL_LOGGER), para que você possa ignorar o restante desta etapa e ir para a Etapa 5.

  2. Se você estiver usando um dos modelos KMDF ou UMDF, a função TraceEvents e as macros WPP necessárias já estarão definidas para habilitar essa função, para que você possa pular para a Etapa 5.

  3. Se você estiver criando sua própria função de mensagem de rastreamento ou convertendo a função de impressão de depuração existente, continue com o restante desta etapa.

Criar ou personalizar uma função de mensagem de rastreamento

  1. Se você estiver usando funções de mensagem de rastreamento personalizadas ou quiser converter funções de impressão de depuração (por exemplo, KdPrint) para gerar mensagens de rastreamento, será necessário definir macros WPP que identificam e habilitam as funções de mensagem de rastreamento em seu provedor de rastreamento. Coloque essas macros no arquivo de cabeçalho Trace.h que você adicionou ao projeto.

  2. Defina as macros do WPP para habilitar a função de rastreamento.

    Cada função de mensagem de rastreamento que você usa deve ter um par correspondente de macros. Essas macros identificam o provedor de rastreamento e especificam as condições que geram as mensagens. Normalmente, você define um par de macros, WPP_<condition>_LOGGER e WPP_<condition>_ENABLED em termos das macros de WPP_LEVEL_ENABLED e WPP_LEVEL_LOGGER padrão.

Cada função de mensagem de rastreamento que você usa deve ter um par correspondente de macros. Essas macros identificam o provedor de rastreamento e especificam as condições que geram as mensagens. Normalmente, você define um par de macros, WPP_<condition>_LOGGER e WPP_<condition>_ENABLED em termos das macros de WPP_LEVEL_ENABLED e WPP_LEVEL_LOGGER padrão.

Termo Descrição

WPP_CONDITIONS_LOGGER

Usado para localizar a sessão de rastreamento associada ao provedor e retorna um identificador para a sessão.

WPP_CONDITIONS_ENABLED

Usado para determinar se o registro em log está habilitado com a condição especificada.

Para as macros do WPP definidas, as CONDITIONS representam as condições às quais a função de mensagem de rastreamento dá suporte, na ordem em que aparecem na lista de parâmetros da função, separadas por sublinhados. Por exemplo, a função de mensagem de rastreamento padrão, DoTraceMessage, dá suporte apenas ao Sinalizador de Rastreamento como a condição, portanto, há apenas um parâmetro nos nomes de macro (WPP_LEVEL_ENABLED).

Nota Infelizmente, os nomes das macros padrão (WPP_LEVEL_ENABLED e WPP_LEVEL_LOGGER) parecem indicar o parâmetro Nível de Rastreamento , mas eles realmente se referem ao Sinalizador de Rastreamento.

Se você usar uma função de mensagem de rastreamento personalizada, poderá definir qualificadores adicionais, como o Nível de Rastreamento. O Nível de Rastreamento é definido no arquivo Evntrace.h e os níveis de rastreamento fornecem uma maneira conveniente de classificar as mensagens de rastreamento como mensagens de erro, aviso e informativas.

Por exemplo, você pode adicionar o snippet de código a seguir ao arquivo de cabeçalho adicionado ao projeto. O código a seguir define as macros personalizadas do WPP para uma função de mensagem de rastreamento que dá suporte a parâmetros de Nível de Rastreamento e sinalizador de rastreamento como condições para gerar mensagens de rastreamento. A macro WPP_LEVEL_FLAGS_ENABLED retornará TRUE se o registro em log estiver habilitado para o valor FLAGS especificado e o valor LEVEL habilitado for maior ou igual ao argumento de nível usado na chamada da função de mensagem de rastreamento.

#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)

Em seguida, você precisa especificar as funções de rastreamento personalizadas no bloco de configuração do WPP (begin_wpp configuração e end_wpp) Por exemplo, se você usar o modelo para projetos de Driver UMDF ou KMDF no Visual Studio, o modelo definirá as macros WPP para uma função de mensagem de rastreamento personalizada chamada TraceEvents. A função macro TraceEvents usa o nível de rastreamento e o sinalizador de rastreamento como condições para gerar mensagens. Se você tiver definido a macro WPP_LEVEL_FLAGS_ENABLED no arquivo de cabeçalho Trace.h, poderá adicionar a seguinte definição de macro.

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

Você também pode converter instruções de impressão de depuração existentes em instruções de rastreamento de mensagens por meio da adição de uma declaração FUNC semelhante no bloco de configuração do WPP. Por exemplo, o exemplo a seguir adiciona o código para converter as instruções KdPrint existentes. A declaração FUNC também define globalmente o KdPrint para usar o nível de rastreamento especificado e o sinalizador {LEVEL=TRACE_LEVEL_INFORMATION, FLAGS=TRACE_DRIVER}. Em vez de enviar a saída para o depurador, as instruções de impressão de depuração são enviadas para o log de rastreamento.

//
// 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 compatiblility with the KdPrint function.
//
// begin_wpp config
// FUNC TraceEvents(LEVEL, FLAGS, MSG, ...);
// FUNC KdPrint{LEVEL=TRACE_LEVEL_INFORMATION, FLAGS=TRACE_DRIVER}((MSG, ...));
// end_wpp
//

Nota Se você quiser converter KdPrintEx em uma função de mensagem de rastreamento, precisará executar algumas etapas adicionais. Em comparação com kdPrint, a função KdPrintEx usa dois argumentos adicionais. Para converter a função KdPrintEx , você precisa definir um WPP_DEFINE_BIT para o ComponentID e definir macros WPP_<condition>_LOGGER e WPP_<condition>_ENABLED personalizadas. O segundo parâmetro para KdPrintEx especifica que o nível de é semelhante aos valores de Nível de Rastreamento , portanto, você não precisa necessariamente redefini-los.


#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
//

Etapa 3: incluir os arquivos de cabeçalho de rastreamento associados (.h e .tmh) em seus arquivos de origem C ou C++

Se você definiu o GUID de controle e os sinalizadores de rastreamento do driver em um arquivo de cabeçalho (por exemplo, trace.h), precisará incluir o arquivo de cabeçalho nos arquivos de origem em que inicializará e descarregará o WPP (Etapa 4) ou chamará funções de mensagem de rastreamento.

Além disso, você precisa adicionar uma instrução #include para Arquivo de Cabeçalho de Mensagem de Rastreamento (.tmh). Quando você cria o driver ou aplicativo, o pré-processador WPP gera os arquivos de cabeçalho de mensagem de rastreamento (.tmh) para cada arquivo de origem que contém funções de mensagem de rastreamento.

/* -- 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 */

Etapa 4: Adicionar macros às funções de retorno de chamada apropriadas para inicializar e limpo o WPP

Para inicializar o WPP na entrada do driver

  • Adicione a macro WPP_INIT_TRACING à rotina DriverEntry de um driver no modo kernel ou driver UMDF 2.0 ou à rotina DLLMain de um driver de modo de usuário (UMDF 1.x) ou aplicativo.

Para limpo recursos do WPP na saída do driver

  • Adicione a macro WPP_CLEANUP à rotina de descarregamento do driver (por exemplo, DriverContextCleanup ou DriverUnload) de um driver no modo kernel ou driver UMDF 2.0.

    Para um driver de modo de usuário (UMDF 1.x) ou aplicativo, adicione a macro WPP_CLEANUP à rotina DLLMain .

    Você também deve adicionar a macro WPP_CLEANUP à rotina DriverEntry caso o DriverEntry falhe. Por exemplo, se o DriverEntry falhar, a rotina de descarregamento do driver não será chamada. Consulte a chamada para WdfDriverCreate no exemplo a seguir.

Exemplo de um driver no modo kernel usando WPP_INIT_TRACING e WPP_CLEANUP no 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;

}

Exemplo de um driver no modo kernel usando WPP_CLEANUP em DriverContextCleanup



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

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

   // ...

}

Exemplo para driver UMDF 2.0 usando WPP_INIT_TRACING no 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 );

Exemplo para o uso do driver UMDF 1.0 de macros WPP_INIT_TRACING e WPP_CLEANUP no 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);
}

Etapa 5: Instrumentar o código do driver para gerar mensagens de rastreamento em pontos apropriados

Você pode usar qualquer função de mensagem de rastreamento escolhida, desde que a função de mensagem de rastreamento, os sinalizadores de rastreamento e os níveis sejam definidos adequadamente. A função de mensagem de rastreamento padrão é a macro DoTraceMessage . Você pode adicionar essa macro ao código para gravar mensagens no arquivo de log. A tabela a seguir lista algumas das funções de mensagem de rastreamento predefinidas e as funções de impressão de depuração que você pode usar para criar mensagens de rastreamento.

Funções de mensagem de rastreamento de exemplo Quando usar
DoTraceMessage

Essa é a função de mensagem de rastreamento padrão. A vantagem de usar o DoTraceMessage é que a função já está definida para você. Você pode usar os sinalizadores de rastreamento especificados na macro WPP_CONFIG_GUIDS. A desvantagem de usar DoTraceMessage é que a função usa apenas um parâmetro condicional, ou seja, sinalizadores de rastreamento. Se você quiser usar níveis de rastreamento, para registrar somente mensagens de erro ou aviso, use a macro DoDebugTrace ou use TraceEvents, que usa sinalizadores de rastreamento e níveis de rastreamento.

TraceEvents

Se você criar um driver usando modelos WDF no Visual Studio, essa será a função de mensagem de rastreamento padrão. A vantagem de usar TraceEvents é que a função de mensagem de rastreamento, os sinalizadores de rastreamento e o nível de rastreamento já estão definidos para você. Além disso, os modelos também incluem instrumentação que grava mensagens no arquivo de log após a entrada e saída da função.

KdPrint, KdPrintEx, DbgPrint, DbgPrintEx

A vantagem de usar as funções de impressão de depuração é que você não precisa modificar suas instruções de impressão de depuração existentes. Você pode alternar facilmente de exibir mensagens no depurador para gravar mensagens de rastreamento em um arquivo. Se você personalizou a função de mensagem de rastreamento para incluir uma das funções de impressão de depuração, não precisará fazer mais nenhum trabalho. Ao criar uma sessão de rastreamento com Logman ou Tracelog ou outro controlador de rastreamento, basta especificar os sinalizadores e níveis para o provedor. Todas as instruções de impressão de depuração que atendam às condições especificadas são impressas no log.

Usando instruções DoTraceMessage

  1. Adicione a macro DoTraceMessage ao código como faria com uma rotina de impressão de depuração. A macro DoTraceMessage usa três parâmetros: o nível do sinalizador (TraceFlagName), que define a condição quando a mensagem de rastreamento é gravada, a cadeia de caracteres Message e a lista de variáveis opcionais.

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

    Por exemplo, a instrução DoTraceMessage a seguir grava o nome da função que contém a instrução DoTraceMessage quando o sinalizador TRACE_DRIVER, conforme definido em WPP_CONTROL_GUIDS, está habilitado para a sessão de rastreamento.

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

    O exemplo usa uma cadeia de caracteres predefinida para a da função em execução no momento (%FUNC!). Para obter mais informações sobre cadeias de caracteres de especificação de formato definidas pelo WPP, consulte Quais são as cadeias de caracteres de especificação de formato estendido do WPP?

  2. Para gerar a mensagem de rastreamento, crie uma sessão de rastreamento para seu provedor de rastreamento, usando Logman ou Tracelog, e especifique um sinalizador de rastreamento que define o sinalizador de TRACE_DRIVER (bit 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);

Se você estiver usando os modelos de driver do Windows no Visual Studio, a macro TraceEvents será definida para você no arquivo de cabeçalho Trace.h.

Usando instruções TraceEvents

  1. Adicione a macro TraceEvents ao seu código como faria com uma rotina de impressão de depuração. A macro TraceEvents usa os seguintes parâmetros: o nível de rastreamento (Nível) e o sinalizador de rastreamento (Sinalizadores), que definem a condição quando a mensagem de rastreamento é gravada, a cadeia de caracteres Message e a lista de variáveis opcionais.

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

    Por exemplo, a instrução TraceEvents a seguir grava o nome da função que contém a instrução TraceEvents quando as condições especificadas nos parâmetros Trace Level e Trace Flag são atendidas. O Nível de Rastreamento é um valor inteiro; qualquer coisa no ou abaixo do nível de rastreamento especificado para essa sessão de rastreamento será rastreado. O TRACE_LEVEL_INFORMATION é definido em Evntrace.h e tem o valor 4. O sinalizador TRACE_DRIVER (bit 1, 0x2) é definido em WPP_CONTROL_GUIDS. Se esse TRACE_DRIVER bit estiver definido para a sessão de rastreamento e o Nível de Rastreamento for 4 ou maior, TraceEvents gravará a mensagem de rastreamento.

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

    O exemplo usa uma cadeia de caracteres predefinida para a da função em execução no momento (%FUNC!). Para obter mais informações sobre cadeias de caracteres de especificação de formato definidas pelo WPP, consulte Quais são as cadeias de caracteres de especificação de formato estendido do WPP?

  2. Para gerar a mensagem de rastreamento, crie uma sessão de rastreamento para o provedor de rastreamento usando Logman ou Tracelog. Especifique um nível de rastreamento para TRACE_LEVEL_INFORMATION (4) ou superior e especifique um nível de rastreamento que define o bit TRACE_DRIVER (bit 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__);

Etapa 6: Modificar o projeto do Visual Studio para executar o pré-processador WPP e compilar a solução

O WDK fornece suporte para o Pré-processador WPP, para que você possa executar o pré-processador usando o Visual Studio e o ambiente MSBuild.

Para executar o pré-processador WPP

  1. Selecione e segure (ou clique com o botão direito do mouse) no projeto de driver em Soluções Explorer e selecione Propriedades.
  2. Na página de propriedades do projeto, selecione Propriedades de Configuração e selecione Rastreamento do WPP.
  3. Em Geral, defina a opção Executar WPP como Sim.
  4. Em Linha de Comando, adicione outras opções para personalizar o comportamento de rastreamento. Para obter informações sobre o que você pode adicionar, consulte Pré-processador WPP.
  5. Crie o projeto ou a solução para sua configuração e plataforma de destino. Consulte Criando um driver com o WDK.

Para obter informações sobre o processo de build, consulte TraceWPP task e WDK and Visual Studio build environment.

Você também pode executar o pré-processador separado do ambiente de build usando a ferramenta TraceWPP (TraceWPP.exe). Essa ferramenta está localizada no subdiretório bin/x86 e bin/x64 do WDK.

Etapa 7: Iniciar uma sessão de rastreamento para capturar e verificar suas mensagens de rastreamento

Para verificar se você configurou o rastreamento do WPP corretamente, instale seu driver ou aplicativo em um computador de teste e crie uma sessão de rastreamento para capturar as mensagens de rastreamento. Você pode criar uma sessão de rastreamento para o provedor de rastreamento usando qualquer controlador de rastreamento, como Logman, Tracelog ou TraceView. Você pode ter as mensagens gravadas em um arquivo de log ou enviadas para um depurador de kernel. Dependendo das funções de mensagem de rastreamento que você está usando, você precisa especificar os sinalizadores de rastreamento e os níveis de rastreamento que gerarão as mensagens.

Por exemplo, se você estiver usando os níveis de rastreamento definidos em Evntrace.h e quiser capturar TRACE_LEVEL_INFORMATION (4) ou superior, precisará definir o nível como 4. Quando você define o nível como 4 para a sessão de rastreamento, todas as mensagens informativas (4), aviso (3), erro (2) e críticas (1) também serão capturadas, supondo que quaisquer outras condições, como sinalizadores de rastreamento, também sejam atendidas.

Para verificar se todas as mensagens são geradas, você pode apenas definir o nível de rastreamento e os sinalizadores de rastreamento como valores máximos para que todas as mensagens sejam geradas. Os sinalizadores de rastreamento usam uma máscara de bits (ULONG), para que você possa definir todos os bits (por exemplo, 0xFFFFFFFF). Os níveis de rastreamento são representados por um valor de byte. Por exemplo, se você estiver usando o Logman, poderá especificar 0xFF para cobrir todos os níveis.

(Exemplo) Iniciando uma sessão de rastreamento usando o 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"

(Exemplo) Iniciando uma sessão de rastreamento usando TraceLog

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

O comando Tracelog inclui o parâmetro -f para especificar o nome e o local do arquivo de log de rastreamento de eventos. Ele inclui o parâmetro -flag para especificar o conjunto de sinalizadores e o parâmetro -level para especificar a configuração de nível. Você pode omitir esses parâmetros, mas alguns provedores de rastreamento não geram mensagens de rastreamento, a menos que você defina o sinalizador ou o nível. O Nível de Rastreamento é definido no arquivo Evntrace.h e os níveis de rastreamento fornecem uma maneira conveniente de classificar as mensagens de rastreamento como mensagens críticas, de erro, de aviso e informativas.