我正在调用 Windows 的事件跟踪StartTrace
功能:
StartTrace(sessionHandle, KERNEL_LOGGER_NAME, sessionProperties);
它失败,错误代码为 87 ( ERROR_INVALID_PARAMETER
)。MSDN 给出了导致此错误的一些常见原因:
- 属性为NULL。
- 会话句柄是NULL。
- Properties的LogFileNameOffset成员无效。
- Properties的LoggerNameOffset成员无效。
- Properties的LogFileMode成员指定了无效的标志组合。
- Wnode.Guid成员是SystemTraceControlGuid,但SessionName参数不是KERNEL_LOGGER_NAME 。
我正在调用的代码是:
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;
我的电话的语言不可知版本:
ADVAPI32.StartTraceA(
TraceHandle: 0x18F56C
InstanceName: 0x44E840
Properties: 0x243BD8);
其中TraceHandle
指向一个 64 位整数:
0018F56C: 00 00 00 00 00 00 00 00
并且InstanceName
是一个指向以 null 结尾的 ansi 字符串的指针:
0044E840: 4E 54 20 4B 65 72 6E 65 NT Kerne
0044E848: 6C 20 4C 6F 67 67 65 72 l Logger
0044E850: 00
并且Properties
是指向EVENT_TRACE_PROPERTIES
结构的指针,我将避免复制完整的十六进制转储
002A3BD8: 0000009A (154 bytes)
重要的值是两个偏移量:
properties.LoggerNameOffset = 116 (i.e. $243BB8 + 116 = $243C4C)
properties.LogFileNameOffset = 133 (i.e. $243BD8 + 133 = $243C5D)
其中还包含有效的以 null 结尾的 ansi 字符串,它们应该:
“NT 内核记录器”:
$243C4C 4B20544E 656E7265 NT Kerne
$243C54 6F4C206C 72656767 l Logger
$243C5C xxxxxx00 .
“C:\Users\Ian\foo.etl”:
$243C5C 5C3A43xx 72657355 .C:\User
$243C64 61495C73 6F665C6E s\Ian\fo
$243C6C 74652E6F xxxx006C o.etc.
为什么我的参数不正确?
奖金阅读
更新:
会话参数:
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
分解为:
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|
如果有对齐问题,我将无法单独发现它。
结构:
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;
随着:
WNODE_HEADER = packed record
BufferSize : Longword;
ProviderId : Longword;
Version : Longword;
Linkage : Longword;
TimeStamp : Int64;
Guid : TGUID;
ClientContext : Longword;
Flags : Longword;
end;