CURRENT WORK ITEM - PREVIEW ONLY

EVENT_HEADER

The EVENT_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_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.

Among the various trace headers, the EVENT_HEADER is unusual in that it is not just a transitory implementation detail for how one type of event gets packed into the trace buffers or even for how NTDLL passes events to the kernel. It is also the header, within an EVENT_RECORD, when event data is unpacked for event consumers—even of event data that had a different header while in the trace buffers. This article is concerned only with the packed form.

Documentation Status

Presumably because of its role in interfaces that support event consumers, the EVENT_HEADER structure is defined in the EVNTCONS.H header for user-mode programming and is documented.

Note, however, that the EVENT_HEADER is documented merely as “defines information about the event” as if the structure exists solely for delivering the event to an event consumer. One might easily miss that the structure has a very much longer role in the life of many events all the way back to their preparation in a trace buffer by the kernel.

Layout

The EVENT_HEADER is 0x50 bytes in both 32-bit and 64-bit Windows in all known versions.

Offset Definition
0x00
USHORT Size;
0x02
USHORT HeaderType;
0x04
USHORT Flags;
0x06
USHORT EventProperty;
0x08
ULONG ThreadId;
0x0C
ULONG ProcessId;
0x10
LARGE_INTEGER TimeStamp;
0x18
GUID ProviderId;
0x28
EVENT_DESCRIPTOR EventDescriptor;
0x38
union {
    struct {
        ULONG KernelTime;
        ULONG UserTime;
    };
    ULONG64 ProcessorTime;
};
0x40
GUID ActivityId;

The Size is the total, in bytes, of the EVENT_HEADER and all the event data that follows. To understand the fixed-size header, it helps to know that the variable-size data that follows it is broadly in two parts:

Many other Trace Headers also begin with a 16-bit Size. What distinguishes the EVENT_HEADER from those and also from the ones that don’t begin with the Size are special values in the bytes at offset 0x02 and 0x03. For the EVENT_HEADER, but for no other types of trace header, Microsoft models these bytes together as a 16-bit HeaderType. The NTETW.H from some editions of the Windows Driver Kit (WDK) for Windows 10 defines the following:

Value Name Implied Layout
0xC012 EVENT_HEADER_EVENT32 0x50 bytes of header followed by 32-bit event data
0xC013 EVENT_HEADER_EVENT64 0x50 bytes of header followed by 64-bit event data

Microsoft defines the following Flags:

Value Name
0x0001 EVENT_HEADER_FLAG_EXTENDED_INFO
0x0002 EVENT_HEADER_FLAG_PRIVATE_SESSION
0x0004 EVENT_HEADER_FLAG_STRING_ONLY
0x0008 EVENT_HEADER_FLAG_TRACE_MESSAGE
0x0010 EVENT_HEADER_FLAG_NO_CPUTIME
0x0020 EVENT_HEADER_FLAG_32_BIT_HEADER
0x0040 EVENT_HEADER_FLAG_64_BIT_HEADER
0x0080 apparently unused
0x0100 EVENT_HEADER_FLAG_CLASSIC_HEADER
0x0200 EVENT_HEADER_FLAG_PROCESSOR_INDEX

Note, however, that most cannot be set in an EVENT_HEADER that is in the trace buffers. Microsoft defines them because they are set for the structure that is presented to event consumers. Some of the Flags exist precisely to tell the event consumer that the event originated differently. For instance, an event that gets EVENT_HEADER_FLAG_TRACE_MESSAGE set in its presentation to an event consumer actually started its life with a MESSAGE_TRACE_HEADER.

Microsoft defines the following for EventProperty:

Name Value
0x0001 EVENT_HEADER_PROPERTY_XML
0x0002 EVENT_HEADER_PROPERTY_FORWARDED_XML
0x0004 EVENT_HEADER_PROPERTY_LEGACY_EVENTLOG
0x0008 EVENT_HEADER_PROPERTY_RELOGGABLE

Most of the other members are generated at logging-time. The ProviderGuid and ActivityId are saved from function arguments.

Extended Data Items

The kernel sets EVENT_HEADER_FLAG_EXTENDED_INFO in the Flags to indicate that the EVENT_HEADER is followed by at least one extended data item. Each such item appears, after 8-byte alignment, as a fixed-size header and variable-size data. The header is an EVENT_HEADER_EXTENDED_DATA_ITEM, not quite as defined in EVNTCONS.H:

Offset Definition
0x00
USHORT Reserved1;
0x02
USHORT ExtType;
0x04
struct {
    USHORT Linkage : 1;
    USHORT Reserved2 : 15;
};
0x06
USHORT DataSize;
0x08
ULONGLONG DataPtr;

The key difference is that DataPtr is not space for a 32-bit or 64-bit pointer to wherever the unpacking has placed the variable-size data. Instead, it holds that data, or at least the beginning of that data. The Reserved1 member is the total size, i.e., of the first 8 bytes of the EVENT_HEADER_EXTENDED_DATA_ITEM plus the DataSize bytes of variable-size data. The form of that data depends on the ExtType. Microsoft’s EVNTCONS.H defines the following values and names:

Value Name DataPtr Replacement 
0x0001 EVENT_HEADER_EXT_TYPE_RELATED_ACTIVITYID EVENT_EXTENDED_ITEM_RELATED_ACTIVITYID
0x0002 EVENT_HEADER_EXT_TYPE_SID SID
0x0003 EVENT_HEADER_EXT_TYPE_TS_ID EVENT_EXTENDED_ITEM_TS_ID
0x0004 EVENT_HEADER_EXT_TYPE_INSTANCE_INFO EVENT_EXTENDED_ITEM_INSTANCE
0x0005 EVENT_HEADER_EXT_TYPE_STACK_TRACE32 EVENT_EXTENDED_ITEM_STACK_TRACE32
0x0006 EVENT_HEADER_EXT_TYPE_STACK_TRACE64 EVENT_EXTENDED_ITEM_STACK_TRACE64
0x0007 EVENT_HEADER_EXT_TYPE_PEBS_INDEX  
0x0008 EVENT_HEADER_EXT_TYPE_PMC_COUNTERS  
0x0009 EVENT_HEADER_EXT_TYPE_PSM_KEY  
0x000A EVENT_HEADER_EXT_TYPE_EVENT_KEY EVENT_EXTENDED_ITEM_EVENT_KEY
0x000B EVENT_HEADER_EXT_TYPE_EVENT_SCHEMA_TL  
0x000C EVENT_HEADER_EXT_TYPE_PROV_TRAITS byte array 
0x000D EVENT_HEADER_EXT_TYPE_PROCESS_START_KEY EVENT_EXTENDED_ITEM_PROCESS_START_KEY
0x000E EVENT_HEADER_EXT_TYPE_MAX  

TO BE CONTINUED