I call event tracking for Windows StartTrace :
StartTrace(sessionHandle, KERNEL_LOGGER_NAME, sessionProperties);
Error with error code 87 ( ERROR_INVALID_PARAMETER ). MSDN gives some common reasons for this error:
- NULL Properties.
- SessionHandle NULL .
- Invalid LogFileNameOffset element is invalid.
- Invalid LoggerNameOffset element is invalid.
- The LogFileMode element of a property indicates a combination of flags that is not valid.
- The Wnode.Guid element is SystemTraceControlGuid , but the SessionName parameter is not KERNEL_LOGGER_NAME .
The code I call:
procedure StartKernelLogging; var sessionProperties: PEVENT_TRACE_PROPERTIES; bufferSize: Int64; loggerName: AnsiString; logFilePath: AnsiString; th: TRACEHANDLE; hr: Cardinal; begin { Allocate memory for the session properties. The memory must be large enough to include the log file name and session name, which get appended to the end of the session properties structure. } loggerName := KERNEL_LOGGER_NAME; logFilePath := 'C:\Users\Ian\foo.etl'; bufferSize := sizeof(EVENT_TRACE_PROPERTIES) + Length(loggerName)+1 + Length(logFilePath)+1; sessionProperties := AllocMem(bufferSize); ZeroMemory(sessionProperties, bufferSize); sessionProperties.Wnode.BufferSize := bufferSize; sessionProperties.Wnode.Flags := WNODE_FLAG_TRACED_GUID; sessionProperties.Wnode.ClientContext := 1; //QPC clock resolution sessionProperties.Wnode.Guid := SystemTraceControlGuid; sessionProperties.EnableFlags := EVENT_TRACE_FLAG_NETWORK_TCPIP; sessionProperties.LogFileMode := EVENT_TRACE_FILE_MODE_CIRCULAR; sessionProperties.MaximumFileSize := 5; // 5 MB sessionProperties.LoggerNameOffset := sizeof(EVENT_TRACE_PROPERTIES); sessionProperties.LogFileNameOffset := sizeof(EVENT_TRACE_PROPERTIES) + Length(loggerName)+1; //Copy LoggerName to the offset address MoveMemory(Pointer(Cardinal(sessionProperties)+Cardinal(sessionProperties.LoggerNameOffset)), PAnsiChar(loggerName), Length(loggerName)+1); //Copy LogFilePath to the offset address MoveMemory(Pointer(Cardinal(sessionProperties)+Cardinal(sessionProperties.LogFileNameOffset)), PAnsiChar(logFilePath), Length(logFilePath)+1); th := 0; hr := EventTrace.StartTrace({var}th, PChar(loggerName), sessionProperties); if (hr <> ERROR_SUCCESS) then begin raise EWin32Error.Create(SysErrorMessage(hr)); end; end;
The language of the agnostic version of my call:
ADVAPI32.StartTraceA( TraceHandle: 0x18F56C InstanceName: 0x44E840 Properties: 0x243BD8);
where TraceHandle points to a 64-bit integer:
0018F56C: 00 00 00 00 00 00 00 00
and InstanceName is a pointer to ansi string with a terminating zero:
0044E840: 4E 54 20 4B 65 72 6E 65 NT Kerne 0044E848: 6C 20 4C 6F 67 67 65 72 l Logger 0044E850: 00
and Properties is a pointer to the EVENT_TRACE_PROPERTIES structure, which I will refrain from playing the full hex dump
002A3BD8: 0000009A (154 bytes)
The important values โโare two offsets:
properties.LoggerNameOffset = 116 (ie $243BB8 + 116 = $243C4C) properties.LogFileNameOffset = 133 (ie $243BD8 + 133 = $243C5D)
which also contain valid ansi strings ending with zero, which they must:
"NT Logger":
$243C4C 4B20544E 656E7265 NT Kerne $243C54 6F4C206C 72656767 l Logger $243C5C xxxxxx00 .
"C: \ Users \ Jan \ foo.etl":
$243C5C 5C3A43xx 72657355 .C:\User $243C64 61495C73 6F665C6E s\Ian\fo $243C6C 74652E6F xxxx006C o.etc.
Why are my options incorrect?
Reading bonuses
Update:
Session Options:
9A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 AD 4A 81 9E 04 32 D2 11 9A 82 00 60 08 A8 69 39 01 00 00 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 05 00 00 00 02 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 85 00 00 00 74 00 00 00
What breaks:
000| Wnode.BufferSize: 9A 00 00 00 (154) 004| Wnode.ProviderID: 00 00 00 00 008| Wnode.Version: 00 00 00 00 012| Wnode.Linkage: 00 00 00 00 016| Wnode.Timestamp: 00 00 00 00 00 00 00 00 024| Wnode.Guid: AD 4A 81 9E 04 32 D2 11 9A 82 00 60 08 A8 69 39 (SystemTraceControlGuid) 040| Wnode.ClientContext: 01 00 00 00 (1) 044| Wnode.Flags: 00 00 02 00 (WNODE_FLAG_TRACED_GUID) 048| BufferSize: 00 00 00 00 052| MinimumBuffers: 00 00 00 00 056| MaximumBuffers: 00 00 00 00 060| MaximumFileSize: 05 00 00 00 (5 MB) 064| LogFileMode: 02 00 00 00 (EVENT_TRACE_FILE_MODE_CIRCULAR) 068| FlushTimer: 00 00 00 00 072| EnableFlags: 00 00 01 00 (EVENT_TRACE_FLAG_NETWORK_TCPIP) 076| AgeLimit: 00 00 00 00 080| NumberOfBuffers: 00 00 00 00 084| FreeBuffers: 00 00 00 00 088| EventsLost: 00 00 00 00 092| BuffersWritten: 00 00 00 00 096| LogBuffersLost: 00 00 00 00 100| RealTimeBuffersLost: 00 00 00 00 104| LoggerThreadId: 00 00 00 00 108| LogFileNameOffset: 85 00 00 00 (133) 112| LoggerNameOffset: 74 00 00 00 (116) 116| NT Kernel Logger\0 133| C:\Users\Ian\foo.etl\0 154|
If the alignment problem, I can not detect it myself.
Structure:
EVENT_TRACE_PROPERTIES = packed record Wnode : WNODE_HEADER; // data provided by caller BufferSize : Longword; // buffer size for logging (kbytes) MinimumBuffers : Longword; // minimum to preallocate MaximumBuffers : Longword; // maximum buffers allowed MaximumFileSize : Longword; // maximum logfile size (in MBytes) LogFileMode : Longword; // sequential, circular FlushTimer : Longword; // buffer flush timer, in seconds EnableFlags :Longword; // trace enable flags AgeLimit : Longint; // age decay time, in minutes // data returned to caller NumberOfBuffers : Longword; // no of buffers in use FreeBuffers : Longword; // no of buffers free EventsLost : Longword; // event records lost BuffersWritten : Longword; // no of buffers written to file LogBuffersLost : Longword; // no of logfile write failures RealTimeBuffersLost : Longword; // no of rt delivery failures LoggerThreadId : HANDLE; // thread id of Logger LogFileNameOffset : Longword; // Offset to LogFileName LoggerNameOffset : Longword; // Offset to LoggerName end;
together with:
WNODE_HEADER = packed record BufferSize : Longword; ProviderId : Longword; Version : Longword; Linkage : Longword; TimeStamp : Int64; Guid : TGUID; ClientContext : Longword; Flags : Longword; end;