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.

514 lines
11 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. // 03/20/96 kevinr wrote it
  12. // 04/17/96 kevinr added OSS init
  13. // 05-Sep-1997 pberkman added sub-system debug.
  14. //
  15. //----------------------------------------------------------------------------
  16. #include <windows.h>
  17. #include <asn1code.h>
  18. #if DBG
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <stdarg.h>
  22. #include <memory.h>
  23. #include <string.h>
  24. #include <process.h>
  25. #include <time.h>
  26. #include <crtdbg.h>
  27. #include "pkicrit.h"
  28. #include "dbgdef.h"
  29. // set DEBUG_MASK=0x26
  30. LPSTR pszDEBUG_MASK = "DEBUG_MASK";
  31. #define DEBUG_MASK_DELAY_FREE_MEM _CRTDBG_DELAY_FREE_MEM_DF /* 0x02 */
  32. #define DEBUG_MASK_CHECK_ALWAYS _CRTDBG_CHECK_ALWAYS_DF /* 0x04 */
  33. #define DEBUG_MASK_LEAK_CHECK _CRTDBG_LEAK_CHECK_DF /* 0x20 */
  34. #define DEBUG_MASK_MEM \
  35. (DEBUG_MASK_DELAY_FREE_MEM | DEBUG_MASK_CHECK_ALWAYS | DEBUG_MASK_LEAK_CHECK)
  36. // from asn1code.h:
  37. // #define DEBUGPDU 0x02 /* produce tracing output */
  38. // #define DEBUG_ERRORS 0x10 /* print decoder errors to output */
  39. // set OSS_DEBUG_MASK=0x02
  40. // set OSS_DEBUG_MASK=0x10 - only print decoder errors
  41. LPSTR pszOSS_DEBUG_MASK = "OSS_DEBUG_MASK";
  42. // receives trace output
  43. LPSTR pszOSS_DEBUG_TRACEFILE = "OSS_DEBUG_TRACEFILE";
  44. static char *pszDEBUG_PRINT_MASK = "DEBUG_PRINT_MASK";
  45. static char *pszDefualtSSTag = "ISPU";
  46. static DBG_SS_TAG sSSTags[] = __DBG_SS_TAGS;
  47. static CRITICAL_SECTION DbgCriticalSection;
  48. #define OSS_SET_DECODING_FLAGS_PROC_IDX 0
  49. #define OSS_SET_ENCODING_FLAGS_PROC_IDX 1
  50. #define OSS_OPEN_TRACE_FILE_PROC_IDX 2
  51. #define OSS_PROC_CNT 3
  52. static LPSTR rgpszOssProc[OSS_PROC_CNT] = {
  53. "ossSetDecodingFlags",
  54. "ossSetEncodingFlags",
  55. "ossOpenTraceFile"
  56. };
  57. static void *rgpvOssProc[OSS_PROC_CNT];
  58. static HMODULE hmsossDll = NULL;
  59. static BOOL fLoadedOss = FALSE;
  60. static void OssUnload()
  61. {
  62. if (hmsossDll) {
  63. FreeLibrary(hmsossDll);
  64. hmsossDll = NULL;
  65. }
  66. }
  67. static void OssLoad()
  68. {
  69. DWORD i;
  70. if (fLoadedOss)
  71. return;
  72. EnterCriticalSection(&DbgCriticalSection);
  73. if (fLoadedOss)
  74. goto LeaveReturn;
  75. if (NULL == (hmsossDll = LoadLibraryA("msoss.dll")))
  76. goto msossLoadLibraryError;
  77. for (i = 0; i < OSS_PROC_CNT; i++) {
  78. if (NULL == (rgpvOssProc[i] = GetProcAddress(
  79. hmsossDll, rgpszOssProc[i])))
  80. goto msossGetProcAddressError;
  81. }
  82. LeaveReturn:
  83. LeaveCriticalSection(&DbgCriticalSection);
  84. CommonReturn:
  85. fLoadedOss = TRUE;
  86. return;
  87. ErrorReturn:
  88. LeaveCriticalSection(&DbgCriticalSection);
  89. OssUnload();
  90. goto CommonReturn;
  91. TRACE_ERROR(msossLoadLibraryError)
  92. TRACE_ERROR(msossGetProcAddressError)
  93. }
  94. typedef int (DLL_ENTRY* pfnossSetDecodingFlags)(struct ossGlobal *world,
  95. unsigned long flags);
  96. static int DLL_ENTRY ossSetDecodingFlags(struct ossGlobal *world,
  97. unsigned long flags)
  98. {
  99. if (hmsossDll)
  100. return ((pfnossSetDecodingFlags)
  101. rgpvOssProc[OSS_SET_DECODING_FLAGS_PROC_IDX])(
  102. world,
  103. flags);
  104. else
  105. return API_DLL_NOT_LINKED;
  106. }
  107. typedef int (DLL_ENTRY* pfnossSetEncodingFlags)(struct ossGlobal *world,
  108. unsigned long flags);
  109. static int DLL_ENTRY ossSetEncodingFlags(struct ossGlobal *world,
  110. unsigned long flags)
  111. {
  112. if (hmsossDll)
  113. return ((pfnossSetEncodingFlags)
  114. rgpvOssProc[OSS_SET_ENCODING_FLAGS_PROC_IDX])(
  115. world,
  116. flags);
  117. else
  118. return API_DLL_NOT_LINKED;
  119. }
  120. typedef int (DLL_ENTRY* pfnossOpenTraceFile)(struct ossGlobal *world,
  121. char *fileName);
  122. static int DLL_ENTRY ossOpenTraceFile(struct ossGlobal *world,
  123. char *fileName)
  124. {
  125. if (hmsossDll)
  126. return ((pfnossOpenTraceFile)
  127. rgpvOssProc[OSS_OPEN_TRACE_FILE_PROC_IDX])(
  128. world,
  129. fileName);
  130. else
  131. return API_DLL_NOT_LINKED;
  132. }
  133. //
  134. //+-------------------------------------------------------------------------
  135. //
  136. // Pithy stubs to create stdcall proc from cdecl
  137. //
  138. //--------------------------------------------------------------------------
  139. void*
  140. _stdcall
  141. scMalloc( size_t size)
  142. {
  143. return malloc(size);
  144. }
  145. void*
  146. _stdcall
  147. scRealloc( void *memblock, size_t size)
  148. {
  149. return realloc(memblock, size);
  150. }
  151. void
  152. _stdcall
  153. scFree( void *memblock)
  154. {
  155. free(memblock);
  156. }
  157. //+-------------------------------------------------------------------------
  158. //
  159. // Function: DbgGetDebugFlags
  160. //
  161. // Synopsis: Get the debug flags.
  162. //
  163. // Returns: the debug flags
  164. //
  165. //--------------------------------------------------------------------------
  166. int
  167. WINAPI
  168. DbgGetDebugFlags()
  169. {
  170. char *pszEnvVar;
  171. char *p;
  172. int iDebugFlags = 0;
  173. if (pszEnvVar = getenv( pszDEBUG_MASK))
  174. iDebugFlags = strtol( pszEnvVar, &p, 16);
  175. return iDebugFlags;
  176. }
  177. //+-------------------------------------------------------------------------
  178. //
  179. // Function: DbgProcessAttach
  180. //
  181. // Synopsis: Handle process attach.
  182. //
  183. // Returns: TRUE
  184. //
  185. //--------------------------------------------------------------------------
  186. BOOL
  187. WINAPI
  188. DbgProcessAttach()
  189. {
  190. int tmpFlag;
  191. #ifdef _DEBUG
  192. tmpFlag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG ); // get current
  193. tmpFlag |= DbgGetDebugFlags(); // enable flags
  194. tmpFlag &= ~_CRTDBG_CHECK_CRT_DF; // disable CRT block checking
  195. _CrtSetDbgFlag( tmpFlag); // set new value
  196. #endif
  197. return TRUE;
  198. }
  199. //+-------------------------------------------------------------------------
  200. //
  201. // Function: DbgProcessDetach
  202. //
  203. // Synopsis: Handle process detach.
  204. //
  205. // Returns: TRUE
  206. //
  207. //--------------------------------------------------------------------------
  208. BOOL
  209. WINAPI
  210. DbgProcessDetach()
  211. {
  212. return TRUE;
  213. }
  214. //+-------------------------------------------------------------------------
  215. //
  216. // Function: DbgInitOSS
  217. //
  218. // Synopsis: Do OSS init for debug.
  219. //
  220. // Returns: TRUE
  221. //
  222. // Note: Always FRONT_ALIGN encoding
  223. //
  224. //--------------------------------------------------------------------------
  225. BOOL
  226. WINAPI
  227. DbgInitOSS(
  228. OssGlobal *pog)
  229. {
  230. char *pszEnvVar;
  231. char *p;
  232. __try {
  233. // Attempt to do delay, demand loading of msoss.dll
  234. OssLoad();
  235. // from asn1code.h:
  236. // #define DEBUGPDU 0x02 /* produce tracing output */
  237. // #define DEBUG_ERRORS 0x10 /* print decoder errors to output */
  238. // set OSS_DEBUG_MASK=0x02
  239. // set OSS_DEBUG_MASK=0x10 - only print decoder errors
  240. if (pszEnvVar = getenv( pszOSS_DEBUG_MASK)) {
  241. unsigned long ulEnvVar;
  242. ulEnvVar = strtoul( pszEnvVar, &p, 16) & (DEBUGPDU | DEBUG_ERRORS);
  243. if ( ulEnvVar)
  244. ossSetDecodingFlags( pog, ulEnvVar | RELAXBER);
  245. if ( DEBUGPDU & ulEnvVar)
  246. ossSetEncodingFlags( pog, DEBUGPDU | FRONT_ALIGN);
  247. else
  248. ossSetEncodingFlags( pog, FRONT_ALIGN);
  249. } else {
  250. ossSetDecodingFlags( pog, DEBUG_ERRORS | RELAXBER);
  251. ossSetEncodingFlags( pog, FRONT_ALIGN);
  252. }
  253. if (pszEnvVar = getenv( pszOSS_DEBUG_TRACEFILE))
  254. ossOpenTraceFile( pog, pszEnvVar);
  255. #ifdef _DEBUG
  256. if (DbgGetDebugFlags() & DEBUG_MASK_MEM) {
  257. pog->mallocp = scMalloc;
  258. pog->reallocp = scRealloc;
  259. pog->freep = scFree;
  260. }
  261. #else
  262. pog->mallocp = scMalloc;
  263. pog->reallocp = scRealloc;
  264. pog->freep = scFree;
  265. #endif
  266. return TRUE;
  267. } __except(EXCEPTION_EXECUTE_HANDLER) {
  268. return FALSE;
  269. }
  270. }
  271. //+-------------------------------------------------------------------------
  272. //
  273. // Function: DebugDllMain
  274. //
  275. // Synopsis: Initialize the debug DLL
  276. //
  277. // Returns: TRUE
  278. //
  279. //--------------------------------------------------------------------------
  280. BOOL
  281. WINAPI
  282. DebugDllMain(
  283. HMODULE hInst,
  284. ULONG ulReason,
  285. LPVOID lpReserved)
  286. {
  287. BOOL fRet = TRUE;
  288. switch (ulReason) {
  289. case DLL_PROCESS_ATTACH:
  290. fRet = DbgProcessAttach();
  291. if (fRet) {
  292. fRet = Pki_InitializeCriticalSection(&DbgCriticalSection);
  293. if (!fRet)
  294. DbgProcessDetach();
  295. }
  296. break;
  297. case DLL_PROCESS_DETACH:
  298. fRet = DbgProcessDetach();
  299. OssUnload();
  300. DeleteCriticalSection(&DbgCriticalSection);
  301. break;
  302. default:
  303. break;
  304. }
  305. return fRet;
  306. }
  307. const char *DbgGetSSString(DWORD dwSubSystemId)
  308. {
  309. DBG_SS_TAG *psSS;
  310. psSS = &sSSTags[0];
  311. while (psSS->dwSS > 0)
  312. {
  313. if ((psSS->dwSS & dwSubSystemId) > 0)
  314. {
  315. if (psSS->pszTag)
  316. {
  317. return(psSS->pszTag);
  318. }
  319. return(pszDefualtSSTag);
  320. }
  321. psSS++;
  322. }
  323. return(pszDefualtSSTag);
  324. }
  325. static BOOL DbgIsSSActive(DWORD dwSSIn)
  326. {
  327. char *pszEnvVar;
  328. DWORD dwEnv;
  329. dwEnv = 0;
  330. if (pszEnvVar = getenv(pszDEBUG_PRINT_MASK))
  331. {
  332. dwEnv = (DWORD)strtol(pszEnvVar, NULL, 16);
  333. }
  334. return((dwEnv & dwSSIn) > 0);
  335. }
  336. //+-------------------------------------------------------------------------
  337. //
  338. // Function: DbgPrintf
  339. //
  340. // Synopsis: outputs debug info to stdout and debugger
  341. //
  342. // Returns: number of chars output
  343. //
  344. //--------------------------------------------------------------------------
  345. int WINAPIV DbgPrintf(DWORD dwSubSystemId, LPCSTR lpFmt, ...)
  346. {
  347. va_list arglist;
  348. CHAR ach1[1024];
  349. CHAR ach2[1080];
  350. int cch;
  351. HANDLE hStdOut;
  352. DWORD cb;
  353. DWORD dwErr;
  354. dwErr = GetLastError();
  355. if (!(DbgIsSSActive(dwSubSystemId)))
  356. {
  357. SetLastError(dwErr);
  358. return(0);
  359. }
  360. _try
  361. {
  362. va_start(arglist, lpFmt);
  363. _vsnprintf( ach1, sizeof(ach1), lpFmt, arglist);
  364. va_end(arglist);
  365. cch = wsprintf(ach2,"%s: %s", DbgGetSSString(dwSubSystemId), ach1);
  366. hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
  367. if (hStdOut != INVALID_HANDLE_VALUE)
  368. {
  369. WriteConsole( hStdOut, ach2, strlen(ach2), &cb, NULL);
  370. }
  371. OutputDebugString(ach2);
  372. } _except( EXCEPTION_EXECUTE_HANDLER)
  373. {
  374. // return failure
  375. cch = 0;
  376. }
  377. SetLastError(dwErr);
  378. return cch;
  379. }
  380. #else
  381. #ifdef __cplusplus
  382. extern "C"
  383. {
  384. #endif
  385. BOOL
  386. WINAPI
  387. DbgInitOSS(
  388. OssGlobal *pog);
  389. int WINAPIV DbgPrintf(DWORD dwSubSystemId, LPCSTR lpFmt, ...);
  390. #ifdef __cplusplus
  391. } // balance of extern "C"
  392. #endif
  393. //+-------------------------------------------------------------------------
  394. //
  395. // Function: DbgInitOSS
  396. //
  397. // Synopsis: Do OSS init for debug. Do nothing in retail builds
  398. //
  399. // Returns: TRUE
  400. //
  401. // Note: Always FRONT_ALIGN encoding
  402. //
  403. //--------------------------------------------------------------------------
  404. BOOL
  405. WINAPI
  406. DbgInitOSS(
  407. OssGlobal *pog)
  408. {
  409. return(TRUE);
  410. }
  411. //+-------------------------------------------------------------------------
  412. //
  413. // Function: DbgPrintf
  414. //
  415. // Synopsis: outputs debug info to stdout and debugger
  416. // Nothing in retail builds
  417. //
  418. // Returns: number of chars output
  419. //
  420. //--------------------------------------------------------------------------
  421. int WINAPIV DbgPrintf(DWORD dwSubSystemId, LPCSTR lpFmt, ...)
  422. {
  423. return(0);
  424. }
  425. #endif // DBG