[PATCH 2/4] ole32: Implement IOleCache_EnumCache().

Huw Davies huw at codeweavers.com
Tue May 23 07:11:40 CDT 2017


Signed-off-by: Huw Davies <huw at codeweavers.com>
---
 dlls/ole32/compobj_private.h |  3 +++
 dlls/ole32/datacache.c       | 36 ++++++++++++++++++++++++++++++-----
 dlls/ole32/oleobj.c          | 45 +++++++++++++++++++++++++-------------------
 3 files changed, 60 insertions(+), 24 deletions(-)

diff --git a/dlls/ole32/compobj_private.h b/dlls/ole32/compobj_private.h
index 8bab8193b4..64b67826be 100644
--- a/dlls/ole32/compobj_private.h
+++ b/dlls/ole32/compobj_private.h
@@ -346,4 +346,7 @@ static inline HRESULT copy_formatetc(FORMATETC *dst, const FORMATETC *src)
     return S_OK;
 }
 
+extern HRESULT EnumSTATDATA_Construct(IUnknown *holder, ULONG index, DWORD array_len, STATDATA *data,
+                                      BOOL copy, IEnumSTATDATA **ppenum) DECLSPEC_HIDDEN;
+
 #endif /* __WINE_OLE_COMPOBJ_H */
diff --git a/dlls/ole32/datacache.c b/dlls/ole32/datacache.c
index a50c4fe6f6..5055c3ff95 100644
--- a/dlls/ole32/datacache.c
+++ b/dlls/ole32/datacache.c
@@ -2129,12 +2129,38 @@ static HRESULT WINAPI DataCache_Uncache(
     return OLE_E_NOCONNECTION;
 }
 
-static HRESULT WINAPI DataCache_EnumCache(
-            IOleCache2*     iface,
-	    IEnumSTATDATA** ppenumSTATDATA)
+static HRESULT WINAPI DataCache_EnumCache(IOleCache2 *iface,
+                                          IEnumSTATDATA **enum_stat)
 {
-  FIXME("stub\n");
-  return E_NOTIMPL;
+    DataCache *This = impl_from_IOleCache2( iface );
+    DataCacheEntry *cache_entry;
+    int i = 0, count = list_count( &This->cache_list );
+    STATDATA *data;
+    HRESULT hr;
+
+    TRACE( "(%p, %p)\n", This, enum_stat );
+
+    data = CoTaskMemAlloc( count * sizeof(*data) );
+    if (!data) return E_OUTOFMEMORY;
+
+    LIST_FOR_EACH_ENTRY( cache_entry, &This->cache_list, DataCacheEntry, entry )
+    {
+        if (i == count) break;
+        hr = copy_formatetc( &data[i].formatetc, &cache_entry->fmtetc );
+        if (FAILED(hr)) goto fail;
+        data[i].advf = cache_entry->advise_flags;
+        data[i].pAdvSink = NULL;
+        data[i].dwConnection = cache_entry->id;
+        i++;
+    }
+
+    hr = EnumSTATDATA_Construct( NULL, 0, i, data, FALSE, enum_stat );
+    if (SUCCEEDED(hr)) return hr;
+
+fail:
+    while (i--) CoTaskMemFree( data[i].formatetc.ptd );
+    CoTaskMemFree( data );
+    return hr;
 }
 
 static HRESULT WINAPI DataCache_InitCache(
diff --git a/dlls/ole32/oleobj.c b/dlls/ole32/oleobj.c
index 17ab8d0e14..44e15e551f 100644
--- a/dlls/ole32/oleobj.c
+++ b/dlls/ole32/oleobj.c
@@ -71,8 +71,6 @@ static HRESULT copy_statdata(STATDATA *dst, const STATDATA *src)
  *  EnumSTATDATA Implementation
  */
 
-static HRESULT EnumSTATDATA_Construct(IUnknown *holder, ULONG index, DWORD array_len, STATDATA *data, IEnumSTATDATA **ppenum);
-
 typedef struct
 {
     IEnumSTATDATA IEnumSTATDATA_iface;
@@ -120,7 +118,7 @@ static ULONG WINAPI EnumSTATDATA_Release(IEnumSTATDATA *iface)
         for(i = 0; i < This->num_of_elems; i++)
             release_statdata(This->statdata + i);
         HeapFree(GetProcessHeap(), 0, This->statdata);
-        IUnknown_Release(This->holder);
+        if (This->holder) IUnknown_Release(This->holder);
         HeapFree(GetProcessHeap(), 0, This);
     }
     return refs;
@@ -184,7 +182,8 @@ static HRESULT WINAPI EnumSTATDATA_Clone(IEnumSTATDATA *iface, IEnumSTATDATA **p
 {
     EnumSTATDATA *This = impl_from_IEnumSTATDATA(iface);
 
-    return EnumSTATDATA_Construct(This->holder, This->index, This->num_of_elems, This->statdata, ppenum);
+    return EnumSTATDATA_Construct(This->holder, This->index, This->num_of_elems, This->statdata,
+                                  TRUE, ppenum);
 }
 
 static const IEnumSTATDATAVtbl EnumSTATDATA_VTable =
@@ -198,8 +197,8 @@ static const IEnumSTATDATAVtbl EnumSTATDATA_VTable =
     EnumSTATDATA_Clone
 };
 
-static HRESULT EnumSTATDATA_Construct(IUnknown *holder, ULONG index, DWORD array_len, STATDATA *data,
-                                      IEnumSTATDATA **ppenum)
+HRESULT EnumSTATDATA_Construct(IUnknown *holder, ULONG index, DWORD array_len, STATDATA *data,
+                               BOOL copy, IEnumSTATDATA **ppenum)
 {
     EnumSTATDATA *This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
     DWORD i, count;
@@ -210,25 +209,33 @@ static HRESULT EnumSTATDATA_Construct(IUnknown *holder, ULONG index, DWORD array
     This->ref = 1;
     This->index = index;
 
-    This->statdata = HeapAlloc(GetProcessHeap(), 0, array_len * sizeof(*This->statdata));
-    if(!This->statdata)
+    if (copy)
     {
-        HeapFree(GetProcessHeap(), 0, This);
-        return E_OUTOFMEMORY;
-    }
+        This->statdata = HeapAlloc(GetProcessHeap(), 0, array_len * sizeof(*This->statdata));
+        if(!This->statdata)
+        {
+            HeapFree(GetProcessHeap(), 0, This);
+            return E_OUTOFMEMORY;
+        }
 
-    for(i = 0, count = 0; i < array_len; i++)
-    {
-        if(data[i].pAdvSink)
+        for(i = 0, count = 0; i < array_len; i++)
         {
-            copy_statdata(This->statdata + count, data + i);
-            count++;
+            if(data[i].pAdvSink)
+            {
+                copy_statdata(This->statdata + count, data + i);
+                count++;
+            }
         }
     }
+    else
+    {
+        This->statdata = data;
+        count = array_len;
+    }
 
     This->num_of_elems = count;
     This->holder = holder;
-    IUnknown_AddRef(holder);
+    if (holder) IUnknown_AddRef(holder);
     *ppenum = &This->IEnumSTATDATA_iface;
     return S_OK;
 }
@@ -403,7 +410,7 @@ static HRESULT WINAPI OleAdviseHolderImpl_EnumAdvise(IOleAdviseHolder *iface, IE
     TRACE("(%p)->(%p)\n", This, enum_advise);
 
     IOleAdviseHolder_QueryInterface(iface, &IID_IUnknown, (void**)&unk);
-    hr = EnumSTATDATA_Construct(unk, 0, This->max_cons, This->connections, enum_advise);
+    hr = EnumSTATDATA_Construct(unk, 0, This->max_cons, This->connections, TRUE, enum_advise);
     IUnknown_Release(unk);
     return hr;
 }
@@ -737,7 +744,7 @@ static HRESULT WINAPI DataAdviseHolder_EnumAdvise(IDataAdviseHolder *iface,
     TRACE("(%p)->(%p)\n", This, enum_advise);
 
     IDataAdviseHolder_QueryInterface(iface, &IID_IUnknown, (void**)&unk);
-    hr = EnumSTATDATA_Construct(unk, 0, This->maxCons, This->connections, enum_advise);
+    hr = EnumSTATDATA_Construct(unk, 0, This->maxCons, This->connections, TRUE, enum_advise);
     IUnknown_Release(unk);
     return hr;
 }
-- 
2.12.0




More information about the wine-patches mailing list