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 typedef struct IEnumFiltersImpl
25 IEnumFilters IEnumFilters_iface
;
27 IGraphVersion
* pVersionSource
;
29 IBaseFilter
*** pppFilters
;
34 static const struct IEnumFiltersVtbl IEnumFiltersImpl_Vtbl
;
36 static inline IEnumFiltersImpl
*impl_from_IEnumFilters(IEnumFilters
*iface
)
38 return CONTAINING_RECORD(iface
, IEnumFiltersImpl
, IEnumFilters_iface
);
41 HRESULT
IEnumFiltersImpl_Construct(IGraphVersion
* pVersionSource
, IBaseFilter
*** pppFilters
, ULONG
* pNumFilters
, IEnumFilters
** ppEnum
)
43 /* Note: The incoming IBaseFilter interfaces are not AddRef'd here as in Windows,
44 * they should have been previously AddRef'd. */
45 IEnumFiltersImpl
* pEnumFilters
= CoTaskMemAlloc(sizeof(IEnumFiltersImpl
));
49 TRACE("(%p, %p, %p)\n", pppFilters
, pNumFilters
, ppEnum
);
58 pEnumFilters
->IEnumFilters_iface
.lpVtbl
= &IEnumFiltersImpl_Vtbl
;
59 pEnumFilters
->refCount
= 1;
60 pEnumFilters
->uIndex
= 0;
61 pEnumFilters
->pNumFilters
= pNumFilters
;
62 pEnumFilters
->pppFilters
= pppFilters
;
63 IGraphVersion_AddRef(pVersionSource
);
64 pEnumFilters
->pVersionSource
= pVersionSource
;
66 /* Store the current version of the graph */
67 hr
= IGraphVersion_QueryVersion(pVersionSource
, ¤tVersion
);
68 pEnumFilters
->Version
= (hr
==S_OK
) ? currentVersion
: 0;
70 *ppEnum
= &pEnumFilters
->IEnumFilters_iface
;
74 static HRESULT WINAPI
IEnumFiltersImpl_QueryInterface(IEnumFilters
* iface
, REFIID riid
, LPVOID
* ppv
)
76 TRACE("(%p)->(%s, %p)\n", iface
, qzdebugstr_guid(riid
), ppv
);
80 if (IsEqualIID(riid
, &IID_IUnknown
))
82 else if (IsEqualIID(riid
, &IID_IEnumFilters
))
87 IUnknown_AddRef((IUnknown
*)(*ppv
));
91 FIXME("No interface for %s!\n", qzdebugstr_guid(riid
));
96 static ULONG WINAPI
IEnumFiltersImpl_AddRef(IEnumFilters
* iface
)
98 IEnumFiltersImpl
*This
= impl_from_IEnumFilters(iface
);
99 ULONG refCount
= InterlockedIncrement(&This
->refCount
);
101 TRACE("(%p)->()\n", iface
);
106 static ULONG WINAPI
IEnumFiltersImpl_Release(IEnumFilters
* iface
)
108 IEnumFiltersImpl
*This
= impl_from_IEnumFilters(iface
);
109 ULONG refCount
= InterlockedDecrement(&This
->refCount
);
111 TRACE("(%p)->()\n", iface
);
115 IGraphVersion_Release(This
->pVersionSource
);
123 static HRESULT WINAPI
IEnumFiltersImpl_Next(IEnumFilters
* iface
, ULONG cFilters
, IBaseFilter
** ppFilters
, ULONG
* pcFetched
)
128 IEnumFiltersImpl
*This
= impl_from_IEnumFilters(iface
);
131 cFetched
= min(*This
->pNumFilters
, This
->uIndex
+ cFilters
) - This
->uIndex
;
133 TRACE("(%p)->(%u, %p, %p)\n", iface
, cFilters
, ppFilters
, pcFetched
);
135 /* First of all check if the graph has changed */
136 hr
= IGraphVersion_QueryVersion(This
->pVersionSource
, ¤tVersion
);
137 if (hr
==S_OK
&& This
->Version
!= currentVersion
)
138 return VFW_E_ENUM_OUT_OF_SYNC
;
144 for (i
= 0; i
< cFetched
; i
++)
146 ppFilters
[i
] = (*This
->pppFilters
)[This
->uIndex
+ i
];
147 IBaseFilter_AddRef(ppFilters
[i
]);
150 This
->uIndex
+= cFetched
;
153 *pcFetched
= cFetched
;
155 if (cFetched
!= cFilters
)
160 static HRESULT WINAPI
IEnumFiltersImpl_Skip(IEnumFilters
* iface
, ULONG cFilters
)
162 IEnumFiltersImpl
*This
= impl_from_IEnumFilters(iface
);
164 TRACE("(%p)->(%u)\n", iface
, cFilters
);
166 if (This
->uIndex
+ cFilters
< *This
->pNumFilters
)
168 This
->uIndex
+= cFilters
;
174 static HRESULT WINAPI
IEnumFiltersImpl_Reset(IEnumFilters
* iface
)
176 IEnumFiltersImpl
*This
= impl_from_IEnumFilters(iface
);
180 TRACE("(%p)->()\n", iface
);
183 hr
= IGraphVersion_QueryVersion(This
->pVersionSource
, ¤tVersion
);
185 This
->Version
= currentVersion
;
189 static HRESULT WINAPI
IEnumFiltersImpl_Clone(IEnumFilters
* iface
, IEnumFilters
** ppEnum
)
192 IEnumFiltersImpl
*This
= impl_from_IEnumFilters(iface
);
194 TRACE("(%p)->(%p)\n", iface
, ppEnum
);
196 hr
= IEnumFiltersImpl_Construct(This
->pVersionSource
, This
->pppFilters
, This
->pNumFilters
, ppEnum
);
199 return IEnumFilters_Skip(*ppEnum
, This
->uIndex
);
202 static const IEnumFiltersVtbl IEnumFiltersImpl_Vtbl
=
204 IEnumFiltersImpl_QueryInterface
,
205 IEnumFiltersImpl_AddRef
,
206 IEnumFiltersImpl_Release
,
207 IEnumFiltersImpl_Next
,
208 IEnumFiltersImpl_Skip
,
209 IEnumFiltersImpl_Reset
,
210 IEnumFiltersImpl_Clone