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.

1505 lines
38 KiB

  1. //*************************************************************
  2. // File name: Events.CPP
  3. //
  4. // Description: Event log entries for RSOP
  5. //
  6. //
  7. // Microsoft Confidential
  8. // Copyright (c) Microsoft Corporation 2000
  9. // All rights reserved
  10. //
  11. //*************************************************************
  12. #include "main.h"
  13. #include "rsoputil.h"
  14. EVENTLOGENTRY ExceptionEventEntries[] =
  15. {
  16. {1036, {0}, TEXT("Application"), TEXT("userenv"), NULL, NULL},
  17. {1037, {0}, TEXT("Application"), TEXT("userenv"), NULL, NULL},
  18. {1038, {0}, TEXT("Application"), TEXT("userenv"), NULL, NULL},
  19. {1039, {0}, TEXT("Application"), TEXT("userenv"), NULL, NULL},
  20. {1040, {0}, TEXT("Application"), TEXT("userenv"), NULL, NULL},
  21. {1041, {0}, TEXT("Application"), TEXT("userenv"), NULL, NULL},
  22. {1085, {0}, TEXT("Application"), TEXT("userenv"), NULL, NULL}
  23. };
  24. DWORD dwExceptionEventEntriesSize = 7;
  25. ///////////////////////////////////////////////////////////////////////////////
  26. // //
  27. // CEvents implementation //
  28. // //
  29. ///////////////////////////////////////////////////////////////////////////////
  30. CEvents::CEvents(void)
  31. {
  32. InterlockedIncrement(&g_cRefThisDll);
  33. m_pEventEntries = NULL;
  34. }
  35. CEvents::~CEvents()
  36. {
  37. if (m_pEventEntries)
  38. {
  39. FreeData (m_pEventEntries);
  40. }
  41. InterlockedDecrement(&g_cRefThisDll);
  42. }
  43. BOOL CEvents::AddEntry(LPTSTR lpEventLogName, LPTSTR lpEventSourceName, LPTSTR lpText,
  44. DWORD dwEventID, FILETIME *ftTime)
  45. {
  46. DWORD dwSize;
  47. LPEVENTLOGENTRY lpItem, lpTemp, pPrev;
  48. //
  49. // Check if this entry exists already
  50. //
  51. lpTemp = m_pEventEntries;
  52. while (lpTemp)
  53. {
  54. if (dwEventID == lpTemp->dwEventID)
  55. {
  56. if (!lstrcmpi(lpEventLogName, lpTemp->lpEventLogName))
  57. {
  58. if (!lstrcmpi(lpEventSourceName, lpTemp->lpEventSourceName))
  59. {
  60. if (ftTime->dwLowDateTime == lpTemp->ftEventTime.dwLowDateTime)
  61. {
  62. if (ftTime->dwHighDateTime == lpTemp->ftEventTime.dwHighDateTime)
  63. {
  64. return TRUE;
  65. }
  66. }
  67. }
  68. }
  69. }
  70. lpTemp = lpTemp->pNext;
  71. }
  72. //
  73. // Calculate the size of the new item
  74. //
  75. dwSize = sizeof (EVENTLOGENTRY);
  76. dwSize += ((lstrlen(lpEventLogName) + 1) * sizeof(TCHAR));
  77. dwSize += ((lstrlen(lpEventSourceName) + 1) * sizeof(TCHAR));
  78. dwSize += ((lstrlen(lpText) + 1) * sizeof(TCHAR));
  79. //
  80. // Allocate space for it
  81. //
  82. lpItem = (LPEVENTLOGENTRY) LocalAlloc (LPTR, dwSize);
  83. if (!lpItem) {
  84. DebugMsg((DM_WARNING, TEXT("CEvents::AddEntry: Failed to allocate memory with %d"),
  85. GetLastError()));
  86. return FALSE;
  87. }
  88. //
  89. // Fill in item
  90. //
  91. lpItem->lpEventLogName = (LPTSTR)(((LPBYTE)lpItem) + sizeof(EVENTLOGENTRY));
  92. lstrcpy (lpItem->lpEventLogName, lpEventLogName);
  93. lpItem->lpEventSourceName = lpItem->lpEventLogName + lstrlen (lpItem->lpEventLogName) + 1;
  94. lstrcpy (lpItem->lpEventSourceName, lpEventSourceName);
  95. lpItem->lpText = lpItem->lpEventSourceName + lstrlen (lpItem->lpEventSourceName) + 1;
  96. lstrcpy (lpItem->lpText, lpText);
  97. lpItem->dwEventID = dwEventID;
  98. CopyMemory ((LPBYTE)&lpItem->ftEventTime, ftTime, sizeof(FILETIME));
  99. //
  100. // Add item to the link list
  101. //
  102. if (m_pEventEntries)
  103. {
  104. if (CompareFileTime(ftTime, &m_pEventEntries->ftEventTime) < 0)
  105. {
  106. lpItem->pNext = m_pEventEntries;
  107. m_pEventEntries = lpItem;
  108. }
  109. else
  110. {
  111. pPrev = m_pEventEntries;
  112. lpTemp = m_pEventEntries->pNext;
  113. while (lpTemp)
  114. {
  115. if (lpTemp->pNext)
  116. {
  117. if ((CompareFileTime(ftTime, &lpTemp->ftEventTime) >= 0) &&
  118. (CompareFileTime(ftTime, &lpTemp->pNext->ftEventTime) <= 0))
  119. {
  120. lpItem->pNext = lpTemp->pNext;
  121. lpTemp->pNext = lpItem;
  122. break;
  123. }
  124. }
  125. pPrev = lpTemp;
  126. lpTemp = lpTemp->pNext;
  127. }
  128. if (!lpTemp)
  129. {
  130. pPrev->pNext = lpItem;
  131. }
  132. }
  133. }
  134. else
  135. {
  136. m_pEventEntries = lpItem;
  137. }
  138. return TRUE;
  139. }
  140. VOID CEvents::FreeData(LPEVENTLOGENTRY lpList)
  141. {
  142. LPEVENTLOGENTRY lpTemp;
  143. do {
  144. lpTemp = lpList->pNext;
  145. LocalFree (lpList);
  146. lpList = lpTemp;
  147. } while (lpTemp);
  148. }
  149. STDMETHODIMP CEvents::SecondsSince1970ToFileTime(DWORD dwSecondsSince1970,
  150. FILETIME *pftTime)
  151. {
  152. // Seconds since the start of 1970 -> 64 bit Time value
  153. LARGE_INTEGER liTime;
  154. RtlSecondsSince1970ToTime(dwSecondsSince1970, &liTime);
  155. //
  156. // The time is in UTC
  157. //
  158. pftTime->dwLowDateTime = liTime.LowPart;
  159. pftTime->dwHighDateTime = liTime.HighPart;
  160. return S_OK;
  161. }
  162. LPTSTR * CEvents::BuildStringArray(LPTSTR lpStrings, DWORD *dwStringCount)
  163. {
  164. DWORD dwCount = 0;
  165. LPTSTR lpTemp, *lpResult;
  166. if (!lpStrings || !(*lpStrings))
  167. {
  168. return NULL;
  169. }
  170. //
  171. // Find out how many strings there are
  172. //
  173. lpTemp = lpStrings;
  174. while (*lpTemp)
  175. {
  176. dwCount++;
  177. lpTemp = lpTemp + lstrlen(lpTemp) + 1;
  178. }
  179. *dwStringCount = dwCount;
  180. //
  181. // Allocate a new array to hold the pointers
  182. //
  183. lpResult = (LPTSTR *) LocalAlloc (LPTR, dwCount * sizeof(LPTSTR));
  184. if (!lpResult)
  185. {
  186. return NULL;
  187. }
  188. //
  189. // Save the pointers
  190. //
  191. lpTemp = lpStrings;
  192. dwCount = 0;
  193. while (*lpTemp)
  194. {
  195. lpResult[dwCount] = lpTemp;
  196. dwCount++;
  197. lpTemp = lpTemp + lstrlen(lpTemp) + 1;
  198. }
  199. return lpResult;
  200. }
  201. LPTSTR CEvents::BuildMessage(LPTSTR lpMsg, LPTSTR *lpStrings, DWORD dwStringCount,
  202. HMODULE hParamFile)
  203. {
  204. LPTSTR lpFullMsg = NULL;
  205. LPTSTR lpSrcIndex;
  206. LPTSTR lpTemp, lpNum;
  207. TCHAR cChar, cTemp;
  208. TCHAR cCharStr[2] = {0,0};
  209. DWORD dwCharCount = 1, dwTemp;
  210. BOOL bAdd;
  211. TCHAR szNumStr[10];
  212. DWORD dwIndex;
  213. LPTSTR lpParamMsg;
  214. if ( !lpMsg || (dwStringCount && !lpStrings) )
  215. {
  216. return 0;
  217. }
  218. lpFullMsg = (LPTSTR) LocalAlloc (LPTR, dwCharCount * sizeof(TCHAR));
  219. if (!lpFullMsg)
  220. {
  221. return NULL;
  222. }
  223. lpSrcIndex = lpMsg;
  224. while (*lpSrcIndex)
  225. {
  226. bAdd = TRUE;
  227. cChar = *lpSrcIndex;
  228. if (cChar == TEXT('%'))
  229. {
  230. cTemp = *(lpSrcIndex + 1);
  231. if (ISDIGIT (cTemp))
  232. {
  233. if (dwStringCount == 0)
  234. {
  235. goto LoopAgain;
  236. }
  237. //
  238. // Found a replaceable parameter from the passed in strings
  239. //
  240. lpNum = lpSrcIndex + 1;
  241. //
  242. // Pull the string index off
  243. //
  244. ZeroMemory (szNumStr, sizeof(szNumStr));
  245. while (ISDIGIT(*lpNum))
  246. {
  247. cCharStr[0] = *lpNum;
  248. lstrcat (szNumStr, cCharStr);
  249. if (lstrlen (szNumStr) == (ARRAYSIZE(szNumStr) - 2))
  250. {
  251. goto LoopAgain;
  252. }
  253. lpNum++;
  254. }
  255. //
  256. // Convert the string index to a dword
  257. //
  258. dwIndex = 0;
  259. StringToNum(szNumStr, (UINT *)&dwIndex);
  260. //
  261. // Subtrack 1 to make it zero based
  262. //
  263. if (dwIndex)
  264. {
  265. dwIndex--;
  266. }
  267. if (dwIndex > dwStringCount)
  268. {
  269. goto LoopAgain;
  270. }
  271. //
  272. // Add the string to the buffer
  273. //
  274. dwTemp = lstrlen (lpStrings[dwIndex]) + dwCharCount;
  275. lpTemp = (LPTSTR) LocalReAlloc (lpFullMsg, dwTemp * sizeof(TCHAR),
  276. LMEM_MOVEABLE | LMEM_ZEROINIT);
  277. if (!lpTemp)
  278. {
  279. LocalFree (lpFullMsg);
  280. lpFullMsg = NULL;
  281. goto Exit;
  282. }
  283. dwCharCount = dwTemp;
  284. lpFullMsg = lpTemp;
  285. lstrcat (lpFullMsg, lpStrings[dwIndex]);
  286. lpSrcIndex = lpNum - 1;
  287. bAdd = FALSE;
  288. }
  289. else if (cTemp == TEXT('%'))
  290. {
  291. cTemp = *(lpSrcIndex + 2);
  292. if (cTemp == TEXT('%'))
  293. {
  294. //
  295. // Found a replacable parameter from the parameter file
  296. //
  297. lpNum = lpSrcIndex + 3;
  298. //
  299. // Pull the string index off
  300. //
  301. ZeroMemory (szNumStr, sizeof(szNumStr));
  302. while (ISDIGIT(*lpNum))
  303. {
  304. cCharStr[0] = *lpNum;
  305. lstrcat (szNumStr, cCharStr);
  306. if (lstrlen (szNumStr) == (ARRAYSIZE(szNumStr) - 2))
  307. {
  308. goto LoopAgain;
  309. }
  310. lpNum++;
  311. }
  312. //
  313. // Convert the string index to a dword
  314. //
  315. dwIndex = 0;
  316. StringToNum(szNumStr, (UINT *)&dwIndex);
  317. //
  318. // Subtrack 1 to make it zero based
  319. //
  320. if (dwIndex)
  321. {
  322. dwIndex--;
  323. }
  324. if (dwIndex > dwStringCount)
  325. {
  326. goto LoopAgain;
  327. }
  328. //
  329. // Convert the string number to a dword
  330. //
  331. StringToNum(lpStrings[dwIndex], (UINT *)&dwIndex);
  332. lpParamMsg = NULL;
  333. if (hParamFile)
  334. {
  335. FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_HMODULE |
  336. FORMAT_MESSAGE_IGNORE_INSERTS, (LPCVOID) hParamFile,
  337. dwIndex, 0, (LPTSTR)&lpParamMsg, 1, NULL);
  338. }
  339. else
  340. {
  341. FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
  342. FORMAT_MESSAGE_IGNORE_INSERTS, NULL,
  343. dwIndex, 0, (LPTSTR)&lpParamMsg, 1, NULL);
  344. }
  345. if (lpParamMsg)
  346. {
  347. lpTemp = lpParamMsg + lstrlen(lpParamMsg) - 2;
  348. *lpTemp = TEXT('\0');
  349. //
  350. // Add the string to the buffer
  351. //
  352. dwTemp = lstrlen (lpParamMsg) + dwCharCount;
  353. lpTemp = (LPTSTR) LocalReAlloc (lpFullMsg, dwTemp * sizeof(TCHAR),
  354. LMEM_MOVEABLE | LMEM_ZEROINIT);
  355. if (!lpTemp)
  356. {
  357. LocalFree (lpFullMsg);
  358. lpFullMsg = NULL;
  359. goto Exit;
  360. }
  361. dwCharCount = dwTemp;
  362. lpFullMsg = lpTemp;
  363. lstrcat (lpFullMsg, lpParamMsg);
  364. lpSrcIndex = lpNum - 1;
  365. bAdd = FALSE;
  366. LocalFree (lpParamMsg);
  367. }
  368. }
  369. }
  370. }
  371. LoopAgain:
  372. if (bAdd)
  373. {
  374. //
  375. // Add this character to the buffer
  376. //
  377. dwCharCount++;
  378. lpTemp = (LPTSTR) LocalReAlloc (lpFullMsg, dwCharCount * sizeof(TCHAR),
  379. LMEM_MOVEABLE | LMEM_ZEROINIT);
  380. if (!lpTemp)
  381. {
  382. LocalFree (lpFullMsg);
  383. lpFullMsg = NULL;
  384. goto Exit;
  385. }
  386. lpFullMsg = lpTemp;
  387. cCharStr[0] = cChar;
  388. lstrcat (lpFullMsg, cCharStr);
  389. }
  390. lpSrcIndex++;
  391. }
  392. Exit:
  393. return lpFullMsg;
  394. }
  395. STDMETHODIMP CEvents::SaveEventLogEntry (PEVENTLOGRECORD pEntry,
  396. LPTSTR lpEventLogName,
  397. LPTSTR lpEventSourceName,
  398. FILETIME *ftEntry)
  399. {
  400. LPTSTR lpRegKey = NULL;
  401. HKEY hKey = NULL;
  402. TCHAR szEventFile[MAX_PATH];
  403. TCHAR szExpEventFile[MAX_PATH];
  404. TCHAR szParamFile[MAX_PATH] = {0};
  405. TCHAR szExpParamFile[MAX_PATH] = {0};
  406. HRESULT hr = S_OK;
  407. DWORD dwType, dwSize;
  408. HMODULE hEventFile = NULL;
  409. HMODULE hParamFile = NULL;
  410. LPTSTR lpMsg, *lpStrings, lpFullMsg;
  411. LPBYTE lpData;
  412. DWORD dwStringCount;
  413. lpRegKey = new TCHAR [(lstrlen(lpEventLogName) + lstrlen(lpEventSourceName) + 60)];
  414. if (!lpRegKey)
  415. {
  416. DebugMsg((DM_WARNING, TEXT("CEvents::SaveEventLogEntry: Failed to alloc memory for key name")));
  417. hr = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
  418. goto Exit;
  419. }
  420. wsprintf (lpRegKey, TEXT("SYSTEM\\CurrentControlSet\\Services\\EventLog\\%s\\%s"), lpEventLogName, lpEventSourceName);
  421. if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, lpRegKey, 0, KEY_READ, &hKey) != ERROR_SUCCESS)
  422. {
  423. DebugMsg((DM_WARNING, TEXT("CEvents::SaveEventLogEntry: Failed to open reg key for %s"), lpRegKey));
  424. hr = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
  425. goto Exit;
  426. }
  427. dwSize = sizeof(szEventFile);
  428. if (RegQueryValueEx (hKey, TEXT("EventMessageFile"), NULL, &dwType, (LPBYTE) szEventFile,
  429. &dwSize) != ERROR_SUCCESS)
  430. {
  431. DebugMsg((DM_WARNING, TEXT("CEvents::SaveEventLogEntry: Failed to query dll pathname for %s"), lpRegKey));
  432. hr = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
  433. goto Exit;
  434. }
  435. ExpandEnvironmentStrings (szEventFile, szExpEventFile, ARRAYSIZE(szExpEventFile));
  436. dwSize = sizeof(szParamFile);
  437. if (RegQueryValueEx (hKey, TEXT("ParameterMessageFile"), NULL, &dwType, (LPBYTE) szParamFile,
  438. &dwSize) == ERROR_SUCCESS)
  439. {
  440. ExpandEnvironmentStrings (szParamFile, szExpParamFile, ARRAYSIZE(szExpParamFile));
  441. }
  442. hEventFile = LoadLibraryEx (szExpEventFile, NULL, LOAD_LIBRARY_AS_DATAFILE);
  443. if (!hEventFile)
  444. {
  445. DebugMsg((DM_WARNING, TEXT("CEvents::SaveEventLogEntry: Failed to loadlibrary dll %s with %d"), szExpEventFile, GetLastError()));
  446. hr = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
  447. goto Exit;
  448. }
  449. if (szExpParamFile[0] != TEXT('\0'))
  450. {
  451. if (!StrStrI(szExpParamFile, TEXT("kernel32")))
  452. {
  453. hParamFile = LoadLibraryEx (szExpParamFile, NULL, LOAD_LIBRARY_AS_DATAFILE);
  454. }
  455. }
  456. lpData = (LPBYTE)((LPBYTE)pEntry + pEntry->StringOffset);
  457. lpStrings = BuildStringArray((LPTSTR) lpData, &dwStringCount);
  458. lpMsg = NULL;
  459. if (FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_HMODULE |
  460. FORMAT_MESSAGE_IGNORE_INSERTS, (LPCVOID) hEventFile,
  461. pEntry->EventID, 0, (LPTSTR)&lpMsg, 1, NULL))
  462. {
  463. lpFullMsg = BuildMessage(lpMsg, lpStrings, dwStringCount, hParamFile);
  464. if (lpFullMsg)
  465. {
  466. AddEntry(lpEventLogName, lpEventSourceName, lpFullMsg, pEntry->EventID, ftEntry);
  467. LocalFree (lpFullMsg);
  468. }
  469. LocalFree (lpMsg);
  470. }
  471. if (lpStrings)
  472. {
  473. LocalFree (lpStrings);
  474. }
  475. Exit:
  476. if (hEventFile)
  477. {
  478. FreeLibrary (hEventFile);
  479. }
  480. if (hParamFile)
  481. {
  482. FreeLibrary (hParamFile);
  483. }
  484. if (hKey)
  485. {
  486. RegCloseKey (hKey);
  487. }
  488. if (lpRegKey)
  489. {
  490. delete [] lpRegKey;
  491. }
  492. return S_OK;
  493. }
  494. STDMETHODIMP CEvents::ParseEventLogRecords (PEVENTLOGRECORD lpEntries,
  495. DWORD dwEntriesSize,
  496. LPTSTR lpEventLogName,
  497. LPTSTR lpEventSourceName,
  498. DWORD dwEventID,
  499. FILETIME * pBeginTime,
  500. FILETIME * pEndTime)
  501. {
  502. PEVENTLOGRECORD pEntry = lpEntries;
  503. FILETIME ftEntry;
  504. LONG lResult;
  505. LPTSTR lpSource;
  506. TCHAR szCurrentTime[100];
  507. DWORD dwTotal = 0;
  508. while (dwTotal < dwEntriesSize)
  509. {
  510. if (pEntry->EventType != EVENTLOG_INFORMATION_TYPE)
  511. {
  512. SecondsSince1970ToFileTime (pEntry->TimeWritten, &ftEntry);
  513. lpSource = (LPTSTR)(((LPBYTE)pEntry) + sizeof(EVENTLOGRECORD));
  514. // DebugMsg((DM_VERBOSE, TEXT("CEvents::ParseEventLogRecords: Found %s at %s"),
  515. // lpSource, ConvertTimeToDisplayTime (NULL, &ftEntry, szCurrentTime)));
  516. if ((CompareFileTime (&ftEntry, pBeginTime) >= 0) &&
  517. (CompareFileTime (&ftEntry, pEndTime) <= 0))
  518. {
  519. if (!lstrcmpi(lpSource, lpEventSourceName))
  520. {
  521. //
  522. // The dwEventID parameter is optional. If it is non-zero, then
  523. // we're looking for a specific event message. If it is zero,
  524. // consider the id to be a wildcard and grab all the events that
  525. // the remaining criteria.
  526. //
  527. if (dwEventID)
  528. {
  529. if (dwEventID == pEntry->EventID)
  530. {
  531. SaveEventLogEntry (pEntry, lpEventLogName, lpEventSourceName, &ftEntry);
  532. }
  533. }
  534. else
  535. {
  536. SaveEventLogEntry (pEntry, lpEventLogName, lpEventSourceName, &ftEntry);
  537. }
  538. }
  539. }
  540. }
  541. dwTotal += pEntry->Length;
  542. pEntry = (PEVENTLOGRECORD)(((LPBYTE)pEntry) + pEntry->Length);
  543. }
  544. return S_OK;
  545. }
  546. STDMETHODIMP CEvents::QueryForEventLogEntries (LPTSTR lpComputerName,
  547. LPTSTR lpEventLogName,
  548. LPTSTR lpEventSourceName,
  549. DWORD dwEventID,
  550. SYSTEMTIME * pBeginTime,
  551. SYSTEMTIME * pEndTime)
  552. {
  553. LPTSTR lpServerName, lpTemp = lpComputerName;
  554. HANDLE hLog;
  555. ULONG ulSize;
  556. TCHAR szBuffer[300];
  557. LPBYTE lpEntries;
  558. DWORD dwEntriesBufferSize = 4096;
  559. DWORD dwBytesRead, dwBytesNeeded;
  560. FILETIME ftBeginTime, ftEndTime;
  561. TCHAR szBeginTime[100];
  562. TCHAR szEndTime[100];
  563. DebugMsg((DM_VERBOSE, TEXT("CEvents::QueryForEventLogEntries: Entering for %s,%s between %s and %s"),
  564. lpEventLogName, lpEventSourceName,
  565. ConvertTimeToDisplayTime (pBeginTime, NULL, szBeginTime),
  566. ConvertTimeToDisplayTime (pEndTime, NULL, szEndTime)));
  567. //
  568. // Check if this is the local machine
  569. //
  570. if (!lstrcmpi(lpComputerName, TEXT(".")))
  571. {
  572. ulSize = ARRAYSIZE(szBuffer);
  573. if ( !GetComputerNameEx (ComputerNameNetBIOS, szBuffer, &ulSize) )
  574. {
  575. DebugMsg((DM_WARNING, TEXT("CEvents::QueryForEventLogEntries: GetComputerNameEx() failed.")));
  576. return HRESULT_FROM_WIN32(GetLastError());
  577. }
  578. lpTemp = szBuffer;
  579. }
  580. lpServerName = new TCHAR [lstrlen(lpTemp) + 3];
  581. if (!lpServerName)
  582. {
  583. DebugMsg((DM_WARNING, TEXT("CEvents::QueryForEventLogEntries: Failed to alloc memory for server name")));
  584. return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
  585. }
  586. lstrcpy (lpServerName, TEXT("\\\\"));
  587. lstrcat (lpServerName, lpTemp);
  588. //
  589. // Open the event log
  590. //
  591. hLog = OpenEventLog (lpServerName, lpEventLogName);
  592. if (!hLog)
  593. {
  594. DebugMsg((DM_WARNING, TEXT("CEvents::QueryForEventLogEntries: Failed to open event log on %s with %d"),
  595. lpServerName, GetLastError()));
  596. }
  597. delete [] lpServerName;
  598. if (!hLog)
  599. return HRESULT_FROM_WIN32(GetLastError());
  600. //
  601. // Allocate a buffer to read the entries into
  602. //
  603. lpEntries = (LPBYTE) LocalAlloc (LPTR, dwEntriesBufferSize);
  604. if (!lpEntries)
  605. {
  606. DebugMsg((DM_WARNING, TEXT("CEvents::QueryForEventLogEntries: Failed to alloc memory for server name")));
  607. CloseEventLog (hLog);
  608. return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
  609. }
  610. SystemTimeToFileTime (pBeginTime, &ftBeginTime);
  611. SystemTimeToFileTime (pEndTime, &ftEndTime);
  612. while (TRUE)
  613. {
  614. ZeroMemory (lpEntries, dwEntriesBufferSize);
  615. if (ReadEventLog (hLog, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ, 0, lpEntries, dwEntriesBufferSize,
  616. &dwBytesRead, &dwBytesNeeded))
  617. {
  618. ParseEventLogRecords ((PEVENTLOGRECORD) lpEntries, dwBytesRead, lpEventLogName, lpEventSourceName, dwEventID, &ftBeginTime, &ftEndTime);
  619. }
  620. else
  621. {
  622. if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
  623. {
  624. dwEntriesBufferSize = dwBytesNeeded;
  625. LocalFree (lpEntries);
  626. lpEntries = (LPBYTE) LocalAlloc (LPTR, dwEntriesBufferSize);
  627. if (!lpEntries)
  628. {
  629. DebugMsg((DM_WARNING, TEXT("CEvents::QueryForEventLogEntries: Failed to alloc memory")));
  630. CloseEventLog (hLog);
  631. return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
  632. }
  633. }
  634. else
  635. {
  636. break;
  637. }
  638. }
  639. }
  640. LocalFree (lpEntries);
  641. CloseEventLog (hLog);
  642. DebugMsg((DM_VERBOSE, TEXT("CEvents::QueryForEventLogEntries: Leaving ===")));
  643. return S_OK;
  644. }
  645. STDMETHODIMP CEvents::GetEventLogEntryText (LPOLESTR pszEventSource,
  646. LPOLESTR pszEventLogName,
  647. LPOLESTR pszEventTime,
  648. DWORD dwEventID,
  649. LPOLESTR *ppszText)
  650. {
  651. XBStr xbstrWbemTime = pszEventTime;
  652. SYSTEMTIME EventTime;
  653. FILETIME ftLower, ftUpper;
  654. ULARGE_INTEGER ulTime;
  655. LPEVENTLOGENTRY lpTemp;
  656. LPOLESTR lpMsg = NULL, lpTempMsg;
  657. ULONG ulSize;
  658. TCHAR szLowerTime[100];
  659. TCHAR szUpperTime[100];
  660. if (!ppszText)
  661. {
  662. return HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER);
  663. }
  664. WbemTimeToSystemTime(xbstrWbemTime, EventTime);
  665. //
  666. // Subtrack 1 second to EventTime to get the lower end of the range
  667. //
  668. SystemTimeToFileTime (&EventTime, &ftLower);
  669. ulTime.LowPart = ftLower.dwLowDateTime;
  670. ulTime.HighPart = ftLower.dwHighDateTime;
  671. ulTime.QuadPart = ulTime.QuadPart - (10000000 * 1); // 1 second
  672. ftLower.dwLowDateTime = ulTime.LowPart;
  673. ftLower.dwHighDateTime = ulTime.HighPart;
  674. //
  675. // Add 2 seconds to determine the upper bounds
  676. //
  677. ulTime.QuadPart = ulTime.QuadPart + (10000000 * 2); // 2 second
  678. ftUpper.dwLowDateTime = ulTime.LowPart;
  679. ftUpper.dwHighDateTime = ulTime.HighPart;
  680. DebugMsg((DM_VERBOSE, TEXT("CEvents::GetEventLogEntryText: Entering for %s,%s,%d between %s and %s"),
  681. pszEventLogName, pszEventSource, dwEventID,
  682. ConvertTimeToDisplayTime (NULL, &ftLower, szLowerTime),
  683. ConvertTimeToDisplayTime (NULL, &ftUpper, szUpperTime)));
  684. //
  685. // Loop through the entries looking for matches
  686. //
  687. lpTemp = m_pEventEntries;
  688. while (lpTemp)
  689. {
  690. if (lpTemp->dwEventID == dwEventID)
  691. {
  692. if (!lstrcmpi(lpTemp->lpEventLogName, pszEventLogName))
  693. {
  694. if (!lstrcmpi(lpTemp->lpEventSourceName, pszEventSource))
  695. {
  696. if ((CompareFileTime (&lpTemp->ftEventTime, &ftLower) >= 0) &&
  697. (CompareFileTime (&lpTemp->ftEventTime, &ftUpper) <= 0))
  698. {
  699. if (lpMsg)
  700. {
  701. ulSize = lstrlen(lpMsg);
  702. ulSize += lstrlen(lpTemp->lpText) + 3;
  703. lpTempMsg = (LPOLESTR) CoTaskMemRealloc (lpMsg, ulSize * sizeof(TCHAR));
  704. if (!lpTempMsg)
  705. {
  706. CoTaskMemFree (lpMsg);
  707. return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
  708. }
  709. lpMsg = lpTempMsg;
  710. lstrcat (lpMsg, TEXT("\r\n"));
  711. lstrcat (lpMsg, lpTemp->lpText);
  712. }
  713. else
  714. {
  715. lpMsg = (LPOLESTR) CoTaskMemAlloc ((lstrlen(lpTemp->lpText) + 1) * sizeof(TCHAR));
  716. if (!lpMsg)
  717. {
  718. return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
  719. }
  720. lstrcpy (lpMsg, lpTemp->lpText);
  721. }
  722. }
  723. }
  724. }
  725. }
  726. lpTemp = lpTemp->pNext;
  727. }
  728. if (!lpMsg)
  729. {
  730. return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
  731. }
  732. *ppszText = lpMsg;
  733. return S_OK;
  734. }
  735. BOOL CEvents::IsEntryInEventSourceList (LPEVENTLOGENTRY lpEntry, LPSOURCEENTRY lpEventSources)
  736. {
  737. LPSOURCEENTRY lpTemp;
  738. if (!lpEventSources)
  739. {
  740. return FALSE;
  741. }
  742. lpTemp = lpEventSources;
  743. while (lpTemp)
  744. {
  745. if (!lstrcmpi(lpTemp->lpEventLogName, lpEntry->lpEventLogName))
  746. {
  747. if (!lstrcmpi(lpTemp->lpEventSourceName, lpEntry->lpEventSourceName))
  748. {
  749. return TRUE;
  750. }
  751. }
  752. lpTemp = lpTemp->pNext;
  753. }
  754. return FALSE;
  755. }
  756. BOOL CEvents::IsEntryInExceptionList (LPEVENTLOGENTRY lpEntry)
  757. {
  758. LPEVENTLOGENTRY lpTemp;
  759. DWORD i;
  760. for (i = 0; i < dwExceptionEventEntriesSize; i++) {
  761. lpTemp = ExceptionEventEntries+i;
  762. if (!lstrcmpi(lpTemp->lpEventLogName, lpEntry->lpEventLogName))
  763. {
  764. if (!lstrcmpi(lpTemp->lpEventSourceName, lpEntry->lpEventSourceName))
  765. {
  766. if (LOWORD(lpTemp->dwEventID) == LOWORD(lpEntry->dwEventID)) {
  767. DebugMsg((DM_VERBOSE, TEXT("Skipping event id")));
  768. DebugMsg((DM_VERBOSE, TEXT("Event Log: %s"), lpEntry->lpEventLogName));
  769. DebugMsg((DM_VERBOSE, TEXT("Event Source: %s"), lpEntry->lpEventSourceName));
  770. DebugMsg((DM_VERBOSE, TEXT("Event ID: %d"), LOWORD(lpEntry->dwEventID)));
  771. return TRUE;
  772. }
  773. }
  774. }
  775. }
  776. return FALSE;
  777. }
  778. STDMETHODIMP CEvents::GetCSEEntries(SYSTEMTIME * pBeginTime, SYSTEMTIME * pEndTime,
  779. LPSOURCEENTRY lpEventSources, LPOLESTR *ppszText,
  780. BOOL bGPCore)
  781. {
  782. LPEVENTLOGENTRY lpTemp;
  783. FILETIME ftBeginTime, ftEndTime;
  784. LPOLESTR lpMsg = NULL, lpTempMsg;
  785. ULONG ulSize;
  786. SystemTimeToFileTime (pBeginTime, &ftBeginTime);
  787. SystemTimeToFileTime (pEndTime, &ftEndTime);
  788. //
  789. // Loop through the entries looking for matches
  790. //
  791. lpTemp = m_pEventEntries;
  792. while (lpTemp)
  793. {
  794. if ((CompareFileTime (&lpTemp->ftEventTime, &ftBeginTime) >= 0) &&
  795. (CompareFileTime (&lpTemp->ftEventTime, &ftEndTime) <= 0))
  796. {
  797. if (IsEntryInEventSourceList (lpTemp, lpEventSources))
  798. {
  799. if ((bGPCore) || (!IsEntryInExceptionList(lpTemp))) {
  800. if (lpMsg)
  801. {
  802. ulSize = lstrlen(lpMsg);
  803. ulSize += lstrlen(lpTemp->lpText) + 3;
  804. lpTempMsg = (LPOLESTR) CoTaskMemRealloc (lpMsg, ulSize * sizeof(TCHAR));
  805. if (!lpTempMsg)
  806. {
  807. CoTaskMemFree (lpMsg);
  808. return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
  809. }
  810. lpMsg = lpTempMsg;
  811. lstrcat (lpMsg, TEXT("\r\n"));
  812. lstrcat (lpMsg, lpTemp->lpText);
  813. }
  814. else
  815. {
  816. lpMsg = (LPOLESTR) CoTaskMemAlloc ((lstrlen(lpTemp->lpText) + 1) * sizeof(TCHAR));
  817. if (!lpMsg)
  818. {
  819. return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
  820. }
  821. lstrcpy (lpMsg, lpTemp->lpText);
  822. }
  823. }
  824. }
  825. }
  826. lpTemp = lpTemp->pNext;
  827. }
  828. if (!lpMsg)
  829. {
  830. return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
  831. }
  832. *ppszText = lpMsg;
  833. return S_OK;
  834. }
  835. STDMETHODIMP CEvents::DumpDebugInfo (void)
  836. {
  837. LPEVENTLOGENTRY lpTemp;
  838. FILETIME ftLocal;
  839. SYSTEMTIME systime;
  840. TCHAR szDateTime[100];
  841. lpTemp = m_pEventEntries;
  842. if (lpTemp)
  843. {
  844. DebugMsg((DM_VERBOSE, TEXT(" ")));
  845. DebugMsg((DM_VERBOSE, TEXT("Event log entries:")));
  846. }
  847. while (lpTemp)
  848. {
  849. ConvertTimeToDisplayTime (NULL, &lpTemp->ftEventTime, szDateTime);
  850. DebugMsg((DM_VERBOSE, TEXT(" ")));
  851. DebugMsg((DM_VERBOSE, TEXT("Event Time: %s"), szDateTime));
  852. DebugMsg((DM_VERBOSE, TEXT("Event Log: %s"), lpTemp->lpEventLogName));
  853. DebugMsg((DM_VERBOSE, TEXT("Event Source: %s"), lpTemp->lpEventSourceName));
  854. DebugMsg((DM_VERBOSE, TEXT("Event ID: %d"), LOWORD(lpTemp->dwEventID)));
  855. DebugMsg((DM_VERBOSE, TEXT("Message: %s"), lpTemp->lpText));
  856. lpTemp = lpTemp->pNext;
  857. }
  858. return S_OK;
  859. }
  860. LPTSTR CEvents::ConvertTimeToDisplayTime (SYSTEMTIME *pSysTime, FILETIME *pFileTime, LPTSTR szBuffer)
  861. {
  862. FILETIME ftTime, ftLocal;
  863. SYSTEMTIME systime;
  864. if (pSysTime)
  865. {
  866. SystemTimeToFileTime (pSysTime, &ftTime);
  867. }
  868. else
  869. {
  870. CopyMemory (&ftTime, pFileTime, sizeof(FILETIME));
  871. }
  872. FileTimeToLocalFileTime (&ftTime, &ftLocal);
  873. FileTimeToSystemTime (&ftLocal, &systime);
  874. wsprintf (szBuffer, TEXT("%d/%d/%d %02d:%02d:%02d:%03d"), systime.wMonth, systime.wDay, systime.wYear,
  875. systime.wHour, systime.wMinute, systime.wSecond, systime.wMilliseconds);
  876. return szBuffer;
  877. }
  878. STDMETHODIMP CEvents::AddSourceEntry (LPTSTR lpEventLogName,
  879. LPTSTR lpEventSourceName,
  880. LPSOURCEENTRY *lpList)
  881. {
  882. LPSOURCEENTRY lpItem;
  883. DWORD dwSize;
  884. //
  885. // Calculate the size of the new item
  886. //
  887. dwSize = sizeof (SOURCEENTRY);
  888. dwSize += ((lstrlen(lpEventLogName) + 1) * sizeof(TCHAR));
  889. dwSize += ((lstrlen(lpEventSourceName) + 1) * sizeof(TCHAR));
  890. //
  891. // Allocate space for it
  892. //
  893. lpItem = (LPSOURCEENTRY) LocalAlloc (LPTR, dwSize);
  894. if (!lpItem) {
  895. DebugMsg((DM_WARNING, TEXT("CEvents::AddSourceEntry: Failed to allocate memory with %d"),
  896. GetLastError()));
  897. return E_FAIL;
  898. }
  899. //
  900. // Fill in item
  901. //
  902. lpItem->lpEventLogName = (LPTSTR)(((LPBYTE)lpItem) + sizeof(SOURCEENTRY));
  903. lstrcpy (lpItem->lpEventLogName, lpEventLogName);
  904. lpItem->lpEventSourceName = lpItem->lpEventLogName + lstrlen (lpItem->lpEventLogName) + 1;
  905. lstrcpy (lpItem->lpEventSourceName, lpEventSourceName);
  906. //
  907. // Add it to the list
  908. //
  909. if (*lpList)
  910. {
  911. lpItem->pNext = *lpList;
  912. }
  913. *lpList = lpItem;
  914. return S_OK;
  915. }
  916. VOID CEvents::FreeSourceData(LPSOURCEENTRY lpList)
  917. {
  918. LPSOURCEENTRY lpTemp;
  919. if (lpList)
  920. {
  921. do {
  922. lpTemp = lpList->pNext;
  923. LocalFree (lpList);
  924. lpList = lpTemp;
  925. } while (lpTemp);
  926. }
  927. }
  928. STDMETHODIMP CEvents::SaveEntriesToStream (IStream *pStm)
  929. {
  930. HRESULT hr;
  931. DWORD dwCount = 0;
  932. LPEVENTLOGENTRY lpTemp;
  933. ULONG nBytesWritten;
  934. //
  935. // First count how many entries are in the link list
  936. //
  937. lpTemp = m_pEventEntries;
  938. while (lpTemp)
  939. {
  940. dwCount++;
  941. lpTemp = lpTemp->pNext;
  942. }
  943. //
  944. // Save the count to the stream
  945. //
  946. hr = pStm->Write(&dwCount, sizeof(dwCount), &nBytesWritten);
  947. if ((hr != S_OK) || (nBytesWritten != sizeof(dwCount)))
  948. {
  949. DebugMsg((DM_WARNING, TEXT("CEvents::SaveEntriesToStream: Failed to write entry count with %d."), hr));
  950. hr = E_FAIL;
  951. goto Exit;
  952. }
  953. //
  954. // Now loop through each item saving each field in the node
  955. //
  956. lpTemp = m_pEventEntries;
  957. while (lpTemp)
  958. {
  959. //
  960. // Save the event id
  961. //
  962. hr = pStm->Write(&lpTemp->dwEventID, sizeof(DWORD), &nBytesWritten);
  963. if ((hr != S_OK) || (nBytesWritten != sizeof(DWORD)))
  964. {
  965. DebugMsg((DM_WARNING, TEXT("CEvents::SaveEntriesToStream: Failed to write event id with %d."), hr));
  966. hr = E_FAIL;
  967. goto Exit;
  968. }
  969. //
  970. // Save the event time
  971. //
  972. hr = pStm->Write(&lpTemp->ftEventTime, sizeof(FILETIME), &nBytesWritten);
  973. if ((hr != S_OK) || (nBytesWritten != sizeof(FILETIME)))
  974. {
  975. DebugMsg((DM_WARNING, TEXT("CEvents::SaveEntriesToStream: Failed to write file time with %d."), hr));
  976. hr = E_FAIL;
  977. goto Exit;
  978. }
  979. //
  980. // Save the event log name
  981. //
  982. hr = SaveString (pStm, lpTemp->lpEventLogName);
  983. if (hr != S_OK)
  984. {
  985. DebugMsg((DM_WARNING, TEXT("CEvents::SaveEntriesToStream: Failed to save event log name with %d."), hr));
  986. goto Exit;
  987. }
  988. //
  989. // Save the event source name
  990. //
  991. hr = SaveString (pStm, lpTemp->lpEventSourceName);
  992. if (hr != S_OK)
  993. {
  994. DebugMsg((DM_WARNING, TEXT("CEvents::SaveEntriesToStream: Failed to save event source name with %d."), hr));
  995. goto Exit;
  996. }
  997. //
  998. // Save the event text
  999. //
  1000. hr = SaveString (pStm, lpTemp->lpText);
  1001. if (hr != S_OK)
  1002. {
  1003. DebugMsg((DM_WARNING, TEXT("CEvents::SaveEntriesToStream: Failed to save event text with %d."), hr));
  1004. goto Exit;
  1005. }
  1006. lpTemp = lpTemp->pNext;
  1007. }
  1008. Exit:
  1009. return hr;
  1010. }
  1011. STDMETHODIMP CEvents::LoadEntriesFromStream (IStream *pStm)
  1012. {
  1013. HRESULT hr;
  1014. DWORD dwCount = 0, dwIndex, dwEventID;
  1015. LPEVENTLOGENTRY lpTemp;
  1016. ULONG nBytesRead;
  1017. FILETIME ftEventTime;
  1018. LPTSTR lpEventLogName = NULL;
  1019. LPTSTR lpEventSourceName = NULL;
  1020. LPTSTR lpText = NULL;
  1021. //
  1022. // Read in the entry count
  1023. //
  1024. hr = pStm->Read(&dwCount, sizeof(dwCount), &nBytesRead);
  1025. if ((hr != S_OK) || (nBytesRead != sizeof(dwCount)))
  1026. {
  1027. DebugMsg((DM_WARNING, TEXT("CEvents::LoadEntriesFromStream: Failed to read event count with 0x%x."), hr));
  1028. hr = E_FAIL;
  1029. goto Exit;
  1030. }
  1031. //
  1032. // Loop through the items
  1033. //
  1034. for (dwIndex = 0; dwIndex < dwCount; dwIndex++)
  1035. {
  1036. //
  1037. // Read in the event id
  1038. //
  1039. hr = pStm->Read(&dwEventID, sizeof(dwEventID), &nBytesRead);
  1040. if ((hr != S_OK) || (nBytesRead != sizeof(dwEventID)))
  1041. {
  1042. DebugMsg((DM_WARNING, TEXT("CEvents::LoadEntriesFromStream: Failed to read event id with 0x%x."), hr));
  1043. hr = E_FAIL;
  1044. goto Exit;
  1045. }
  1046. //
  1047. // Read in the event time
  1048. //
  1049. hr = pStm->Read(&ftEventTime, sizeof(FILETIME), &nBytesRead);
  1050. if ((hr != S_OK) || (nBytesRead != sizeof(FILETIME)))
  1051. {
  1052. DebugMsg((DM_WARNING, TEXT("CEvents::LoadEntriesFromStream: Failed to read event time with 0x%x."), hr));
  1053. hr = E_FAIL;
  1054. goto Exit;
  1055. }
  1056. //
  1057. // Read the event log name
  1058. //
  1059. hr = ReadString (pStm, &lpEventLogName);
  1060. if (hr != S_OK)
  1061. {
  1062. DebugMsg((DM_WARNING, TEXT("CEvents::LoadEntriesFromStream: Failed to read the event log name with 0x%x."), hr));
  1063. goto Exit;
  1064. }
  1065. //
  1066. // Read the event source name
  1067. //
  1068. hr = ReadString (pStm, &lpEventSourceName);
  1069. if (hr != S_OK)
  1070. {
  1071. DebugMsg((DM_WARNING, TEXT("CEvents::LoadEntriesFromStream: Failed to read the event source name with 0x%x."), hr));
  1072. goto Exit;
  1073. }
  1074. //
  1075. // Read the event text
  1076. //
  1077. hr = ReadString (pStm, &lpText);
  1078. if (hr != S_OK)
  1079. {
  1080. DebugMsg((DM_WARNING, TEXT("CEvents::LoadEntriesFromStream: Failed to read the event text with 0x%x."), hr));
  1081. goto Exit;
  1082. }
  1083. //
  1084. // Add this entry to the link list
  1085. //
  1086. if (!AddEntry (lpEventLogName, lpEventSourceName, lpText, dwEventID, &ftEventTime))
  1087. {
  1088. DebugMsg((DM_WARNING, TEXT("CEvents::LoadEntriesFromStream: Failed to add the entry.")));
  1089. hr = E_FAIL;
  1090. goto Exit;
  1091. }
  1092. //
  1093. // Clean up for next item
  1094. //
  1095. delete [] lpEventLogName;
  1096. lpEventLogName = NULL;
  1097. delete [] lpEventSourceName;
  1098. lpEventSourceName = NULL;
  1099. delete [] lpText;
  1100. lpText = NULL;
  1101. }
  1102. Exit:
  1103. if (lpEventLogName)
  1104. {
  1105. delete [] lpEventLogName;
  1106. }
  1107. if (lpEventSourceName)
  1108. {
  1109. delete [] lpEventSourceName;
  1110. }
  1111. if (lpText)
  1112. {
  1113. delete [] lpText;
  1114. }
  1115. return hr;
  1116. }