Click here to Skip to main content
Email Password   helpLost your password?
  • Download demo executable - 17 Kb
  • Download source files - 43 Kb
  • Sample Image

    The Event Viewer is intended to be run under WindowsNT System Manager (check the submission with the same name). This sample application uses (more or less) the same policy regarding MDI, child dialog encapsulation, controls etc., and these things are treated there. In this article you can see two thread routines which you may find interesting.
    1. The first is the routine which enumerates event entries, FillEventLogList. The structure passed as parameter to this thread routine is

    typedef struct _tagEVENTLOGFILTER
    {
       BOOL      fApplication;            /* 'Application' entries       */
       BOOL      fSecurity;            /* 'Security' entries       */
       BOOL      fSystem;               /* 'System' entries       */
       BOOL      fCustom;               /* 'Custom' entries: unused      */
       TCHAR      lpszComputerName[_MAX_PATH + 1];      /* computer name         */
       HWND      hwndLV;               /* list view handle      */
       HWND      hwndDlg;               /* encapsulated dialog handle   */
       HWND      hwndProgr;            /* progress bar handle      */
       HANDLE      hCancelEvent;            /* 'Cancel' event handle      */
       HANDLE      hCloseEvent;            /* 'Close' event handle      */
       unsigned   uThreadId;               /* thread ID         */
       TCHAR      lpszCustomEventFileName[_MAX_PATH + 1];   /* Custom file name: unused      */
    } EVENTLOGFILTER, *LPEVENTLOGFILTER;
    
    The routine looks like this:
    unsigned int __stdcall 
    FillEventLogList(LPVOID lpParam)
    {
       EVENTLOGFILTER *pelf = 0;
       int nRetVal = 0;
       HWND hParentWnd = 0, hwndDlg = 0, hwndLV = 0, hwndProgr = 0;
       HANDLE hEventLog = 0;
       DWORD dwEventLogRecords = 0, dwOldestEventLogRecord = 0, dwEvLogCounter = 0, dwNumberOfBytesToRead = 0, 
          dwBytesRead = 0, dwMinNumberOfBytesNeeded = 0, dwCancel = 0, dwClose = 0;
       LPVOID lpEventLogRecordBuffer = 0;
       TCHAR chFakeBuffer;
       BOOL bRetVal = FALSE;
       BOOL fExit = FALSE;
       UINT uStep = 0, uStepAt = 0, uPos = 0, uOffset = 0;
       TCHAR lpUNCServerName[_MAX_PATH + 1], lpszEventLogSourceName[_MAX_PATH + 1], lpszErrMsg[1024];
    
       // get thread parameter structure address...
    
       pelf = (EVENTLOGFILTER *)lpParam;
       // ...and retrieve the appropriate handles
    
       hwndDlg   = pelf->hwndDlg;
       hwndLV   = pelf->hwndLV;
       hwndProgr = pelf->hwndProgr;
    
       // get parent window...
    
       hParentWnd = GetParent(hwndDlg);
       // ...and set user data to 1 (the window has thread running) - will be reset to 0 when thread will terminate
    
       SetWindowLong(hParentWnd, GWL_USERDATA, (LONG)pelf); 
    
       // resize dialog
    
       MDIChild_ResizeDlg(hwndDlg, TRUE);
    
       // format UNC machine name to work with
    
       wsprintf(lpUNCServerName, _T("\\\\%s"), pelf->lpszComputerName);
    
       // establish what kind of event log section will show the list
    
       if(g_fApplication)
          _tcscpy(lpszEventLogSourceName, _T("Application"));            //   APPLICATION
    
       else if(g_fSystem)
          _tcscpy(lpszEventLogSourceName, _T("System"));               //   SYSTEM
    
       else if(g_fSecurity)
          _tcscpy(lpszEventLogSourceName, _T("Security"));            //   SECURITY
    
       else if(g_fCustom)
          _tcscpy(lpszEventLogSourceName, pelf->lpszCustomEventFileName);   //   CUSTOM
    
       else
       {
          nRetVal = -1;
          goto _cleanup_;
       }
    
       //   lookup for close or cancel (ESC pressed) attempts to intrrerupt thread
    
       dwCancel = WaitForSingleObject(pelf->hCancelEvent, 0);
       dwClose = WaitForSingleObject(pelf->hCloseEvent, 0);
    
       while(!fExit)
       {
          if(g_fCustom)   //   never reached
    
             hEventLog = OpenBackupEventLog((LPCTSTR)lpUNCServerName, (LPCTSTR)lpszEventLogSourceName);
          else
             hEventLog = OpenEventLog((LPCTSTR)lpUNCServerName, (LPCTSTR)lpszEventLogSourceName);
    
          if(hEventLog)
          {
             if(GetNumberOfEventLogRecords(hEventLog, &dwEventLogRecords) && 
                GetOldestEventLogRecord(hEventLog, &dwOldestEventLogRecord))
             {
                //   establish step fro progress bar
    
                SendMessage(hwndProgr, PBM_SETRANGE, (WPARAM)0, (LPARAM)MAKELPARAM(0, 100));
                uStepAt = (dwEventLogRecords / 100) + 1;
    
                for(dwEvLogCounter = dwOldestEventLogRecord; 
                   dwEvLogCounter < (dwOldestEventLogRecord + dwEventLogRecords); 
                   dwEvLogCounter++)
                {
                   //   advance progress bar with step
    
                   uStep++;
                   if(uStep % uStepAt == 0)
                      hwndProgr && SendMessage(hwndProgr, PBM_SETPOS, (WPARAM)++uPos, 0);
    
                   dwCancel = WaitForSingleObject(pelf->hCancelEvent, 0);
                   if(dwCancel == WAIT_OBJECT_0)
                      goto _canceled_;
                   dwClose = WaitForSingleObject(pelf->hCloseEvent, 0);
                   if(dwClose == WAIT_OBJECT_0)
                      goto _close_;
    
                   //   this is a false call (intended to get the real structure size)
    
                   lpEventLogRecordBuffer      = (LPVOID)&chFakeBuffer;
                   dwNumberOfBytesToRead      = 1;
                   dwMinNumberOfBytesNeeded   = 1;
    
       _retry_:
                   bRetVal = ReadEventLog(hEventLog, EVENTLOG_SEEK_READ | EVENTLOG_FORWARDS_READ, dwEvLogCounter, 
                      lpEventLogRecordBuffer, dwNumberOfBytesToRead, &dwBytesRead, &dwMinNumberOfBytesNeeded);
    
                   if(!bRetVal)
                   {
                      g_dwLastError = GetLastError();
    
                      if(g_dwLastError == ERROR_INSUFFICIENT_BUFFER)
                      {
                         lpEventLogRecordBuffer = (LPVOID)GlobalAlloc(GPTR, dwMinNumberOfBytesNeeded);
                         if(lpEventLogRecordBuffer == (void *)0)
                            goto _allocationfailure_;
    
                         dwNumberOfBytesToRead = dwMinNumberOfBytesNeeded;
                         goto _retry_;
                      }
                      else
                         goto _unknownerror_;
                   }
                   else   //   here we are with complete structure filled; proceed
    
                   {
                      PEVENTLOGRECORD pELR = 0;
                      TCHAR *lpszSourceName = 0, lpszUserName[_MAX_PATH + 1], *lpszComputerName = 0,
                         lpszRefDomainName[_MAX_PATH + 1], *szSIDType = 0, *szSIDName = 0, sz2[32],
                         *szExpandedString = 0, szSubmitTime[32], szWriteTime[32];
                      DWORD dwSourceNameLen = 0, dwComputerNameLen = 0, cbName = _MAX_PATH + 1, 
                         cbRefDomainName = _MAX_PATH + 1, dwSIDTypeLen = 0, dwSidSize = 0, dwEventTypeLen = 0;
                      PSID pUserSID = 0;
                      SID_NAME_USE _SidNameUse = (SID_NAME_USE)(SidTypeUser - 1);
                      BOOL bRetVal = FALSE;
                      LPBYTE pStrings = 0, pData = 0;
                      UINT x = 0, uSize, uStringOffset, uStepOfString = 0, uImage = 0;
    
                      //   the buffer
    
                      pELR   = (PEVENTLOGRECORD)lpEventLogRecordBuffer;
    
                      //   source name and advance offset
    
                      uOffset   = sizeof(EVENTLOGRECORD);
                      lpszSourceName = (TCHAR *)GlobalAlloc(GPTR, (_MAX_PATH + 1) * sizeof(TCHAR));
                      strcpy(lpszSourceName, (LPTSTR)((LPBYTE)pELR + uOffset));
                      dwSourceNameLen = strlen(lpszSourceName);
    
                      //   computer name and advance offset
    
                      uOffset   += strlen(lpszSourceName) + sizeof(TCHAR);
                      lpszComputerName = (TCHAR *)GlobalAlloc(GPTR, (_MAX_PATH + 1) * sizeof(TCHAR));
                      strcpy(lpszComputerName, (LPTSTR)((LPBYTE)pELR + uOffset));
                      dwComputerNameLen = strlen(lpszComputerName);
    
                      uOffset += strlen(lpszComputerName) + sizeof(TCHAR);
    
                      //   SID
    
                      dwSIDTypeLen = 32;
                      szSIDType = (TCHAR *)GlobalAlloc(GPTR, (dwSIDTypeLen + 1) * sizeof(TCHAR));
    
                      //   retrieve SID
    
                      if(pELR->UserSidLength > 0)
                      {
                         pUserSID = (SID *)GlobalAlloc(GPTR, pELR->UserSidLength);
                         memcpy(pUserSID, (PSID)((LPBYTE)pELR + pELR->UserSidOffset), pELR->UserSidLength);
                         
                         cbName = cbRefDomainName = _MAX_PATH + 1;
                         *lpszRefDomainName = *lpszUserName = '\0';
    
                         bRetVal = LookupAccountSid(0, pUserSID, 
                            lpszUserName, &cbName, 
                            lpszRefDomainName, &cbRefDomainName, 
                            &_SidNameUse);
    
                         if(bRetVal)
                         {
                            if(bRetVal)
                            {
                               dwSIDTypeLen = 32;
                               GetNameUse(_SidNameUse, szSIDType, &dwSIDTypeLen);
    
                               dwSidSize = (15 + 12 + (12 * (*GetSidSubAuthorityCount(pUserSID))) + 1) * sizeof(TCHAR);
                               szSIDName = (TCHAR *)GlobalAlloc(GPTR, (dwSidSize + 1) * sizeof(TCHAR));
                               ConvertSid(pUserSID, szSIDName, &dwSidSize); 
                            }
                            else
                            {
                               strcpy(lpszRefDomainName, "N/A");
                               strcpy(lpszUserName, "N/A");
                               strcpy(szSIDType, "N/A");
                            }
                         }
                         else
                         {
                         }
                      }
                      else
                      {
                         strcpy(lpszRefDomainName, "N/A");
                         strcpy(lpszUserName, "N/A");
                         strcpy(szSIDType, "N/A");
                      }
    
                      //   Now we have to get the description strings.
    
                      uSize = 0, uStringOffset = pELR->StringOffset;
                      uSize = pELR->DataOffset - pELR->StringOffset;
    
                      // Strings
    
                      if(uSize > 0)
                      {
                         pStrings = (LPBYTE)GlobalAlloc(GPTR, uSize * sizeof(BYTE));
                         memcpy(pStrings, (LPBYTE)pELR + uStringOffset, uSize);
    
                         //   Strings
    
                         uStepOfString = 0;
                         szExpandedString = (TCHAR *)GlobalAlloc(GPTR, (uSize + MAX_MSG_LENGTH) * sizeof(TCHAR));
                         for(x = 0; x < pELR->NumStrings; x++)
                         {
                            if(x == 0)
                            {
                               strcpy(szExpandedString, (TCHAR *)pStrings + uStepOfString);
                               if(x < (UINT)pELR->NumStrings - 1)
                                  strcat(szExpandedString, ",");
                            }
                            else
                               strcat(szExpandedString, (TCHAR *)pStrings + uStepOfString);
    
                            uStepOfString = strlen((TCHAR *)pStrings + uStepOfString) + 1;
                         }
                      }
    
                      //   Data
    
                      pData = (LPBYTE)GlobalAlloc(GPTR, pELR->DataLength * sizeof(BYTE));
                      memcpy(pData, (LPBYTE)((LPBYTE)pELR + pELR->DataOffset), pELR->DataLength);
    
                      dwEventTypeLen = 32;
                      GetEventLogType(sz2, pELR->EventType, &dwEventTypeLen);
                      GetEventLogImage(&uImage, pELR->EventType);
    
                      lstrcpyn(szSubmitTime, asctime(localtime((time_t *)&(pELR->TimeGenerated))), 25);
                      lstrcpyn(szWriteTime, asctime(localtime((time_t *)&(pELR->TimeWritten))), 25);
    
                      InsertRowInList(hwndLV, 9, &dwEvLogCounter, 
                         lpszSourceName, 
                         lpszUserName, 
                         szSIDName, 
                         lpszRefDomainName, 
                         sz2, uImage, 
                         szSubmitTime, szWriteTime);
    
                      SafeDeletePointer(pData, pELR->DataLength);
                      SafeDeletePointer(szExpandedString, uSize); 
                      SafeDeletePointer(pStrings, pELR->DataOffset - pELR->StringOffset);
                      SafeDeletePointer(szSIDName, dwSidSize + 1);
                      SafeDeletePointer(szSIDType, dwSIDTypeLen + 1);
                      SafeDeletePointer(lpszSourceName, dwSourceNameLen);
                      SafeDeletePointer(lpszComputerName, dwComputerNameLen);
                      SafeDeletePointer(pUserSID, pELR->UserSidLength);
                      SafeDeletePointer(lpEventLogRecordBuffer, dwNumberOfBytesToRead);
                   }
                }
    
                goto _cleanup_;
             }
             else
                ReportLastError(0, 0, TRUE);
    
       _unknownerror_:
             ReportLastError(lpszErrMsg, 0, TRUE);
             goto _cleanup_;
    
       _allocationfailure_:
             LoadString(g_hInstance, IDS_ERR_ALLOCATIONFAILURE, lpszErrMsg, 1024);
             MessageBox(0, lpszErrMsg, 0, MB_OK | MB_ICONSTOP);
             goto _cleanup_;
    
       _canceled_:
             nRetVal = 1;
             goto _cleanup_;
    
       _close_:
             nRetVal = 2;
             goto _cleanup_;
    
       _cleanup_:
             fExit = TRUE;
    
             CloseEventLog(hEventLog);
             hEventLog = 0;
          }
          else
          {
             fExit = TRUE;
             ReportLastError(0, 0, TRUE);
          }
       }
    
       // final cleanup on dialog
    
       if(nRetVal != 2)
       {
          if(IsWindow(hwndDlg))
             MDIChild_ResizeDlg(hwndDlg, FALSE);
          if(IsWindow(hParentWnd))
             SetWindowLong(hParentWnd, GWL_USERDATA, (LONG)0);
       }
    
       CloseHandle(pelf->hCancelEvent);
       CloseHandle(pelf->hCloseEvent);
    
       GlobalFree(pelf);
       pelf = 0;
    
       return nRetVal;
    }
    

    The key to understanding this king of enumeration and especially the using of structure PEVENTLOGRECORD resides in its definition:

    typedef struct _EVENTLOGRECORD { 
        DWORD  Length; 
        DWORD  Reserved; 
        DWORD  RecordNumber; 
        DWORD  TimeGenerated; 
        DWORD  TimeWritten; 
        DWORD  EventID; 
        WORD   EventType; 
        WORD   NumStrings; 
        WORD   EventCategory; 
        WORD   ReservedFlags; 
        DWORD  ClosingRecordNumber; 
        DWORD  StringOffset; 
        DWORD  UserSidLength; 
        DWORD  UserSidOffset; 
        DWORD  DataLength; 
        DWORD  DataOffset; 
        // 
    
        // Then follow: 
    
        // 
    
        // TCHAR SourceName[] 
    
        // TCHAR Computername[] 
    
        // SID   UserSid 
    
        // TCHAR Strings[] 
    
        // BYTE  Data[] 
    
        // CHAR  Pad[] 
    
        // DWORD Length; 
    
        // 
    
    } EVENTLOGRECORD; 
    

    Because this is a variable-length structure, the using of offsets, conversion and allocations seems to me the best approach. (By the way, spending more time you can easily rewrite a better routine).
    Also, you could spend some time reading the ConvertSid function, which retrieves the name of SID looking in some weird registry key. Again you have to deal with a nonstandard structure, SID, which cannot be manipulated manually, but only using the API specific routines.

    BOOL 
    ConvertSid(PSID pSid, LPTSTR pszSidText, LPDWORD dwBufferLen) 
    { 
         DWORD                     dwSubAuthorities; 
         DWORD                     dwSidRev = SID_REVISION; 
         DWORD                     dwCounter; 
         DWORD                     dwSidSize; 
         PSID_IDENTIFIER_AUTHORITY psia; 
     
         if(!IsValidSid(pSid))  
              return FALSE; 
     
         psia = GetSidIdentifierAuthority(pSid); 
    
         dwSubAuthorities =* GetSidSubAuthorityCount(pSid); 
     
         dwSidSize = (15 + 12 + (12 * dwSubAuthorities) + 1) * sizeof(TCHAR); 
     
         if (*dwBufferLen < dwSidSize)
        { 
              *dwBufferLen = dwSidSize; 
              SetLastError(ERROR_INSUFFICIENT_BUFFER); 
              return FALSE; 
        } 
     
         dwSidSize=wsprintf(pszSidText, TEXT("S-%lu-"), dwSidRev ); 
     
         if((psia->Value[0] != 0) || (psia->Value[1] != 0))
              dwSidSize += wsprintf(pszSidText + lstrlen(pszSidText), 
              TEXT("0x%02hx%02hx%02hx%02hx%02hx%02hx"), 
              (USHORT)psia->Value[0], 
              (USHORT)psia->Value[1], 
              (USHORT)psia->Value[2], 
              (USHORT)psia->Value[3], 
              (USHORT)psia->Value[4], 
              (USHORT)psia->Value[5]); 
         else 
              dwSidSize += wsprintf(pszSidText + lstrlen(pszSidText), 
                                   TEXT("%lu"), 
                                   (ULONG)(psia->Value[5]      )   + 
                                   (ULONG)(psia->Value[4] <<  8)   + 
                                   (ULONG)(psia->Value[3] << 16)   + 
                                   (ULONG)(psia->Value[2] << 24)   ); 
     
         for (dwCounter=0 ; dwCounter < dwSubAuthorities ; dwCounter++)
              dwSidSize+=wsprintf(pszSidText + dwSidSize, TEXT("-%lu"), *GetSidSubAuthority(pSid, dwCounter)); 
     
         return TRUE; 
    } 
    

    Double-clicking on an event log entry represented by a row in list, the data window appears, showing more detailed data about the entry you choose. You have to excuse me for the resize problems (sometimes - or I must say often? - resizing parent data window does not resize encapsulated dialog). Again, the job is done via another thread, which use the EVENTID structure

    typedef struct _tagEVENTID
    {
       TCHAR lpszMachineName[_MAX_PATH + 1];
       TCHAR lpszEventName[_MAX_PATH + 1];
       DWORD   dwEventId;
       HWND  hwndDlg;
    } EVENTID, *LPEVENTID;
    
    which simply identifies the record entry, and the routine:
    unsigned int __stdcall 
    ShowEventData(LPVOID lpParam)
    {
       LPEVENTID peid = (LPEVENTID)lpParam;
    
       int   nRetVal = 0;
    
       HWND  hwndDlg      = peid->hwndDlg;
       HWND  hwndEditStrings   = GetDlgItem(hwndDlg, IDE_STRINGS);
       HWND  hwndEditData      = GetDlgItem(hwndDlg, IDE_DATA);
       DWORD dwRecId      = peid->dwEventId;
    
       TCHAR  lpUNCServerName[_MAX_PATH + 1];
       TCHAR  lpSourceName[_MAX_PATH + 1];
    
       HANDLE  hEventLog         = 0;
       
       DWORD  dwEventLogRecords      = 0;
       DWORD  dwOldestEventLogRecord   = 0;
       DWORD  dwEvLogCounter      = 0;
    
       LPVOID lpEventLogRecordBuffer   = 0;
       char   chFakeBuffer      = ' ';
       DWORD  dwNumberOfBytesToRead   = 0;
       DWORD  dwBytesRead         = 0;
       DWORD  dwMinNumberOfBytesNeeded   = 0;
       BOOL    bRetVal         = FALSE;
       TCHAR   lpszEventLogSourceName[_MAX_PATH + 1];
    
       wsprintf(lpUNCServerName, _T("\\\\%s"), peid->lpszMachineName);
       wsprintf(lpSourceName, _T("%s"), peid->lpszEventName);
    
       if(g_fApplication)
          _tcscpy(lpszEventLogSourceName, _T("Application"));
       else if(g_fSystem)
          _tcscpy(lpszEventLogSourceName, _T("System"));
       else if(g_fSecurity)
          _tcscpy(lpszEventLogSourceName, _T("Security"));
    //   else if(g_fCustom)
    
    //      _tcscpy(lpszEventLogSourceName, _T("Application"));
    
       else
       {
          nRetVal = -1;
          goto _cleanup_;
       }
    
       hEventLog = OpenEventLog((LPCTSTR)lpUNCServerName, (LPCTSTR)lpszEventLogSourceName);
       if(hEventLog)
       {
          if(GetNumberOfEventLogRecords(hEventLog, &dwEventLogRecords) && 
             GetOldestEventLogRecord(hEventLog, &dwOldestEventLogRecord))
          {
             for(dwEvLogCounter = dwOldestEventLogRecord; 
                dwEvLogCounter <= (dwOldestEventLogRecord + dwEventLogRecords); 
                dwEvLogCounter++)
             {
                if(dwEvLogCounter != dwRecId)
                   continue;
    
                lpEventLogRecordBuffer      = (LPVOID)&chFakeBuffer;
                dwNumberOfBytesToRead      = 1;
                dwMinNumberOfBytesNeeded   = 0;
    
    _retry_:
                bRetVal = ReadEventLog(hEventLog, EVENTLOG_SEEK_READ | EVENTLOG_FORWARDS_READ,
                          dwEvLogCounter, lpEventLogRecordBuffer, dwNumberOfBytesToRead, 
                          &dwBytesRead, &dwMinNumberOfBytesNeeded);
    
                if(!bRetVal)
                {
                   g_dwLastError = GetLastError();
    
                   if(g_dwLastError == ERROR_INSUFFICIENT_BUFFER)
                   {
                      lpEventLogRecordBuffer = (LPVOID)GlobalAlloc(GPTR, dwMinNumberOfBytesNeeded);
                      if(lpEventLogRecordBuffer == (void *)0)
                         goto _allocationfailure_;
    
                      dwNumberOfBytesToRead = dwMinNumberOfBytesNeeded;
                      goto _retry_;
                   }
                   else
                      goto _unknownerror_;
                }
                else
                {
                   PEVENTLOGRECORD pELR = 0;
                   LPBYTE         pData = 0;
                   HMODULE hModule = 0;
                   TCHAR szExeFile[_MAX_PATH + 1], szExeFilePath[_MAX_PATH + 1];
                   HKEY   hk                  = (HKEY)0;
                   TCHAR  szKeyName[_MAX_PATH + 1];
                   DWORD dwMaxPath;
                   DWORD dwType;
                   LPBYTE         pStrings = 0;
                   UINT uStringOffset;
                   TCHAR *szExpandedString;
                   LPVOID lpszBuffer = 0;
                   
                   pELR   = (PEVENTLOGRECORD)lpEventLogRecordBuffer;
    
                   pData = (LPBYTE)GlobalAlloc(GPTR, pELR->DataLength * sizeof(BYTE));
                   memcpy(pData, (LPBYTE)((LPBYTE)pELR + pELR->DataOffset), pELR->DataLength);
    
                   {
                      UINT x, uStepOfString = 0;
    
                      pStrings = (LPBYTE)GlobalAlloc(GPTR, pELR->DataOffset - pELR->StringOffse
                                                     * sizeof(BYTE));
                      memcpy(pStrings, (LPBYTE)pELR + pELR->StringOffset, pELR->DataOffset
                                                      - pELR->StringOffset);
    
                      szExpandedString = (TCHAR *)GlobalAlloc(GPTR, (pELR->DataOffset
                                                    - pELR->StringOffset + 1024) * sizeof(TCHAR));
                      for(x = 0; x < pELR->NumStrings; x++)
                      {
                         if(x == 0)
                         {
                            strcpy(szExpandedString, (TCHAR *)pStrings + uStepOfString);
                            if(x < (UINT)pELR->NumStrings - 1)
                               strcat(szExpandedString, ",");
                         }
                         else
                            strcat(szExpandedString, (TCHAR *)pStrings + uStepOfString);
    
                         uStepOfString = strlen((TCHAR *)pStrings + uStepOfString) + 1;
                      }
    
                      wsprintf(szKeyName, _T("SYSTEM\\CurrentControlSet\\Services\\EventLog\\%s\\%s"), 
                         lpszEventLogSourceName, peid->lpszEventName);
                      if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, szKeyName, 0L, KEY_READ, &hk) == NOERROR)
                      {
                         dwMaxPath = _MAX_PATH + 1;
                         if(RegQueryValueEx(hk, _T("EventMessageFile"), 0, &dwType, 
                                            (LPBYTE)szExeFile, &dwMaxPath) == NOERROR)
                         {
                            if(ExpandEnvironmentStrings(szExeFile, szExeFilePath, _MAX_PATH + 1) == 0)
                               strcpy(szExeFilePath, szExeFile);
    
                            hModule = LoadLibraryEx(szExeFilePath, 0, DONT_RESOLVE_DLL_REFERENCES);
                            if(hModule)
                            {
                               TCHAR **_sz = (TCHAR**)GlobalAlloc(GPTR, (pELR->NumStrings) 
                                                                     * sizeof(TCHAR *));
                               register UINT z;
    
                               uStringOffset = 0;
                               for(z = 0; z < pELR->NumStrings; z++)
                               {
                                  _sz[z] = (TCHAR *)GlobalAlloc(GPTR, 
                                     (strlen((TCHAR *)pStrings + uStringOffset) + 1) * sizeof(TCHAR));
                                  strcpy(_sz[z], (TCHAR *)pStrings + uStringOffset);
    
                                  uStringOffset += strlen((TCHAR *)pStrings + uStringOffset) + 1;
                               }
    
                               FormatMessage(
                                  FORMAT_MESSAGE_ALLOCATE_BUFFER | 
                                  FORMAT_MESSAGE_FROM_HMODULE | 
                                  FORMAT_MESSAGE_FROM_SYSTEM | 
                                  FORMAT_MESSAGE_ARGUMENT_ARRAY,
                                  hModule, pELR->EventID, 0, (LPTSTR)&lpszBuffer, 1024, 
                                  _sz
                               );
    
                               for(z = 0; z < pELR->NumStrings; z++)
                               {
                                  SafeDeletePointer(_sz[z], strlen(_sz[z]));
                                  _sz[z] = 0;
                               }
                               SafeDeletePointer(_sz, (pELR->NumStrings) * sizeof(TCHAR *));
                               _sz = 0;
    
                               if(lpszBuffer)
                               {
                                  strcpy(szExpandedString, (TCHAR *)lpszBuffer);
                                  uStringOffset = strlen(szExpandedString);
                               }
    
                               if(lpszBuffer)
                                  LocalFree(lpszBuffer);
    
                               FreeLibrary(hModule);
                            }
                         }                  
                         RegCloseKey(hk);
                      }
    
                      SendMessage(hwndEditStrings, WM_SETTEXT, 0, (LPARAM)(LPCTSTR)szExpandedString);
    
                      SafeDeletePointer(szExpandedString, strlen(szExpandedString));
                   }
    
                   {
                      TCHAR _str[1024];
                      _tcscpy(_str, _T(""));
                      if(pELR->DataLength > 0)
                      {
                         register UINT x;
    
                         for(x = 0; x < pELR->DataLength; x += 8)
                         {
                            TCHAR _strAux[1024];
                            register UINT y;
    
                            wsprintf(_strAux, "%.4x: ", x);
                            _tcscat(_str, _strAux);
    
                            for(y = x; y < x + 8; y++)
                            {
                               wsprintf(_strAux, "%.2x ", pData[y]);
                               _tcscat(_str, _strAux);
                            }
                            _tcscat(_str, _T("  "));
    
                            for(y = x; y < x + 8; y++)
                            {
                               if(!isprint((int)pData[y]))
                                  _tcscat(_str, _T("."));
                               else
                               {
                                  TCHAR s[2];
                                  s[0] = (TCHAR)pData[y];
                                  s[1] = '\0';
                                  _tcscat(_str, s);
                               }
                            }
                            _tcscat(_str, _T("\r\n"));
                         }
                      }
                      else
                         _tcscat(_str, _T("No data available."));
    
                      SendMessage(hwndEditData, WM_SETTEXT, 0, (LPARAM)(LPCTSTR)_str);
                   }
                }
             }
    
             goto _cleanup_;
          }
          else
             ReportLastError(0, 0, TRUE);
    
    _unknownerror_:
          MessageBox(0, TEXT("Unknown error."), 0, MB_OK | MB_ICONSTOP);
          goto _cleanup_;
    
    _allocationfailure_:
          MessageBox(0, TEXT("Allocation failure."), 0, MB_OK | MB_ICONSTOP);
          goto _cleanup_;
    
    _cleanup_:
          CloseEventLog(hEventLog);
          hEventLog = 0;
       }
       else
          ReportLastError(0, 0, TRUE);
    
       #pragma warning(disable:4127)
       SafeDeletePointer(peid, sizeof(EVENTID));
    
       return 0L;
    }
    
    Although the string szExpandedString is allocated with only 1024 length (so can truncate sometimes thre REAL value), again you can easily replace with the correct size doing some checkings before. The construction key is now a registry key specific to the record entry, located under SYSTEM\CurrentControlSet\Sevices\EventLog key. If opening of this key succeeds and the call of ExpandEnvironmentStrings leads to the binary file where .mc message entry resides, then a LoadLibraryEx call with the DONT_RESOLVE_DLL_REFERENCES flag set (to do not load other DLLs, but rather resource section) will lead us to the necessary .mc resource entry, which is a entry in the message table (usually created with message compiler tool). Now, the call
       FormatMessage
       (
          FORMAT_MESSAGE_ALLOCATE_BUFFER | 
          FORMAT_MESSAGE_FROM_HMODULE | 
          FORMAT_MESSAGE_FROM_SYSTEM | 
          FORMAT_MESSAGE_ARGUMENT_ARRAY,
          hModule, 
          pELR->EventID, 
          0, 
          (LPTSTR)&lpszBuffer, 
          1024, 
          _sz
       );
    
    will offers us the message bound with this particular event log entry. The rest is history (hexa formatting, dialog stuff).
    You must Sign In to use this message board.
     
     
    Per page   
     FirstPrevNext
    GeneralHow do i detect the status of the hardware
    paul10001
    21:50 6 Sep '08  
    I want to detect the status of the hardware, such as tape device.
    OS: Windows 2003

    thanks.
    GeneralRe: How do i detect the status of the hardware
    Cristian Amarie
    7:43 11 Feb '09  
    Best bets would be WMI.

    Nuclear launch detected

    GeneralHow to get Administration/User subscribe logging?
    Ingenious001
    3:23 31 Aug '07  
    Hello my friends,

    I want to retrieve information from the Eventlog when an Administrator or a user has logged in the pc. How can I achieve that?

    Thank you very much.

    **We are an example of helping each other**

    Questionit's wrong, geting particular description of a record in windows vista
    raopeitao
    17:57 2 Aug '07  
    wrong code:///////////////////
    if (pRecord->NumStrings ) {
    pStr = (char*)((LPBYTE)pRecord + pRecord->StringOffset);
    } else {
    pStr = "";
    }

    if ( pStr )
    {
    DWORD i;
    for ( i = 0; i < pRecord->NumStrings; i++ )
    {
    lpP[i] = (LPSTR)pStr;
    pStr = strchr( (char*)pStr, '\0' ) + 1;
    }
    }
    /////////////////////////////
    up : code is used to geting insertion string that are inserted to a message
    from eventmessagefile to get particular description. but in windows vista,
    if containing chinaese string in pRecord->StringOffset data, it will get "?"
    ,replaced right chinaese string .why? how do i do?

    null

    AnswerRe: it's wrong, geting particular description of a record in windows vista
    Cristian Amarie
    1:00 8 Sep '07  
    Perhaps using Unicode strings and LPWSTR?

    Nuclear launch detected

    QuestionRegarding // CHAR Pad[]
    Amit Papriwal
    0:56 23 Jul '07  
    How I come to know Pad size and also
    from where we shall start reading logs from old to new or from new to old

    Thanks
    AnswerRe: Regarding // CHAR Pad[]
    raopeitao
    18:12 2 Aug '07  
    CHAR Pad[] ??

    start reading logs from old to new or from new to old?

    read ReadEventLog() in msdn , the second param ,for example: VENTLOG_SEEK_READ | EVENTLOG_FORWARDS_READ in code

    null

    GeneralVery cool :)
    OddArne
    10:39 14 Oct '04  
    At work I thought that we'd need a program to trigger on certain events (and then maybe send an email, or so). So I thought I'd write an eventlog-"watcher".

    Just had some trouble with finding the extra piece of info related to the event when I came over this section telling me that I should use FormatMessage with files (who's location I can find in the registry related to the eventsource) Smile

    Nice - just what I needed to know, thanks
    GeneralEvent loging on PDC
    vijayv
    1:49 6 Feb '04  
    How can I use this application on PDC to detect each remote logon to the domain and get information about the user
    GeneralXP Pro
    NeilDevlin
    8:05 6 Jun '03  
    Hi,
    Is there a way to getting it to run on XP pro?
    I cant open any windows when building the application.

    Neil
    GeneralRe: XP Pro
    Sardaukar
    20:59 21 Sep '03  
    The computer enumeration is very outdated (frankly, is a horror - don't tell anyone I wrote it). So if you write a correct routine to write computer names there, it should work.
    GeneralThe RPC server is unavailable.
    Pravinu
    2:13 6 Jun '03  
    Hi,

    when i connect the system from dropdown, and press open button, it is saying

    "The RPC server is unavailable."

    How can i rectify it?

    Thank you in Advance.

    Regards,
    Pravin.

    GeneralRe: The RPC server is unavailable.
    Sardaukar
    2:30 6 Jun '03  
    1. The computer enumeration needs a complete rewrite using NetAPI...Frown
    2. The RPC server is unavailable is one of the multitude of errors returned by various APIs. You have to debug the code in order to see what is the call that triggered this error.
    GeneralRe: The RPC server is unavailable.
    Pravinu
    23:31 8 Jun '03  
    Hi,

    I am using Windows 2000..

    I debugged the coding and found it was in the SysMain_WndProc.C file, in

    LRESULT*
    OnOpen(HWND hWnd, LRESULT *plResult)

    and line is

    _stprintf(lpszCaption, "Event Log on %s - ", lpszMachineName);

    here in _stprintf it goes deep into and asking for Output.C and skipping that gives the Messagebox with 'The RPC server is unavailable.' as message.

    Can you help me to solve this?.. i tried with Windows2000.. is there anything special settings to be made?

    Thank you in Advance,

    Regards,
    Pravin.


    GeneralRe: The RPC server is unavailable.
    Sardaukar
    3:41 9 Jun '03  
    Output.c is an internal CRT file.
    I doubt C runtime library needs RPC to format the string.

    It is one of the next API calls that gives you this message. I don't remember now what OnOpen does, but I suppose it is calling OpenSCManager or OpenEventLog. Either one can return this to you.

    If you think the problem is not in code, you have a lot of articles in MSDN (you can start with 'Troubleshooting "RPC Server is Unavailable" in Windows 2000' - Q224370). Please read them, search help on internet etc. - I can't help you just starting from RPC_S_SERVER_UNAVAILABLE.

    Don't be afraid to debug. I posted this sample almost 4 years ago. If you get a crash, ok - but this is a valid error message and can be exactly what is happening on your machine.

    GeneralReadEventLog: Invalid Parameter
    massel
    3:04 17 Feb '03  
    Hallo,

    I use the Function ReadEventLog with Visual Basic, but it works not with all Servers.
    With some Severs I get the error "INVALID_PARAMETER" (ID: 87). I don't
    change any parameter!
    Have anybody an idee ?

    massel
    GeneralRe: ReadEventLog: Invalid Parameter
    massel
    4:18 19 Feb '03  
    Thank you for the answer but this was not the reasen, bacause in my Code there stands :


    If GetNumberOfEventLogRecords(plngEventLogHwd, _
    plngRecordNumber) <> False Then ....

    so, this part is ok.
    And I get allways the numbers of the Eventlog Records.

    but the Funktion

    plngRtn = ReadEventLog(plngEventLogHwd, _
    plngReadFlags, plngReadRecordOffset, _
    pbyteBuffer(0), plngNumBytesToRead, _
    plngBytesRead, plngMinNumBytesNeeded)

    returns with some servers zero and the LastDllError is 87. The parameter plngMinNumBytesNeeded is zero too.
    With other Servers, The parameter plngMinNumBytesNeeded is not zero.
    If I call this function again with plngNumBytesToRead=plngMinNumBytesNeeded it works.
    I don't know whether the Problem is the Code, may be it is the Server ??

    M.Siebel
    GeneralRe: ReadEventLog: Invalid Parameter
    massel
    4:40 20 Feb '03  
    Dear Cristian,

    thank you for this Resolution - it works!

    But not all log files it fails whith the EVENTLOG_SEEK_READ were larger than 2MB and one
    log file it didn't failed was larger than 2MB!
    So, I don't know, whether the log file-size is the reason.

    Many thanks

    M.Siebel
    GeneralRe: ReadEventLog: Invalid Parameter
    TClegg
    8:26 29 Jan '04  
    Could you post the solution on the board here? I'm experiencing the same issue -- when I use "EVENTLOG_FORWARDS_READ Or EVENTLOG_SEEK_READ" I get the invalid parameter error. When I use "EVENTLOG_FORWARDS_READ Or EVENTLOG_SEQUENTIAL_READ" it works, but I have to loop through *ALL* event records to read the event record in the middle that I want to read.

    Thanks in advance,

    TClegg
    GeneralHot to get the description text of an event?
    Ralph
    1:57 6 Feb '03  
    Does anybody has an idea how to extract the description string of an event, which is diplayed when opening the properties dialog?

    Thanks!

    Ralph

    GeneralRe: Hot to get the description text of an event?
    Maria Jose
    8:53 21 Sep '03  
    ive just copied the code from my program, i dont have much time so i havent modified. As u can see i save the information into a fiel, but i guess u can ignore it. If u have any problem understanding my writing just write back.
    All right??
    Mariajo

    int GetString(EVENTLOGRECORD *pRecord, FILE **xmlFile, LPSTR source)
    {
    BOOL f;
    FILE *xml;
    TCHAR szEvent[256],szBuffer[256], **first_sz;
    HMODULE hEvt;
    LPTSTR lpP[] = { "", "", "", "", "", "","", "", "","", "", "","", "", "","", "", "","", "", ""};
    LPTSTR lpBuf, lib;
    LPBYTE pStr;
    xml = *xmlFile;

    //LPSTR *final_str;
    //final_str = (LPSTR *)malloc(pRecord->NumStrings);

    if (pRecord->NumStrings )
    pStr = (LPBYTE)pRecord + pRecord->StringOffset;

    if ( pStr )
    {
    DWORD i;

    for ( i = 0; i < pRecord->NumStrings; i++ )
    {

    // final_str[i] = pStr;
    lpP[i] = pStr;
    pStr = strchr( pStr, '\0' ) + 1;

    }

    }
    f = ReadEventSourceInfo( source, szEvent);
    if(strchr(szEvent, ';'))
    {
    int i=0, j, k, num_files=0, last=0;
    char *aux, *cad;
    aux = szEvent;
    while(aux = strchr(aux, ';'))
    {
    num_files++;
    aux++;
    }
    aux = szEvent;

    for(j=0; j<= num_files; j++)
    {

    int counter =0;
    while((szEvent[i]!= ';') && i {
    i++;
    counter++;
    }
    first_sz= (TCHAR **)malloc(num_files * (sizeof(szEvent)));
    cad = (char *) malloc(counter+1);
    for(k = 0; k {
    cad[k] = szEvent[last+k];
    }
    cad[counter]= '\0';
    first_sz[j] = cad;
    i++;
    last = i;
    ExpandEnvironmentStrings(first_sz[j],szBuffer, 257);

    hEvt = LoadLibraryEx(szBuffer, NULL, DONT_RESOLVE_DLL_REFERENCES );
    /* Load the event message file DLL */
    if ( hEvt )
    {
    int i=0;

    /* Get the event message with the paramater strings inserted */
    lpBuf = GetEventMessage( hEvt, pRecord->EventID,
    MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), lpP );

    if ( lpBuf )
    {
    for(i=0; i {
    if((lpBuf[i]=="<") || (lpBuf[i]==">"))
    {
    lpBuf[i]='"';
    }
    }

    fprintf(xml, " ");
    fputs( lpBuf, xml );
    LocalFree( lpBuf );
    fprintf(xml, "
    \n");
    return 1;
    }
    FreeLibrary( hEvt );

    }
    }
    return 1;


    }
    else
    {
    ExpandEnvironmentStrings(szEvent,szBuffer, 257);
    hEvt = LoadLibraryEx(szBuffer, NULL, DONT_RESOLVE_DLL_REFERENCES );
    /* Load the event message file DLL */
    if ( hEvt )
    {
    int i;
    /* Get the event message with the paramater strings inserted */
    lpBuf = GetEventMessage( hEvt, pRecord->EventID,
    MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), lpP );
    if ( lpBuf )
    {
    for(i=0; i {


    if((lpBuf[i]=='<') || (lpBuf[i]=='>'))
    lpBuf[i]='"';
    }

    fprintf(xml, "\n ");
    fprintf(xml,"%s\n",lpBuf);
    //LocalFree( lpBuf );
    fprintf(xml, "
    \n");

    return 1;
    }
    FreeLibrary( hEvt );
    }
    }
    }
    BOOL ReadEventSourceInfo(LPCSTR lpszESName, LPSTR lpszEvent)
    {
    BOOL fResult = FALSE;
    HANDLE hKey;
    LONG lResult;
    DWORD dwBytesReturned;
    TCHAR szKeyName[128];

    /* Find the event source key */
    lstrcpy( szKeyName,
    "System\\CurrentControlSet\\Services\\EventLog\\Security\\" );
    lstrcat( szKeyName, lpszESName );
    if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_ALL_ACCESS,
    &hKey ) != ERROR_SUCCESS )
    {
    lstrcpy( szKeyName,
    "System\\CurrentControlSet\\Services\\EventLog\\System\\" );
    lstrcat( szKeyName, lpszESName );
    if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_ALL_ACCESS,
    &hKey ) != ERROR_SUCCESS )
    {
    lstrcpy( szKeyName,
    "System\\CurrentControlSet\\Services\\EventLog\\application\\" );
    lstrcat( szKeyName, lpszESName );
    if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_ALL_ACCESS,
    &hKey ) != ERROR_SUCCESS )
    {
    goto Exit_ReadEventSourceInfo;
    }
    }
    }
    fResult = TRUE; /* Found the registered event source key */

    dwBytesReturned = 256;
    if ( RegQueryValueEx( hKey, "EventMessageFile", NULL, NULL,
    lpszEvent, &dwBytesReturned ) != ERROR_SUCCESS )
    lpszEvent[0] = '\0';

    Exit_ReadEventSourceInfo:
    return( fResult );
    }

    GeneralRe: Hot to get the description text of an event?
    gino_d_animal
    5:06 11 Mar '04  
    // I needed the description text.  
    // Here is a (hacked) example to print out the full text messages.
    // Compiles on VC71
    ////////////////////////////////////////////////////////////////////
    //
    // Event_Test.cpp : Defines the entry point for the console application.
    //

    #define _WIN32_WINNT 0x0400               //Target NT and greater OS
                       
    #include <iostream>
    #include <tchar.h>
    #include <iostream>
    #include <afx.h>

    using namespace std;

    LPSTR GetString(EVENTLOGRECORD *pRecord,   LPSTR source);
    BOOL ReadEventSourceInfo(LPCSTR lpszESName, LPSTR lpszEvent);
    LPSTR GetEventMessage(
       HMODULE hDll,                  /* Handle to the event message file */
       DWORD   dwEventIndex,      /* Index of the event description message */
       DWORD   dwLanguageID,      /* Language ID of the message to retrieve */
       LPTSTR   *lpInserts );

    int _tmain(int argc, _TCHAR* argv[])
    {
              #define BUFFER_SIZE 40960
              HANDLE h;
              EVENTLOGRECORD *pevlr;
              BYTE bBuffer[BUFFER_SIZE];
              DWORD dwRead, dwNeeded,   dwThisRecord;
              LPSTR     lpmessagetext="";

              // Open the Application event log.     
              h = OpenEventLog( NULL,          // use local computer
                        "System");               // System Log name
              if (h == NULL) {
                   printf("Could not open the System event log.");
                   return 1;
              }
              pevlr = (EVENTLOGRECORD *) &bBuffer;
        
              // Get the record number of the oldest event log record.
              GetOldestEventLogRecord(h, &dwThisRecord);

              // Opening the event log positions the file pointer for this
              // handle 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_BACKWARDS_READ |   // reads from most recent
                             EVENTLOG_SEQUENTIAL_READ, // sequential read
                             0,                  // ignored for sequential reads
                             pevlr,            // pointer to buffer
                             BUFFER_SIZE,   // size of buffer
                             &dwRead,         // number of bytes read
                             &dwNeeded))   // bytes in next record
              {
                   while (dwRead > 0)
                   {
                        printf("%02d   Event ID: %i ",
                            dwThisRecord++, (short)pevlr->EventID);
                        printf("EventType: %d Source: %s\n",
                            pevlr->EventType, (LPSTR) ((LPBYTE) pevlr + sizeof(EVENTLOGRECORD)));

                        lpmessagetext =   GetString(pevlr,   ((LPSTR) ((LPBYTE) pevlr +
                             sizeof(EVENTLOGRECORD))));
                        printf("%s\n", lpmessagetext);
                        dwRead -= pevlr->Length;
                        pevlr = (EVENTLOGRECORD *)
                             ((LPBYTE) pevlr + pevlr->Length);
                   }
                   pevlr = (EVENTLOGRECORD *) &bBuffer;
              }
              CloseEventLog(h);
         return 0;
    }

    LPSTR GetString(EVENTLOGRECORD *pRecord,   LPSTR source)
    {
         BOOL f;
         TCHAR szEvent[256],szBuffer[256], **first_sz;
         HMODULE hEvt;
         LPTSTR lpP[] = { "", "", "", "", "", "","", "", "","", "", "","", "", "","", "", "","", "", ""};
         LPSTR     lpBuf="";
         LPTSTR   lpstrlpBuf = "";
         char* pStr;

         if (pRecord->NumStrings ) {
              pStr = (char*)((LPBYTE)pRecord + pRecord->StringOffset);
         } else {
              pStr = "";
         }

         if ( pStr )
         {
              DWORD i;
              for ( i = 0; i < pRecord->NumStrings; i++ )
              {
                   lpP[i] = (LPSTR)pStr;
                   pStr = strchr( (char*)pStr, '\0' ) + 1;
              }
         }
         //Get the file name(s) from the registry
         f = ReadEventSourceInfo( source, szEvent);
         if(strchr(szEvent, ';'))
         {
              int i=0, j, k, num_files=0, last=0;
              char *aux, *cad;
              aux = szEvent;
              while(aux = strchr(aux, ';'))
              {
                   num_files++;
                   aux++;
              }
              aux = szEvent;

              for(j=0; j<= num_files; j++)
              {
                   int counter =0;
                   while((szEvent[i]!= ';') && i ){
                        i++;
                        counter++;
                   }
                   first_sz= (TCHAR **)malloc(num_files * (sizeof(szEvent)));
                   cad = (char *) malloc(counter+1);
                   for(k = 0; k < counter; k++ ){
                        cad[k] = szEvent[last+k];
                   }
                   cad[counter]= '\0';
                   first_sz[j] = cad;
                   i++;
                   last = i;
                   //Convert the %SystemRoot% stuff
                   ExpandEnvironmentStrings(first_sz[j],szBuffer, 257);

                   //We actually have to load an .exe or what not to read the messages
                   hEvt = LoadLibraryEx(szBuffer, NULL, DONT_RESOLVE_DLL_REFERENCES );

                   /* Load the event message file DLL */
                   if ( hEvt )
                   {
                        /* Get the event message with the paramater strings inserted */
                        lpBuf = GetEventMessage( hEvt, pRecord->EventID,
                             MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), lpP );
                        FreeLibrary( hEvt );
                   }
              }
              return (lpBuf);
         }
         else
         {
              ExpandEnvironmentStrings(szEvent,szBuffer, 257);
              hEvt = LoadLibraryEx(szBuffer, NULL, DONT_RESOLVE_DLL_REFERENCES );
              /* Load the event message file DLL */
              if ( hEvt )
              {
                   /* Get the event message with the paramater strings inserted */
                   lpBuf = GetEventMessage( hEvt, pRecord->EventID,
                        MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), lpP );
                   FreeLibrary( hEvt );
              }
         }
         return (lpBuf);
    }

    //
    BOOL ReadEventSourceInfo(LPCSTR lpszESName, LPSTR lpszEvent)
    {
         BOOL fResult = FALSE;
         HKEY hKey;
         DWORD dwBytesReturned;
         TCHAR szKeyName[128];

         /* Find the event source key */
         lstrcpy( szKeyName,
              "System\\CurrentControlSet\\Services\\EventLog\\Security\\" );
         lstrcat( szKeyName, lpszESName );
         if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_ALL_ACCESS,
              &hKey ) != ERROR_SUCCESS )
         {
              lstrcpy( szKeyName,
                   "System\\CurrentControlSet\\Services\\EventLog\\System\\" );
              lstrcat( szKeyName, lpszESName );
              if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_ALL_ACCESS,
                   &hKey ) != ERROR_SUCCESS )
              {
                   lstrcpy( szKeyName,
                        "System\\CurrentControlSet\\Services\\EventLog\\application\\" );
                   lstrcat( szKeyName, lpszESName );
                   if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_ALL_ACCESS,
                        &hKey ) != ERROR_SUCCESS )
                   {
                        goto Exit_ReadEventSourceInfo;
                   }
              }
         }
         fResult = TRUE; /* Found the registered event source key */

         dwBytesReturned = 256;
         if ( RegQueryValueEx( hKey, "EventMessageFile", NULL, NULL,
              (LPBYTE)lpszEvent, &dwBytesReturned ) != ERROR_SUCCESS )
              lpszEvent[0] = '\0';

    Exit_ReadEventSourceInfo:
         return( fResult );
    }

    //Format the message
    LPSTR GetEventMessage(
       HMODULE hDll,                  /* Handle to the event message file */
       DWORD   dwEventIndex,      /* Index of the event description message */
       DWORD   dwLanguageID,      /* Language ID of the message to retrieve */
       LPTSTR   *lpInserts )         /* Array of insertion strings */
    {
       DWORD   dwReturn;
       LPSTR lpMsgBuf = NULL;
       DWORD   dwFlags = FORMAT_MESSAGE_FROM_HMODULE |
                               FORMAT_MESSAGE_ALLOCATE_BUFFER;

       if ( lpInserts )
          dwFlags |= FORMAT_MESSAGE_ARGUMENT_ARRAY;

       dwReturn = FormatMessage(
          dwFlags,
          hDll,
          dwEventIndex,
          dwLanguageID,
          (LPTSTR) &lpMsgBuf,
          0,
          lpInserts );

       return( lpMsgBuf );
    }

    "Never leave your Wingman!"
    GeneralRe: Hot to get the description text of an event?
    gino_d_animal
    12:10 6 Apr '04  
    For the love of God, close the friggin registry key in the "ReadEventSourceInfo" routine above (unless you like a lot of open handles in your bloated app!)

    Add the following line in the "ReadEventSourceInfo" routine above:

    }
    RegCloseKey(hKey); fResult = TRUE; /* Found the registered event source key */


    "Never leave your Wingman!" WTF
    GeneralRe: Hot to get the description text of an event?
    Brooks Younce
    4:45 14 May '05  
    //found memory was not being free'ed in the example code provided, here is some that works, and I have tested it good. and the loop for the multiple dll's works also (a bug in the example code)
    //CEventView is the name of my custom MFC class in case your wondering

    void CEventView::DisplayEntries()
    {
    HANDLE h;
    EVENTLOGRECORD *pevlr;
    BYTE bBuffer[1024];
    DWORD dwRead, dwNeeded, dwThisRecord;
    LPSTR lpmessagetext = "";

    // Open the Application event log.

    h = OpenEventLog( ".", // use local computer
    "System"); // source name
    if (h == NULL)
    {TRACE("ERROR COULD NOT OPEN LOG FILE\n");}
    // ErrorExit("Could not open the Application event log.");


    pevlr = (EVENTLOGRECORD *) &bBuffer;

    // Get the record number of the oldest event log record.

    GetOldestEventLogRecord(h, &dwThisRecord);


    // Opening the event log positions the file pointer for this
    // handle at the beginning of the log. Read the event log records
    // sequentially until the last record has been read.
    TRACE("\n");

    while (ReadEventLog(h, // event log handle
    EVENTLOG_FORWARDS_READ | // reads forward
    EVENTLOG_SEQUENTIAL_READ, // sequential read
    0, // ignored for sequential reads
    pevlr, // pointer to buffer
    1024, // size of buffer
    &dwRead, // number of bytes read
    &dwNeeded)) // bytes in next record
    {
    while (dwRead > 0)
    {
    // Print the record number, event identifier, type,
    // and source name.

    lpmessagetext = GetString(pevlr, ((LPSTR) ((LPBYTE) pevlr +
    sizeof(EVENTLOGRECORD))));
    TRACE("-------------------\n");
    TRACE("MSG: %s\n",lpmessagetext);
    TRACE("%02d Event ID: 0x%08X ",
    dwThisRecord++, pevlr->EventID);
    TRACE("EventType: %d Source: %s\n",
    pevlr->EventType, (LPSTR) ((LPBYTE) pevlr +
    sizeof(EVENTLOGRECORD)));
    TRACE("-------------------\n");

    dwRead -= pevlr->Length;
    pevlr = (EVENTLOGRECORD *)
    ((LPBYTE) pevlr + pevlr->Length);
    }

    pevlr = (EVENTLOGRECORD *) &bBuffer;
    }

    CloseEventLog(h);
    }

    LPSTR CEventView::GetString(EVENTLOGRECORD *pRecord, LPSTR source)
    {
    BOOL f;
    TCHAR szEvent[256],szBuffer[256];//, **first_sz;
    ZeroMemory(szEvent,256);
    ZeroMemory(szBuffer,256);
    HMODULE hEvt;
    LPTSTR lpP[] = { "", "", "", "", "", "","", "", "","", "", "","", "", "","", "", "","", "", ""};
    LPSTR lpBuf="";
    LPTSTR lpstrlpBuf = "";
    char* pStr;

    if (pRecord->NumStrings ) {
    pStr = (char*)((LPBYTE)pRecord + pRecord->StringOffset);
    } else {
    pStr = "";
    }

    if ( pStr )
    {
    DWORD i;
    for ( i = 0; i < pRecord->NumStrings; i++ )
    {
    lpP[i] = (LPSTR)pStr;
    pStr = strchr( (char*)pStr, '\0' ) + 1;
    }
    }
    //Get the file name(s) from the registry
    f = ReadEventSourceInfo( source, szEvent);
    if(strchr(szEvent, ';'))//we have more than 1 dll to resolve
    {
    CStringArray array;
    CString sEntry;
    CString s = szEvent;
    s += ";";
    int iLast=0,iCur=0;
    while(iLast != -1)
    {
    iLast = s.Find(';',iCur);
    if(iLast == -1){break;}
    sEntry = s.Mid(iCur,iLast-iCur);
    array.Add(sEntry);
    iCur=iLast+1;
    }

    for(int i=0; i {
    ExpandEnvironmentStrings(array[i],szBuffer, 257);
    hEvt = LoadLibraryEx(szBuffer, NULL, DONT_RESOLVE_DLL_REFERENCES );
    /* Load the event message file DLL */
    if ( hEvt )
    {
    /* Get the event message with the paramater strings inserted */
    lpBuf = GetEventMessage( hEvt, pRecord->EventID,
    MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), lpP );
    FreeLibrary( hEvt );
    return (lpBuf);
    }
    }
    }
    else
    {
    ExpandEnvironmentStrings(szEvent,szBuffer, 257);
    hEvt = LoadLibraryEx(szBuffer, NULL, DONT_RESOLVE_DLL_REFERENCES );
    // Load the event message file DLL
    if ( hEvt )
    {
    // Get the event message with the paramater strings inserted
    lpBuf = GetEventMessage( hEvt, pRecord->EventID,
    MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), lpP );
    FreeLibrary( hEvt );
    }
    }

    return (lpBuf);
    }

    //
    BOOL CEventView::ReadEventSourceInfo(LPCSTR lpszESName, LPSTR lpszEvent)
    {
    BOOL fResult = FALSE;
    HKEY hKey;
    DWORD dwBytesReturned;
    TCHAR szKeyName[128];

    /* Find the event source key */
    lstrcpy( szKeyName,
    "System\\CurrentControlSet\\Services\\EventLog\\Security\\" );
    lstrcat( szKeyName, lpszESName );
    if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_ALL_ACCESS,
    &hKey ) != ERROR_SUCCESS )
    {
    lstrcpy( szKeyName,
    "System\\CurrentControlSet\\Services\\EventLog\\System\\" );
    lstrcat( szKeyName, lpszESName );
    if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_ALL_ACCESS,
    &hKey ) != ERROR_SUCCESS )
    {
    lstrcpy( szKeyName,
    "System\\CurrentControlSet\\Services\\EventLog\\application\\" );
    lstrcat( szKeyName, lpszESName );
    if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_ALL_ACCESS,
    &hKey ) != ERROR_SUCCESS )
    {
    goto Exit_ReadEventSourceInfo;
    }
    }
    }
    fResult = TRUE; /* Found the registered event source key */

    dwBytesReturned = 256;
    if ( RegQueryValueEx( hKey, "EventMessageFile", NULL, NULL,
    (LPBYTE)lpszEvent, &dwBytesReturned ) != ERROR_SUCCESS )
    lpszEvent[0] = '\0';

    Exit_ReadEventSourceInfo:
    RegCloseKey(hKey);
    return( fResult );
    }

    //Format the message
    LPSTR CEventView::GetEventMessage(
    HMODULE hDll, /* Handle to the event message file */
    DWORD dwEventIndex, /* Index of the event description message */
    DWORD dwLanguageID, /* Language ID of the message to retrieve */
    LPTSTR *lpInserts ) /* Array of insertion strings */
    {
    DWORD dwReturn;
    LPSTR lpMsgBuf = NULL;
    DWORD dwFlags = FORMAT_MESSAGE_FROM_HMODULE |
    FORMAT_MESSAGE_ALLOCATE_BUFFER;

    if ( lpInserts )
    dwFlags |= FORMAT_MESSAGE_ARGUMENT_ARRAY;

    dwReturn = FormatMessage(
    dwFlags,
    hDll,
    dwEventIndex,
    dwLanguageID,
    (LPTSTR) &lpMsgBuf,
    0,
    lpInserts );

    return( lpMsgBuf );
    }

    GeneralRe: Hot to get the description text of an event?
    Torben_Surmer
    23:39 7 Nov '05  
    Do somone try to run the code for the "security-log"? I got: "Run-Time Check Failure #2 - Stack around the variable 'lpP' was corrupted."

    Any idea, what causes the problem?


    Here is the code:
    >>>> #include #include
    #define BUFFER_SIZE 1024*64

    static char g_szLogfile[80];

    BOOL ReadEventSourceInfo(LPCSTR lpszESName, LPSTR lpszEvent) ;


    LPSTR GetEventMessage(
    HMODULE hDll, /* Handle to the event message file */
    DWORD dwEventIndex, /* Index of the event description message */
    DWORD dwLanguageID, /* Language ID of the message to retrieve */
    LPTSTR *lpInserts ) /* Array of insertion strings */
    {
    DWORD dwReturn;
    LPSTR lpMsgBuf = NULL;
    DWORD dwFlags = FORMAT_MESSAGE_FROM_HMODULE |
    FORMAT_MESSAGE_ALLOCATE_BUFFER;

    if ( lpInserts )
    dwFlags |= FORMAT_MESSAGE_ARGUMENT_ARRAY;

    dwReturn = FormatMessage(
    dwFlags,
    hDll,
    dwEventIndex,
    dwLanguageID,
    (LPTSTR) &lpMsgBuf,
    0,
    lpInserts );
    return( lpMsgBuf );
    }
    LPSTR GetStringEx(EVENTLOGRECORD *pRecord, LPSTR source)
    {
    BOOL f;
    TCHAR szEvent[256],szBuffer[256], **first_sz;
    HMODULE hEvt;
    LPTSTR lpP[] = { "", "", "", "", "", "","", "", "","", "", "","", "", "","", "", "","", "", ""};
    LPSTR lpBuf="";
    LPTSTR lpstrlpBuf = "";
    char* pStr;

    if (pRecord->NumStrings ) {
    pStr = (char*)((LPBYTE)pRecord + pRecord->StringOffset);
    } else {
    pStr = "";
    }

    if ( pStr )
    {
    DWORD i;
    for ( i = 0; i < pRecord->NumStrings; i++ )
    {
    lpP[i] = (LPSTR)pStr;
    pStr = strchr( (char*)pStr, '\0' ) + 1;
    }
    }
    //Get the file name(s) from the registry
    f = ReadEventSourceInfo( source, szEvent);
    if(strchr(szEvent, ';'))
    {
    int i=0, j, k, num_files=0, last=0;
    char *aux, *cad;
    aux = szEvent;
    while(aux = strchr(aux, ';'))
    {
    num_files++;
    aux++;
    }
    aux = szEvent;

    for(j=0; j<= num_files; j++)
    {
    int counter =0;
    while((szEvent[i]!= ';') && i ){
    i++;
    counter++;
    }
    first_sz= (TCHAR **)malloc(num_files * (sizeof(szEvent)));
    cad = (char *) malloc(counter+1);
    for(k = 0; k < counter; k++ ){
    cad[k] = szEvent[last+k];
    }
    cad[counter]= '\0';
    first_sz[j] = cad;
    i++;
    last = i;
    //Convert the %SystemRoot% stuff
    ExpandEnvironmentStrings(first_sz[j],szBuffer, 257);

    //We actually have to load an .exe or what not to read the messages
    hEvt = LoadLibraryEx(szBuffer, NULL, DONT_RESOLVE_DLL_REFERENCES );

    /* Load the event message file DLL */
    if ( hEvt )
    {
    /* Get the event message with the paramater strings inserted */
    lpBuf = GetEventMessage( hEvt, pRecord->EventID,
    MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), lpP );
    FreeLibrary( hEvt );
    }
    }
    return (lpBuf);
    }
    else
    {
    ExpandEnvironmentStrings(szEvent,szBuffer, 257);
    hEvt = LoadLibraryEx(szBuffer, NULL, DONT_RESOLVE_DLL_REFERENCES );
    /* Load the event message file DLL */
    if ( hEvt )
    {
    /* Get the event message with the paramater strings inserted */
    lpBuf = GetEventMessage( hEvt, pRecord->EventID,
    MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), lpP );
    FreeLibrary( hEvt );
    }
    }
    return (lpBuf);
    }

    BOOL ReadEventSourceInfo(LPCSTR lpszESName, LPSTR lpszEvent)
    {
    BOOL fResult = FALSE;
    HANDLE hKey;
    LONG lResult;
    DWORD dwBytesReturned;
    TCHAR szKeyName[128];

    /* Find the event source key */
    lstrcpy( szKeyName,
    "System\\CurrentControlSet\\Services\\EventLog\\Security\\" );
    lstrcat( szKeyName, lpszESName );

    if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_ALL_ACCESS,
    &hKey ) != ERROR_SUCCESS )
    {
    lstrcpy( szKeyName,
    "System\\CurrentControlSet\\Services\\EventLog\\System\\" );
    lstrcat( szKeyName, lpszESName );

    if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_ALL_ACCESS,
    &hKey ) != ERROR_SUCCESS )
    {
    lstrcpy( szKeyName,
    "System\\CurrentControlSet\\Services\\EventLog\\application\\" );
    lstrcat( szKeyName, lpszESName );

    if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_ALL_ACCESS,
    &hKey ) != ERROR_SUCCESS )
    {
    goto Exit_ReadEventSourceInfo;
    }
    }
    }

    fResult = TRUE; /* Found the registered event source key */
    dwBytesReturned = 256;
    if ( RegQueryValueEx( hKey, "EventMessageFile", NULL, NULL,
    lpszEvent, &dwBytesReturned ) != ERROR_SUCCESS )
    lpszEvent[0] = '\0';

    Exit_ReadEventSourceInfo:
    return( fResult );
    }




    void DisplayEntries( )
    {
    HANDLE h;
    EVENTLOGRECORD *pevlr;
    BYTE bBuffer[BUFFER_SIZE];
    DWORD dwRead, dwNeeded, dwThisRecord;
    LPSTR lpmessagetext = "";
    char* pStr;
    LPTSTR lpP[] = { "", "", "", "", "", "","", "", "","", "", "","", "", "","", "", "","", "", ""};

    // Open the Application event log.

    h = OpenEventLog( NULL, // use local computer
    g_szLogfile); // source name
    if (h == NULL)
    {
    printf("Could not open the Application event log.");
    return;
    }

    pevlr = (EVENTLOGRECORD *) &bBuffer;

    // Get the record number of the oldest event log record.

    GetOldestEventLogRecord(h, &dwThisRecord);

    // Opening the event log positions the file pointer for this
    // handle 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 reads
    pevlr, // pointer to buffer
    BUFFER_SIZE, // size of buffer
    &dwRead, // number of bytes read
    &dwNeeded)) // bytes in next record
    {
    while (dwRead > 0)
    {
    // Print the record number, event identifier, type,
    // and source name.
    lpmessagetext = GetStringEx(pevlr, ((LPSTR) ((LPBYTE) pevlr +
    sizeof(EVENTLOGRECORD))));
    printf("Event source/text/num: [%s]/[%s]/[%d]\n",
    (LPSTR) ((LPBYTE) pevlr + sizeof(EVENTLOGRECORD)), lpmessagetext,
    pevlr->NumStrings);

    if (pevlr->NumStrings ) {
    pStr = (char*)((LPBYTE)pevlr + pevlr->StringOffset);
    } else {
    pStr = "";
    }

    if ( pStr )
    {
    DWORD i;
    for ( i = 0; i < pevlr->NumStrings; i++ )
    {
    lpP[i] = (LPSTR)pStr;
    pStr = strchr( (char*)pStr, '\0' ) + 1;
    printf("--> [%s]\n", pStr);
    }
    }
    dwRead -= pevlr->Length;
    pevlr = (EVENTLOGRECORD *)
    ((LPBYTE) pevlr + pevlr->Length);
    }

    pevlr = (EVENTLOGRECORD *) &bBuffer;
    }

    CloseEventLog(h);
    }

    int main(int argc, char * argv[])
    {
    if (argc!=2)
    {
    printf("%s [logfile]\n", argv[0]);
    exit (0);
    }
    strcpy(g_szLogfile, argv[1]);


    DisplayEntries();
    return 1;
    }

    #if 0
    LPSTR GetString(EVENTLOGRECORD *pRecord, LPSTR source)
    {
    BOOL f;
    TCHAR szEvent[256],szBuffer[256];//, **first_sz;
    ZeroMemory(szEvent,256);
    ZeroMemory(szBuffer,256);
    HMODULE hEvt;
    LPTSTR lpP[] = { "", "", "", "", "", "","", "", "","", "", "","", "", "","", "", "","", "", ""};
    LPSTR lpBuf="";
    LPTSTR lpstrlpBuf = "";
    char* pStr;

    if (pRecord->NumStrings ) {
    pStr = (char*)((LPBYTE)pRecord + pRecord->StringOffset);
    } else {
    pStr = "";
    }

    if ( pStr )
    {
    DWORD i;
    for ( i = 0; i < pRecord->NumStrings; i++ )
    {
    lpP[i] = (LPSTR)pStr;
    pStr = strchr( (char*)pStr, '\0' ) + 1;
    }
    }
    //Get the file name(s) from the registry
    f = ReadEventSourceInfo( source, szEvent);
    if(strchr(szEvent, ';'))//we have more than 1 dll to resolve
    {
    CStringArray array;
    CString sEntry;
    CString s = szEvent;
    s += ";";
    int iLast=0,iCur=0;
    while(iLast != -1)
    {
    iLast = s.Find(';',iCur);
    if(iLast == -1){break;}
    sEntry = s.Mid(iCur,iLast-iCur);
    array.Add(sEntry);
    iCur=iLast+1;
    }
    for(int i=0; i
    {
    ExpandEnvironmentStrings(array[i],szBuffer, 257);
    hEvt = LoadLibraryEx(szBuffer, NULL, DONT_RESOLVE_DLL_REFERENCES );
    /* Load the event message file DLL */
    if ( hEvt )
    {
    /* Get the event message with the paramater strings inserted */
    lpBuf = GetEventMessage( hEvt, pRecord->EventID,
    MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), lpP );
    FreeLibrary( hEvt );
    return (lpBuf);
    }
    }
    }
    else
    {
    ExpandEnvironmentStrings(szEvent,szBuffer, 257);
    hEvt = LoadLibraryEx(szBuffer, NULL, DONT_RESOLVE_DLL_REFERENCES );
    // Load the event message file DLL
    if ( hEvt )
    {
    // Get the event message with the paramater strings inserted
    lpBuf = GetEventMessage( hEvt, pRecord->EventID,
    MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), lpP );
    FreeLibrary( hEvt );
    }
    }
    return (lpBuf);
    }
    #endif

    <<<< End code



    Last Updated 1 Dec 1999 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2010