On Fri, Mar 30, 2018 at 12:11:33PM -0500, Sergio Gómez Del Real wrote:
Signed-off-by: Sergio Gómez Del Real <sdelreal(a)codeweavers.com> --- dlls/ole32/datacache.c | 185 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 122 insertions(+), 63 deletions(-)
diff --git a/dlls/ole32/datacache.c b/dlls/ole32/datacache.c index 325a98b33b..799e14a867 100644 --- a/dlls/ole32/datacache.c +++ b/dlls/ole32/datacache.c @@ -701,7 +764,62 @@ fail: GlobalUnlock( hglobal ); GlobalFree( hglobal ); return E_FAIL; +}
+static HRESULT load_emf( DataCacheEntry *cache_entry, IStream *stm ) +{ + HRESULT hr; + + if (cache_entry->load_stream_num != STREAM_NUMBER_CONTENTS) + { + STGMEDIUM stgmed; + + hr = load_mf_pict( cache_entry, stm ); + if (SUCCEEDED( hr )) + hr = synthesize_emf( cache_entry->stgmedium.u.hMetaFilePict, &stgmed ); + if (SUCCEEDED( hr )) + { + ReleaseStgMedium( &cache_entry->stgmedium );
I think we want to release this even if synthesize_emf fails, otherwise we'll be stuck with a mfpict in there, that will likely confuse things later on.
+ hr = copy_stg_medium( CF_ENHMETAFILE, &cache_entry->stgmedium, &stgmed ); + ReleaseStgMedium( &stgmed );
I didn't mean a deep copy here. Just &cache_entry->stgmedium = stgmed; would do.
+ } + } + else + { + STATSTG stat; + void *data;
If data were a BYTE * you won't need the cast later on.
+ DWORD size_bits; + ULONG read; + + hr = IStream_Stat( stm, &stat, STATFLAG_NONAME ); + + if (SUCCEEDED( hr )) + { + data = HeapAlloc( GetProcessHeap(), 0, stat.cbSize.u.LowPart ); + if (!data) return E_OUTOFMEMORY; + + hr = IStream_Read( stm, data, stat.cbSize.u.LowPart, &read ); + if (hr != S_OK || read != stat.cbSize.u.LowPart) + { + HeapFree( GetProcessHeap(), 0, data ); + return E_FAIL; + } + + size_bits = read - sizeof(DWORD) - sizeof(ENHMETAHEADER); + if (size_bits <= 0) + { + HeapFree( GetProcessHeap(), 0, data ); + return E_FAIL; + } + cache_entry->stgmedium.u.hEnhMetaFile = SetEnhMetaFileBits( size_bits, (BYTE *)data + (read - size_bits) ); + cache_entry->stgmedium.tymed = TYMED_ENHMF; + cache_entry->stgmedium.pUnkForRelease = NULL; + + HeapFree( GetProcessHeap(), 0, data ); + } + } + + return hr; }