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