Почему мой вектор <PEVENTLOGRECORD>загадочно очищается? - PullRequest
0 голосов
/ 29 декабря 2010

Я делаю программу, которая читает и сохраняет данные из файлов Windows EventLog (.evt) в C ++. Я использую вызовы OpenBackupEventLog (ServerName, FileName) и ReadEventLog (...) . Также используя это: PEVENTLOGRECORD

В любом случае, без предоставления всего кода, вот основная идея:
1. Я получаю дескриптор к файлу .evt, используя OpenBackupEventLog () и передавая имя файла.
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;
   }
}

В любом случае, всякий раз, когда я запускаю это, он получает все EventLogs в файле, и вектор будет иметь все, что я хочу. Но как только эта строка:

if(!ReadEventLog())

вызывается и возвращает истину (aka ReadEventLog () возвращает ложь), тогда каждое поле в моем векторе устанавливается в ноль.

Вектор по-прежнему будет содержать правильное количество элементов, просто все поля в структуре PEVENTLOGRECORD теперь равны нулю.

Кто-нибудь с лучшим опытом отладки имеет какие-либо идеи?

Спасибо.

Редактировать: я обновил код в соответствии с предложением Майкла Берра. Приведенный выше код теперь устраняет исходную проблему, с которой я столкнулся.

Редактировать 2: Обращаясь к другому предложению Майкла Берра: Из-за переменной части EVENTLOGRECORD я сделаю собственную структуру, которая имеет EVENTLOGRECORD плюс несколько других переменных, которые меня интересуют:

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

Извлечение переменных частей не является тривиальной задачей, но вот отличный пример для начала: Запрос информации о событии

1 Ответ

2 голосов
/ 29 декабря 2010

Я предполагаю, что ваш вектор (который, я думаю, должен читаться как vector<PEVENTLOGRECORD>, а не vector(PEVENTLOGRECORD)) содержит указатели на данные, а не копии данных. Я думаю, что тот, кто владеет фактическими данными, выпускает его, когда ReadEventLog() указывает на то, что данных больше нет.

Одним из возможных исправлений является то, что вы должны хранить сами данные в векторе, а не в указателях. Сделайте вектор vector<EVENTLOGRECORD> и сохраните разыменованное содержимое указателя PEVENTLOGRECORD в векторе (который должен создать копию) вместо самого указателя:

allRecords.push_back(*currentRecord);

Обновление: при ближайшем рассмотрении в MSDN EVENTLOGRECORD - это одна из тех неприятных структур переменной длины, где компилятор знает только о части заголовка. Данные переменной длины следуют за этим заголовком, но, строго говоря, не являются частью структуры с точки зрения компилятора. Так что vector<EVENTLOGRECORD> не будет захватывать переменную часть данных. Вам нужно будет создать собственный класс, который можно инициализировать с помощью PEVENTLOGRECORD, и он знает, как правильно обращаться с переменными данными, или вам нужно будет скопировать структуру и ее переменные данные в динамический файл правильного размера. -распределенный массив байтов и сохраните указатель на этот выделенный блок (но не освобождайте блок, пока с ним не закончится вектор - здесь может помочь умный указатель).

Придумать класс, который может разумно работать с данными записи журнала событий, может быть немного трудом заранее, но я думаю, что работа окупится в долгосрочной перспективе, если вы выполняете какую-либо значительную работу с записи. Вы можете найти класс в сети, который можно использовать или использовать в качестве отправной точки для своего собственного (например, быстрый поиск нашел CEventLogRecord из http://www.naughter.com/serv.html,).

...