quartz: Fix return value for video renderer.
[wine] / dlls / quartz / enummoniker.c
1 /*
2  * IEnumMoniker implementation
3  *
4  * Copyright 2003 Robert Shearman
5  *
6  * This file contains the (internal) driver registration functions,
7  * driver enumeration APIs and DirectDraw creation functions.
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22  */
23
24 #define COBJMACROS
25
26 #include "quartz_private.h"
27
28 #include "wine/debug.h"
29
30 WINE_DEFAULT_DEBUG_CHANNEL(quartz);
31
32 typedef struct EnumMonikerImpl
33 {
34     const IEnumMonikerVtbl *lpVtbl;
35     LONG ref;
36     IMoniker ** ppMoniker;
37     ULONG nMonikerCount;
38     ULONG index;
39 } EnumMonikerImpl;
40
41 static const IEnumMonikerVtbl EnumMonikerImpl_Vtbl;
42
43 static ULONG WINAPI EnumMonikerImpl_AddRef(LPENUMMONIKER iface);
44
45 HRESULT EnumMonikerImpl_Create(IMoniker ** ppMoniker, ULONG nMonikerCount, IEnumMoniker ** ppEnum)
46 {
47     /* NOTE: assumes that array of IMonikers has already been AddRef'd
48      * I.e. this function does not AddRef the array of incoming
49      * IMonikers */
50     EnumMonikerImpl * pemi = CoTaskMemAlloc(sizeof(EnumMonikerImpl));
51
52     TRACE("(%p, %d, %p)\n", ppMoniker, nMonikerCount, ppEnum);
53
54     *ppEnum = NULL;
55
56     if (!pemi)
57         return E_OUTOFMEMORY;
58
59     pemi->lpVtbl = &EnumMonikerImpl_Vtbl;
60     pemi->ref = 1;
61     pemi->ppMoniker = CoTaskMemAlloc(nMonikerCount * sizeof(IMoniker*));
62     memcpy(pemi->ppMoniker, ppMoniker, nMonikerCount*sizeof(IMoniker*));
63     pemi->nMonikerCount = nMonikerCount;
64     pemi->index = 0;
65
66     *ppEnum = (IEnumMoniker *)pemi;
67
68     return S_OK;
69 }
70
71 /**********************************************************************
72  * IEnumMoniker_QueryInterface (also IUnknown)
73  */
74 static HRESULT WINAPI EnumMonikerImpl_QueryInterface(
75     LPENUMMONIKER iface,
76     REFIID riid,
77     LPVOID *ppvObj)
78 {
79     EnumMonikerImpl *This = (EnumMonikerImpl *)iface;
80     TRACE("\n\tIID:\t%s\n",debugstr_guid(riid));
81
82     if (This == NULL || ppvObj == NULL) return E_POINTER;
83
84     if (IsEqualGUID(riid, &IID_IUnknown) ||
85         IsEqualGUID(riid, &IID_IEnumMoniker))
86     {
87         *ppvObj = (LPVOID)iface;
88         EnumMonikerImpl_AddRef(iface);
89         return S_OK;
90     }
91
92     *ppvObj = NULL;
93     FIXME("- no interface\n\tIID:\t%s\n", debugstr_guid(riid));
94     return E_NOINTERFACE;
95 }
96
97 /**********************************************************************
98  * IEnumMoniker_AddRef (also IUnknown)
99  */
100 static ULONG WINAPI EnumMonikerImpl_AddRef(LPENUMMONIKER iface)
101 {
102     EnumMonikerImpl *This = (EnumMonikerImpl *)iface;
103     ULONG ref;
104
105     if (This == NULL) return E_POINTER;
106
107     ref = InterlockedIncrement(&This->ref);
108
109     TRACE("(%p)->() AddRef from %d\n", iface, ref - 1);
110
111     return ref;
112 }
113
114 /**********************************************************************
115  * IEnumMoniker_Release (also IUnknown)
116  */
117 static ULONG WINAPI EnumMonikerImpl_Release(LPENUMMONIKER iface)
118 {
119     EnumMonikerImpl *This = (EnumMonikerImpl *)iface;
120     ULONG ref = InterlockedDecrement(&This->ref);
121
122     TRACE("(%p)->() Release from %d\n", iface, ref + 1);
123
124     if (!ref)
125     {
126         ULONG i;
127
128         for (i = 0; i < This->nMonikerCount; i++)
129             IMoniker_Release(This->ppMoniker[i]);
130
131         CoTaskMemFree(This->ppMoniker);
132         This->ppMoniker = NULL;
133         CoTaskMemFree(This);
134         return 0;
135     }
136     return ref;
137 }
138
139 static HRESULT WINAPI EnumMonikerImpl_Next(LPENUMMONIKER iface, ULONG celt, IMoniker ** rgelt, ULONG * pceltFetched)
140 {
141     ULONG fetched;
142     EnumMonikerImpl *This = (EnumMonikerImpl *)iface;
143
144     TRACE("(%p)->(%d, %p, %p)\n", iface, celt, rgelt, pceltFetched);
145
146     for (fetched = 0; (This->index + fetched < This->nMonikerCount) && (fetched < celt); fetched++)
147     {
148         rgelt[fetched] = This->ppMoniker[This->index + fetched];
149         IMoniker_AddRef(rgelt[fetched]);
150     }
151
152     This->index += fetched;
153
154     TRACE("-- fetched %d\n", fetched);
155
156     if (pceltFetched)
157         *pceltFetched = fetched;
158
159     if (fetched != celt)
160         return S_FALSE;
161     else
162         return S_OK;
163 }
164
165 static HRESULT WINAPI EnumMonikerImpl_Skip(LPENUMMONIKER iface, ULONG celt)
166 {
167     EnumMonikerImpl *This = (EnumMonikerImpl *)iface;
168
169     TRACE("(%p)->(%d)\n", iface, celt);
170
171     This->index += celt;
172
173     return S_OK;
174 }
175
176 static HRESULT WINAPI EnumMonikerImpl_Reset(LPENUMMONIKER iface)
177 {
178     EnumMonikerImpl *This = (EnumMonikerImpl *)iface;
179
180     TRACE("(%p)->()\n", iface);
181
182     This->index = 0;
183
184     return S_OK;
185 }
186
187 static HRESULT WINAPI EnumMonikerImpl_Clone(LPENUMMONIKER iface, IEnumMoniker ** ppenum)
188 {
189     FIXME("(%p)->(%p): stub\n", iface, ppenum);
190
191     return E_NOTIMPL;
192 }
193
194 /**********************************************************************
195  * IEnumMoniker_Vtbl
196  */
197 static const IEnumMonikerVtbl EnumMonikerImpl_Vtbl =
198 {
199     EnumMonikerImpl_QueryInterface,
200     EnumMonikerImpl_AddRef,
201     EnumMonikerImpl_Release,
202     EnumMonikerImpl_Next,
203     EnumMonikerImpl_Skip,
204     EnumMonikerImpl_Reset,
205     EnumMonikerImpl_Clone
206 };