1

系统事件日志中包含以下详细信息的事件:

Source: Kernel-General
Event ID: 1
Details: The system time has changed to ‎2010‎-‎07‎-‎17T02:58:20.285000000Z from ‎2010‎-‎07‎-‎17T02:58:20.285868600Z.

EVENTLOGRECORD 的 EventID 字段也有一个 1,因此它与我们在事件日志查看器中看到的相匹配。

到目前为止,一切都很好。

问题是,当您查看 advapi32.dll 时,这是该源从中获取消息的地方,您会看到:

ID:01000001
String: The system time has changed to %1 from %2.

事件日志查看器如何神奇地知道将这些额外的位添加到 ID 以找到正确的字符串?并非所有事件字符串都具有该高位,有些还设置了其他高位。

使用 1 调用 FormatMessage 失败。用 x01000001 调用它成功。但这不是事件日志记录包含的内容...... :(

我找不到任何文档来讨论这个问题(除了描述显示错误/严重性/设施/代码位的 ID 格式之外)。

4

2 回答 2

1

像你一样,我在任何地方都找不到它,但看起来事件查看器将结构的EventType成员映射到消息表标识符的严重性位。EVENTLOGRECORD

例如,服务控制管理器事件 7035 属于“信息”类型,它映射到严重性值 1,产生消息 ID 0x40001B7B,这确实是事件查看器从 netevent.dll 显示的文本:%1 服务成功发送了 %2 控件。

同样,事件 7000 的类型为“错误”,映射到严重性3,消息 ID 为 0xC0001B58:由于以下错误,%1 服务无法启动:%n%2

当然,这与您的示例不太相符;你确定你的 0 和 1 在正确的位置吗?

于 2010-08-12T23:00:17.147 回答
1

假设在 Windows XP 和更早版本中,事件 ID 直接映射到消息表中的消息 ID。对于 Vista 及更高版本,有两种方法可以将事件 ID 映射到消息 ID。

  1. 事件限定符(这可能是像 Brian 最初提到的那样被掩盖的严重性)
  2. Windows 事件模板资源

本文更详细地描述了这两种方式: https ://github.com/libyal/libevtx/blob/master/documentation/Windows%20XML%20Event%20Log%20(EVTX).asciidoc#message-string-identifier

特别是对于此“系统时间已更改...”事件,Windows 10 正在使用 Windows 事件模板资源。如果您在注册表中查找该事件的 EventMessageFile 键(基于事件源 = Microsoft-Windows-Kernel-General),您会找到提供程序 DLL。

计算机\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog\System\Microsoft-Windows-Kernel-General

然后,您可以使用 windows 事件实用程序查看提供程序 dll 的内容(添加 /gm:true 标志将显示消息文本):

wevtutil gp Microsoft-Windows-Kernel-General /ge:true

输出显示带有事件任务 5 的事件 ID 1 的消息 ID = 16777217 (0x01000001)。

于 2018-04-17T14:35:54.297 回答