Rev 6 | Blame | Compare with Previous | Last modification | View Log
///////////////////////////////// Includes //////////////////////////////////#pragma warning( disable : 4996 )#include "stdafx.h"#include "nteventlogsource.h"///////////////////////////////// Macros /////////////////////////////////////#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif///////////////////////// CNTEventLogSource implementation ////////////////////CNTEventLogSource::CNTEventLogSource(LPCTSTR lpUNCServerName, LPCTSTR lpSourceName){m_hEventSource = NULL;m_sServerName = lpUNCServerName;m_sSourceName = lpSourceName;}CNTEventLogSource::~CNTEventLogSource(){Deregister();}CNTEventLogSource::operator HANDLE() const{return m_hEventSource;}BOOL CNTEventLogSource::Attach(HANDLE hEventSource){if (m_hEventSource != hEventSource)Deregister();m_hEventSource = hEventSource;return TRUE;}HANDLE CNTEventLogSource::Detach(){HANDLE hReturn = m_hEventSource;m_hEventSource = NULL;return hReturn;}BOOL CNTEventLogSource::Register(LPCTSTR lpUNCServerName, LPCTSTR lpSourceName){Deregister();m_hEventSource = ::RegisterEventSource(lpUNCServerName, lpSourceName);if (m_hEventSource == NULL)TRACE(_T("Failed in call to RegisterEventSource in Register, GetLastError:%d\n"), ::GetLastError());else{m_sServerName = lpUNCServerName;m_sSourceName = lpSourceName;}return (m_hEventSource != NULL);}BOOL CNTEventLogSource::Report(WORD wType, WORD wCategory, DWORD dwEventID, PSID lpUserSid,WORD wNumStrings, DWORD dwDataSize, LPCTSTR* lpStrings, LPVOID lpRawData){//CSingleLock sl(&m_csReport, TRUE);ASSERT(m_hEventSource == NULL);Register(m_sServerName, m_sSourceName);//Call the SDK version of the functionBOOL bSuccess = ::ReportEvent(m_hEventSource, wType, wCategory, dwEventID, lpUserSid,wNumStrings, dwDataSize, lpStrings, lpRawData);if (!bSuccess)TRACE(_T("Failed in call to ReportEvent in Report, GetLastError:%d\n"), ::GetLastError());Deregister();return bSuccess;}BOOL CNTEventLogSource::Report(WORD wType, DWORD dwEventID){return Report(wType, 0, dwEventID, NULL, 0, 0, NULL, NULL);}BOOL CNTEventLogSource::Report(WORD wType, LPCTSTR lpszString){return Report(wType, CNT_MSG_FULLSTRING, lpszString);}BOOL CNTEventLogSource::Report(WORD wType, DWORD dwEventID, LPCTSTR lpszString){ASSERT(lpszString);return Report(wType, 0, dwEventID, NULL, 1, 0, &lpszString, NULL);}BOOL CNTEventLogSource::Report(WORD wType, DWORD dwEventID, LPCTSTR lpszString1, LPCTSTR lpszString2){ASSERT(lpszString1);ASSERT(lpszString2);// LPCTSTR lpStrings[2];// lpStrings[0] = lpszString1;// lpStrings[1] = lpszString2;return Report(wType, 0, dwEventID, NULL, 1, strlen(lpszString2), &lpszString1, (void *)lpszString2);}BOOL CNTEventLogSource::Report(WORD wType, DWORD dwEventID, LPCTSTR lpszString1, LPCTSTR lpszString2, int len2){ASSERT(lpszString1);ASSERT(lpszString2);// LPCTSTR lpStrings[2];// lpStrings[0] = lpszString1;// lpStrings[1] = lpszString2;return Report(wType, 0, dwEventID, NULL, 1, len2, &lpszString1, (void *)lpszString2);}BOOL CNTEventLogSource::Report(WORD wType, DWORD dwEventID, LPCTSTR lpszString1, LPCTSTR lpszString2, DWORD dwCode, BOOL bReportAsHex){ASSERT(lpszString1);ASSERT(lpszString2);LPCTSTR lpStrings[3];lpStrings[0] = lpszString1;lpStrings[1] = lpszString2;CString sError;if (bReportAsHex)sError.Format(_T("%x"), dwCode);elsesError.Format(_T("%d"), dwCode);lpStrings[2] = sError;return Report(wType, 0, dwEventID, NULL, 3, 0, lpStrings, NULL);}BOOL CNTEventLogSource::Report(WORD wType, DWORD dwEventID, DWORD dwCode, BOOL bReportAsHex){CString sError;if (bReportAsHex)sError.Format(_T("%x"), dwCode);elsesError.Format(_T("%d"), dwCode);return Report(wType, dwEventID, sError);}BOOL CNTEventLogSource::Report(WORD wType, DWORD dwEventID, LPCTSTR lpszString, DWORD dwCode, BOOL bReportAsHex){LPCTSTR lpStrings[2];CString sError;if (bReportAsHex)sError.Format(_T("%x"), dwCode);elsesError.Format(_T("%d"), dwCode);lpStrings[0] = lpszString;lpStrings[1] = sError;return Report(wType, 0, dwEventID, NULL, 2, 0, lpStrings, NULL);}BOOL CNTEventLogSource::Deregister(){BOOL bSuccess = TRUE;if (m_hEventSource != NULL){bSuccess = ::DeregisterEventSource(m_hEventSource);if (!bSuccess)TRACE(_T("Failed in call to DeregisterEventSource in Deregister, GetLastError:%d\n"), ::GetLastError());m_hEventSource = NULL;}return bSuccess;}BOOL CNTEventLogSource::Install(LPCTSTR lpSourceName, LPCTSTR lpEventMessageFile, DWORD dwTypesSupported){//Validate our parametersASSERT(lpSourceName);ASSERT(lpEventMessageFile);//Make the necessary updates to the registryHKEY hAppKey;BOOL bSuccess = FALSE;int error = 0;error = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\"), 0,KEY_WRITE|KEY_READ, &hAppKey);if (error == ERROR_SUCCESS){DWORD dw;HKEY hSourceKey;if (RegCreateKeyEx(hAppKey, lpSourceName, 0, REG_NONE, REG_OPTION_NON_VOLATILE, KEY_WRITE|KEY_READ, NULL,&hSourceKey, &dw) == ERROR_SUCCESS){//Write the Message file stringbSuccess = (RegSetValueEx(hSourceKey, _T("EventMessageFile"), NULL, REG_SZ, (LPBYTE)lpEventMessageFile,(lstrlen(lpEventMessageFile)+1)*sizeof(TCHAR)) == ERROR_SUCCESS);if (!bSuccess)TRACE(_T("Failed in call to RegSetValueEx in Install, GetLastError:%d\n"), ::GetLastError());//Write the Types supported dwordbSuccess = bSuccess && (RegSetValueEx(hSourceKey, _T("TypesSupported"), NULL, REG_DWORD,(LPBYTE)&dwTypesSupported, sizeof(dwTypesSupported)) == ERROR_SUCCESS);if (!bSuccess)TRACE(_T("Failed in call to RegSetValueEx in Install, GetLastError:%d\n"), ::GetLastError());//Close the registry key we opened::RegCloseKey(hSourceKey);//Update the sources registry key so that the event viewer can filter//on the events which we write to the event logCStringArray sources;if (GetStringArrayFromRegistry(hAppKey, _T("Sources"), sources)){//If our name is not in the array then add itBOOL bFoundMyself = FALSE;for (int i=0; i<sources.GetSize() && !bFoundMyself; i++)bFoundMyself = (sources.GetAt(i) == lpSourceName);if (!bFoundMyself){sources.Add(lpSourceName);SetStringArrayIntoRegistry(hAppKey, _T("Sources"), sources);}}}elseTRACE(_T("Failed in call to RegCreateKeyEx in Install, GetLastError:%d\n"), ::GetLastError()); //::GetLastError());//Close the registry key we opened::RegCloseKey(hAppKey);}elseTRACE(_T("Failed in call to RegOpenKeyEx in Install, GetLastError:%d\n"), error);return bSuccess;}BOOL CNTEventLogSource::Uninstall(LPCTSTR lpSourceName){//Validate our parametersASSERT(lpSourceName);//Remove the settings from the registryCString sSubKey(_T("SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\"));sSubKey += lpSourceName;BOOL bSuccess = (RegDeleteKey(HKEY_LOCAL_MACHINE, sSubKey) == ERROR_SUCCESS);if (!bSuccess)TRACE(_T("Failed in call to RegDeleteKey in Uninstall, GetLastError:%d\n"), ::GetLastError());//Remove ourself from the "Sources" registry keyHKEY hAppKey;if (::RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\"), 0,KEY_WRITE|KEY_READ, &hAppKey) == ERROR_SUCCESS){CStringArray sources;if (GetStringArrayFromRegistry(hAppKey, _T("Sources"), sources)){//If our name is in the array then remove itBOOL bFoundMyself = FALSE;for (int i=0; i<sources.GetSize() && !bFoundMyself; i++){bFoundMyself = (sources.GetAt(i) == lpSourceName);if (bFoundMyself)sources.RemoveAt(i);}if (bFoundMyself)SetStringArrayIntoRegistry(hAppKey, _T("Sources"), sources);}//Close the registry key we opened::RegCloseKey(hAppKey);}return bSuccess;}BOOL CNTEventLogSource::GetStringArrayFromRegistry(HKEY hKey, LPCTSTR lpszEntry, CStringArray& array){ASSERT(hKey != NULL);ASSERT(lpszEntry != NULL);//Assume the worstBOOL bSuccess = FALSE;//Empty the array before we go any furtherarray.RemoveAll();DWORD dwType, dwCount;LONG lResult = RegQueryValueEx(hKey, (LPTSTR)lpszEntry, NULL, &dwType, NULL, &dwCount);if (lResult == ERROR_SUCCESS){ASSERT(dwType == REG_MULTI_SZ);LPBYTE lpBuffer = new BYTE[dwCount];lResult = RegQueryValueEx(hKey, (LPTSTR)lpszEntry, NULL, &dwType, lpBuffer, &dwCount);if (lResult == ERROR_SUCCESS){LPTSTR lpszStrings = (LPTSTR) lpBuffer;while (lpszStrings[0] != 0){array.Add((LPCTSTR) lpszStrings);lpszStrings += (_tcslen(lpszStrings ) + 1);}bSuccess = TRUE;}//Tidy up the heap memory we have useddelete [] lpBuffer;}return bSuccess;}BOOL CNTEventLogSource::SetStringArrayIntoRegistry(HKEY hKey, LPCTSTR lpszEntry, const CStringArray& array){int i;//Validate our input parametersASSERT(hKey);ASSERT(lpszEntry != NULL);//Work out the size of the buffer we will needDWORD dwSize = 0;int nStrings = array.GetSize();for (i=0; i<nStrings; i++)dwSize += array.GetAt(i).GetLength() + 1; //1 extra for each NULL terminator//Need one second NULL for the double NULL at the enddwSize++;//Convert from BYTE size to character sizedwSize *= sizeof(TCHAR);//Allocate the memory we wantBYTE* lpBuffer = new BYTE[dwSize];::ZeroMemory(lpBuffer, dwSize);//Now copy the strings into the bufferint nCurOffset = 0;LPTSTR lpszString = (LPTSTR) lpBuffer;for (i=0; i<nStrings; i++){CString sText = array.GetAt(i);_tcscpy(&lpszString[nCurOffset], sText);nCurOffset += sText.GetLength();nCurOffset++;}//Don't forgot to doubly NULL terminatelpszString[nCurOffset] = _T('\0');//Finally write it into the registryBOOL bSuccess = (::RegSetValueEx(hKey, lpszEntry, NULL, REG_MULTI_SZ, lpBuffer, dwSize) == ERROR_SUCCESS);//free up the memory we useddelete [] lpBuffer;return bSuccess;}