oleaut32: Add a helper to return INVOKEKIND flags value.
[wine] / dlls / quartz / enumregfilters.c
1 /*
2  * Implementation of IEnumRegFilters Interface
3  *
4  * Copyright 2004 Christian Costa
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #include "quartz_private.h"
22
23 #include "wine/unicode.h"
24
25 #include "wine/debug.h"
26
27 WINE_DEFAULT_DEBUG_CHANNEL(quartz);
28
29 typedef struct IEnumRegFiltersImpl
30 {
31     IEnumRegFilters IEnumRegFilters_iface;
32     LONG refCount;
33     ULONG size;
34     REGFILTER* RegFilters;
35     ULONG uIndex;
36 } IEnumRegFiltersImpl;
37
38 static inline IEnumRegFiltersImpl *impl_from_IEnumRegFilters(IEnumRegFilters *iface)
39 {
40     return CONTAINING_RECORD(iface, IEnumRegFiltersImpl, IEnumRegFilters_iface);
41 }
42
43 static const struct IEnumRegFiltersVtbl IEnumRegFiltersImpl_Vtbl;
44
45 HRESULT IEnumRegFiltersImpl_Construct(REGFILTER* pInRegFilters, const ULONG size, IEnumRegFilters ** ppEnum)
46 {
47     IEnumRegFiltersImpl* pEnumRegFilters;
48     REGFILTER* pRegFilters = NULL;
49     unsigned int i;
50
51     TRACE("(%p, %d, %p)\n", pInRegFilters, size, ppEnum);
52
53     pEnumRegFilters = CoTaskMemAlloc(sizeof(IEnumRegFiltersImpl));
54     if (!pEnumRegFilters)
55     {
56         *ppEnum = NULL;
57         return E_OUTOFMEMORY;
58     }
59
60     /* Accept size of 0 */
61     if (size)
62     {
63         pRegFilters = CoTaskMemAlloc(sizeof(REGFILTER)*size);
64         if (!pRegFilters)
65         {
66             CoTaskMemFree(pEnumRegFilters);
67             *ppEnum = NULL;
68            return E_OUTOFMEMORY;
69         }
70     }
71
72     for(i = 0; i < size; i++)
73     {
74         pRegFilters[i].Clsid = pInRegFilters[i].Clsid;
75         pRegFilters[i].Name = CoTaskMemAlloc((strlenW(pInRegFilters[i].Name)+1)*sizeof(WCHAR));
76         if (!pRegFilters[i].Name)
77         {
78             while(i)
79                 CoTaskMemFree(pRegFilters[--i].Name);
80             CoTaskMemFree(pRegFilters);
81             CoTaskMemFree(pEnumRegFilters);
82             return E_OUTOFMEMORY;
83         }
84         CopyMemory(pRegFilters[i].Name, pInRegFilters[i].Name, (strlenW(pInRegFilters[i].Name)+1)*sizeof(WCHAR));
85     }
86
87     pEnumRegFilters->IEnumRegFilters_iface.lpVtbl = &IEnumRegFiltersImpl_Vtbl;
88     pEnumRegFilters->refCount = 1;
89     pEnumRegFilters->uIndex = 0;
90     pEnumRegFilters->RegFilters = pRegFilters;
91     pEnumRegFilters->size = size;
92
93     *ppEnum = &pEnumRegFilters->IEnumRegFilters_iface;
94
95     return S_OK;
96 }
97
98 static HRESULT WINAPI IEnumRegFiltersImpl_QueryInterface(IEnumRegFilters * iface, REFIID riid, LPVOID * ppv)
99 {
100     TRACE("(%p)->(%s, %p)\n", iface, qzdebugstr_guid(riid), ppv);
101
102     *ppv = NULL;
103
104     if (IsEqualIID(riid, &IID_IUnknown))
105         *ppv = iface;
106     else if (IsEqualIID(riid, &IID_IEnumRegFilters))
107         *ppv = iface;
108
109     if (*ppv)
110     {
111         IUnknown_AddRef((IUnknown *)(*ppv));
112         return S_OK;
113     }
114
115     FIXME("No interface for %s!\n", qzdebugstr_guid(riid));
116
117     return E_NOINTERFACE;
118 }
119
120 static ULONG WINAPI IEnumRegFiltersImpl_AddRef(IEnumRegFilters * iface)
121 {
122     IEnumRegFiltersImpl *This = impl_from_IEnumRegFilters(iface);
123     ULONG refCount = InterlockedIncrement(&This->refCount);
124
125     TRACE("(%p)\n", iface);
126
127     return refCount;
128 }
129
130 static ULONG WINAPI IEnumRegFiltersImpl_Release(IEnumRegFilters * iface)
131 {
132     IEnumRegFiltersImpl *This = impl_from_IEnumRegFilters(iface);
133     ULONG refCount = InterlockedDecrement(&This->refCount);
134
135     TRACE("(%p)\n", iface);
136
137     if (!refCount)
138     {
139         ULONG i;
140
141         for(i = 0; i < This->size; i++)
142         {
143             CoTaskMemFree(This->RegFilters[i].Name);
144         }
145         CoTaskMemFree(This->RegFilters);
146         CoTaskMemFree(This);
147         return 0;
148     } else
149         return refCount;
150 }
151
152 static HRESULT WINAPI IEnumRegFiltersImpl_Next(IEnumRegFilters * iface, ULONG cFilters, REGFILTER ** ppRegFilter, ULONG * pcFetched)
153 {
154     ULONG cFetched; 
155     IEnumRegFiltersImpl *This = impl_from_IEnumRegFilters(iface);
156     unsigned int i;
157
158     cFetched = min(This->size, This->uIndex + cFilters) - This->uIndex;
159
160     TRACE("(%p)->(%u, %p, %p)\n", iface, cFilters, ppRegFilter, pcFetched);
161
162     if (cFetched > 0)
163     {
164         for(i = 0; i < cFetched; i++)
165         {
166             /* The string in the REGFILTER structure must be allocated in the same block as the REGFILTER structure itself */
167             ppRegFilter[i] = CoTaskMemAlloc(sizeof(REGFILTER)+(strlenW(This->RegFilters[This->uIndex + i].Name)+1)*sizeof(WCHAR));
168             if (!ppRegFilter[i])
169             {
170                 while(i)
171                 {
172                     CoTaskMemFree(ppRegFilter[--i]);
173                     ppRegFilter[i] = NULL;
174                 }
175                 return E_OUTOFMEMORY;
176         }
177             ppRegFilter[i]->Clsid = This->RegFilters[This->uIndex + i].Clsid;
178             ppRegFilter[i]->Name = (WCHAR*)((char*)ppRegFilter[i]+sizeof(REGFILTER));
179             CopyMemory(ppRegFilter[i]->Name, This->RegFilters[This->uIndex + i].Name,
180                             (strlenW(This->RegFilters[This->uIndex + i].Name)+1)*sizeof(WCHAR));
181         }
182
183         This->uIndex += cFetched;
184         if (pcFetched)
185             *pcFetched = cFetched;
186         return S_OK;
187     }
188
189     return S_FALSE;
190 }
191
192 static HRESULT WINAPI IEnumRegFiltersImpl_Skip(IEnumRegFilters * iface, ULONG n)
193 {
194     TRACE("(%p)->(%u)\n", iface, n);
195
196     return E_NOTIMPL;
197 }
198
199 static HRESULT WINAPI IEnumRegFiltersImpl_Reset(IEnumRegFilters * iface)
200 {
201     IEnumRegFiltersImpl *This = impl_from_IEnumRegFilters(iface);
202
203     TRACE("(%p)\n", iface);
204
205     This->uIndex = 0;
206     return S_OK;
207 }
208
209 static HRESULT WINAPI IEnumRegFiltersImpl_Clone(IEnumRegFilters * iface, IEnumRegFilters ** ppEnum)
210 {
211     TRACE("(%p)->(%p)\n", iface, ppEnum);
212
213     return E_NOTIMPL;
214 }
215
216 static const IEnumRegFiltersVtbl IEnumRegFiltersImpl_Vtbl =
217 {
218     IEnumRegFiltersImpl_QueryInterface,
219     IEnumRegFiltersImpl_AddRef,
220     IEnumRegFiltersImpl_Release,
221     IEnumRegFiltersImpl_Next,
222     IEnumRegFiltersImpl_Skip,
223     IEnumRegFiltersImpl_Reset,
224     IEnumRegFiltersImpl_Clone
225 };