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.

454 lines
8.3 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996 - 1999
  5. //
  6. // File: debug.cpp
  7. //
  8. // Contents: Debug sub system APIs implementation
  9. //
  10. //----------------------------------------------------------------------------
  11. #include <pch.cpp>
  12. #pragma hdrstop
  13. #define DBG_CERTSRV_DEBUG_PRINT
  14. #ifdef DBG_CERTSRV_DEBUG_PRINT
  15. #include <stdarg.h>
  16. FILE *g_pfLog;
  17. DWORD g_dwPrintMask = ~(DBG_SS_INFO | DBG_SS_MODLOAD | DBG_SS_NOQUIET);
  18. CRITICAL_SECTION g_DBGCriticalSection;
  19. BOOL g_fDBGCSInit = FALSE;
  20. FNLOGSTRING *s_pfnLogString = NULL;
  21. const char *
  22. DbgGetSSString(
  23. IN DWORD dwSubSystemId)
  24. {
  25. char const *psz = NULL;
  26. if (MAXDWORD != dwSubSystemId)
  27. {
  28. switch (dwSubSystemId & ~DBG_SS_INFO)
  29. {
  30. case DBG_SS_ERROR: psz = "CertError"; break;
  31. case DBG_SS_ASSERT: psz = "CertAssert"; break;
  32. case DBG_SS_CERTHIER: psz = "CertHier"; break;
  33. case DBG_SS_CERTREQ: psz = "CertReq"; break;
  34. case DBG_SS_CERTUTIL: psz = "CertUtil"; break;
  35. case DBG_SS_CERTSRV: psz = "CertSrv"; break;
  36. case DBG_SS_CERTADM: psz = "CertAdm"; break;
  37. case DBG_SS_CERTCLI: psz = "CertCli"; break;
  38. case DBG_SS_CERTDB: psz = "CertDB"; break;
  39. case DBG_SS_CERTENC: psz = "CertEnc"; break;
  40. case DBG_SS_CERTEXIT: psz = "CertExit"; break;
  41. case DBG_SS_CERTIF: psz = "CertIF"; break;
  42. case DBG_SS_CERTMMC: psz = "CertMMC"; break;
  43. case DBG_SS_CERTOCM: psz = "CertOCM"; break;
  44. case DBG_SS_CERTPOL: psz = "CertPol"; break;
  45. case DBG_SS_CERTVIEW: psz = "CertView"; break;
  46. case DBG_SS_CERTBCLI: psz = "CertBCli"; break;
  47. case DBG_SS_CERTJET: psz = "CertJet"; break;
  48. case DBG_SS_CERTLIBXE: psz = "CertLibXE"; break;
  49. case DBG_SS_CERTLIB: psz = "CertLib"; break;
  50. case DBG_SS_AUDIT: psz = "CertAudit"; break;
  51. default: psz = "Cert"; break;
  52. }
  53. }
  54. return(psz);
  55. }
  56. DWORD
  57. myatolx(
  58. char const *psz)
  59. {
  60. DWORD dw = 0;
  61. while (isxdigit(*psz))
  62. {
  63. char ch = *psz++;
  64. if (isdigit(ch))
  65. {
  66. ch -= '0';
  67. }
  68. else if (isupper(ch))
  69. {
  70. ch += 10 - 'A';
  71. }
  72. else
  73. {
  74. ch += 10 - 'a';
  75. }
  76. dw = (dw << 4) | ch;
  77. }
  78. return(dw);
  79. }
  80. VOID
  81. DbgLogDateTime(
  82. IN CHAR const *pszPrefix)
  83. {
  84. if (NULL != g_pfLog)
  85. {
  86. WCHAR *pwszDate;
  87. FILETIME ft;
  88. SYSTEMTIME st;
  89. fprintf(g_pfLog, "%hs: ", pszPrefix);
  90. GetSystemTime(&st);
  91. if (SystemTimeToFileTime(&st, &ft))
  92. {
  93. if (S_OK == myGMTFileTimeToWszLocalTime(&ft, TRUE, &pwszDate))
  94. {
  95. fprintf(g_pfLog, "%ws", pwszDate);
  96. LocalFree(pwszDate);
  97. }
  98. }
  99. fprintf(g_pfLog, "\n");
  100. }
  101. }
  102. VOID
  103. DbgCloseLogFile()
  104. {
  105. if(g_fDBGCSInit)
  106. {
  107. EnterCriticalSection(&g_DBGCriticalSection);
  108. if (NULL != g_pfLog)
  109. {
  110. DbgLogDateTime("Closed Log");
  111. fclose(g_pfLog);
  112. g_pfLog = NULL;
  113. }
  114. LeaveCriticalSection(&g_DBGCriticalSection);
  115. }
  116. }
  117. char const szHeader[] = "\n========================================================================\n";
  118. VOID
  119. DbgOpenLogFile(
  120. OPTIONAL IN CHAR const *pszFile)
  121. {
  122. if (NULL != pszFile)
  123. {
  124. BOOL fAppend = FALSE;
  125. UINT cch;
  126. char aszLogFile[MAX_PATH];
  127. if ('+' == *pszFile)
  128. {
  129. pszFile++;
  130. fAppend = TRUE;
  131. }
  132. if (NULL == strchr(pszFile, '\\'))
  133. {
  134. cch = GetWindowsDirectoryA(aszLogFile, ARRAYSIZE(aszLogFile));
  135. if (0 != cch)
  136. {
  137. if (L'\\' != aszLogFile[cch - 1])
  138. {
  139. strcat(aszLogFile, "\\");
  140. }
  141. strcat(aszLogFile, pszFile);
  142. pszFile = aszLogFile;
  143. }
  144. }
  145. DbgCloseLogFile();
  146. if (g_fDBGCSInit)
  147. {
  148. EnterCriticalSection(&g_DBGCriticalSection);
  149. while (TRUE)
  150. {
  151. g_pfLog = fopen(pszFile, fAppend? "at" : "wt");
  152. if (NULL == g_pfLog)
  153. {
  154. _PrintError(E_FAIL, "fopen(Log)");
  155. }
  156. else
  157. {
  158. if (fAppend)
  159. {
  160. DWORD cbLogMax = 0;
  161. char const *pszEnvVar;
  162. pszEnvVar = getenv(szCERTSRV_LOGMAX);
  163. if (NULL != pszEnvVar)
  164. {
  165. cbLogMax = myatolx(pszEnvVar);
  166. }
  167. if (CBLOGMAXAPPEND > cbLogMax)
  168. {
  169. cbLogMax = CBLOGMAXAPPEND;
  170. }
  171. if (0 == fseek(g_pfLog, 0L, SEEK_END) &&
  172. MAXDWORD != cbLogMax)
  173. {
  174. LONG lcbLog = ftell(g_pfLog);
  175. if (0 > lcbLog || cbLogMax < (DWORD) lcbLog)
  176. {
  177. fclose(g_pfLog);
  178. g_pfLog = NULL;
  179. fAppend = FALSE;
  180. continue;
  181. }
  182. }
  183. fprintf(g_pfLog, szHeader);
  184. }
  185. DbgLogDateTime("Opened Log");
  186. }
  187. break;
  188. }
  189. LeaveCriticalSection(&g_DBGCriticalSection);
  190. }
  191. }
  192. }
  193. VOID
  194. DbgInit(
  195. IN BOOL fOpenDefaultLog)
  196. {
  197. static BOOL s_fFirst = TRUE;
  198. if (s_fFirst)
  199. {
  200. char const *pszEnvVar;
  201. __try
  202. {
  203. InitializeCriticalSection(&g_DBGCriticalSection);
  204. g_fDBGCSInit = TRUE;
  205. }
  206. __except(EXCEPTION_EXECUTE_HANDLER)
  207. {
  208. return;
  209. }
  210. s_fFirst = FALSE;
  211. pszEnvVar = getenv(szCERTSRV_DEBUG);
  212. if (NULL != pszEnvVar)
  213. {
  214. g_dwPrintMask = myatolx(pszEnvVar);
  215. }
  216. else
  217. {
  218. HRESULT hr;
  219. DWORD PrintMask;
  220. hr = myGetCertRegDWValue(
  221. NULL,
  222. NULL,
  223. NULL,
  224. wszREGCERTSRVDEBUG,
  225. &PrintMask);
  226. if (S_OK == hr)
  227. {
  228. g_dwPrintMask = PrintMask;
  229. }
  230. }
  231. if (fOpenDefaultLog && NULL == g_pfLog)
  232. {
  233. pszEnvVar = getenv(szCERTSRV_LOGFILE);
  234. DbgOpenLogFile(pszEnvVar);
  235. }
  236. }
  237. }
  238. BOOL
  239. DbgIsSSActive(
  240. IN DWORD dwSSIn)
  241. {
  242. DbgInit(TRUE);
  243. if (MAXDWORD == dwSSIn)
  244. {
  245. return(TRUE);
  246. }
  247. if ((DBG_SS_INFO & dwSSIn) && 0 == (DBG_SS_INFO & g_dwPrintMask))
  248. {
  249. return(FALSE);
  250. }
  251. return(0 != (~DBG_SS_INFO & g_dwPrintMask & dwSSIn));
  252. }
  253. VOID
  254. DbgLogStringInit(
  255. IN FNLOGSTRING *pfnLogString)
  256. {
  257. if (NULL == s_pfnLogString)
  258. {
  259. s_pfnLogString = pfnLogString;
  260. }
  261. }
  262. VOID
  263. DbgPrintfInit(
  264. OPTIONAL IN CHAR const *pszFile)
  265. {
  266. DbgInit(NULL == pszFile);
  267. DbgOpenLogFile(pszFile);
  268. }
  269. VOID
  270. fputsStripCR(
  271. IN BOOL fUnicode,
  272. IN char const *psz,
  273. IN FILE *pf)
  274. {
  275. while ('\0' != *psz)
  276. {
  277. DWORD i;
  278. i = strcspn(psz, "\r");
  279. if (0 != i)
  280. {
  281. if (fUnicode)
  282. {
  283. if (IOBUNALIGNED(pf))
  284. {
  285. fflush(pf); // fails when running as a service
  286. }
  287. if (IOBUNALIGNED(pf))
  288. {
  289. fprintf(pf, " ");
  290. fflush(pf);
  291. }
  292. fwprintf(pf, L"%.*hs", i, psz);
  293. }
  294. else
  295. {
  296. fprintf(pf, "%.*hs", i, psz);
  297. }
  298. psz += i;
  299. }
  300. if ('\r' == *psz)
  301. {
  302. psz++;
  303. }
  304. }
  305. }
  306. //+-------------------------------------------------------------------------
  307. //
  308. // Function: DbgPrintf
  309. //
  310. // Synopsis: outputs debug info to stdout and debugger
  311. //
  312. // Returns: number of chars output
  313. //
  314. //--------------------------------------------------------------------------
  315. int WINAPIV
  316. DbgPrintf(
  317. IN DWORD dwSubSystemId,
  318. IN LPCSTR lpFmt,
  319. ...)
  320. {
  321. va_list arglist;
  322. CHAR ach1[4096];
  323. CHAR ach2[4096 + 56];
  324. char *pch = NULL;
  325. char const *pszPrefix;
  326. int cch = 0;
  327. HANDLE hStdOut;
  328. DWORD cb;
  329. DWORD dwErr;
  330. BOOL fCritSecEntered = FALSE;
  331. dwErr = GetLastError();
  332. if (DbgIsSSActive(dwSubSystemId))
  333. {
  334. _try
  335. {
  336. va_start(arglist, lpFmt);
  337. cch = _vsnprintf(ach1, sizeof(ach1), lpFmt, arglist);
  338. va_end(arglist);
  339. if (0 > cch)
  340. {
  341. pch = &ach1[sizeof(ach1) - 5];
  342. strcpy(pch, "...\n");
  343. }
  344. pch = ach1;
  345. pszPrefix = DbgGetSSString(dwSubSystemId);
  346. if (NULL != pszPrefix)
  347. {
  348. cch = _snprintf(
  349. ach2,
  350. sizeof(ach2),
  351. "%hs: %hs",
  352. DbgGetSSString(dwSubSystemId),
  353. ach1);
  354. if (0 > cch)
  355. {
  356. pch = &ach2[sizeof(ach2) - 5];
  357. strcpy(pch, "...\n");
  358. }
  359. pch = ach2;
  360. }
  361. EnterCriticalSection(&g_DBGCriticalSection);
  362. fCritSecEntered = TRUE;
  363. if (!IsDebuggerPresent())
  364. {
  365. hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
  366. if (hStdOut != INVALID_HANDLE_VALUE)
  367. {
  368. // WriteConsoleA drops the output on the floor when stdout
  369. // is redirected to a file.
  370. // WriteConsoleA(hStdOut, pch, strlen(pch), &cb, NULL);
  371. fputsStripCR(TRUE, pch, stdout);
  372. fflush(stdout);
  373. }
  374. }
  375. if (NULL != g_pfLog)
  376. {
  377. fputsStripCR(FALSE, pch, g_pfLog);
  378. fflush(g_pfLog);
  379. }
  380. OutputDebugStringA(pch);
  381. }
  382. _except(EXCEPTION_EXECUTE_HANDLER)
  383. {
  384. // return failure
  385. cch = 0;
  386. }
  387. }
  388. if (fCritSecEntered)
  389. {
  390. LeaveCriticalSection(&g_DBGCriticalSection);
  391. }
  392. if (NULL != pch && NULL != s_pfnLogString)
  393. {
  394. (*s_pfnLogString)(pch);
  395. }
  396. SetLastError(dwErr);
  397. return(cch);
  398. }
  399. #endif // DBG_CERTSRV_DEBUG_PRINT