MspEnum.h
上传用户:dzyhzl
上传日期:2019-04-29
资源大小:56270k
文件大小:4k
- /*
- Copyright (c) Microsoft Corporation. All rights reserved.
- */
- #ifndef _MSPENUM_H_
- #define _MSPENUM_H_
- //////////////////////////////////////////////////////////////////////////////
- //
- // CSafeComEnum
- //
- // All TAPI 3.0 system components and MSPs use the CSafeComEnum class instead
- // of ATL 2.1's CComEnum class when implementing enumerator objects that are
- // accessible to applications. This is needed for the following reasons:
- //
- // 1. CComEnum does not perform IsBadWritePtr checks on the pointer arguments
- // to the enumerator methods. This allows the component exposing the
- // enumerator to AV when called with invalid pointer arguments.
- //
- // 2. CComEnum does not support free thread marshaling, and therefore cannot
- // be used from an apartment threaded application.
- //
- // Note: No debug tracing is done here, to facilitate use of this template
- // independent of the rest of the MSP Base Classes.
- //
- /////////////////////////////////////////////////////////////////////////////
- template <class Base, const IID* piid, class T, class Copy,
- class ThreadModel = CComObjectThreadModel>
- class ATL_NO_VTABLE CSafeComEnum :
- public CComEnumImpl<Base, piid, T, Copy>,
- public CComObjectRootEx< ThreadModel >
- {
- typedef CSafeComEnum<Base, piid, T, Copy, ThreadModel> ThisClass;
- typedef CComEnumImpl<Base, piid, T, Copy> BaseClass;
- STDMETHOD(Next)(ULONG celt, T* rgelt, ULONG* pceltFetched)
- {
- //
- // Check if the return array is valid for as many elements as
- // specified. No need to explicitly check if celt is zero here, as
- // IsBadWritePtr(p, 0) is valid and returns 0.
- // celt itself will be checked in the base class method.
- //
- if ( IsBadWritePtr(rgelt, celt * sizeof(T) ) )
- {
- return E_POINTER;
- }
- //
- // Check if the return dword is bad, but if pceltFetched == NULL,
- // this may still be a valid call. pceltFetched == NULL implies that
- // celt should be equal to 1, but that will be checked in the
- // base class method.
- //
- if ( ( pceltFetched != NULL ) &&
- IsBadWritePtr(pceltFetched, sizeof(ULONG) ) )
- {
- return E_POINTER;
- }
- //
- // Everything OK so far; proceed with base class method.
- //
- return BaseClass::Next(celt, rgelt, pceltFetched);
- }
- STDMETHOD(Clone)(Base** ppEnum)
- {
- //
- // Check if the return pointer is valid.
- //
- if ( IsBadWritePtr(ppEnum, sizeof(Base *) ) )
- {
- return E_POINTER;
- }
- //
- // Everything OK so far; proceed with base class method.
- //
- return BaseClass::Clone(ppEnum);
- }
- //
- // We do not override Skip or Reset as they have no pointer arguments.
- //
- //
- // The rest of this class involves support for free thread marshaling.
- //
- BEGIN_COM_MAP( ThisClass )
- COM_INTERFACE_ENTRY_IID( *piid, BaseClass )
- COM_INTERFACE_ENTRY_AGGREGATE( IID_IMarshal, m_pFTM )
- END_COM_MAP()
- DECLARE_GET_CONTROLLING_UNKNOWN()
- HRESULT Init(T* begin, T* end, IUnknown* pUnk,
- CComEnumFlags flags = AtlFlagNoCopy)
- {
- //
- // We do not check the pointer arguments in this method because this
- // method is not exposed to the application (it is not a COM interface
- // method).
- //
-
- HRESULT hr;
- IUnknown * pIU = GetControllingUnknown();
- hr = CoCreateFreeThreadedMarshaler( pIU,
- & m_pFTM );
- if ( FAILED(hr) )
- {
- return hr;
- }
- return BaseClass::Init(begin, end, pUnk, flags);
- }
- CSafeComEnum()
- {
- m_pFTM = NULL;
- }
- void FinalRelease(void)
- {
- if ( m_pFTM )
- {
- m_pFTM->Release();
- }
- CComObjectRootEx< ThreadModel >::FinalRelease();
- }
- protected:
- IUnknown * m_pFTM; // pointer to free thread marshaler
- };
- #endif // _MSPENUM_H_