EVENT_TRACE_HEADER

The EVENT_TRACE_HEADER is one of several types of fixed-size header that introduce variable-size data for events that are logged through Event Tracing for Windows (ETW). As with other types of event, those that begin with an EVENT_TRACE_HEADER accumulate first in trace buffers. To have these events persist in this raw form for ready inspection, configure the event tracing session to flush the trace buffers to an Event Trace Log (ETL) file.

Indeed, the EVENT_TRACE_HEADER, along with EVENT_INSTANCE_HEADER, is the oldest of all such Trace Headers. Presumably because of its survival from the simpler architecture of ETW in Windows 2000—indeed, when ETW was not yet named ETW but was arguably just a side-line to the then-new Windows Management Infrastructure (WMI)—the EVENT_TRACE_HEADER can be involved in event tracing all the way from provider to consumer.

If an event in the trace buffers begins with an EVENT_TRACE_HEADER, it typically originated with this header. The documented API function TraceEvent takes an EVENT_TRACE_HEADER as its input. The similarly old kernel export IoWMIWriteEvent is documented as taking a WNODE_HEADER as its input, but can handle an EVENT_TRACE_HEADER.

The EVENT_TRACE_HEADER also turns up when an event is retrieved from the ETW machinery, even if the event had a different header while in the trace buffers. The caller of the documented API function OpenTrace registers one or more routines to be called back during a call to the documented API function ProcessTrace. One of these callback routines describes events in an EVENT_TRACE structure which begins with an EVENT_TRACE_HEADER.

Documentation Status

The EVENT_TRACE_HEADER structure is documented.

That said, documentation that IoWMIWriteEvent accepts an EVENT_TRACE_HEADER has always been, shall we say, obscure. To this day, 10th December 2018, no hint of it shows on Microsoft’s page for IoWMIWriteEvent itself. Neither is it to be found by following links to WNODE_EVENT_ITEM or WNODE_HEADER to find what Microsoft says about the function’s arguments. To find that IoWMIWriteEvent can write an EVENT_TRACE_HEADER, your question (as Microsoft supports your thinking) should not be: what events can this function write? Instead, you must already know to start with the Windows Driver Kit (WDK) documentation of EVENT_TRACE_HEADER and ask: which function works with this data?

Layout

The EVENT_TRACE_HEADER is 0x30 bytes in both 32-bit and 64-bit Windows in all known versions that have it, i.e., 5.0 and higher.

Offset Definition Versions
0x00
USHORT Size;
5.0 and higher
0x02
UCHAR HeaderType;
UCHAR MarkerFlags;
5.0 only
union {
    USHORT FieldTypeFlags;
    struct {
        UCHAR HeaderType;
        UCHAR MarkerFlags;
    };
};
5.1 and higher
0x04
union {
    ULONG Version;
    struct {
        UCHAR Type;
        UCHAR Level;
        USHORT Version;
    } Class;
};
5.0 and higher
0x08
ULONGLONG ThreadId;
5.0 only
ULONG ThreadId;
5.1 and higher
0x0C
ULONG ProcessId;
5.1 and higher
0x10
LARGE_INTEGER TimeStamp;
5.0 and higher
0x18
union {
    GUID Guid;
    ULONGLONG GuidPtr;
};
5.0 and higher
0x28
union {
    struct {
        ULONG ClientContext;
        ULONG Flags;
    };
    struct {
        ULONG KernelTime;
        ULONG UserTime;
    };
    ULONG64 ProcessorTime;
};
5.0 to 5.2
union {
    struct {
        ULONG KernelTime;
        ULONG UserTime;
    };
    ULONG64 ProcessorTime;
    struct {
        ULONG ClientContext;
        ULONG Flags;
    };
};
6.0 and higher

The first 4 bytes have common elements in all the various Trace Headers. All have the high two bits set in the MarkerFlags. What distinguishes a header as continuing specifically as an EVENT_TRACE_HEADER is the HeaderType:

Value Name Implied Layout
0x0A TRACE_HEADER_TYPE_FULL_HEADER32 0x30 bytes of header followed by 32-bit event data
0x14 TRACE_HEADER_TYPE_FULL_HEADER64 0x30 bytes of header followed by 64-bit event data