Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

299 lines
7.2 KiB

/*++
Copyright (C) 1996-2001 Microsoft Corporation
Module Name:
EVTLOG.CPP
Abstract:
Event Log helpers
History:
--*/
#include "precomp.h"
#include <stdio.h>
#include <wbemcomn.h>
#include "CWbemTime.h"
#include <evtlog.h>
#include <genutils.h>
CInsertionString::CInsertionString(long l) : m_bEmpty(FALSE)
{
WCHAR wsz[100];
swprintf(wsz, L"%d", l);
m_ws = wsz;
}
CInsertionString::CInsertionString(CHex h) : m_bEmpty(FALSE)
{
WCHAR wsz[100];
swprintf(wsz, L"0x%x", (long)h);
m_ws = wsz;
}
CEventLogRecord::CEventLogRecord(WORD wType, DWORD dwEventID,
CInsertionString s1,
CInsertionString s2,
CInsertionString s3,
CInsertionString s4,
CInsertionString s5,
CInsertionString s6,
CInsertionString s7,
CInsertionString s8,
CInsertionString s9,
CInsertionString s10)
{
m_wType = wType;
m_dwEventID = dwEventID;
m_CreationTime = CWbemTime::GetCurrentTime();
AddInsertionString(s10);
AddInsertionString(s9);
AddInsertionString(s8);
AddInsertionString(s7);
AddInsertionString(s6);
AddInsertionString(s5);
AddInsertionString(s4);
AddInsertionString(s3);
AddInsertionString(s2);
AddInsertionString(s1);
}
void CEventLogRecord::AddInsertionString(CInsertionString& s)
{
if(!s.IsEmpty() || m_awsStrings.Size() > 0)
m_awsStrings.InsertAt(0, s.GetString());
}
LPCWSTR CEventLogRecord::GetStringAt(int nIndex)
{
if(nIndex >= m_awsStrings.Size())
return NULL;
else
return m_awsStrings[nIndex];
}
BOOL CEventLogRecord::operator==(const CEventLogRecord& Other)
{
if(m_wType != Other.m_wType)
return FALSE;
if(m_dwEventID != Other.m_dwEventID)
return FALSE;
if(m_awsStrings.Size() != Other.m_awsStrings.Size())
return FALSE;
for(int i = 0; i < m_awsStrings.Size(); i++)
{
if(wcscmp(m_awsStrings[i], Other.m_awsStrings[i]))
{
return FALSE;
}
}
return TRUE;
}
CEventLog::CEventLog(LPCWSTR wszUNCServerName, LPCWSTR wszSourceName,
DWORD dwTimeout)
: m_wsServerName(wszUNCServerName), m_wsSourceName(wszSourceName),
m_hSource(NULL), m_fLog(NULL), m_dwTimeout(dwTimeout)
{
m_pRecords = new LogRecords;
m_bNT = IsNT();
}
CEventLog::~CEventLog()
{
delete m_pRecords;
Close();
}
BOOL CEventLog::Close()
{
if(m_bNT)
{
if(m_hSource != NULL)
{
DeregisterEventSource(m_hSource);
m_hSource = NULL;
}
}
return TRUE;
}
BOOL CEventLog::Open()
{
if(m_bNT)
{
if(m_hSource == NULL)
{
m_hSource = RegisterEventSourceW(m_wsServerName, m_wsSourceName);
}
return (m_hSource != NULL);
}
else return TRUE;
}
BOOL CEventLog::SearchForRecord(CEventLogRecord* pRecord)
{
for(int i = 0; i < m_pRecords->GetSize(); i++)
{
// Check if this record is still current
// =====================================
CWbemInterval Age =
CWbemTime::GetCurrentTime() - (*m_pRecords)[i]->GetCreationTime();
if(Age.GetSeconds() > m_dwTimeout)
{
m_pRecords->RemoveAt(i);
i--;
continue;
}
// Compare the data
// ================
if( *(*m_pRecords)[i] == *pRecord)
return TRUE;
}
return FALSE;
}
void CEventLog::AddRecord(CEventLogRecord* pRecord)
{
m_pRecords->Add(pRecord);
}
BOOL CEventLog::Report(WORD wType, DWORD dwEventID,
CInsertionString s1,
CInsertionString s2,
CInsertionString s3,
CInsertionString s4,
CInsertionString s5,
CInsertionString s6,
CInsertionString s7,
CInsertionString s8,
CInsertionString s9,
CInsertionString s10)
{
CInCritSec ics(&m_cs);
// Create a record
// ===============
CEventLogRecord* pRecord = new CEventLogRecord(wType, dwEventID,
s1, s2, s3, s4, s5, s6, s7, s8, s9, s10);
if(!pRecord)
return FALSE;
// Search for it
// =============
BOOL bDuplicate = SearchForRecord(pRecord);
if(bDuplicate)
{
delete pRecord;
return TRUE;
}
AddRecord(pRecord);
WORD wNumStrings = pRecord->GetNumStrings();
// Log it
// ======
if(m_bNT)
{
if(m_hSource == NULL)
return FALSE;
LPCWSTR* awszStrings = new LPCWSTR[wNumStrings];
if(!awszStrings)
return FALSE;
for(int i = 0; i < wNumStrings; i++)
awszStrings[i] = pRecord->GetStringAt(i);
BOOL bRes = ReportEventW(m_hSource, wType, 0, dwEventID, NULL,
wNumStrings, 0, awszStrings, NULL);
delete [] awszStrings;
return bRes;
}
else
{
Registry r(HKEY_LOCAL_MACHINE, KEY_READ, WBEM_REG_WINMGMT);
TCHAR* szInstDir;
if(r.GetStr(__TEXT("Working Directory"), &szInstDir) != Registry::no_error)
{
ERRORTRACE((LOG_EVENTLOG, "Logging is unable to read the system "
"registry!\n"));
return FALSE;
}
CDeleteMe<TCHAR> dm1(szInstDir);
TCHAR* szDllPath = new TCHAR[lstrlen(szInstDir) + 100];
if(!szDllPath)
return FALSE;
wsprintf(szDllPath, __TEXT("%s\\WinMgmtR.dll"), szInstDir);
HINSTANCE hDll = LoadLibrary(szDllPath);
delete [] szDllPath;
if(hDll == NULL)
{
ERRORTRACE((LOG_EVENTLOG, "Logging is unable to open the message "
"DLL. Error code %d\n", GetLastError()));
return FALSE;
}
LPSTR* aszStrings = new LPSTR[wNumStrings];
if(!aszStrings)
return FALSE;
int i;
for(i = 0; i < wNumStrings; i++)
aszStrings[i] = WString(pRecord->GetStringAt(i)).GetLPSTR();
char* szMessage;
DWORD dwRes = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_HMODULE |
FORMAT_MESSAGE_ARGUMENT_ARRAY,
hDll, dwEventID, 0, (char*)&szMessage,
0, (va_list*)aszStrings);
for(i = 0; i < wNumStrings; i++)
delete [] aszStrings[i];
delete [] aszStrings;
if(dwRes == 0)
{
ERRORTRACE((LOG_EVENTLOG, "Logging is unable to format the message "
"for event 0x%X. Error code: %d\n",
dwEventID, GetLastError()));
return FALSE;
}
switch(wType)
{
case EVENTLOG_ERROR_TYPE:
case EVENTLOG_WARNING_TYPE:
case EVENTLOG_AUDIT_FAILURE:
ERRORTRACE((LOG_EVENTLOG, "%s\n", szMessage));
default:
DEBUGTRACE((LOG_EVENTLOG, "%s\n", szMessage));
}
LocalFree(szMessage);
return TRUE;
}
}