Compartilhar via


Adicionar 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 no modo de usuário, você precisa adicionar código (ou instrumento) aos arquivos de origem do driver e modificar o projeto de driver. Esta seção descreverá essas etapas.

Observação

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 Windows Driver (modo de usuário ou modo 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 no modo de usuário) deve ser definido exclusivamente. Você faz 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, definir um GUID de controle e definir 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 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 delimitados por parênteses, em vez dos hífens e chaves habituais. 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 */ \
            )                             
    

    Observação

    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 (Ferramentas | Criar GUID>). Você também pode usar a ferramenta Uuidgen.exe, que está disponível na janela de prompt do 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órios 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. Use 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).

    Observação

    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). Adicione 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 o 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 um debug print, uma função de mensagem de rastreamento é uma função (ou macro) que você adiciona ao código para escrever mensagens de rastreamento.

Escolhendo uma função de mensagem de rastreamento

  • A função de mensagem de rastreamento padrão é a macro DoTraceMessage . Se você usar a função padrão, poderá controlar o momento de gerar mensagens usando os valores do Trace Flag para o seu provedor. Os valores de Sinalizadores de Rastreamento são os sinalizadores definidos quando você criou o GUID de controle na Etapa 1. Se você usar o 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.

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

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

Criando ou personalizando uma função de mensagem de rastreamento

  1. Se você estiver usando funções de mensagens de rastreamento personalizadas ou quiser converter funções de impressão de depuração (por exemplo, KdPrint) para gerar mensagens de rastreamento, é necessário definir macros WPP que identifiquem e habilitem essas funções em seu provedor de rastreamento. Coloque essas macros no arquivo de cabeçalho Trace.h que você adicionou ao seu 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 de macros de WPP_LEVEL_ENABLED e WPP_LEVEL_LOGGER padrão.

Prazo Description
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 log está habilitado com a condição especificada.

Para as macros do WPP definidas, as CONDIÇÕES 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 condição, portanto, há apenas um parâmetro nos nomes de macro (WPP_LEVEL_ENABLED).

Observação

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 informações.

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 WPP personalizadas para uma função de mensagem de rastreamento que dá suporte aos parâmetros trace Level e Trace Flag 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 do WPP para uma função de mensagem de rastreamento personalizada chamada TraceEvents. A função de 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 mensagens de rastreamento, acrescentando uma declaração semelhante a FUNC 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 sinalizar {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 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
//

Observação

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 é 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 flags de rastreamento para o driver em um arquivo de cabeçalho (por exemplo, trace.h), é necessário incluir esse arquivo nos arquivos de origem em que irá inicializar e descarregar o WPP (conforme a Etapa 4) ou chamar funções de mensagem de rastreamento.

Além disso, você precisa adicionar uma instrução #include para o Arquivo de Cabeçalho de Mensagem de Rastreamento (.tmh). Quando você cria o driver ou o 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 limpar 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 limpar os recursos do WPP quando o driver sair.

  • 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 no DriverContextCleanup



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

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

   // ...

}

Exemplo de 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 do uso do driver UMDF 1.0 com as 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 funções de mensagem de rastreamento predefinidas e funções de depuração para impressã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 o 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, poderá usar a macro DoDebugTrace ou usar TraceEvents, que usa sinalizadores de rastreamento e níveis de rastreamento.
TraceEvents Se você criar um driver usando modelos do 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 na 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 precisa fazer mais nada. 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 declaraçõ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 3 parâmetros: o nível do sinalizador (TraceFlagName), que define a condição quando a mensagem de rastreamento é gravada, a cadeia de caracteres De mensagem 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 função em execução no momento (%FUNC!). Para obter mais informações sobre cadeias de caracteres de especificação de formato definido pelo WPP, consulte O que 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);

Usando instruções TraceEvents

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.

  1. Adicione a macro TraceEvents ao seu código como faria ao usar uma rotina de depuração para impressã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 De mensagem 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 função em execução no momento (%FUNC!). Para obter mais informações sobre cadeias de caracteres de especificação de formato definido pelo WPP, consulte O que 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 o Logman ou o 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 criar 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 do MSBuild.

Para executar o pré-processador WPP

  1. Selecione e segure (ou clique com o botão direito do mouse) no projeto de driver no Gerenciador de Soluções 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 opções adicionais para personalizar o comportamento de rastreamento. Para obter informações sobre o que você pode adicionar, consulte o Pré-processador WPP.
  5. Crie o projeto ou a solução para sua configuração e plataforma de destino. Consulte Como criar um driver com o WDK.

Para obter informações sobre o processo de build, consulte a tarefa TraceWPP e o ambiente de build do WDK e do Visual Studio.

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 seu 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 ter certeza de 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 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 abranger 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 de nível 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.