quartz: Fix converting between the media time and REFTIME.
[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     IEnumMoniker IEnumMoniker_iface;
35     LONG ref;
36     IMoniker ** ppMoniker;
37     ULONG nMonikerCount;
38     ULONG index;
39 } EnumMonikerImpl;
40
41 static const IEnumMonikerVtbl EnumMonikerImpl_Vtbl;
42
43 static inline EnumMonikerImpl *impl_from_IEnumMoniker(IEnumMoniker *iface)
44 {
45     return CONTAINING_RECORD(iface, EnumMonikerImpl, IEnumMoniker_iface);
46 }
47
48 static ULONG WINAPI EnumMonikerImpl_AddRef(LPENUMMONIKER iface);
49
50 HRESULT EnumMonikerImpl_Create(IMoniker ** ppMoniker, ULONG nMonikerCount, IEnumMoniker ** ppEnum)
51 {
52     /* NOTE: assumes that array of IMonikers has already been AddRef'd
53      * I.e. this function does not AddRef the array of incoming
54      * IMonikers */
55     EnumMonikerImpl * pemi = CoTaskMemAlloc(sizeof(EnumMonikerImpl));
56
57     TRACE("(%p, %d, %p)\n", ppMoniker, nMonikerCount, ppEnum);
58
59     *ppEnum = NULL;
60
61     if (!pemi)
62         return E_OUTOFMEMORY;
63
64     pemi->IEnumMoniker_iface.lpVtbl = &EnumMonikerImpl_Vtbl;
65     pemi->ref = 1;
66     pemi->ppMoniker = CoTaskMemAlloc(nMonikerCount * sizeof(IMoniker*));
67     memcpy(pemi->ppMoniker, ppMoniker, nMonikerCount*sizeof(IMoniker*));
68     pemi->nMonikerCount = nMonikerCount;
69     pemi->index = 0;
70
71     *ppEnum = &pemi->IEnumMoniker_iface;
72
73     return S_OK;
74 }
75
76 /**********************************************************************
77  * IEnumMoniker_QueryInterface (also IUnknown)
78  */
79 static HRESULT WINAPI EnumMonikerImpl_QueryInterface(
80     LPENUMMONIKER iface,
81     REFIID riid,
82     LPVOID *ppvObj)
83 {
84     EnumMonikerImpl *This = impl_from_IEnumMoniker(iface);
85     TRACE("\n\tIID:\t%s\n",debugstr_guid(riid));
86
87     if (This == NULL || ppvObj == NULL) return E_POINTER;
88
89     if (IsEqualGUID(riid, &IID_IUnknown) ||
90         IsEqualGUID(riid, &IID_IEnumMoniker))
91     {
92         *ppvObj = iface;
93         EnumMonikerImpl_AddRef(iface);
94         return S_OK;
95     }
96
97     *ppvObj = NULL;
98     FIXME("- no interface\n\tIID:\t%s\n", debugstr_guid(riid));
99     return E_NOINTERFACE;
100 }
101
102 /**********************************************************************
103  * IEnumMoniker_AddRef (also IUnknown)
104  */
105 static ULONG WINAPI EnumMonikerImpl_AddRef(LPENUMMONIKER iface)
106 {
107     EnumMonikerImpl *This = impl_from_IEnumMoniker(iface);
108     ULONG ref;
109
110     if (This == NULL) return E_POINTER;
111
112     ref = InterlockedIncrement(&This->ref);
113
114     TRACE("(%p)->() AddRef from %d\n", iface, ref - 1);
115
116     return ref;
117 }
118
119 /**********************************************************************
120  * IEnumMoniker_Release (also IUnknown)
121  */
122 static ULONG WINAPI EnumMonikerImpl_Release(LPENUMMONIKER iface)
123 {
124     EnumMonikerImpl *This = impl_from_IEnumMoniker(iface);
125     ULONG ref = InterlockedDecrement(&This->ref);
126
127     TRACE("(%p)->() Release from %d\n", iface, ref + 1);
128
129     if (!ref)
130     {
131         ULONG i;
132
133         for (i = 0; i < This->nMonikerCount; i++)
134             IMoniker_Release(This->ppMoniker[i]);
135
136         CoTaskMemFree(This->ppMoniker);
137         This->ppMoniker = NULL;
138         CoTaskMemFree(This);
139         return 0;
140     }
141     return ref;
142 }
143
144 static HRESULT WINAPI EnumMonikerImpl_Next(LPENUMMONIKER iface, ULONG celt, IMoniker ** rgelt, ULONG * pceltFetched)
145 {
146     ULONG fetched;
147     EnumMonikerImpl *This = impl_from_IEnumMoniker(iface);
148
149     TRACE("(%p)->(%d, %p, %p)\n", iface, celt, rgelt, pceltFetched);
150
151     for (fetched = 0; (This->index + fetched < This->nMonikerCount) && (fetched < celt); fetched++)
152     {
153         rgelt[fetched] = This->ppMoniker[This->index + fetched];
154         IMoniker_AddRef(rgelt[fetched]);
155     }
156
157     This->index += fetched;
158
159     TRACE("-- fetched %d\n", fetched);
160
161     if (pceltFetched)
162         *pceltFetched = fetched;
163
164     if (fetched != celt)
165         return S_FALSE;
166     else
167         return S_OK;
168 }
169
170 static HRESULT WINAPI EnumMonikerImpl_Skip(LPENUMMONIKER iface, ULONG celt)
171 {
172     EnumMonikerImpl *This = impl_from_IEnumMoniker(iface);
173
174     TRACE("(%p)->(%d)\n", iface, celt);
175
176     This->index += celt;
177
178     return S_OK;
179 }
180
181 static HRESULT WINAPI EnumMonikerImpl_Reset(LPENUMMONIKER iface)
182 {
183     EnumMonikerImpl *This = impl_from_IEnumMoniker(iface);
184
185     TRACE("(%p)->()\n", iface);
186
187     This->index = 0;
188
189     return S_OK;
190 }
191
192 static HRESULT WINAPI EnumMonikerImpl_Clone(LPENUMMONIKER iface, IEnumMoniker ** ppenum)
193 {
194     FIXME("(%p)->(%p): stub\n", iface, ppenum);
195
196     return E_NOTIMPL;
197 }
198
199 /**********************************************************************
200  * IEnumMoniker_Vtbl
201  */
202 static const IEnumMonikerVtbl EnumMonikerImpl_Vtbl =
203 {
204     EnumMonikerImpl_QueryInterface,
205     EnumMonikerImpl_AddRef,
206     EnumMonikerImpl_Release,
207     EnumMonikerImpl_Next,
208     EnumMonikerImpl_Skip,
209     EnumMonikerImpl_Reset,
210     EnumMonikerImpl_Clone
211 };