home *** CD-ROM | disk | FTP | other *** search
/ Softwarová Záchrana 3 / Softwarova-zachrana-3.bin / pserv.cpl / pserv-2.4.exe / source / ceventlog.cpp < prev    next >
C/C++ Source or Header  |  2005-01-05  |  12KB  |  389 lines

  1. #include "stdafx.h"
  2. #include "resource.h"
  3. #include "CEventLog.h"
  4. #include "CConfiguration.h"
  5.  
  6. CEventSource::CEventSource( LPCTSTR name, LPCTSTR type )
  7.     :   m_strName( name ),
  8.         m_hFile(0)
  9. {
  10.     HKEY hKey;
  11.  
  12.     LONG lResult = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  13.                         FormattedString(_T("SYSTEM\\CurrentControlSet\\Services\\Eventlog\\%s\\%s"), type, name),
  14.                         0,
  15.                         KEY_READ,
  16.                         &hKey );
  17.     if( lResult == 0 )
  18.     {
  19.         BYTE bMaxData[1024*sizeof(TCHAR)];
  20.         DWORD dwData = sizeof(bMaxData), dwType;
  21.  
  22.         if( RegQueryValueEx(hKey,_T("EventMessageFile"),0,&dwType,bMaxData,&dwData ) == 0 )
  23.         {
  24.             if( dwType == REG_SZ || dwType == REG_EXPAND_SZ )
  25.             {
  26.                 TCHAR expanded[1024];
  27.  
  28.                 // BUG BUG BUG 
  29.                 VERIFY( ExpandEnvironmentStrings((LPCTSTR) bMaxData, expanded, sizeof(expanded)) );
  30.  
  31.                 m_strFile = expanded;
  32.             }
  33.         }
  34.         RegCloseKey(hKey);
  35.     }
  36.     if( !IsEmptyString(m_strFile) )
  37.     {
  38.         m_hFile = LoadLibraryEx(m_strFile, 0, LOAD_LIBRARY_AS_DATAFILE);
  39.         
  40.     }
  41. }
  42.  
  43. CEventSource::~CEventSource()
  44. {
  45.     if(m_hFile)
  46.         FreeLibrary(HMODULE(m_hFile));
  47. }
  48.  
  49. BOOL CEventSource::IsValid()
  50. {
  51.     if( !this )
  52.         return FALSE;
  53.  
  54.     if( IsEmptyString(m_strFile) )
  55.         return FALSE;
  56.  
  57.     if( !m_hFile )
  58.         return FALSE;
  59.  
  60.     return TRUE;
  61. }
  62.  
  63. CString GetTimeAsString(DWORD dwSeconds)
  64. {
  65.     FILETIME FileTime, LocalFileTime;
  66.     SYSTEMTIME SysTime;
  67.     __int64 lgTemp;
  68.     __int64 SecsTo1970 = 116444736000000000;
  69.  
  70.     lgTemp = Int32x32To64(dwSeconds,10000000) + SecsTo1970;
  71.  
  72.     FileTime.dwLowDateTime = (DWORD) lgTemp;
  73.     FileTime.dwHighDateTime = (DWORD)(lgTemp >> 32);
  74.  
  75.     FileTimeToLocalFileTime(&FileTime, &LocalFileTime);
  76.     FileTimeToSystemTime(&LocalFileTime, &SysTime);
  77.  
  78.  
  79.  
  80.     TCHAR szDate[256], szTime[256];
  81.     VERIFY( GetDateFormat( LOCALE_USER_DEFAULT, DATE_SHORTDATE, &SysTime, NULL, szDate, sizeof(szDate)/sizeof(TCHAR) ) );
  82.     VERIFY( GetTimeFormat( LOCALE_USER_DEFAULT, 0, &SysTime, NULL, szTime, sizeof(szTime)/sizeof(TCHAR) ) );
  83.     return FormattedString(_T("%s %s"), szDate, szTime );
  84. }
  85.  
  86. CString CEventEntry::GetDisplayString(DWORD dwIndex)
  87. {
  88.     switch(dwIndex)
  89.     {
  90.     case 0: return m_strShortText;
  91.     case 1: return m_strSourceName;
  92.     case 2: return m_strEventType;
  93.     case 3: return m_strTimeWritten;
  94.     case 4: return m_strComputerName;
  95.     case 5: return m_strSourceDll;
  96.     case 6: return m_strEventCategory;
  97.     case 7: return m_strUsername;
  98.     case 8: return m_strTimeGenerated;
  99.     case 9: return m_strRecordNumber;
  100.     case 10: return m_strClosingRecordNumber;
  101.     }
  102.     return CString();
  103. }
  104.  
  105. COLORREF CEventEntry::GetTextColor()
  106. {
  107.     if( (m_Record.EventType == EVENTLOG_ERROR_TYPE) || 
  108.         (m_Record.EventType == EVENTLOG_AUDIT_FAILURE) )
  109.     {
  110.         return RGB(255, 0, 0);
  111.     }
  112.     else if(m_Record.EventType == EVENTLOG_WARNING_TYPE)
  113.     {
  114.         return RGB(140, 140, 0);
  115.     }
  116.     else if(m_Record.EventType == EVENTLOG_INFORMATION_TYPE)
  117.     {
  118.         return RGB(0, 0, 0);
  119.     }
  120.     else if(m_Record.EventType == EVENTLOG_INFORMATION_TYPE)
  121.     {
  122.         return RGB(0, 200, 0);
  123.     }
  124.     return RGB(0, 0, 0);
  125. }
  126.  
  127. CString CEventEntry::GetInfoTip()
  128. {
  129.     return m_strDescription;
  130. }
  131.  
  132. CString CEventEntry::GetEventTypeAsString(DWORD dwEventType)
  133. {
  134.     switch(dwEventType)
  135.     {
  136.     case EVENTLOG_SUCCESS:
  137.         return _T("Success");
  138.     case EVENTLOG_ERROR_TYPE:    
  139.         return _T("Error");
  140.     case EVENTLOG_WARNING_TYPE:    
  141.         return _T("Warning");
  142.     case EVENTLOG_INFORMATION_TYPE:    
  143.         return _T("Information");
  144.     case EVENTLOG_AUDIT_SUCCESS:        
  145.         return _T("Audit success");
  146.     case EVENTLOG_AUDIT_FAILURE:        
  147.         return _T("Audit failure");
  148.     }
  149.     CString result;
  150.     result.Format(_T("<INVALID: 0x%08lx>"), dwEventType );
  151.     return result;
  152. }
  153.  
  154. CEventEntry::CEventEntry( CEventLog* parent, PEVENTLOGRECORD entry )
  155. {
  156.     m_strTimeWritten = GetTimeAsString( entry->TimeWritten );    
  157.     m_strEventType = GetEventTypeAsString(entry->EventType);
  158.     m_strEventCategory.Format(_T("%hd"), entry->EventCategory );
  159.  
  160.     m_Record = *entry;
  161.  
  162.     LPCTSTR p = LPCTSTR((LPBYTE(&entry->DataOffset) + sizeof(DWORD)));
  163.     m_strSourceName = p;
  164.  
  165.     p += lstrlen(p) +1;
  166.     m_strComputerName = p;
  167.  
  168.     p += lstrlen(p) +1;
  169.  
  170.     p = (LPCTSTR)( LPBYTE(entry) + entry->StringOffset);
  171.  
  172.     LPCTSTR* Strings = new LPCTSTR[entry->NumStrings+1];
  173.     for( int i = 0; i < entry->NumStrings; i++ )
  174.     {
  175.         if( !IsEmptyString(p) && IsEmptyString(m_strDescription) )
  176.             m_strDescription = p;
  177.         m_strStrings.Add(p);
  178.         Strings[i] = m_strStrings.GetAt(i);
  179.         p += lstrlen(p)+1;
  180.     }
  181.     Strings[i] = NULL;
  182.  
  183.  
  184.     if( entry->UserSidLength )
  185.     {
  186.         m_strUsername = GetUsernameFromSid((PSID)( LPBYTE(entry) + entry->UserSidOffset));
  187.     }
  188.     m_strTimeGenerated = GetTimeAsString( entry->TimeGenerated );
  189.     m_strRecordNumber.Format(_T("%ld"), entry->RecordNumber );
  190.     m_strClosingRecordNumber.Format(_T("%ld"), entry->ClosingRecordNumber );
  191.  
  192.     // SID   UserSid
  193.     // BYTE  Data[]
  194.  
  195.     CEventSource* pest = parent->GetEventSource(m_strSourceName);
  196.     if( pest )
  197.     {
  198.         m_strSourceDll = pest->m_strFile;
  199.         LPTSTR lpszBuffer;
  200.         if( FormatMessage(
  201.           FORMAT_MESSAGE_ALLOCATE_BUFFER | 
  202.           FORMAT_MESSAGE_FROM_HMODULE | 
  203.           FORMAT_MESSAGE_FROM_SYSTEM | 
  204.           FORMAT_MESSAGE_ARGUMENT_ARRAY,
  205.           pest->m_hFile, entry->EventID, 0, (LPTSTR)&lpszBuffer, 0, 
  206.           (va_list*) Strings
  207.         ) )
  208.         {
  209.             m_strDescription = lpszBuffer;
  210.             LocalFree(HLOCAL(lpszBuffer));
  211.         }
  212.     }
  213.     delete Strings;
  214.     m_strShortText = m_strDescription;
  215.     m_strShortText.Replace(TEXT("\r\n"), TEXT(" "));
  216.      
  217. }
  218.  
  219. #define SORT_BY_STRING(NAME)                                            \
  220. int SortBy##NAME(const CEventEntry** ps1, const CEventEntry** ps2)      \
  221. {                                                                       \
  222.     return (*ps1)->m_str##NAME.CompareNoCase((*ps2)->m_str##NAME);      \
  223. }
  224.  
  225. SORT_BY_STRING(ShortText)
  226. SORT_BY_STRING(SourceName)
  227. SORT_BY_STRING(EventType)
  228. SORT_BY_STRING(ComputerName)
  229. SORT_BY_STRING(SourceDll)
  230. SORT_BY_STRING(EventCategory)
  231. SORT_BY_STRING(Username)
  232.  
  233. #define SORT_BY_INTEGER(NAME)                                           \
  234. int SortBy##NAME(const CEventEntry** ps1, const CEventEntry** ps2)      \
  235. {                                                                       \
  236.     return LONG((*ps1)->m_Record.NAME)-LONG((*ps2)->m_Record.NAME);     \
  237. }
  238.  
  239. SORT_BY_INTEGER(TimeGenerated)
  240. SORT_BY_INTEGER(TimeWritten)
  241. SORT_BY_INTEGER(RecordNumber)
  242. SORT_BY_INTEGER(ClosingRecordNumber)
  243.  
  244. static GENERICCOMPAREFN SortMethods[] = {
  245.     GENERICCOMPAREFN(&SortByShortText),
  246.     GENERICCOMPAREFN(&SortBySourceName),
  247.     GENERICCOMPAREFN(&SortByEventType),
  248.     GENERICCOMPAREFN(&SortByTimeWritten),
  249.     GENERICCOMPAREFN(&SortByComputerName),
  250.     GENERICCOMPAREFN(&SortBySourceDll),
  251.     GENERICCOMPAREFN(&SortByEventCategory),
  252.     GENERICCOMPAREFN(&SortByUsername),
  253.     GENERICCOMPAREFN(&SortByTimeGenerated),
  254.     GENERICCOMPAREFN(&SortByRecordNumber),
  255.     GENERICCOMPAREFN(&SortByClosingRecordNumber),
  256. };
  257.  
  258. CEventLog::CEventLog()
  259.     :   CListViewEntries(SortMethods, _T("EventLog") ),
  260.         m_strLogName( _T("System") )
  261. {
  262.     CreateColumns( _T("Event"), _T("Source"), _T("Type"), _T("Written"), _T("Machine"), _T("DLL"), _T("Category"), 
  263.         _T("Username"), _T("Generated"), _T("Record Nr."), _T("Closing Nr."), NULL );
  264. }
  265.  
  266. BOOL CEventLog::Refresh()
  267. {
  268.     RefreshTitleString();
  269.  
  270.     HANDLE hLog = OpenEventLog(m_strServiceMachine, m_strLogName);
  271.     if( !hLog )
  272.         return FALSE;
  273.  
  274.     DeleteObjects(m_Entries);
  275.  
  276.     #define BUFFER_SIZE 1024*64
  277.  
  278.     BYTE bBuffer[BUFFER_SIZE]; 
  279.     DWORD dwRead, dwNeeded /*, dwThisRecord*/; 
  280.  
  281.     PEVENTLOGRECORD pevlr = PEVENTLOGRECORD(bBuffer); 
  282.  
  283.     // Get the record number of the oldest event log record.
  284.     //VERIFY(GetOldestEventLogRecord(hLog, &dwThisRecord));
  285.  
  286.     // Opening the event log positions the file pointer for this 
  287.     // handle at the beginning of the log. Read the event log records 
  288.     // sequentially until the last record has been read. 
  289.  
  290.     while (ReadEventLog(hLog,                // event log handle 
  291.                 EVENTLOG_BACKWARDS_READ |  // reads forward 
  292.                 EVENTLOG_SEQUENTIAL_READ, // sequential read 
  293.                 0,            // ignored for sequential reads 
  294.                 pevlr,        // pointer to buffer 
  295.                 BUFFER_SIZE,  // size of buffer 
  296.                 &dwRead,      // number of bytes read 
  297.                 &dwNeeded))   // bytes in next record 
  298.     {
  299.         while (dwRead > 0) 
  300.         { 
  301.             m_Entries.Add(new CEventEntry(this, pevlr));
  302.             dwRead -= pevlr->Length; 
  303.             pevlr = (EVENTLOGRECORD *) ((LPBYTE) pevlr + pevlr->Length); 
  304.         } 
  305.         pevlr = (EVENTLOGRECORD *) &bBuffer; 
  306.     } 
  307.     VERIFY(CloseEventLog(hLog));
  308.  
  309.     // needed only during enumeration 
  310.     DeleteObjects(m_EventSources);
  311.  
  312.     return TRUE;
  313. }
  314.  
  315. void CEventLog::SetEnumType( LPCTSTR lpszType )
  316. {
  317.     m_strLogName = lpszType;
  318. }
  319.  
  320.  
  321. CEventSource* CEventLog::GetEventSource(LPCTSTR name)
  322. {
  323.     for( int nIndex = 0, nElements = m_EventSources.GetSize(); nIndex < nElements; nIndex++ )
  324.     {                                         
  325.         CEventSource* source = (CEventSource*) m_EventSources.GetAt(nIndex);
  326.         if( source->m_strName.CompareNoCase(name) == 0 )
  327.         {
  328.             return source;
  329.         }
  330.     }
  331.  
  332.     CEventSource* s = new CEventSource(name, m_strLogName);
  333.     if( s->IsValid() )
  334.     {
  335.         m_EventSources.Add(s);
  336.         return s;
  337.     }
  338.     delete s;
  339.     return NULL;
  340. }
  341.  
  342.  
  343. void CEventLog::ConnectTo( LPCTSTR lpszMachine )
  344. {
  345.     m_strServiceMachine = lpszMachine;
  346.     RefreshTitleString();
  347. }
  348.  
  349. void CEventLog::RefreshTitleString()
  350. {
  351.     LPCTSTR lpszMachine = m_strServiceMachine;
  352.     if( !lpszMachine || !*lpszMachine )
  353.     {
  354.         m_strTitle.Format( TEXT("pserv ") CURRENT_VERSION TEXT(": %s events on local machine"), (LPCTSTR) m_strLogName );
  355.     }
  356.     else
  357.     {
  358.         m_strTitle.Format( TEXT("pserv ") CURRENT_VERSION TEXT(": %s events on \\\\%s"), (LPCTSTR) m_strLogName, (LPCTSTR)m_strServiceMachine  );
  359.     }
  360. }
  361.  
  362. UINT CEventLog::GetContextMenuID()
  363. {
  364.     return IDR_CONTEXTMENU_EVENTS;
  365. }
  366.  
  367. void CEventLog::ExportXmlToFile( CFile* pFile )
  368. {
  369.     PrintToFile(pFile, _T("<?xml version=\"1.0\" encoding=\"ISO-8859-1\" standalone=\"yes\"?>\r\n")
  370.               _T("<%s>\r\n"), (LPCTSTR) m_strLogName );
  371.  
  372.     for(int n = 0, nmax = m_Entries.GetSize(); n < nmax; n++ )
  373.     {
  374.         CEventEntry* p = (CEventEntry*)m_Entries.GetAt(n);
  375.         PrintToFile(pFile, _T("\t<entry id=\"%ld\">\r\n"), p->m_Record.RecordNumber );
  376.         PrintToFile(pFile, _T("\t\t<event>%s</event>\r\n"),(LPCTSTR)  XmlEscape(p->m_strDescription) );
  377.         PrintToFile(pFile, _T("\t\t<timewritten>%s</timewritten>\r\n"), (LPCTSTR) XmlEscape(p->m_strTimeWritten) );
  378.         PrintToFile(pFile, _T("\t\t<source>%s</source>\r\n"),(LPCTSTR)  XmlEscape(p->m_strSourceName) );
  379.         PrintToFile(pFile, _T("\t\t<eventtype>%s</eventtype>\r\n"),(LPCTSTR)  XmlEscape(p->m_strEventType) );
  380.         PrintToFile(pFile, _T("\t\t<computername>%s</computername>\r\n"),(LPCTSTR)  XmlEscape(p->m_strComputerName) );
  381.         PrintToFile(pFile, _T("\t\t<sourcedll>%s</sourcedll>\r\n"),(LPCTSTR)  XmlEscape(p->m_strSourceDll) );
  382.         PrintToFile(pFile, _T("\t\t<category>%s</category>\r\n"),(LPCTSTR)  XmlEscape(p->m_strEventCategory) );
  383.         PrintToFile(pFile, _T("\t</entry>\r\n") );
  384.     }
  385.  
  386.     PrintToFile(pFile, _T("</%s>"), (LPCTSTR) m_strLogName);
  387. }
  388.  
  389.