WMI_LOGGER_CONTEXT

The WMI_LOGGER_CONTEXT structure is the kernel’s representation of an event logger, known more formally as an event tracing session. An instance is created when the logger is started and is retained until the logger is stopped. Except for the auto-loggers, which the kernel itself starts, all ways to start a logger go through NtTraceControl with the function code EtwStartLoggerCode (0x01). For well-behaved user-mode programs, this means through the documented StartTrace function.

The kernel keeps the addresses of the created WMI_LOGGER_CONTEXT instances in an array of pointers in the kernel’s own data section. This array’s capacity of 64 is therefore the maximum number of event tracing sessions that can be active at any given time. This limit has long been documented, though curiously not in the documentation of StartTrace.

Documentation Status

The WMI_LOGGER_CONTEXT structure is not documented.

The limit of 64 to the number of WMI_LOGGER_CONTEXT structures that can exist at any one time is formalised by the definition of a macro MAXLOGGERS in the NTWMI.H header in the Windows Driver Kit (WDK) for Windows 10.

Layout

Since the WMI_LOGGER_CONTEXT is very much for the kernel’s own use, it should not surprise that the layout changes significantly between versions and even between builds. The following sizes are known:

Version Size (x86) Size (x64)
early 6.0 (before Windows Vista SP1) 0x0270 0x0350
late 6.0 (Windows Vista SP1 and higher) 0x0280 0x0370
6.1 0x0238 0x0330
6.2 0x0270 0x0378
6.3 0x0278 0x0378
10.0 0x0288 0x0398

The preceding sizes, and the offsets, types and names in the table below are from Microsoft’s symbol files for the kernel starting with Windows 7. Symbol files from earlier versions have type information for the structure, but the difference in layout is great enough that I put the early history aside, at least for now.

Offset (x86) Offset (x64) Definition Versions
0x00 0x00
ULONG LoggerId;
6.1 and higher
0x04 0x04
ULONG BufferSize;
6.1 and higher
0x08 0x08
ULONG MaximumEventSize;
6.1 and higher
0x0C (6.1) 0x0C (6.1)
LONG CollectionOn;
6.1 only
0x10 (6.1);
0x0C
0x10 (6.1);
0x0C
ULONG LoggerMode;
6.1 and higher
0x14 (6.1);
0x10
0x14 (6.1);
0x10
LONG AcceptNewEvents;
6.1 and higher
0x14 0x14
ULONG EventMarker [1];
6.2 and higher (x86)
ULONG EventMarker [2];
6.2 and higher (x64)
0x18 0x1C
ULONG ErrorMarker;
6.2 and higher
0x1C 0x20
ULONG SizeMask;
6.2 and higher
0x18 (6.1);
0x20
0x18 (6.1);
0x28
LONGLONG (*GetCpuClock) (VOID);
6.1 and higher
0x20 (6.1) 0x20 (6.1)
LARGE_INTEGER StartTime;
6.1 only
0x28 (6.1) 0x28 (6.1)
HANDLE LogFileHandle;
6.1 only
0x2C (6.1);
0x24
0x30
ETHREAD *LoggerThread;
6.1 and higher
0x30 (6.1);
0x28
0x38
NTSTATUS LoggerStatus;
6.1 and higher
0x2C 0x3C
ULONG FailureReason;
6.2 and higher
0x34 (6.1);
0x30
0x40
PVOID NBQHead;
6.1 only
ETW_BUFFER_QUEUE BufferQueue;
6.2 and higher
0x38 (6.1);
0x3C
0x48 (6.1);
0x58
PVOID OverflowNBQHead;
6.1 only
ETW_BUFFER_QUEUE OverflowQueue;
6.2 and higher
0x40 (6.1) 0x50 (6.1)
SLIST_HEADER QueueBlockFreeList;
6.1 only
0x48 0x60 (6.1);
0x70
LIST_ENTRY GlobalList;
6.1 and higher
0x50 0x80
LIST_ENTRY ProviderBinaryList;
6.2 and higher
0x50 (6.1);
0x58
0x70 (6.1);
0x90
union {
    WMI_BUFFER_HEADER *BatchedBufferList;
    EX_FAST_REF CurrentBuffer;
};
6.1 and higher
0x54 (6.1);
0x5C
0x78 (6.1);
0x98
UNICODE_STRING LoggerName;
6.1 and higher
0x5C (6.1);
0x64
0x88 (6.1);
0xA8
UNICODE_STRING LogFileName;
6.1 and higher
0x64 (6.1);
0x6C
0x98 (6.1);
0xB8
UNICODE_STRING LogFilePattern;
6.1 and higher
0x6C (6.1);
0x74
0xA8 (6.1);
0xC8
UNICODE_STRING NewLogFileName;
6.1 and higher
0x74 (6.1);
0x7C
0xB8 (6.1);
0xD8
ULONG ClockType;
6.1 and higher
0x78 (6.1) 0xBC (6.1)
ULONG MaximumFileSize;
6.1 only
0x7C (6.1);
0x80
0xC0 (6.1);
0xDC
ULONG LastFlushedBuffer;
6.1 and higher
0x80 (6.1);
0x84
0xC4 (6.1);
0xE0
ULONG FlushTimer;
6.1 and higher
0x84 (6.1);
0x88
0xC8 (6.1);
0xE4
ULONG FlushThreshold;
6.1 and higher
0x88 (6.1);
0x90
0xD0 (6.1);
0xE8
LARGE_INTEGER ByteOffset;
6.1 and higher
0x90 (6.1);
0x98
0xD8 (6.1);
0xF0
ULONG MinimumBuffers;
6.1 and higher
0x94 (6.1);
0x9C
0xDC (6.1);
0xF4
LONG volatile BuffersAvailable;
6.1 and higher
0x98 (6.1);
0xA0
0xE0 (6.1);
0xF8
LONG volatile NumberOfBuffers;
6.1 and higher
0x9C (6.1);
0xA4
0xE4 (6.1);
0xFC
ULONG MaximumBuffers;
6.1 and higher
0xA0 (6.1);
0xA8
0xE8 (6.1);
0x0100
ULONG volatile EventsLost;
6.1 and higher
0xAC 0x0104
LONG volatile PeakBuffersCount;
6.3 and higher
0xA4 (6.1);
0xAC (6.2);
0xB0
0xEC (6.1);
0x0104 (6.2);
0x0108
ULONG BuffersWritten;
6.1 and higher
0xA8 (6.1);
0xB0 (6.2);
0xB4
0xF0 (6.1);
0x0108 (6.2);
0x010C
ULONG LogBuffersLost;
6.1 and higher
0xAC (6.1);
0xB4 (6.2);
0xB8
0xF4 (6.1);
0x010C (6.2);
0x0110
ULONG RealTimeBuffersDelivered;
6.1 and higher
0xB0 (6.1);
0xB8 (6.2);
0xBC
0xF8 (6.1);
0x0110 (6.2);
0x0114
ULONG RealTimeBuffersLost;
6.1 and higher
0xB4 (6.1);
0xBC (6.2);
0xC0
0x0100 (6.1);
0x0118
LONG *SequencePtr;
6.1 and higher
0xB8 (6.1);
0xC0 (6.2);
0xC4
0x0108 (6.1);
0x0120
ULONG LocalSequence;
6.1 and higher
0xBC (6.1);
0xC4 (6.2);
0xC8
0x010C (6.1);
0x0124
GUID InstanceGuid;
6.1 and higher
0xD4 (6.2);
0xD8
0x0134
ULONG MaximumFileSize;
6.2 and higher
0xCC (6.1);
0xD8 (6.2);
0xDC
0x011C (6.1);
0x0138
LONG FileCounter;
6.1 and higher
0xD0 (6.1) 0x0120 (6.1)
VOID 
(* volatile BufferCallback) (
    WMI_BUFFER_HEADER *, 
    PVOID);
6.1 only
0xD4 (6.1);
0xDC (6.2);
0xE0
0x0128 (6.1);
0x013C
POOL_TYPE PoolType;
6.1 and higher
0xD8 (6.1);
0xE0 (6.2);
0xE8
0x0130 (6.1);
0x0140
ETW_REF_CLOCK ReferenceTime;
6.1 and higher
0xF0 (6.2);
0xF8
0x0150
LONG CollectionOn;
6.2 and higher
0xF4 (6.2);
0xFC
0x0154
ULONG ProviderInfoSize;
6.2 and higher
0xE8 (6.1);
0xF8 (6.2);
0x0100
0x0140 (6.1);
0x0158
LIST_ENTRY Consumers;
6.1 and higher
0xF0 (6.1);
0x0100 (6.2);
0x0108
0x0150 (6.1);
0x0168
ULONG NumConsumers;
6.1 and higher
0xF4 (6.1);
0x0104 (6.2);
0x010C
0x0158 (6.1);
0x0170
ETW_REALTIME_CONSUMER *TransitionConsumer;
6.1 and higher
0xF8 (6.1);
0x0108 (6.2);
0x0110
0x0160 (6.1);
0x0178
HANDLE RealtimeLogfileHandle;
6.1 and higher
0xFC (6.1);
0x010C (6.2);
0x0114
0x0168 (6.1);
0x0180
UNICODE_STRING RealtimeLogfileName;
6.1 and higher
0x0108 (6.1);
0x0118 (6.2);
0x0120
0x0178 (6.1);
0x0190
LARGE_INTEGER RealtimeWriteOffset;
6.1 and higher
0x0110 (6.1);
0x0120 (6.2);
0x0128
0x0180 (6.1);
0x0198
LARGE_INTEGER RealtimeReadOffset;
6.1 and higher
0x0118 (6.1);
0x0128 (6.2);
0x0130
0x0188 (6.1);
0x01A0
LARGE_INTEGER RealtimeLogfileSize;
6.1 and higher
0x0120 (6.1);
0x0130 (6.2);
0x0138
0x0190 (6.1);
0x01A8
ULONGLONG RealtimeLogfileUsage;
6.1 and higher
0x0128 (6.1);
0x0138 (6.2);
0x0140
0x0198 (6.1);
0x01B0
ULONGLONG RealtimeMaximumFileSize;
6.1 and higher
0x0130 (6.1);
0x0140 (6.2);
0x0148
0x01A0 (6.1);
0x01B8
ULONG RealtimeBuffersSaved;
6.1 and higher
0x0138 (6.1);
0x0148 (6.2);
0x0150
0x01A8 (6.1);
0x01C0
ETW_REF_CLOCK RealtimeReferenceTime;
6.1 and higher
0x0148 (6.1);
0x0158 (6.2);
0x0160
0x01B8 (6.1);
0x01D0
ETW_RT_EVENT_LOSS NewRTEventsLost;
6.1 and higher
0x014C (6.1);
0x015C (6.2);
0x0164
0x01C0 (6.1);
0x01D8
KEVENT LoggerEvent;
6.1 and higher
0x015C (6.1);
0x016C (6.2);
0x0174
0x01D8 (6.1);
0x01F0
KEVENT FlushEvent;
6.1 and higher
0x0170 (6.1);
0x0180 (6.2);
0x0188
0x01F0 (6.1);
0x0208
KTIMER FlushTimeOutTimer;
6.1 and higher
0x0198 (6.1);
0x01A8 (6.2);
0x01B0
0x0230 (6.1);
0x0248
KDPC FlushDpc;
6.1 only
KDPC LoggerDpc;
6.2 and higher
0x01B8 (6.1);
0x01C8 (6.2);
0x01D0
0x0270 (6.1);
0x0288
KMUTANT LoggerMutex;
6.1 and higher
0x01D8 (6.1);
0x01E8 (6.2);
0x01F0
0x02A8 (6.1);
0x02C0
EX_PUSH_LOCK LoggerLock;
6.1 and higher
0x01DC (6.1);
0x01EC (6.2);
0x01F4
0x02B0 (6.1);
0x02C8
union {
    KSPIN_LOCK BufferListSpinLock;
    EX_PUSH_LOCK BufferListPushLock;
};
6.1 and higher
0x01E0 (6.1);
0x01F0 (6.2);
0x01F8
0x02B8 (6.1);
0x02D0
SECURITY_CLIENT_CONTEXT ClientSecurityContext;
6.1 and higher
0x0234 0x0318
TOKEN_ACCESS_INFORMATION *TokenAccessInformation;
10.0 and higher
0x021C (6.1);
0x022C (6.2);
0x0234 (6.3);
0x0238
0x0300 (6.1);
0x0318 (6.2 to 6.3);
0x0320
EX_FAST_REF SecurityDescriptor;
6.1 and higher
0x0230 (6.2);
0x0238 (6.3);
0x0240
0x0320 (6.2 to 6.3);
0x0328
LARGE_INTEGER StartTime;
6.2 and higher
0x0238 (6.2);
0x0240 (6.3);
0x0248
0x0328 (6.2 to 6.3);
0x0330
HANDLE LogFileHandle;
6.2 and higher
0x0220 (6.1);
0x0240 (6.2);
0x0248 (6.3);
0x0250
0x0308 (6.1);
0x0330 (6.2 to 6.3);
0x0338
LONGLONG BufferSequenceNumber;
6.1 and higher
0x0228 (6.1);
0x0248 (6.2);
0x0250 (6.3);
0x0258
0x0310 (6.1);
0x0338 (6.2 to 6.3);
0x0340
union {
    ULONG Flags;
    struct {
        /*  bit fields, see below  */
    };
};
6.1 and higher
0x022C (6.1);
0x024C (6.2);
0x0254 (6.3);
0x025C
0x0314 (6.1);
0x033C (6.2 to 6.3);
0x0344
union {
    ULONG volatile RequestFlag;
    struct {
        /*  bit fields, see below  */
    };
};
6.1 and higher
0x0230 (6.1);
0x0250 (6.2);
0x0258 (6.3);
0x0260
0x0318 (6.1);
0x0340 (6.2 to 6.3);
0x0348
RTL_BITMAP HookIdMap;
6.1 and higher
0x0258 (6.2);
0x0260 (6.3);
0x0268
0x0350 (6.2 to 6.3);
0x0358
ETW_STACK_CACHE *StackCache;
6.2 and higher
0x025C (6.2);
0x0264 (6.3);
0x026C
0x0358 (6.2 to 6.3);
0x0360
ETW_PMC_SUPPORT *PmcData;
6.2 and higher
0x0260 (6.2);
0x0268 (6.3);
0x0270
0x0360 (6.2 to 6.3);
0x0368
LIST_ENTRY WinRtProviderBinaryList;
6.2 and higher
0x0268 (6.2);
0x0270 (6.3);
0x0278
0x0370 (6.2 to 6.3);
0x0378
WMI_BUFFER_HEADER **ScratchArray;
6.2 and higher
0x027C 0x0380
DISALLOWED_GUIDS DisallowedGuids;
10.0 and higher
0x0284 0x0390
ESILO *ServerSilo;
10.0 and higher

Logger Mode

It is perhaps as well to collect here the various bits that represent the wide variety of possible logger modes, as kept in the LoggerMode member. Some are documented, and are defined as macros in EVNTRACE.H. Some are known only from the NTWMI.H header:

Value Name
0x00000001 EVENT_TRACE_FILE_MODE_SEQUENTIAL
0x00000002 EVENT_TRACE_FILE_MODE_CIRCULAR
0x00000004 EVENT_TRACE_FILE_MODE_APPEND
0x00000008 EVENT_TRACE_FILE_MODE_NEWFILE
0x00000010 EVENT_TRACE_USE_MS_FLUSH_TIMER
0x00000020 EVENT_TRACE_FILE_MODE_PREALLOCATE
0x00000040 EVENT_TRACE_NONSTOPPABLE_MODE
0x00000080 EVENT_TRACE_SECURE_MODE
0x00000100 EVENT_TRACE_REAL_TIME_MODE
0x00000200 EVENT_TRACE_DELAY_OPEN_FILE_MODE
0x00000400 EVENT_TRACE_BUFFERING_MODE
0x00000800 EVENT_TRACE_PRIVATE_LOGGER_MODE
0x00001000 EVENT_TRACE_ADD_HEADER_MODE
0x00002000 EVENT_TRACE_USE_KBYTES_FOR_SIZE
0x00004000 EVENT_TRACE_USE_GLOBAL_SEQUENCE
0x00008000 EVENT_TRACE_USE_LOCAL_SEQUENCE
0x00010000 EVENT_TRACE_RELOG_MODE
0x00020000 EVENT_TRACE_PRIVATE_IN_PROC
0x00040000 EVENT_TRACE_BUFFER_INTERFACE_MODE
0x00080000 EVENT_TRACE_KD_FILTER_MODE
0x00100000 EVENT_TRACE_REAL_TIME_RELOG_MODE
0x00200000 EVENT_TRACE_LOST_EVENTS_DEBUG_MODE
0x00400000 EVENT_TRACE_STOP_ON_HYBRID_SHUTDOWN
0x00800000 EVENT_TRACE_PERSIST_ON_HYBRID_SHUTDOWN
0x01000000 EVENT_TRACE_USE_PAGED_MEMORY
0x02000000 EVENT_TRACE_SYSTEM_LOGGER_MODE
0x04000000 EVENT_TRACE_COMPRESSED_MODE
0x08000000 EVENT_TRACE_INDEPENDENT_SESSION_MODE
0x10000000 EVENT_TRACE_NO_PER_PROCESSOR_BUFFERING
0x20000000 EVENT_TRACE_BLOCKING_MODE
0x40000000 apparently unused
0x80000000 EVENT_TRACE_ADDTO_TRIAGE_DUMP

Very many combinations of these bits are invalid. Some bits are not known to the kernel but are instead vital to the separate NTDLL implementation that lets user-mode processes do their own event tracing.

Clock Type

The defined values for the ClockType each correspond to a different GetCpuClock routine for getting timestamps. Microsoft’s names are known from the NTWMI.H header:

Value Name Time
0 EVENT_TRACE_CLOCK_RAW  
1 EVENT_TRACE_CLOCK_PERFCOUNTER tick count from the KeQueryPerformanceCounter function
2 EVENT_TRACE_CLOCK_SYSTEMTIME 100ns units since 1601, as from the KeQuerySystemTimePrecise function 
3 EVENT_TRACE_CLOCK_CPUCYCLE CPU cycle count from the rdtsc instruction
4 EVENT_TRACE_CLOCK_MAX  

Flags

Bit fields in union with the Flags member grew for Windows 8 and further for Windows 10:

Mask Definition Versions
0x00000001
ULONG Persistent : 1;
6.1 and higher
0x00000002
ULONG AutoLogger : 1;
6.1 and higher
0x00000004
ULONG FsReady : 1;
6.1 and higher
0x00000008
ULONG RealTime : 1;
6.1 and higher
0x00000010
ULONG Wow : 1;
6.1 and higher
0x00000020
ULONG KernelTrace : 1;
6.1 and higher
0x00000040
ULONG NoMoreEnable : 1;
6.1 and higher
0x00000080
ULONG StackTracing : 1;
6.1 and higher
0x00000100
ULONG ErrorLogged : 1;
6.1 and higher
0x00000200
ULONG RealtimeLoggerContextFreed : 1;
6.1 and higher
0x00000400
ULONG PebsTracing : 1;
6.2 and higher
0x00000800
ULONG PmcCounters : 1;
6.2 and higher
0x00001000
ULONG PageAlignBuffers : 1;
6.2 and higher
0x00002000
ULONG StackLookasideListAllocated : 1;
10.0 and higher
0x00004000
ULONG SecurityTrace : 1;
10.0 and higher
 
ULONG SpareFlags1 : 3;
6.2 to 6.3
ULONG SpareFlags1 : 1;
10.0 and higher
0x00FF0000
ULONG SystemLoggerIndex : 8;
6.2 and higher
0x01000000
ULONG StackCaching : 1;
6.2 and higher
 
ULONG SpareFlags2 : 7;
6.2 and higher

RequestFlag

The separate bit fields in union with the RequestFlag member have been much more stable than they look. Though Windows 8 did add some, most of the change is just renaming. The changes for Windows 10 are just spelling corrections.

Mask Definition Versions
0x00000001
ULONG RequestNewFie : 1;
6.1 only
ULONG DbgRequestNewFie : 1;
6.2 to 6.3
ULONG DbgRequestNewFile : 1;
10.0 and higher
0x00000002
ULONG RequestUpdateFile : 1;
6.1 only
ULONG DbgRequestUpdateFile : 1;
6.2 and higher
0x00000004
ULONG RequestFlush : 1;
6.1 only
ULONG DbgRequestFlush : 1;
6.2 and higher
0x00000008
ULONG RequestDisableRealtime : 1;
6.1 only
ULONG DbgRequestDisableRealtime : 1;
6.2 and higher
0x00000010
ULONG RequestDisconnectConsumer : 1;
6.1 only
ULONG DbgRequestDisconnectConsumer : 1;
6.2 and higher
0x00000020
ULONG RequestConnectConsumer : 1;
6.1 only
ULONG DbgRequestConnectConsumer : 1;
6.2 and higher
0x00000040
ULONG DbgRequestNotifyConsumer : 1;
6.2 and higher
0x00000080
ULONG DbgRequestUpdateHeader : 1;
6.2 and higher
0x00000100
ULONG DbgRequestDefferdFlush : 1;
6.2 to 6.3
ULONG DbgRequestDeferredFlush : 1;
10.0 and higher
0x00000200
ULONG DbgRequestDefferdFlushTimer : 1;
6.2 to 6.3
ULONG DbgRequestDeferredFlushTimer : 1;
10.0 and higher
0x00000400
ULONG DbgRequestFlushTimer : 1;
6.2 and higher
0x00000800
ULONG DbgRequestUpdateDebugger : 1;
6.2 and higher
 
ULONG DbgSpareRequestFlags : 20;
6.2 and higher