Leaked source code of windows server 2003
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.

302 lines
7.6 KiB

  1. /*++
  2. Copyright (C) 1996-2001 Microsoft Corporation
  3. Module Name:
  4. EVTLOG.CPP
  5. Abstract:
  6. Event Log helpers
  7. History:
  8. --*/
  9. #include "precomp.h"
  10. #include <stdio.h>
  11. #include <wbemcomn.h>
  12. #include "CWbemTime.h"
  13. #include <evtlog.h>
  14. #include <genutils.h>
  15. CInsertionString::CInsertionString(long l) : m_bEmpty(FALSE)
  16. {
  17. WCHAR wsz[100];
  18. StringCchPrintfW(wsz, 100, L"%d", l);
  19. m_ws = wsz;
  20. }
  21. CInsertionString::CInsertionString(CHex h) : m_bEmpty(FALSE)
  22. {
  23. WCHAR wsz[100];
  24. StringCchPrintfW(wsz, 100 , L"0x%x", (long)h);
  25. m_ws = wsz;
  26. }
  27. CEventLogRecord::CEventLogRecord(WORD wType, DWORD dwEventID,
  28. CInsertionString s1,
  29. CInsertionString s2,
  30. CInsertionString s3,
  31. CInsertionString s4,
  32. CInsertionString s5,
  33. CInsertionString s6,
  34. CInsertionString s7,
  35. CInsertionString s8,
  36. CInsertionString s9,
  37. CInsertionString s10)
  38. {
  39. m_wType = wType;
  40. m_dwEventID = dwEventID;
  41. m_CreationTime = CWbemTime::GetCurrentTime();
  42. AddInsertionString(s10);
  43. AddInsertionString(s9);
  44. AddInsertionString(s8);
  45. AddInsertionString(s7);
  46. AddInsertionString(s6);
  47. AddInsertionString(s5);
  48. AddInsertionString(s4);
  49. AddInsertionString(s3);
  50. AddInsertionString(s2);
  51. AddInsertionString(s1);
  52. }
  53. void CEventLogRecord::AddInsertionString(CInsertionString& s)
  54. {
  55. if(!s.IsEmpty() || m_awsStrings.Size() > 0)
  56. m_awsStrings.InsertAt(0, s.GetString());
  57. }
  58. LPCWSTR CEventLogRecord::GetStringAt(int nIndex)
  59. {
  60. if(nIndex >= m_awsStrings.Size())
  61. return NULL;
  62. else
  63. return m_awsStrings[nIndex];
  64. }
  65. BOOL CEventLogRecord::operator==(const CEventLogRecord& Other)
  66. {
  67. if(m_wType != Other.m_wType)
  68. return FALSE;
  69. if(m_dwEventID != Other.m_dwEventID)
  70. return FALSE;
  71. if(m_awsStrings.Size() != Other.m_awsStrings.Size())
  72. return FALSE;
  73. for(int i = 0; i < m_awsStrings.Size(); i++)
  74. {
  75. if(wcscmp(m_awsStrings[i], Other.m_awsStrings[i]))
  76. {
  77. return FALSE;
  78. }
  79. }
  80. return TRUE;
  81. }
  82. CEventLog::CEventLog(LPCWSTR wszUNCServerName, LPCWSTR wszSourceName,
  83. DWORD dwTimeout)
  84. : m_wsServerName(wszUNCServerName), m_wsSourceName(wszSourceName),
  85. m_hSource(NULL), m_fLog(NULL), m_dwTimeout(dwTimeout)
  86. {
  87. m_pRecords = new LogRecords;
  88. m_bNT = IsNT();
  89. }
  90. CEventLog::~CEventLog()
  91. {
  92. delete m_pRecords;
  93. Close();
  94. }
  95. BOOL CEventLog::Close()
  96. {
  97. if(m_bNT)
  98. {
  99. if(m_hSource != NULL)
  100. {
  101. DeregisterEventSource(m_hSource);
  102. m_hSource = NULL;
  103. }
  104. }
  105. return TRUE;
  106. }
  107. BOOL CEventLog::Open()
  108. {
  109. if(m_bNT)
  110. {
  111. if(m_hSource == NULL)
  112. {
  113. m_hSource = RegisterEventSourceW(m_wsServerName, m_wsSourceName);
  114. }
  115. return (m_hSource != NULL);
  116. }
  117. else return TRUE;
  118. }
  119. BOOL CEventLog::SearchForRecord(CEventLogRecord* pRecord)
  120. {
  121. for(int i = 0; i < m_pRecords->GetSize(); i++)
  122. {
  123. // Check if this record is still current
  124. // =====================================
  125. CWbemInterval Age =
  126. CWbemTime::GetCurrentTime() - (*m_pRecords)[i]->GetCreationTime();
  127. if(Age.GetSeconds() > m_dwTimeout)
  128. {
  129. m_pRecords->RemoveAt(i);
  130. i--;
  131. continue;
  132. }
  133. // Compare the data
  134. // ================
  135. if( *(*m_pRecords)[i] == *pRecord)
  136. return TRUE;
  137. }
  138. return FALSE;
  139. }
  140. void CEventLog::AddRecord(CEventLogRecord* pRecord)
  141. {
  142. m_pRecords->Add(pRecord);
  143. }
  144. BOOL CEventLog::Report(WORD wType, DWORD dwEventID,
  145. CInsertionString s1,
  146. CInsertionString s2,
  147. CInsertionString s3,
  148. CInsertionString s4,
  149. CInsertionString s5,
  150. CInsertionString s6,
  151. CInsertionString s7,
  152. CInsertionString s8,
  153. CInsertionString s9,
  154. CInsertionString s10)
  155. {
  156. CInCritSec ics(&m_cs);
  157. // Create a record
  158. // ===============
  159. CEventLogRecord* pRecord = new CEventLogRecord(wType, dwEventID,
  160. s1, s2, s3, s4, s5, s6, s7, s8, s9, s10);
  161. if(!pRecord)
  162. return FALSE;
  163. // Search for it
  164. // =============
  165. BOOL bDuplicate = SearchForRecord(pRecord);
  166. if(bDuplicate)
  167. {
  168. delete pRecord;
  169. return TRUE;
  170. }
  171. AddRecord(pRecord);
  172. WORD wNumStrings = pRecord->GetNumStrings();
  173. // Log it
  174. // ======
  175. if(m_bNT)
  176. {
  177. if(m_hSource == NULL)
  178. return FALSE;
  179. LPCWSTR* awszStrings = new LPCWSTR[wNumStrings];
  180. if(!awszStrings)
  181. return FALSE;
  182. for(int i = 0; i < wNumStrings; i++)
  183. awszStrings[i] = pRecord->GetStringAt(i);
  184. BOOL bRes = ReportEventW(m_hSource, wType, 0, dwEventID, NULL,
  185. wNumStrings, 0, awszStrings, NULL);
  186. delete [] awszStrings;
  187. return bRes;
  188. }
  189. else
  190. {
  191. Registry r(HKEY_LOCAL_MACHINE, KEY_READ, WBEM_REG_WINMGMT);
  192. TCHAR* szInstDir;
  193. if(r.GetStr(__TEXT("Working Directory"), &szInstDir) != Registry::no_error)
  194. {
  195. ERRORTRACE((LOG_EVENTLOG, "Logging is unable to read the system "
  196. "registry!\n"));
  197. return FALSE;
  198. }
  199. CDeleteMe<TCHAR> dm1(szInstDir);
  200. size_t instDirLength = lstrlen(szInstDir);
  201. TCHAR* szDllPath = new TCHAR[instDirLength + 100];
  202. if(!szDllPath)
  203. return FALSE;
  204. StringCchPrintf(szDllPath, instDirLength+100, __TEXT("%s\\WinMgmtR.dll"), szInstDir);
  205. HINSTANCE hDll = LoadLibrary(szDllPath);
  206. delete [] szDllPath;
  207. if(hDll == NULL)
  208. {
  209. ERRORTRACE((LOG_EVENTLOG, "Logging is unable to open the message "
  210. "DLL. Error code %d\n", GetLastError()));
  211. return FALSE;
  212. }
  213. LPSTR* aszStrings = new LPSTR[wNumStrings];
  214. if(!aszStrings)
  215. return FALSE;
  216. int i;
  217. for(i = 0; i < wNumStrings; i++)
  218. aszStrings[i] = WString(pRecord->GetStringAt(i)).GetLPSTR();
  219. char* szMessage;
  220. DWORD dwRes = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
  221. FORMAT_MESSAGE_FROM_HMODULE |
  222. FORMAT_MESSAGE_ARGUMENT_ARRAY,
  223. hDll, dwEventID, 0, (char*)&szMessage,
  224. 0, (va_list*)aszStrings);
  225. for(i = 0; i < wNumStrings; i++)
  226. delete [] aszStrings[i];
  227. delete [] aszStrings;
  228. if(dwRes == 0)
  229. {
  230. ERRORTRACE((LOG_EVENTLOG, "Logging is unable to format the message "
  231. "for event 0x%X. Error code: %d\n",
  232. dwEventID, GetLastError()));
  233. return FALSE;
  234. }
  235. switch(wType)
  236. {
  237. case EVENTLOG_ERROR_TYPE:
  238. case EVENTLOG_WARNING_TYPE:
  239. case EVENTLOG_AUDIT_FAILURE:
  240. ERRORTRACE((LOG_EVENTLOG, "%s\n", szMessage));
  241. default:
  242. DEBUGTRACE((LOG_EVENTLOG, "%s\n", szMessage));
  243. }
  244. LocalFree(szMessage);
  245. return TRUE;
  246. }
  247. }