5182e6a8dddfef9c318d356a7ae81adf5c3813f1
[reactos.git] / reactos / dll / directx / wine / quartz / enumfilters.c
1 /*
2 * Implementation of IEnumFilters 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/debug.h>
24
25 WINE_DEFAULT_DEBUG_CHANNEL(quartz);
26
27 typedef struct IEnumFiltersImpl
28 {
29 IEnumFilters IEnumFilters_iface;
30 LONG refCount;
31 IGraphVersion * pVersionSource;
32 LONG Version;
33 IBaseFilter *** pppFilters;
34 ULONG * pNumFilters;
35 ULONG uIndex;
36 } IEnumFiltersImpl;
37
38 static const struct IEnumFiltersVtbl IEnumFiltersImpl_Vtbl;
39
40 static inline IEnumFiltersImpl *impl_from_IEnumFilters(IEnumFilters *iface)
41 {
42 return CONTAINING_RECORD(iface, IEnumFiltersImpl, IEnumFilters_iface);
43 }
44
45 HRESULT IEnumFiltersImpl_Construct(IGraphVersion * pVersionSource, IBaseFilter *** pppFilters, ULONG * pNumFilters, IEnumFilters ** ppEnum)
46 {
47 /* Note: The incoming IBaseFilter interfaces are not AddRef'd here as in Windows,
48 * they should have been previously AddRef'd. */
49 IEnumFiltersImpl * pEnumFilters = CoTaskMemAlloc(sizeof(IEnumFiltersImpl));
50 HRESULT hr;
51 LONG currentVersion;
52
53 TRACE("(%p, %p, %p)\n", pppFilters, pNumFilters, ppEnum);
54
55 *ppEnum = NULL;
56
57 if (!pEnumFilters)
58 {
59 return E_OUTOFMEMORY;
60 }
61
62 pEnumFilters->IEnumFilters_iface.lpVtbl = &IEnumFiltersImpl_Vtbl;
63 pEnumFilters->refCount = 1;
64 pEnumFilters->uIndex = 0;
65 pEnumFilters->pNumFilters = pNumFilters;
66 pEnumFilters->pppFilters = pppFilters;
67 IGraphVersion_AddRef(pVersionSource);
68 pEnumFilters->pVersionSource = pVersionSource;
69
70 /* Store the current version of the graph */
71 hr = IGraphVersion_QueryVersion(pVersionSource, &currentVersion);
72 pEnumFilters->Version = (hr==S_OK) ? currentVersion : 0;
73
74 *ppEnum = &pEnumFilters->IEnumFilters_iface;
75 return S_OK;
76 }
77
78 static HRESULT WINAPI IEnumFiltersImpl_QueryInterface(IEnumFilters * iface, REFIID riid, LPVOID * ppv)
79 {
80 TRACE("(%p)->(%s, %p)\n", iface, qzdebugstr_guid(riid), ppv);
81
82 *ppv = NULL;
83
84 if (IsEqualIID(riid, &IID_IUnknown))
85 *ppv = iface;
86 else if (IsEqualIID(riid, &IID_IEnumFilters))
87 *ppv = iface;
88
89 if (*ppv)
90 {
91 IUnknown_AddRef((IUnknown *)(*ppv));
92 return S_OK;
93 }
94
95 FIXME("No interface for %s!\n", qzdebugstr_guid(riid));
96
97 return E_NOINTERFACE;
98 }
99
100 static ULONG WINAPI IEnumFiltersImpl_AddRef(IEnumFilters * iface)
101 {
102 IEnumFiltersImpl *This = impl_from_IEnumFilters(iface);
103 ULONG refCount = InterlockedIncrement(&This->refCount);
104
105 TRACE("(%p)->()\n", iface);
106
107 return refCount;
108 }
109
110 static ULONG WINAPI IEnumFiltersImpl_Release(IEnumFilters * iface)
111 {
112 IEnumFiltersImpl *This = impl_from_IEnumFilters(iface);
113 ULONG refCount = InterlockedDecrement(&This->refCount);
114
115 TRACE("(%p)->()\n", iface);
116
117 if (!refCount)
118 {
119 IGraphVersion_Release(This->pVersionSource);
120 return 0;
121 }
122 else
123 return refCount;
124 }
125
126 static HRESULT WINAPI IEnumFiltersImpl_Next(IEnumFilters * iface, ULONG cFilters, IBaseFilter ** ppFilters, ULONG * pcFetched)
127 {
128 ULONG cFetched;
129 ULONG i;
130 LONG currentVersion;
131 IEnumFiltersImpl *This = impl_from_IEnumFilters(iface);
132 HRESULT hr;
133
134 cFetched = min(*This->pNumFilters, This->uIndex + cFilters) - This->uIndex;
135
136 TRACE("(%p)->(%u, %p, %p)\n", iface, cFilters, ppFilters, pcFetched);
137
138 /* First of all check if the graph has changed */
139 hr = IGraphVersion_QueryVersion(This->pVersionSource, &currentVersion);
140 if (hr==S_OK && This->Version != currentVersion)
141 return VFW_E_ENUM_OUT_OF_SYNC;
142
143
144 if (!ppFilters)
145 return E_POINTER;
146
147 for (i = 0; i < cFetched; i++)
148 {
149 ppFilters[i] = (*This->pppFilters)[This->uIndex + i];
150 IBaseFilter_AddRef(ppFilters[i]);
151 }
152
153 This->uIndex += cFetched;
154
155 if (pcFetched)
156 *pcFetched = cFetched;
157
158 if (cFetched != cFilters)
159 return S_FALSE;
160 return S_OK;
161 }
162
163 static HRESULT WINAPI IEnumFiltersImpl_Skip(IEnumFilters * iface, ULONG cFilters)
164 {
165 IEnumFiltersImpl *This = impl_from_IEnumFilters(iface);
166
167 TRACE("(%p)->(%u)\n", iface, cFilters);
168
169 if (This->uIndex + cFilters < *This->pNumFilters)
170 {
171 This->uIndex += cFilters;
172 return S_OK;
173 }
174 return S_FALSE;
175 }
176
177 static HRESULT WINAPI IEnumFiltersImpl_Reset(IEnumFilters * iface)
178 {
179 IEnumFiltersImpl *This = impl_from_IEnumFilters(iface);
180 HRESULT hr;
181 LONG currentVersion;
182
183 TRACE("(%p)->()\n", iface);
184
185 This->uIndex = 0;
186 hr = IGraphVersion_QueryVersion(This->pVersionSource, &currentVersion);
187 if (!hr)
188 This->Version = currentVersion;
189 return S_OK;
190 }
191
192 static HRESULT WINAPI IEnumFiltersImpl_Clone(IEnumFilters * iface, IEnumFilters ** ppEnum)
193 {
194 HRESULT hr;
195 IEnumFiltersImpl *This = impl_from_IEnumFilters(iface);
196
197 TRACE("(%p)->(%p)\n", iface, ppEnum);
198
199 hr = IEnumFiltersImpl_Construct(This->pVersionSource, This->pppFilters, This->pNumFilters, ppEnum);
200 if (FAILED(hr))
201 return hr;
202 return IEnumFilters_Skip(*ppEnum, This->uIndex);
203 }
204
205 static const IEnumFiltersVtbl IEnumFiltersImpl_Vtbl =
206 {
207 IEnumFiltersImpl_QueryInterface,
208 IEnumFiltersImpl_AddRef,
209 IEnumFiltersImpl_Release,
210 IEnumFiltersImpl_Next,
211 IEnumFiltersImpl_Skip,
212 IEnumFiltersImpl_Reset,
213 IEnumFiltersImpl_Clone
214 };