Msputils.h
上传用户:dzyhzl
上传日期:2019-04-29
资源大小:56270k
文件大小:14k
- /*++
- Copyright (c) Microsoft Corporation. All rights reserved.
- Module Name:
- MSPutils.h
- Abstract:
-
- This file defines several utility classes used by the MSP base classes.
- --*/
- #ifndef __MSPUTILS_H_
- #define __MSPUTILS_H_
- #if _ATL_VER >= 0x0300
- //
- // ATL 3.0 contains an equivalent of DECLARE_VQI in its END_COM_MAP(), so
- // DECLARE_VQI() is not needed
- //
-
- #define DECLARE_VQI()
- #else
- #define DECLARE_VQI()
- STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject) = 0;
- STDMETHOD_(ULONG, AddRef)() = 0;
- STDMETHOD_(ULONG, Release)() = 0;
- #endif
- //
- // this macro expands to the appropriate MSP_x value, depending on hr.
- // this is useful for logging. for instance, the statements:
- //
- // .....
- //
- // if (FAILED(hr))
- // {
- // LOG((MSP_ERROR, "MyClass::MyFunc - exit. hr = 0x%lx", hr));
- // }
- // else
- // {
- // LOG((MSP_TRACE, "MyClass::MyFunc - exit. hr = 0x%lx", hr));
- // }
- //
- // return hr;
- // }
- //
- // can be replaced with:
- //
- // ....
- //
- // LOG((MSP_(hr), "MyClass::MyFunc - exit. hr = 0x%lx", hr));
- //
- // return hr;
- // }
- //
- #define MSP_(hr) (FAILED(hr)?MSP_ERROR:MSP_TRACE)
- //
- // return TRUE if the (possibly aggregated) media type that was passed in is valid.
- //
- // here is the criteria for a valid aggregated media type:
- //
- // 1. there is one or more bit set
- // 2. all bits that are set match the possible media types
- // 3. there are no set bits that don't correspond to valid meda types
- //
- inline BOOL IsValidAggregatedMediaType(DWORD dwAggregatedMediaType)
- {
- //
- // these are all possible media types
- //
- const DWORD dwAllPossibleMediaTypes = TAPIMEDIATYPE_AUDIO |
- TAPIMEDIATYPE_VIDEO |
- TAPIMEDIATYPE_DATAMODEM |
- TAPIMEDIATYPE_G3FAX |
- TAPIMEDIATYPE_MULTITRACK;
-
- //
- // return value
- //
- BOOL bValidMediaType = FALSE;
- //
- // make sure that there is at least one allowed media type
- //
- // and
- //
- // there are no invalid media types
- //
- if ( (0 == (dwAggregatedMediaType & dwAllPossibleMediaTypes ) ) || // any valid bits set
- (0 != (dwAggregatedMediaType & (~dwAllPossibleMediaTypes)) ) ) // no invalid bits are set
- {
- //
- // the media type is invalid.
- //
- bValidMediaType = FALSE;
- }
- else
- {
- //
- // the media type is valid.
- //
- bValidMediaType = TRUE;
- }
- return bValidMediaType;
- }
- //
- // Make sure we have exactly one media type. That's not the case if
- // dwMediaType is 0 or more than one bit is set in dwMediaType. Note
- // that DWORD is unsigned so this should be safe.
- //
- inline BOOL IsSingleMediaType(DWORD dwMediaType)
- {
- return !((dwMediaType == 0) || ((dwMediaType & (dwMediaType - 1)) != 0));
- }
- //
- // Check to see if the mediatype is a single type and is in the mask.
- //
- inline BOOL IsValidSingleMediaType(DWORD dwMediaType, DWORD dwMask)
- {
- return IsSingleMediaType(dwMediaType)
- && ((dwMediaType & dwMask) == dwMediaType);
- }
- /*++
- CMSPArray template Description:
- Definitions for a simple vector template. The implementaion is borrowed
- from CMSPArray in atlapp.h. Modified only the allocation behavior.
- This array should only be used to store simple types. It doesn't call the
- constructor nor the destructor for each element in the array.
- --*/
- const DWORD INITIAL = 8;
- const DWORD DELTA = 8;
- template <class T, DWORD dwInitial = INITIAL, DWORD dwDelta = DELTA>
- class CMSPArray
- {
- protected:
- T* m_aT;
- int m_nSize;
- int m_nAllocSize;
- public:
- // Construction/destruction
- CMSPArray() : m_aT(NULL), m_nSize(0), m_nAllocSize(0)
- { }
- ~CMSPArray()
- {
- RemoveAll();
- }
- // Operations
- int GetSize() const
- {
- return m_nSize;
- }
- BOOL Grow()
- {
- T* aT;
- int nNewAllocSize =
- (m_nAllocSize == 0) ? dwInitial : (m_nSize + DELTA);
- aT = (T*)realloc(m_aT, nNewAllocSize * sizeof(T));
- if(aT == NULL)
- return FALSE;
- m_nAllocSize = nNewAllocSize;
- m_aT = aT;
- return TRUE;
- }
- BOOL Add(T& t)
- {
- if(m_nSize == m_nAllocSize)
- {
- if (!Grow()) return FALSE;
- }
- m_nSize++;
- SetAtIndex(m_nSize - 1, t);
- return TRUE;
- }
- BOOL Remove(T& t)
- {
- int nIndex = Find(t);
- if(nIndex == -1)
- return FALSE;
- return RemoveAt(nIndex);
- }
- BOOL RemoveAt(int nIndex)
- {
- if(nIndex != (m_nSize - 1))
- memmove((void*)&m_aT[nIndex], (void*)&m_aT[nIndex + 1],
- (m_nSize - (nIndex + 1)) * sizeof(T));
- m_nSize--;
- return TRUE;
- }
- void RemoveAll()
- {
- if(m_nAllocSize > 0)
- {
- free(m_aT);
- m_aT = NULL;
- m_nSize = 0;
- m_nAllocSize = 0;
- }
- }
- T& operator[] (int nIndex) const
- {
- _ASSERTE(nIndex >= 0 && nIndex < m_nSize);
- return m_aT[nIndex];
- }
- T* GetData() const
- {
- return m_aT;
- }
- // Implementation
- void SetAtIndex(int nIndex, T& t)
- {
- _ASSERTE(nIndex >= 0 && nIndex < m_nSize);
- m_aT[nIndex] = t;
- }
- int Find(T& t) const
- {
- for(int i = 0; i < m_nSize; i++)
- {
- if(m_aT[i] == t)
- return i;
- }
- return -1; // not found
- }
- };
- /*++
- CMSPCritSection Description:
- Definitions for a auto initialize critical section.
- --*/
- class CMSPCritSection
- {
- private:
- CRITICAL_SECTION m_CritSec;
- public:
- CMSPCritSection()
- {
- InitializeCriticalSection(&m_CritSec);
- }
- ~CMSPCritSection()
- {
- DeleteCriticalSection(&m_CritSec);
- }
- void Lock()
- {
- EnterCriticalSection(&m_CritSec);
- }
- BOOL TryLock()
- {
- return TryEnterCriticalSection(&m_CritSec);
- }
- void Unlock()
- {
- LeaveCriticalSection(&m_CritSec);
- }
- };
- /*++
- CMSPCritSection Description:
- Definitions for a auto lock that unlocks when the variable is out
- of scope.
- --*/
- class CLock
- {
- private:
- CMSPCritSection &m_CriticalSection;
- public:
- CLock(CMSPCritSection &CriticalSection)
- : m_CriticalSection(CriticalSection)
- {
- m_CriticalSection.Lock();
- }
- ~CLock()
- {
- m_CriticalSection.Unlock();
- }
- };
- ///////////////////////////////////////////////////////////////////////////////
- //
- // CCSLock
- //
- // a plain old automatic lock that takes a pointer to CRITICAL_SECTION
- //
- // constructore enters crit section, destructor leaves critical section
- //
- // class client is responsible for passing a valid critical section
- //
- class CCSLock
- {
- private:
- CRITICAL_SECTION *m_pCritSec;
- public:
- CCSLock(CRITICAL_SECTION *pCritSec)
- : m_pCritSec(pCritSec)
- {
- EnterCriticalSection(m_pCritSec);
- }
- ~CCSLock()
- {
- LeaveCriticalSection(m_pCritSec);
- }
- };
- /*++
- LINK list:
- Definitions for a double link list.
- --*/
- //
- // Calculate the address of the base of the structure given its type, and an
- // address of a field within the structure.
- //
- #ifndef CONTAINING_RECORD
- #define CONTAINING_RECORD(address, type, field)
- ((type *)((PCHAR)(address) - (ULONG_PTR)(&((type *)0)->field)))
- #endif
- #ifndef InitializeListHead
- //
- // VOID
- // InitializeListHead(
- // PLIST_ENTRY ListHead
- // );
- //
- #define InitializeListHead(ListHead) (
- (ListHead)->Flink = (ListHead)->Blink = (ListHead))
- //
- // BOOLEAN
- // IsListEmpty(
- // PLIST_ENTRY ListHead
- // );
- //
- #define IsListEmpty(ListHead)
- ((ListHead)->Flink == (ListHead))
- //
- // PLIST_ENTRY
- // RemoveHeadList(
- // PLIST_ENTRY ListHead
- // );
- //
- #define RemoveHeadList(ListHead)
- (ListHead)->Flink;
- {RemoveEntryList((ListHead)->Flink)}
- //
- // PLIST_ENTRY
- // RemoveTailList(
- // PLIST_ENTRY ListHead
- // );
- //
- #define RemoveTailList(ListHead)
- (ListHead)->Blink;
- {RemoveEntryList((ListHead)->Blink)}
- //
- // VOID
- // RemoveEntryList(
- // PLIST_ENTRY Entry
- // );
- //
- #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;
- }
- //
- // VOID
- // InsertTailList(
- // PLIST_ENTRY ListHead,
- // PLIST_ENTRY Entry
- // );
- //
- #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);
- }
- //
- // VOID
- // InsertHeadList(
- // PLIST_ENTRY ListHead,
- // PLIST_ENTRY Entry
- // );
- //
- #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);
- }
- BOOL IsNodeOnList(PLIST_ENTRY ListHead, PLIST_ENTRY Entry);
- #endif //InitializeListHead
- //
- // Templates for private addref and release. See Platform SDK documentation.
- //
- template <class T> ULONG MSPAddRefHelper (T * pMyThis)
- {
- LOG((MSP_INFO, "MSPAddRefHelper - this = 0x%08x", pMyThis));
- typedef CComAggObject<T> AggClass;
- AggClass * p = CONTAINING_RECORD(pMyThis, AggClass, m_contained);
- return p->AddRef();
- }
- template <class T> ULONG MSPReleaseHelper (T * pMyThis)
- {
- LOG((MSP_INFO, "MSPReleaseHelper - this = 0x%08x", pMyThis));
- typedef CComAggObject<T> AggClass;
- AggClass * p = CONTAINING_RECORD(pMyThis, AggClass, m_contained);
- return p->Release();
- }
- //
- // Basic implementation for IObjectSafety.
- //
- // Derive from this class to make your object safe for scripting on all its
- // interfaces
- //
- #include <Objsafe.h>
- class CMSPObjectSafetyImpl : public IObjectSafety
- {
- public:
-
- CMSPObjectSafetyImpl()
- :m_dwSafety(0)
- {}
- //
- // we support the following safety options:
- //
- enum { SUPPORTED_SAFETY_OPTIONS =
- INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA };
- STDMETHOD(SetInterfaceSafetyOptions)(REFIID riid, DWORD dwOptionSetMask, DWORD dwEnabledOptions)
- {
- //
- // any options requested that we do not support?
- //
-
- if ( (~SUPPORTED_SAFETY_OPTIONS & dwOptionSetMask) != 0 )
- {
- return E_FAIL;
- }
-
- //
- // see if the interface is supported at all
- //
- IUnknown *pUnk = NULL;
- HRESULT hr = QueryInterface(riid, (void**)&pUnk);
- if (SUCCEEDED(hr))
- {
- //
- // we don't need the interface, just wanted to see if it
- // was supported. so release.
- //
-
- pUnk->Release();
- pUnk = NULL;
- //
- // the object supports the interface. Set options
- //
- s_CritSection.Lock();
- //
- // set the bits specified by the mask to the values specified by
- // dwEnabledOptions
- //
- m_dwSafety = (dwEnabledOptions & dwOptionSetMask) |
- (m_dwSafety & ~dwOptionSetMask);
- s_CritSection.Unlock();
- }
- return hr;
- }
-
- STDMETHOD(GetInterfaceSafetyOptions)(REFIID riid, DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
- {
-
- //
- // check caller's pointers
- //
- if ( IsBadWritePtr(pdwSupportedOptions, sizeof(DWORD)) ||
- IsBadWritePtr(pdwEnabledOptions, sizeof(DWORD)) )
- {
- return E_POINTER;
- }
- //
- // if we fail, return something meaningful
- //
- *pdwSupportedOptions = 0;
- *pdwEnabledOptions = 0;
- //
- // see if the interface is supported at all
- //
- IUnknown *pUnk = NULL;
- HRESULT hr = QueryInterface(riid, (void**)&pUnk);
- if (SUCCEEDED(hr))
- {
- //
- // we don't need the interface, just wanted to see if it
- // was supported. so release.
- //
-
- pUnk->Release();
- pUnk = NULL;
- //
- // the object supports the interface. get safe scripting options
- //
- *pdwSupportedOptions = SUPPORTED_SAFETY_OPTIONS;
-
- s_CritSection.Lock();
- *pdwEnabledOptions = m_dwSafety;
- s_CritSection.Unlock();
- }
- return hr;
- }
- private:
- DWORD m_dwSafety;
- //
- // thread safety
- //
- // the critical section is shared among all instances of this class
- //
- static CMSPCritSection s_CritSection;
-
- };
- #endif //__MSPUTILS_H_
- // eof