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.

597 lines
14 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. eventlog.c
  5. Abstract:
  6. This file contains all functions that access the application event log.
  7. Author:
  8. Wesley Witt (wesw) 19-Mar-1996
  9. Environment:
  10. User Mode
  11. --*/
  12. #include <windows.h>
  13. #include <tapi.h>
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <tchar.h>
  17. #include "fxsapip.h"
  18. #include "faxutil.h"
  19. #include "faxreg.h"
  20. #include "faxext.h"
  21. #include "..\service\registry\faxsvcrg.h"
  22. #include "faxdev.h"
  23. #include "faxevent.h"
  24. #include "faxevent_messages.h"
  25. #include "CritSec.h"
  26. static DWORD gs_dwWarningEvents;
  27. static DWORD gs_dwErrorEvents;
  28. static DWORD gs_dwInformationEvents;
  29. #define MAX_STRINGS 64
  30. static HANDLE gs_hEventSrc;
  31. static DWORD gs_FaxCategoryCount;
  32. static CFaxCriticalSection gs_CsEvent;
  33. PFAX_LOG_CATEGORY gs_pFaxCategory;
  34. #ifdef __cplusplus
  35. extern "C" {
  36. #endif
  37. BOOL
  38. FXSEVENTInitialize(
  39. VOID
  40. )
  41. {
  42. //
  43. // Becuase the process is not always terminated when the service is stopped,
  44. // We must not have any staticly initialized global variables.
  45. // Initialize FXSEVENT global variables before starting the service
  46. //
  47. gs_hEventSrc = NULL;
  48. gs_pFaxCategory = NULL;
  49. gs_FaxCategoryCount = 0;
  50. gs_dwWarningEvents = 0;
  51. gs_dwErrorEvents = 0;
  52. gs_dwInformationEvents = 0;
  53. return TRUE;
  54. }
  55. VOID
  56. FXSEVENTFree(
  57. VOID
  58. )
  59. {
  60. DEBUG_FUNCTION_NAME(TEXT("FXSEVENTFree"));
  61. if (NULL != gs_hEventSrc)
  62. {
  63. if (!DeregisterEventSource(gs_hEventSrc))
  64. {
  65. DebugPrintEx(
  66. DEBUG_ERR,
  67. TEXT("DeregisterEventSource() failed (ec: %ld)"),
  68. GetLastError());
  69. }
  70. gs_hEventSrc = NULL;
  71. }
  72. gs_CsEvent.SafeDelete();
  73. for (DWORD i = 0; i < gs_FaxCategoryCount; i++)
  74. {
  75. MemFree( (LPVOID)gs_pFaxCategory[i].Name );
  76. }
  77. MemFree (gs_pFaxCategory);
  78. gs_pFaxCategory = NULL;
  79. gs_FaxCategoryCount = 0;
  80. HeapCleanup();
  81. return;
  82. }
  83. BOOL
  84. InitializeEventLog(OUT PREG_FAX_SERVICE* ppFaxReg)
  85. /*++
  86. Routine Description:
  87. Initializes the event log for the FAX service to
  88. record event entries.
  89. Arguments:
  90. ppFaxReg -
  91. Return Value:
  92. TRUE for success, FALSE for failure
  93. --*/
  94. {
  95. DWORD i;
  96. DWORD ec;
  97. FAX_LOG_CATEGORY DefaultCategories[] =
  98. {
  99. { L"Initialization/Termination", FAXLOG_CATEGORY_INIT, FAXLOG_LEVEL_MED },
  100. { L"Outbound", FAXLOG_CATEGORY_OUTBOUND, FAXLOG_LEVEL_MED },
  101. { L"Inbound", FAXLOG_CATEGORY_INBOUND, FAXLOG_LEVEL_MED },
  102. { L"Unknown", FAXLOG_CATEGORY_UNKNOWN, FAXLOG_LEVEL_MED }
  103. };
  104. DEBUG_FUNCTION_NAME(TEXT("InitializeEventLog"));
  105. if (!gs_CsEvent.InitializeAndSpinCount())
  106. {
  107. ec = GetLastError();
  108. DebugPrintEx(
  109. DEBUG_ERR,
  110. TEXT("CFaxCriticalSection::InitializeAndSpinCount (&gs_CsEvent) failed: err = %d"),
  111. ec);
  112. return FALSE;
  113. }
  114. *ppFaxReg = NULL;
  115. ec = GetFaxRegistry(ppFaxReg);
  116. if (ERROR_SUCCESS != ec)
  117. {
  118. DebugPrintEx(
  119. DEBUG_ERR,
  120. TEXT("GetFaxRegistry() failed (ec: %ld)"),
  121. ec);
  122. return FALSE;
  123. }
  124. //
  125. // create the event source, if it does not already exist
  126. //
  127. if (!CreateFaxEventSource( *ppFaxReg,
  128. DefaultCategories,
  129. ARR_SIZE(DefaultCategories)))
  130. {
  131. DebugPrintEx(
  132. DEBUG_ERR,
  133. TEXT("CreateFaxEventSource() failed"));
  134. return FALSE;
  135. }
  136. Assert( (*ppFaxReg)->Logging );
  137. //
  138. // allocate memory for the logging category info
  139. //
  140. EnterCriticalSection( &gs_CsEvent );
  141. gs_pFaxCategory = (PFAX_LOG_CATEGORY) MemAlloc( sizeof(FAX_LOG_CATEGORY) * (*ppFaxReg)->LoggingCount );
  142. if (!gs_pFaxCategory)
  143. {
  144. DebugPrintEx(
  145. DEBUG_ERR,
  146. TEXT("MemAlloc() failed"));
  147. LeaveCriticalSection( &gs_CsEvent );
  148. return FALSE;
  149. }
  150. ZeroMemory (gs_pFaxCategory, sizeof(FAX_LOG_CATEGORY) * (*ppFaxReg)->LoggingCount);
  151. gs_FaxCategoryCount = (*ppFaxReg)->LoggingCount;
  152. //
  153. // capture the event categories from the registry
  154. //
  155. for (i = 0; i < (*ppFaxReg)->LoggingCount; i++)
  156. {
  157. Assert (NULL != (*ppFaxReg)->Logging[i].CategoryName);
  158. gs_pFaxCategory[i].Name = StringDup( (*ppFaxReg)->Logging[i].CategoryName );
  159. if (NULL == gs_pFaxCategory[i].Name)
  160. {
  161. //
  162. // FXSEVENTFree() will free all resources
  163. //
  164. LeaveCriticalSection( &gs_CsEvent );
  165. return FALSE;
  166. }
  167. gs_pFaxCategory[i].Category = (*ppFaxReg)->Logging[i].Number;
  168. gs_pFaxCategory[i].Level = (*ppFaxReg)->Logging[i].Level;
  169. }
  170. LeaveCriticalSection( &gs_CsEvent );
  171. //
  172. // get a handle to the event log
  173. //
  174. gs_hEventSrc = RegisterEventSource(
  175. NULL,
  176. FAX_SVC_EVENT
  177. );
  178. if (!gs_hEventSrc)
  179. {
  180. return FALSE;
  181. }
  182. return TRUE;
  183. }
  184. DWORD
  185. RefreshEventLog(
  186. PREG_FAX_LOGGING FaxReg
  187. )
  188. /*++
  189. Routine Description:
  190. Refreshes the event log for the FAX service to
  191. record event entries.
  192. Arguments:
  193. None.
  194. Return Value:
  195. Win32 error code.
  196. --*/
  197. {
  198. DWORD i;
  199. PFAX_LOG_CATEGORY pLoggingCategories = NULL;
  200. DWORD dwRes = ERROR_SUCCESS;
  201. DEBUG_FUNCTION_NAME(TEXT("RefreshEventLog"));
  202. EnterCriticalSection( &gs_CsEvent );
  203. pLoggingCategories = (PFAX_LOG_CATEGORY) MemAlloc( sizeof(FAX_LOG_CATEGORY) * FaxReg->LoggingCount);
  204. if (NULL == pLoggingCategories)
  205. {
  206. DebugPrintEx(
  207. DEBUG_ERR,
  208. TEXT("MemAlloc() failed"));
  209. dwRes = ERROR_OUTOFMEMORY;
  210. goto exit;
  211. }
  212. ZeroMemory (pLoggingCategories, sizeof(FAX_LOG_CATEGORY) * FaxReg->LoggingCount);
  213. //
  214. // Set the new values
  215. //
  216. for (i = 0; i < FaxReg->LoggingCount; i++)
  217. {
  218. pLoggingCategories[i].Name = StringDup( FaxReg->Logging[i].CategoryName );
  219. if (NULL == pLoggingCategories[i].Name)
  220. {
  221. dwRes = ERROR_OUTOFMEMORY;
  222. goto exit;
  223. }
  224. pLoggingCategories[i].Category = FaxReg->Logging[i].Number;
  225. pLoggingCategories[i].Level = FaxReg->Logging[i].Level;
  226. }
  227. //
  228. // Free old settings
  229. //
  230. for (i = 0; i < gs_FaxCategoryCount; i++)
  231. {
  232. MemFree( (LPVOID)gs_pFaxCategory[i].Name );
  233. }
  234. MemFree (gs_pFaxCategory);
  235. //
  236. // Set the gs_pFaxCategory to point to the new values
  237. //
  238. gs_pFaxCategory = pLoggingCategories;
  239. gs_FaxCategoryCount = FaxReg->LoggingCount;
  240. pLoggingCategories = NULL; // Do not free at exit
  241. Assert (ERROR_SUCCESS == dwRes);
  242. exit:
  243. LeaveCriticalSection( &gs_CsEvent );
  244. if (NULL != pLoggingCategories)
  245. {
  246. for (i = 0; i < FaxReg->LoggingCount; i++)
  247. {
  248. MemFree( (LPVOID)pLoggingCategories[i].Name );
  249. }
  250. MemFree(pLoggingCategories);
  251. }
  252. return dwRes;
  253. }
  254. BOOL
  255. FaxLog(
  256. DWORD Category,
  257. DWORD Level,
  258. DWORD StringCount,
  259. DWORD FormatId,
  260. ...
  261. )
  262. /*++
  263. Routine Description:
  264. Writes a log file entry to the event log.
  265. Arguments:
  266. Level - Severity of the log record
  267. StringCount - Number of strings included in the varargs
  268. FormatId - Message file id
  269. Return Value:
  270. TRUE for success, FALSE for failure
  271. --*/
  272. {
  273. LPCTSTR Strings[MAX_STRINGS];
  274. DWORD i;
  275. va_list args;
  276. WORD Type;
  277. WORD wEventCategory; // The event categoey as it appears in the MC file. The WINFAX.H cateogry values
  278. // are mapped to the .MC values before ReportEvent() is called.
  279. DEBUG_FUNCTION_NAME(TEXT("FaxLog"));
  280. if(StringCount > MAX_STRINGS)
  281. {
  282. DebugPrintEx(DEBUG_ERR, TEXT("Too many parameters."));
  283. return FALSE;
  284. }
  285. if (!gs_hEventSrc)
  286. {
  287. //
  288. // Not yet initialized
  289. //
  290. DebugPrintEx(
  291. DEBUG_WRN,
  292. TEXT("Event log is not initialized yet."),
  293. Category);
  294. return FALSE;
  295. }
  296. //
  297. // look for the category
  298. //
  299. EnterCriticalSection( &gs_CsEvent );
  300. for (i = 0; i < gs_FaxCategoryCount; i++)
  301. {
  302. if (gs_pFaxCategory[i].Category == Category)
  303. {
  304. if (Level > gs_pFaxCategory[i].Level)
  305. {
  306. LeaveCriticalSection( &gs_CsEvent );
  307. return FALSE;
  308. }
  309. }
  310. }
  311. va_start( args, FormatId );
  312. //
  313. // capture the strings
  314. //
  315. for (i=0; i<StringCount; i++)
  316. {
  317. Strings[i] = va_arg( args, LPTSTR );
  318. if(Strings[i] == NULL)
  319. {
  320. Strings[i] = TEXT("");
  321. }
  322. }
  323. va_end (args);
  324. switch (FormatId >> 30)
  325. {
  326. case STATUS_SEVERITY_WARNING:
  327. Type = EVENTLOG_WARNING_TYPE;
  328. gs_dwWarningEvents++;
  329. break;
  330. case STATUS_SEVERITY_ERROR:
  331. Type = EVENTLOG_ERROR_TYPE;
  332. gs_dwErrorEvents++;
  333. break;
  334. case STATUS_SEVERITY_INFORMATIONAL:
  335. case STATUS_SEVERITY_SUCCESS:
  336. Type = EVENTLOG_INFORMATION_TYPE;
  337. gs_dwInformationEvents++;
  338. break;
  339. default:
  340. DebugPrintEx(
  341. DEBUG_ERR,
  342. TEXT("Invalid Type id [%ld]"),
  343. (FormatId >> 30));
  344. ASSERT_FALSE;
  345. break;
  346. }
  347. LeaveCriticalSection( &gs_CsEvent );
  348. //
  349. // Map the public category index to the .MC category index
  350. //
  351. //
  352. switch (Category)
  353. {
  354. case FAXLOG_CATEGORY_INIT:
  355. wEventCategory = FAX_LOG_CATEGORY_INIT;
  356. break;
  357. case FAXLOG_CATEGORY_OUTBOUND:
  358. wEventCategory = FAX_LOG_CATEGORY_OUTBOUND;
  359. break;
  360. case FAXLOG_CATEGORY_INBOUND:
  361. wEventCategory = FAX_LOG_CATEGORY_INBOUND;
  362. break;
  363. case FAXLOG_CATEGORY_UNKNOWN:
  364. wEventCategory = FAX_LOG_CATEGORY_UNKNOWN;
  365. break;
  366. default:
  367. DebugPrintEx(
  368. DEBUG_ERR,
  369. TEXT("Invalid category id [%ld]"),
  370. Category);
  371. ASSERT_FALSE;
  372. }
  373. //
  374. // record the event
  375. //
  376. if (!ReportEvent(
  377. gs_hEventSrc, // event log handle
  378. Type, // type
  379. wEventCategory, // category
  380. FormatId, // event id
  381. NULL, // security id
  382. (WORD) StringCount, // string count
  383. 0, // data buffer size
  384. Strings, // strings
  385. NULL // data buffer
  386. ))
  387. {
  388. DebugPrintEx(
  389. DEBUG_ERR,
  390. TEXT("ReportEvent() failed, ec: %ld"),
  391. GetLastError());
  392. }
  393. return TRUE;
  394. }
  395. void
  396. GetEventsCounters(
  397. OUT LPDWORD lpdwWarningEvents,
  398. OUT LPDWORD lpdwErrorEvents,
  399. OUT LPDWORD lpdwInformationEvents
  400. )
  401. {
  402. Assert (lpdwWarningEvents && lpdwErrorEvents && lpdwInformationEvents);
  403. EnterCriticalSection( &gs_CsEvent );
  404. *lpdwWarningEvents = gs_dwWarningEvents;
  405. *lpdwErrorEvents = gs_dwErrorEvents;
  406. *lpdwInformationEvents = gs_dwInformationEvents;
  407. LeaveCriticalSection( &gs_CsEvent );
  408. return;
  409. }
  410. DWORD
  411. GetLoggingCategories(
  412. OUT PFAX_LOG_CATEGORY* lppFaxCategory,
  413. OUT LPDWORD lpdwFaxCategorySize,
  414. OUT LPDWORD lpdwNumberCategories
  415. )
  416. /*++
  417. Routine Description:
  418. returns the logging categories. The caller should call MemFree to deallocate (lppFaxCategory).
  419. The returned data is serialized. The caller should call FixupString() on CategoryName to convert offset to address.
  420. Arguments:
  421. OUT LPBYTE *lppFaxCategory - Address of a buffer to recieve the fax category. The buffer is allocated by the function.
  422. OUT LPDWORD lpdwFaxCategorySize - Allocated buffer size.
  423. OUT LPDWORD lpdwNumberCategories - Number of fax logging categories.
  424. Return Value:
  425. None.
  426. --*/
  427. {
  428. DWORD i;
  429. DWORD dwBufferSize;
  430. ULONG_PTR ulpOffset;
  431. DEBUG_FUNCTION_NAME(TEXT("GetLoggingCategories"));
  432. Assert (lppFaxCategory && lpdwFaxCategorySize && lpdwNumberCategories);
  433. *lpdwFaxCategorySize = 0;
  434. *lppFaxCategory = NULL;
  435. *lpdwNumberCategories = 0;
  436. EnterCriticalSection( &gs_CsEvent );
  437. //
  438. // Calculate buffer size
  439. //
  440. dwBufferSize = gs_FaxCategoryCount * sizeof(FAX_LOG_CATEGORY);
  441. for (i = 0; i < gs_FaxCategoryCount; i++)
  442. {
  443. dwBufferSize += StringSize(gs_pFaxCategory[i].Name);
  444. }
  445. //
  446. // Allocate memory
  447. //
  448. *lppFaxCategory = (PFAX_LOG_CATEGORY)MemAlloc(dwBufferSize);
  449. if (NULL == *lppFaxCategory)
  450. {
  451. DebugPrintEx(
  452. DEBUG_ERR,
  453. TEXT("MemAlloc failed"));
  454. LeaveCriticalSection( &gs_CsEvent );
  455. return ERROR_NOT_ENOUGH_MEMORY;
  456. }
  457. *lpdwFaxCategorySize = dwBufferSize;
  458. *lpdwNumberCategories = gs_FaxCategoryCount;
  459. //
  460. // Get the fax logging logging
  461. //
  462. ulpOffset = gs_FaxCategoryCount * sizeof(FAX_LOG_CATEGORY);
  463. for (i = 0; i < gs_FaxCategoryCount; i++)
  464. {
  465. StoreString(
  466. gs_pFaxCategory[i].Name,
  467. (PULONG_PTR)&((*lppFaxCategory)[i].Name),
  468. (LPBYTE)*lppFaxCategory,
  469. &ulpOffset,
  470. dwBufferSize
  471. );
  472. (*lppFaxCategory)[i].Category = gs_pFaxCategory[i].Category;
  473. (*lppFaxCategory)[i].Level = gs_pFaxCategory[i].Level;
  474. }
  475. LeaveCriticalSection( &gs_CsEvent );
  476. return ERROR_SUCCESS;
  477. } // GetLoggingCategories
  478. #ifdef __cplusplus
  479. }
  480. #endif