1 /** 2 * This file has no copyright assigned and is placed in the Public Domain. 3 * This file is part of the mingw-w64 runtime package. 4 * No warranty is given; refer to the file DISCLAIMER.PD within this package. 5 */ 6 #ifndef __MSPUTILS_H_ 7 #define __MSPUTILS_H_ 8 9 #if _ATL_VER >= 0x0300 10 #define DECLARE_VQI() 11 #else 12 #define DECLARE_VQI() STDMETHOD(QueryInterface)(REFIID iid,void **ppvObject) = 0; STDMETHOD_(ULONG,AddRef)() = 0; STDMETHOD_(ULONG,Release)() = 0; 13 #endif 14 15 #define MSP_(hr) (FAILED(hr)?MSP_ERROR:MSP_TRACE) 16 17 extern __inline WINBOOL IsValidAggregatedMediaType(DWORD dwAggregatedMediaType) { 18 const DWORD dwAllPossibleMediaTypes = TAPIMEDIATYPE_AUDIO | TAPIMEDIATYPE_VIDEO | TAPIMEDIATYPE_DATAMODEM | TAPIMEDIATYPE_G3FAX | TAPIMEDIATYPE_MULTITRACK; 19 WINBOOL bValidMediaType = FALSE; 20 if((0==(dwAggregatedMediaType & dwAllPossibleMediaTypes)) || (0!=(dwAggregatedMediaType & (~dwAllPossibleMediaTypes)))) { 21 bValidMediaType = FALSE; 22 } else { 23 bValidMediaType = TRUE; 24 } 25 return bValidMediaType; 26 } 27 28 extern __inline WINBOOL IsSingleMediaType(DWORD dwMediaType) { return !((dwMediaType==0) || ((dwMediaType & (dwMediaType - 1))!=0)); } 29 extern __inline WINBOOL IsValidSingleMediaType(DWORD dwMediaType,DWORD dwMask) { return IsSingleMediaType(dwMediaType) && ((dwMediaType & dwMask)==dwMediaType); } 30 31 const DWORD INITIAL = 8; 32 const DWORD DELTA = 8; 33 34 template <class T,DWORD dwInitial = INITIAL,DWORD dwDelta = DELTA> class CMSPArray { 35 protected: 36 T *m_aT; 37 int m_nSize; 38 int m_nAllocSize; 39 public: 40 CMSPArray() : m_aT(NULL),m_nSize(0),m_nAllocSize(0) { } 41 ~CMSPArray() { RemoveAll(); } 42 int GetSize() const { return m_nSize; } 43 WINBOOL Grow() { 44 T *aT; 45 int nNewAllocSize = (m_nAllocSize==0) ? dwInitial : (m_nSize + DELTA); 46 aT = (T *)realloc(m_aT,nNewAllocSize *sizeof(T)); 47 if(!aT) return FALSE; 48 m_nAllocSize = nNewAllocSize; 49 m_aT = aT; 50 return TRUE; 51 } 52 WINBOOL Add(T &t) { 53 if(m_nSize==m_nAllocSize) { 54 if(!Grow()) return FALSE; 55 } 56 m_nSize++; 57 SetAtIndex(m_nSize - 1,t); 58 return TRUE; 59 } 60 WINBOOL Remove(T &t) { 61 int nIndex = Find(t); 62 if(nIndex==-1) return FALSE; 63 return RemoveAt(nIndex); 64 } 65 WINBOOL RemoveAt(int nIndex) { 66 if(nIndex!=(m_nSize - 1)) 67 memmove((void*)&m_aT[nIndex],(void*)&m_aT[nIndex + 1],(m_nSize - (nIndex + 1))*sizeof(T)); 68 m_nSize--; 69 return TRUE; 70 } 71 void RemoveAll() { 72 if(m_nAllocSize > 0) { 73 free(m_aT); 74 m_aT = NULL; 75 m_nSize = 0; 76 m_nAllocSize = 0; 77 } 78 } 79 T &operator[] (int nIndex) const { 80 _ASSERTE(nIndex >= 0 && nIndex < m_nSize); 81 return m_aT[nIndex]; 82 } 83 T *GetData() const { return m_aT; } 84 void SetAtIndex(int nIndex,T &t) { 85 _ASSERTE(nIndex >= 0 && nIndex < m_nSize); 86 m_aT[nIndex] = t; 87 } 88 int Find(T &t) const { 89 for(int i = 0;i < m_nSize;i++) { 90 if(m_aT[i]==t) return i; 91 } 92 return -1; 93 } 94 }; 95 96 class CMSPCritSection { 97 private: 98 CRITICAL_SECTION m_CritSec; 99 public: 100 CMSPCritSection() { InitializeCriticalSection(&m_CritSec); } 101 ~CMSPCritSection() { DeleteCriticalSection(&m_CritSec); } 102 void Lock() { EnterCriticalSection(&m_CritSec); } 103 WINBOOL TryLock() { return TryEnterCriticalSection(&m_CritSec); } 104 void Unlock() { LeaveCriticalSection(&m_CritSec); } 105 }; 106 107 class CLock { 108 private: 109 CMSPCritSection &m_CriticalSection; 110 public: 111 CLock(CMSPCritSection &CriticalSection) : m_CriticalSection(CriticalSection) { 112 m_CriticalSection.Lock(); 113 } 114 ~CLock() { m_CriticalSection.Unlock(); } 115 }; 116 117 class CCSLock { 118 private: 119 CRITICAL_SECTION *m_pCritSec; 120 public: 121 CCSLock(CRITICAL_SECTION *pCritSec) : m_pCritSec(pCritSec) { 122 EnterCriticalSection(m_pCritSec); 123 } 124 ~CCSLock() { LeaveCriticalSection(m_pCritSec); } 125 }; 126 127 #ifndef CONTAINING_RECORD 128 #define CONTAINING_RECORD(address,type,field) ((type *)((PCHAR)(address) - (ULONG_PTR)(&((type *)0)->field))) 129 #endif 130 131 #ifndef InitializeListHead 132 #define InitializeListHead(ListHead) ((ListHead)->Flink = (ListHead)->Blink = (ListHead)) 133 #define IsListEmpty(ListHead) ((ListHead)->Flink==(ListHead)) 134 #define RemoveHeadList(ListHead) (ListHead)->Flink; {RemoveEntryList((ListHead)->Flink)} 135 #define RemoveTailList(ListHead) (ListHead)->Blink; {RemoveEntryList((ListHead)->Blink)} 136 #define RemoveEntryList(Entry) { PLIST_ENTRY _EX_Blink; PLIST_ENTRY _EX_Flink; _EX_Flink = (Entry)->Flink; _EX_Blink = (Entry)->Blink; _EX_Blink->Flink = _EX_Flink; _EX_Flink->Blink = _EX_Blink; } 137 #define InsertTailList(ListHead,Entry) { PLIST_ENTRY _EX_Blink; PLIST_ENTRY _EX_ListHead; _EX_ListHead = (ListHead); _EX_Blink = _EX_ListHead->Blink; (Entry)->Flink = _EX_ListHead; (Entry)->Blink = _EX_Blink; _EX_Blink->Flink = (Entry); _EX_ListHead->Blink = (Entry); } 138 #define InsertHeadList(ListHead,Entry) { PLIST_ENTRY _EX_Flink; PLIST_ENTRY _EX_ListHead; _EX_ListHead = (ListHead); _EX_Flink = _EX_ListHead->Flink; (Entry)->Flink = _EX_Flink; (Entry)->Blink = _EX_ListHead; _EX_Flink->Blink = (Entry); _EX_ListHead->Flink = (Entry); } 139 140 WINBOOL IsNodeOnList(PLIST_ENTRY ListHead,PLIST_ENTRY Entry); 141 #endif 142 143 template <class T> ULONG MSPAddRefHelper (T *pMyThis) { 144 LOG((MSP_INFO,"MSPAddRefHelper - this = 0x%08x",pMyThis)); 145 typedef CComAggObject<T> AggClass; 146 AggClass *p = CONTAINING_RECORD(pMyThis,AggClass,m_contained); 147 return p->AddRef(); 148 } 149 150 template <class T> ULONG MSPReleaseHelper (T *pMyThis) { 151 LOG((MSP_INFO,"MSPReleaseHelper - this = 0x%08x",pMyThis)); 152 typedef CComAggObject<T> AggClass; 153 AggClass *p = CONTAINING_RECORD(pMyThis,AggClass,m_contained); 154 return p->Release(); 155 } 156 157 #include <objsafe.h> 158 159 class CMSPObjectSafetyImpl : public IObjectSafety { 160 public: 161 CMSPObjectSafetyImpl() : m_dwSafety(0) { } 162 enum { 163 SUPPORTED_SAFETY_OPTIONS = INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA 164 }; 165 STDMETHOD(SetInterfaceSafetyOptions)(REFIID riid,DWORD dwOptionSetMask,DWORD dwEnabledOptions) { 166 if((~SUPPORTED_SAFETY_OPTIONS & dwOptionSetMask)!=0) return E_FAIL; 167 IUnknown *pUnk = NULL; 168 HRESULT hr = QueryInterface(riid,(void**)&pUnk); 169 if(SUCCEEDED(hr)) { 170 pUnk->Release(); 171 pUnk = NULL; 172 s_CritSection.Lock(); 173 m_dwSafety = (dwEnabledOptions & dwOptionSetMask) | (m_dwSafety & ~dwOptionSetMask); 174 s_CritSection.Unlock(); 175 } 176 return hr; 177 } 178 STDMETHOD(GetInterfaceSafetyOptions)(REFIID riid,DWORD *pdwSupportedOptions,DWORD *pdwEnabledOptions) { 179 if(IsBadWritePtr(pdwSupportedOptions,sizeof(DWORD)) || IsBadWritePtr(pdwEnabledOptions,sizeof(DWORD))) return E_POINTER; 180 *pdwSupportedOptions = 0; 181 *pdwEnabledOptions = 0; 182 IUnknown *pUnk = NULL; 183 HRESULT hr = QueryInterface(riid,(void**)&pUnk); 184 if(SUCCEEDED(hr)) { 185 pUnk->Release(); 186 pUnk = NULL; 187 *pdwSupportedOptions = SUPPORTED_SAFETY_OPTIONS; 188 s_CritSection.Lock(); 189 *pdwEnabledOptions = m_dwSafety; 190 s_CritSection.Unlock(); 191 } 192 return hr; 193 } 194 private: 195 DWORD m_dwSafety; 196 static CMSPCritSection s_CritSection; 197 }; 198 199 #endif 200