Mike McCormack : ole32: Add a framework for implementing IEnum* interfaces.

Alexandre Julliard julliard at wine.codeweavers.com
Wed Jul 12 06:53:42 CDT 2006


Module: wine
Branch: master
Commit: 127ae2bf8b80c7f2b4a9d61fe6c318f1464ab585
URL:    http://source.winehq.org/git/?p=wine.git;a=commit;h=127ae2bf8b80c7f2b4a9d61fe6c318f1464ab585

Author: Mike McCormack <mike at codeweavers.com>
Date:   Tue Jul 11 16:12:38 2006 +0900

ole32: Add a framework for implementing IEnum* interfaces.

---

 dlls/ole32/Makefile.in |    1 
 dlls/ole32/enumx.c     |  202 ++++++++++++++++++++++++++++++++++++++++++++++++
 dlls/ole32/enumx.h     |   34 ++++++++
 3 files changed, 237 insertions(+), 0 deletions(-)
 create mode 100644 dlls/ole32/enumx.c
 create mode 100644 dlls/ole32/enumx.h

diff --git a/dlls/ole32/Makefile.in b/dlls/ole32/Makefile.in
index 01b7ea6..0a44570 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 0000000..c928e4e
--- /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 <stdarg.h>
+
+#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 0000000..2d36b73
--- /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




More information about the wine-cvs mailing list