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.

354 lines
9.5 KiB

  1. //+---------------------------------------------------------------------------
  2. // Copyright (C) 1991-1994, Microsoft Corporation.
  3. //
  4. // File: assert.cxx
  5. //
  6. // Contents: Debugging output routines
  7. //
  8. // History: 23-Jul-91 KyleP Created.
  9. // 09-Oct-91 KevinRo Major changes and comments added
  10. // 18-Oct-91 vich moved debug print routines out
  11. // 10-Jun-92 BryanT Switched to w4crt.h instead of wchar.h
  12. // 30-Sep-93 KyleP DEVL obsolete
  13. // 7-Oct-94 BruceFo Ripped out all kernel, non-FLAT,
  14. // DLL-specific, non-Win32 functionality.
  15. // Now it's basically "print to the
  16. // debugger" code.
  17. //
  18. //----------------------------------------------------------------------------
  19. #if DBG == 1
  20. #include <windows.h>
  21. #include <stdio.h>
  22. #include <stdarg.h>
  23. #include "debug.h"
  24. #include <strsafe.h>
  25. #ifndef ARRAYLEN
  26. #define ARRAYLEN(a) (sizeof(a) / sizeof((a)[0]))
  27. #endif
  28. //////////////////////////////////////////////////////////////////////////////
  29. unsigned long Win4InfoLevel = DEF_INFOLEVEL;
  30. unsigned long Win4InfoMask = 0xffffffff;
  31. unsigned long Win4AssertLevel = ASSRT_MESSAGE | ASSRT_BREAK | ASSRT_POPUP;
  32. //////////////////////////////////////////////////////////////////////////////
  33. static int _cdecl w4dprintf(const char *format, ...);
  34. static int _cdecl w4vdprintf(const char *format, va_list arglist);
  35. //////////////////////////////////////////////////////////////////////////////
  36. static CRITICAL_SECTION s_csMessageBuf;
  37. static char g_szMessageBuf[500]; // this is the message buffer
  38. static int _cdecl w4dprintf(const char *format, ...)
  39. {
  40. int ret;
  41. va_list va;
  42. va_start(va, format);
  43. ret = w4vdprintf(format, va);
  44. va_end(va);
  45. return ret;
  46. }
  47. static int _cdecl w4vdprintf(const char *format, va_list arglist)
  48. {
  49. int ret = 0;
  50. EnterCriticalSection(&s_csMessageBuf);
  51. if (SUCCEEDED(StringCchPrintfA(g_szMessageBuf, ARRAYLEN(g_szMessageBuf), format, arglist)))
  52. {
  53. ret = lstrlenA(g_szMessageBuf);
  54. }
  55. OutputDebugStringA(g_szMessageBuf);
  56. LeaveCriticalSection(&s_csMessageBuf);
  57. return ret;
  58. }
  59. //////////////////////////////////////////////////////////////////////////////
  60. //+---------------------------------------------------------------------------
  61. //
  62. // Function: _asdprintf
  63. //
  64. // Synopsis: Calls vdprintf to output a formatted message.
  65. //
  66. // History: 18-Oct-91 vich Created
  67. //
  68. //----------------------------------------------------------------------------
  69. inline void __cdecl
  70. _asdprintf(
  71. char const *pszfmt, ...)
  72. {
  73. va_list va;
  74. va_start(va, pszfmt);
  75. vdprintf(DEB_FORCE, "Assert", pszfmt, va);
  76. va_end(va);
  77. }
  78. //+---------------------------------------------------------------------------
  79. //
  80. // Function: Win4AssertEx, private
  81. //
  82. // Synopsis: Display assertion information
  83. //
  84. // Effects: Called when an assertion is hit.
  85. //
  86. //----------------------------------------------------------------------------
  87. EXPORTIMP void APINOT
  88. Win4AssertEx(
  89. char const * szFile,
  90. int iLine,
  91. char const * szMessage)
  92. {
  93. if (Win4AssertLevel & ASSRT_MESSAGE)
  94. {
  95. DWORD tid = GetCurrentThreadId();
  96. _asdprintf("%s File: %s Line: %u, thread id %d\n",
  97. szMessage, szFile, iLine, tid);
  98. }
  99. if (Win4AssertLevel & ASSRT_POPUP)
  100. {
  101. int id = PopUpError(szMessage,iLine,szFile);
  102. if (id == IDCANCEL)
  103. {
  104. DebugBreak();
  105. }
  106. }
  107. else if (Win4AssertLevel & ASSRT_BREAK)
  108. {
  109. DebugBreak();
  110. }
  111. }
  112. //+------------------------------------------------------------
  113. // Function: SetWin4InfoLevel(unsigned long ulNewLevel)
  114. //
  115. // Synopsis: Sets the global info level for debugging output
  116. // Returns: Old info level
  117. //
  118. //-------------------------------------------------------------
  119. EXPORTIMP unsigned long APINOT
  120. SetWin4InfoLevel(
  121. unsigned long ulNewLevel)
  122. {
  123. unsigned long ul;
  124. ul = Win4InfoLevel;
  125. Win4InfoLevel = ulNewLevel;
  126. return(ul);
  127. }
  128. //+------------------------------------------------------------
  129. // Function: SetWin4InfoMask(unsigned long ulNewMask)
  130. //
  131. // Synopsis: Sets the global info mask for debugging output
  132. // Returns: Old info mask
  133. //
  134. //-------------------------------------------------------------
  135. EXPORTIMP unsigned long APINOT
  136. SetWin4InfoMask(
  137. unsigned long ulNewMask)
  138. {
  139. unsigned long ul;
  140. ul = Win4InfoMask;
  141. Win4InfoMask = ulNewMask;
  142. return(ul);
  143. }
  144. //+------------------------------------------------------------
  145. // Function: SetWin4AssertLevel(unsigned long ulNewLevel)
  146. //
  147. // Synopsis: Sets the global assert level for debugging output
  148. // Returns: Old assert level
  149. //
  150. //-------------------------------------------------------------
  151. EXPORTIMP unsigned long APINOT
  152. SetWin4AssertLevel(
  153. unsigned long ulNewLevel)
  154. {
  155. unsigned long ul;
  156. ul = Win4AssertLevel;
  157. Win4AssertLevel = ulNewLevel;
  158. return(ul);
  159. }
  160. //+------------------------------------------------------------
  161. // Function: PopUpError
  162. //
  163. // Synopsis: Displays a dialog box using provided text,
  164. // and presents the user with the option to
  165. // continue or cancel.
  166. //
  167. // Arguments:
  168. // szMsg -- The string to display in main body of dialog
  169. // iLine -- Line number of file in error
  170. // szFile -- Filename of file in error
  171. //
  172. // Returns:
  173. // IDCANCEL -- User selected the CANCEL button
  174. // IDOK -- User selected the OK button
  175. //-------------------------------------------------------------
  176. EXPORTIMP int APINOT
  177. PopUpError(
  178. char const *szMsg,
  179. int iLine,
  180. char const *szFile)
  181. {
  182. int id;
  183. static char szAssertCaption[128];
  184. static char szModuleName[128];
  185. DWORD tid = GetCurrentThreadId();
  186. DWORD pid = GetCurrentProcessId();
  187. char * pszModuleName;
  188. if (GetModuleFileNameA(NULL, szModuleName, 128))
  189. {
  190. pszModuleName = strrchr(szModuleName, '\\');
  191. if (!pszModuleName)
  192. {
  193. pszModuleName = szModuleName;
  194. }
  195. else
  196. {
  197. pszModuleName++;
  198. }
  199. }
  200. else
  201. {
  202. pszModuleName = "Unknown";
  203. }
  204. StringCchPrintfA(szAssertCaption, ARRAYLEN(szAssertCaption), "Process: %s File: %s line %u, thread id %d.%d",
  205. pszModuleName, szFile, iLine, pid, tid);
  206. id = MessageBoxA(NULL,
  207. szMsg,
  208. szAssertCaption,
  209. MB_SETFOREGROUND
  210. | MB_DEFAULT_DESKTOP_ONLY
  211. | MB_TASKMODAL
  212. | MB_ICONEXCLAMATION
  213. | MB_OKCANCEL);
  214. //
  215. // If id == 0, then an error occurred. There are two possibilities
  216. // that can cause the error: Access Denied, which means that this
  217. // process does not have access to the default desktop, and everything
  218. // else (usually out of memory).
  219. //
  220. if (0 == id)
  221. {
  222. if (GetLastError() == ERROR_ACCESS_DENIED)
  223. {
  224. //
  225. // Retry this one with the SERVICE_NOTIFICATION flag on. That
  226. // should get us to the right desktop.
  227. //
  228. id = MessageBoxA(NULL,
  229. szMsg,
  230. szAssertCaption,
  231. MB_SETFOREGROUND
  232. | MB_SERVICE_NOTIFICATION
  233. | MB_TASKMODAL
  234. | MB_ICONEXCLAMATION
  235. | MB_OKCANCEL);
  236. }
  237. }
  238. return id;
  239. }
  240. //+------------------------------------------------------------
  241. // Function: vdprintf
  242. //
  243. // Synopsis: Prints debug output using a pointer to the
  244. // variable information. Used primarily by the
  245. // xxDebugOut macros
  246. //
  247. // Arguements:
  248. // ulCompMask -- Component level mask used to determine
  249. // output ability
  250. // pszComp -- String const of component prefix.
  251. // ppszfmt -- Pointer to output format and data
  252. //
  253. //-------------------------------------------------------------
  254. static CRITICAL_SECTION s_csDebugPrint;
  255. EXPORTIMP void APINOT
  256. vdprintf(
  257. unsigned long ulCompMask,
  258. char const *pszComp,
  259. char const *ppszfmt,
  260. va_list pargs)
  261. {
  262. if ((ulCompMask & DEB_FORCE) == DEB_FORCE ||
  263. ((ulCompMask | Win4InfoLevel) & Win4InfoMask))
  264. {
  265. EnterCriticalSection(&s_csDebugPrint);
  266. DWORD tid = GetCurrentThreadId();
  267. DWORD pid = GetCurrentProcessId();
  268. if ((Win4InfoLevel & (DEB_DBGOUT | DEB_STDOUT)) != DEB_STDOUT)
  269. {
  270. if (! (ulCompMask & DEB_NOCOMPNAME))
  271. {
  272. w4dprintf("%d.%03d> %s: ", pid, tid, pszComp);
  273. }
  274. w4vdprintf(ppszfmt, pargs);
  275. }
  276. if (Win4InfoLevel & DEB_STDOUT)
  277. {
  278. if (! (ulCompMask & DEB_NOCOMPNAME))
  279. {
  280. printf("%d.%03d> %s: ", pid, tid, pszComp);
  281. }
  282. vprintf(ppszfmt, pargs);
  283. }
  284. LeaveCriticalSection(&s_csDebugPrint);
  285. }
  286. }
  287. void APINOT InitializeDebugging(void)
  288. {
  289. InitializeCriticalSection(&s_csMessageBuf);
  290. InitializeCriticalSection(&s_csDebugPrint);
  291. }
  292. void APINOT UninitializeDebugging(void)
  293. {
  294. DeleteCriticalSection(&s_csMessageBuf);
  295. DeleteCriticalSection(&s_csDebugPrint);
  296. }
  297. #endif // DBG == 1