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.

391 lines
9.8 KiB

  1. //+---------------------------------------------------------------------------
  2. // Copyright (C) 1991, Microsoft Corporation.
  3. //
  4. // File: assert.cxx
  5. //
  6. // Contents: Debugging output routines for idsmgr.dll
  7. //
  8. // Functions: Assert
  9. // PopUpError
  10. //
  11. // History: 23-Jul-91 KyleP Created.
  12. // 09-Oct-91 KevinRo Major changes and comments added
  13. // 18-Oct-91 vich moved debug print routines out
  14. // 10-Jun-92 BryanT Switched to w4crt.h instead of wchar.h
  15. // 30-Sep-93 KyleP DEVL obsolete
  16. //
  17. //----------------------------------------------------------------------------
  18. #pragma hdrstop
  19. //
  20. // This one file **always** uses debugging options
  21. //
  22. #if DBG == 1
  23. // needed for CT TOM assert events trapping
  24. #include <assert.hxx>
  25. #include <stdarg.h>
  26. #include <stdio.h>
  27. # include <dprintf.h> // w4printf, w4dprintf prototypes
  28. # include <debnot.h>
  29. # ifdef FLAT
  30. # include <sem.hxx>
  31. # include <dllsem.hxx>
  32. # endif // FLAT
  33. extern "C"
  34. {
  35. # ifdef FLAT
  36. # undef FAR
  37. # undef NEAR
  38. # else
  39. # define MessageBoxA MessageBox
  40. # endif
  41. # include <windows.h>
  42. }
  43. extern BOOL gfService = FALSE;
  44. unsigned long Win4InfoLevel = DEF_INFOLEVEL;
  45. unsigned long Win4InfoMask = 0xffffffff;
  46. unsigned long Win4AssertLevel = ASSRT_MESSAGE | ASSRT_BREAK | ASSRT_POPUP;
  47. //+---------------------------------------------------------------------------
  48. //
  49. // Function: _asdprintf
  50. //
  51. // Synopsis: Calls vdprintf to output a formatted message.
  52. //
  53. // History: 18-Oct-91 vich Created
  54. //
  55. //----------------------------------------------------------------------------
  56. inline void __cdecl
  57. _asdprintf(
  58. char const *pszfmt, ...)
  59. {
  60. va_list va;
  61. va_start(va, pszfmt);
  62. vdprintf(DEB_FORCE, "Assert", pszfmt, va);
  63. va_end(va);
  64. }
  65. //+---------------------------------------------------------------------------
  66. //
  67. // Function: _Win4Assert, private
  68. //
  69. // Synopsis: Display assertion information
  70. //
  71. // Effects: Called when an assertion is hit.
  72. //
  73. // History: 12-Jul-91 AlexT Created.
  74. // 05-Sep-91 AlexT Catch Throws and Catches
  75. // 19-Oct-92 HoiV Added events for TOM
  76. //
  77. //----------------------------------------------------------------------------
  78. STDAPI_(void) Win4AssertEx(
  79. char const * szFile,
  80. int iLine,
  81. char const * szMessage)
  82. {
  83. #if defined( FLAT )
  84. //
  85. // This code is for the CT Lab only. When running in the lab,
  86. // all assert popups will be trapped and notifications will
  87. // be sent to the manager. If running in the office (non-lab
  88. // mode), the event CTTOMTrapAssertEvent will not exist and
  89. // consequently, no event will be pulsed.
  90. //
  91. HANDLE hTrapAssertEvent,
  92. hThreadStartEvent;
  93. if (hTrapAssertEvent = OpenEvent(EVENT_ALL_ACCESS,
  94. FALSE,
  95. CAIRO_CT_TOM_TRAP_ASSERT_EVENT))
  96. {
  97. SetEvent(hTrapAssertEvent);
  98. //
  99. // This event is to allow TOM Manager time to perform
  100. // a CallBack to the dispatcher.
  101. //
  102. if (hThreadStartEvent = OpenEvent(EVENT_ALL_ACCESS,
  103. FALSE,
  104. CAIRO_CT_TOM_THREAD_START_EVENT))
  105. {
  106. //
  107. // Wait until it's ok to popup or until timed-out
  108. //
  109. WaitForSingleObject(hThreadStartEvent, TWO_MINUTES);
  110. }
  111. }
  112. #endif
  113. if (Win4AssertLevel & ASSRT_MESSAGE)
  114. {
  115. # ifdef FLAT
  116. DWORD tid = GetCurrentThreadId();
  117. _asdprintf("%s File: %s Line: %u, thread id %d\n",
  118. szMessage, szFile, iLine, tid);
  119. # else // FLAT
  120. _asdprintf("%s File: %s Line: %u\n", szMessage, szFile, iLine);
  121. # endif // FLAT
  122. }
  123. if (Win4AssertLevel & ASSRT_POPUP)
  124. {
  125. int id = PopUpError(szMessage,iLine,szFile);
  126. if (id == IDCANCEL)
  127. {
  128. #ifdef FLAT
  129. DebugBreak();
  130. #else
  131. _asm int 3;
  132. #endif
  133. }
  134. }
  135. else if (Win4AssertLevel & ASSRT_BREAK)
  136. {
  137. #ifdef FLAT
  138. DebugBreak();
  139. #else
  140. _asm int 3;
  141. #endif
  142. }
  143. }
  144. //+------------------------------------------------------------
  145. // Function: SetWin4InfoLevel(unsigned long ulNewLevel)
  146. //
  147. // Synopsis: Sets the global info level for debugging output
  148. // Returns: Old info level
  149. //
  150. //-------------------------------------------------------------
  151. EXPORTIMP unsigned long APINOT
  152. SetWin4InfoLevel(
  153. unsigned long ulNewLevel)
  154. {
  155. unsigned long ul;
  156. ul = Win4InfoLevel;
  157. Win4InfoLevel = ulNewLevel;
  158. return(ul);
  159. }
  160. //+------------------------------------------------------------
  161. // Function: _SetWin4InfoMask(unsigned long ulNewMask)
  162. //
  163. // Synopsis: Sets the global info mask for debugging output
  164. // Returns: Old info mask
  165. //
  166. //-------------------------------------------------------------
  167. EXPORTIMP unsigned long APINOT
  168. SetWin4InfoMask(
  169. unsigned long ulNewMask)
  170. {
  171. unsigned long ul;
  172. ul = Win4InfoMask;
  173. Win4InfoMask = ulNewMask;
  174. return(ul);
  175. }
  176. //+------------------------------------------------------------
  177. // Function: _SetWin4AssertLevel(unsigned long ulNewLevel)
  178. //
  179. // Synopsis: Sets the global assert level for debugging output
  180. // Returns: Old assert level
  181. //
  182. //-------------------------------------------------------------
  183. EXPORTIMP unsigned long APINOT
  184. SetWin4AssertLevel(
  185. unsigned long ulNewLevel)
  186. {
  187. unsigned long ul;
  188. ul = Win4AssertLevel;
  189. Win4AssertLevel = ulNewLevel;
  190. return(ul);
  191. }
  192. //+------------------------------------------------------------
  193. // Function: PopUpError
  194. //
  195. // Synopsis: Displays a dialog box using provided text,
  196. // and presents the user with the option to
  197. // continue or cancel.
  198. //
  199. // Arguments:
  200. // szMsg -- The string to display in main body of dialog
  201. // iLine -- Line number of file in error
  202. // szFile -- Filename of file in error
  203. //
  204. // Returns:
  205. // IDCANCEL -- User selected the CANCEL button
  206. // IDOK -- User selected the OK button
  207. //-------------------------------------------------------------
  208. STDAPI_(int) PopUpError(
  209. char const *szMsg,
  210. int iLine,
  211. char const *szFile)
  212. {
  213. int id;
  214. static char szAssertCaption[128];
  215. static char szModuleName[128];
  216. DWORD tid = GetCurrentThreadId();
  217. DWORD pid = GetCurrentProcessId();
  218. char * pszModuleName;
  219. if (GetModuleFileNameA(NULL, szModuleName, 128))
  220. {
  221. pszModuleName = strrchr(szModuleName, '\\');
  222. if (!pszModuleName)
  223. {
  224. pszModuleName = szModuleName;
  225. }
  226. else
  227. {
  228. pszModuleName++;
  229. }
  230. }
  231. else
  232. {
  233. pszModuleName = "Unknown";
  234. }
  235. sprintf(szAssertCaption,"Process: %s File: %s line %u, thread id %d.%d",
  236. pszModuleName, szFile, iLine, pid, tid);
  237. DWORD dwMessageFlags = MB_SETFOREGROUND | MB_TASKMODAL |
  238. MB_ICONEXCLAMATION | MB_OKCANCEL;
  239. #ifndef _CHICAGO_
  240. // Since this code is also used by SCM.EXE, we pass
  241. // in the following flag which causes Service pop ups
  242. // to appear on the desktop correctly
  243. if (gfService)
  244. {
  245. dwMessageFlags |= MB_SERVICE_NOTIFICATION | MB_DEFAULT_DESKTOP_ONLY;
  246. }
  247. #endif // _CHICAGO_
  248. id = MessageBoxA(NULL,(char *) szMsg, (LPSTR) szAssertCaption,
  249. dwMessageFlags);
  250. // If id == 0, then an error occurred. There are two possibilities
  251. // that can cause the error: Access Denied, which means that this
  252. // process does not have access to the default desktop, and everything
  253. // else (usually out of memory). Oh well.
  254. return id;
  255. }
  256. //+------------------------------------------------------------
  257. // Function: vdprintf
  258. //
  259. // Synopsis: Prints debug output using a pointer to the
  260. // variable information. Used primarily by the
  261. // xxDebugOut macros
  262. //
  263. // Arguements:
  264. // ulCompMask -- Component level mask used to determine
  265. // output ability
  266. // pszComp -- String const of component prefix.
  267. // ppszfmt -- Pointer to output format and data
  268. //
  269. //-------------------------------------------------------------
  270. //
  271. // This semaphore is *outside* vdprintf because the compiler isn't smart
  272. // enough to serialize access for construction if it's function-local and
  273. // protected by a guard variable.
  274. //
  275. // KyleP - 20 May, 1993
  276. //
  277. static CDLLStaticMutexSem mxs;
  278. STDAPI_(void) vdprintf(
  279. unsigned long ulCompMask,
  280. char const *pszComp,
  281. char const *ppszfmt,
  282. va_list pargs)
  283. {
  284. if ((ulCompMask & DEB_FORCE) == DEB_FORCE ||
  285. ((ulCompMask | Win4InfoLevel) & Win4InfoMask))
  286. {
  287. #if defined( FLAT )
  288. mxs.Request();
  289. DWORD tid = GetCurrentThreadId();
  290. DWORD pid = GetCurrentProcessId();
  291. if ((Win4InfoLevel & (DEB_DBGOUT | DEB_STDOUT)) != DEB_STDOUT)
  292. #endif // FLAT
  293. {
  294. if (! (ulCompMask & DEB_NOCOMPNAME))
  295. {
  296. #ifdef FLAT
  297. #if defined(_CHICAGO_)
  298. //
  299. // Hex Process/Thread ID's are better for Chicago since both
  300. // actually memory addresses.
  301. //
  302. w4dprintf( "%08x.%08x> ", pid, tid );
  303. #else
  304. w4dprintf( "%d.%03d> ", pid, tid );
  305. #endif
  306. #endif // FLAT
  307. w4dprintf("%s: ", pszComp);
  308. }
  309. w4vdprintf(ppszfmt, pargs);
  310. }
  311. #if defined( FLAT )
  312. if (Win4InfoLevel & DEB_STDOUT)
  313. {
  314. if (! (ulCompMask & DEB_NOCOMPNAME))
  315. {
  316. w4printf( "%03d> ", tid );
  317. w4printf("%s: ", pszComp);
  318. }
  319. w4vprintf(ppszfmt, pargs);
  320. }
  321. mxs.Release();
  322. #endif // FLAT
  323. }
  324. }
  325. #else
  326. int assertDontUseThisName(void)
  327. {
  328. return 1;
  329. }
  330. #endif // DBG == 1