push 73336d9f381967eae40f391d78198b916ed9848d
[wine/hacks.git] / dlls / ole32 / enumx.c
blobea850926f15386dd077be38dc8c2282cad42ec9b
1 /*
2 * IEnum* implementation
4 * Copyright 2006 Mike McCormack
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 #define COBJMACROS
23 #include <stdarg.h>
25 #include "windef.h"
26 #include "winbase.h"
27 #include "objbase.h"
28 #include "wine/list.h"
29 #include "wine/debug.h"
31 WINE_DEFAULT_DEBUG_CHANNEL(ole);
33 typedef struct tagEnumSTATPROPSETSTG_impl
35 const void *vtbl;
36 LONG ref;
37 struct list elements;
38 struct list *current;
39 ULONG elem_size;
40 GUID riid;
41 } enumx_impl;
43 /************************************************************************
44 * enumx_QueryInterface
46 HRESULT WINAPI enumx_QueryInterface(
47 enumx_impl *This,
48 REFIID riid,
49 void** ppvObject)
51 if ( (This==0) || (ppvObject==0) )
52 return E_INVALIDARG;
54 *ppvObject = 0;
56 if (IsEqualGUID(&IID_IUnknown, riid) ||
57 IsEqualGUID(&This->riid, riid))
59 IUnknown_AddRef(((IUnknown*)This));
60 *ppvObject = This;
61 return S_OK;
64 return E_NOINTERFACE;
67 /************************************************************************
68 * enumx_AddRef
70 ULONG WINAPI enumx_AddRef(enumx_impl *This)
72 return InterlockedIncrement(&This->ref);
75 /************************************************************************
76 * enumx_Release
78 ULONG WINAPI enumx_Release(enumx_impl *This)
80 ULONG ref;
82 ref = InterlockedDecrement(&This->ref);
83 if (ref == 0)
85 while (!list_empty(&This->elements))
87 struct list *x = list_head(&This->elements);
88 list_remove(x);
89 HeapFree(GetProcessHeap(), 0, x);
91 HeapFree(GetProcessHeap(), 0, This);
93 return ref;
96 /************************************************************************
97 * enumx_Next
99 HRESULT WINAPI enumx_Next(enumx_impl *This, ULONG celt,
100 void *rgelt, ULONG *pceltFetched)
102 unsigned char *p;
103 ULONG count = 0;
105 TRACE("%p %u %p\n", This, celt, pceltFetched);
107 if (This->current == NULL)
108 This->current = list_head(&This->elements);
109 p = rgelt;
110 while (count < celt && This->current && This->current != &This->elements)
112 memcpy(p, &This->current[1], This->elem_size);
113 p += This->elem_size;
114 This->current = This->current->next;
115 count++;
117 if (pceltFetched)
118 *pceltFetched = count;
119 if (count < celt)
120 return S_FALSE;
121 return S_OK;
124 /************************************************************************
125 * enumx_Skip
127 HRESULT WINAPI enumx_Skip(enumx_impl *This, ULONG celt)
129 ULONG count = 0;
131 TRACE("%p %u\n", This, celt);
133 if (This->current == NULL)
134 This->current = list_head(&This->elements);
136 while (count < celt && This->current && This->current != &This->elements)
137 count++;
139 return S_OK;
142 /************************************************************************
143 * enumx_Reset
145 HRESULT WINAPI enumx_Reset(enumx_impl *This)
147 TRACE("\n");
149 This->current = NULL;
150 return S_OK;
153 /************************************************************************
154 * enumx_fnClone
156 HRESULT WINAPI enumx_Clone(
157 enumx_impl *iface,
158 enumx_impl **ppenum)
160 FIXME("\n");
161 return E_NOTIMPL;
164 /************************************************************************
165 * enumx_allocate
167 * Allocate a generic enumerator
169 enumx_impl *enumx_allocate(REFIID riid, const void *vtbl, ULONG elem_size)
171 enumx_impl *enumx;
173 enumx = HeapAlloc(GetProcessHeap(), 0, sizeof *enumx);
174 if (enumx)
176 enumx->vtbl = vtbl;
177 enumx->ref = 1;
178 enumx->current = NULL;
179 enumx->elem_size = elem_size;
180 enumx->riid = *riid;
181 list_init(&enumx->elements);
184 return enumx;
187 /************************************************************************
188 * enumx_add_element
190 * Add an element to the enumeration.
192 void *enumx_add_element(enumx_impl *enumx, const void *data)
194 struct list *element;
196 element = HeapAlloc(GetProcessHeap(), 0, sizeof *element + enumx->elem_size);
197 if (!element)
198 return NULL;
199 memcpy(&element[1], data, enumx->elem_size);
200 list_add_tail(&enumx->elements, element);
201 return &element[1];