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.

472 lines
15 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1999
  5. //
  6. // File: debug.h
  7. //
  8. // Contents: Debug routines and miscelaneous stuff.
  9. //
  10. // Classes: None.
  11. //
  12. // History: 24-Mar-97 EricB Created
  13. //
  14. // Notes on Error Handling: The general rule is that errors will be reported
  15. // to the user as close to the detection of the error as possible. There are
  16. // two exceptions to this rule. First, utility routines that don't take an
  17. // HWND parameter (or a page object pointer) don't report errors because we
  18. // want a window handle so that the error dialogs will be modal. Second,
  19. // there are some circumstances where the error needs to be interpreted at a
  20. // higher level. These exceptions should be noted where they occur.
  21. //
  22. //----------------------------------------------------------------------------
  23. #ifndef __DEBUG_HXX__
  24. #define __DEBUG_HXX__
  25. // macros
  26. #define ByteOffset(base, offset) (((LPBYTE)base)+offset)
  27. //+----------------------------------------------------------------------------
  28. // Macro: LOAD_STRING
  29. // Purpose: attempts to load a string, takes "action" if fails
  30. //-----------------------------------------------------------------------------
  31. #define LOAD_STRING(ids, wcs, len, action) \
  32. if (!LoadString(g_hInstance, ids, wcs, len - 1)) \
  33. { \
  34. DWORD dwErr = GetLastError(); \
  35. dspDebugOut((DEB_ERROR, "LoadString of " #ids " failed with error %lu\n", dwErr)); \
  36. action; \
  37. }
  38. //+----------------------------------------------------------------------------
  39. // Function: LoadStringReport
  40. // Purpose: attempts to load a string, returns FALSE and gives error message
  41. // if a failure occurs.
  42. //-----------------------------------------------------------------------------
  43. BOOL LoadStringReport(int ids, PTSTR ptsz, int len, HWND hwnd);
  44. //
  45. // debugging support
  46. //
  47. #if DBG == 1
  48. #ifndef APINOT
  49. #ifdef _X86_
  50. #define APINOT _stdcall
  51. #else
  52. #define APINOT _cdecl
  53. #endif
  54. #endif
  55. #ifdef __cplusplus
  56. extern "C" {
  57. #define EXTRNC "C"
  58. #else
  59. #define EXTRNC
  60. #endif
  61. // smprintf should only be called from xxDebugOut()
  62. void APINOT
  63. smprintf(
  64. unsigned long ulCompMask,
  65. char const *pszComp,
  66. char const *ppszfmt,
  67. va_list ArgList);
  68. void APINOT
  69. SmAssertEx(
  70. char const *pszFile,
  71. int iLine,
  72. char const *pszMsg);
  73. int APINOT
  74. PopUpError(
  75. char const *pszMsg,
  76. int iLine,
  77. char const *pszFile);
  78. void APINOT
  79. CheckInit(char * pInfoLevelString, unsigned long * InfoLevel);
  80. #define DSP_DEBUG_BUF_SIZE (512)
  81. #ifdef __cplusplus
  82. }
  83. #endif // __cplusplus
  84. //
  85. // Debug print macros
  86. //
  87. #define DEB_ERROR 0x00000001 // exported error paths
  88. #define DEB_WARN 0x00000002 // exported warnings
  89. #define DEB_TRACE 0x00000004 // exported trace messages
  90. #define DEB_DBGOUT 0x00000010 // Output to debugger
  91. #define DEB_STDOUT 0x00000020 // Output to stdout
  92. #define DEB_IERROR 0x00000100 // internal error paths
  93. #define DEB_IWARN 0x00000200 // internal warnings
  94. #define DEB_ITRACE 0x00000400 // internal trace messages
  95. #define DEB_USER1 0x00010000 // User defined
  96. #define DEB_USER2 0x00020000 // User defined
  97. #define DEB_USER3 0x00040000 // User defined
  98. #define DEB_USER4 0x00080000 // User defined
  99. #define DEB_USER5 0x00100000 // User defined
  100. #define DEB_USER6 0x00200000 // User defined
  101. #define DEB_USER7 0x00400000 // User defined
  102. #define DEB_USER8 0x00800000 // User defined
  103. #define DEB_USER9 0x01000000 // User defined
  104. #define DEB_USER10 0x02000000 // User defined
  105. #define DEB_USER11 0x04000000 // User defined
  106. #define DEB_USER12 0x08000000 // User defined
  107. #define DEB_USER13 0x10000000 // User defined
  108. #define DEB_USER14 0x20000000 // User defined
  109. #define DEB_USER15 0x40000000 // User defined
  110. #define DEB_NOCOMPNAME 0x80000000 // suppress component name
  111. #define DEB_FORCE 0x7fffffff // force message
  112. #define ASSRT_MESSAGE 0x00000001 // Output a message
  113. #define ASSRT_BREAK 0x00000002 // Int 3 on assertion
  114. #define ASSRT_POPUP 0x00000004 // And popup message
  115. //+----------------------------------------------------------------------
  116. //
  117. // DECLARE_DEBUG(comp)
  118. // DECLARE_INFOLEVEL(comp)
  119. //
  120. // This macro defines xxDebugOut where xx is the component prefix
  121. // to be defined. This declares a static variable 'xxInfoLevel', which
  122. // can be used to control the type of xxDebugOut messages printed to
  123. // the terminal. For example, xxInfoLevel may be set at the debug terminal.
  124. // This will enable the user to turn debugging messages on or off, based
  125. // on the type desired. The predefined types are defined below. Component
  126. // specific values should use the upper 24 bits
  127. //
  128. // To Use:
  129. //
  130. // 1) In your components main include file, include the line
  131. // DECLARE_DEBUG(comp)
  132. // where comp is your component prefix
  133. //
  134. // 2) In one of your components source files, include the line
  135. // DECLARE_INFOLEVEL(comp)
  136. // where comp is your component prefix. This will define the
  137. // global variable that will control output.
  138. //
  139. // It is suggested that any component define bits be combined with
  140. // existing bits. For example, if you had a specific error path that you
  141. // wanted, you might define DEB_<comp>_ERRORxxx as being
  142. //
  143. // (0x100 | DEB_ERROR)
  144. //
  145. // This way, we can turn on DEB_ERROR and get the error, or just 0x100
  146. // and get only your error.
  147. //
  148. //-----------------------------------------------------------------------
  149. #ifndef DEF_INFOLEVEL
  150. #define DEF_INFOLEVEL (DEB_ERROR | DEB_WARN)
  151. #endif
  152. #define DECLARE_INFOLEVEL(comp) \
  153. extern EXTRNC unsigned long comp##InfoLevel = DEF_INFOLEVEL;\
  154. extern EXTRNC char* comp##InfoLevelString = #comp;
  155. #ifdef __cplusplus
  156. #define DECLARE_DEBUG(comp) \
  157. extern EXTRNC unsigned long comp##InfoLevel; \
  158. extern EXTRNC char *comp##InfoLevelString; \
  159. _inline void \
  160. comp##InlineDebugOut(unsigned long fDebugMask, char const *pszfmt, ...) \
  161. { \
  162. CheckInit(comp##InfoLevelString, &comp##InfoLevel); \
  163. if (comp##InfoLevel & fDebugMask) \
  164. { \
  165. va_list va; \
  166. va_start (va, pszfmt); \
  167. smprintf(fDebugMask, comp##InfoLevelString, pszfmt, va);\
  168. va_end(va); \
  169. } \
  170. } \
  171. \
  172. class comp##CDbgTrace\
  173. {\
  174. private:\
  175. unsigned long _ulFlags;\
  176. char const * const _pszName;\
  177. public:\
  178. comp##CDbgTrace(unsigned long ulFlags, char const * const pszName);\
  179. ~comp##CDbgTrace();\
  180. };\
  181. \
  182. inline comp##CDbgTrace::comp##CDbgTrace(\
  183. unsigned long ulFlags,\
  184. char const * const pszName)\
  185. : _ulFlags(ulFlags), _pszName(pszName)\
  186. {\
  187. comp##InlineDebugOut(_ulFlags, "Entering %s\n", _pszName);\
  188. }\
  189. \
  190. inline comp##CDbgTrace::~comp##CDbgTrace()\
  191. {\
  192. comp##InlineDebugOut(_ulFlags, "Exiting %s\n", _pszName);\
  193. }
  194. #else // ! __cplusplus
  195. #define DECLARE_DEBUG(comp) \
  196. extern EXTRNC unsigned long comp##InfoLevel; \
  197. extern EXTRNC char *comp##InfoLevelString; \
  198. _inline void \
  199. comp##InlineDebugOut(unsigned long fDebugMask, char const *pszfmt, ...) \
  200. { \
  201. CheckInit(comp##InfoLevelString, &comp##InfoLevel);
  202. if (comp##InfoLevel & fDebugMask) \
  203. { \
  204. va_list va; \
  205. va_start (va, pszfmt); \
  206. smprintf(fDebugMask, comp##InfoLevelString, pszfmt, va);\
  207. va_end(va); \
  208. } \
  209. }
  210. #endif // ! __cplusplus
  211. DECLARE_DEBUG(DsProp)
  212. #define dspDebugOut(x) DsPropInlineDebugOut x
  213. #define dspAssert(x) (void)((x) || (SmAssertEx(__FILE__, __LINE__, #x),0))
  214. #include "dscmn.h"
  215. #define ERR_OUT(msg, hr) \
  216. if (SUCCEEDED(hr)) { \
  217. dspDebugOut((DEB_ERROR, #msg "\n")); \
  218. } else { \
  219. dspDebugOut((DEB_ERROR, #msg " failed with error 0x%x\n", hr)); \
  220. ReportError(hr, 0, 0); \
  221. }
  222. #define REPORT_ERROR(hr, hwnd) \
  223. dspDebugOut((DEB_ERROR, "**** ERROR RETURN <%s @line %d> -> %08lx\n", \
  224. __FILE__, __LINE__, hr)); \
  225. ReportError(hr, 0, hwnd);
  226. #define REPORT_ERROR_FORMAT(hr, ids, hwnd) \
  227. dspDebugOut((DEB_ERROR, "**** ERROR RETURN <%s @line %d> -> %08lx\n", \
  228. __FILE__, __LINE__, hr)); \
  229. ReportError(hr, ids, hwnd);
  230. #define ERR_MSG(id, hwnd) \
  231. dspDebugOut((DEB_ERROR, "**** ERROR <%s @line %d> msg string ID: %d\n", \
  232. __FILE__, __LINE__, id)); \
  233. ErrMsg(id, hwnd);
  234. #define CHECK_HRESULT(hr, action) \
  235. if (FAILED(hr)) { \
  236. dspDebugOut((DEB_ERROR, "**** ERROR RETURN <%s @line %d> -> %08lx\n", \
  237. __FILE__, __LINE__, hr)); \
  238. action; \
  239. }
  240. #define CHECK_HRESULT_REPORT(hr, hwnd, action) \
  241. if (FAILED(hr)) { \
  242. dspDebugOut((DEB_ERROR, "**** ERROR RETURN <%s @line %d> -> %08lx\n", \
  243. __FILE__, __LINE__, hr)); \
  244. ReportError(hr, 0, hwnd); \
  245. action; \
  246. }
  247. #define CHECK_NULL(ptr, action) \
  248. if (ptr == NULL) { \
  249. dspDebugOut((DEB_ERROR, "**** ERROR RETURN <%s @line %d> -> NULL ptr\n", \
  250. __FILE__, __LINE__)); \
  251. action; \
  252. }
  253. #define CHECK_NULL_REPORT(ptr, hwnd, action) \
  254. if (ptr == NULL) { \
  255. dspDebugOut((DEB_ERROR, "**** ERROR RETURN <%s @line %d> -> NULL ptr\n", \
  256. __FILE__, __LINE__)); \
  257. ReportError(E_OUTOFMEMORY, 0, hwnd); \
  258. action; \
  259. }
  260. #define CHECK_WIN32(err, action) \
  261. if (err != ERROR_SUCCESS) { \
  262. dspDebugOut((DEB_ERROR, "**** ERROR RETURN <%s @line %d> -> %d\n", \
  263. __FILE__, __LINE__, err)); \
  264. action; \
  265. }
  266. #define CHECK_WIN32_REPORT(err, hwnd, action) \
  267. if (err != ERROR_SUCCESS) { \
  268. dspDebugOut((DEB_ERROR, "**** ERROR RETURN <%s @line %d> -> %d\n", \
  269. __FILE__, __LINE__, err)); \
  270. ReportError(err, 0, hwnd); \
  271. action; \
  272. }
  273. #define CHECK_STATUS(err, action) \
  274. if (!NT_SUCCESS(err)) { \
  275. dspDebugOut((DEB_ERROR, "**** ERROR RETURN <%s @line %d> -> 0x%08x\n", \
  276. __FILE__, __LINE__, err)); \
  277. action; \
  278. }
  279. #define CHECK_STATUS_REPORT(err, hwnd, action) \
  280. if (!NT_SUCCESS(err)) { \
  281. dspDebugOut((DEB_ERROR, "**** ERROR RETURN <%s @line %d> -> 0x%08x\n", \
  282. __FILE__, __LINE__, err)); \
  283. ReportError(RtlNtStatusToDosError(err), 0, hwnd); \
  284. action; \
  285. }
  286. #define CHECK_LSA_STATUS(err, action) \
  287. if (!NT_SUCCESS(err)) { \
  288. dspDebugOut((DEB_ERROR, "**** ERROR RETURN <%s @line %d> -> 0x%08x\n", \
  289. __FILE__, __LINE__, err)); \
  290. action; \
  291. }
  292. #define CHECK_LSA_STATUS_REPORT(err, hwnd, action) \
  293. if (!NT_SUCCESS(err)) { \
  294. dspDebugOut((DEB_ERROR, "**** ERROR RETURN <%s @line %d> -> 0x%08x\n", \
  295. __FILE__, __LINE__, err)); \
  296. ReportError(LsaNtStatusToWinError(err), 0, hwnd); \
  297. action; \
  298. }
  299. #define TRACER(ClassName,MethodName) \
  300. dspDebugOut((DEB_TRACE, #ClassName"::"#MethodName"(0x%p)\n", this)); \
  301. if (DsPropInfoLevel & DEB_USER5) HeapValidate(GetProcessHeap(), 0, NULL);
  302. #define TRACE(ClassName,MethodName) \
  303. dspDebugOut((DEB_USER1, #ClassName"::"#MethodName"(0x%p)\n", this)); \
  304. if (DsPropInfoLevel & DEB_USER5) HeapValidate(GetProcessHeap(), 0, NULL);
  305. #define TRACE2(ClassName,MethodName) \
  306. dspDebugOut((DEB_USER2, #ClassName"::"#MethodName"(0x%p)\n", this)); \
  307. if (DsPropInfoLevel & DEB_USER5) HeapValidate(GetProcessHeap(), 0, NULL);
  308. #define TRACE3(ClassName,MethodName) \
  309. dspDebugOut((DEB_USER3, #ClassName"::"#MethodName"(0x%p)\n", this)); \
  310. if (DsPropInfoLevel & DEB_USER5) HeapValidate(GetProcessHeap(), 0, NULL);
  311. #define TRACE_FUNCTION(FunctionName) \
  312. dspDebugOut((DEB_USER1, #FunctionName"\n"));
  313. #define TRACE_FUNCTION3(FunctionName) \
  314. dspDebugOut((DEB_USER3, #FunctionName"\n"));
  315. #define DBG_OUT(String) \
  316. dspDebugOut((DEB_ITRACE, String "\n"));
  317. #define DBG_OUT3(String) \
  318. dspDebugOut((DEB_USER3, String "\n"));
  319. #else // DBG != 1
  320. #define DECLARE_DEBUG(comp)
  321. #define DECLARE_INFOLEVEL(comp)
  322. #define dspDebugOut(x)
  323. #define dspAssert(x)
  324. #include "dscmn.h"
  325. #define ERR_OUT(msg, hr) \
  326. ReportError(hr, 0, 0);
  327. #define REPORT_ERROR(hr, hwnd) ReportError(hr, 0, hwnd);
  328. #define REPORT_ERROR_FORMAT(hr, ids, hwnd) ReportError(hr, ids, hwnd);
  329. #define ERR_MSG(id, hwnd) \
  330. ErrMsg(id, hwnd);
  331. #define CHECK_HRESULT(hr, action) \
  332. if (FAILED(hr)) { \
  333. action; \
  334. }
  335. #define CHECK_HRESULT_H(hr, hwnd, action) \
  336. if (FAILED(hr)) { \
  337. action; \
  338. }
  339. #define CHECK_HRESULT_REPORT(hr, hwnd, action) \
  340. if (FAILED(hr)) { \
  341. ReportError(hr, 0, hwnd); \
  342. action; \
  343. }
  344. #define CHECK_NULL(ptr, action) \
  345. if (ptr == NULL) { \
  346. action; \
  347. }
  348. #define CHECK_NULL_REPORT(ptr, hwnd, action) \
  349. if (ptr == NULL) { \
  350. ReportError(E_OUTOFMEMORY, 0, hwnd); \
  351. action; \
  352. }
  353. #define CHECK_WIN32(err, action) \
  354. if (err != ERROR_SUCCESS) { \
  355. ReportError(err, 0); \
  356. action; \
  357. }
  358. #define CHECK_WIN32_REPORT(err, hwnd, action) \
  359. if (err != ERROR_SUCCESS) { \
  360. ReportError(err, 0, hwnd); \
  361. action; \
  362. }
  363. #define CHECK_STATUS(err, action) \
  364. if (!NT_SUCCESS(err)) { \
  365. action; \
  366. }
  367. #define CHECK_STATUS_REPORT(err, hwnd, action) \
  368. if (!NT_SUCCESS(err)) { \
  369. ReportError(err, 0, hwnd); \
  370. action; \
  371. }
  372. #define CHECK_LSA_STATUS(err, action) \
  373. if (!NT_SUCCESS(err)) { \
  374. action; \
  375. }
  376. #define CHECK_LSA_STATUS_REPORT(err, hwnd, action) \
  377. if (!NT_SUCCESS(err)) { \
  378. ReportError(LsaNtStatusToWinError(err), 0, hwnd); \
  379. action; \
  380. }
  381. #define TRACER(ClassName,MethodName)
  382. #define TRACE(ClassName,MethodName)
  383. #define TRACE2(ClassName,MethodName)
  384. #define TRACE3(ClassName,MethodName)
  385. #define TRACE_FUNCTION(FunctionName)
  386. #define TRACE_FUNCTION3(FunctionName)
  387. #define DBG_OUT(String)
  388. #define DBG_OUT3(String)
  389. #endif // DBG == 1
  390. #endif // __DEBUG_HXX__