0

我正在制作一个程序,它从 C++ 中的 Windows EventLog 文件 (.evt) 读取和存储数据。我正在使用调用OpenBackupEventLog(ServerName, FileName)ReadEventLog(...)。也使用这个:PEVENTLOGRECORD

无论如何,在不提供所有代码的情况下,基本思想如下:
1. 我使用 OpenBackupEventLog() 获取 .evt 文件的句柄并传入文件名。
2. 然后我使用 ReadEventLog() 用未知数量的 EventLog 消息填充缓冲区。
3. 我遍历缓冲区并将每条消息添加到向量
4. 我不断填充缓冲区(重复步骤 2 和 3)直到到达文件末尾。

这是我填充向量的代码:

vector<EVENTLOGRECORD> allRecords;
while(_status == ERROR_SUCCESS)
{
   if(!ReadEventLog(...))
       CheckStatus();
   else
       FillVectorFromBuffer(allRecords)
}

// Function FillVectorFromBuffer
FillVectorFromBuffer(vector(EVENTLOGRECORD) &allRecords)
{
   int bytesExamined = 0;
   PBYTE pRecord = (PBYTE)_lpBuffer;    // This is one of the params in ReadEventLog()
   while(bytesExamined < _pnBytesRead)  // Another param from ReadEventLog
   {
      EVENTLOGRECORD currentRecord = (EVENTLOGRECORD)(pRecord);
      allRecords.push_back(currentRecord);
      pRecord += currentRecord->Length;
      bytesExamined += currentRecord->Length;
   }
}

无论如何,每当我运行它时,它都会获取文件中的所有事件日志,并且向量将拥有我想要的一切。但只要这一行:

如果(!ReadEventLog())

被调用并返回 true(又名 ReadEventLog() 返回 false),然后我的向量中的每个字段都设置为零。

该向量仍将包含正确数量的元素,只是 PEVENTLOGRECORD 结构中的所有字段现在都为零。

有更好调试经验的人有什么想法吗?

谢谢。

编辑:我已经按照 Michael Burr 的建议更新了代码。上面的代码现在消除了我原来遇到的问题。

编辑 2:解决 Michael Burr 的其他建议:由于 EVENTLOGRECORD 的可变部分,我将制作一个自定义结构,其中包含 EVENTLOGRECORD 以及我感兴趣的一些其他变量:

struct CustomRecord
{
   EVENTLOGRECORD recordHeader;
   string sourceName;
   string computerName;
   string message;
};

提取可变部分并非易事,但这里有一个很好的示例可以帮助您入门: Querying for Event Information

4

1 回答 1

2

我猜你的向量(我认为应该读作vector<PEVENTLOGRECORD>,而不是vector(PEVENTLOGRECORD))包含指向数据的指针,而不是数据的副本。我认为,当ReadEventLog()指示没有更多数据时,拥有实际数据的任何人都会释放它。

一种可能的解决方法是您应该将数据本身存储在向量中而不是指针中。使向量 avector<EVENTLOGRECORD>并将 PEVENTLOGRECORD 指针的取消引用内容存储到向量中(应该创建一个副本)而不是指针本身:

allRecords.push_back(*currentRecord);

更新:在 MSDN 中仔细观察,这EVENTLOGRECORD是编译器只知道“标题”部分的那些讨厌的可变长度结构之一。可变长度数据遵循该标头,但严格来说,就编译器而言,它不是结构的一部分。所以 avector<EVENTLOGRECORD>不会捕获数据的可变部分。您需要提供一个可以用 a 初始化的自定义类,PEVENTLOGRECORD并且知道如何正确处理变量数据,或者您需要将结构及其变量数据复制到适当大小的动态分配数组中字节并存储指向该分配块的指针(但在向量完成之前不要释放块 - 智能指针可以在这里提供帮助)。

提出可以智能地处理事件日志记录数据的类可能需要一些前期工作,但我猜从长远来看,如果您对记录进行任何重要的工作,这些工作会有所回报。您可能会在网上找到一个可以用作或用作您自己的起点的类(例如,快速搜索从http://www.naughter.com/serv.html找到 CEventLogRecord )。

于 2010-12-29T06:44:36.773 回答