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 
11 template <class Base,const IID *piid,class T,class Copy,class ThreadModel = CComObjectThreadModel>
12 class 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;
STDMETHOD(Next)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   }
STDMETHOD(Clone)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)
COM_INTERFACE_ENTRY_AGGREGATE(IID_IMarshal,m_pFTM)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   }
CSafeComEnum()37   CSafeComEnum() { m_pFTM = NULL; }
FinalRelease(void)38   void FinalRelease(void) {
39     if(m_pFTM) {
40       m_pFTM->Release();
41     }
42     CComObjectRootEx< ThreadModel >::FinalRelease();
43   }
44 protected:
45   IUnknown *m_pFTM;
46 };
47 
48 #endif /* __cplusplus */
49 
50 #endif
51 
52