ole32: Implement IOleCache_EnumCache().

Signed-off-by: Huw Davies <huw@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Huw Davies 2017-05-23 13:11:40 +01:00 committed by Alexandre Julliard
parent f9b0f60ae3
commit 20a8f1adf4
3 changed files with 61 additions and 25 deletions

View File

@ -346,4 +346,7 @@ static inline HRESULT copy_formatetc(FORMATETC *dst, const FORMATETC *src)
return S_OK; 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 */ #endif /* __WINE_OLE_COMPOBJ_H */

View File

@ -2129,12 +2129,38 @@ static HRESULT WINAPI DataCache_Uncache(
return OLE_E_NOCONNECTION; return OLE_E_NOCONNECTION;
} }
static HRESULT WINAPI DataCache_EnumCache( static HRESULT WINAPI DataCache_EnumCache(IOleCache2 *iface,
IOleCache2* iface, IEnumSTATDATA **enum_stat)
IEnumSTATDATA** ppenumSTATDATA)
{ {
FIXME("stub\n"); DataCache *This = impl_from_IOleCache2( iface );
return E_NOTIMPL; 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( static HRESULT WINAPI DataCache_InitCache(

View File

@ -71,8 +71,6 @@ static HRESULT copy_statdata(STATDATA *dst, const STATDATA *src)
* EnumSTATDATA Implementation * EnumSTATDATA Implementation
*/ */
static HRESULT EnumSTATDATA_Construct(IUnknown *holder, ULONG index, DWORD array_len, STATDATA *data, IEnumSTATDATA **ppenum);
typedef struct typedef struct
{ {
IEnumSTATDATA IEnumSTATDATA_iface; IEnumSTATDATA IEnumSTATDATA_iface;
@ -120,7 +118,7 @@ static ULONG WINAPI EnumSTATDATA_Release(IEnumSTATDATA *iface)
for(i = 0; i < This->num_of_elems; i++) for(i = 0; i < This->num_of_elems; i++)
release_statdata(This->statdata + i); release_statdata(This->statdata + i);
HeapFree(GetProcessHeap(), 0, This->statdata); HeapFree(GetProcessHeap(), 0, This->statdata);
IUnknown_Release(This->holder); if (This->holder) IUnknown_Release(This->holder);
HeapFree(GetProcessHeap(), 0, This); HeapFree(GetProcessHeap(), 0, This);
} }
return refs; return refs;
@ -184,7 +182,8 @@ static HRESULT WINAPI EnumSTATDATA_Clone(IEnumSTATDATA *iface, IEnumSTATDATA **p
{ {
EnumSTATDATA *This = impl_from_IEnumSTATDATA(iface); 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 = static const IEnumSTATDATAVtbl EnumSTATDATA_VTable =
@ -198,8 +197,8 @@ static const IEnumSTATDATAVtbl EnumSTATDATA_VTable =
EnumSTATDATA_Clone EnumSTATDATA_Clone
}; };
static HRESULT EnumSTATDATA_Construct(IUnknown *holder, ULONG index, DWORD array_len, STATDATA *data, HRESULT EnumSTATDATA_Construct(IUnknown *holder, ULONG index, DWORD array_len, STATDATA *data,
IEnumSTATDATA **ppenum) BOOL copy, IEnumSTATDATA **ppenum)
{ {
EnumSTATDATA *This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This)); EnumSTATDATA *This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
DWORD i, count; DWORD i, count;
@ -210,25 +209,33 @@ static HRESULT EnumSTATDATA_Construct(IUnknown *holder, ULONG index, DWORD array
This->ref = 1; This->ref = 1;
This->index = index; This->index = index;
This->statdata = HeapAlloc(GetProcessHeap(), 0, array_len * sizeof(*This->statdata)); if (copy)
if(!This->statdata)
{ {
HeapFree(GetProcessHeap(), 0, This); This->statdata = HeapAlloc(GetProcessHeap(), 0, array_len * sizeof(*This->statdata));
return E_OUTOFMEMORY; if(!This->statdata)
}
for(i = 0, count = 0; i < array_len; i++)
{
if(data[i].pAdvSink)
{ {
copy_statdata(This->statdata + count, data + i); HeapFree(GetProcessHeap(), 0, This);
count++; return E_OUTOFMEMORY;
} }
for(i = 0, count = 0; i < array_len; i++)
{
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->num_of_elems = count;
This->holder = holder; This->holder = holder;
IUnknown_AddRef(holder); if (holder) IUnknown_AddRef(holder);
*ppenum = &This->IEnumSTATDATA_iface; *ppenum = &This->IEnumSTATDATA_iface;
return S_OK; return S_OK;
} }
@ -403,7 +410,7 @@ static HRESULT WINAPI OleAdviseHolderImpl_EnumAdvise(IOleAdviseHolder *iface, IE
TRACE("(%p)->(%p)\n", This, enum_advise); TRACE("(%p)->(%p)\n", This, enum_advise);
IOleAdviseHolder_QueryInterface(iface, &IID_IUnknown, (void**)&unk); 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); IUnknown_Release(unk);
return hr; return hr;
} }
@ -737,7 +744,7 @@ static HRESULT WINAPI DataAdviseHolder_EnumAdvise(IDataAdviseHolder *iface,
TRACE("(%p)->(%p)\n", This, enum_advise); TRACE("(%p)->(%p)\n", This, enum_advise);
IDataAdviseHolder_QueryInterface(iface, &IID_IUnknown, (void**)&unk); 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); IUnknown_Release(unk);
return hr; return hr;
} }