[PATCH] ole32: Add separate IEnumSTATPROPSTG implementation.

Nikolay Sivov nsivov at codeweavers.com
Mon Nov 11 01:39:23 CST 2019


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/ole32/Makefile.in |   1 -
 dlls/ole32/enumx.c     | 205 ------------------------------
 dlls/ole32/enumx.h     |  34 -----
 dlls/ole32/stg_prop.c  | 281 +++++++++++++++++++++++++----------------
 4 files changed, 175 insertions(+), 346 deletions(-)
 delete mode 100644 dlls/ole32/enumx.c
 delete mode 100644 dlls/ole32/enumx.h

diff --git a/dlls/ole32/Makefile.in b/dlls/ole32/Makefile.in
index 32de987a8c..310f6fc119 100644
--- a/dlls/ole32/Makefile.in
+++ b/dlls/ole32/Makefile.in
@@ -17,7 +17,6 @@ C_SRCS = \
 	datacache.c \
 	defaulthandler.c \
 	dictionary.c \
-	enumx.c \
 	errorinfo.c \
 	filelockbytes.c \
 	filemoniker.c \
diff --git a/dlls/ole32/enumx.c b/dlls/ole32/enumx.c
deleted file mode 100644
index 4279ca81fa..0000000000
--- a/dlls/ole32/enumx.c
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * 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 "enumx.h"
-
-#include "wine/list.h"
-#include "wine/debug.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(ole);
-
-struct tagEnumSTATPROPSETSTG_impl
-{
-    const void *vtbl;
-    LONG ref;
-    struct list elements;
-    struct list *current;
-    ULONG elem_size;
-    GUID riid;
-};
-
-/************************************************************************
- * enumx_QueryInterface
- */
-HRESULT WINAPI enumx_QueryInterface(
-    enumx_impl *This,
-    REFIID riid,
-    void** ppvObject)
-{
-    if ( 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 %u %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 %u\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;
-        enumx->riid = *riid;
-        list_init(&enumx->elements);
-    }
-
-    return enumx;
-}
-
-/************************************************************************
- * enumx_add_element
- *
- * Add an element to the enumeration.
- */
-void *enumx_add_element(enumx_impl *enumx, const 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
deleted file mode 100644
index da76e13769..0000000000
--- a/dlls/ole32/enumx.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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**) DECLSPEC_HIDDEN;
-extern ULONG WINAPI enumx_AddRef(enumx_impl *) DECLSPEC_HIDDEN;
-extern ULONG WINAPI enumx_Release(enumx_impl *) DECLSPEC_HIDDEN;
-extern HRESULT WINAPI enumx_Next(enumx_impl *, ULONG, void *, ULONG *) DECLSPEC_HIDDEN;
-extern HRESULT WINAPI enumx_Skip(enumx_impl *, ULONG) DECLSPEC_HIDDEN;
-extern HRESULT WINAPI enumx_Reset(enumx_impl *) DECLSPEC_HIDDEN;
-extern HRESULT WINAPI enumx_Clone(enumx_impl *, enumx_impl **) DECLSPEC_HIDDEN;
-extern enumx_impl *enumx_allocate(REFIID, const void *, ULONG) DECLSPEC_HIDDEN;
-extern void *enumx_add_element(enumx_impl *, const void *) DECLSPEC_HIDDEN;
-
-#endif
diff --git a/dlls/ole32/stg_prop.c b/dlls/ole32/stg_prop.c
index 2e43d16b35..70b8cd3b0e 100644
--- a/dlls/ole32/stg_prop.c
+++ b/dlls/ole32/stg_prop.c
@@ -10,6 +10,7 @@
  * Copyright 1999 Thuy Nguyen
  * Copyright 2005 Mike McCormack
  * Copyright 2005 Juan Lang
+ * 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
@@ -54,7 +55,6 @@
 #include "wine/heap.h"
 #include "dictionary.h"
 #include "storage32.h"
-#include "enumx.h"
 #include "oleauto.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(storage);
@@ -143,8 +143,6 @@ static HRESULT PropertyStorage_StringCopy(LPCSTR src, LCID srcCP, LPSTR *dst,
  LCID targetCP);
 
 static const IPropertyStorageVtbl IPropertyStorage_Vtbl;
-static const IEnumSTATPROPSTGVtbl IEnumSTATPROPSTG_Vtbl;
-static HRESULT create_EnumSTATPROPSTG(PropertyStorage_impl *, IEnumSTATPROPSTG**);
 
 /***********************************************************************
  * Implementation of IPropertyStorage
@@ -175,6 +173,174 @@ static inline PropertyStorage_impl *impl_from_IPropertyStorage(IPropertyStorage
     return CONTAINING_RECORD(iface, PropertyStorage_impl, IPropertyStorage_iface);
 }
 
+struct enum_stat_prop_stg
+{
+    IEnumSTATPROPSTG IEnumSTATPROPSTG_iface;
+    LONG refcount;
+    STATPROPSTG *stats;
+    size_t current;
+    size_t count;
+};
+
+static struct enum_stat_prop_stg *impl_from_IEnumSTATPROPSTG(IEnumSTATPROPSTG *iface)
+{
+    return CONTAINING_RECORD(iface, struct enum_stat_prop_stg, IEnumSTATPROPSTG_iface);
+}
+
+static HRESULT WINAPI enum_stat_prop_stg_QueryInterface(IEnumSTATPROPSTG *iface, REFIID riid, void **obj)
+{
+    TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj);
+
+    if (IsEqualIID(riid, &IID_IEnumSTATPROPSTG) ||
+            IsEqualIID(riid, &IID_IUnknown))
+    {
+        *obj = iface;
+        IEnumSTATPROPSTG_AddRef(iface);
+        return S_OK;
+    }
+
+    WARN("Unsupported interface %s.\n", debugstr_guid(riid));
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI enum_stat_prop_stg_AddRef(IEnumSTATPROPSTG *iface)
+{
+    struct enum_stat_prop_stg *penum = impl_from_IEnumSTATPROPSTG(iface);
+    LONG refcount = InterlockedIncrement(&penum->refcount);
+
+    TRACE("%p, refcount %u.\n", iface, refcount);
+
+    return refcount;
+}
+
+static ULONG WINAPI enum_stat_prop_stg_Release(IEnumSTATPROPSTG *iface)
+{
+    struct enum_stat_prop_stg *penum = impl_from_IEnumSTATPROPSTG(iface);
+    LONG refcount = InterlockedDecrement(&penum->refcount);
+
+    TRACE("%p, refcount %u.\n", iface, refcount);
+
+    if (!refcount)
+    {
+        heap_free(penum->stats);
+        heap_free(penum);
+    }
+
+    return refcount;
+}
+
+static HRESULT WINAPI enum_stat_prop_stg_Next(IEnumSTATPROPSTG *iface, ULONG celt, STATPROPSTG *ret, ULONG *fetched)
+{
+    struct enum_stat_prop_stg *penum = impl_from_IEnumSTATPROPSTG(iface);
+    ULONG count = 0;
+
+    TRACE("%p, %u, %p, %p.\n", iface, celt, ret, fetched);
+
+    if (penum->current == ~0u)
+        penum->current = 0;
+
+    while (count < celt && penum->current < penum->count)
+        ret[count++] = penum->stats[penum->current++];
+
+    if (fetched)
+        *fetched = count;
+
+    return count < celt ? S_FALSE : S_OK;
+}
+
+static HRESULT WINAPI enum_stat_prop_stg_Skip(IEnumSTATPROPSTG *iface, ULONG celt)
+{
+    FIXME("%p, %u.\n", iface, celt);
+
+    return S_OK;
+}
+
+static HRESULT WINAPI enum_stat_prop_stg_Reset(IEnumSTATPROPSTG *iface)
+{
+    struct enum_stat_prop_stg *penum = impl_from_IEnumSTATPROPSTG(iface);
+
+    TRACE("%p.\n", iface);
+
+    penum->current = ~0u;
+
+    return S_OK;
+}
+
+static HRESULT WINAPI enum_stat_prop_stg_Clone(IEnumSTATPROPSTG *iface, IEnumSTATPROPSTG **ppenum)
+{
+    FIXME("%p, %p.\n", iface, ppenum);
+
+    return E_NOTIMPL;
+}
+
+static const IEnumSTATPROPSTGVtbl enum_stat_prop_stg_vtbl =
+{
+    enum_stat_prop_stg_QueryInterface,
+    enum_stat_prop_stg_AddRef,
+    enum_stat_prop_stg_Release,
+    enum_stat_prop_stg_Next,
+    enum_stat_prop_stg_Skip,
+    enum_stat_prop_stg_Reset,
+    enum_stat_prop_stg_Clone,
+};
+
+static BOOL prop_enum_stat(const void *k, const void *v, void *extra, void *arg)
+{
+    struct enum_stat_prop_stg *stg = arg;
+    PROPID propid = PtrToUlong(k);
+    const PROPVARIANT *prop = v;
+    STATPROPSTG *dest;
+
+    dest = &stg->stats[stg->count];
+
+    dest->lpwstrName = NULL;
+    dest->propid = propid;
+    dest->vt = prop->vt;
+    stg->count++;
+
+    return TRUE;
+}
+
+static BOOL prop_enum_stat_count(const void *k, const void *v, void *extra, void *arg)
+{
+    DWORD *count = arg;
+
+    *count += 1;
+
+    return TRUE;
+}
+
+static HRESULT create_enum_stat_prop_stg(PropertyStorage_impl *storage, IEnumSTATPROPSTG **ret)
+{
+    struct enum_stat_prop_stg *enum_obj;
+    DWORD count;
+
+    enum_obj = heap_alloc_zero(sizeof(*enum_obj));
+    if (!enum_obj)
+        return E_OUTOFMEMORY;
+
+    enum_obj->IEnumSTATPROPSTG_iface.lpVtbl = &enum_stat_prop_stg_vtbl;
+    enum_obj->refcount = 1;
+
+    count = 0;
+    dictionary_enumerate(storage->propid_to_prop, prop_enum_stat_count, &count);
+
+    if (count)
+    {
+        if (!(enum_obj->stats = heap_alloc(sizeof(*enum_obj->stats) * count)))
+        {
+            IEnumSTATPROPSTG_Release(&enum_obj->IEnumSTATPROPSTG_iface);
+            return E_OUTOFMEMORY;
+        }
+
+        dictionary_enumerate(storage->propid_to_prop, prop_enum_stat, enum_obj);
+    }
+
+    *ret = &enum_obj->IEnumSTATPROPSTG_iface;
+
+    return S_OK;
+}
+
 /************************************************************************
  * IPropertyStorage_fnQueryInterface (IPropertyStorage)
  */
@@ -853,12 +1019,13 @@ static HRESULT WINAPI IPropertyStorage_fnRevert(
 /************************************************************************
  * IPropertyStorage_fnEnum (IPropertyStorage)
  */
-static HRESULT WINAPI IPropertyStorage_fnEnum(
-    IPropertyStorage* iface,
-    IEnumSTATPROPSTG** ppenum)
+static HRESULT WINAPI IPropertyStorage_fnEnum(IPropertyStorage *iface, IEnumSTATPROPSTG **ppenum)
 {
-    PropertyStorage_impl *This = impl_from_IPropertyStorage(iface);
-    return create_EnumSTATPROPSTG(This, ppenum);
+    PropertyStorage_impl *storage = impl_from_IPropertyStorage(iface);
+
+    TRACE("%p, %p.\n", iface, ppenum);
+
+    return create_enum_stat_prop_stg(storage, ppenum);
 }
 
 /************************************************************************
@@ -2516,93 +2683,6 @@ static HRESULT WINAPI IPropertySetStorage_fnEnum(IPropertySetStorage *iface, IEn
     return create_enum_stat_propset_stg(storage, enum_obj);
 }
 
-/************************************************************************
- * Implement IEnumSTATPROPSTG using enumx
- */
-static HRESULT WINAPI IEnumSTATPROPSTG_fnQueryInterface(
-    IEnumSTATPROPSTG *iface,
-    REFIID riid,
-    void** ppvObject)
-{
-    return enumx_QueryInterface((enumx_impl*)iface, riid, ppvObject);
-}
-
-static ULONG WINAPI IEnumSTATPROPSTG_fnAddRef(
-    IEnumSTATPROPSTG *iface)
-{
-    return enumx_AddRef((enumx_impl*)iface);
-}
-
-static ULONG WINAPI IEnumSTATPROPSTG_fnRelease(
-    IEnumSTATPROPSTG *iface)
-{
-    return enumx_Release((enumx_impl*)iface);
-}
-
-static HRESULT WINAPI IEnumSTATPROPSTG_fnNext(
-    IEnumSTATPROPSTG *iface,
-    ULONG celt,
-    STATPROPSTG *rgelt,
-    ULONG *pceltFetched)
-{
-    return enumx_Next((enumx_impl*)iface, celt, rgelt, pceltFetched);
-}
-
-static HRESULT WINAPI IEnumSTATPROPSTG_fnSkip(
-    IEnumSTATPROPSTG *iface,
-    ULONG celt)
-{
-    return enumx_Skip((enumx_impl*)iface, celt);
-}
-
-static HRESULT WINAPI IEnumSTATPROPSTG_fnReset(
-    IEnumSTATPROPSTG *iface)
-{
-    return enumx_Reset((enumx_impl*)iface);
-}
-
-static HRESULT WINAPI IEnumSTATPROPSTG_fnClone(
-    IEnumSTATPROPSTG *iface,
-    IEnumSTATPROPSTG **ppenum)
-{
-    return enumx_Clone((enumx_impl*)iface, (enumx_impl**)ppenum);
-}
-
-static BOOL prop_enum_stat(const void *k, const void *v, void *extra, void *arg)
-{
-    enumx_impl *enumx = arg;
-    PROPID propid = PtrToUlong(k);
-    const PROPVARIANT *prop = v;
-    STATPROPSTG stat;
-
-    stat.lpwstrName = NULL;
-    stat.propid = propid;
-    stat.vt = prop->vt;
-
-    enumx_add_element(enumx, &stat);
-
-    return TRUE;
-}
-
-static HRESULT create_EnumSTATPROPSTG(
-    PropertyStorage_impl *This,
-    IEnumSTATPROPSTG** ppenum)
-{
-    enumx_impl *enumx;
-
-    TRACE("%p %p\n", This, ppenum);
-
-    enumx = enumx_allocate(&IID_IEnumSTATPROPSTG,
-                           &IEnumSTATPROPSTG_Vtbl,
-                           sizeof (STATPROPSTG));
-
-    dictionary_enumerate(This->propid_to_prop, prop_enum_stat, enumx);
-
-    *ppenum = (IEnumSTATPROPSTG*) enumx;
-
-    return S_OK;
-}
-
 /***********************************************************************
  * vtables
  */
@@ -2636,17 +2716,6 @@ static const IPropertyStorageVtbl IPropertyStorage_Vtbl =
     IPropertyStorage_fnStat,
 };
 
-static const IEnumSTATPROPSTGVtbl IEnumSTATPROPSTG_Vtbl =
-{
-    IEnumSTATPROPSTG_fnQueryInterface,
-    IEnumSTATPROPSTG_fnAddRef,
-    IEnumSTATPROPSTG_fnRelease,
-    IEnumSTATPROPSTG_fnNext,
-    IEnumSTATPROPSTG_fnSkip,
-    IEnumSTATPROPSTG_fnReset,
-    IEnumSTATPROPSTG_fnClone,
-};
-
 /***********************************************************************
  * Format ID <-> name conversion
  */
-- 
2.24.0




More information about the wine-devel mailing list