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 _MSPCOLL_H_
7 #define _MSPCOLL_H_
8 
9 template <class T> class CTapiIfCollection : public IDispatchImpl<ITCollection,&IID_ITCollection,&LIBID_TAPI3Lib>,public CComObjectRootEx<CComMultiThreadModelNoCS>
10 {
11 public:
12   typedef CTapiIfCollection<T> _CTapiCollectionBase;
13   BEGIN_COM_MAP(_CTapiCollectionBase)
14     COM_INTERFACE_ENTRY(IDispatch)
15     COM_INTERFACE_ENTRY(ITCollection)
16   END_COM_MAP()
17 private:
18   int m_nSize;
19   CComVariant *m_Var;
20 
21 public:
CTapiIfCollection(void)22   CTapiIfCollection(void) : m_nSize(0),m_Var(NULL) { }
Initialize(DWORD dwSize,T * pBegin,T * pEnd)23   HRESULT WINAPI Initialize(DWORD dwSize,T *pBegin,T *pEnd) {
24     int i;
25     HRESULT hr;
26     T *iter;
27     LOG((MSP_TRACE,"CTapiCollection::Initialize - enter"));
28     m_nSize = dwSize;
29     m_Var = new CComVariant[m_nSize];
30     if(!m_Var) return E_OUTOFMEMORY;
31     i = 0;
32     for(iter = pBegin;iter!=pEnd;iter++) {
33       IDispatch *pDisp = NULL;
34       hr = (*iter)->QueryInterface(IID_IDispatch,(void**)&pDisp);
35       if(hr!=S_OK) return hr;
36       CComVariant& var = m_Var[i];
37       VariantInit(&var);
38       var.vt = VT_DISPATCH;
39       var.pdispVal = pDisp;
40       i++;
41     }
42     LOG((MSP_TRACE,"CTapiCollection::Initialize - exit"));
43     return S_OK;
44   }
FinalRelease()45   void FinalRelease() {
46     LOG((MSP_TRACE,"CTapiCollection::FinalRelease - enter"));
47     delete [] m_Var;
48     LOG((MSP_TRACE,"CTapiCollection::FinalRelease - exit"));
49   }
STDMETHOD(get_Count)50   STDMETHOD(get_Count)(__LONG32 *retval) {
51     HRESULT hr = S_OK;
52     LOG((MSP_TRACE,"CTapiCollection::get_Count - enter"));
53     try {
54       *retval = m_nSize;
55     } catch(...) {
56       hr = E_INVALIDARG;
57     }
58     LOG((MSP_TRACE,"CTapiCollection::get_Count - exit"));
59     return hr;
60   }
STDMETHOD(get_Item)61   STDMETHOD(get_Item)(__LONG32 Index,VARIANT *retval) {
62     HRESULT hr = S_OK;
63     LOG((MSP_TRACE,"CTapiCollection::get_Item - enter"));
64     if(!retval) return E_POINTER;
65     try {
66       VariantInit(retval);
67     } catch(...) {
68       hr = E_INVALIDARG;
69     }
70     if(hr!=S_OK) return hr;
71     retval->vt = VT_UNKNOWN;
72     retval->punkVal = NULL;
73     if((Index < 1) || (Index > m_nSize)) return E_INVALIDARG;
74     hr = VariantCopy(retval,&m_Var[Index-1]);
75     if(FAILED(hr)) {
76       LOG((MSP_ERROR,"CTapiCollection::get_Item - VariantCopy failed. hr = %lx",hr));
77       return hr;
78     }
79     LOG((MSP_TRACE,"CTapiCollection::get_Item - exit"));
80     return S_OK;
81   }
get__NewEnum(IUnknown ** retval)82   HRESULT WINAPI get__NewEnum(IUnknown **retval) {
83     HRESULT hr;
84     LOG((MSP_TRACE,"CTapiCollection::new__Enum - enter"));
85     if(!retval) return E_POINTER;
86     *retval = NULL;
87     typedef CComObject<CSafeComEnum<IEnumVARIANT,&IID_IEnumVARIANT,VARIANT,_Copy<VARIANT> > > enumvar;
88     enumvar *p;
89     hr = enumvar::CreateInstance(&p);
90     if(FAILED(hr)) return hr;
91     hr = p->Init(&m_Var[0],&m_Var[m_nSize],NULL,AtlFlagCopy);
92     if(SUCCEEDED(hr)) hr = p->QueryInterface(IID_IEnumVARIANT,(void**)retval);
93     if(FAILED(hr)) delete p;
94     LOG((MSP_TRACE,"CTapiCollection::new__Enum - exit"));
95     return hr;
96   }
97 };
98 
99 class CTapiBstrCollection : public CComObjectRootEx<CComMultiThreadModelNoCS>,public IDispatchImpl<ITCollection,&IID_ITCollection,&LIBID_TAPI3Lib>,public CMSPObjectSafetyImpl
100 {
101 public:
102   BEGIN_COM_MAP(CTapiBstrCollection)
103     COM_INTERFACE_ENTRY(IDispatch)
104     COM_INTERFACE_ENTRY(ITCollection)
105     COM_INTERFACE_ENTRY(IObjectSafety)
106   END_COM_MAP()
107 private:
108   DWORD m_dwSize;
109   CComVariant *m_Var;
110 public:
CTapiBstrCollection(void)111   CTapiBstrCollection(void) : m_dwSize(0),m_Var(NULL) { }
Initialize(DWORD dwSize,BSTR * pBegin,BSTR * pEnd)112   HRESULT WINAPI Initialize(DWORD dwSize,BSTR *pBegin,BSTR *pEnd) {
113     BSTR *i;
114     DWORD dw = 0;
115     LOG((MSP_TRACE,"CTapiBstrCollection::Initialize - enter"));
116     m_dwSize = dwSize;
117     m_Var = new CComVariant[m_dwSize];
118     if(!m_Var) return E_OUTOFMEMORY;
119     for(i = pBegin;i!=pEnd;i++) {
120       CComVariant& var = m_Var[dw];
121       var.vt = VT_BSTR;
122       var.bstrVal = *i;
123       dw++;
124     }
125     LOG((MSP_TRACE,"CTapiBstrCollection::Initialize - exit"));
126     return S_OK;
127   }
STDMETHOD(get_Count)128   STDMETHOD(get_Count)(__LONG32 *retval) {
129     HRESULT hr = S_OK;
130     LOG((MSP_TRACE,"CTapiBstrCollection::get_Count - enter"));
131     try {
132       *retval = m_dwSize;
133     } catch(...) {
134       hr = E_INVALIDARG;
135     }
136     LOG((MSP_TRACE,"CTapiBstrCollection::get_Count - exit"));
137     return hr;
138   }
STDMETHOD(get_Item)139   STDMETHOD(get_Item)(__LONG32 Index,VARIANT *retval) {
140     HRESULT hr = S_OK;
141     LOG((MSP_TRACE,"CTapiBstrCollection::get_Item - enter"));
142     if(!retval) return E_POINTER;
143     try {
144       VariantInit(retval);
145     } catch(...) {
146       hr = E_INVALIDARG;
147     }
148     if(hr!=S_OK) return hr;
149     retval->vt = VT_BSTR;
150     retval->bstrVal = NULL;
151     if((Index < 1) || ((DWORD) Index > m_dwSize)) return E_INVALIDARG;
152     hr = VariantCopy(retval,&m_Var[Index-1]);
153     if(FAILED(hr)) {
154       LOG((MSP_ERROR,"CTapiBstrCollection::get_Item - VariantCopy failed. hr = %lx",hr));
155       return hr;
156     }
157     LOG((MSP_TRACE,"CTapiBstrCollection::get_Item - exit"));
158     return S_OK;
159   }
get__NewEnum(IUnknown ** retval)160   HRESULT WINAPI get__NewEnum(IUnknown **retval) {
161     HRESULT hr;
162     LOG((MSP_TRACE,"CTapiBstrCollection::get__NumEnum - enter"));
163     if(!retval) return E_POINTER;
164     *retval = NULL;
165     typedef CComObject<CSafeComEnum<IEnumVARIANT,&IID_IEnumVARIANT,VARIANT,_Copy<VARIANT> > > enumvar;
166     enumvar *p = new enumvar;
167     if(!p) return E_OUTOFMEMORY;
168     hr = p->Init(&m_Var[0],&m_Var[m_dwSize],NULL,AtlFlagCopy);
169     if(SUCCEEDED(hr)) {
170       hr = p->QueryInterface(IID_IEnumVARIANT,(void**)retval);
171     }
172     if(FAILED(hr)) delete p;
173     LOG((MSP_TRACE,"CTapiBstrCollection::get__NewEnum - exit"));
174     return hr;
175   }
FinalRelease()176   void FinalRelease() {
177     LOG((MSP_TRACE,"CTapiBstrCollection::FinalRelease() - enter"));
178     delete [] m_Var;
179     LOG((MSP_TRACE,"CTapiBstrCollection::FinalRelease() - exit"));
180   }
181 };
182 #endif
183