2010-12-29 1 views
0

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

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

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

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

Спасибо.

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

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

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

Вытащив переменной части не тривиальная задача, но вот отличный пример, чтобы вы начали: Querying for Event Information

+0

Пожалуйста, внесите фактический код. 'vector (PEVENTLOGRECORD)' даже не будет компилироваться. –

+1

Всякий раз, когда я помещаю a, он исчезает. – Eric

+1

Я вижу, что вы использовали блок «» для его форматирования - вместо этого выберите блок кода программы и отступьте его, нажав Ctrl-K или нажав кнопку «фигурные скобки» над окном редактирования. –

ответ

2

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

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

allRecords.push_back(*currentRecord); 

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

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

+0

Вот и все. У меня было ощущение, что это проблема, но я не могу поверить, что не понимал, что «P» в «PEVENTLOGRECORD» стоял за указатель. Благодарю. – Eric

+0

@ Эрик: прочитайте мое обновление - есть серьезная проблема с использованием 'vector ' –

+0

Спасибо, что посмотрели на него глубже. Свойство «Длина» дает мне общий размер записи (заголовок + переменная), поэтому кажется, что мой код просто пропускает часть переменной и сохраняет только заголовок? Вы правы, что это проблема, и я уже придумал методы для обработки частей переменной длины. Я думаю, что возьму ваше первоначальное предложение и сделаю пользовательский класс (см. Выше). – Eric

Смежные вопросы