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.

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