WMI Event Tracing
This section describes the WMI extensions to WDM (supported by Windows 2000 and later) that kernel-mode drivers, as information providers, can use to provide information to information consumers. Drivers typically provide information that a consumer uses to determine the driver's configuration and resource usage. In addition to the WMI extensions to WDM, a user-mode API supports providers or consumers of WMI event information—see the Windows SDK for more information.
The event tracing logger supports up to 32 instances. One of the instances is reserved for tracing the kernel. The logger supports tracing a high event rate.
Trace events are defined in the same manner as other WMI events. WMI events are described in the MOF file. For more information about WMI event descriptions, see MOF Syntax for WMI Data and Event Blocks.
The process by which kernel-mode drivers log information is integrated into the existing WMI infrastructure. To log trace events, a driver does the following:
Register as a WMI provider by calling IoWMIRegistrationControl.
Mark events as traceable by setting WMIREG_FLAG_TRACED_GUID in the Flags member of the WMIREGGUID structure that is passed when the driver registers events with WMI.
Specify one event as the control event for overall enabling/disabling of a set of trace events by setting WMIREG_FLAG_TRACE_CONTROL_GUID in the Flags member of the WMIREGGUID structure that is passed when the driver registers events with WMI.
Upon receiving a request from WMI to enable events where the GUID matches the trace control GUID, the driver should store the handle to the logger. The value will be needed when writing an event. For information about how to use this handle, see step 6. The logger handle value is contained in the HistoricalContext member of the WNODE_HEADER portion of the WMI buffer that is part of the parameters in the enable events request.
Decide whether the trace event will be sent to WMI event consumers or is targeted for the WMI event logger only. This will determine where the memory for the EVENT_TRACE_HEADER structure should come from. This memory will eventually be passed to IoWMIWriteEvent.
If the event is a log event only, the memory will not be deleted by WMI. In this case, the driver should pass in a buffer on the stack or should be reusing an allocated buffer for this purpose. For performance reasons, the driver should minimize any unnecessary calls to allocate or free memory. Failure to comply with this recommendation will compromise the integrity of the timing information contained in the log file.
If the event is to be sent to both the logger and to WMI event consumers, then the memory must be allocated from a nonpaged pool. In this case the event will be sent to the logger and then forwarded to WMI to be sent to WMI event consumers who have requested notification of the event. The memory for the event will then be freed by WMI according to the behavior of IoWMIWriteEvent.
After the memory for the EVENT_TRACE_HEADER and any driver event data, if any, has been secured, the following information should be set:
Set the Size member to the sizeof(EVENT_TRACE_HEADER) plus the size of any additional driver event data that will be appended on to the end of EVENT_TRACE_HEADER.
Set the Flags member to WNODE_FLAG_TRACED_GUID to have the event sent to the logger. If the event is to be sent to WMI event consumers as well, set the WNODE_FLAG_LOG_WNODE. Note, it is not necessary to set WNODE_FLAG_TRACED_GUID if setting WNODE_FLAG_LOG_WNODE. If both are set, WNODE_FLAG_TRACED_GUID will take precedence and the event will not be sent to WMI event consumers.
Set the Guid or the GuidPtr member. If using GuidPtr, set WNODE_FLAG_USE_GUID_PTR in the Flags member.
Optionally, specify a value for TimeStamp. If the driver does not specify a TimeStamp value the logger will fill this in. If the driver does not want the logger to set the time stamp then it should set WNODE_FLAG_USE_TIMESTAMP in the Flags member.
Set any of the following EVENT_TRACE_HEADER members that have meaning to the driver: Class.Type, Class.Level, and Class.Version.
Finally cast the EVENT_TRACE_HEADER to a WNODE_HEADER and set the HistoricalContext value of the Wnode to the logger handle that was saved in step 4 above.
Call IoWMIWriteEvent with the pointer to the EVENT_TRACE_HEADER structure.
The driver should continue logging trace events associated with the control GUID until the driver receives notification to disable event logging via an IRP_MN_DISABLE_EVENTS request.