Geoff Chappell, Software Analyst
SKETCH OF HOW RESEARCH MIGHT CONTINUE AND RESULTS BE PRESENTED
The EVENT_TRACE_PROPERTIES structure describes a tracing session, also known as an event logger, for the ControlTrace, FlushTrace, QueryAllTraces, QueryTrace, StartTrace, StopTrace and UpdateTrace functions. These are all documented functions and the structure too is documented.
A tracing session is a set of buffers that receive events from possibly many event providers and a mechanism for asynchronously flushing the buffers somewhere, typically but not necessarily to an Event Trace Log (ETL) file. The selection of event providers and the control of which events to receive from them is managed through other functions. These functions and this structure are concerned more with the configuration of the buffers and the mechanism of delivering the buffered events. There are many options. Their description starts with the EVENT_TRACE_PROPERTIES structure.
The EVENT_TRACE_PROPERTIES structure is a fixed-size header whose members describe many of the session’s properties directly, but it is typically followed by variable-size properties. The most notable such extensions of the header are the names of the tracing session itself and of the log file, if any, that events are written to. Indeed, from Microsoft’s documentation and from headers in the Software Development Kit (SDK) these are all there would seem to be, even now in 2020, but there are others and have been for nearly two decades since Windows XP.
The structure can be both input and output for these functions. When starting a tracing session, most members of the structure are meaningful on input to specify what the started session should do. For all the functions, many members are meaningful on output to report what the session does. This is important and useful: that a session is successfully started or updated does not certainly mean that all the desired properties expressed on input were accepted.
The EVENT_TRACE_PROPERTIES structure is 0x78 in both 32-bit and 64-bit Windows, but not from being the same in both:
Offset (x86) | Offset (x64) | Definition | Versions |
---|---|---|---|
0x00 | 0x00 |
WNODE_HEADER Wnode; |
5.0 and higher |
0x30 | 0x30 |
ULONG BufferSize; |
5.0 and higher |
0x34 | 0x34 |
ULONG MinimumBuffers; |
5.0 and higher |
0x38 | 0x38 |
ULONG MaximumBuffers; |
5.0 and higher |
0x3C | 0x3C |
ULONG MaximumFileSize; |
5.0 and higher |
0x40 | 0x40 |
ULONG LogFileMode; |
5.0 and higher |
0x44 | 0x44 |
ULONG FlushTimer; |
5.0 and higher |
0x48 | 0x48 |
ULONG EnableFlags; |
5.0 and higher |
0x4C | 0x4C |
LONG AgeLimit; |
5.0 to 6.2 |
union { LONG AgeLimit; LONG FlushThreshold; }; |
6.3 and higher | ||
0x50 | 0x50 |
ULONG NumberOfBuffers; |
5.0 and higher |
0x54 | 0x54 |
ULONG FreeBuffers; |
5.0 and higher |
0x58 | 0x58 |
ULONG EventsLost; |
5.0 and higher |
0x5C | 0x5C |
ULONG BuffersWritten; |
5.0 and higher |
0x60 | 0x60 |
ULONG LogBuffersLost; |
5.0 and higher |
0x64 | 0x64 |
ULONG RealTimeBuffersLost; |
5.0 and higher |
0x68 | 0x68 |
HANDLE LoggerThreadId; |
5.0 and higher |
0x6C | 0x70 |
ULONG LogFileNameOffset; |
5.0 and higher |
0x70 | 0x74 |
ULONG LoggerNameOffset; |
5.0 and higher |
As noted above, the structure is intended as a fixed-size header for variable-size data. The BufferSize in the Wnode is the total size in bytes. This is required on input to all the applicable functions.
The WNODE_HEADER has many uses other than to start an EVENT_TRACE_PROPERTIES. Most of the Wnode is not meaningful for input to or output from the applicable functions, though some is used internally
The MaximumFileSize member is (roughly) the largest size to which the log file is permitted to grow, or is zero. The size is measured in MB typically, but in KB if EVENT_TRACE_USE_KBYTES_FOR_SIZE is set in the LogFileMode (see below). The StartTrace function requires a non-zero MaximumFileSize if any of the following bits are set in the LogFileMode:
The LogFileMode member is interpreted in bit flags. Many are invalid if combined with others:
Bit Flag | Symbolic Name | Conditions for StartTrace Function |
---|---|---|
0x00000001 | EVENT_TRACE_FILE_MODE_SEQUENTIAL | |
0x00000002 | EVENT_TRACE_FILE_MODE_CIRCULAR | requires non-zero MaximumFileSize; invalid with EVENT_TRACE_FILE_MODE_APPEND; invalid with EVENT_TRACE_FILE_MODE_NEWFILE; invalid with EVENT_TRACE_RELOG_MODE |
0x00000004 | EVENT_TRACE_FILE_MODE_APPEND | invalid with EVENT_TRACE_FILE_MODE_CIRCULAR;
invalid with EVENT_TRACE_REAL_TIME_MODE; invalid with EVENT_TRACE_RELOG_MODE |
0x00000008 | EVENT_TRACE_FILE_MODE_NEWFILE | requires non-zero MaximumFileSize and a log
file; invalid with EVENT_TRACE_FILE_MODE_CIRCULAR ; invalid with EVENT_TRACE_FILE_MODE_PREALLOCATE; invalid with EVENT_TRACE_PRIVATE_LOGGER_MODE; invalid with EVENT_TRACE_RELOG_MODE invalid for “NT Kernel Logger” session |
0x00000020 | EVENT_TRACE_FILE_MODE_PREALLOCATE | requires non-zero MaximumFileSize and a log
file; invalid with EVENT_TRACE_FILE_MODE_NEWFILE |
0x00000040 | EVENT_TRACE_NONSTOPPABLE_MODE | invalid |
0x00000080 | EVENT_TRACE_SECURE_MODE | |
0x00000100 | EVENT_TRACE_REAL_TIME_MODE | required unless EVENT_TRACE_BUFFER_MODE is
set or a log file is named; invalid with EVENT_TRACE_PRIVATE_LOGGER_MODE |
0x00000200 | EVENT_TRACE_DELAY_OPEN_FILE_MODE | |
0x00000400 | EVENT_TRACE_BUFFERING_MODE | required unless EVENT_TRACE_REAL_TIME_MODE is set or a log file is named |
0x00000800 | EVENT_TRACE_PRIVATE_LOGGER_MODE | |
0x00001000 | EVENT_TRACE_ADD_HEADER_MODE | |
0x00002000 | EVENT_TRACE_USE_KBYTES_FOR_SIZE | requires non-zero MaximumFileSize and a log file |
0x00004000 | EVENT_TRACE_USE_GLOBAL_SEQUENCE | |
0x00008000 | EVENT_TRACE_USE_LOCAL_SEQUENCE | |
0x00010000 | EVENT_TRACE_RELOG_MODE | requires EVENT_TRACE_PRIVATE_LOGGER_MODE;
invalid with EVENT_TRACE_FILE_MODE_CIRCULAR; invalid with EVENT_TRACE_FILE_MODE_APPEND; invalid with EVENT_TRACE_FILE_MODE_NEWFILE |
0x00020000 | EVENT_TRACE_PRIVATE_IN_PROC | invalid with EVENT_TRACE_PRIVATE_LOGGER_MODE |
0x00080000 | ||
0x00100000 | EVENT_TRACE_MODE_RESERVED | |
0x01000000 | use paged pool |
The EnableFlags member has the following defined values:
Bit Flag | Symbolic Name |
---|---|
0x00000001 | EVENT_TRACE_FLAG_PROCESS |
0x00000002 | EVENT_TRACE_FLAG_THREAD |
0x00000004 | EVENT_TRACE_FLAG_IMAGE_LOAD |
0x00000008 | EVENT_TRACE_FLAG_PROCESS_COUNTERS |
0x00000010 | EVENT_TRACE_FLAG_CSWITCH |
0x00000020 | EVENT_TRACE_FLAG_DPC |
0x00000040 | EVENT_TRACE_FLAG_INTERRUPT |
0x00000080 | EVENT_TRACE_FLAG_SYSTEMCALL |
0x00000100 | EVENT_TRACE_FLAG_DISK_IO |
0x00000200 | EVENT_TRACE_FLAG_DISK_FILE_IO |
0x00000400 | EVENT_TRACE_FLAG_DISK_IO_INIT |
0x00001000 | EVENT_TRACE_FLAG_MEMORY_PAGE_FAULTS |
0x00002000 | EVENT_TRACE_FLAG_MEMORY_HARD_FAULTS |
0x00010000 | EVENT_TRACE_FLAG_NETWORK_TCPIP |
0x00020000 | EVENT_TRACE_FLAG_REGISTRY |
0x00040000 | EVENT_TRACE_FLAG_DBGPRINT |
0x00100000 | EVENT_TRACE_FLAG_ALPC |
0x00200000 | EVENT_TRACE_FLAG_SPLIT_IO |
0x00800000 | EVENT_TRACE_FLAG_DRIVER |
0x01000000 | EVENT_TRACE_FLAG_PROFILE |
0x02000000 | EVENT_TRACE_FLAG_FILE_IO |
0x04000000 | EVENT_TRACE_FLAG_FILE_IO_INIT |
0x20000000 | EVENT_TRACE_FLAG_ENABLE_RESERVE |
0x40000000 | EVENT_TRACE_FLAG_FORWARD_WMI |
0x80000000 | EVENT_TRACE_FLAG_EXTENSION |
However, a set EVENT_TRACE_FLAG_EXTENSION bit indicates that the 4-byte EnableFlags member is instead interpreted as a structure:
Offset | Size | Description |
---|---|---|
0x00 | word | offset from start of buffer to flags extension structure |
0x02 | byte | |
0x03 | byte | bit flags: 0x80 necessarily set |
The LogFileNameOffset member is an offset in bytes from the start of the structure to the name of the log file as a null-terminated string, or is zero to denote that there is no name. This member is meaningful on input to the StartTrace function. Since the name is expected to lie in space after the structure but within the buffer, a valid non-zero LogFileNameOffset must be at least 0x78 and less than Wnode.BufferSize.
The LoggerNameOffset member is an offset in bytes from the start of the structure to the name of the logger as a null-terminated string, or is zero to denote that there is no name. This member is meaningful on input to the StartTrace function. Since the name is expected to lie in space after the structure but within the buffer, a valid non-zero LoggerNameOffset must be at least 0x78 and less than Wnode.BufferSize.