Windows ETW:StartTrace失败,错误87(ERROR_INVALID_PARAMETER) [英] Windows ETW: StartTrace failing with error 87 (ERROR_INVALID_PARAMETER)

查看:141
本文介绍了Windows ETW:StartTrace失败,错误87(ERROR_INVALID_PARAMETER)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在呼叫Windows事件跟踪 StartTrace 函数:

i'm calling the Event Tracing for Windows StartTrace function:

StartTrace(sessionHandle, KERNEL_LOGGER_NAME, sessionProperties);

它失败,错误代码为87( ERROR_INVALID_PARAMETER ).MSDN给出了此错误的一些常见原因:

It is failing with error code 87 (ERROR_INVALID_PARAMETER). The MSDN gives some common causes for this error:

  • 属性 NULL .
  • SessionHandle NULL .
  • 属性 LogFileNameOffset 成员无效.
  • 属性 LoggerNameOffset 成员无效.
  • 属性 LogFileMode 成员指定了无效的标志组合.
  • Wnode.Guid 成员是 SystemTraceControlGuid ,但是 SessionName 参数不是 KERNEL_LOGGER_NAME .
  • >
  • Properties is NULL.
  • SessionHandle is NULL.
  • The LogFileNameOffset member of Properties is not valid.
  • The LoggerNameOffset member of Properties is not valid.
  • The LogFileMode member of Properties specifies a combination of flags that is not valid.
  • The Wnode.Guid member is SystemTraceControlGuid, but the SessionName parameter is not 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;

与我通话的语言无关的版本:

The language agnostic version of my call:

ADVAPI32.StartTraceA(
     TraceHandle: 0x18F56C
     InstanceName: 0x44E840
     Properties: 0x243BD8);

其中 TraceHandle 指向一个64位整数:

where TraceHandle points to a a 64-bit integer:

0018F56C: 00 00 00 00  00 00 00 00

InstanceName 是指向以null结尾的ansi字符串的指针:

and InstanceName is a pointer to a null-terminated ansi string:

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 结构,我将避免复制完整的十六进制转储

and Properties is a pointer to an EVENT_TRACE_PROPERTIES structure, which i'll refrain from reproducing a complete hex dump

002A3BD8: 0000009A (154 bytes)

重要的值是两个偏移量:

The important values are the two offsets:

properties.LoggerNameOffset = 116  (i.e. $243BB8 + 116 = $243C4C)
properties.LogFileNameOffset = 133 (i.e. $243BD8 + 133 = $243C5D)

其中还包含应以其结尾的有效的以null终止的ansi字符串:

which also contain the valid null-terminated ansi strings they are supposed to:

"NT Kernel Logger":

"NT Kernel Logger":

$243C4C  4B20544E 656E7265  NT Kerne
$243C54  6F4C206C 72656767  l Logger
$243C5C  xxxxxx00           .

"C:\ Users \ Ian \ foo.etl":

"C:\Users\Ian\foo.etl":

$243C5C  5C3A43xx 72657355  .C:\User
$243C64  61495C73 6F665C6E  s\Ian\fo
$243C6C  74652E6F xxxx006C  o.etc.

为什么我的参数不正确?

Why are my parameters incorrect?

  • wtf wants to know how to register for realtime monitoring of kernel events
  • MSDN sample code (which this is a translation of) of how to connect to the kernel logging session

更新:

会话参数:

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|

如果存在对齐问题,我将无法独自发现它.

If there's an alignment problem i won't be able to discover it alone.

结构:

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;

推荐答案

哦,我明白了卢克评论中的评论在说什么.

Oh i see what the comments from Luke's comments are saying.

这并不是说结构未对齐.结构中的之后内容必须为 8字节对齐.换句话说:

It's not that the structure is misaligned is any way. The content after the structure must be 8-byte aligned. In other words:

000| Wnode.BufferSize:          9A 00 00 00 (154)
004| Wnode.ProviderID:          00 00 00 00
     ...snip...
108| LogFileNameOffset:   85 00 00 00 (133)
112| LoggerNameOffset:    74 00 00 00 (116)
116| 00 00 00 00 (4 bytes padding)
120| NT Kernel Logger\0
136| 00 00 00 00 00 00 00 (7 bytes padding)
144| C:\Users\Ian\foo.etl\0

看起来数据需要在Windows(7(专业(64位))(7(专业(64位)))的 8字节边界上对齐

Looks like data needs to be aligned on 8-byte boundries in Windows (7 (Professional (64-bit)))

为了帮助填充,我编写了 Pad 函数,该函数将数字四舍五入到最接近的8的倍数:

To help the padding, i wrote a Pad function, which rounds a number up to the nearest multiple of 8:

function Pad(length: Cardinal): Cardinal;
var
    m: Integer;
const
    DataAlignment = 8; //align data on 8-byte boundaries
begin
    Result := length;

    m := length mod DataAlignment;
    if (m > 0) then
        Result := result + DataAlignment-m;
end;

然后我更改了原始问题中的某些代码以使用它.

Then i changed some of the code from the original question to use it.

  • 计算所需的总 buffserSize :

loggerName := KERNEL_LOGGER_NAME;
logFilePath := 'C:\Users\Ian\foo.etl';

bufferSize := sizeof(EVENT_TRACE_PROPERTIES)
        + Pad(Length(loggerName)+1)
        + Pad(Length(logFilePath)+1);

  • 然后我需要将偏移量推入8字节边界:

  • then i need to push my offsets on an 8-byte boundary:

    sessionProperties.LoggerNameOffset := Pad(sizeof(EVENT_TRACE_PROPERTIES));
    sessionProperties.LogFileNameOffset := Pad(sizeof(EVENT_TRACE_PROPERTIES)) + Pad(Length(loggerName)+1);
    

  • ,只要我将字符串复制到结构中声明的偏移量中就可以了:

  • and as long as i copy the strings to the offsets declared in the structure i'm fine:

    //Copy LoggerName to the offset address
    MoveMemory(
          Pointer(Cardinal(sessionProperties)+sessionProperties.LoggerNameOffset),
          PAnsiChar(loggerName), Length(loggerName)+1);
    
    //Copy LogFilePath to the offset address
    MoveMemory(
          Pointer(Cardinal(sessionProperties)+sessionProperties.LogFileNameOffset),
          PAnsiChar(logFilePath), Length(logFilePath)+1);
    

  • 还有blingo-blango,都可以.

    And blingo-blango, it works.

    注意:任何代码都已发布到公共领域.无需注明出处.

    Note: Any code is released into the public domain. No attribution required.

    这篇关于Windows ETW:StartTrace失败,错误87(ERROR_INVALID_PARAMETER)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆