/////////////////////////////////////////////////////////////////////////////// // // File: tmutils.h // // Description: Useful Tepmlate Code, debugging stuff, general utilities // used throughout the termmgr and MST // /////////////////////////////////////////////////////////////////////////////// // // Note: // // use tm.h to define symbols shared throughout modules composing terminal // manager // #ifndef ___TM_UTILS_INCLUDED___ #define ___TM_UTILS_INCLUDED___ #if defined(_DEBUG) #define new new(_NORMAL_BLOCK, __FILE__, __LINE__) #endif #define DECLARE_VQI() \ STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject) = 0; \ STDMETHOD_(ULONG, AddRef)() = 0; \ STDMETHOD_(ULONG, Release)() = 0; bool IsSameObject(IUnknown *pUnk1, IUnknown *pUnk2); STDAPI_(void) TStringFromGUID(const GUID* pguid, LPTSTR pszBuf); #ifdef UNICODE #define WStringFromGUID TStringFromGUID #else STDAPI_(void) WStringFromGUID(const GUID* pguid, LPWSTR pszBuf); #endif void InitMediaType(AM_MEDIA_TYPE *pmt); // We use ATL for our lists // #include // #define CList CSimpleArray // We use our own assertions #define ASSERT(x) TM_ASSERT(x) // inline fns, macros inline BOOL HRESULT_FAILURE( IN HRESULT HResult ) { // ZoltanS: We now consider S_FALSE to be success. Hopefully nothing // depends on this... // return (FAILED(HResult) || (S_FALSE == HResult)); return FAILED(HResult); } // ZoltanS: We now consider S_FALSE to be success. Hopefully nothing // depends on this... // if ( FAILED(LocalHResult) || (S_FALSE == LocalHResult) ) #define BAIL_ON_FAILURE(MacroHResult) \ { \ HRESULT LocalHResult = MacroHResult ; \ if ( FAILED(LocalHResult) ) \ { \ LOG((MSP_ERROR, "BAIL_ON_FAILURE - error %x", LocalHResult)); \ return LocalHResult; \ } \ } // NULL is second - this way if an == operator // is defined on Ptr, the operator may be used #define BAIL_IF_NULL(Ptr, ReturnValue) \ { \ void *LocalPtr = (void *)Ptr; \ if ( LocalPtr == NULL ) \ { \ LOG((MSP_ERROR, "BAIL_IF_NULL - ret value %x", ReturnValue)); \ return ReturnValue; \ } \ } // sets the first bit to indicate error // sets the win32 facility code // this is used instead of the HRESULT_FROM_WIN32 macro because that clears the customer flag inline long HRESULT_FROM_ERROR_CODE( IN long ErrorCode ) { // LOG((MSP_ERROR, "HRESULT_FROM_ERROR_CODE - error %x", (0x80070000 | (0xa000ffff & ErrorCode)))); return ( 0x80070000 | (0xa000ffff & ErrorCode) ); } ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// // Better auto critical section lock ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// // locks a critical section, and unlocks it automatically // when the lock goes out of scope ONLY if (and as many times as) // it holds it // It may also be locked and unlocked independently template class LOCAL_CRIT_LOCK { public: LOCAL_CRIT_LOCK( IN T *plock ) { m_pLock = plock; m_pLock->Lock(); NumLocksHeld = 1; } BOOL IsLocked( ) { return ( (NumLocksHeld > 0)? TRUE : FALSE ); } void Lock( ) { m_pLock->Lock(); NumLocksHeld++; } void Unlock( ) { NumLocksHeld--; m_pLock->Unlock(); } ~LOCAL_CRIT_LOCK( ) { while (IsLocked()) { Unlock(); } } protected: DWORD NumLocksHeld; T *m_pLock; private: // make copy constructor and assignment operator inaccessible LOCAL_CRIT_LOCK( IN const LOCAL_CRIT_LOCK &RefLocalLock ); LOCAL_CRIT_LOCK &operator=(const LOCAL_CRIT_LOCK &RefLocalLock); }; typedef LOCAL_CRIT_LOCK COM_LOCAL_CRIT_LOCK; #ifdef DBG // // Declare methods to log the AddRef/Release calls and values // #define DECLARE_DEBUG_ADDREF_RELEASE(x) \ void LogDebugAddRef(DWORD dw) \ { LOG((MSP_TRACE, "%s::AddRef() = %d", _T(#x), dw)); } \ void LogDebugRelease(DWORD dw) \ { LOG((MSP_TRACE, "%s::Release() = %d", _T(#x), dw)); } // // Create a template class derived from CComObject to supply // the debug logic. // template class CTMComObject : public CComObject { typedef CComObject _BaseClass; STDMETHOD_(ULONG, AddRef)() { DWORD dwR = _BaseClass::AddRef(); base::LogDebugAddRef(m_dwRef); return dwR; } STDMETHOD_(ULONG, Release)() { DWORD dwRef = m_dwRef; DWORD dwR = _BaseClass::Release(); LogDebugRelease(--dwRef); return dwR; } }; #else // #ifdef DBG #define DECLARE_DEBUG_ADDREF_RELEASE(x) #endif // #ifdef DBG // ??? why??? #ifndef __WXUTIL__ // locks a critical section, and unlocks it automatically // when the lock goes out of scope class CAutoObjectLock { // make copy constructor and assignment operator inaccessible CAutoObjectLock(const CAutoObjectLock &refAutoLock); CAutoObjectLock &operator=(const CAutoObjectLock &refAutoLock); protected: CComObjectRoot * m_pObject; public: CAutoObjectLock(CComObjectRoot * pobject) { m_pObject = pobject; m_pObject->Lock(); }; ~CAutoObjectLock() { m_pObject->Unlock(); }; }; #define AUTO_CRIT_LOCK CAutoObjectLock lck(this); #ifdef _DEBUG #define EXECUTE_ASSERT(_x_) TM_ASSERT(_x_) #else #define EXECUTE_ASSERT(_x_) _x_ #endif // ??? why??? #endif // #ifndef __WXUTIL__ #endif // ___TM_UTILS_INCLUDED___ // eof