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.

476 lines
15 KiB

  1. /*++
  2. Copyright (c) 2001 Microsoft Corporation
  3. Abstract:
  4. Implementation of standard logs support:
  5. setupact.log, setuperr.log and debug.log.
  6. Author:
  7. Souren Aghajanyan (sourenag) 24-Sep-2001
  8. Revision History:
  9. <alias> <date> <comments>
  10. --*/
  11. #include "pch.h"
  12. #include "mem.h"
  13. #include "setuplog.h"
  14. ILogManager * g_pLogManager = NULL;
  15. HINSTANCE g_ModuleInstance = NULL;
  16. DWORD g_ProcessID = 0;
  17. #define L_QUOTE1(x) L##x
  18. #define L_QUOTE(x) L_QUOTE1(x)
  19. #define TOO_LONG_MESSAGEA "Log: Too Long Message"
  20. #define TOO_LONG_MESSAGEW L_QUOTE(TOO_LONG_MESSAGEA)
  21. #define FAILED_TO_GET_MSG_FROM_IDA "Log: Failed To Get Msg From ID"
  22. #define STANDART_LOG_FIELD_SEVERITY L"Severity"
  23. #define STANDART_LOG_FIELD_MESSAGE L"Message"
  24. #define STANDART_LOG_FIELD_CONDITION L"Condition"
  25. #define STANDART_LOG_FIELD_SOURCELINENUMBER L"SourceLineNumber"
  26. #define STANDART_LOG_FIELD_SOURCEFILE L"SourceFile"
  27. #define STANDART_LOG_FIELD_SOURCEFUNCTION L"SourceFunction"
  28. #define STANDART_LOG_PROCESS_ID L"ProcessID"
  29. #define STANDART_LOG_THREAD_ID L"ThreadID"
  30. static LOG_FIELD_INFO g_infoFields[] = {
  31. {LT_DWORD, TRUE, STANDART_LOG_FIELD_SEVERITY},
  32. {LT_SZ, TRUE, STANDART_LOG_FIELD_MESSAGE},
  33. {LT_DWORD, TRUE, STANDART_LOG_PROCESS_ID},
  34. {LT_DWORD, TRUE, STANDART_LOG_THREAD_ID},
  35. {LT_SZ, FALSE, STANDART_LOG_FIELD_CONDITION},
  36. {LT_DWORD, FALSE, STANDART_LOG_FIELD_SOURCELINENUMBER},
  37. {LT_SZ, FALSE, STANDART_LOG_FIELD_SOURCEFILE},
  38. {LT_SZ, FALSE, STANDART_LOG_FIELD_SOURCEFUNCTION},
  39. };
  40. #define NUMBER_OF_FIELDS (sizeof(g_infoFields) / sizeof(g_infoFields[0]))
  41. ILogManager *
  42. STD_CALL_TYPE
  43. LogStandardInit(
  44. IN PCWSTR pDebugLogFileName,
  45. IN HINSTANCE hModuleInstance, OPTIONAL
  46. IN BOOL bCreateNew, OPTIONAL
  47. IN BOOL bExcludeSetupActLog, OPTIONAL
  48. IN BOOL bExcludeSetupErrLog, OPTIONAL
  49. IN BOOL bExcludeXMLLog, OPTIONAL
  50. IN BOOL bExcludeDebugFilter OPTIONAL
  51. )
  52. {
  53. BOOL bResult;
  54. ILogManager * pLogManager;
  55. UINT uiNumberOfFields;
  56. DWORD dwFlags = bCreateNew? DEVICE_CREATE_NEW: 0;
  57. CHAR winDirectory[MAX_PATH];
  58. WCHAR setupactDir[MAX_PATH];
  59. WCHAR setuperrDir[MAX_PATH];
  60. WCHAR setupxmlDir[MAX_PATH];
  61. if(g_pLogManager){
  62. return NULL;
  63. }
  64. uiNumberOfFields = NUMBER_OF_FIELDS;
  65. LogRegisterStockProviders();
  66. pLogManager = LogCreateLog(L"SetupLog", g_infoFields, uiNumberOfFields);
  67. if(!pLogManager){
  68. return NULL;
  69. }
  70. bResult = FALSE;
  71. GetWindowsDirectoryA(winDirectory, sizeof(winDirectory) / sizeof(winDirectory[0]));
  72. swprintf(setupactDir, L"%S\\%s", winDirectory, L"setupact.log");
  73. swprintf(setuperrDir, L"%S\\%s", winDirectory, L"setuperr.log");
  74. swprintf(setupxmlDir, L"%S\\%s", winDirectory, L"setuplog.xml");
  75. __try{
  76. LOG_DEVICE_PROV_INIT_DATA deviceActInitData = {setupactDir, dwFlags | DEVICE_WRITE_THROUGH, 0, 0};
  77. LOG_DEVICE_PROV_INIT_DATA deviceErrInitData = {setuperrDir, dwFlags, 0, 0};
  78. LOG_DEVICE_PROV_INIT_DATA deviceDbgInitData = {pDebugLogFileName, dwFlags, 0, 0};
  79. LOG_DEVICE_PROV_INIT_DATA deviceXMLInitData = {setupxmlDir, dwFlags, 0, 0};
  80. LOG_SETUPLOG_FORMAT_PROV_INIT_DATA formatterInitData = {
  81. STANDART_LOG_FIELD_SEVERITY,
  82. STANDART_LOG_FIELD_MESSAGE,
  83. 0
  84. };
  85. LOG_DEBUG_FORMAT_AND_DEVICE_PROV_INIT_DATA debugFormatterAndDevice = {
  86. STANDART_LOG_FIELD_SEVERITY,
  87. STANDART_LOG_FIELD_MESSAGE,
  88. STANDART_LOG_FIELD_CONDITION,
  89. STANDART_LOG_FIELD_SOURCELINENUMBER,
  90. STANDART_LOG_FIELD_SOURCEFILE,
  91. STANDART_LOG_FIELD_SOURCEFUNCTION
  92. };
  93. LOG_SETUPLOG_FILTER_PROV_INIT_DATA filterActInitData = {STANDART_LOG_FIELD_SEVERITY, LOG_INFO, TRUE};
  94. LOG_SETUPLOG_FILTER_PROV_INIT_DATA filterErrInitData = {STANDART_LOG_FIELD_SEVERITY, LOG_ERROR, TRUE};
  95. //LOG_SETUPLOG_FILTER_PROV_INIT_DATA filterDbgInitData = {L"Severity", LOG_INFO, L"Debug", FALSE};
  96. if(!bExcludeSetupActLog){
  97. if(!ILogManager_AddStack(pLogManager,
  98. &GUID_STANDARD_SETUPLOG_FILTER, &filterActInitData,
  99. &GUID_STANDARD_SETUPLOG_FORMATTER, &formatterInitData,
  100. &GUID_FILE_DEVICE, &deviceActInitData,
  101. NULL)){
  102. __leave;
  103. return NULL;
  104. }
  105. }
  106. if(!bExcludeSetupErrLog){
  107. if(!ILogManager_AddStack(pLogManager,
  108. &GUID_STANDARD_SETUPLOG_FILTER, &filterErrInitData,
  109. &GUID_STANDARD_SETUPLOG_FORMATTER, &formatterInitData,
  110. &GUID_FILE_DEVICE, &deviceErrInitData,
  111. NULL)){
  112. __leave;
  113. }
  114. }
  115. if(pDebugLogFileName){
  116. if(!ILogManager_AddStack(pLogManager,
  117. NULL, NULL,
  118. &GUID_STANDARD_SETUPLOG_FORMATTER, &formatterInitData,
  119. &GUID_FILE_DEVICE, &deviceDbgInitData,
  120. NULL)){
  121. __leave;
  122. }
  123. }
  124. if(!bExcludeDebugFilter){
  125. if(!ILogManager_AddStack(pLogManager,
  126. &GUID_DEBUG_FILTER, &debugFormatterAndDevice,
  127. &GUID_DEBUG_FORMATTER_AND_DEVICE, &debugFormatterAndDevice,
  128. NULL, NULL,
  129. NULL)){
  130. __leave;
  131. }
  132. }
  133. if(!bExcludeXMLLog){
  134. if(!ILogManager_AddStack(pLogManager,
  135. NULL, NULL,
  136. &GUID_XML_FORMATTER, NULL,
  137. &GUID_FILE_DEVICE, &deviceXMLInitData,
  138. NULL)){
  139. __leave;
  140. }
  141. }
  142. g_ProcessID = GetCurrentProcessId();
  143. bResult = TRUE;
  144. }
  145. __finally{
  146. if(!bResult){
  147. LogDestroyStandard();
  148. pLogManager = NULL;
  149. }
  150. }
  151. g_pLogManager = pLogManager;
  152. return pLogManager;
  153. }
  154. VOID
  155. STD_CALL_TYPE
  156. LogDestroyStandard(
  157. VOID
  158. )
  159. {
  160. if(!g_pLogManager){
  161. return;
  162. }
  163. LogDestroyLog(g_pLogManager);
  164. LogUnRegisterStockProviders();
  165. }
  166. LOGRESULT
  167. STD_CALL_TYPE
  168. LogMessageW(
  169. IN PLOG_PARTIAL_MSG pPartialMsg,
  170. IN PCSTR Condition,
  171. IN DWORD SourceLineNumber,
  172. IN PCWSTR SourceFile,
  173. IN PCWSTR SourceFunction
  174. )
  175. {
  176. LOGRESULT logResult;
  177. WCHAR unicodeConditionBuffer[MAX_MESSAGE_CHAR];
  178. PCWSTR pUnicodeCondition;
  179. DWORD lastError = GetLastError();
  180. if(!g_pLogManager || !pPartialMsg){
  181. return logError;
  182. }
  183. if(Condition){
  184. _snwprintf(unicodeConditionBuffer, MAX_MESSAGE_CHAR, L"%S", Condition);
  185. pUnicodeCondition = unicodeConditionBuffer;
  186. }
  187. else{
  188. pUnicodeCondition = NULL;
  189. }
  190. logResult = ILogManager(g_pLogManager)->LogW(g_pLogManager,
  191. NUMBER_OF_FIELDS,
  192. pPartialMsg->Severity,
  193. pPartialMsg->Message.pWStr,
  194. g_ProcessID,
  195. GetCurrentThreadId(),
  196. pUnicodeCondition,
  197. SourceLineNumber,
  198. SourceFile,
  199. SourceFunction);
  200. if(logAbortProcess == logResult){
  201. LogDestroyStandard();
  202. ExitProcess(0);
  203. }
  204. FREE(pPartialMsg);
  205. SetLastError (lastError);
  206. return logResult;
  207. }
  208. LOGRESULT
  209. STD_CALL_TYPE
  210. LogMessageA(
  211. IN PLOG_PARTIAL_MSG pPartialMsg,
  212. IN PCSTR Condition,
  213. IN DWORD SourceLineNumber,
  214. IN PCSTR SourceFile,
  215. IN PCSTR SourceFunction
  216. )
  217. {
  218. LOGRESULT logResult;
  219. DWORD lastError = GetLastError();
  220. if(!g_pLogManager || !pPartialMsg){
  221. return logError;
  222. }
  223. logResult = ILogManager(g_pLogManager)->LogA(g_pLogManager,
  224. NUMBER_OF_FIELDS,
  225. pPartialMsg->Severity,
  226. pPartialMsg->Message.pAStr,
  227. g_ProcessID,
  228. GetCurrentThreadId(),
  229. Condition,
  230. SourceLineNumber,
  231. SourceFile,
  232. SourceFunction);
  233. if(logAbortProcess == logResult){
  234. LogDestroyStandard();
  235. ExitProcess(0);
  236. }
  237. FREE(pPartialMsg);
  238. SetLastError (lastError);
  239. return logResult;
  240. }
  241. PLOG_PARTIAL_MSG
  242. STD_CALL_TYPE
  243. ConstructPartialMsgVA(
  244. IN DWORD dwSeverity,
  245. IN PCSTR Format,
  246. IN va_list args
  247. )
  248. {
  249. PLOG_PARTIAL_MSG partialMsg;
  250. PSTR ptrString;
  251. if(!g_pLogManager){
  252. return NULL;
  253. }
  254. //
  255. // improve later, by using TLS
  256. //
  257. partialMsg = (PLOG_PARTIAL_MSG)MALLOC(sizeof(LOG_PARTIAL_MSG));
  258. if(partialMsg){
  259. partialMsg->Severity = dwSeverity;
  260. if(Format){
  261. ptrString = NULL;
  262. if(!(HIWORD(Format))){
  263. //
  264. // StringID
  265. //
  266. if(!FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
  267. FORMAT_MESSAGE_FROM_HMODULE,
  268. g_ModuleInstance,
  269. (DWORD)LOWORD(Format),
  270. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  271. (PVOID)&ptrString,
  272. 0,
  273. &args)){
  274. Format = FAILED_TO_GET_MSG_FROM_IDA;
  275. }
  276. else{
  277. Format = ptrString;
  278. }
  279. }
  280. if(_vsnprintf(partialMsg->Message.pAStr,
  281. MAX_MESSAGE_CHAR,
  282. Format,
  283. args) < 0){
  284. strcpy(partialMsg->Message.pAStr, TOO_LONG_MESSAGEA);
  285. }
  286. if(ptrString){
  287. LocalFree(ptrString);
  288. }
  289. }
  290. else{
  291. partialMsg->Message.pAStr[0] = '0';
  292. }
  293. }
  294. return partialMsg;
  295. }
  296. PLOG_PARTIAL_MSG
  297. STD_CALL_TYPE
  298. ConstructPartialMsgVW(
  299. IN DWORD dwSeverity,
  300. IN PCSTR Format,
  301. IN va_list args
  302. )
  303. {
  304. PLOG_PARTIAL_MSG partialMsg;
  305. PWSTR ptrString;
  306. PCWSTR unicodeFormatString = NULL;
  307. PCWSTR pStringToFree = NULL;
  308. WCHAR unicodeBuffer[MAX_MESSAGE_CHAR];
  309. if(!g_pLogManager){
  310. return NULL;
  311. }
  312. //
  313. // improve later, by using TLS
  314. //
  315. partialMsg = (PLOG_PARTIAL_MSG)MALLOC(sizeof(LOG_PARTIAL_MSG));
  316. if(partialMsg){
  317. partialMsg->Severity = dwSeverity;
  318. if(Format){
  319. ptrString = NULL;
  320. if(!(HIWORD(Format))){
  321. //
  322. // StringID
  323. //
  324. if(!FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
  325. FORMAT_MESSAGE_FROM_HMODULE,
  326. g_ModuleInstance,
  327. (DWORD)LOWORD(Format),
  328. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  329. (PVOID)&ptrString,
  330. 0,
  331. &args)){
  332. Format = FAILED_TO_GET_MSG_FROM_IDA;
  333. }
  334. else{
  335. unicodeFormatString = ptrString;
  336. }
  337. }
  338. if(!unicodeFormatString){
  339. _snwprintf(unicodeBuffer, MAX_MESSAGE_CHAR, L"%S", Format);
  340. unicodeBuffer[MAX_MESSAGE_CHAR - 1] = 0;
  341. unicodeFormatString = unicodeBuffer;
  342. }
  343. if(_vsnwprintf(partialMsg->Message.pWStr,
  344. MAX_MESSAGE_CHAR,
  345. unicodeFormatString,
  346. args) < 0){
  347. wcscpy(partialMsg->Message.pWStr, TOO_LONG_MESSAGEW);
  348. }
  349. if(ptrString){
  350. LocalFree(ptrString);
  351. }
  352. }
  353. else{
  354. partialMsg->Message.pWStr[0] = '0';
  355. }
  356. }
  357. return partialMsg;
  358. }
  359. PLOG_PARTIAL_MSG
  360. STD_CALL_TYPE
  361. ConstructPartialMsgIfA(
  362. IN BOOL bCondition,
  363. IN DWORD dwSeverity,
  364. IN PCSTR Format,
  365. ...
  366. )
  367. {
  368. va_list args;
  369. if(!bCondition){
  370. return NULL;
  371. }
  372. va_start(args, Format);
  373. return ConstructPartialMsgVA(dwSeverity, Format, args);
  374. }
  375. PLOG_PARTIAL_MSG
  376. STD_CALL_TYPE
  377. ConstructPartialMsgIfW(
  378. IN BOOL bCondition,
  379. IN DWORD dwSeverity,
  380. IN PCSTR Format,
  381. ...
  382. )
  383. {
  384. va_list args;
  385. if(!bCondition){
  386. return NULL;
  387. }
  388. va_start(args, Format);
  389. return ConstructPartialMsgVW(dwSeverity, Format, args);
  390. }