Модераторы: feodorv, GremlinProg, xvr, Fixin
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> проблемка с ReadEventLog, ReadEventLog читает не все записи ( 
V
    Опции темы
heavix
Дата 5.12.2011, 14:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 60
Регистрация: 10.8.2007

Репутация: нет
Всего: нет



Приветствую Всех)
Уважаемые форумчане, кто-нибудь использовал функцию ReadEventLog? 
Возникла задача читать записи из системного лога... Почитал МСДН... нашел апишки: OpenEventLog и ReadEventLog
набросал тестовый примерчик, и застрял... Собственно проблемка: читаю в цикле все записи с System ивент лога,
замечательно читается, только вот не весь лог! Впихнул счетчик... читает около 500 записей, потом коректно завершается и все... 
нигде по ошибке не вылетает! Виндовый Event Viewer говорит что у мну записей в даном логе больше 2000! Может кто сталкивался, 
есть там какие-нить особенности работы с данной функцией, или еще где торможу! Заранее благодарен всем откликнувшимся!

делаю так:

Код

#define MAX_TIMESTAMP_LEN       23 + 1   // mm/dd/yyyy hh:mm:ss.mmm
#define MAX_RECORD_BUFFER_SIZE  0x10000  // 64K

SYSTEMTIME GetTimestamp(const DWORD Time);
void processEventRecord(PBYTE pBuff,DWORD num);

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
  wcout<<L"open System log..."<<endl;

  HANDLE hEventLog(NULL);
  DWORD  dwBytesToRead(0);
  DWORD  dwBytesRead(0);
  DWORD  dwBytesNeed(0);
  DWORD  dwStatus(ERROR_SUCCESS);

  if(NULL == (hEventLog = OpenEventLog(NULL,L"Application")))
  {
    wcout<<L"# Error to open System log"<<endl;
    return 0;
  }

  wcout<<L"System log opened succesfull"<<endl;
  wcout<<L"Reading was started..."<<endl;
   /*
    Reading 
  */

  // allocating reading buffer
  boost::scoped_array<BYTE>pBuffer(new BYTE[1]);
  dwBytesToRead = 1;

  // Read blocks of records until you reach the end of the log or an 
  // error occurs. The records are read from newest to oldest. If the buffer
  // is not big enough to hold a complete event record, reallocate the buffer.

  while (ERROR_SUCCESS == dwStatus)
  {
    if(NULL == pBuffer.get())
    {
      wcout<<L"Error allocation "<<endl;
      break;
    }
    DWORD res = ReadEventLog(hEventLog, 
      EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ,
      0, 
      reinterpret_cast<PBYTE>(pBuffer.get()),
      dwBytesToRead,
      &dwBytesRead,
      &dwBytesNeed);
    if (!res)
    {
      dwStatus = GetLastError();
      if (ERROR_INSUFFICIENT_BUFFER == dwStatus)
      {
        dwStatus = ERROR_SUCCESS;
        if(dwBytesNeed >= MAX_RECORD_BUFFER_SIZE)
        {
          wcout<<L"Error reading..."<<endl;
          break;
        }
        // allocate buffer
        pBuffer.reset(new BYTE[dwBytesNeed]);
        dwBytesToRead = dwBytesNeed;
      }
      else 
      {
        if (ERROR_HANDLE_EOF != dwStatus)
        {
          wcout<<L"Error reading..."<<endl;
          break;
        }
      }
    }
    else
    {
      processEventRecord(reinterpret_cast<PBYTE>(pBuffer.get()),dwBytesRead);
    }
  }
  
  wcout<<L"Closing System log..."<<endl;
  CloseEventLog(hEventLog);
  wcout<<L"System log closed"<<endl;
  _getch();
    return 0;
}

// Get a string that contains the time stamp of when the event 
// was generated.
SYSTEMTIME GetTimestamp(const DWORD Time)
{
  ULONGLONG ullTimeStamp = 0;
  ULONGLONG SecsTo1970 = 116444736000000000;
  SYSTEMTIME st;
  FILETIME ft, ftLocal;

  ullTimeStamp = Int32x32To64(Time, 10000000) + SecsTo1970;
  ft.dwHighDateTime = (DWORD)((ullTimeStamp >> 32) & 0xFFFFFFFF);
  ft.dwLowDateTime = (DWORD)(ullTimeStamp & 0xFFFFFFFF);

  FileTimeToLocalFileTime(&ft, &ftLocal);
  FileTimeToSystemTime(&ftLocal, &st);
  return st;
}

void processEventRecord(PBYTE pBuff,DWORD num)
{
  if((NULL == pBuff)||(num < sizeof(EVENTLOGRECORD)))
    return;
  PEVENTLOGRECORD pRecord = reinterpret_cast<PEVENTLOGRECORD>(pBuff);
  // get Event ID
  DWORD EV_ID = pRecord->EventID & 0xFFFF;
  //if(EV_ID == 100)
  {
    static int i = 1;
    // get time stamp
    SYSTEMTIME st = GetTimestamp(pRecord->TimeGenerated);
    // write it
    CString str;
    str.Format(L"%u   ---   %d//%d//%d %d:%d:%d.%d   --- %u"
              ,i
              ,st.wMonth
              ,st.wDay
              ,st.wYear
              ,st.wHour
              ,st.wMinute
              ,st.wSecond
              ,st.wMilliseconds
              ,EV_ID);// mm/dd/yyyy hh:mm:ss.mmm
    ++i;
    wcout << str.GetString()<<endl;
  }
}


  
PM MAIL   Вверх
Andrey44
Дата 5.12.2011, 14:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1501
Регистрация: 4.12.2006
Где: На работе

Репутация: 8
Всего: 26



Код

#include <stdafx.h>
#include <windows.h>
#include <iostream>

#define BUFFER_SIZE 512

void __cdecl wmain(int argc, LPWSTR *argv)
{
    // Name of the event log.
    wchar_t *logName = L"Application";
    // Event Source name.
    wchar_t *sourceName = L"MsiInstaller";
    // This is the event ID that you are querying for.
    DWORD dwMessageID = 1014;  
    // DLL that contains the event messages (descriptions).
    wchar_t *dllName = L"C:\\WINDOWS\\SYSTEM32\\msi.dll"; 
    
   
    HANDLE h, ghResDll;
    char lpMsgBuf1[BUFFER_SIZE];
    EVENTLOGRECORD *pevlr;
    BYTE bBuffer[BUFFER_SIZE];
    DWORD dwRead, dwNeeded, dwThisRecord;
    LPCTSTR lpSourceName;

    // Step 1: ---------------------------------------------------------
    // Open the event log. ---------------------------------------------
    h = OpenEventLog( NULL,               // Use the local computer.
        logName);
    if (h == NULL)
    {
        std::wcout << L"Could not open the event log." << std::endl;;
        return;
    }
    
    // Step 2: ---------------------------------------------------------
    // Initialize the event record buffer. -----------------------------
    pevlr = (EVENTLOGRECORD *) &bBuffer;

    // Step 3: ---------------------------------------------------------
    // Load the message DLL file. --------------------------------------
    ghResDll =  LoadLibrary(dllName);

    // Step 4: ---------------------------------------------------------
    // Get the record number of the oldest event log record. -----------
    GetOldestEventLogRecord(h, &dwThisRecord);

    // Step 5: ---------------------------------------------------------
    // When the event log is opened, the position of the file pointer
    // is at the beginning of the log. Read the event log records
    // sequentially until the last record has been read.
    while (ReadEventLog(h,                // Event log handle
        EVENTLOG_FORWARDS_READ |          // Reads forward
        EVENTLOG_SEQUENTIAL_READ,         // Sequential read
        0,                                // Ignored for sequential read
        pevlr,                            // Pointer to buffer
        BUFFER_SIZE,                      // Size of buffer
        &dwRead,                          // Number of bytes read
        &dwNeeded))                       // Bytes in the next record
    {
        while (dwRead > 0)
        {
            // Get the event source name.
            lpSourceName = (LPCTSTR) ((LPBYTE) pevlr + sizeof(EVENTLOGRECORD));        

            // Print the information if the event source and the message
            // match the parameters
            
            if ((lstrcmp(lpSourceName,sourceName) == 0) &&
                (dwMessageID == pevlr->EventID))
            {
                // Step 6: ----------------------------------------------
                // Retrieve the message string. -------------------------
                FormatMessage(
                    FORMAT_MESSAGE_FROM_HMODULE, // Format of message
                    ghResDll,                    // Handle to the DLL file
                    pevlr->EventID,              // Event message identifier
                    MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
                    (LPTSTR) &lpMsgBuf1,         // Buffer that contains message
                    BUFFER_SIZE,                 // Size of buffer
                    NULL);                       // Array of insert values
                
                // Print the event identifier, event type, event category,
                // event source, and event message.
                std::wcout << dwThisRecord++ <<
                    L"  Event ID: " << pevlr->EventID << L" Event Type: " <<
                    std::endl;

                switch(pevlr->EventType)
                {
                    case EVENTLOG_ERROR_TYPE:
                        std::wcout << L"EVENTLOG_ERROR_TYPE  " << std::endl;
                        break;
                    case EVENTLOG_WARNING_TYPE:
                        std::wcout << L"EVENTLOG_WARNING_TYPE  " << std::endl;
                        break;
                    case EVENTLOG_INFORMATION_TYPE:
                        std::wcout << L"EVENTLOG_INFORMATION_TYPE  " << std::endl;
                        break;
                    case EVENTLOG_AUDIT_SUCCESS:
                        std::wcout << L"EVENTLOG_AUDIT_SUCCESS  " << std::endl;
                        break;
                    case EVENTLOG_AUDIT_FAILURE:
                        std::wcout << L"EVENTLOG_AUDIT_FAILURE  " << std::endl;
                        break;
                    default:
                        std::wcout << L"Unknown  " << std::endl;
                        break;
                }   

                std::wcout << L"  Event Category: " <<
                    pevlr->EventCategory << L" Event Source: " <<
                    lpSourceName << L" Message: " << (LPTSTR) lpMsgBuf1 <<
                    std::endl;
            }
         
            dwRead -= pevlr->Length;
            pevlr = (EVENTLOGRECORD *) ((LPBYTE) pevlr + pevlr->Length);
        }

        pevlr = (EVENTLOGRECORD *) &bBuffer;
    }
   
    // Step 7: -------------------------------------------------------------
    // Close the event log.
    CloseEventLog(h);
}            




Пример из МСДН



--------------------
????? ??, ??????? ?????.  smile 
PM MAIL WWW ICQ   Вверх
heavix
Дата 5.12.2011, 15:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 60
Регистрация: 10.8.2007

Репутация: нет
Всего: нет



Огромное спасибо))) Но уже сам разобрался - спас рихтер)
хотя не совсем понял почему именно так не работало, но избавившись от переменной dwBytesToRead
и сделав вызов чтения следующим образом:

Код

DWORD res = ReadEventLog(hEventLog, 
      EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ,
      0, 
      reinterpret_cast<PBYTE>(pBuffer.get()),
      dwBytesNeed,
      &dwBytesRead,
      &dwBytesNeed);


все замечательно начало работать)))
PM MAIL   Вверх
Andrey44
Дата 5.12.2011, 15:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1501
Регистрация: 4.12.2006
Где: На работе

Репутация: 8
Всего: 26



dwBytesNeed - как я понял это размер бафера для чтения, а вы передавали туда 1


--------------------
????? ??, ??????? ?????.  smile 
PM MAIL WWW ICQ   Вверх
heavix
Дата 5.12.2011, 19:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 60
Регистрация: 10.8.2007

Репутация: нет
Всего: нет



Цитата

dwBytesNeed - как я понял это размер бафера для чтения, а вы передавали туда 1

только dwBytesToRead )) 
Да, передавал )) но это нормальная ситуация для Апишек, когда вызов происходит в 2 этапа:
при первом передается единичка (или вообще 0), получаем в dwBytesNeed размер для буфера,
выделяем под него место и повторно перечитываем)) 
Даже если бы функция делала смещение на 1 запись при каждом чтении (а что не так) то я
читал бы количество записей меньшее реального ровно в половину))) - что тоже не наблюдалось.
По сему пока данное поведение сией апишки для меня мистика) но главное что задача вообще решена)  

Это сообщение отредактировал(а) heavix - 5.12.2011, 19:37
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.0840 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.