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

模拟服务器

开发平台:

C/C++

  1. /*
  2.     Copyright (c) Microsoft Corporation. All rights reserved.
  3. */
  4. #ifndef _MSPENUM_H_
  5. #define _MSPENUM_H_
  6. //////////////////////////////////////////////////////////////////////////////
  7. //
  8. // CSafeComEnum
  9. //
  10. // All TAPI 3.0 system components and MSPs use the CSafeComEnum class instead
  11. // of ATL 2.1's CComEnum class when implementing enumerator objects that are
  12. // accessible to applications. This is needed for the following reasons:
  13. //
  14. // 1. CComEnum does not perform IsBadWritePtr checks on the pointer arguments
  15. //    to the enumerator methods. This allows the component exposing the
  16. //    enumerator to AV when called with invalid pointer arguments.
  17. //
  18. // 2. CComEnum does not support free thread marshaling, and therefore cannot
  19. //    be used from an apartment threaded application.
  20. //
  21. // Note: No debug tracing is done here, to facilitate use of this template
  22. // independent of the rest of the MSP Base Classes.
  23. //
  24. /////////////////////////////////////////////////////////////////////////////
  25. template <class Base, const IID* piid, class T, class Copy,
  26.           class ThreadModel = CComObjectThreadModel>
  27. class ATL_NO_VTABLE CSafeComEnum :
  28.         public CComEnumImpl<Base, piid, T, Copy>,
  29.         public CComObjectRootEx< ThreadModel >
  30. {
  31.     typedef CSafeComEnum<Base, piid, T, Copy, ThreadModel> ThisClass;
  32.     typedef CComEnumImpl<Base, piid, T, Copy>              BaseClass;
  33.     STDMETHOD(Next)(ULONG celt, T* rgelt, ULONG* pceltFetched)
  34.     {
  35.         //
  36.         // Check if the return array is valid for as many elements as
  37.         // specified. No need to explicitly check if celt is zero here, as
  38.         // IsBadWritePtr(p, 0) is valid and returns 0.
  39.         // celt itself will be checked in the base class method.
  40.         //
  41.         if ( IsBadWritePtr(rgelt, celt * sizeof(T) ) )
  42.         {
  43.             return E_POINTER;
  44.         }
  45.         //
  46.         // Check if the return dword is bad, but if pceltFetched == NULL,
  47.         // this may still be a valid call. pceltFetched == NULL implies that
  48.         // celt should be equal to 1, but that will be checked in the
  49.         // base class method.
  50.         //
  51.         if ( ( pceltFetched != NULL ) &&
  52.              IsBadWritePtr(pceltFetched, sizeof(ULONG) ) )
  53.         {
  54.             return E_POINTER;
  55.         }
  56.         //
  57.         // Everything OK so far; proceed with base class method.
  58.         //
  59.         return BaseClass::Next(celt, rgelt, pceltFetched);
  60.     }
  61.     STDMETHOD(Clone)(Base** ppEnum)
  62.     {
  63.         //
  64.         // Check if the return pointer is valid.
  65.         //
  66.         if ( IsBadWritePtr(ppEnum, sizeof(Base *) ) )
  67.         {
  68.             return E_POINTER;
  69.         }
  70.         //
  71.         // Everything OK so far; proceed with base class method.
  72.         //
  73.         return BaseClass::Clone(ppEnum);
  74.     }
  75.     //
  76.     // We do not override Skip or Reset as they have no pointer arguments.
  77.     //
  78.     //
  79.     // The rest of this class involves support for free thread marshaling.
  80.     //
  81.     BEGIN_COM_MAP( ThisClass )
  82. COM_INTERFACE_ENTRY_IID( *piid, BaseClass )
  83.         COM_INTERFACE_ENTRY_AGGREGATE( IID_IMarshal, m_pFTM )
  84.     END_COM_MAP()
  85.     DECLARE_GET_CONTROLLING_UNKNOWN()
  86.     HRESULT Init(T* begin, T* end, IUnknown* pUnk,
  87.             CComEnumFlags flags = AtlFlagNoCopy)
  88.     {
  89.         //
  90.         // We do not check the pointer arguments in this method because this
  91.         // method is not exposed to the application (it is not a COM interface
  92.         // method).
  93.         //
  94.         
  95.         HRESULT hr;
  96.         IUnknown * pIU = GetControllingUnknown();
  97.         hr = CoCreateFreeThreadedMarshaler( pIU, 
  98.                                             & m_pFTM );
  99.         if ( FAILED(hr) )
  100.         {
  101.             return hr;
  102.         }
  103.         return BaseClass::Init(begin, end, pUnk, flags);
  104.     }
  105.     CSafeComEnum()
  106.     {
  107.         m_pFTM = NULL;
  108.     }
  109.     void FinalRelease(void)
  110.     {
  111.         if ( m_pFTM )
  112.         {
  113.             m_pFTM->Release();
  114.         }
  115.         CComObjectRootEx< ThreadModel >::FinalRelease();
  116.     }
  117. protected:
  118.     IUnknown * m_pFTM; // pointer to free thread marshaler
  119. };
  120. #endif // _MSPENUM_H_