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.

384 lines
13 KiB

  1. //------------------------------------------------------------------------------
  2. // File: WXDebug.h
  3. //
  4. // Desc: DirectShow base classes - provides debugging facilities.
  5. //
  6. //@@BEGIN_MSINTERNAL
  7. //
  8. // January 1995
  9. //
  10. //@@END_MSINTERNAL
  11. // Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
  12. //------------------------------------------------------------------------------
  13. #ifndef __WXDEBUG__
  14. #define __WXDEBUG__
  15. // This library provides fairly straight forward debugging functionality, this
  16. // is split into two main sections. The first is assertion handling, there are
  17. // three types of assertions provided here. The most commonly used one is the
  18. // ASSERT(condition) macro which will pop up a message box including the file
  19. // and line number if the condition evaluates to FALSE. Then there is the
  20. // EXECUTE_ASSERT macro which is the same as ASSERT except the condition will
  21. // still be executed in NON debug builds. The final type of assertion is the
  22. // KASSERT macro which is more suitable for pure (perhaps kernel) filters as
  23. // the condition is printed onto the debugger rather than in a message box.
  24. //
  25. // The other part of the debug module facilties is general purpose logging.
  26. // This is accessed by calling DbgLog(). The function takes a type and level
  27. // field which define the type of informational string you are presenting and
  28. // it's relative importance. The type field can be a combination (one or more)
  29. // of LOG_TIMING, LOG_TRACE, LOG_MEMORY, LOG_LOCKING and LOG_ERROR. The level
  30. // is a DWORD value where zero defines highest important. Use of zero as the
  31. // debug logging level is to be encouraged ONLY for major errors or events as
  32. // they will ALWAYS be displayed on the debugger. Other debug output has it's
  33. // level matched against the current debug output level stored in the registry
  34. // for this module and if less than the current setting it will be displayed.
  35. //
  36. // Each module or executable has it's own debug output level for each of the
  37. // five types. These are read in when the DbgInitialise function is called
  38. // for DLLs linking to STRMBASE.LIB this is done automatically when the DLL
  39. // is loaded, executables must call it explicitely with the module instance
  40. // handle given to them through the WINMAIN entry point. An executable must
  41. // also call DbgTerminate when they have finished to clean up the resources
  42. // the debug library uses, once again this is done automatically for DLLs
  43. // These are the five different categories of logging information
  44. enum { LOG_TIMING = 0x01, // Timing and performance measurements
  45. LOG_TRACE = 0x02, // General step point call tracing
  46. LOG_MEMORY = 0x04, // Memory and object allocation/destruction
  47. LOG_LOCKING = 0x08, // Locking/unlocking of critical sections
  48. LOG_ERROR = 0x10, // Debug error notification
  49. LOG_CUSTOM1 = 0x20,
  50. LOG_CUSTOM2 = 0x40,
  51. LOG_CUSTOM3 = 0x80,
  52. LOG_CUSTOM4 = 0x100,
  53. LOG_CUSTOM5 = 0x200,
  54. };
  55. #define LOG_FORCIBLY_SET 0x80000000
  56. enum { CDISP_HEX = 0x01,
  57. CDISP_DEC = 0x02};
  58. // For each object created derived from CBaseObject (in debug builds) we
  59. // create a descriptor that holds it's name (statically allocated memory)
  60. // and a cookie we assign it. We keep a list of all the active objects
  61. // we have registered so that we can dump a list of remaining objects
  62. typedef struct tag_ObjectDesc {
  63. const CHAR *m_szName;
  64. const WCHAR *m_wszName;
  65. DWORD m_dwCookie;
  66. tag_ObjectDesc *m_pNext;
  67. } ObjectDesc;
  68. #define DLLIMPORT __declspec(dllimport)
  69. #define DLLEXPORT __declspec(dllexport)
  70. #ifdef DEBUG
  71. #define NAME(x) TEXT(x)
  72. // These are used internally by the debug library (PRIVATE)
  73. void WINAPI DbgInitKeyLevels(HKEY hKey, bool fTakeMax);
  74. void WINAPI DbgInitGlobalSettings(bool fTakeMax);
  75. void WINAPI DbgInitModuleSettings(bool fTakeMax);
  76. void WINAPI DbgInitModuleName();
  77. DWORD WINAPI DbgRegisterObjectCreation(
  78. const CHAR *szObjectName, const WCHAR *wszObjectName);
  79. BOOL WINAPI DbgRegisterObjectDestruction(DWORD dwCookie);
  80. // These are the PUBLIC entry points
  81. BOOL WINAPI DbgCheckModuleLevel(DWORD Type,DWORD Level);
  82. void WINAPI DbgSetModuleLevel(DWORD Type,DWORD Level);
  83. void WINAPI DbgSetAutoRefreshLevels(bool fAuto);
  84. // Initialise the library with the module handle
  85. void WINAPI DbgInitialise(HINSTANCE hInst);
  86. void WINAPI DbgTerminate();
  87. void WINAPI DbgDumpObjectRegister();
  88. // Display error and logging to the user
  89. void WINAPI DbgAssert(const TCHAR *pCondition,const TCHAR *pFileName,INT iLine);
  90. void WINAPI DbgBreakPoint(const TCHAR *pCondition,const TCHAR *pFileName,INT iLine);
  91. void WINAPI DbgBreakPoint(const TCHAR *pFileName,INT iLine,const TCHAR* szFormatString,...);
  92. void WINAPI DbgKernelAssert(const TCHAR *pCondition,const TCHAR *pFileName,INT iLine);
  93. void WINAPI DbgLogInfo(DWORD Type,DWORD Level,const TCHAR *pFormat,...);
  94. #ifdef UNICODE
  95. void WINAPI DbgLogInfo(DWORD Type,DWORD Level,const CHAR *pFormat,...);
  96. void WINAPI DbgAssert(const CHAR *pCondition,const CHAR *pFileName,INT iLine);
  97. void WINAPI DbgBreakPoint(const CHAR *pCondition,const CHAR *pFileName,INT iLine);
  98. void WINAPI DbgKernelAssert(const CHAR *pCondition,const CHAR *pFileName,INT iLine);
  99. #endif
  100. void WINAPI DbgOutString(LPCTSTR psz);
  101. // Debug infinite wait stuff
  102. DWORD WINAPI DbgWaitForSingleObject(HANDLE h);
  103. DWORD WINAPI DbgWaitForMultipleObjects(DWORD nCount,
  104. CONST HANDLE *lpHandles,
  105. BOOL bWaitAll);
  106. void WINAPI DbgSetWaitTimeout(DWORD dwTimeout);
  107. #ifdef __strmif_h__
  108. // Display a media type: Terse at level 2, verbose at level 5
  109. void WINAPI DisplayType(LPTSTR label, const AM_MEDIA_TYPE *pmtIn);
  110. // Dump lots of information about a filter graph
  111. void WINAPI DumpGraph(IFilterGraph *pGraph, DWORD dwLevel);
  112. #endif
  113. #define KASSERT(_x_) if (!(_x_)) \
  114. DbgKernelAssert(TEXT(#_x_),TEXT(__FILE__),__LINE__)
  115. // Break on the debugger without putting up a message box
  116. // message goes to debugger instead
  117. #define KDbgBreak(_x_) \
  118. DbgKernelAssert(TEXT(#_x_),TEXT(__FILE__),__LINE__)
  119. // We chose a common name for our ASSERT macro, MFC also uses this name
  120. // So long as the implementation evaluates the condition and handles it
  121. // then we will be ok. Rather than override the behaviour expected we
  122. // will leave whatever first defines ASSERT as the handler (i.e. MFC)
  123. #ifndef ASSERT
  124. #define ASSERT(_x_) if (!(_x_)) \
  125. DbgAssert(TEXT(#_x_),TEXT(__FILE__),__LINE__)
  126. #endif
  127. #define DbgAssertAligned( _ptr_, _alignment_ ) ASSERT( ((DWORD_PTR) (_ptr_)) % (_alignment_) == 0)
  128. // Put up a message box informing the user of a halt
  129. // condition in the program
  130. #define DbgBreak(_x_) \
  131. DbgBreakPoint(TEXT(#_x_),TEXT(__FILE__),__LINE__)
  132. #define EXECUTE_ASSERT(_x_) ASSERT(_x_)
  133. #define DbgLog(_x_) DbgLogInfo _x_
  134. // MFC style trace macros
  135. #define NOTE(_x_) DbgLog((LOG_TRACE,5,TEXT(_x_)))
  136. #define NOTE1(_x_,a) DbgLog((LOG_TRACE,5,TEXT(_x_),a))
  137. #define NOTE2(_x_,a,b) DbgLog((LOG_TRACE,5,TEXT(_x_),a,b))
  138. #define NOTE3(_x_,a,b,c) DbgLog((LOG_TRACE,5,TEXT(_x_),a,b,c))
  139. #define NOTE4(_x_,a,b,c,d) DbgLog((LOG_TRACE,5,TEXT(_x_),a,b,c,d))
  140. #define NOTE5(_x_,a,b,c,d,e) DbgLog((LOG_TRACE,5,TEXT(_x_),a,b,c,d,e))
  141. #else
  142. // Retail builds make public debug functions inert - WARNING the source
  143. // files do not define or build any of the entry points in debug builds
  144. // (public entry points compile to nothing) so if you go trying to call
  145. // any of the private entry points in your source they won't compile
  146. #define NAME(_x_) ((TCHAR *) NULL)
  147. #define DbgInitialise(hInst)
  148. #define DbgTerminate()
  149. #define DbgLog(_x_) 0
  150. #define DbgOutString(psz)
  151. #define DbgAssertAligned( _ptr_, _alignment_ ) 0
  152. #define DbgRegisterObjectCreation(pObjectName)
  153. #define DbgRegisterObjectDestruction(dwCookie)
  154. #define DbgDumpObjectRegister()
  155. #define DbgCheckModuleLevel(Type,Level)
  156. #define DbgSetModuleLevel(Type,Level)
  157. #define DbgSetAutoRefreshLevels(fAuto)
  158. #define DbgWaitForSingleObject(h) WaitForSingleObject(h, INFINITE)
  159. #define DbgWaitForMultipleObjects(nCount, lpHandles, bWaitAll) \
  160. WaitForMultipleObjects(nCount, lpHandles, bWaitAll, INFINITE)
  161. #define DbgSetWaitTimeout(dwTimeout)
  162. #define KDbgBreak(_x_)
  163. #define DbgBreak(_x_)
  164. #define KASSERT(_x_) ((void)0)
  165. #ifndef ASSERT
  166. #define ASSERT(_x_) ((void)0)
  167. #endif
  168. #define EXECUTE_ASSERT(_x_) ((void)(_x_))
  169. // MFC style trace macros
  170. #define NOTE(_x_) ((void)0)
  171. #define NOTE1(_x_,a) ((void)0)
  172. #define NOTE2(_x_,a,b) ((void)0)
  173. #define NOTE3(_x_,a,b,c) ((void)0)
  174. #define NOTE4(_x_,a,b,c,d) ((void)0)
  175. #define NOTE5(_x_,a,b,c,d,e) ((void)0)
  176. #define DisplayType(label, pmtIn) ((void)0)
  177. #define DumpGraph(pGraph, label) ((void)0)
  178. #endif
  179. // Checks a pointer which should be non NULL - can be used as follows.
  180. #define CheckPointer(p,ret) {if((p)==NULL) return (ret);}
  181. // HRESULT Foo(VOID *pBar)
  182. // {
  183. // CheckPointer(pBar,E_INVALIDARG)
  184. // }
  185. //
  186. // Or if the function returns a boolean
  187. //
  188. // BOOL Foo(VOID *pBar)
  189. // {
  190. // CheckPointer(pBar,FALSE)
  191. // }
  192. // These validate pointers when symbol VFWROBUST is defined
  193. // This will normally be defined in debug not retail builds
  194. #ifdef DEBUG
  195. #define VFWROBUST
  196. #endif
  197. #ifdef VFWROBUST
  198. #define ValidateReadPtr(p,cb) \
  199. {if(IsBadReadPtr((PVOID)p,cb) == TRUE) \
  200. DbgBreak("Invalid read pointer");}
  201. #define ValidateWritePtr(p,cb) \
  202. {if(IsBadWritePtr((PVOID)p,cb) == TRUE) \
  203. DbgBreak("Invalid write pointer");}
  204. #define ValidateReadWritePtr(p,cb) \
  205. {ValidateReadPtr(p,cb) ValidateWritePtr(p,cb)}
  206. #define ValidateStringPtr(p) \
  207. {if(IsBadStringPtr((LPCTSTR)p,INFINITE) == TRUE) \
  208. DbgBreak("Invalid string pointer");}
  209. #define ValidateStringPtrA(p) \
  210. {if(IsBadStringPtrA((LPCSTR)p,INFINITE) == TRUE) \
  211. DbgBreak("Invalid ANSI string pointer");}
  212. #define ValidateStringPtrW(p) \
  213. {if(IsBadStringPtrW((LPCWSTR)p,INFINITE) == TRUE) \
  214. DbgBreak("Invalid UNICODE string pointer");}
  215. #else
  216. #define ValidateReadPtr(p,cb) 0
  217. #define ValidateWritePtr(p,cb) 0
  218. #define ValidateReadWritePtr(p,cb) 0
  219. #define ValidateStringPtr(p) 0
  220. #define ValidateStringPtrA(p) 0
  221. #define ValidateStringPtrW(p) 0
  222. #endif
  223. #ifdef _OBJBASE_H_
  224. // Outputting GUID names. If you want to include the name
  225. // associated with a GUID (eg CLSID_...) then
  226. //
  227. // GuidNames[yourGUID]
  228. //
  229. // Returns the name defined in uuids.h as a string
  230. typedef struct {
  231. CHAR *szName;
  232. GUID guid;
  233. } GUID_STRING_ENTRY;
  234. class CGuidNameList {
  235. public:
  236. CHAR *operator [] (const GUID& guid);
  237. };
  238. extern CGuidNameList GuidNames;
  239. #endif
  240. #ifndef REMIND
  241. // REMIND macro - generates warning as reminder to complete coding
  242. // (eg) usage:
  243. //
  244. // #pragma message (REMIND("Add automation support"))
  245. #define QUOTE(x) #x
  246. #define QQUOTE(y) QUOTE(y)
  247. #define REMIND(str) __FILE__ "(" QQUOTE(__LINE__) ") : " str
  248. #endif
  249. // Method to display objects in a useful format
  250. //
  251. // eg If you want to display a LONGLONG ll in a debug string do (eg)
  252. //
  253. // DbgLog((LOG_TRACE, n, TEXT("Value is %s"), (LPCTSTR)CDisp(ll, CDISP_HEX)));
  254. class CDispBasic
  255. {
  256. public:
  257. CDispBasic() { m_pString = m_String; };
  258. ~CDispBasic();
  259. protected:
  260. PTCHAR m_pString; // normally points to m_String... unless too much data
  261. TCHAR m_String[50];
  262. };
  263. class CDisp : public CDispBasic
  264. {
  265. public:
  266. CDisp(LONGLONG ll, int Format = CDISP_HEX); // Display a LONGLONG in CDISP_HEX or CDISP_DEC form
  267. CDisp(REFCLSID clsid); // Display a GUID
  268. CDisp(double d); // Display a floating point number
  269. #ifdef __strmif_h__
  270. #ifdef __STREAMS__
  271. CDisp(CRefTime t); // Display a Reference Time
  272. #endif
  273. CDisp(IPin *pPin); // Display a pin as {filter clsid}(pin name)
  274. CDisp(IUnknown *pUnk); // Display a filter or pin
  275. #endif // __strmif_h__
  276. ~CDisp();
  277. // Implement cast to (LPCTSTR) as parameter to logger
  278. operator LPCTSTR()
  279. {
  280. return (LPCTSTR)m_pString;
  281. };
  282. };
  283. #if defined(DEBUG)
  284. class CAutoTrace
  285. {
  286. private:
  287. const TCHAR* _szBlkName;
  288. const int _level;
  289. static const TCHAR _szEntering[];
  290. static const TCHAR _szLeaving[];
  291. public:
  292. CAutoTrace(const TCHAR* szBlkName, const int level = 15)
  293. : _szBlkName(szBlkName), _level(level)
  294. {DbgLog((LOG_TRACE, _level, _szEntering, _szBlkName));}
  295. ~CAutoTrace()
  296. {DbgLog((LOG_TRACE, _level, _szLeaving, _szBlkName));}
  297. };
  298. #define AMTRACE(_x_) CAutoTrace __trace _x_
  299. #else
  300. #define AMTRACE(_x_)
  301. #endif
  302. #endif // __WXDEBUG__