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.

1113 lines
33 KiB

  1. /*++
  2. Copyright (c) 1996-1999 Microsoft Corporation
  3. Module Name:
  4. eventlog.c
  5. Abstract:
  6. This module provides common eventlog services for the File Replication service
  7. Stolen from the routine of the same name in the cluster service.
  8. Author:
  9. John Vert (jvert) 9/13/1996
  10. RohanK - Added Filter
  11. Davidor - Rewrite init using FrsRegistryKeyTable and CfgReg read/write functions.
  12. Revision History:
  13. --*/
  14. #include <ntreppch.h>
  15. #pragma hdrstop
  16. #include <frs.h>
  17. #include <debug.h>
  18. //
  19. // Event Log Sources (NULL Terminated)
  20. //
  21. WORD FrsMessageIdToEventType[] = {
  22. EVENTLOG_SUCCESS,
  23. EVENTLOG_INFORMATION_TYPE,
  24. EVENTLOG_WARNING_TYPE,
  25. EVENTLOG_ERROR_TYPE
  26. };
  27. #define MESSAGEID_TO_EVENTTYPE(_id_) (FrsMessageIdToEventType[_id_ >> 30])
  28. BOOL EventLogRunning = FALSE;
  29. BOOL
  30. DebTryLock(
  31. VOID
  32. );
  33. typedef struct _FRS_EL_ENTRY{
  34. DWORD EventId;
  35. PCHAR EventTag;
  36. } FRS_EL_ENTRY, *PFRS_EL_ENTRY;
  37. FRS_EL_ENTRY FrsEvents[] = {
  38. {EVENT_FRS_ERROR, "EVENT_FRS_ERROR"},
  39. {EVENT_FRS_STARTING, "EVENT_FRS_STARTING"},
  40. {EVENT_FRS_STOPPING, "EVENT_FRS_STOPPING"},
  41. {EVENT_FRS_STOPPED, "EVENT_FRS_STOPPED"},
  42. {EVENT_FRS_STOPPED_FORCE, "EVENT_FRS_STOPPED_FORCE"},
  43. {EVENT_FRS_STOPPED_ASSERT, "EVENT_FRS_STOPPED_ASSERT"},
  44. {EVENT_FRS_ASSERT, "EVENT_FRS_ASSERT"},
  45. {EVENT_FRS_VOLUME_NOT_SUPPORTED, "EVENT_FRS_VOLUME_NOT_SUPPORTED"},
  46. {EVENT_FRS_LONG_JOIN, "EVENT_FRS_LONG_JOIN"},
  47. {EVENT_FRS_LONG_JOIN_DONE, "EVENT_FRS_LONG_JOIN_DONE"},
  48. {EVENT_FRS_CANNOT_COMMUNICATE, "EVENT_FRS_CANNOT_COMMUNICATE"},
  49. {EVENT_FRS_DATABASE_SPACE, "EVENT_FRS_DATABASE_SPACE"},
  50. {EVENT_FRS_DISK_WRITE_CACHE_ENABLED, "EVENT_FRS_DISK_WRITE_CACHE_ENABLED"},
  51. {EVENT_FRS_JET_1414, "EVENT_FRS_JET_1414"},
  52. {EVENT_FRS_SYSVOL_NOT_READY, "EVENT_FRS_SYSVOL_NOT_READY"},
  53. {EVENT_FRS_SYSVOL_NOT_READY_PRIMARY, "EVENT_FRS_SYSVOL_NOT_READY_PRIMARY"},
  54. {EVENT_FRS_SYSVOL_READY, "EVENT_FRS_SYSVOL_READY"},
  55. {EVENT_FRS_ACCESS_CHECKS_DISABLED, "EVENT_FRS_ACCESS_CHECKS_DISABLED"},
  56. {EVENT_FRS_ACCESS_CHECKS_FAILED_USER, "EVENT_FRS_ACCESS_CHECKS_FAILED_USER"},
  57. {EVENT_FRS_ACCESS_CHECKS_FAILED_UNKNOWN, "EVENT_FRS_ACCESS_CHECKS_FAILED_UNKNOWN"},
  58. {EVENT_FRS_MOVED_PREEXISTING, "EVENT_FRS_MOVED_PREEXISTING"},
  59. {EVENT_FRS_CANNOT_START_BACKUP_RESTORE_IN_PROGRESS, "EVENT_FRS_CANNOT_START_BACKUP_RESTORE_IN_PROGRESS"},
  60. {EVENT_FRS_STAGING_AREA_FULL, "EVENT_FRS_STAGING_AREA_FULL"},
  61. {EVENT_FRS_HUGE_FILE, "EVENT_FRS_HUGE_FILE"},
  62. {EVENT_FRS_CANNOT_CREATE_UUID, "EVENT_FRS_CANNOT_CREATE_UUID"},
  63. {EVENT_FRS_NO_DNS_ATTRIBUTE, "EVENT_FRS_NO_DNS_ATTRIBUTE"},
  64. {EVENT_FRS_NO_SID, "EVENT_FRS_NO_SID"},
  65. {NTFRSPRF_OPEN_RPC_BINDING_ERROR_SET, "NTFRSPRF_OPEN_RPC_BINDING_ERROR_SET"},
  66. {NTFRSPRF_OPEN_RPC_BINDING_ERROR_CONN, "NTFRSPRF_OPEN_RPC_BINDING_ERROR_CONN"},
  67. {NTFRSPRF_OPEN_RPC_CALL_ERROR_SET, "NTFRSPRF_OPEN_RPC_CALL_ERROR_SET"},
  68. {NTFRSPRF_OPEN_RPC_CALL_ERROR_CONN, "NTFRSPRF_OPEN_RPC_CALL_ERROR_CONN"},
  69. {NTFRSPRF_COLLECT_RPC_BINDING_ERROR_SET, "NTFRSPRF_COLLECT_RPC_BINDING_ERROR_SET"},
  70. {NTFRSPRF_COLLECT_RPC_BINDING_ERROR_CONN,"NTFRSPRF_COLLECT_RPC_BINDING_ERROR_CONN"},
  71. {NTFRSPRF_COLLECT_RPC_CALL_ERROR_SET, "NTFRSPRF_COLLECT_RPC_CALL_ERROR_SET"},
  72. {NTFRSPRF_COLLECT_RPC_CALL_ERROR_CONN, "NTFRSPRF_COLLECT_RPC_CALL_ERROR_CONN"},
  73. {NTFRSPRF_VIRTUALALLOC_ERROR_SET, "NTFRSPRF_VIRTUALALLOC_ERROR_SET"},
  74. {NTFRSPRF_VIRTUALALLOC_ERROR_CONN, "NTFRSPRF_VIRTUALALLOC_ERROR_CONN"},
  75. {NTFRSPRF_REGISTRY_ERROR_SET, "NTFRSPRF_REGISTRY_ERROR_SET"},
  76. {NTFRSPRF_REGISTRY_ERROR_CONN, "NTFRSPRF_REGISTRY_ERROR_CONN"},
  77. {EVENT_FRS_ROOT_NOT_VALID, "EVENT_FRS_ROOT_NOT_VALID"},
  78. {EVENT_FRS_STAGE_NOT_VALID, "EVENT_FRS_STAGE_NOT_VALID"},
  79. {EVENT_FRS_OVERLAPS_LOGGING, "EVENT_FRS_OVERLAPS_LOGGING"},
  80. {EVENT_FRS_OVERLAPS_WORKING, "EVENT_FRS_OVERLAPS_WORKING"},
  81. {EVENT_FRS_OVERLAPS_STAGE, "EVENT_FRS_OVERLAPS_STAGE"},
  82. {EVENT_FRS_OVERLAPS_ROOT, "EVENT_FRS_OVERLAPS_ROOT"},
  83. {EVENT_FRS_OVERLAPS_OTHER_STAGE, "EVENT_FRS_OVERLAPS_OTHER_STAGE"},
  84. {EVENT_FRS_PREPARE_ROOT_FAILED, "EVENT_FRS_PREPARE_ROOT_FAILED"},
  85. {EVENT_FRS_BAD_REG_DATA, "EVENT_FRS_BAD_REG_DATA"},
  86. {EVENT_FRS_JOIN_FAIL_TIME_SKEW, "EVENT_FRS_JOIN_FAIL_TIME_SKEW"},
  87. {EVENT_FRS_RMTCO_TIME_SKEW, "EVENT_FRS_RMTCO_TIME_SKEW"},
  88. {EVENT_FRS_CANT_OPEN_STAGE, "EVENT_FRS_CANT_OPEN_STAGE"},
  89. {EVENT_FRS_CANT_OPEN_PREINSTALL, "EVENT_FRS_CANT_OPEN_PREINSTALL"},
  90. {EVENT_FRS_REPLICA_SET_CREATE_FAIL, "EVENT_FRS_REPLICA_SET_CREATE_FAIL"},
  91. {EVENT_FRS_REPLICA_SET_CREATE_OK, "EVENT_FRS_REPLICA_SET_CREATE_OK"},
  92. {EVENT_FRS_REPLICA_SET_CXTIONS, "EVENT_FRS_REPLICA_SET_CXTIONS"},
  93. {EVENT_FRS_IN_ERROR_STATE, "EVENT_FRS_IN_ERROR_STATE"},
  94. {EVENT_FRS_REPLICA_NO_ROOT_CHANGE, "EVENT_FRS_REPLICA_NO_ROOT_CHANGE"},
  95. {EVENT_FRS_DUPLICATE_IN_CXTION_SYSVOL, "EVENT_FRS_DUPLICATE_IN_CXTION_SYSVOL"},
  96. {EVENT_FRS_DUPLICATE_IN_CXTION, "EVENT_FRS_DUPLICATE_IN_CXTION"},
  97. {EVENT_FRS_ROOT_HAS_MOVED, "EVENT_FRS_ROOT_HAS_MOVED"},
  98. {EVENT_FRS_ERROR_REPLICA_SET_DELETED, "EVENT_FRS_ERROR_REPLICA_SET_DELETED"},
  99. {EVENT_FRS_REPLICA_IN_JRNL_WRAP_ERROR, "EVENT_FRS_REPLICA_IN_JRNL_WRAP_ERROR"},
  100. {EVENT_FRS_DS_POLL_ERROR_SUMMARY, "EVENT_FRS_DS_POLL_ERROR_SUMMARY"},
  101. {EVENT_FRS_STAGE_HAS_CHANGED, "EVENT_FRS_STAGE_HAS_CHANGED"},
  102. {EVENT_FRS_LOG_SPACE, "EVENT_FRS_LOG_SPACE"},
  103. {EVENT_FRS_SYSVOL_NOT_READY_2, "EVENT_FRS_SYSVOL_NOT_READY_2"},
  104. {EVENT_FRS_SYSVOL_NOT_READY_PRIMARY_2, "EVENT_FRS_SYSVOL_NOT_READY_PRIMARY_2"},
  105. {EVENT_FRS_FILE_UPDATES_SUPPRESSED, "EVENT_FRS_FILE_UPDATES_SUPPRESSED"},
  106. {EVENT_FRS_REPLICA_IN_JRNL_WRAP_NO_AUTO_RESTORE, "EVENT_FRS_REPLICA_IN_JRNL_WRAP_NO_AUTO_RESTORE"},
  107. {EVENT_FRS_FILES_SKIPPED_DURING_PRIMARY_LOAD, "EVENT_FRS_FILES_SKIPPED_DURING_PRIMARY_LOAD"},
  108. {0 , "Event tag not found"}
  109. };
  110. PCHAR FrsEventIdToTag (
  111. DWORD ID
  112. )
  113. {
  114. DWORD j = 0;
  115. while ((FrsEvents[j].EventId != ID) && (FrsEvents[j].EventId != 0)) {j++;}
  116. return FrsEvents[j].EventTag;
  117. }
  118. DWORD
  119. ELHashFunction (
  120. IN PVOID Qkey,
  121. IN ULONG len
  122. )
  123. /*++
  124. Routine Description:
  125. This is the hashing function used by the functions that Lookup,
  126. Add or Delete entries from the Hash Tables. The Key is a 64 bit
  127. number and the hashing function casts it to a 32 bit number and
  128. returns it as the hash value.
  129. Arguments:
  130. QKey - Pointer to the Key to be hashed.
  131. len - Length of QKey (unused here).
  132. Return Value:
  133. The hashed value of the Key.
  134. --*/
  135. {
  136. #undef DEBSUB
  137. #define DEBSUB "ELHashFunction:"
  138. ULONG key; // hashed key value to be returned
  139. PULONGLONG p; // hash the key to PULONGLONG
  140. FRS_ASSERT(Qkey != NULL);
  141. p = (PULONGLONG)Qkey;
  142. key = (ULONG)*p;
  143. return (key);
  144. }
  145. BOOL
  146. FrsEventLogFilter(
  147. IN DWORD EventMessageId,
  148. IN PWCHAR *ArrOfPtrToArgs,
  149. IN DWORD NumOfArgs
  150. )
  151. /*++
  152. Routine Description:
  153. This function is used to filter out eventlogs messages
  154. which have been already written to the EventLog in the
  155. last EVENTLOG_FILTER_TIME sec.
  156. This is done so that the eventlog does not get filled
  157. up with noisy similar messages.
  158. WARNING -- this function may be called from inside of DPRINTs. So
  159. do not call DPRINT (or any function referenced by
  160. DPRINT) from this function.
  161. DPRINTS below are left for testing but normally are commented out.
  162. Arguments:
  163. EventMessageId - Supplies the message ID to be logged.
  164. ArrOfPtrToArgs - Array of pointers to Arguments passed
  165. in to the FrsEventLogx functions.
  166. NumOfArgs - The number of elements in the above
  167. array
  168. Return Value:
  169. TRUE - Print the entry in the eventlog
  170. FALSE - Do not print the entry
  171. --*/
  172. {
  173. #undef DEBSUB
  174. #define DEBSUB "FrsEventLogFilter:"
  175. DWORD i, j, sc = 0; // sc = shiftcount while calc the hash value
  176. ULONGLONG QKey = 0; // The hash key value
  177. ULONGLONG QVal = 0;
  178. DWORD GStatus;
  179. ULONGLONG Data;
  180. ULONG_PTR Flags;
  181. FILETIME CurrentTime;
  182. LARGE_INTEGER CT;
  183. LONGLONG TimeDiff = 0;
  184. //DPRINT2(5, "ELOG:Filter Request came in with %08x args and an ID value of %08x\n",
  185. // NumOfArgs, EventMessageId);
  186. //
  187. // Quit if event log not yet initialized.
  188. //
  189. if (!EventLogRunning) {
  190. return FALSE;
  191. }
  192. //
  193. // Calculate the hash key using the arguments that came in.
  194. // Assign the Id value to the QKey to start with.
  195. //
  196. QKey = EventMessageId;
  197. //
  198. // To calculate the value of QKey, every character of every argument
  199. // is taken, cast to a ULONGLONG left shifted by (0, 4, 8....60) and then
  200. // added to the value of QKey
  201. //
  202. for (i = 0; i < NumOfArgs; i++) {
  203. if (ArrOfPtrToArgs[i]) {
  204. for (j = 0; ArrOfPtrToArgs[i][j] != L'\0'; j++) {
  205. QVal = (ULONGLONG)ArrOfPtrToArgs[i][j];
  206. QVal = QVal << sc;
  207. sc += 4;
  208. if (sc >= 60) {
  209. sc = 0;
  210. }
  211. QKey += QVal;
  212. }
  213. }
  214. }
  215. //
  216. // QKey should never be zero
  217. //
  218. if (QKey == 0) {
  219. QKey = EventMessageId;
  220. }
  221. //
  222. // Lookup this entry in the table. If it exists, get the time associated
  223. // with this entry. If the difference between the current time and the
  224. // time associated with the entry is greater than EVENTLOG_FILTER_TIME
  225. // sec, update the entry and return TRUE, otherwise return FALSE If the
  226. // entry for this key does not exist in the hash table, then this is the
  227. // first time this key is being written to the eventlog. In this case,
  228. // add the entry to the hash table, associate the current time with it and
  229. // return TRUE
  230. //
  231. GStatus = QHashLookup(HTEventLogTimes, &(QKey), &Data, &Flags);
  232. if (GStatus == GHT_STATUS_SUCCESS) {
  233. //
  234. // Key exists, now compare the time values
  235. //
  236. GetSystemTimeAsFileTime(&CurrentTime);
  237. CT.LowPart = CurrentTime.dwLowDateTime;
  238. CT.HighPart = CurrentTime.dwHighDateTime;
  239. TimeDiff = ((((LONGLONG)CT.QuadPart) / (LONGLONG)CONVERTTOSEC) - (LONGLONG)Data);
  240. //DPRINT1(5, "ELOG:The value of TimeDiff is %08x %08x\n", PRINTQUAD(TimeDiff));
  241. if (TimeDiff > EVENTLOG_FILTER_TIME) {
  242. //
  243. // UpDate the hash table entry. GetSystemTimeAsFileTime
  244. // retuns the time in 100 nano (100 * 10^9) sec units. Hence
  245. // to get it in sec we need to divide by (10^7)
  246. //
  247. Data = (((ULONGLONG)CT.QuadPart) / (ULONGLONG)CONVERTTOSEC);
  248. GStatus = QHashUpdate(HTEventLogTimes, &(QKey), &Data, Flags);
  249. if (GStatus == GHT_STATUS_FAILURE) {
  250. //DPRINT2(5, "ELOG:QHashUpdate failed while updating ID %08x with QKey %08x %08x\n",
  251. // EventMessageId, PRINTQUAD(QKey));
  252. } else {
  253. //DPRINT2(5, "ELOG:Update was successful for eventlog entry with ID %08x and QKey %08x %08x\n",
  254. // EventMessageId, PRINTQUAD(QKey));
  255. }
  256. return TRUE;
  257. }
  258. else {
  259. //
  260. // This event log entry should not be written
  261. //
  262. //DPRINT2(5, "ELOG: Did not add the ID %08x with QKey %08x %08x to the EventLog\n",
  263. // EventMessageId, PRINTQUAD(QKey));
  264. return FALSE;
  265. }
  266. } else {
  267. //
  268. // Key does not exist
  269. // Create a new entry for it
  270. //
  271. //DPRINT2(5, "ELOG:Got a new eventlog entry with ID %08x and QKey %08x %08x\n",
  272. // EventMessageId, PRINTQUAD(QKey));
  273. //
  274. // Get the current system time
  275. //
  276. GetSystemTimeAsFileTime(&CurrentTime);
  277. CT.LowPart = CurrentTime.dwLowDateTime;
  278. CT.HighPart = CurrentTime.dwHighDateTime;
  279. //
  280. // GetSystemTimeAsFileTime retuns the time in 100 nano
  281. // (100 * 10^9) sec units. Hence to get it in sec we need to
  282. // divide by (10^7)
  283. //
  284. Data = (((ULONGLONG)CT.QuadPart) / (ULONGLONG)CONVERTTOSEC);
  285. //
  286. // Insert the new entry into the hash table
  287. //
  288. GStatus = QHashInsert(HTEventLogTimes, &QKey, &Data, 0, FALSE);
  289. if (GStatus == GHT_STATUS_FAILURE) {
  290. //DPRINT2(5, "ELOG:QHashInsert failed while Inserting ID %08x with QKey %08x %08x\n",
  291. // EventMessageId, PRINTQUAD(QKey));
  292. } else {
  293. //DPRINT2(5, "ELOG:Insert was successful for eventlog entry with ID %08x and QKey %08x %08x\n",
  294. // EventMessageId, PRINTQUAD(QKey));
  295. }
  296. return TRUE;
  297. }
  298. }
  299. VOID
  300. InitializeEventLog(
  301. VOID
  302. )
  303. /*++
  304. Routine Description:
  305. Create the event log entry and setup the event log handle.
  306. Arguments:
  307. None.
  308. Return Value:
  309. None.
  310. --*/
  311. {
  312. #undef DEBSUB
  313. #define DEBSUB "InitializeEventLog:"
  314. DWORD WStatus;
  315. PWCHAR Path = NULL;
  316. HANDLE hEventLog;
  317. HKEY EventLogKey = INVALID_HANDLE_VALUE;
  318. HKEY FrsEventLogKey = INVALID_HANDLE_VALUE;
  319. HKEY FrsSourceKey = INVALID_HANDLE_VALUE;
  320. //
  321. // create the hash table and assign the hash function. The table
  322. // is used for storing eventlog times of similar messages. These
  323. // values of time are used in filtering these similar messages
  324. //
  325. HTEventLogTimes = FrsAllocTypeSize(QHASH_TABLE_TYPE, ELHASHTABLESIZE);
  326. SET_QHASH_TABLE_HASH_CALC(HTEventLogTimes, ELHashFunction);
  327. //
  328. // EventLog Key - <SERVICE_ROOT>\EventLog
  329. //
  330. WStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  331. EVENTLOG_ROOT,
  332. 0,
  333. KEY_ALL_ACCESS,
  334. &EventLogKey);
  335. CLEANUP1_WS(0, "WARN - Cannot open %ws;", EVENTLOG_ROOT, WStatus, CLEANUP);
  336. //
  337. // Set new eventlog source in the registry
  338. //
  339. WStatus = RegCreateKey(EventLogKey, SERVICE_LONG_NAME, &FrsEventLogKey);
  340. CLEANUP1_WS(0, "WARN - Cannot create %ws;", FRS_EVENTLOG_SECTION, WStatus, CLEANUP);
  341. //
  342. // Add the following values to the Reg key HKLM.....\EventLog\File Replication Service
  343. // 1. File 2. Retention 3. MaxSize
  344. //
  345. // If the values already exist then preserve them.
  346. //
  347. //
  348. // Event log file name -- "%SystemRoot%\system32\config\NtFrs.Evt"
  349. //
  350. CfgRegWriteString(FKC_EVENTLOG_FILE,
  351. SERVICE_LONG_NAME,
  352. FRS_RKF_FORCE_DEFAULT_VALUE | FRS_RKF_KEEP_EXISTING_VALUE,
  353. 0);
  354. //
  355. // Retention
  356. //
  357. CfgRegWriteDWord(FKC_EVENTLOG_RETENTION,
  358. SERVICE_LONG_NAME,
  359. FRS_RKF_FORCE_DEFAULT_VALUE | FRS_RKF_KEEP_EXISTING_VALUE,
  360. 0);
  361. //
  362. // MaxSize
  363. //
  364. CfgRegWriteDWord(FKC_EVENTLOG_MAXSIZE,
  365. SERVICE_LONG_NAME,
  366. FRS_RKF_FORCE_DEFAULT_VALUE | FRS_RKF_KEEP_EXISTING_VALUE,
  367. 0);
  368. //
  369. // DisplayNameID
  370. //
  371. CfgRegWriteDWord(FKC_EVENTLOG_DISPLAY_NAMEID,
  372. SERVICE_LONG_NAME,
  373. FRS_RKF_FORCE_DEFAULT_VALUE | FRS_RKF_KEEP_EXISTING_VALUE,
  374. 0);
  375. //
  376. // DisplayNameFile
  377. //
  378. CfgRegWriteString(FKC_EVENTLOG_DISPLAY_FILENAME,
  379. SERVICE_LONG_NAME,
  380. FRS_RKF_FORCE_DEFAULT_VALUE | FRS_RKF_KEEP_EXISTING_VALUE,
  381. NULL);
  382. //
  383. // CustomSD : used to make FRS eventlogs secure.
  384. //
  385. CfgRegWriteString(FKC_EVENTLOG_CUSTOM_SD,
  386. SERVICE_LONG_NAME,
  387. FRS_RKF_FORCE_DEFAULT_VALUE | FRS_RKF_KEEP_EXISTING_VALUE,
  388. NULL);
  389. //
  390. // Event Message File
  391. //
  392. WStatus = RegSetValueEx(FrsEventLogKey,
  393. L"Sources",
  394. 0,
  395. REG_MULTI_SZ,
  396. (PCHAR)(SERVICE_NAME L"\0"
  397. SERVICE_LONG_NAME L"\0"),
  398. (wcslen(SERVICE_NAME) +
  399. wcslen(SERVICE_LONG_NAME) +
  400. 3) * sizeof(WCHAR));
  401. CLEANUP1_WS(0, "WARN - Cannot set event log value Sources for %ws;",
  402. SERVICE_LONG_NAME, WStatus, CLEANUP);
  403. //
  404. // Get the message file path. (expanding any environment vars).
  405. //
  406. CfgRegReadString(FKC_FRS_MESSAGE_FILE_PATH, NULL, 0, &Path);
  407. //
  408. // Add values for message file and event types for each event log source.
  409. //
  410. CfgRegWriteString(FKC_EVENTLOG_EVENT_MSG_FILE, SERVICE_NAME, 0, Path);
  411. CfgRegWriteString(FKC_EVENTLOG_EVENT_MSG_FILE, SERVICE_LONG_NAME, 0, Path);
  412. CfgRegWriteDWord(FKC_EVENTLOG_TYPES_SUPPORTED,
  413. SERVICE_NAME,
  414. FRS_RKF_FORCE_DEFAULT_VALUE,
  415. 0);
  416. CfgRegWriteDWord(FKC_EVENTLOG_TYPES_SUPPORTED,
  417. SERVICE_LONG_NAME,
  418. FRS_RKF_FORCE_DEFAULT_VALUE,
  419. 0);
  420. //
  421. // Unfortunately, this call will succeed with the Application log file
  422. // instead of the File Replication Log file if the EventLog service has not
  423. // yet reacted to the change notify of the updated registry keys above.
  424. // Hence, the source will be re-registered for each event so that ntfrs
  425. // events eventually show up in the file replication service log. The
  426. // register/deregister pair allows EventLog some extra time so that MAYBE
  427. // the first event will show up in the right log.
  428. //
  429. // The eventlog folk may someday supply an interface to see if
  430. // the register was kicked into Application.
  431. //
  432. hEventLog = RegisterEventSource(NULL, SERVICE_NAME);
  433. if (hEventLog) {
  434. DeregisterEventSource(hEventLog);
  435. }
  436. WStatus = ERROR_SUCCESS;
  437. EventLogRunning = TRUE;
  438. DPRINT(0, "Event Log is running\n");
  439. CLEANUP:
  440. DPRINT_WS(0, "ERROR - Cannot start event logging;", WStatus);
  441. FRS_REG_CLOSE(EventLogKey);
  442. FRS_REG_CLOSE(FrsEventLogKey);
  443. FrsFree(Path);
  444. }
  445. void FrsPrintEvent(
  446. IN DWORD Severity,
  447. IN DWORD EventMessageId,
  448. IN PWCHAR *ArgArray,
  449. IN DWORD NumOfArgs
  450. )
  451. /*++
  452. Routine Description:
  453. Print the message ID and the substitution strings to the debug logs.
  454. Arguments:
  455. Severity -- Severity level of DPRINT to debug log.
  456. EventMessageId -- FRS event log message ID.
  457. ArgArray -- Array of insertion strings.
  458. NumOfArgs -- Num of insertion strings.
  459. Return Value:
  460. None.
  461. --*/
  462. {
  463. #undef DEBSUB
  464. #define DEBSUB "FrsPrintEvent:"
  465. DWORD j, EventType;
  466. char *EventTypeStr;
  467. WCHAR TimeBuf[MAX_PATH];
  468. WCHAR DateBuf[MAX_PATH];
  469. TimeBuf[0] = L'\0';
  470. DateBuf[0] = L'\0';
  471. GetTimeFormat(LOCALE_SYSTEM_DEFAULT, 0, NULL, L"HH':'mm':'ss", TimeBuf, MAX_PATH);
  472. GetDateFormat(LOCALE_SYSTEM_DEFAULT, 0, NULL, L"ddd',' MMM dd yyyy", DateBuf, MAX_PATH);
  473. EventType = MESSAGEID_TO_EVENTTYPE(EventMessageId);
  474. if (EventType == EVENTLOG_SUCCESS) {EventTypeStr = "Success";
  475. } else if (EventType & EVENTLOG_ERROR_TYPE) {EventTypeStr = "Error";
  476. } else if (EventType & EVENTLOG_WARNING_TYPE) {EventTypeStr = "Warn";
  477. } else if (EventType & EVENTLOG_INFORMATION_TYPE) {EventTypeStr = "Info";
  478. } else if (EventType & EVENTLOG_AUDIT_SUCCESS) {EventTypeStr = "AudSuccess";
  479. } else if (EventType & EVENTLOG_AUDIT_FAILURE) {EventTypeStr = "AudFail";
  480. } else {EventTypeStr = "Unknown";
  481. }
  482. //
  483. // It is possible that we are being called within a Debug print (e.g.
  484. // an exception handler). If we can't get the lock then we can't print.
  485. //
  486. if (DebTryLock()) {
  487. try {
  488. DPRINT_NOLOCK5(Severity, ":E: Eventlog written for %s (%d) severity: %s at: %ws %ws\n",
  489. FrsEventIdToTag(EventMessageId),
  490. EventMessageId & 0x3FFFFFFF,
  491. EventTypeStr, DateBuf, TimeBuf);
  492. if ((ArgArray != NULL) && (NumOfArgs > 0)) {
  493. DPRINT_NOLOCK(Severity, ":E: STRINGS: \n");
  494. for (j=0; j<NumOfArgs; j++) {
  495. DPRINT_NOLOCK2(Severity, ":E: %d : '%ws'\n", j,
  496. (ArgArray[j] != NULL) ? ArgArray[j] : L"<null>");
  497. }
  498. }
  499. } except (EXCEPTION_EXECUTE_HANDLER) {
  500. //
  501. // Catch any exception and drop the lock.
  502. //
  503. NOTHING;
  504. }
  505. DebUnLock();
  506. }
  507. }
  508. DWORD
  509. FrsReportEvent(
  510. IN DWORD EventMessageId,
  511. IN PWCHAR *ArgArray,
  512. IN DWORD NumOfArgs
  513. )
  514. /*++
  515. Routine Description:
  516. This function is used to register the event source and post the event.
  517. WARNING -- this function may be called from inside of DPRINTs. So
  518. do not call DPRINT (or any function referenced by
  519. DPRINT) from this function.
  520. Arguments:
  521. EventMessageId - Supplies the message ID to be logged.
  522. ArgArray - Array of pointers to Arguments passed
  523. in to the FrsEventLogx functions.
  524. NumOfArgs - The number of elements in the above
  525. array
  526. Return Value:
  527. Win32 Status.
  528. --*/
  529. {
  530. #undef DEBSUB
  531. #define DEBSUB "FrsReportEvent:"
  532. DWORD WStatus = ERROR_SUCCESS;
  533. HANDLE hEventLog;
  534. UINT i;
  535. PWCHAR ResStr;
  536. WORD EventType;
  537. hEventLog = RegisterEventSource(NULL, SERVICE_NAME);
  538. if (!HANDLE_IS_VALID(hEventLog)) {
  539. WStatus = GetLastError();
  540. if (!WIN_SUCCESS(WStatus)) {
  541. //
  542. // It is possible that we are being called within a Debug print (e.g.
  543. // an exception handler). If we can't get the lock then we can't print.
  544. //
  545. if (DebTryLock()) {
  546. try {
  547. DPRINT_NOLOCK1(1, ":E: WARN - Cannot register event source; WStatus: %s\n",
  548. ErrLabelW32(WStatus) );
  549. } finally {
  550. //
  551. // If the above took an exception make sure we drop the lock.
  552. //
  553. DebUnLock();
  554. }
  555. }
  556. }
  557. return WStatus;
  558. }
  559. //
  560. // Check if any argument exceeds the 32K size limit. If it does then truncate it
  561. // and indicate that the event log message size has been exceeded.
  562. //
  563. for (i=0;i<NumOfArgs;++i) {
  564. if (wcslen(ArgArray[i]) > 32000/sizeof(WCHAR)) { //Each string has a limit of 32K bytes.
  565. ResStr = FrsGetResourceStr(IDS_EVENT_LOG_MSG_SIZE_EXCEEDED);
  566. wcscpy(&ArgArray[i][32000/sizeof(WCHAR) - 500], ResStr);
  567. FrsFree(ResStr);
  568. }
  569. }
  570. //
  571. //
  572. // The Event Type is is part of the message ID (upper two bits) and should
  573. // map to be one of the following:
  574. // EVENTLOG_SUCCESS Success event
  575. // EVENTLOG_ERROR_TYPE Error event
  576. // EVENTLOG_WARNING_TYPE Warning event
  577. // EVENTLOG_INFORMATION_TYPE Information event
  578. //
  579. EventType = MESSAGEID_TO_EVENTTYPE(EventMessageId);
  580. //
  581. // Report the event.
  582. //
  583. if (!ReportEvent(hEventLog, // handle returned by RegisterEventSource
  584. EventType, // event type to log
  585. 0, // event category
  586. EventMessageId, // event identifier
  587. NULL, // user security identifier (optional)
  588. (WORD) NumOfArgs, // number of strings to merge with message
  589. 0, // size of binary data, in bytes
  590. ArgArray, // array of strings to merge with message
  591. NULL)) { // address of binary data
  592. WStatus = GetLastError();
  593. }
  594. DeregisterEventSource(hEventLog);
  595. if (!WIN_SUCCESS(WStatus)) {
  596. if (DebTryLock()) {
  597. try {
  598. DPRINT_NOLOCK3(0, ":E: Failed to report event log message. %s (%d); WStatus: %s\n",
  599. FrsEventIdToTag(EventMessageId), EventMessageId, ErrLabelW32(WStatus) );
  600. } finally {
  601. //
  602. // If the above took an exception make sure we drop the lock.
  603. //
  604. DebUnLock();
  605. }
  606. }
  607. }
  608. return WStatus;
  609. }
  610. /*++
  611. Routine Description:
  612. The following functions Log an event to the event log with
  613. from zero to six insertion strings.
  614. WARNING -- these functions may be called from inside of DPRINTs. So
  615. do not call DPRINT (or any function referenced by
  616. DPRINT) from this function.
  617. Arguments:
  618. EventMessageId - Supplies the message ID to be logged.
  619. EventMessage1..6 - Insertion strings
  620. Return Value:
  621. None.
  622. --*/
  623. VOID
  624. FrsEventLog0(
  625. IN DWORD EventMessageId
  626. )
  627. {
  628. #undef DEBSUB
  629. #define DEBSUB "FrsEventLog0:"
  630. DWORD Severity = 4;
  631. //
  632. // Check to see if this eventlog request can be filtered.
  633. //
  634. if (FrsEventLogFilter(EventMessageId, NULL, 0)) {
  635. FrsReportEvent(EventMessageId, NULL, 0);
  636. Severity = 0;
  637. }
  638. FrsPrintEvent(Severity, EventMessageId, NULL, 0);
  639. }
  640. VOID
  641. FrsEventLog1(
  642. IN DWORD EventMessageId,
  643. IN PWCHAR EventMessage1
  644. )
  645. {
  646. #undef DEBSUB
  647. #define DEBSUB "FrsEventLog1:"
  648. DWORD Severity = 4;
  649. PWCHAR ArgArray[1];
  650. //
  651. // Check to see if this eventlog request can be filtered.
  652. //
  653. ArgArray[0] = EventMessage1;
  654. if (FrsEventLogFilter(EventMessageId, ArgArray, 1)) {
  655. FrsReportEvent(EventMessageId, ArgArray, 1);
  656. Severity = 0;
  657. }
  658. FrsPrintEvent(Severity, EventMessageId, ArgArray, 1);
  659. }
  660. VOID
  661. FrsEventLog2(
  662. IN DWORD EventMessageId,
  663. IN PWCHAR EventMessage1,
  664. IN PWCHAR EventMessage2
  665. )
  666. {
  667. #undef DEBSUB
  668. #define DEBSUB "FrsEventLog2:"
  669. DWORD Severity = 4;
  670. PWCHAR ArgArray[2];
  671. //
  672. // Check to see if this eventlog request can be filtered.
  673. //
  674. ArgArray[0] = EventMessage1;
  675. ArgArray[1] = EventMessage2;
  676. if (FrsEventLogFilter(EventMessageId, ArgArray, 2)) {
  677. FrsReportEvent(EventMessageId, ArgArray, 2);
  678. Severity = 0;
  679. }
  680. FrsPrintEvent(Severity, EventMessageId, ArgArray, 2);
  681. }
  682. VOID
  683. FrsEventLog3(
  684. IN DWORD EventMessageId,
  685. IN PWCHAR EventMessage1,
  686. IN PWCHAR EventMessage2,
  687. IN PWCHAR EventMessage3
  688. )
  689. {
  690. #undef DEBSUB
  691. #define DEBSUB "FrsEventLog3:"
  692. DWORD Severity = 4;
  693. PWCHAR ArgArray[3];
  694. //
  695. // Check to see if this eventlog request can be filtered.
  696. //
  697. ArgArray[0] = EventMessage1;
  698. ArgArray[1] = EventMessage2;
  699. ArgArray[2] = EventMessage3;
  700. if (FrsEventLogFilter(EventMessageId, ArgArray, 3)) {
  701. FrsReportEvent(EventMessageId, ArgArray, 3);
  702. Severity = 0;
  703. }
  704. FrsPrintEvent(Severity, EventMessageId, ArgArray, 3);
  705. }
  706. VOID
  707. FrsEventLog4(
  708. IN DWORD EventMessageId,
  709. IN PWCHAR EventMessage1,
  710. IN PWCHAR EventMessage2,
  711. IN PWCHAR EventMessage3,
  712. IN PWCHAR EventMessage4
  713. )
  714. {
  715. #undef DEBSUB
  716. #define DEBSUB "FrsEventLog4:"
  717. DWORD Severity = 4;
  718. PWCHAR ArgArray[4];
  719. //
  720. // Check to see if this eventlog request can be filtered.
  721. //
  722. ArgArray[0] = EventMessage1;
  723. ArgArray[1] = EventMessage2;
  724. ArgArray[2] = EventMessage3;
  725. ArgArray[3] = EventMessage4;
  726. if (FrsEventLogFilter(EventMessageId, ArgArray, 4)) {
  727. FrsReportEvent(EventMessageId, ArgArray, 4);
  728. Severity = 0;
  729. }
  730. FrsPrintEvent(Severity, EventMessageId, ArgArray, 4);
  731. }
  732. VOID
  733. FrsEventLog5(
  734. IN DWORD EventMessageId,
  735. IN PWCHAR EventMessage1,
  736. IN PWCHAR EventMessage2,
  737. IN PWCHAR EventMessage3,
  738. IN PWCHAR EventMessage4,
  739. IN PWCHAR EventMessage5
  740. )
  741. {
  742. #undef DEBSUB
  743. #define DEBSUB "FrsEventLog5:"
  744. DWORD Severity = 4;
  745. PWCHAR ArgArray[5];
  746. //
  747. // Check to see if this eventlog request can be filtered.
  748. //
  749. ArgArray[0] = EventMessage1;
  750. ArgArray[1] = EventMessage2;
  751. ArgArray[2] = EventMessage3;
  752. ArgArray[3] = EventMessage4;
  753. ArgArray[4] = EventMessage5;
  754. if (FrsEventLogFilter(EventMessageId, ArgArray, 5)) {
  755. FrsReportEvent(EventMessageId, ArgArray, 5);
  756. Severity = 0;
  757. }
  758. FrsPrintEvent(Severity, EventMessageId, ArgArray, 5);
  759. }
  760. VOID
  761. FrsEventLog6(
  762. IN DWORD EventMessageId,
  763. IN PWCHAR EventMessage1,
  764. IN PWCHAR EventMessage2,
  765. IN PWCHAR EventMessage3,
  766. IN PWCHAR EventMessage4,
  767. IN PWCHAR EventMessage5,
  768. IN PWCHAR EventMessage6
  769. )
  770. {
  771. #undef DEBSUB
  772. #define DEBSUB "FrsEventLog6:"
  773. DWORD Severity = 4;
  774. PWCHAR ArgArray[6];
  775. //
  776. // Check to see if this eventlog request can be filtered.
  777. //
  778. ArgArray[0] = EventMessage1;
  779. ArgArray[1] = EventMessage2;
  780. ArgArray[2] = EventMessage3;
  781. ArgArray[3] = EventMessage4;
  782. ArgArray[4] = EventMessage5;
  783. ArgArray[5] = EventMessage6;
  784. if (FrsEventLogFilter(EventMessageId, ArgArray, 6)) {
  785. FrsReportEvent(EventMessageId, ArgArray, 6);
  786. Severity = 0;
  787. }
  788. FrsPrintEvent(Severity, EventMessageId, ArgArray, 6);
  789. }
  790. VOID
  791. FrsEventLog7(
  792. IN DWORD EventMessageId,
  793. IN PWCHAR EventMessage1,
  794. IN PWCHAR EventMessage2,
  795. IN PWCHAR EventMessage3,
  796. IN PWCHAR EventMessage4,
  797. IN PWCHAR EventMessage5,
  798. IN PWCHAR EventMessage6,
  799. IN PWCHAR EventMessage7
  800. )
  801. {
  802. #undef DEBSUB
  803. #define DEBSUB "FrsEventLog7:"
  804. DWORD Severity = 4;
  805. PWCHAR ArgArray[7];
  806. //
  807. // Check to see if this eventlog request can be filtered.
  808. //
  809. ArgArray[0] = EventMessage1;
  810. ArgArray[1] = EventMessage2;
  811. ArgArray[2] = EventMessage3;
  812. ArgArray[3] = EventMessage4;
  813. ArgArray[4] = EventMessage5;
  814. ArgArray[5] = EventMessage6;
  815. ArgArray[6] = EventMessage7;
  816. if (FrsEventLogFilter(EventMessageId, ArgArray, 7)) {
  817. FrsReportEvent(EventMessageId, ArgArray, 7);
  818. Severity = 0;
  819. }
  820. FrsPrintEvent(Severity, EventMessageId, ArgArray, 7);
  821. }
  822. VOID
  823. FrsEventLog8(
  824. IN DWORD EventMessageId,
  825. IN PWCHAR EventMessage1,
  826. IN PWCHAR EventMessage2,
  827. IN PWCHAR EventMessage3,
  828. IN PWCHAR EventMessage4,
  829. IN PWCHAR EventMessage5,
  830. IN PWCHAR EventMessage6,
  831. IN PWCHAR EventMessage7,
  832. IN PWCHAR EventMessage8
  833. )
  834. {
  835. #undef DEBSUB
  836. #define DEBSUB "FrsEventLog8:"
  837. DWORD Severity = 4;
  838. PWCHAR ArgArray[8];
  839. //
  840. // Check to see if this eventlog request can be filtered.
  841. //
  842. ArgArray[0] = EventMessage1;
  843. ArgArray[1] = EventMessage2;
  844. ArgArray[2] = EventMessage3;
  845. ArgArray[3] = EventMessage4;
  846. ArgArray[4] = EventMessage5;
  847. ArgArray[5] = EventMessage6;
  848. ArgArray[6] = EventMessage7;
  849. ArgArray[7] = EventMessage8;
  850. if (FrsEventLogFilter(EventMessageId, ArgArray, 8)) {
  851. FrsReportEvent(EventMessageId, ArgArray, 8);
  852. Severity = 0;
  853. }
  854. FrsPrintEvent(Severity, EventMessageId, ArgArray, 8);
  855. }
  856. VOID
  857. FrsEventLog9(
  858. IN DWORD EventMessageId,
  859. IN PWCHAR EventMessage1,
  860. IN PWCHAR EventMessage2,
  861. IN PWCHAR EventMessage3,
  862. IN PWCHAR EventMessage4,
  863. IN PWCHAR EventMessage5,
  864. IN PWCHAR EventMessage6,
  865. IN PWCHAR EventMessage7,
  866. IN PWCHAR EventMessage8,
  867. IN PWCHAR EventMessage9
  868. )
  869. {
  870. #undef DEBSUB
  871. #define DEBSUB "FrsEventLog9:"
  872. DWORD Severity = 4;
  873. PWCHAR ArgArray[9];
  874. //
  875. // Check to see if this eventlog request can be filtered.
  876. //
  877. ArgArray[0] = EventMessage1;
  878. ArgArray[1] = EventMessage2;
  879. ArgArray[2] = EventMessage3;
  880. ArgArray[3] = EventMessage4;
  881. ArgArray[4] = EventMessage5;
  882. ArgArray[5] = EventMessage6;
  883. ArgArray[6] = EventMessage7;
  884. ArgArray[7] = EventMessage8;
  885. ArgArray[8] = EventMessage9;
  886. if (FrsEventLogFilter(EventMessageId, ArgArray, 9)) {
  887. FrsReportEvent(EventMessageId, ArgArray, 9);
  888. Severity = 0;
  889. }
  890. FrsPrintEvent(Severity, EventMessageId, ArgArray, 9);
  891. }