wineps: Don't display the MFCOMMENT escape.
[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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  */
23
24 #define COBJMACROS
25 #define COM_NO_WINDOWS_H
26
27 #include "quartz_private.h"
28
29 #include "wine/debug.h"
30
31 WINE_DEFAULT_DEBUG_CHANNEL(quartz);
32
33 typedef struct EnumMonikerImpl
34 {
35     const IEnumMonikerVtbl *lpVtbl;
36     LONG ref;
37     IMoniker ** ppMoniker;
38     ULONG nMonikerCount;
39     ULONG index;
40 } EnumMonikerImpl;
41
42 static const IEnumMonikerVtbl EnumMonikerImpl_Vtbl;
43
44 static ULONG WINAPI EnumMonikerImpl_AddRef(LPENUMMONIKER iface);
45
46 HRESULT EnumMonikerImpl_Create(IMoniker ** ppMoniker, ULONG nMonikerCount, IEnumMoniker ** ppEnum)
47 {
48     /* NOTE: assumes that array of IMonikers has already been AddRef'd
49      * I.e. this function does not AddRef the array of incoming
50      * IMonikers */
51     EnumMonikerImpl * pemi = CoTaskMemAlloc(sizeof(EnumMonikerImpl));
52
53     TRACE("(%p, %ld, %p)\n", ppMoniker, nMonikerCount, ppEnum);
54
55     *ppEnum = NULL;
56
57     if (!pemi)
58         return E_OUTOFMEMORY;
59
60     pemi->lpVtbl = &EnumMonikerImpl_Vtbl;
61     pemi->ref = 1;
62     pemi->ppMoniker = CoTaskMemAlloc(nMonikerCount * sizeof(IMoniker*));
63     memcpy(pemi->ppMoniker, ppMoniker, nMonikerCount*sizeof(IMoniker*));
64     pemi->nMonikerCount = nMonikerCount;
65     pemi->index = 0;
66
67     *ppEnum = (IEnumMoniker *)pemi;
68
69     return S_OK;
70 }
71
72 /**********************************************************************
73  * IEnumMoniker_QueryInterface (also IUnknown)
74  */
75 static HRESULT WINAPI EnumMonikerImpl_QueryInterface(
76     LPENUMMONIKER iface,
77     REFIID riid,
78     LPVOID *ppvObj)
79 {
80     EnumMonikerImpl *This = (EnumMonikerImpl *)iface;
81     TRACE("\n\tIID:\t%s\n",debugstr_guid(riid));
82
83     if (This == NULL || ppvObj == NULL) return E_POINTER;
84
85     if (IsEqualGUID(riid, &IID_IUnknown) ||
86         IsEqualGUID(riid, &IID_IEnumMoniker))
87     {
88         *ppvObj = (LPVOID)iface;
89         EnumMonikerImpl_AddRef(iface);
90         return S_OK;
91     }
92
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 %ld\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 %ld\n", iface, ref + 1);
123
124     if (!ref)
125     {
126         CoTaskMemFree(This->ppMoniker);
127         This->ppMoniker = NULL;
128         CoTaskMemFree(This);
129         return 0;
130     }
131     return ref;
132 }
133
134 static HRESULT WINAPI EnumMonikerImpl_Next(LPENUMMONIKER iface, ULONG celt, IMoniker ** rgelt, ULONG * pceltFetched)
135 {
136     ULONG fetched;
137     EnumMonikerImpl *This = (EnumMonikerImpl *)iface;
138
139     TRACE("(%p)->(%ld, %p, %p)\n", iface, celt, rgelt, pceltFetched);
140
141     for (fetched = 0; (This->index + fetched < This->nMonikerCount) && (fetched < celt); fetched++)
142     {
143         rgelt[fetched] = This->ppMoniker[This->index + fetched];
144         IMoniker_AddRef(rgelt[fetched]);
145     }
146
147     This->index += fetched;
148
149     TRACE("-- fetched %ld\n", fetched);
150
151     if (pceltFetched)
152         *pceltFetched = fetched;
153
154     if (fetched != celt)
155         return S_FALSE;
156     else
157         return S_OK;
158 }
159
160 static HRESULT WINAPI EnumMonikerImpl_Skip(LPENUMMONIKER iface, ULONG celt)
161 {
162     EnumMonikerImpl *This = (EnumMonikerImpl *)iface;
163
164     TRACE("(%p)->(%ld)\n", iface, celt);
165
166     This->index += celt;
167
168     return S_OK;
169 }
170
171 static HRESULT WINAPI EnumMonikerImpl_Reset(LPENUMMONIKER iface)
172 {
173     EnumMonikerImpl *This = (EnumMonikerImpl *)iface;
174
175     TRACE("(%p)->()\n", iface);
176
177     This->index = 0;
178
179     return S_OK;
180 }
181
182 static HRESULT WINAPI EnumMonikerImpl_Clone(LPENUMMONIKER iface, IEnumMoniker ** ppenum)
183 {
184     FIXME("(%p)->(%p): stub\n", iface, ppenum);
185
186     return E_NOTIMPL;
187 }
188
189 /**********************************************************************
190  * IEnumMoniker_Vtbl
191  */
192 static const IEnumMonikerVtbl EnumMonikerImpl_Vtbl =
193 {
194     EnumMonikerImpl_QueryInterface,
195     EnumMonikerImpl_AddRef,
196     EnumMonikerImpl_Release,
197     EnumMonikerImpl_Next,
198     EnumMonikerImpl_Skip,
199     EnumMonikerImpl_Reset,
200     EnumMonikerImpl_Clone
201 };