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.

379 lines
10 KiB

  1. /*++
  2. Copyright (c) 1998 Microsoft Corporation
  3. Module Name:
  4. eventlog.c
  5. Abstract:
  6. Implementation of event logging.
  7. Author:
  8. Wesley Witt (wesw) 18-Dec-1998
  9. Revision History:
  10. Andrew Ritz (andrewr) 7-Jul-1999
  11. --*/
  12. #include "sfcp.h"
  13. #pragma hdrstop
  14. typedef BOOL (WINAPI *PPSETUPLOGSFCERROR)(PCWSTR,DWORD);
  15. //
  16. // global handle to eventlog
  17. //
  18. HANDLE hEventSrc;
  19. //
  20. // pointer to gui-setup eventlog function
  21. //
  22. PPSETUPLOGSFCERROR pSetuplogSfcError;
  23. BOOL
  24. pSfcGetSetuplogSfcError(
  25. VOID
  26. )
  27. /*++
  28. Routine Description:
  29. Routine retreives a function pointer to the error logging entrypoint in
  30. syssetup.dll
  31. Arguments:
  32. None.
  33. Return Value:
  34. TRUE for success, FALSE for failure.
  35. --*/
  36. {
  37. HMODULE hMod;
  38. if (NULL == pSetuplogSfcError) {
  39. hMod = GetModuleHandle( L"syssetup.dll" );
  40. if (hMod) {
  41. pSetuplogSfcError = (PPSETUPLOGSFCERROR)SfcGetProcAddress( hMod, "pSetuplogSfcError" );
  42. } else {
  43. DebugPrint1(LVL_MINIMAL, L"GetModuleHandle on syssetup.dll failed, ec=0x%08x",GetLastError());
  44. }
  45. }
  46. return pSetuplogSfcError != NULL;
  47. }
  48. BOOL
  49. SfcReportEvent(
  50. IN ULONG EventId,
  51. IN PCWSTR FileName,
  52. IN PCOMPLETE_VALIDATION_DATA ImageValData,
  53. IN DWORD LastError OPTIONAL
  54. )
  55. /*++
  56. Routine Description:
  57. Routine logs an event into the eventlog. Also contains a hack for logging
  58. data into the GUI-setup error log as well. we typically log unsigned files
  59. or the user tht cancelled the replacement of the signed files.
  60. Arguments:
  61. EventId - id of the eventlog error
  62. FileName - null terminated unicode string indicating the file that was
  63. unsigned, etc.
  64. ImageValData - pointer to file data for unsigned file
  65. LastError - contains an optional last error code for logging
  66. Return Value:
  67. TRUE for success, FALSE for failure.
  68. --*/
  69. {
  70. PFILE_VERSION_INFO FileVer;
  71. WCHAR SysVer[64];
  72. WCHAR BadVer[64];
  73. PCWSTR s[3];
  74. WORD Count = 0;
  75. WCHAR LastErrorText[MAX_PATH];
  76. PVOID ErrText = NULL;
  77. WORD wEventType;
  78. //
  79. // if we're in gui-mode setup, we take a special path to log into
  80. // gui-setup's logfile instead of the eventlog
  81. //
  82. if (SFCDisable == SFC_DISABLE_SETUP) {
  83. if(!pSfcGetSetuplogSfcError()) {
  84. return FALSE;
  85. }
  86. switch (EventId){
  87. case MSG_DLL_CHANGE: //fall through
  88. case MSG_SCAN_FOUND_BAD_FILE:
  89. pSetuplogSfcError( FileName,0 );
  90. break;
  91. case MSG_COPY_CANCEL_NOUI:
  92. case MSG_RESTORE_FAILURE:
  93. pSetuplogSfcError( FileName, 1 );
  94. break;
  95. case MSG_CACHE_COPY_ERROR:
  96. pSetuplogSfcError( FileName, 2 );
  97. break;
  98. default:
  99. DebugPrint1(
  100. LVL_MINIMAL,
  101. L"unexpected EventId 0x%08x in GUI Setup, ",
  102. EventId);
  103. return FALSE;
  104. //ASSERT( FALSE && L"Unexpected EventId in SfcReportEvent");
  105. }
  106. return(TRUE);
  107. }
  108. //
  109. // we're outside of GUI-setup so we really want to log to the eventlog
  110. //
  111. if (EventId == 0) {
  112. ASSERT( FALSE && L"Unexpected EventId in SfcReportEvent");
  113. return(FALSE);
  114. }
  115. //
  116. // if we don't have a handle to the eventlog, create one.
  117. //
  118. if (hEventSrc == NULL) {
  119. hEventSrc = RegisterEventSource( NULL, L"Windows File Protection" );
  120. if (hEventSrc == NULL) {
  121. DebugPrint1(LVL_MINIMAL, L"RegisterEventSource failed, ec=0x%08x",GetLastError());
  122. return(FALSE);
  123. }
  124. }
  125. ASSERT(hEventSrc != NULL);
  126. FormatMessage(
  127. FORMAT_MESSAGE_ALLOCATE_BUFFER |
  128. FORMAT_MESSAGE_FROM_SYSTEM |
  129. FORMAT_MESSAGE_IGNORE_INSERTS,
  130. NULL,
  131. LastError,
  132. 0,
  133. (PWSTR) &ErrText,
  134. 0,
  135. NULL
  136. );
  137. if (ErrText) {
  138. wsprintf(LastErrorText,L"0x%08x [%ws]",LastError,ErrText);
  139. LocalFree( ErrText );
  140. } else {
  141. wsprintf(LastErrorText,L"0x%08x",LastError);
  142. }
  143. //
  144. // pick out the appropriate message to log
  145. // the default event type is "information"
  146. //
  147. wEventType = EVENTLOG_INFORMATION_TYPE;
  148. switch (EventId) {
  149. case MSG_DLL_CHANGE:
  150. ASSERT(FileName != NULL);
  151. s[0] = FileName;
  152. //
  153. // we prefer a message that is most informative message with
  154. // version information for both dlls to the least informative
  155. // message with no version information
  156. //
  157. //
  158. if (ImageValData->New.DllVersion && ImageValData->Original.DllVersion) {
  159. FileVer = (PFILE_VERSION_INFO)&ImageValData->New.DllVersion;
  160. swprintf( SysVer, L"%d.%d.%d.%d", FileVer->VersionHigh, FileVer->VersionLow, FileVer->BuildNumber, FileVer->Revision );
  161. FileVer = (PFILE_VERSION_INFO)&ImageValData->Original.DllVersion;
  162. swprintf( BadVer, L"%d.%d.%d.%d", FileVer->VersionHigh, FileVer->VersionLow, FileVer->BuildNumber, FileVer->Revision );
  163. s[1] = BadVer;
  164. s[2] = SysVer;
  165. Count = 3;
  166. EventId = MSG_DLL_CHANGE2;
  167. } else if (ImageValData->New.DllVersion) {
  168. FileVer = (PFILE_VERSION_INFO)&ImageValData->New.DllVersion;
  169. swprintf( SysVer, L"%d.%d.%d.%d", FileVer->VersionHigh, FileVer->VersionLow, FileVer->BuildNumber, FileVer->Revision );
  170. s[1] = SysVer;
  171. Count = 2;
  172. EventId = MSG_DLL_CHANGE3;
  173. } else if (ImageValData->Original.DllVersion) {
  174. FileVer = (PFILE_VERSION_INFO)&ImageValData->Original.DllVersion;
  175. swprintf( BadVer, L"%d.%d.%d.%d", FileVer->VersionHigh, FileVer->VersionLow, FileVer->BuildNumber, FileVer->Revision );
  176. s[1] = BadVer;
  177. Count = 2;
  178. EventId = MSG_DLL_CHANGE;
  179. } else {
  180. //
  181. // we have to protect some things without version information,
  182. // so we just log an error that doesn't mention version
  183. // information. If we stop protecting files like this, this
  184. // should be an assert in prerelease versions of the code
  185. //
  186. Count = 1;
  187. EventId = MSG_DLL_CHANGE_NOVERSION;
  188. DebugPrint1( LVL_MINIMAL, L"TskTsk...the protected OS file %ws does not have any version information", FileName);
  189. }
  190. break;
  191. case MSG_SCAN_FOUND_BAD_FILE:
  192. ASSERT(FileName != NULL);
  193. s[0] = FileName;
  194. //
  195. // if we found a bad file, we only want the version of the restored file
  196. //
  197. if (ImageValData->New.DllVersion) {
  198. FileVer = (PFILE_VERSION_INFO)&ImageValData->New.DllVersion;
  199. swprintf( SysVer, L"%d.%d.%d.%d", FileVer->VersionHigh, FileVer->VersionLow, FileVer->BuildNumber, FileVer->Revision );
  200. s[1] = SysVer;
  201. Count = 2;
  202. } else {
  203. DebugPrint1( LVL_MINIMAL, L"TskTsk...the protected OS file %ws does not have any version information", FileName);
  204. EventId = MSG_SCAN_FOUND_BAD_FILE_NOVERSION;
  205. Count = 1;
  206. break;
  207. }
  208. break;
  209. case MSG_RESTORE_FAILURE:
  210. Count = 3;
  211. s[0] = FileName;
  212. s[1] = BadVer;
  213. s[2] = (PCWSTR)LastErrorText;
  214. if (ImageValData->Original.DllVersion) {
  215. FileVer = (PFILE_VERSION_INFO)&ImageValData->Original.DllVersion;
  216. swprintf( BadVer,
  217. L"%d.%d.%d.%d",
  218. FileVer->VersionHigh,
  219. FileVer->VersionLow,
  220. FileVer->BuildNumber,
  221. FileVer->Revision );
  222. } else {
  223. LoadString( SfcInstanceHandle,IDS_UNKNOWN,BadVer,UnicodeChars(BadVer));
  224. }
  225. break;
  226. case MSG_CACHE_COPY_ERROR:
  227. Count = 2;
  228. s[0] = FileName;
  229. s[1] = (PCWSTR)LastErrorText;
  230. break;
  231. case MSG_COPY_CANCEL_NOUI:
  232. //fall through
  233. case MSG_COPY_CANCEL:
  234. Count = 3;
  235. s[0] = FileName;
  236. s[1] = LoggedOnUserName;
  237. s[2] = BadVer;
  238. if (ImageValData->Original.DllVersion) {
  239. FileVer = (PFILE_VERSION_INFO)&ImageValData->Original.DllVersion;
  240. swprintf( BadVer,
  241. L"%d.%d.%d.%d",
  242. FileVer->VersionHigh,
  243. FileVer->VersionLow,
  244. FileVer->BuildNumber,
  245. FileVer->Revision );
  246. } else {
  247. LoadString( SfcInstanceHandle,IDS_UNKNOWN,BadVer,UnicodeChars(BadVer));
  248. }
  249. break;
  250. case MSG_DLL_NOVALIDATION_TERMINATION:
  251. wEventType = EVENTLOG_WARNING_TYPE;
  252. s[0] = FileName;
  253. Count = 1;
  254. break;
  255. case MSG_RESTORE_FAILURE_MAX_RETRIES:
  256. s[0] = FileName;
  257. Count = 1;
  258. break;
  259. case MSG_SCAN_STARTED:
  260. Count = 0;
  261. break;
  262. case MSG_SCAN_COMPLETED:
  263. Count = 0;
  264. break;
  265. case MSG_SCAN_CANCELLED:
  266. s[0] = LoggedOnUserName;
  267. Count = 1;
  268. break;
  269. case MSG_DISABLE:
  270. Count = 0;
  271. break;
  272. case MSG_DLLCACHE_INVALID:
  273. Count = 0;
  274. break;
  275. case MSG_SXS_INITIALIZATION_FAILED:
  276. Count = 1;
  277. s[0] = LastErrorText;
  278. break;
  279. case MSG_INITIALIZATION_FAILED:
  280. Count = 1;
  281. s[0] = LastErrorText;
  282. break;
  283. case MSG_CATALOG_RESTORE_FAILURE:
  284. Count = 2;
  285. s[0] = FileName;
  286. s[1] = LastErrorText;
  287. break;
  288. default:
  289. ASSERT( FALSE && L"Unknown EventId in SfcReportEvent");
  290. return FALSE;
  291. }
  292. return ReportEvent(
  293. hEventSrc,
  294. wEventType,
  295. 0,
  296. EventId,
  297. NULL,
  298. Count,
  299. 0,
  300. s,
  301. NULL
  302. );
  303. }