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.

316 lines
8.6 KiB

  1. //+----------------------------------------------------------------------------
  2. //
  3. // File:
  4. // debug.h
  5. //
  6. // Contents:
  7. // macros and declarations for debug support--all are appropriately
  8. // defined to nothing when not doing debug build
  9. //
  10. // Classes:
  11. //
  12. // Functions:
  13. //
  14. // History:
  15. // 12/30/93 - ChrisWe - added file prologue; defined _DEBUG when
  16. // DBG==1; added "const" to ASSERTDATA macro
  17. //
  18. //-----------------------------------------------------------------------------
  19. #ifndef _DEBUG_H_
  20. #define _DEBUG_H_
  21. #include <debnot.h>
  22. #ifndef RC_INVOKED
  23. #ifdef _DEBUG
  24. #define DBGSTATE " Debug is on"
  25. #else
  26. #define DBGSTATE " Debug is off"
  27. #endif
  28. #endif /* RC_INVOKED */
  29. #ifndef _CAIRO_
  30. #include <ole2dbg.h>
  31. #endif
  32. //these are bogus APIs (they do nothing)
  33. STDAPI_(BOOL) ValidateAllObjects( BOOL fSuspicious );
  34. STDAPI_(void) DumpAllObjects( void );
  35. #ifdef _DEBUG
  36. BOOL InstallHooks(void);
  37. BOOL UnInstallHooks(void);
  38. #undef ASSERTDATA
  39. #define ASSERTDATA
  40. #undef AssertSz
  41. #define AssertSz(a,b) ((a) ? NOERROR : FnAssert(#a, b, __FILE__, __LINE__))
  42. #undef Puts
  43. #define Puts(s) OutputDebugString(TEXT(s))
  44. #else // !_DEBUG
  45. #define ASSERTDATA
  46. #define AssertSz(a, b) ((void)0)
  47. #define Puts(s) ((void)0)
  48. #endif // _DEBUG
  49. // special Assert for asserts below (since the expression is so large)
  50. // REVIEW, shouldn't these be in the debug.h file?
  51. #ifdef _DEBUG
  52. #define AssertOut(a, b) { if (!(a)) FnAssert(szCheckOutParam, b, __FILE__, __LINE__); }
  53. #else
  54. #define AssertOut(a, b) ((void)0)
  55. #endif
  56. #define AssertOutPtrParam(hr, p) \
  57. AssertOut(SUCCEEDED(hr) && IsValidPtrIn(p, sizeof(OLECHAR)) || \
  58. FAILED(hr) && (p) == NULL, \
  59. szBadOutParam)
  60. #define AssertOutPtrIface(hr, p) \
  61. AssertOut(SUCCEEDED(hr) && IsValidInterface(p) || \
  62. FAILED(hr) && (p) == NULL, \
  63. szBadOutIface)
  64. #define AssertOutPtrFailed(p) \
  65. AssertOut((p) == NULL, \
  66. szNonNULLOutPtr)
  67. #define AssertOutStgmedium(hr, pstgm) \
  68. AssertOut(SUCCEEDED(hr) && (pstgm)->tymed != TYMED_NULL || \
  69. FAILED(hr) && (pstgm)->tymed == TYMED_NULL, \
  70. szBadOutStgm)
  71. // assert data for above assert out macros; once per dll
  72. // Note that since these are only used in asserts, we leave them as ANSI
  73. #define ASSERTOUTDATA \
  74. char szCheckOutParam[] = "check out param"; \
  75. char szBadOutParam[] = "Out pointer param conventions not followed"; \
  76. char szBadOutIface[] = "Out pointer interface conventions not followed"; \
  77. char szNonNULLOutPtr[] = "Out pointer not NULL on error"; \
  78. char szBadOutStgm[] = "Out stgmed param conventions not followed";
  79. extern char szCheckOutParam[];
  80. extern char szBadOutParam[];
  81. extern char szBadOutIface[];
  82. extern char szNonNULLOutPtr[];
  83. extern char szBadOutStgm[];
  84. #ifdef __cplusplus
  85. interface IDebugStream;
  86. /*
  87. * Class CBool wraps boolean values in such a way that they are
  88. * readily distinguishable fron integers by the compiler so we can
  89. * overload the stream << operator.
  90. */
  91. class FAR CBool
  92. {
  93. BOOL value;
  94. public:
  95. CBool (BOOL& b) {value = b;}
  96. operator BOOL( void ) { return value; }
  97. };
  98. /*
  99. * Class CHwnd wraps HWND values in such a way that they are
  100. * readily distinguishable from UINTS by the compiler so we can
  101. * overload the stream << operator
  102. */
  103. class FAR CHwnd
  104. {
  105. HWND m_hwnd;
  106. public:
  107. CHwnd (HWND hwnd) {m_hwnd = hwnd; }
  108. operator HWND( void ) {return m_hwnd;}
  109. };
  110. /*
  111. * Class CAtom wraps ATOM values in such a way that they are
  112. * readily distinguishable from UINTS by the compiler so we can
  113. * overload the stream << operator
  114. */
  115. class FAR CAtom
  116. {
  117. ATOM m_atom;
  118. public:
  119. CAtom (ATOM atom) {m_atom = atom; }
  120. operator ATOM( void ) {return m_atom; }
  121. };
  122. /*
  123. * IDebugStream is a stream to be used for debug output. One
  124. * implementation uses the OutputDebugString function of Windows.
  125. *
  126. * The style is modeled on that of AT&T streams, and so uses
  127. * overloaded operators. You can write to a stream in the
  128. * following ways:
  129. *
  130. * *pdbstm << pUnk; // calls the IDebug::Dump function to
  131. * display the object, if IDebug is supported.
  132. * int n;
  133. * *pdbstm << n; // writes n in decimal
  134. *
  135. -
  136. * *pdbstm << sz; // writes a string
  137. *
  138. * CBool b(TRUE);
  139. * *pdbstm << b; // writes True or False
  140. *
  141. * void FAR * pv;
  142. * *pdbstm << pv; // writes the address pv in hex
  143. *
  144. * TCHAR ch;
  145. * *pdbstm << ch; // writes the character
  146. *
  147. * ATOM atom;
  148. * *pdbstm << CAtom(atom); // writes the string extracted from the atom
  149. *
  150. * HWND hwnd;
  151. * *pdbstm << CHwnd(hwnd); // writes the info about a window handle
  152. *
  153. * These can be chained together, as such (somewhat artificial
  154. * example):
  155. *
  156. * REFCLSID rclsid;
  157. * pUnk->GetClass(&rclsid);
  158. * *pdbstm << rclsid << " at " << (void FAR *)pUnk <<':' << pUnk;
  159. *
  160. * This produces something like:
  161. *
  162. * CFoo at A7360008: <description of object>
  163. *
  164. * The other useful feature is the Indent and UnIndent functions
  165. * which allow an object to print some information, indent, print
  166. * the info on its member objects, and unindent. This gives
  167. * nicely formatted output.
  168. *
  169. * WARNING: do not (while implementing Dump) write
  170. *
  171. * *pdbstm << pUnkOuter
  172. *
  173. * since this will do a QueryInterface for IDebug, and start
  174. * recursing! It is acceptable to write
  175. *
  176. * *pdbstm << (VOID FAR *)pUnkOuter
  177. *
  178. * as this will simply write the address of pUnkOuter.
  179. *
  180. */
  181. interface IDebugStream : public IUnknown
  182. {
  183. STDMETHOD_(IDebugStream&, operator << ) ( IUnknown FAR * pDebug ) = 0;
  184. STDMETHOD_(IDebugStream&, operator << ) ( REFCLSID rclsid ) = 0;
  185. STDMETHOD_(IDebugStream&, operator << ) ( int n ) = 0;
  186. STDMETHOD_(IDebugStream&, operator << ) ( long l ) = 0;
  187. STDMETHOD_(IDebugStream&, operator << ) ( ULONG l ) = 0;
  188. STDMETHOD_(IDebugStream&, operator << ) ( LPCTSTR sz ) = 0;
  189. STDMETHOD_(IDebugStream&, operator << ) ( TCHAR ch ) = 0;
  190. STDMETHOD_(IDebugStream&, operator << ) ( void FAR * pv ) = 0;
  191. STDMETHOD_(IDebugStream&, operator << ) ( CBool b ) = 0;
  192. STDMETHOD_(IDebugStream&, operator << ) ( CHwnd hwnd ) = 0;
  193. STDMETHOD_(IDebugStream&, operator << ) ( CAtom atom ) = 0;
  194. STDMETHOD_(IDebugStream&, Tab )( void ) = 0;
  195. STDMETHOD_(IDebugStream&, Indent )( void ) = 0;
  196. STDMETHOD_(IDebugStream&, UnIndent )( void ) = 0;
  197. STDMETHOD_(IDebugStream&, Return )( void ) = 0;
  198. STDMETHOD_(IDebugStream&, LF )( void ) = 0;
  199. };
  200. STDAPI_(IDebugStream FAR*) MakeDebugStream( short margin=70, short tabsize=4, BOOL fHeader=1);
  201. interface IDebug
  202. {
  203. STDMETHOD_(void, Dump )( IDebugStream FAR * pdbstm ) = 0;
  204. STDMETHOD_(BOOL, IsValid )( BOOL fSuspicious = FALSE ) = 0;
  205. #ifdef NEVER
  206. __export IDebug(void);
  207. __export ~IDebug(void);
  208. private:
  209. #ifdef _DEBUG
  210. IDebug FAR * pIDPrev;
  211. IDebug FAR * pIDNext;
  212. friend void STDAPICALLTYPE DumpAllObjects( void );
  213. friend BOOL STDAPICALLTYPE ValidateAllObjects( BOOL fSuspicious );
  214. #endif // _DEBUG
  215. #endif // NEVER
  216. };
  217. /*************************************************************************
  218. ** The following functions can be used to log debug messages to a file
  219. ** and simutaneously write them to the dbwin debug window.
  220. ** The CDebugStream implementation automatically writes to a debug
  221. ** log file called "debug.log" in the current working directory.
  222. ** NOTE: The functions are only intended for C programmers. C++
  223. ** programmers should use the "MakeDebugStream" instead.
  224. *************************************************************************/
  225. // Open a log file.
  226. STDAPI_(HFILE) DbgLogOpen(LPCTSTR lpszFile, LPCTSTR lpszMode);
  227. // Close the log file.
  228. STDAPI_(void) DbgLogClose(HFILE fh);
  229. // Write to debug log and debug window (used with cvw.exe or dbwin.exe).
  230. STDAPI_(void) DbgLogOutputDebugString(HFILE fh, LPCTSTR lpsz);
  231. // Write to debug log only.
  232. STDAPI_(void) DbgLogWrite(HFILE fh, LPCTSTR lpsz);
  233. // Write the current Date and Time to the log file.
  234. STDAPI_(void) DbgLogTimeStamp(HFILE fh, LPCTSTR lpsz);
  235. // Write a banner separater to the log to separate sections.
  236. STDAPI_(void) DbgLogWriteBanner(HFILE fh, LPCTSTR lpsz);
  237. /*
  238. * STDDEBDECL macro - helper for debug declaration
  239. *
  240. */
  241. #ifdef _DEBUG
  242. #define STDDEBDECL(ignore, classname ) implement CDebug:public IDebug { public: \
  243. CDebug( C##classname FAR * p##classname ) { m_p##classname = p##classname;} \
  244. ~CDebug(void) {} \
  245. STDMETHOD_(void, Dump)(IDebugStream FAR * pdbstm ); \
  246. STDMETHOD_(BOOL, IsValid)(BOOL fSuspicious ); \
  247. private: C##classname FAR* m_p##classname; }; \
  248. DECLARE_NC(C##classname, CDebug) \
  249. CDebug m_Debug;
  250. #define CONSTRUCT_DEBUG m_Debug(this),
  251. #else // _DEBUG
  252. // no debugging
  253. #define STDDEBDECL(cclassname,classname)
  254. #define CONSTRUCT_DEBUG
  255. #endif // _DEBUG
  256. #endif __cplusplus
  257. #endif // !_DEBUG_H_