dpnet/tests: Add a trailing '\n' to some ok() calls.
[wine.git] / dlls / quartz / enumfilters.c
blobea2af2ad1c4185688410bebd0dff292af2a78202
1 /*
2 * Implementation of IEnumFilters Interface
4 * Copyright 2004 Christian Costa
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.
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.
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
21 #include "quartz_private.h"
23 #include "wine/debug.h"
25 WINE_DEFAULT_DEBUG_CHANNEL(quartz);
27 typedef struct IEnumFiltersImpl
29 IEnumFilters IEnumFilters_iface;
30 LONG refCount;
31 IGraphVersion * pVersionSource;
32 LONG Version;
33 IBaseFilter *** pppFilters;
34 ULONG * pNumFilters;
35 ULONG uIndex;
36 } IEnumFiltersImpl;
38 static const struct IEnumFiltersVtbl IEnumFiltersImpl_Vtbl;
40 static inline IEnumFiltersImpl *impl_from_IEnumFilters(IEnumFilters *iface)
42 return CONTAINING_RECORD(iface, IEnumFiltersImpl, IEnumFilters_iface);
45 HRESULT IEnumFiltersImpl_Construct(IGraphVersion * pVersionSource, IBaseFilter *** pppFilters, ULONG * pNumFilters, IEnumFilters ** ppEnum)
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;
53 TRACE("(%p, %p, %p)\n", pppFilters, pNumFilters, ppEnum);
55 *ppEnum = NULL;
57 if (!pEnumFilters)
59 return E_OUTOFMEMORY;
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;
70 /* Store the current version of the graph */
71 hr = IGraphVersion_QueryVersion(pVersionSource, &currentVersion);
72 pEnumFilters->Version = (hr==S_OK) ? currentVersion : 0;
74 *ppEnum = &pEnumFilters->IEnumFilters_iface;
75 return S_OK;
78 static HRESULT WINAPI IEnumFiltersImpl_QueryInterface(IEnumFilters * iface, REFIID riid, LPVOID * ppv)
80 TRACE("(%p)->(%s, %p)\n", iface, qzdebugstr_guid(riid), ppv);
82 *ppv = NULL;
84 if (IsEqualIID(riid, &IID_IUnknown))
85 *ppv = iface;
86 else if (IsEqualIID(riid, &IID_IEnumFilters))
87 *ppv = iface;
89 if (*ppv)
91 IUnknown_AddRef((IUnknown *)(*ppv));
92 return S_OK;
95 FIXME("No interface for %s!\n", qzdebugstr_guid(riid));
97 return E_NOINTERFACE;
100 static ULONG WINAPI IEnumFiltersImpl_AddRef(IEnumFilters * iface)
102 IEnumFiltersImpl *This = impl_from_IEnumFilters(iface);
103 ULONG refCount = InterlockedIncrement(&This->refCount);
105 TRACE("(%p)->()\n", iface);
107 return refCount;
110 static ULONG WINAPI IEnumFiltersImpl_Release(IEnumFilters * iface)
112 IEnumFiltersImpl *This = impl_from_IEnumFilters(iface);
113 ULONG refCount = InterlockedDecrement(&This->refCount);
115 TRACE("(%p)->()\n", iface);
117 if (!refCount)
119 IGraphVersion_Release(This->pVersionSource);
120 CoTaskMemFree(This);
121 return 0;
123 else
124 return refCount;
127 static HRESULT WINAPI IEnumFiltersImpl_Next(IEnumFilters * iface, ULONG cFilters, IBaseFilter ** ppFilters, ULONG * pcFetched)
129 ULONG cFetched;
130 ULONG i;
131 LONG currentVersion;
132 IEnumFiltersImpl *This = impl_from_IEnumFilters(iface);
133 HRESULT hr;
135 cFetched = min(*This->pNumFilters, This->uIndex + cFilters) - This->uIndex;
137 TRACE("(%p)->(%u, %p, %p)\n", iface, cFilters, ppFilters, pcFetched);
139 /* First of all check if the graph has changed */
140 hr = IGraphVersion_QueryVersion(This->pVersionSource, &currentVersion);
141 if (hr==S_OK && This->Version != currentVersion)
142 return VFW_E_ENUM_OUT_OF_SYNC;
145 if (!ppFilters)
146 return E_POINTER;
148 for (i = 0; i < cFetched; i++)
150 ppFilters[i] = (*This->pppFilters)[This->uIndex + i];
151 IBaseFilter_AddRef(ppFilters[i]);
154 This->uIndex += cFetched;
156 if (pcFetched)
157 *pcFetched = cFetched;
159 if (cFetched != cFilters)
160 return S_FALSE;
161 return S_OK;
164 static HRESULT WINAPI IEnumFiltersImpl_Skip(IEnumFilters * iface, ULONG cFilters)
166 IEnumFiltersImpl *This = impl_from_IEnumFilters(iface);
168 TRACE("(%p)->(%u)\n", iface, cFilters);
170 if (This->uIndex + cFilters < *This->pNumFilters)
172 This->uIndex += cFilters;
173 return S_OK;
175 return S_FALSE;
178 static HRESULT WINAPI IEnumFiltersImpl_Reset(IEnumFilters * iface)
180 IEnumFiltersImpl *This = impl_from_IEnumFilters(iface);
181 HRESULT hr;
182 LONG currentVersion;
184 TRACE("(%p)->()\n", iface);
186 This->uIndex = 0;
187 hr = IGraphVersion_QueryVersion(This->pVersionSource, &currentVersion);
188 if (!hr)
189 This->Version = currentVersion;
190 return S_OK;
193 static HRESULT WINAPI IEnumFiltersImpl_Clone(IEnumFilters * iface, IEnumFilters ** ppEnum)
195 HRESULT hr;
196 IEnumFiltersImpl *This = impl_from_IEnumFilters(iface);
198 TRACE("(%p)->(%p)\n", iface, ppEnum);
200 hr = IEnumFiltersImpl_Construct(This->pVersionSource, This->pppFilters, This->pNumFilters, ppEnum);
201 if (FAILED(hr))
202 return hr;
203 return IEnumFilters_Skip(*ppEnum, This->uIndex);
206 static const IEnumFiltersVtbl IEnumFiltersImpl_Vtbl =
208 IEnumFiltersImpl_QueryInterface,
209 IEnumFiltersImpl_AddRef,
210 IEnumFiltersImpl_Release,
211 IEnumFiltersImpl_Next,
212 IEnumFiltersImpl_Skip,
213 IEnumFiltersImpl_Reset,
214 IEnumFiltersImpl_Clone