2 * Implementation of IEnumUnknown (for internal use).
4 * hidenori@a2.ctktv.ne.jp
12 #include "wine/obj_base.h"
13 #include "wine/obj_misc.h"
15 #include "debugtools.h"
16 DEFAULT_DEBUG_CHANNEL(quartz);
18 #include "quartz_private.h"
24 typedef struct IEnumUnknownImpl
26 ICOM_VFIELD(IEnumUnknown);
32 IEnumUnknownImpl enumunk;
33 struct QUARTZ_IFEntry IFEntries[1];
34 QUARTZ_CompList* pCompList;
35 QUARTZ_CompListItem* pItemCur;
38 #define CEnumUnknown_THIS(iface,member) CEnumUnknown* This = ((CEnumUnknown*)(((char*)iface)-offsetof(CEnumUnknown,member)))
44 IEnumUnknown_fnQueryInterface(IEnumUnknown* iface,REFIID riid,void** ppobj)
46 CEnumUnknown_THIS(iface,enumunk);
48 TRACE("(%p)->()\n",This);
50 return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
54 IEnumUnknown_fnAddRef(IEnumUnknown* iface)
56 CEnumUnknown_THIS(iface,enumunk);
58 TRACE("(%p)->()\n",This);
60 return IUnknown_AddRef(This->unk.punkControl);
64 IEnumUnknown_fnRelease(IEnumUnknown* iface)
66 CEnumUnknown_THIS(iface,enumunk);
68 TRACE("(%p)->()\n",This);
70 return IUnknown_Release(This->unk.punkControl);
74 IEnumUnknown_fnNext(IEnumUnknown* iface,ULONG cReq,IUnknown** ppunk,ULONG* pcFetched)
76 CEnumUnknown_THIS(iface,enumunk);
80 TRACE("(%p)->(%lu,%p,%p)\n",This,cReq,ppunk,pcFetched);
82 if ( pcFetched == NULL && cReq > 1 )
87 QUARTZ_CompList_Lock( This->pCompList );
93 if ( This->pItemCur == NULL )
98 ppunk[ cFetched ++ ] = QUARTZ_CompList_GetItemPtr( This->pItemCur );
99 IUnknown_AddRef( *ppunk );
102 QUARTZ_CompList_GetNext( This->pCompList, This->pItemCur );
106 QUARTZ_CompList_Unlock( This->pCompList );
108 if ( pcFetched != NULL )
109 *pcFetched = cFetched;
114 static HRESULT WINAPI
115 IEnumUnknown_fnSkip(IEnumUnknown* iface,ULONG cSkip)
117 CEnumUnknown_THIS(iface,enumunk);
120 TRACE("(%p)->()\n",This);
122 QUARTZ_CompList_Lock( This->pCompList );
127 if ( This->pItemCur == NULL )
133 QUARTZ_CompList_GetNext( This->pCompList, This->pItemCur );
137 QUARTZ_CompList_Unlock( This->pCompList );
142 static HRESULT WINAPI
143 IEnumUnknown_fnReset(IEnumUnknown* iface)
145 CEnumUnknown_THIS(iface,enumunk);
147 TRACE("(%p)->()\n",This);
149 QUARTZ_CompList_Lock( This->pCompList );
151 This->pItemCur = QUARTZ_CompList_GetFirst( This->pCompList );
153 QUARTZ_CompList_Unlock( This->pCompList );
158 static HRESULT WINAPI
159 IEnumUnknown_fnClone(IEnumUnknown* iface,IEnumUnknown** ppunk)
161 CEnumUnknown_THIS(iface,enumunk);
164 TRACE("(%p)->()\n",This);
169 QUARTZ_CompList_Lock( This->pCompList );
171 hr = QUARTZ_CreateEnumUnknown(
172 This->IFEntries[0].piid,
175 FIXME( "current pointer must be seeked correctly\n" );
177 QUARTZ_CompList_Unlock( This->pCompList );
183 static ICOM_VTABLE(IEnumUnknown) ienumunk =
185 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
186 /* IUnknown fields */
187 IEnumUnknown_fnQueryInterface,
188 IEnumUnknown_fnAddRef,
189 IEnumUnknown_fnRelease,
190 /* IEnumUnknown fields */
193 IEnumUnknown_fnReset,
194 IEnumUnknown_fnClone,
197 void QUARTZ_DestroyEnumUnknown(IUnknown* punk)
199 CEnumUnknown_THIS(punk,unk);
201 if ( This->pCompList != NULL )
202 QUARTZ_CompList_Free( This->pCompList );
205 HRESULT QUARTZ_CreateEnumUnknown(
206 REFIID riidEnum, void** ppobj, const QUARTZ_CompList* pCompList )
209 QUARTZ_CompList* pCompListDup;
211 TRACE("(%s,%p,%p)\n",debugstr_guid(riidEnum),ppobj,pCompList);
213 pCompListDup = QUARTZ_CompList_Dup( pCompList, FALSE );
214 if ( pCompListDup == NULL )
215 return E_OUTOFMEMORY;
217 penum = (CEnumUnknown*)QUARTZ_AllocObj( sizeof(CEnumUnknown) );
220 QUARTZ_CompList_Free( pCompListDup );
221 return E_OUTOFMEMORY;
224 QUARTZ_IUnkInit( &penum->unk, NULL );
225 ICOM_VTBL(&penum->enumunk) = &ienumunk;
227 penum->IFEntries[0].piid = riidEnum;
228 penum->IFEntries[0].ofsVTPtr =
229 offsetof(CEnumUnknown,enumunk)-offsetof(CEnumUnknown,unk);
230 penum->pCompList = pCompListDup;
231 penum->pItemCur = QUARTZ_CompList_GetFirst( pCompListDup );
233 penum->unk.pEntries = penum->IFEntries;
234 penum->unk.dwEntries = 1;
235 penum->unk.pOnFinalRelease = QUARTZ_DestroyEnumUnknown;
237 *ppobj = (void*)(&penum->enumunk);