Skip to main content

Add WPP tracing to the Kernel Mode (Windows driver)

Adding trace messages like errors, warning, and information in a software application is an important but time-consuming task. Also, adding custom trace handler in an application might hamper performance. So, there is some built-in tracing mechanism in windows which can be used by the software developer to add the tracing mechanism.

This mechanism is known as "WPP" (Windows Software Trace PreProcessor), and, it can be used directly in user-mode applications and even in kernel mode components (Drivers).

Some advantages of WPP tracing:
  •  Dynamic and flexible control
  • Ability view message in Real Time
  • Rich Information 
  • Easy migration from DbgPrint and KDPrint
  • Inclusion is shipped product
  • Minimal performance impact

In this article, we are going to implement WPP for a kernel mode component (driver). WPP uses the "Event Tracing for Windows" (ETW) API for logging event messages.

Support: Windows 2000 and onwards
Note: Settings which are mentioned in this article will be valid to VS2015 or VS2017, thought these settings can be worked with other VS with the little adjustment.

In this section we are going to look for WPP tracing:

  • The basics of architecture 
  • Create the control GUID and Defining the trace bit flags
  • Define/Use trace functions
  • Settings to be done in Driver project solution file (IN VS)
  • Testing of tracing on Windows 7

Architecture:

Trace Provider:

A trace provider is an application, operating system component, or driver that is instrumented for tracing.

Trace Controller:

A trace controller is an application or tool that manages a trace session.

Trace Buffer:

The system maintains a set of buffers to store the trace messages for each trace session.

Trace Session:

A trace session is a time period during which one or more trace provider have been enabled and generate  a series of trace messages that are written to a trace buffer.

Trace Consumer:

A trace consume is an application that receives, formats, and displays a session's trace log, either in real time or from a log file.

NOW, Create a header file name as "trace.h" in which we are going to add control GUID and supportive macro's to use custom trace function.


Create the control GUID and Defining the trace bit flags:

Each trace message provider must have a control GUID that trace controllers use to identify the driver as a trace message provider. Typically, each driver has a separate control GUID. However, a one-to-one relationship between control GUID and driver is not required because:
  • A driver can have multiple control GUIDs.
  • Multiple drivers can use the same control GUID.
Now create the new GUID using "Create GUID" tool from VS tool set (VS->Tools->Create GUID).
Newly generated can be used to define the macro "WPP_CONTROL_GUIDS" using the macro "WPP_DEFINE_CONTROL_GUID".

For single GUID we can define 32 bit flags. 

Syntax: (Following macro should be added in "trace.h")

Define/Use trace functions:

To trace the message we can use DDK provided "DoTraceMessage" API or we can define own API which can be used to trace out the message.
  • Use "DoTraceMessage" API: This the default WPP function which takes the three parameter, one is BIT flag, second is the message string, and third is the variable list.
    please refer: https://msdn.microsoft.com/library/windows/hardware/ff544918
  • Use Custom trace API: Some time we need to categories the defined BIT flags as in information, error, and warning, which can be achieved by the custom API which take four parameters.
    To support custom API we need to define some more macro in "trace.h": (following macro can directly copy paste in trace.h)

Adding trace messages in C file:

For demo purpose we will add the messages in DriverEntry and DriverUnload routine only.

To enable the tracing we need to call the "WPP_INIT_TRACING" by passing driver object and driver registry path in DriverEntry.
Syntax: 

And to stop the tracing, we will be calling "WPP_CLEANUP" in DriverUnload.
Syntax:


To add the trace message we will be using "MyTraceMessage" API, later we'll see how to enable this API to log our trace messages.
Syntax:
 
TRACE_LEVEL_ERROR is defined in DDK.

Now, we have to add the header file's in "C"  file,
Syntax:


TMH files: This files are auto generated by the WPP framework which contains the required code for trace messages. TMH file name should be the same as C file, for example if we are adding the trace message in "driver.c" then the we are supposed to include "driver.tmh".


VS project settings for WPP:

To enable WPP for the current project we need to required do some settings in project propertiesin VS.

I enabled “Run Wpp Tracing” in the Wpp Tracing, General set of Project Properties in Visual Studio.  “Yes” is the default setting (that you had to turn to “No” if you didn’t originally use WPP tracing in your driver).



Also define custom function in settings like



Now we are done, just compile your driver which will be WPP tracing enabled.

Testing of tracing on Windows:

The WDK includes a set of tools for software tracing. These tools are designed to support drivers that use ETW tracing and to supplement the tracing tools in Windows. The tools are located under WinDDK\BuildNumber\tools\tracing\, with separate sets of tools for each of the three supported CPU architectures.

The tools include the following:

Tracefmt

A command-line trace consumer that formats trace messages and writes them to files or displays them in the command window.

Tracelog

A command-line trace controller that supports user-mode and kernel-mode trace sessions.

Tracepdb

A command-line tool that creates TMF files from symbol files.

TraceView

A GUI-based trace controller and trace consumer that combines and extends the features of Tracepdb, Tracelog, and Tracefmt. This tool is designed for real-time displays of trace messages but can also be used to view trace log files.

TraceWPP

A command-line tool that runs the WPP preprocessor on a trace provider’s source files. This tool is an alternative to running the preprocessor as part of the regular build process.


To Start the trace session:

1.    Install  TraceView on your test computer.
2.    Run TraceView by double-clicking it in Windows Explorer or by using a command line.
       In Windows Vista and later versions, you must run TraceView with elevated privileges.
3.    On the File menu, click Create New Log Session, and then click Add Provider.
4.    In the Provider Control GUID Setup dialog box, select CTL (Control GUID) File, enter the path   to the sample’s CTL file, and then click OK.
5.    In the Format Information Source Select dialog box, select Select TMF Files, and then click OK.
6.    In the Trace Format Information Setup dialog box, click Add.
7.    In the File Open dialog box, enter the names of the TMF files that you created earlier.
8.    In the Trace Format Information Setup dialog box, click Done.
9.    In the Create New Log Session dialog box, click Next.
10.  On the Log Session Options page, select Log Trace Event Data To File, specify a name for the log file, and then click Finish to complete setting up the trace session.

Output will be look like:




Regards and Happy Coding,
Sourabh

Comments