Agregar seguimiento de software de WPP a un controlador de Windows

Para usar el seguimiento de software de WPP en un proveedor de seguimiento, como un controlador en modo kernel o una aplicación en modo de usuario, debe agregar código (o instrumentar) los archivos de origen del controlador y modificar el proyecto de controlador. En esta sección se describen esos pasos.

Propina La manera más fácil de agregar el seguimiento de WPP al controlador es usar una de las plantillas de controlador KMDF o UMDF en Visual Studio. Si usa las plantillas, gran parte del código que necesita agregar ya se ha realizado por usted. En Visual Studio, seleccione Archivo > nuevo > proyecto y, a continuación, seleccione el proyecto WDF controlador de Windows (modo de usuario o modo kernel). Las macros de WPP se definen en el archivo de encabezado Trace.h que se incluye como parte del proyecto. Si usa una de las plantillas, puede ir directamente al paso 5.

Paso 1: Definir el GUID de control y las marcas de seguimiento

Cada proveedor de seguimiento (como un controlador o una aplicación en modo de usuario) debe definirse de forma única. Para ello, agregue la macro WPP_CONTROL_GUIDS que define un GUID de control, un identificador y marcas de seguimiento. Esto se hace para que pueda identificar y controlar cuándo y qué desea realizar un seguimiento. Aunque cada controlador normalmente tiene un GUID de control independiente, un controlador podría tener varios GUID de control o varios controladores podría compartir un GUID de control.

Por comodidad, la macro WPP_CONTROL_GUIDS normalmente se define en un archivo de encabezado común. El archivo de encabezado debe incluirse (#include) en cualquier archivo de origen que quiera instrumentar para el seguimiento.

Para agregar WPP_CONTROL_GUIDS macro al controlador:

  1. Agregue un nuevo archivo de encabezado de C++ al proyecto de Visual Studio que puede usar para definir las macros de seguimiento de WPP. Por ejemplo, seleccione y mantenga presionado (o haga clic con el botón derecho) en el controlador en Explorador de soluciones y seleccione Agregar > nuevo elemento. Guarde el archivo (como Trace.h, por ejemplo).

  2. Agregue una macro de WPP_CONTROL_GUIDS para especificar el nombre descriptivo para el proveedor de seguimiento, defina un GUID de control y defina las marcas de seguimiento que puede usar para calificar mensajes de seguimiento específicos.

    La macro WPP_CONTROL_GUIDS tiene la siguiente sintaxis:

    Sintaxis de 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 ejemplo, el código siguiente usa myDriverTraceGuid como GUIDFriendlyName. Tenga en cuenta que ControlGUID tiene un formato ligeramente diferente al formato estándar de un GUID hexadecimal de 32 dígitos. ControlGUID tiene los cinco campos, pero están separados por comas y entre paréntesis, en lugar de los guiones habituales y llaves. Por ejemplo, especifique ((84bdb2e9,829e,41b3,b891,02f454bc2bd7) en lugar de {84bdb2e9-829e-41b3-b891-02f454bc2bd7}.

    Ejemplo de una instrucción 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 */ \
            )                             
    

    Propina Puede copiar este fragmento de código en un archivo de encabezado. Asegúrese de cambiar el GUID del control y el nombre descriptivo. Puede usar GUIDgen.exe para generar el GUID de control. El Guidgen.exe se incluye con Visual Studio (Tools > Create GUID). También puede usar la herramienta Uuidgen.exe, que está disponible en la ventana del símbolo del sistema de Visual Studio (escriba uuidgen.exe /? para obtener más información).

  3. Defina las marcas de seguimiento para el proveedor de seguimiento.

    Los elementos WPP_DEFINE_BIT de la macro WPP_CONTROL_GUIDS definen las marcas de seguimiento para el proveedor de seguimiento. Normalmente, las marcas representan niveles de informes cada vez más detallados, pero puede usar marcas como cualquier forma que desee como condiciones para generar mensajes de seguimiento. En el ejemplo de WPP_CONTROL_GUIDS, el WPP_DEFINE_BIT define cuatro marcas de seguimiento (MYDRIVER_ALL_INFO, TRACE_DRIVER, TRACE_DEVICE y TRACE_QUEUE).

    Puede definir hasta 31 marcas de seguimiento. WPP asigna valores de bits a los elementos en el orden en que aparecen, por ejemplo, bit 0 (0x1), bit 1 (0x2), bit 2 (0x4), bit 3 (0x8) etc. Las marcas de seguimiento se usan al agregar funciones de mensaje de seguimiento al código fuente (se describe en paso 5: Instrumentar el código del controlador para generar mensajes de seguimiento en los puntos adecuados).

    Nota Con las marcas de seguimiento puede controlar cuándo realizar un seguimiento de componentes específicos (por ejemplo, solicitudes de E/S específicas o actividades de objetos de dispositivo o controlador). Agregue la marca de seguimiento a la instrucción de mensaje de seguimiento (por ejemplo, DoTraceMessage (TRACE_DRIVER, "Hello World!\n"). Cuando se crea una sesión de seguimiento con un controlador de seguimiento, como Tracelog, se especifica la opción -flag que se va a usar para el proveedor de seguimiento en esa sesión, en este caso, la marca es el bit 1 (0x1), que corresponde a la marca TRACE_DRIVER. Al iniciar la sesión de seguimiento, todos los mensajes de seguimiento que especifican esa marca de seguimiento se escriben en el registro.

Paso 2: Elegir las funciones de mensaje de seguimiento que quiere usar y definir las macros de WPP para esas funciones

Al igual que una función de impresión de depuración, una función de mensaje de seguimiento es una función (o macro) que se agrega al código para escribir mensajes de seguimiento.

Elección de una función de mensaje de seguimiento

  1. La función de mensaje de seguimiento predeterminada es la macro DoTraceMessage . Si usa la función predeterminada, puede controlar cuándo generar mensajes mediante los valores de marca de seguimiento del proveedor. Los valores de Marcas de seguimiento son las marcas que definió al crear el GUID de control en el paso 1. Si usa DoTraceMessage, las macros de WPP predeterminadas ya están definidas (WPP_LEVEL_ENABLED y WPP_LEVEL_LOGGER), por lo que puede omitir el resto de este paso y ir al paso 5.

  2. Si usa una de las plantillas de KMDF o UMDF, la función TraceEvents y las macros de WPP necesarias ya están definidas para habilitar esa función, por lo que puede ir directamente al paso 5.

  3. Si va a crear su propia función de mensaje de seguimiento o convertir la función de impresión de depuración existente, continúe con el resto de este paso.

Creación o personalización de una función de mensaje de seguimiento

  1. Si usa funciones de mensaje de seguimiento personalizadas o desea convertir funciones de impresión de depuración (por ejemplo, KdPrint) para generar mensajes de seguimiento, debe definir macros de WPP que identifiquen y habiliten las funciones de mensaje de seguimiento en el proveedor de seguimiento. Coloque estas macros en el archivo de encabezado Trace.h que agregó al proyecto.

  2. Defina las macros de WPP para habilitar la función de seguimiento.

    Cada función de mensaje de seguimiento que use debe tener un par de macros correspondiente. Estas macros identifican el proveedor de seguimiento y especifican las condiciones que generan los mensajes. Normalmente, se define un par de macros, WPP_<condition>_LOGGER y WPP_<condition>_ENABLED en términos de las macros predeterminadas WPP_LEVEL_ENABLED y WPP_LEVEL_LOGGER.

Cada función de mensaje de seguimiento que use debe tener un par de macros correspondiente. Estas macros identifican el proveedor de seguimiento y especifican las condiciones que generan los mensajes. Normalmente, se define un par de macros, WPP_<condition>_LOGGER y WPP_<condition>_ENABLED en términos de las macros predeterminadas WPP_LEVEL_ENABLED y WPP_LEVEL_LOGGER.

Término Descripción

WPP_CONDITIONS_LOGGER

Se usa para buscar la sesión de seguimiento asociada al proveedor y devuelve un identificador a la sesión.

WPP_CONDITIONS_ENABLED

Se usa para determinar si el registro está habilitado con la condición especificada.

Para las macros de WPP que defina, las CONDICIONES representan las condiciones que admite la función de mensaje de seguimiento, en el orden en que aparecen en la lista de parámetros de la función, separadas por caracteres de subrayado. Por ejemplo, la función de mensaje de seguimiento predeterminada , DoTraceMessage, solo admite Trace Flag como condición, por lo que solo hay un parámetro en los nombres de macro (WPP_LEVEL_ENABLED).

Nota Desafortunadamente, los nombres de las macros predeterminadas (WPP_LEVEL_ENABLED y WPP_LEVEL_LOGGER) parecen indicar el parámetro Nivel de seguimiento , pero realmente hacen referencia a la marca de seguimiento.

Si usa una función de mensaje de seguimiento personalizada, puede establecer calificadores adicionales, como el nivel de seguimiento. El nivel de seguimiento se define en el archivo Evntrace.h y los niveles de seguimiento proporcionan una manera cómoda de clasificar los mensajes de seguimiento como mensajes de error, advertencia e informativos.

Por ejemplo, puede agregar el siguiente fragmento de código al archivo de encabezado que agregó al proyecto. El código siguiente define las macros de WPP personalizadas para una función de mensaje de seguimiento que admite los parámetros Nivel de seguimiento y Marca de seguimiento como condiciones para generar mensajes de seguimiento. La macro WPP_LEVEL_FLAGS_ENABLED devuelve TRUE si el registro está habilitado para el valor FLAGS especificado y el valor LEVEL habilitado es mayor o igual que el argumento level usado en la llamada a la función de mensaje de seguimiento.

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

A continuación, debe especificar las funciones de seguimiento personalizadas en el bloque de configuración de WPP (begin_wpp config y end_wpp). Por ejemplo, si usa la plantilla para proyectos de controlador UMDF o KMDF en Visual Studio, la plantilla define las macros de WPP para una función de mensaje de seguimiento personalizada denominada TraceEvents. La función de macro TraceEvents usa Trace Level y Trace Flag como condiciones para generar mensajes. Si ha definido la macro WPP_LEVEL_FLAGS_ENABLED en el archivo de encabezado Trace.h, puede agregar la siguiente definición 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
//

También puede convertir instrucciones de impresión de depuración existentes en instrucciones de seguimiento de mensajes mediante la adición de una declaración FUNC similar en el bloque de configuración de WPP. Por ejemplo, en el ejemplo siguiente se agrega el código para convertir las instrucciones KdPrint existentes. La declaración FUNC también define globalmente KdPrint para usar el nivel de seguimiento especificado y la marca {LEVEL=TRACE_LEVEL_INFORMATION, FLAGS=TRACE_DRIVER}. En lugar de enviar la salida al depurador, las instrucciones de impresión de depuración se envían al registro de seguimiento.

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

Nota Si desea convertir KdPrintEx en una función de mensaje de seguimiento, debe realizar algunos pasos adicionales. En comparación con KdPrint, la función KdPrintEx toma dos argumentos adicionales. Para convertir la función KdPrintEx, debe definir un WPP_DEFINE_BIT para ComponentID y definir WPP_condition<> personalizado_LOGGER y WPP_<condition>_ENABLED macros. El segundo parámetro de KdPrintEx especifica que el nivel de es similar a los valores de Nivel de seguimiento , por lo que no es necesario volver a definirlos necesariamente.


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

Paso 3: Incluir los archivos de encabezado de seguimiento asociados (.h y .tmh) en los archivos de origen de C o C++

Si ha definido el GUID de control y las marcas de seguimiento para el controlador en un archivo de encabezado (por ejemplo, trace.h), debe incluir el archivo de encabezado en los archivos de origen donde inicializará y descargará WPP (paso 4) o llamará a las funciones de mensaje de seguimiento.

Además, debe agregar una instrucción #include para el archivo de encabezado de mensaje de seguimiento (.tmh). Al compilar el controlador o la aplicación, el preprocesador de WPP genera los archivos de encabezado del mensaje de seguimiento (.tmh) para cada archivo de origen que contiene funciones de mensaje de seguimiento.

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

Paso 4: Agregar macros a las funciones de devolución de llamada adecuadas para inicializar y limpiar WPP

Para inicializar WPP en la entrada del controlador

  • Agregue la macro WPP_INIT_TRACING a la rutina DriverEntry de un controlador en modo kernel o un controlador UMDF 2.0, o a la rutina DLLMain de un controlador en modo de usuario (UMDF 1.x) o aplicación.

Para limpiar los recursos de WPP en la salida del controlador

  • Agregue la macro WPP_CLEANUP a la rutina de descarga del controlador (por ejemplo, DriverContextCleanup o DriverUnload) de un controlador en modo kernel o un controlador UMDF 2.0.

    Para un controlador en modo de usuario (UMDF 1.x) o aplicación, agregue la macro WPP_CLEANUP a la rutina DLLMain .

    También debe agregar la macro WPP_CLEANUP a la rutina DriverEntry en caso de que se produzca un error en DriverEntry . Por ejemplo, si se produce un error en DriverEntry , no se llamará a la rutina de descarga del controlador. Vea la llamada a WdfDriverCreate en el ejemplo siguiente.

Ejemplo de un controlador en modo kernel mediante WPP_INIT_TRACING y WPP_CLEANUP en 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;

}

Ejemplo de un controlador en modo kernel mediante WPP_CLEANUP en DriverContextCleanup



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

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

   // ...

}

Ejemplo del controlador UMDF 2.0 con WPP_INIT_TRACING en 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 );

Ejemplo de uso del controlador UMDF 1.0 de WPP_INIT_TRACING y macros de WPP_CLEANUP en 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);
}

Paso 5: Instrumentar el código del controlador para generar mensajes de seguimiento en los puntos adecuados

Puede usar cualquier función de mensaje de seguimiento que elija, siempre que la función de mensaje de seguimiento, las marcas de seguimiento y los niveles se definan correctamente. La función de mensaje de seguimiento predeterminada es la macro DoTraceMessage . Puede agregar esta macro al código para escribir mensajes en el archivo de registro. En la tabla siguiente se enumeran algunas de las funciones de mensaje de seguimiento predefinidas y las funciones de impresión de depuración que puede usar para crear mensajes de seguimiento.

Funciones de mensaje de seguimiento de ejemplo Cuándo se usa
DoTraceMessage

Esta es la función de mensaje de seguimiento predeterminada. La ventaja de usar DoTraceMessage es que la función ya está definida. Puede usar las marcas de seguimiento que especifique en la macro WPP_CONFIG_GUIDS. La desventaja de usar DoTraceMessage es que la función solo toma un parámetro condicional, es decir, marcas de seguimiento. Si desea usar niveles de seguimiento, para registrar solo mensajes de error o advertencia, puede usar la macro DoDebugTrace o usar TraceEvents, que usa marcas de seguimiento y niveles de seguimiento.

TraceEvents

Si crea un controlador mediante plantillas de WDF en Visual Studio, esta es la función de mensaje de seguimiento predeterminada. La ventaja de usar TraceEvents es que la función de mensaje de seguimiento, las marcas de seguimiento y el nivel de seguimiento ya están definidas. Además, las plantillas también incluyen instrumentación que escribe mensajes en el archivo de registro tras la entrada y salida de la función.

KdPrint, KdPrintEx, DbgPrint, DbgPrintEx

La ventaja de usar las funciones de impresión de depuración es que no es necesario modificar las instrucciones de impresión de depuración existentes. Puede cambiar fácilmente de ver mensajes en el depurador a grabar mensajes de seguimiento en un archivo. Si ha personalizado la función de mensaje de seguimiento para incluir una de las funciones de impresión de depuración, no es necesario realizar más trabajo. Al crear una sesión de seguimiento con Logman o Tracelog, u otro controlador de seguimiento, solo tiene que especificar las marcas y los niveles del proveedor. Las instrucciones de impresión de depuración que cumplan las condiciones especificadas se imprimen en el registro.

Uso de instrucciones DoTraceMessage

  1. Agregue la macro DoTraceMessage al código como lo haría con una rutina de impresión de depuración. La macro DoTraceMessage toma 3 parámetros: el nivel de marca (TraceFlagName), que define la condición cuando se escribe el mensaje de seguimiento, la cadena Message y la lista de variables opcionales.

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

    Por ejemplo, la siguiente instrucción DoTraceMessage escribe el nombre de la función que contiene la instrucción DoTraceMessage cuando la marca de TRACE_DRIVER, tal como se define en WPP_CONTROL_GUIDS, está habilitada para la sesión de seguimiento.

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

    En el ejemplo se usa una cadena predefinida para la de la función que se está ejecutando actualmente (%FUNC!). Para obtener más información sobre las cadenas de especificación de formato definidas por WPP, vea ¿Cuáles son las cadenas de especificación de formato extendido de WPP?

  2. Para generar el mensaje de seguimiento, cree una sesión de seguimiento para el proveedor de seguimiento, mediante Logman o Tracelog, y especifique una marca de seguimiento que establezca la marca 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);

Si usa las plantillas de controlador de Windows en Visual Studio, la macro TraceEvents se define para usted en el archivo de encabezado Trace.h.

Uso de instrucciones TraceEvents

  1. Agregue la macro TraceEvents al código como haría con una rutina de impresión de depuración. La macro TraceEvents toma los parámetros siguientes: el nivel de seguimiento (Nivel) y la marca de seguimiento (Marcas), que definen la condición cuando se escribe el mensaje de seguimiento, la cadena Message y la lista de variables opcionales.

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

    Por ejemplo, la siguiente instrucción TraceEvents escribe el nombre de la función que contiene la instrucción TraceEvents cuando se cumplen las condiciones especificadas en los parámetros Trace Level y Trace Flag. El nivel de seguimiento es un valor entero; se realizará un seguimiento de cualquier elemento en el nivel de seguimiento especificado para esa sesión de seguimiento. El TRACE_LEVEL_INFORMATION se define en Evntrace.h y tiene el valor 4. La marca de TRACE_DRIVER (bit 1, 0x2) se define en WPP_CONTROL_GUIDS. Si este bit de TRACE_DRIVER se establece para la sesión de seguimiento y el nivel de seguimiento es 4 o superior, TraceEvents escribe el mensaje de seguimiento.

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

    En el ejemplo se usa una cadena predefinida para la de la función que se está ejecutando actualmente (%FUNC!). Para obtener más información sobre las cadenas de especificación de formato definidas por WPP, vea ¿Cuáles son las cadenas de especificación de formato extendido de WPP?

  2. Para generar el mensaje de seguimiento, cree una sesión de seguimiento para el proveedor de seguimiento mediante Logman o Tracelog. Especifique un nivel de seguimiento para TRACE_LEVEL_INFORMATION (4) o superior y especifique un nivel de seguimiento que establezca el bit de 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__);

Paso 6: Modificar el proyecto de Visual Studio para ejecutar el preprocesador de WPP y compilar la solución

WDK proporciona compatibilidad con el preprocesador de WPP, de modo que pueda ejecutar el preprocesador mediante Visual Studio y el entorno de MSBuild.

Para ejecutar el preprocesador de WPP

  1. Seleccione y mantenga presionado (o haga clic con el botón derecho) en el proyecto de controlador en el Explorador de soluciones y seleccione Propiedades.
  2. En la página de propiedades del proyecto, seleccione Propiedades de configuración y seleccione Seguimiento de WPP.
  3. En General, establezca la opción Ejecutar WPP en .
  4. En Línea de comandos, agregue las opciones adicionales para personalizar el comportamiento de seguimiento. Para obtener información sobre lo que puede agregar, consulta Preprocesador de WPP.
  5. Compile el proyecto o la solución para la configuración y la plataforma de destino. Consulte Creación de un controlador con WDK.

Para obtener información sobre el proceso de compilación, vea Tarea TraceWPP y WDK y entorno de compilación de Visual Studio.

También puede ejecutar el preprocesador independiente del entorno de compilación mediante la herramienta TraceWPP (TraceWPP.exe). Esta herramienta se encuentra en el subdirectorio bin/x86 y bin/x64 del WDK.

Paso 7: Iniciar una sesión de seguimiento para capturar y comprobar los mensajes de seguimiento

Para comprobar que ha configurado correctamente el seguimiento de WPP, debe instalar el controlador o la aplicación en un equipo de prueba y, a continuación, crear una sesión de seguimiento para capturar los mensajes de seguimiento. Puede crear una sesión de seguimiento para el proveedor de seguimiento, mediante cualquier controlador de seguimiento, como Logman, Tracelog o TraceView. Puede escribir los mensajes en un archivo de registro o enviarlos a un depurador de kernel. En función de las funciones de mensaje de seguimiento que use, debe asegurarse de especificar las marcas de seguimiento y los niveles de seguimiento que generarán los mensajes.

Por ejemplo, si usa los niveles de seguimiento definidos en Evntrace.h y desea capturar TRACE_LEVEL_INFORMATION (4) o superior, debe establecer el nivel en 4. Al establecer el nivel en 4 para la sesión de seguimiento, también se capturarán todos los mensajes informativos (4), advertencia (3), error (2) y crítico (1), suponiendo que también se cumplen cualquier otra condición, como marcas de seguimiento.

Para comprobar que se generan todos los mensajes, es posible que solo establezca el nivel de seguimiento y las marcas de seguimiento en valores máximos para que se generen todos los mensajes. Las marcas de seguimiento usan una máscara de bits (ULONG), por lo que podría establecer todos los bits (por ejemplo, 0xFFFFFFFF). Los niveles de seguimiento se representan mediante un valor de byte. Por ejemplo, si usa Logman, puede especificar 0xFF para cubrir todos los niveles.

(Ejemplo) Inicio de una sesión de seguimiento mediante 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"

(Ejemplo) Inicio de una sesión de seguimiento mediante TraceLog

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

El comando Tracelog incluye el parámetro -f para especificar el nombre y la ubicación del archivo de registro de seguimiento de eventos. Incluye el parámetro -flag para especificar las marcas establecidas y el parámetro -level para especificar la configuración de nivel. Puede omitir estos parámetros, pero algunos proveedores de seguimiento no generan ningún mensaje de seguimiento a menos que establezca la marca o el nivel. El nivel de seguimiento se define en el archivo Evntrace.h y los niveles de seguimiento proporcionan una manera cómoda de clasificar los mensajes de seguimiento como mensajes críticos, de error, de advertencia e informativos.