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 _MSPENUM_H_ 7#define _MSPENUM_H_ 8 9#ifdef __cplusplus 10 11template <class Base,const IID *piid,class T,class Copy,class ThreadModel = CComObjectThreadModel> 12class ATL_NO_VTABLE CSafeComEnum : public CComEnumImpl<Base,piid,T,Copy>,public CComObjectRootEx< ThreadModel > 13{ 14 typedef CSafeComEnum<Base,piid,T,Copy,ThreadModel> ThisClass; 15 typedef CComEnumImpl<Base,piid,T,Copy> BaseClass; 16 STDMETHOD(Next)(ULONG celt,T *rgelt,ULONG *pceltFetched) { 17 if(IsBadWritePtr(rgelt,celt *sizeof(T))) return E_POINTER; 18 if((pceltFetched!=NULL) && IsBadWritePtr(pceltFetched,sizeof(ULONG))) return E_POINTER; 19 return BaseClass::Next(celt,rgelt,pceltFetched); 20 } 21 STDMETHOD(Clone)(Base **ppEnum) { 22 if(IsBadWritePtr(ppEnum,sizeof(Base *))) return E_POINTER; 23 return BaseClass::Clone(ppEnum); 24 } 25 BEGIN_COM_MAP(ThisClass) 26 COM_INTERFACE_ENTRY_IID(*piid,BaseClass) 27 COM_INTERFACE_ENTRY_AGGREGATE(IID_IMarshal,m_pFTM) 28 END_COM_MAP() 29 DECLARE_GET_CONTROLLING_UNKNOWN() 30 HRESULT Init(T *begin,T *end,IUnknown *pUnk,CComEnumFlags flags = AtlFlagNoCopy) { 31 HRESULT hr; 32 IUnknown *pIU = GetControllingUnknown(); 33 hr = CoCreateFreeThreadedMarshaler(pIU,& m_pFTM); 34 if(FAILED(hr)) return hr; 35 return BaseClass::Init(begin,end,pUnk,flags); 36 } 37 CSafeComEnum() { m_pFTM = NULL; } 38 void FinalRelease(void) { 39 if(m_pFTM) { 40 m_pFTM->Release(); 41 } 42 CComObjectRootEx< ThreadModel >::FinalRelease(); 43 } 44protected: 45 IUnknown *m_pFTM; 46}; 47 48#endif /* __cplusplus */ 49 50#endif 51 52