diff --git a/dlls/ole32/Makefile.in b/dlls/ole32/Makefile.in index 01b7ea6433e..0a445708b20 100644 --- a/dlls/ole32/Makefile.in +++ b/dlls/ole32/Makefile.in @@ -18,6 +18,7 @@ C_SRCS = \ datacache.c \ defaulthandler.c \ dictionary.c \ + enumx.c \ errorinfo.c \ filemoniker.c \ ftmarshal.c \ diff --git a/dlls/ole32/enumx.c b/dlls/ole32/enumx.c new file mode 100644 index 00000000000..c928e4eb075 --- /dev/null +++ b/dlls/ole32/enumx.c @@ -0,0 +1,202 @@ +/* + * IEnum* implementation + * + * Copyright 2006 Mike McCormack + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define COBJMACROS + +#include + +#include "windef.h" +#include "winbase.h" +#include "objbase.h" +#include "wine/list.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(ole); + +typedef struct tagEnumSTATPROPSETSTG_impl +{ + const void *vtbl; + LONG ref; + struct list elements; + struct list *current; + ULONG elem_size; + GUID riid; +} enumx_impl; + +/************************************************************************ + * enumx_QueryInterface + */ +HRESULT WINAPI enumx_QueryInterface( + enumx_impl *This, + REFIID riid, + void** ppvObject) +{ + if ( (This==0) || (ppvObject==0) ) + return E_INVALIDARG; + + *ppvObject = 0; + + if (IsEqualGUID(&IID_IUnknown, riid) || + IsEqualGUID(&This->riid, riid)) + { + IUnknown_AddRef(((IUnknown*)This)); + *ppvObject = This; + return S_OK; + } + + return E_NOINTERFACE; +} + +/************************************************************************ + * enumx_AddRef + */ +ULONG WINAPI enumx_AddRef(enumx_impl *This) +{ + return InterlockedIncrement(&This->ref); +} + +/************************************************************************ + * enumx_Release + */ +ULONG WINAPI enumx_Release(enumx_impl *This) +{ + ULONG ref; + + ref = InterlockedDecrement(&This->ref); + if (ref == 0) + { + while (!list_empty(&This->elements)) + { + struct list *x = list_head(&This->elements); + list_remove(x); + HeapFree(GetProcessHeap(), 0, x); + } + HeapFree(GetProcessHeap(), 0, This); + } + return ref; +} + +/************************************************************************ + * enumx_Next + */ +HRESULT WINAPI enumx_Next(enumx_impl *This, ULONG celt, + void *rgelt, ULONG *pceltFetched) +{ + unsigned char *p; + ULONG count = 0; + + TRACE("%p %lu %p\n", This, celt, pceltFetched); + + if (This->current == NULL) + This->current = list_head(&This->elements); + p = rgelt; + while (count < celt && This->current && This->current != &This->elements) + { + memcpy(p, &This->current[1], This->elem_size); + p += This->elem_size; + This->current = This->current->next; + count++; + } + if (pceltFetched) + *pceltFetched = count; + if (count < celt) + return S_FALSE; + return S_OK; +} + +/************************************************************************ + * enumx_Skip + */ +HRESULT WINAPI enumx_Skip(enumx_impl *This, ULONG celt) +{ + ULONG count = 0; + + TRACE("%p %lu\n", This, celt); + + if (This->current == NULL) + This->current = list_head(&This->elements); + + while (count < celt && This->current && This->current != &This->elements) + count++; + + return S_OK; +} + +/************************************************************************ + * enumx_Reset + */ +HRESULT WINAPI enumx_Reset(enumx_impl *This) +{ + TRACE("\n"); + + This->current = NULL; + return S_OK; +} + +/************************************************************************ + * enumx_fnClone + */ +HRESULT WINAPI enumx_Clone( + enumx_impl *iface, + enumx_impl **ppenum) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +/************************************************************************ + * enumx_allocate + * + * Allocate a generic enumerator + */ +enumx_impl *enumx_allocate(REFIID riid, const void *vtbl, ULONG elem_size) +{ + enumx_impl *enumx; + + enumx = HeapAlloc(GetProcessHeap(), 0, sizeof *enumx); + if (enumx) + { + enumx->vtbl = vtbl; + enumx->ref = 1; + enumx->current = NULL; + enumx->elem_size = elem_size; + memcpy(&enumx->riid, riid, sizeof *riid); + list_init(&enumx->elements); + } + + return enumx; +} + +/************************************************************************ + * enumx_add_element + * + * Add an element to the enumeration. + */ +void *enumx_add_element(enumx_impl *enumx, void *data) +{ + struct list *element; + + element = HeapAlloc(GetProcessHeap(), 0, sizeof *element + enumx->elem_size); + if (!element) + return NULL; + memcpy(&element[1], data, enumx->elem_size); + list_add_tail(&enumx->elements, element); + return &element[1]; +} diff --git a/dlls/ole32/enumx.h b/dlls/ole32/enumx.h new file mode 100644 index 00000000000..2d36b732549 --- /dev/null +++ b/dlls/ole32/enumx.h @@ -0,0 +1,34 @@ +/* + * Copyright 2006 Mike McCormack + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef __OLE_ENUM_H__ +#define __OLE_ENUM_H__ + +typedef struct tagEnumSTATPROPSETSTG_impl enumx_impl; + +extern HRESULT WINAPI enumx_QueryInterface(enumx_impl *, REFIID, void**); +extern ULONG WINAPI enumx_AddRef(enumx_impl *); +extern ULONG WINAPI enumx_Release(enumx_impl *); +extern HRESULT WINAPI enumx_Next(enumx_impl *, ULONG, void *, ULONG *); +extern HRESULT WINAPI enumx_Skip(enumx_impl *, ULONG); +extern HRESULT WINAPI enumx_Reset(enumx_impl *); +extern HRESULT WINAPI enumx_Clone(enumx_impl *, enumx_impl **); +extern enumx_impl *enumx_allocate(REFIID, const void *, ULONG); +extern void *enumx_add_element(enumx_impl *, void *); + +#endif