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.

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