Msputils.h
上传用户:dzyhzl
上传日期:2019-04-29
资源大小:56270k
文件大小:14k
源码类别:

模拟服务器

开发平台:

C/C++

  1. /*++
  2. Copyright (c) Microsoft Corporation. All rights reserved.
  3. Module Name:
  4.     MSPutils.h
  5. Abstract:
  6.     
  7.     This file defines several utility classes used by the MSP base classes.
  8. --*/
  9. #ifndef __MSPUTILS_H_
  10. #define __MSPUTILS_H_
  11. #if _ATL_VER >= 0x0300
  12.  //
  13.  // ATL 3.0 contains an equivalent of DECLARE_VQI in its END_COM_MAP(), so 
  14.  // DECLARE_VQI() is not needed
  15.  //
  16.  
  17.  #define DECLARE_VQI()
  18. #else
  19.  #define DECLARE_VQI() 
  20.     STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject) = 0; 
  21.     STDMETHOD_(ULONG, AddRef)() = 0; 
  22.     STDMETHOD_(ULONG, Release)() = 0;
  23. #endif
  24. //
  25. // this macro expands to the appropriate MSP_x value, depending on hr.
  26. // this is useful for logging. for instance, the statements:
  27. //
  28. //      .....
  29. //
  30. //      if (FAILED(hr))
  31. //      {
  32. //          LOG((MSP_ERROR, "MyClass::MyFunc - exit. hr = 0x%lx", hr));
  33. //      }
  34. //      else
  35. //      {
  36. //          LOG((MSP_TRACE, "MyClass::MyFunc - exit. hr = 0x%lx", hr));
  37. //      }
  38. //
  39. //      return hr;
  40. //  }
  41. //
  42. //  can be replaced with:
  43. //  
  44. //      ....
  45. //
  46. //      LOG((MSP_(hr), "MyClass::MyFunc - exit. hr = 0x%lx", hr));
  47. //      
  48. //      return hr;
  49. //  }
  50. //
  51. #define MSP_(hr) (FAILED(hr)?MSP_ERROR:MSP_TRACE)
  52. //
  53. // return TRUE if the (possibly aggregated) media type that was passed in is valid.
  54. //
  55. // here is the criteria for a valid aggregated media type:
  56. //
  57. // 1. there is one or more bit set
  58. // 2. all bits that are set match the possible media types
  59. // 3. there are no set bits that don't correspond to valid meda types
  60. //
  61. inline BOOL IsValidAggregatedMediaType(DWORD dwAggregatedMediaType) 
  62. {   
  63.     //
  64.     // these are all possible media types
  65.     //
  66.     const DWORD dwAllPossibleMediaTypes =  TAPIMEDIATYPE_AUDIO | 
  67.                                         TAPIMEDIATYPE_VIDEO | 
  68.                                         TAPIMEDIATYPE_DATAMODEM | 
  69.                                         TAPIMEDIATYPE_G3FAX | 
  70.                                         TAPIMEDIATYPE_MULTITRACK;
  71.     
  72.     //
  73.     // return value
  74.     //
  75.     BOOL bValidMediaType = FALSE;
  76.     //
  77.     // make sure that there is at least one allowed media type 
  78.     //
  79.     // and
  80.     //
  81.     // there are no invalid media types
  82.     //
  83.     if (  (0 == (dwAggregatedMediaType &    dwAllPossibleMediaTypes )   )  ||      // any valid bits set
  84.           (0 != (dwAggregatedMediaType &  (~dwAllPossibleMediaTypes))   )      )   // no invalid bits are set
  85.     {
  86.         //
  87.         // the media type is invalid.
  88.         //
  89.         bValidMediaType = FALSE;
  90.     }
  91.     else
  92.     {
  93.         //
  94.         // the media type is valid.
  95.         //
  96.         bValidMediaType = TRUE;
  97.     }
  98.     return bValidMediaType;
  99. }
  100. //
  101. // Make sure we have exactly one media type. That's not the case if
  102. // dwMediaType is 0 or more than one bit is set in dwMediaType. Note
  103. // that DWORD is unsigned so this should be safe.
  104. //
  105. inline BOOL IsSingleMediaType(DWORD dwMediaType) 
  106. {   
  107.     return !((dwMediaType == 0) || ((dwMediaType & (dwMediaType - 1)) != 0));
  108. }
  109. //
  110. // Check to see if the mediatype is a single type and is in the mask.
  111. //
  112. inline BOOL IsValidSingleMediaType(DWORD dwMediaType, DWORD dwMask)
  113. {
  114.     return IsSingleMediaType(dwMediaType)
  115.         && ((dwMediaType & dwMask) == dwMediaType);
  116. }
  117. /*++
  118. CMSPArray template Description:
  119.     Definitions for a simple vector template. The implementaion is borrowed
  120.     from CMSPArray in atlapp.h. Modified only the allocation behavior.
  121.     This array should only be used to store simple types. It doesn't call the
  122.     constructor nor the destructor for each element in the array.
  123. --*/
  124. const DWORD INITIAL = 8;
  125. const DWORD DELTA   = 8;
  126. template <class T, DWORD dwInitial = INITIAL, DWORD dwDelta = DELTA>
  127. class CMSPArray
  128. {
  129. protected:
  130.     T* m_aT;
  131.     int m_nSize;
  132.     int m_nAllocSize;
  133. public:
  134. // Construction/destruction
  135.     CMSPArray() : m_aT(NULL), m_nSize(0), m_nAllocSize(0)
  136.     { }
  137.     ~CMSPArray()
  138.     {
  139.         RemoveAll();
  140.     }
  141. // Operations
  142.     int GetSize() const
  143.     {
  144.         return m_nSize;
  145.     }
  146.     BOOL Grow()
  147.     {
  148.         T* aT;
  149.         int nNewAllocSize = 
  150.             (m_nAllocSize == 0) ? dwInitial : (m_nSize + DELTA);
  151.         aT = (T*)realloc(m_aT, nNewAllocSize * sizeof(T));
  152.         if(aT == NULL)
  153.             return FALSE;
  154.         m_nAllocSize = nNewAllocSize;
  155.         m_aT = aT;
  156.         return TRUE;
  157.     }
  158.     BOOL Add(T& t)
  159.     {
  160.         if(m_nSize == m_nAllocSize)
  161.         {
  162.             if (!Grow()) return FALSE;
  163.         }
  164.         m_nSize++;
  165.         SetAtIndex(m_nSize - 1, t);
  166.         return TRUE;
  167.     }
  168.     BOOL Remove(T& t)
  169.     {
  170.         int nIndex = Find(t);
  171.         if(nIndex == -1)
  172.             return FALSE;
  173.         return RemoveAt(nIndex);
  174.     }
  175.     BOOL RemoveAt(int nIndex)
  176.     {
  177.         if(nIndex != (m_nSize - 1))
  178.             memmove((void*)&m_aT[nIndex], (void*)&m_aT[nIndex + 1], 
  179.                 (m_nSize - (nIndex + 1)) * sizeof(T));
  180.         m_nSize--;
  181.         return TRUE;
  182.     }
  183.     void RemoveAll()
  184.     {
  185.         if(m_nAllocSize > 0)
  186.         {
  187.             free(m_aT);
  188.             m_aT = NULL;
  189.             m_nSize = 0;
  190.             m_nAllocSize = 0;
  191.         }
  192.     }
  193.     T& operator[] (int nIndex) const
  194.     {
  195.         _ASSERTE(nIndex >= 0 && nIndex < m_nSize);
  196.         return m_aT[nIndex];
  197.     }
  198.     T* GetData() const
  199.     {
  200.         return m_aT;
  201.     }
  202. // Implementation
  203.     void SetAtIndex(int nIndex, T& t)
  204.     {
  205.         _ASSERTE(nIndex >= 0 && nIndex < m_nSize);
  206.         m_aT[nIndex] = t;
  207.     }
  208.     int Find(T& t) const
  209.     {
  210.         for(int i = 0; i < m_nSize; i++)
  211.         {
  212.             if(m_aT[i] == t)
  213.                 return i;
  214.         }
  215.         return -1;  // not found
  216.     }
  217. };
  218. /*++
  219. CMSPCritSection Description:
  220.     Definitions for a auto initialize critical section.
  221. --*/
  222. class CMSPCritSection
  223. {
  224. private:
  225.     CRITICAL_SECTION m_CritSec;
  226. public:
  227.     CMSPCritSection()
  228.     {
  229.         InitializeCriticalSection(&m_CritSec);
  230.     }
  231.     ~CMSPCritSection()
  232.     {
  233.         DeleteCriticalSection(&m_CritSec);
  234.     }
  235.     void Lock() 
  236.     {
  237.         EnterCriticalSection(&m_CritSec);
  238.     }
  239.     BOOL TryLock() 
  240.     {
  241.         return TryEnterCriticalSection(&m_CritSec);
  242.     }
  243.     void Unlock() 
  244.     {
  245.         LeaveCriticalSection(&m_CritSec);
  246.     }
  247. };
  248. /*++
  249. CMSPCritSection Description:
  250.     Definitions for a auto lock that unlocks when the variable is out
  251.     of scope.
  252. --*/
  253. class CLock
  254. {
  255. private:
  256.     CMSPCritSection &m_CriticalSection;
  257. public:
  258.     CLock(CMSPCritSection &CriticalSection)
  259.         : m_CriticalSection(CriticalSection)
  260.     {
  261.         m_CriticalSection.Lock();
  262.     }
  263.     ~CLock()
  264.     {
  265.         m_CriticalSection.Unlock();
  266.     }
  267. };
  268. ///////////////////////////////////////////////////////////////////////////////
  269. //
  270. // CCSLock
  271. //
  272. // a plain old automatic lock that takes a pointer to CRITICAL_SECTION
  273. //
  274. // constructore enters crit section, destructor leaves critical section
  275. //
  276. // class client is responsible for passing a valid critical section
  277. //
  278. class CCSLock
  279. {
  280. private:
  281.     CRITICAL_SECTION *m_pCritSec;
  282. public:
  283.     CCSLock(CRITICAL_SECTION *pCritSec)
  284.         : m_pCritSec(pCritSec)
  285.     {
  286.         EnterCriticalSection(m_pCritSec);
  287.     }
  288.     ~CCSLock()
  289.     {
  290.         LeaveCriticalSection(m_pCritSec);
  291.     }
  292. };
  293. /*++
  294. LINK list:
  295.     Definitions for a double link list.
  296. --*/
  297. //
  298. // Calculate the address of the base of the structure given its type, and an
  299. // address of a field within the structure.
  300. //
  301. #ifndef CONTAINING_RECORD
  302. #define CONTAINING_RECORD(address, type, field) 
  303.     ((type *)((PCHAR)(address) - (ULONG_PTR)(&((type *)0)->field)))
  304. #endif
  305. #ifndef InitializeListHead
  306. //
  307. //  VOID
  308. //  InitializeListHead(
  309. //      PLIST_ENTRY ListHead
  310. //      );
  311. //
  312. #define InitializeListHead(ListHead) (
  313.     (ListHead)->Flink = (ListHead)->Blink = (ListHead))
  314. //
  315. //  BOOLEAN
  316. //  IsListEmpty(
  317. //      PLIST_ENTRY ListHead
  318. //      );
  319. //
  320. #define IsListEmpty(ListHead) 
  321.     ((ListHead)->Flink == (ListHead))
  322. //
  323. //  PLIST_ENTRY
  324. //  RemoveHeadList(
  325. //      PLIST_ENTRY ListHead
  326. //      );
  327. //
  328. #define RemoveHeadList(ListHead) 
  329.     (ListHead)->Flink;
  330.     {RemoveEntryList((ListHead)->Flink)}
  331. //
  332. //  PLIST_ENTRY
  333. //  RemoveTailList(
  334. //      PLIST_ENTRY ListHead
  335. //      );
  336. //
  337. #define RemoveTailList(ListHead) 
  338.     (ListHead)->Blink;
  339.     {RemoveEntryList((ListHead)->Blink)}
  340. //
  341. //  VOID
  342. //  RemoveEntryList(
  343. //      PLIST_ENTRY Entry
  344. //      );
  345. //
  346. #define RemoveEntryList(Entry) {
  347.     PLIST_ENTRY _EX_Blink;
  348.     PLIST_ENTRY _EX_Flink;
  349.     _EX_Flink = (Entry)->Flink;
  350.     _EX_Blink = (Entry)->Blink;
  351.     _EX_Blink->Flink = _EX_Flink;
  352.     _EX_Flink->Blink = _EX_Blink;
  353.     }
  354. //
  355. //  VOID
  356. //  InsertTailList(
  357. //      PLIST_ENTRY ListHead,
  358. //      PLIST_ENTRY Entry
  359. //      );
  360. //
  361. #define InsertTailList(ListHead,Entry) {
  362.     PLIST_ENTRY _EX_Blink;
  363.     PLIST_ENTRY _EX_ListHead;
  364.     _EX_ListHead = (ListHead);
  365.     _EX_Blink = _EX_ListHead->Blink;
  366.     (Entry)->Flink = _EX_ListHead;
  367.     (Entry)->Blink = _EX_Blink;
  368.     _EX_Blink->Flink = (Entry);
  369.     _EX_ListHead->Blink = (Entry);
  370.     }
  371. //
  372. //  VOID
  373. //  InsertHeadList(
  374. //      PLIST_ENTRY ListHead,
  375. //      PLIST_ENTRY Entry
  376. //      );
  377. //
  378. #define InsertHeadList(ListHead,Entry) {
  379.     PLIST_ENTRY _EX_Flink;
  380.     PLIST_ENTRY _EX_ListHead;
  381.     _EX_ListHead = (ListHead);
  382.     _EX_Flink = _EX_ListHead->Flink;
  383.     (Entry)->Flink = _EX_Flink;
  384.     (Entry)->Blink = _EX_ListHead;
  385.     _EX_Flink->Blink = (Entry);
  386.     _EX_ListHead->Flink = (Entry);
  387.     }
  388. BOOL IsNodeOnList(PLIST_ENTRY ListHead, PLIST_ENTRY Entry);
  389. #endif //InitializeListHead
  390. //
  391. // Templates for private addref and release. See Platform SDK documentation.
  392. //
  393. template <class T> ULONG MSPAddRefHelper (T * pMyThis)
  394. {
  395.     LOG((MSP_INFO, "MSPAddRefHelper - this = 0x%08x", pMyThis));
  396.     typedef CComAggObject<T> AggClass;
  397.     AggClass * p = CONTAINING_RECORD(pMyThis, AggClass, m_contained);
  398.     return p->AddRef();
  399. }
  400. template <class T> ULONG MSPReleaseHelper (T * pMyThis)
  401. {
  402.     LOG((MSP_INFO, "MSPReleaseHelper - this = 0x%08x", pMyThis));
  403.     typedef CComAggObject<T> AggClass;
  404.     AggClass * p = CONTAINING_RECORD(pMyThis, AggClass, m_contained);
  405.     return p->Release();
  406. }
  407. //
  408. //  Basic implementation for IObjectSafety.
  409. //
  410. //  Derive from this class to make your object safe for scripting on all its
  411. //  interfaces
  412. //
  413. #include <Objsafe.h>
  414. class CMSPObjectSafetyImpl : public IObjectSafety
  415. {
  416. public:
  417.     
  418.     CMSPObjectSafetyImpl()
  419.         :m_dwSafety(0)
  420.     {}
  421.     //
  422.     // we support the following safety options:
  423.     //
  424.     enum { SUPPORTED_SAFETY_OPTIONS = 
  425.        INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA };
  426.     STDMETHOD(SetInterfaceSafetyOptions)(REFIID riid, DWORD dwOptionSetMask, DWORD dwEnabledOptions)
  427.     {
  428.         //
  429.         // any options requested that we do not support?
  430.         //
  431.         
  432.         if ( (~SUPPORTED_SAFETY_OPTIONS & dwOptionSetMask) != 0 )
  433.         {
  434.             return E_FAIL;
  435.         }
  436.         
  437.         //
  438.         // see if the interface is supported at all
  439.         //
  440.         IUnknown *pUnk = NULL;
  441.         HRESULT hr = QueryInterface(riid, (void**)&pUnk);
  442.         if (SUCCEEDED(hr))
  443.         {
  444.             //
  445.             // we don't need the interface, just wanted to see if it 
  446.             // was supported. so release.
  447.             //
  448.             
  449.             pUnk->Release();
  450.             pUnk = NULL;
  451.             //
  452.             // the object supports the interface. Set options
  453.             // 
  454.             s_CritSection.Lock();
  455.             //
  456.             // set the bits specified by the mask to the values specified by 
  457.             // dwEnabledOptions
  458.             //
  459.             m_dwSafety = (dwEnabledOptions & dwOptionSetMask) |
  460.                          (m_dwSafety & ~dwOptionSetMask);
  461.             s_CritSection.Unlock();
  462.         }
  463.         return hr;
  464.     }
  465.     
  466.     STDMETHOD(GetInterfaceSafetyOptions)(REFIID riid, DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
  467.     {
  468.         
  469.         //
  470.         // check caller's pointers
  471.         //
  472.         if ( IsBadWritePtr(pdwSupportedOptions, sizeof(DWORD)) ||
  473.              IsBadWritePtr(pdwEnabledOptions, sizeof(DWORD)) )
  474.         {
  475.              return E_POINTER;
  476.         }
  477.         //
  478.         //  if we fail, return something meaningful
  479.         //
  480.         *pdwSupportedOptions = 0;
  481.         *pdwEnabledOptions = 0;
  482.         //
  483.         // see if the interface is supported at all
  484.         //
  485.         IUnknown *pUnk = NULL;
  486.         HRESULT hr = QueryInterface(riid, (void**)&pUnk);
  487.         if (SUCCEEDED(hr))
  488.         {
  489.             //
  490.             // we don't need the interface, just wanted to see if it 
  491.             // was supported. so release.
  492.             //
  493.             
  494.             pUnk->Release();
  495.             pUnk = NULL;
  496.             //
  497.             // the object supports the interface. get safe scripting options
  498.             // 
  499.             *pdwSupportedOptions = SUPPORTED_SAFETY_OPTIONS;
  500.  
  501.             s_CritSection.Lock();
  502.             *pdwEnabledOptions = m_dwSafety;
  503.             s_CritSection.Unlock();
  504.         }
  505.         return hr;
  506.     }
  507. private:
  508.     DWORD m_dwSafety;
  509.     // 
  510.     // thread safety
  511.     //
  512.     // the critical section is shared among all instances of this class
  513.     //
  514.     static CMSPCritSection s_CritSection;
  515.     
  516. };
  517. #endif  //__MSPUTILS_H_
  518. // eof