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
;
31 IGraphVersion
* pVersionSource
;
33 IBaseFilter
*** pppFilters
;
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
));
53 TRACE("(%p, %p, %p)\n", pppFilters
, pNumFilters
, ppEnum
);
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
, ¤tVersion
);
72 pEnumFilters
->Version
= (hr
==S_OK
) ? currentVersion
: 0;
74 *ppEnum
= &pEnumFilters
->IEnumFilters_iface
;
78 static HRESULT WINAPI
IEnumFiltersImpl_QueryInterface(IEnumFilters
* iface
, REFIID riid
, LPVOID
* ppv
)
80 TRACE("(%p)->(%s, %p)\n", iface
, qzdebugstr_guid(riid
), ppv
);
84 if (IsEqualIID(riid
, &IID_IUnknown
))
86 else if (IsEqualIID(riid
, &IID_IEnumFilters
))
91 IUnknown_AddRef((IUnknown
*)(*ppv
));
95 FIXME("No interface for %s!\n", qzdebugstr_guid(riid
));
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
);
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
);
119 IGraphVersion_Release(This
->pVersionSource
);
127 static HRESULT WINAPI
IEnumFiltersImpl_Next(IEnumFilters
* iface
, ULONG cFilters
, IBaseFilter
** ppFilters
, ULONG
* pcFetched
)
132 IEnumFiltersImpl
*This
= impl_from_IEnumFilters(iface
);
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
, ¤tVersion
);
141 if (hr
==S_OK
&& This
->Version
!= currentVersion
)
142 return VFW_E_ENUM_OUT_OF_SYNC
;
148 for (i
= 0; i
< cFetched
; i
++)
150 ppFilters
[i
] = (*This
->pppFilters
)[This
->uIndex
+ i
];
151 IBaseFilter_AddRef(ppFilters
[i
]);
154 This
->uIndex
+= cFetched
;
157 *pcFetched
= cFetched
;
159 if (cFetched
!= cFilters
)
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
;
178 static HRESULT WINAPI
IEnumFiltersImpl_Reset(IEnumFilters
* iface
)
180 IEnumFiltersImpl
*This
= impl_from_IEnumFilters(iface
);
184 TRACE("(%p)->()\n", iface
);
187 hr
= IGraphVersion_QueryVersion(This
->pVersionSource
, ¤tVersion
);
189 This
->Version
= currentVersion
;
193 static HRESULT WINAPI
IEnumFiltersImpl_Clone(IEnumFilters
* iface
, IEnumFilters
** ppEnum
)
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
);
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