Signed-off-by: Sergio Gómez Del Real sdelreal@codeweavers.com --- dlls/ole32/datacache.c | 184 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 121 insertions(+), 63 deletions(-)
diff --git a/dlls/ole32/datacache.c b/dlls/ole32/datacache.c index 325a98b33b..3d97473c10 100644 --- a/dlls/ole32/datacache.c +++ b/dlls/ole32/datacache.c @@ -459,6 +459,45 @@ static void DataCache_FireOnViewChange( } }
+/* helper for copying STGMEDIUM of type bitmap, MF, EMF or HGLOBAL. +* does no checking of whether src_stgm has a supported tymed, so this should be +* done in the caller */ +static HRESULT copy_stg_medium(CLIPFORMAT cf, STGMEDIUM *dest_stgm, + const STGMEDIUM *src_stgm) +{ + if (src_stgm->tymed == TYMED_MFPICT) + { + const METAFILEPICT *src_mfpict = GlobalLock(src_stgm->u.hMetaFilePict); + METAFILEPICT *dest_mfpict; + + if (!src_mfpict) + return DV_E_STGMEDIUM; + dest_stgm->u.hMetaFilePict = GlobalAlloc(GMEM_MOVEABLE, sizeof(METAFILEPICT)); + dest_mfpict = GlobalLock(dest_stgm->u.hMetaFilePict); + if (!dest_mfpict) + { + GlobalUnlock(src_stgm->u.hMetaFilePict); + return E_OUTOFMEMORY; + } + *dest_mfpict = *src_mfpict; + dest_mfpict->hMF = CopyMetaFileW(src_mfpict->hMF, NULL); + GlobalUnlock(src_stgm->u.hMetaFilePict); + GlobalUnlock(dest_stgm->u.hMetaFilePict); + } + else if (src_stgm->tymed != TYMED_NULL) + { + dest_stgm->u.hGlobal = OleDuplicateData(src_stgm->u.hGlobal, cf, + GMEM_MOVEABLE); + if (!dest_stgm->u.hGlobal) + return E_OUTOFMEMORY; + } + dest_stgm->tymed = src_stgm->tymed; + dest_stgm->pUnkForRelease = src_stgm->pUnkForRelease; + if (dest_stgm->pUnkForRelease) + IUnknown_AddRef(dest_stgm->pUnkForRelease); + return S_OK; +} + static HRESULT read_clipformat(IStream *stream, CLIPFORMAT *clipformat) { DWORD length; @@ -547,6 +586,30 @@ static HRESULT open_pres_stream( IStorage *stg, int stream_number, IStream **stm return IStorage_OpenStream( stg, name, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, stm ); }
+static HRESULT synthesize_emf( HMETAFILEPICT data, STGMEDIUM *med ) +{ + METAFILEPICT *pict; + HRESULT hr = E_FAIL; + UINT size; + void *bits; + + if (!(pict = GlobalLock( data ))) return hr; + + size = GetMetaFileBitsEx( pict->hMF, 0, NULL ); + if ((bits = HeapAlloc( GetProcessHeap(), 0, size ))) + { + GetMetaFileBitsEx( pict->hMF, size, bits ); + med->u.hEnhMetaFile = SetWinMetaFileBits( size, bits, NULL, pict ); + HeapFree( GetProcessHeap(), 0, bits ); + med->tymed = TYMED_ENHMF; + med->pUnkForRelease = NULL; + hr = S_OK; + } + + GlobalUnlock( data ); + return hr; +} + static HRESULT load_mf_pict( DataCacheEntry *cache_entry, IStream *stm ) { HRESULT hr; @@ -701,7 +764,61 @@ 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 ); + ReleaseStgMedium( &cache_entry->stgmedium ); + } + if (SUCCEEDED( hr )) + cache_entry->stgmedium = stgmed; + } + else + { + STATSTG stat; + BYTE *data; + 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, data + (read - size_bits) ); + cache_entry->stgmedium.tymed = TYMED_ENHMF; + cache_entry->stgmedium.pUnkForRelease = NULL; + + HeapFree( GetProcessHeap(), 0, data ); + } + } + + return hr; }
/************************************************************************ @@ -736,6 +853,10 @@ static HRESULT DataCacheEntry_LoadData(DataCacheEntry *cache_entry, IStorage *st hr = load_dib( cache_entry, stm ); break;
+ case CF_ENHMETAFILE: + hr = load_emf( cache_entry, stm ); + break; + default: FIXME( "Unimplemented clip format %x\n", cache_entry->fmtetc.cfFormat ); hr = E_NOTIMPL; @@ -1030,45 +1151,6 @@ static HRESULT DataCacheEntry_Save(DataCacheEntry *cache_entry, IStorage *storag return hr; }
-/* helper for copying STGMEDIUM of type bitmap, MF, EMF or HGLOBAL. -* does no checking of whether src_stgm has a supported tymed, so this should be -* done in the caller */ -static HRESULT copy_stg_medium(CLIPFORMAT cf, STGMEDIUM *dest_stgm, - const STGMEDIUM *src_stgm) -{ - if (src_stgm->tymed == TYMED_MFPICT) - { - const METAFILEPICT *src_mfpict = GlobalLock(src_stgm->u.hMetaFilePict); - METAFILEPICT *dest_mfpict; - - if (!src_mfpict) - return DV_E_STGMEDIUM; - dest_stgm->u.hMetaFilePict = GlobalAlloc(GMEM_MOVEABLE, sizeof(METAFILEPICT)); - dest_mfpict = GlobalLock(dest_stgm->u.hMetaFilePict); - if (!dest_mfpict) - { - GlobalUnlock(src_stgm->u.hMetaFilePict); - return E_OUTOFMEMORY; - } - *dest_mfpict = *src_mfpict; - dest_mfpict->hMF = CopyMetaFileW(src_mfpict->hMF, NULL); - GlobalUnlock(src_stgm->u.hMetaFilePict); - GlobalUnlock(dest_stgm->u.hMetaFilePict); - } - else if (src_stgm->tymed != TYMED_NULL) - { - dest_stgm->u.hGlobal = OleDuplicateData(src_stgm->u.hGlobal, cf, - GMEM_MOVEABLE); - if (!dest_stgm->u.hGlobal) - return E_OUTOFMEMORY; - } - dest_stgm->tymed = src_stgm->tymed; - dest_stgm->pUnkForRelease = src_stgm->pUnkForRelease; - if (dest_stgm->pUnkForRelease) - IUnknown_AddRef(dest_stgm->pUnkForRelease); - return S_OK; -} - static HRESULT synthesize_dib( HBITMAP bm, STGMEDIUM *med ) { HDC hdc = GetDC( 0 ); @@ -1118,30 +1200,6 @@ static HRESULT synthesize_bitmap( HGLOBAL dib, STGMEDIUM *med ) return hr; }
-static HRESULT synthesize_emf( HMETAFILEPICT data, STGMEDIUM *med ) -{ - METAFILEPICT *pict; - HRESULT hr = E_FAIL; - UINT size; - void *bits; - - if (!(pict = GlobalLock( data ))) return hr; - - size = GetMetaFileBitsEx( pict->hMF, 0, NULL ); - if ((bits = HeapAlloc( GetProcessHeap(), 0, size ))) - { - GetMetaFileBitsEx( pict->hMF, size, bits ); - med->u.hEnhMetaFile = SetWinMetaFileBits( size, bits, NULL, pict ); - HeapFree( GetProcessHeap(), 0, bits ); - med->tymed = TYMED_ENHMF; - med->pUnkForRelease = NULL; - hr = S_OK; - } - - GlobalUnlock( data ); - return hr; -} - static HRESULT DataCacheEntry_SetData(DataCacheEntry *cache_entry, const FORMATETC *formatetc, STGMEDIUM *stgmedium,
Signed-off-by: Sergio Gómez Del Real sdelreal@codeweavers.com --- dlls/ole32/datacache.c | 43 ++++++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 17 deletions(-)
diff --git a/dlls/ole32/datacache.c b/dlls/ole32/datacache.c index 3d97473c10..2678c3ff06 100644 --- a/dlls/ole32/datacache.c +++ b/dlls/ole32/datacache.c @@ -686,48 +686,57 @@ static HRESULT load_dib( DataCacheEntry *cache_entry, IStream *stm ) { HRESULT hr; STATSTG stat; - void *dib; + BYTE *dib; HGLOBAL hglobal; ULONG read, info_size, bi_size; - BITMAPFILEHEADER file; BITMAPINFOHEADER *info; - - if (cache_entry->load_stream_num != STREAM_NUMBER_CONTENTS) - { - FIXME( "Unimplemented for presentation stream\n" ); - return E_FAIL; - } + CLIPFORMAT cf[4]; + PresentationDataHeader pres; + BITMAPFILEHEADER file;
hr = IStream_Stat( stm, &stat, STATFLAG_NONAME ); if (FAILED( hr )) return hr;
- if (stat.cbSize.QuadPart < sizeof(file) + sizeof(DWORD)) return E_FAIL; - hr = IStream_Read( stm, &file, sizeof(file), &read ); - if (hr != S_OK || read != sizeof(file)) return E_FAIL; - stat.cbSize.QuadPart -= sizeof(file); + if (cache_entry->load_stream_num != STREAM_NUMBER_CONTENTS) + { + if (stat.cbSize.QuadPart < sizeof(pres) + sizeof(cf)) return E_FAIL; + hr = read_clipformat( stm, cf ); + if (FAILED( hr )) return hr; + hr = IStream_Read( stm, &pres, sizeof(pres), &read ); + stat.cbSize.QuadPart -= sizeof(pres) + sizeof(cf); + } + else + { + if (stat.cbSize.QuadPart < sizeof(BITMAPFILEHEADER)) return E_FAIL; + hr = IStream_Read( stm, &file, sizeof(BITMAPFILEHEADER), &read ); + stat.cbSize.QuadPart -= sizeof(BITMAPFILEHEADER); + }
hglobal = GlobalAlloc( GMEM_MOVEABLE, stat.cbSize.u.LowPart ); if (!hglobal) return E_OUTOFMEMORY; dib = GlobalLock( hglobal );
+ /* read first DWORD of BITMAPINFOHEADER */ hr = IStream_Read( stm, dib, sizeof(DWORD), &read ); if (hr != S_OK || read != sizeof(DWORD)) goto fail; bi_size = *(DWORD *)dib; if (stat.cbSize.QuadPart < bi_size) goto fail;
- hr = IStream_Read( stm, (char *)dib + sizeof(DWORD), bi_size - sizeof(DWORD), &read ); + /* read rest of BITMAPINFOHEADER */ + hr = IStream_Read( stm, dib + sizeof(DWORD), bi_size - sizeof(DWORD), &read ); if (hr != S_OK || read != bi_size - sizeof(DWORD)) goto fail;
- info_size = bitmap_info_size( dib, DIB_RGB_COLORS ); + info_size = bitmap_info_size( (BITMAPINFO *)dib, DIB_RGB_COLORS ); if (stat.cbSize.QuadPart < info_size) goto fail; if (info_size > bi_size) { - hr = IStream_Read( stm, (char *)dib + bi_size, info_size - bi_size, &read ); + hr = IStream_Read( stm, dib + bi_size, info_size - bi_size, &read ); if (hr != S_OK || read != info_size - bi_size) goto fail; } stat.cbSize.QuadPart -= info_size;
- if (file.bfOffBits) + /* set Stream pointer to beginning of bitmap bits */ + if (cache_entry->load_stream_num == STREAM_NUMBER_CONTENTS && file.bfOffBits) { LARGE_INTEGER skip;
@@ -738,7 +747,7 @@ static HRESULT load_dib( DataCacheEntry *cache_entry, IStream *stm ) stat.cbSize.QuadPart -= skip.QuadPart; }
- hr = IStream_Read( stm, (char *)dib + info_size, stat.cbSize.u.LowPart, &read ); + hr = IStream_Read( stm, dib + info_size, stat.cbSize.u.LowPart, &read ); if (hr != S_OK || read != stat.cbSize.QuadPart) goto fail;
if (bi_size >= sizeof(*info))
On 5 Apr 2018, at 14:05, Sergio Gómez Del Real sdelreal@codeweavers.com wrote:
Signed-off-by: Sergio Gómez Del Real sdelreal@codeweavers.com
dlls/ole32/datacache.c | 43 ++++++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 17 deletions(-)
diff --git a/dlls/ole32/datacache.c b/dlls/ole32/datacache.c index 3d97473c10..2678c3ff06 100644 --- a/dlls/ole32/datacache.c +++ b/dlls/ole32/datacache.c @@ -686,48 +686,57 @@ static HRESULT load_dib( DataCacheEntry *cache_entry, IStream *stm ) { HRESULT hr; STATSTG stat;
- void *dib;
- BYTE *dib; HGLOBAL hglobal; ULONG read, info_size, bi_size;
- BITMAPFILEHEADER file; BITMAPINFOHEADER *info;
- if (cache_entry->load_stream_num != STREAM_NUMBER_CONTENTS)
- {
FIXME( "Unimplemented for presentation stream\n" );
return E_FAIL;
- }
- CLIPFORMAT cf[4];
Why cf[4]? There’s only one clip format.
PresentationDataHeader pres;
BITMAPFILEHEADER file;
hr = IStream_Stat( stm, &stat, STATFLAG_NONAME ); if (FAILED( hr )) return hr;
- if (stat.cbSize.QuadPart < sizeof(file) + sizeof(DWORD)) return E_FAIL;
- hr = IStream_Read( stm, &file, sizeof(file), &read );
- if (hr != S_OK || read != sizeof(file)) return E_FAIL;
- stat.cbSize.QuadPart -= sizeof(file);
- if (cache_entry->load_stream_num != STREAM_NUMBER_CONTENTS)
- {
if (stat.cbSize.QuadPart < sizeof(pres) + sizeof(cf)) return E_FAIL;
You could remove this size check (it’s not right anyway) and rely on read_clipformat() failing or the following Read() to return fewer than sizeof(pres) bytes to indicate a small stream. You would then call Seek() to return the current pos and subtract that from stat.cbSize. See how it’s done in load_mfpict().
hr = read_clipformat( stm, cf );
if (FAILED( hr )) return hr;
hr = IStream_Read( stm, &pres, sizeof(pres), &read );
stat.cbSize.QuadPart -= sizeof(pres) + sizeof(cf);
- }
- else
- {
if (stat.cbSize.QuadPart < sizeof(BITMAPFILEHEADER)) return E_FAIL;
Similarly this could go and check read == sizeof(BITMAPFILEHEADER).
hr = IStream_Read( stm, &file, sizeof(BITMAPFILEHEADER), &read );
stat.cbSize.QuadPart -= sizeof(BITMAPFILEHEADER);
}
hglobal = GlobalAlloc( GMEM_MOVEABLE, stat.cbSize.u.LowPart ); if (!hglobal) return E_OUTOFMEMORY; dib = GlobalLock( hglobal );
/* read first DWORD of BITMAPINFOHEADER */ hr = IStream_Read( stm, dib, sizeof(DWORD), &read ); if (hr != S_OK || read != sizeof(DWORD)) goto fail; bi_size = *(DWORD *)dib; if (stat.cbSize.QuadPart < bi_size) goto fail;
- hr = IStream_Read( stm, (char *)dib + sizeof(DWORD), bi_size - sizeof(DWORD), &read );
- /* read rest of BITMAPINFOHEADER */
- hr = IStream_Read( stm, dib + sizeof(DWORD), bi_size - sizeof(DWORD), &read ); if (hr != S_OK || read != bi_size - sizeof(DWORD)) goto fail;
- info_size = bitmap_info_size( dib, DIB_RGB_COLORS );
- info_size = bitmap_info_size( (BITMAPINFO *)dib, DIB_RGB_COLORS ); if (stat.cbSize.QuadPart < info_size) goto fail; if (info_size > bi_size) {
hr = IStream_Read( stm, (char *)dib + bi_size, info_size - bi_size, &read );
} stat.cbSize.QuadPart -= info_size;hr = IStream_Read( stm, dib + bi_size, info_size - bi_size, &read ); if (hr != S_OK || read != info_size - bi_size) goto fail;
- if (file.bfOffBits)
- /* set Stream pointer to beginning of bitmap bits */
- if (cache_entry->load_stream_num == STREAM_NUMBER_CONTENTS && file.bfOffBits) { LARGE_INTEGER skip;
@@ -738,7 +747,7 @@ static HRESULT load_dib( DataCacheEntry *cache_entry, IStream *stm ) stat.cbSize.QuadPart -= skip.QuadPart; }
- hr = IStream_Read( stm, (char *)dib + info_size, stat.cbSize.u.LowPart, &read );
hr = IStream_Read( stm, dib + info_size, stat.cbSize.u.LowPart, &read ); if (hr != S_OK || read != stat.cbSize.QuadPart) goto fail;
if (bi_size >= sizeof(*info))
-- 2.14.1
Signed-off-by: Sergio Gómez Del Real sdelreal@codeweavers.com --- dlls/ole32/datacache.c | 66 ++++++++++++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 29 deletions(-)
diff --git a/dlls/ole32/datacache.c b/dlls/ole32/datacache.c index 2678c3ff06..1967f9dec0 100644 --- a/dlls/ole32/datacache.c +++ b/dlls/ole32/datacache.c @@ -609,6 +609,17 @@ static HRESULT synthesize_emf( HMETAFILEPICT data, STGMEDIUM *med ) GlobalUnlock( data ); return hr; } +#include <pshpack2.h> +struct meta_placeable +{ + DWORD key; + WORD hwmf; + WORD bounding_box[4]; + WORD inch; + DWORD reserved; + WORD checksum; +}; +#include <poppack.h>
static HRESULT load_mf_pict( DataCacheEntry *cache_entry, IStream *stm ) { @@ -618,25 +629,24 @@ static HRESULT load_mf_pict( DataCacheEntry *cache_entry, IStream *stm ) void *bits; METAFILEPICT *mfpict; HGLOBAL hmfpict; - PresentationDataHeader header; - CLIPFORMAT clipformat; static const LARGE_INTEGER offset_zero; ULONG read; + CLIPFORMAT cf[4]; + PresentationDataHeader pres; + struct meta_placeable mf_place;
- if (cache_entry->load_stream_num == STREAM_NUMBER_CONTENTS) + hr = IStream_Stat( stm, &stat, STATFLAG_NONAME ); + if (FAILED( hr )) return hr; + + if (cache_entry->load_stream_num != STREAM_NUMBER_CONTENTS) { - FIXME( "Unimplemented for CONTENTS stream\n" ); - return E_FAIL; + if (stat.cbSize.QuadPart < sizeof(pres) + sizeof(cf)) return E_FAIL; + hr = read_clipformat( stm, cf ); + if (FAILED( hr )) return hr; + hr = IStream_Read( stm, &pres, sizeof(pres), &read ); } - - hr = IStream_Stat( stm, &stat, STATFLAG_NONAME ); - if (FAILED( hr )) return hr; - - hr = read_clipformat( stm, &clipformat ); - if (FAILED( hr )) return hr; - - hr = IStream_Read( stm, &header, sizeof(header), &read ); - if (hr != S_OK || read != sizeof(header)) return E_FAIL; + else + hr = IStream_Read( stm, &mf_place, sizeof(mf_place), &read );
hr = IStream_Seek( stm, offset_zero, STREAM_SEEK_CUR, ¤t_pos ); if (FAILED( hr )) return hr; @@ -659,10 +669,20 @@ static HRESULT load_mf_pict( DataCacheEntry *cache_entry, IStream *stm )
if (SUCCEEDED( hr )) { - /* FIXME: get this from the stream */ mfpict->mm = MM_ANISOTROPIC; - mfpict->xExt = header.dwObjectExtentX; - mfpict->yExt = header.dwObjectExtentY; + /* FIXME: get this from the stream */ + if (cache_entry->load_stream_num != STREAM_NUMBER_CONTENTS) + { + mfpict->xExt = pres.dwObjectExtentX; + mfpict->yExt = pres.dwObjectExtentY; + } + else + { + mfpict->xExt = ((mf_place.bounding_box[2] - mf_place.bounding_box[0]) + * 2540) / mf_place.inch; + mfpict->yExt = ((mf_place.bounding_box[3] - mf_place.bounding_box[1]) + * 2540) / mf_place.inch; + } mfpict->hMF = SetMetaFileBitsEx( stat.cbSize.u.LowPart, bits ); if (!mfpict->hMF) hr = E_FAIL; @@ -947,18 +967,6 @@ end: return hr; }
-#include <pshpack2.h> -struct meta_placeable -{ - DWORD key; - WORD hwmf; - WORD bounding_box[4]; - WORD inch; - DWORD reserved; - WORD checksum; -}; -#include <poppack.h> - static HRESULT save_mfpict(DataCacheEntry *entry, BOOL contents, IStream *stream) { HRESULT hr = S_OK;
On 5 Apr 2018, at 14:05, Sergio Gómez Del Real sdelreal@codeweavers.com wrote:
Signed-off-by: Sergio Gómez Del Real sdelreal@codeweavers.com
dlls/ole32/datacache.c | 66 ++++++++++++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 29 deletions(-)
diff --git a/dlls/ole32/datacache.c b/dlls/ole32/datacache.c index 2678c3ff06..1967f9dec0 100644 --- a/dlls/ole32/datacache.c +++ b/dlls/ole32/datacache.c @@ -609,6 +609,17 @@ static HRESULT synthesize_emf( HMETAFILEPICT data, STGMEDIUM *med ) GlobalUnlock( data ); return hr; } +#include <pshpack2.h> +struct meta_placeable +{
- DWORD key;
- WORD hwmf;
- WORD bounding_box[4];
- WORD inch;
- DWORD reserved;
- WORD checksum;
+}; +#include <poppack.h>
static HRESULT load_mf_pict( DataCacheEntry *cache_entry, IStream *stm ) { @@ -618,25 +629,24 @@ static HRESULT load_mf_pict( DataCacheEntry *cache_entry, IStream *stm ) void *bits; METAFILEPICT *mfpict; HGLOBAL hmfpict;
- PresentationDataHeader header;
- CLIPFORMAT clipformat; static const LARGE_INTEGER offset_zero; ULONG read;
- CLIPFORMAT cf[4];
See my comments for [2/5].
- PresentationDataHeader pres;
- struct meta_placeable mf_place;
- if (cache_entry->load_stream_num == STREAM_NUMBER_CONTENTS)
- hr = IStream_Stat( stm, &stat, STATFLAG_NONAME );
- if (FAILED( hr )) return hr;
- if (cache_entry->load_stream_num != STREAM_NUMBER_CONTENTS) {
FIXME( "Unimplemented for CONTENTS stream\n" );
return E_FAIL;
if (stat.cbSize.QuadPart < sizeof(pres) + sizeof(cf)) return E_FAIL;
hr = read_clipformat( stm, cf );
if (FAILED( hr )) return hr;
}hr = IStream_Read( stm, &pres, sizeof(pres), &read );
- hr = IStream_Stat( stm, &stat, STATFLAG_NONAME );
- if (FAILED( hr )) return hr;
- hr = read_clipformat( stm, &clipformat );
- if (FAILED( hr )) return hr;
- hr = IStream_Read( stm, &header, sizeof(header), &read );
- if (hr != S_OK || read != sizeof(header)) return E_FAIL;
else
hr = IStream_Read( stm, &mf_place, sizeof(mf_place), &read );
hr = IStream_Seek( stm, offset_zero, STREAM_SEEK_CUR, ¤t_pos ); if (FAILED( hr )) return hr;
@@ -659,10 +669,20 @@ static HRESULT load_mf_pict( DataCacheEntry *cache_entry, IStream *stm )
if (SUCCEEDED( hr )) {
/* FIXME: get this from the stream */ mfpict->mm = MM_ANISOTROPIC;
mfpict->xExt = header.dwObjectExtentX;
mfpict->yExt = header.dwObjectExtentY;
/* FIXME: get this from the stream */
if (cache_entry->load_stream_num != STREAM_NUMBER_CONTENTS)
{
mfpict->xExt = pres.dwObjectExtentX;
mfpict->yExt = pres.dwObjectExtentY;
}
else
{
mfpict->xExt = ((mf_place.bounding_box[2] - mf_place.bounding_box[0])
* 2540) / mf_place.inch;
mfpict->yExt = ((mf_place.bounding_box[3] - mf_place.bounding_box[1])
* 2540) / mf_place.inch;
} mfpict->hMF = SetMetaFileBitsEx( stat.cbSize.u.LowPart, bits ); if (!mfpict->hMF) hr = E_FAIL;
@@ -947,18 +967,6 @@ end: return hr; }
-#include <pshpack2.h> -struct meta_placeable -{
- DWORD key;
- WORD hwmf;
- WORD bounding_box[4];
- WORD inch;
- DWORD reserved;
- WORD checksum;
-}; -#include <poppack.h>
static HRESULT save_mfpict(DataCacheEntry *entry, BOOL contents, IStream *stream) { HRESULT hr = S_OK; -- 2.14.1
Signed-off-by: Sergio Gómez Del Real sdelreal@codeweavers.com --- dlls/ole32/datacache.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/dlls/ole32/datacache.c b/dlls/ole32/datacache.c index 1967f9dec0..fbf8b2dde1 100644 --- a/dlls/ole32/datacache.c +++ b/dlls/ole32/datacache.c @@ -1838,6 +1838,7 @@ static HRESULT WINAPI DataCache_Load( IPersistStorage *iface, IStorage *stg )
LIST_FOR_EACH_ENTRY_SAFE( entry, cursor2, &This->cache_list, DataCacheEntry, entry ) DataCacheEntry_Destroy( This, entry ); + This->clsid = CLSID_NULL;
ReadClassStg( stg, &clsid ); hr = create_automatic_entry( This, &clsid );
On 5 Apr 2018, at 14:05, Sergio Gómez Del Real sdelreal@codeweavers.com wrote:
Signed-off-by: Sergio Gómez Del Real sdelreal@codeweavers.com
dlls/ole32/datacache.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/dlls/ole32/datacache.c b/dlls/ole32/datacache.c index 1967f9dec0..fbf8b2dde1 100644 --- a/dlls/ole32/datacache.c +++ b/dlls/ole32/datacache.c @@ -1838,6 +1838,7 @@ static HRESULT WINAPI DataCache_Load( IPersistStorage *iface, IStorage *stg )
LIST_FOR_EACH_ENTRY_SAFE( entry, cursor2, &This->cache_list, DataCacheEntry, entry ) DataCacheEntry_Destroy( This, entry );
This->clsid = CLSID_NULL;
ReadClassStg( stg, &clsid ); hr = create_automatic_entry( This, &clsid );
Looks good.
Huw.
Signed-off-by: Sergio Gómez Del Real sdelreal@codeweavers.com --- dlls/ole32/tests/ole2.c | 136 +++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 116 insertions(+), 20 deletions(-)
diff --git a/dlls/ole32/tests/ole2.c b/dlls/ole32/tests/ole2.c index 3bd4acce92..1d388bbc5d 100644 --- a/dlls/ole32/tests/ole2.c +++ b/dlls/ole32/tests/ole2.c @@ -4078,6 +4078,71 @@ static void check_storage_contents(IStorage *stg, const struct storage_def *stg_ } }
+static HRESULT stgmedium_cmp(const STGMEDIUM *stgmed_def, const STGMEDIUM *stgmed_ld) +{ + BYTE *data_def, *data_ld; + int data_size = 0, data_size_def, data_size_ld; + + if (stgmed_def->tymed != stgmed_ld->tymed) + return E_FAIL; + + if (stgmed_def->tymed == TYMED_MFPICT) + { + METAFILEPICT *mfpict_def = GlobalLock(U(stgmed_def)->hMetaFilePict); + METAFILEPICT *mfpict_ld = GlobalLock(U(stgmed_ld)->hMetaFilePict); + + data_size_def = GetMetaFileBitsEx(mfpict_def->hMF, 0, NULL); + data_size_ld = GetMetaFileBitsEx(mfpict_ld->hMF, 0, NULL); + if (data_size_def == data_size_ld) + { + data_def = HeapAlloc(GetProcessHeap(), 0, data_size_def); + data_ld = HeapAlloc(GetProcessHeap(), 0, data_size_ld); + GetMetaFileBitsEx(mfpict_def->hMF, data_size_def, data_def); + GetMetaFileBitsEx(mfpict_ld->hMF, data_size_ld, data_ld); + data_size = data_size_def; + } + else return E_FAIL; + } + else if (stgmed_def->tymed == TYMED_ENHMF) + { + data_size_def = GetEnhMetaFileBits(stgmed_def->hEnhMetaFile, 0, NULL); + data_size_ld = GetEnhMetaFileBits(stgmed_ld->hEnhMetaFile, 0, NULL); + if (data_size_def == data_size_ld) + { + data_def = HeapAlloc(GetProcessHeap(), 0, data_size_def); + data_ld = HeapAlloc(GetProcessHeap(), 0, data_size_ld); + GetEnhMetaFileBits(stgmed_def->hEnhMetaFile, data_size_def, data_def); + GetEnhMetaFileBits(stgmed_ld->hEnhMetaFile, data_size_ld, data_ld); + data_size = data_size_def; + } + else return E_FAIL; + } + else if (stgmed_def->tymed == TYMED_HGLOBAL) + { + data_def = GlobalLock(stgmed_def->hGlobal); + data_ld = GlobalLock(stgmed_ld->hGlobal); + data_size = sizeof(dib); + } + else + return E_NOTIMPL; + + if (memcmp(data_def, data_ld, data_size) != 0) + return E_FAIL; + + if (stgmed_def->tymed == TYMED_HGLOBAL) + { + GlobalUnlock(stgmed_def->hGlobal); + GlobalUnlock(stgmed_ld->hGlobal); + } + else if (stgmed_def->tymed == TYMED_MFPICT) + { + GlobalUnlock(U(stgmed_def)->hMetaFilePict); + GlobalUnlock(U(stgmed_ld)->hMetaFilePict); + } + + return S_OK; +} + static IStorage *create_storage_from_def(const struct storage_def *stg_def) { HRESULT hr; @@ -4250,8 +4315,10 @@ static void test_data_cache_save_data(void) IStorage *doc; IOleCache2 *cache; IPersistStorage *persist; + IDataObject *odata; int enumerated_streams, matched_streams, i; DWORD dummy; + STGMEDIUM stgmeds[MAX_FMTS]; struct tests_data_cache { FORMATETC fmts[MAX_FMTS]; @@ -4274,8 +4341,8 @@ static void test_data_cache_save_data(void) &CLSID_WineTestOld, 4, { { "\2OlePres000", CF_DIB, DVASPECT_CONTENT, 0, NULL, 0 }, { "\2OlePres001", CF_METAFILEPICT, DVASPECT_CONTENT, 0, NULL, 0 }, { "\2OlePres002", CF_ENHMETAFILE, DVASPECT_CONTENT, 0, NULL, 0 }, - { "\2OlePres003", 0, DVASPECT_DOCPRINT, 0, NULL, 0 } } - } + { "\2OlePres003", 0, DVASPECT_DOCPRINT, 0, NULL, 0 } }, + }, }, /* without setting data */ { @@ -4288,8 +4355,8 @@ static void test_data_cache_save_data(void) { &CLSID_WineTestOld, 3, { { "\2OlePres000", CF_DIB, DVASPECT_CONTENT, 0, NULL, 0 }, { "\2OlePres001", CF_METAFILEPICT, DVASPECT_CONTENT, 0, NULL, 0 }, - { "\2OlePres002", CF_ENHMETAFILE, DVASPECT_CONTENT, 0, NULL, 0 } } - } + { "\2OlePres002", CF_ENHMETAFILE, DVASPECT_CONTENT, 0, NULL, 0 } }, + }, }, /* static picture clsids */ { @@ -4298,8 +4365,8 @@ static void test_data_cache_save_data(void) }, 1, 1, &CLSID_Picture_Dib, { - &CLSID_WineTestOld, 1, { { "CONTENTS", -1, 0, 0, NULL, 0 } } - } + &CLSID_WineTestOld, 1, { { "CONTENTS", -1, 0, 0, NULL, 0 } }, + }, }, { { @@ -4307,8 +4374,8 @@ static void test_data_cache_save_data(void) }, 1, 1, &CLSID_Picture_Metafile, { - &CLSID_WineTestOld, 1, { { "CONTENTS", -1, 0, 0, NULL, 0 } } - } + &CLSID_WineTestOld, 1, { { "CONTENTS", -1, 0, 0, NULL, 0 } }, + }, }, { { @@ -4316,8 +4383,8 @@ static void test_data_cache_save_data(void) }, 1, 1, &CLSID_Picture_EnhMetafile, { - &CLSID_WineTestOld, 1, { { "CONTENTS", -1, 0, 0, NULL, 0 } } - } + &CLSID_WineTestOld, 1, { { "CONTENTS", -1, 0, 0, NULL, 0 } }, + }, }, /* static picture clsids without setting any data */ { @@ -4326,8 +4393,8 @@ static void test_data_cache_save_data(void) }, 1, 0, &CLSID_Picture_Dib, { - &CLSID_WineTestOld, 1, { { "CONTENTS", -1, 0, 0, NULL, 0 } } - } + &CLSID_WineTestOld, 1, { { "CONTENTS", -1, 0, 0, NULL, 0 } }, + }, }, { { @@ -4335,8 +4402,8 @@ static void test_data_cache_save_data(void) }, 1, 0, &CLSID_Picture_Metafile, { - &CLSID_WineTestOld, 1, { { "CONTENTS", -1, 0, 0, NULL, 0 } } - } + &CLSID_WineTestOld, 1, { { "CONTENTS", -1, 0, 0, NULL, 0 } }, + }, }, { { @@ -4344,8 +4411,8 @@ static void test_data_cache_save_data(void) }, 1, 0, &CLSID_Picture_EnhMetafile, { - &CLSID_WineTestOld, 1, { { "CONTENTS", -1, 0, 0, NULL, 0 } } - } + &CLSID_WineTestOld, 1, { { "CONTENTS", -1, 0, 0, NULL, 0 } }, + }, }, { { @@ -4366,9 +4433,9 @@ static void test_data_cache_save_data(void) ok(SUCCEEDED(hr), "unexpected %#x\n", hr); if (i < pdata->num_set) { - get_stgmedium(pdata->fmts[i].cfFormat, &stgmed); - get_stgdef(&pdata->stg_def, pdata->fmts[i].cfFormat, &stgmed, i); - hr = IOleCache2_SetData(cache, &pdata->fmts[i], &stgmed, TRUE); + get_stgmedium(pdata->fmts[i].cfFormat, &stgmeds[i]); + get_stgdef(&pdata->stg_def, pdata->fmts[i].cfFormat, &stgmeds[i], i); + hr = IOleCache2_SetData(cache, &pdata->fmts[i], &stgmeds[i], FALSE); ok(hr == S_OK, "unexpected %#x\n", hr); } } @@ -4399,12 +4466,41 @@ static void test_data_cache_save_data(void) ok(enumerated_streams == pdata->stg_def.stream_count, "created %d != def streams %d\n", enumerated_streams, pdata->stg_def.stream_count);
+ IPersistStorage_Release(persist); + IOleCache2_Release(cache); + + /* now test _Load/_GetData using the storage we used for _Save */ + hr = CreateDataCache(NULL, pdata->clsid, &IID_IOleCache2, (void **)&cache); + ok(hr == S_OK, "unexpected %#x\n", hr); + hr = IOleCache2_QueryInterface(cache, &IID_IPersistStorage, (void **)&persist); + ok(hr == S_OK, "unexpected %#x\n", hr); + + hr = IStorage_SetClass(doc, pdata->clsid); + ok(hr == S_OK, "unexpected %#x\n", hr); + trace("IPersistStorage_Load\n"); + hr = IPersistStorage_Load(persist, doc); + ok(hr == S_OK, "unexpected %#x\n", hr); + + hr = IOleCache2_QueryInterface(cache, &IID_IDataObject, (void **)&odata); + ok(hr == S_OK, "unexpected %#x\n", hr); for (i = 0; i < pdata->num_set; i++) - HeapFree(GetProcessHeap(), 0, (void *)pdata->stg_def.stream[i].data); + { + hr = IDataObject_GetData(odata, &pdata->fmts[i], &stgmed); + ok(hr == S_OK, "unexpected %#x\n", hr);
+ hr = stgmedium_cmp(&stgmeds[i], &stgmed); + ok(hr == S_OK, "unexpected %#x\n", hr); + ReleaseStgMedium(&stgmed); + ReleaseStgMedium(&stgmeds[i]); + } + + IDataObject_Release(odata); IPersistStorage_Release(persist); IStorage_Release(doc); IOleCache2_Release(cache); + for (i = 0; i < pdata->num_set; i++) + HeapFree(GetProcessHeap(), 0, (void *)pdata->stg_def.stream[i].data); + } }
On 5 Apr 2018, at 14:05, Sergio Gómez Del Real sdelreal@codeweavers.com wrote:
Signed-off-by: Sergio Gómez Del Real sdelreal@codeweavers.com
dlls/ole32/tests/ole2.c | 136 +++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 116 insertions(+), 20 deletions(-)
diff --git a/dlls/ole32/tests/ole2.c b/dlls/ole32/tests/ole2.c index 3bd4acce92..1d388bbc5d 100644 --- a/dlls/ole32/tests/ole2.c +++ b/dlls/ole32/tests/ole2.c @@ -4078,6 +4078,71 @@ static void check_storage_contents(IStorage *stg, const struct storage_def *stg_ } }
+static HRESULT stgmedium_cmp(const STGMEDIUM *stgmed_def, const STGMEDIUM *stgmed_ld) +{
Being a bit picky, but I find stgmed_def and stgmed_ld confusing. What does ‘def’ and ‘ld’ stand for. I’d rather they were just med1 and med2 frankly.
- BYTE *data_def, *data_ld;
- int data_size = 0, data_size_def, data_size_ld;
- if (stgmed_def->tymed != stgmed_ld->tymed)
return E_FAIL;
- if (stgmed_def->tymed == TYMED_MFPICT)
- {
METAFILEPICT *mfpict_def = GlobalLock(U(stgmed_def)->hMetaFilePict);
METAFILEPICT *mfpict_ld = GlobalLock(U(stgmed_ld)->hMetaFilePict);
data_size_def = GetMetaFileBitsEx(mfpict_def->hMF, 0, NULL);
data_size_ld = GetMetaFileBitsEx(mfpict_ld->hMF, 0, NULL);
if (data_size_def == data_size_ld)
{
data_def = HeapAlloc(GetProcessHeap(), 0, data_size_def);
data_ld = HeapAlloc(GetProcessHeap(), 0, data_size_ld);
GetMetaFileBitsEx(mfpict_def->hMF, data_size_def, data_def);
GetMetaFileBitsEx(mfpict_ld->hMF, data_size_ld, data_ld);
data_size = data_size_def;
}
else return E_FAIL;
- }
- else if (stgmed_def->tymed == TYMED_ENHMF)
- {
data_size_def = GetEnhMetaFileBits(stgmed_def->hEnhMetaFile, 0, NULL);
data_size_ld = GetEnhMetaFileBits(stgmed_ld->hEnhMetaFile, 0, NULL);
if (data_size_def == data_size_ld)
{
data_def = HeapAlloc(GetProcessHeap(), 0, data_size_def);
data_ld = HeapAlloc(GetProcessHeap(), 0, data_size_ld);
GetEnhMetaFileBits(stgmed_def->hEnhMetaFile, data_size_def, data_def);
GetEnhMetaFileBits(stgmed_ld->hEnhMetaFile, data_size_ld, data_ld);
data_size = data_size_def;
}
else return E_FAIL;
- }
- else if (stgmed_def->tymed == TYMED_HGLOBAL)
- {
data_def = GlobalLock(stgmed_def->hGlobal);
data_ld = GlobalLock(stgmed_ld->hGlobal);
data_size = sizeof(dib);
- }
- else
return E_NOTIMPL;
- if (memcmp(data_def, data_ld, data_size) != 0)
return E_FAIL;
- if (stgmed_def->tymed == TYMED_HGLOBAL)
- {
GlobalUnlock(stgmed_def->hGlobal);
GlobalUnlock(stgmed_ld->hGlobal);
- }
- else if (stgmed_def->tymed == TYMED_MFPICT)
- {
GlobalUnlock(U(stgmed_def)->hMetaFilePict);
GlobalUnlock(U(stgmed_ld)->hMetaFilePict);
- }
- return S_OK;
+}
static IStorage *create_storage_from_def(const struct storage_def *stg_def) { HRESULT hr; @@ -4250,8 +4315,10 @@ static void test_data_cache_save_data(void) IStorage *doc; IOleCache2 *cache; IPersistStorage *persist;
- IDataObject *odata; int enumerated_streams, matched_streams, i; DWORD dummy;
- STGMEDIUM stgmeds[MAX_FMTS]; struct tests_data_cache { FORMATETC fmts[MAX_FMTS];
@@ -4274,8 +4341,8 @@ static void test_data_cache_save_data(void) &CLSID_WineTestOld, 4, { { "\2OlePres000", CF_DIB, DVASPECT_CONTENT, 0, NULL, 0 }, { "\2OlePres001", CF_METAFILEPICT, DVASPECT_CONTENT, 0, NULL, 0 }, { "\2OlePres002", CF_ENHMETAFILE, DVASPECT_CONTENT, 0, NULL, 0 },
{ "\2OlePres003", 0, DVASPECT_DOCPRINT, 0, NULL, 0 } }
}
{ "\2OlePres003", 0, DVASPECT_DOCPRINT, 0, NULL, 0 } },
}, }, /* without setting data */ {
Why this pointless change? I realise that the previous version of this patch had a real change here, but the ghost of that change shouldn’t have survived.
@@ -4288,8 +4355,8 @@ static void test_data_cache_save_data(void) { &CLSID_WineTestOld, 3, { { "\2OlePres000", CF_DIB, DVASPECT_CONTENT, 0, NULL, 0 }, { "\2OlePres001", CF_METAFILEPICT, DVASPECT_CONTENT, 0, NULL, 0 },
{ "\2OlePres002", CF_ENHMETAFILE, DVASPECT_CONTENT, 0, NULL, 0 } }
}
{ "\2OlePres002", CF_ENHMETAFILE, DVASPECT_CONTENT, 0, NULL, 0 } },
}, }, /* static picture clsids */ {
@@ -4298,8 +4365,8 @@ static void test_data_cache_save_data(void) }, 1, 1, &CLSID_Picture_Dib, {
&CLSID_WineTestOld, 1, { { "CONTENTS", -1, 0, 0, NULL, 0 } }
}
&CLSID_WineTestOld, 1, { { "CONTENTS", -1, 0, 0, NULL, 0 } },
}, }, { {
@@ -4307,8 +4374,8 @@ static void test_data_cache_save_data(void) }, 1, 1, &CLSID_Picture_Metafile, {
&CLSID_WineTestOld, 1, { { "CONTENTS", -1, 0, 0, NULL, 0 } }
}
&CLSID_WineTestOld, 1, { { "CONTENTS", -1, 0, 0, NULL, 0 } },
}, }, { {
@@ -4316,8 +4383,8 @@ static void test_data_cache_save_data(void) }, 1, 1, &CLSID_Picture_EnhMetafile, {
&CLSID_WineTestOld, 1, { { "CONTENTS", -1, 0, 0, NULL, 0 } }
}
&CLSID_WineTestOld, 1, { { "CONTENTS", -1, 0, 0, NULL, 0 } },
}, }, /* static picture clsids without setting any data */ {
@@ -4326,8 +4393,8 @@ static void test_data_cache_save_data(void) }, 1, 0, &CLSID_Picture_Dib, {
&CLSID_WineTestOld, 1, { { "CONTENTS", -1, 0, 0, NULL, 0 } }
}
&CLSID_WineTestOld, 1, { { "CONTENTS", -1, 0, 0, NULL, 0 } },
}, }, { {
@@ -4335,8 +4402,8 @@ static void test_data_cache_save_data(void) }, 1, 0, &CLSID_Picture_Metafile, {
&CLSID_WineTestOld, 1, { { "CONTENTS", -1, 0, 0, NULL, 0 } }
}
&CLSID_WineTestOld, 1, { { "CONTENTS", -1, 0, 0, NULL, 0 } },
}, }, { {
@@ -4344,8 +4411,8 @@ static void test_data_cache_save_data(void) }, 1, 0, &CLSID_Picture_EnhMetafile, {
&CLSID_WineTestOld, 1, { { "CONTENTS", -1, 0, 0, NULL, 0 } }
}
&CLSID_WineTestOld, 1, { { "CONTENTS", -1, 0, 0, NULL, 0 } },
}, }, { {
@@ -4366,9 +4433,9 @@ static void test_data_cache_save_data(void) ok(SUCCEEDED(hr), "unexpected %#x\n", hr); if (i < pdata->num_set) {
get_stgmedium(pdata->fmts[i].cfFormat, &stgmed);
get_stgdef(&pdata->stg_def, pdata->fmts[i].cfFormat, &stgmed, i);
hr = IOleCache2_SetData(cache, &pdata->fmts[i], &stgmed, TRUE);
get_stgmedium(pdata->fmts[i].cfFormat, &stgmeds[i]);
get_stgdef(&pdata->stg_def, pdata->fmts[i].cfFormat, &stgmeds[i], i);
hr = IOleCache2_SetData(cache, &pdata->fmts[i], &stgmeds[i], FALSE); ok(hr == S_OK, "unexpected %#x\n", hr); } }
@@ -4399,12 +4466,41 @@ static void test_data_cache_save_data(void) ok(enumerated_streams == pdata->stg_def.stream_count, "created %d != def streams %d\n", enumerated_streams, pdata->stg_def.stream_count);
IPersistStorage_Release(persist);
IOleCache2_Release(cache);
/* now test _Load/_GetData using the storage we used for _Save */
hr = CreateDataCache(NULL, pdata->clsid, &IID_IOleCache2, (void **)&cache);
ok(hr == S_OK, "unexpected %#x\n", hr);
hr = IOleCache2_QueryInterface(cache, &IID_IPersistStorage, (void **)&persist);
ok(hr == S_OK, "unexpected %#x\n", hr);
hr = IStorage_SetClass(doc, pdata->clsid);
ok(hr == S_OK, "unexpected %#x\n", hr);
trace("IPersistStorage_Load\n");
hr = IPersistStorage_Load(persist, doc);
ok(hr == S_OK, "unexpected %#x\n", hr);
hr = IOleCache2_QueryInterface(cache, &IID_IDataObject, (void **)&odata);
ok(hr == S_OK, "unexpected %#x\n", hr); for (i = 0; i < pdata->num_set; i++)
HeapFree(GetProcessHeap(), 0, (void *)pdata->stg_def.stream[i].data);
{
hr = IDataObject_GetData(odata, &pdata->fmts[i], &stgmed);
ok(hr == S_OK, "unexpected %#x\n", hr);
hr = stgmedium_cmp(&stgmeds[i], &stgmed);
ok(hr == S_OK, "unexpected %#x\n", hr);
ReleaseStgMedium(&stgmed);
ReleaseStgMedium(&stgmeds[i]);
}
IDataObject_Release(odata); IPersistStorage_Release(persist); IStorage_Release(doc); IOleCache2_Release(cache);
for (i = 0; i < pdata->num_set; i++)
HeapFree(GetProcessHeap(), 0, (void *)pdata->stg_def.stream[i].data);
}
}
-- 2.14.1
On 5 Apr 2018, at 14:05, Sergio Gómez Del Real sdelreal@codeweavers.com wrote:
Signed-off-by: Sergio Gómez Del Real sdelreal@codeweavers.com
dlls/ole32/datacache.c | 184 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 121 insertions(+), 63 deletions(-)
diff --git a/dlls/ole32/datacache.c b/dlls/ole32/datacache.c index 325a98b33b..3d97473c10 100644 --- a/dlls/ole32/datacache.c +++ b/dlls/ole32/datacache.c @@ -459,6 +459,45 @@ static void DataCache_FireOnViewChange( } }
+/* helper for copying STGMEDIUM of type bitmap, MF, EMF or HGLOBAL. +* does no checking of whether src_stgm has a supported tymed, so this should be +* done in the caller */ +static HRESULT copy_stg_medium(CLIPFORMAT cf, STGMEDIUM *dest_stgm,
const STGMEDIUM *src_stgm)
This doesn’t need to be moved anymore right?
+{
- if (src_stgm->tymed == TYMED_MFPICT)
- {
const METAFILEPICT *src_mfpict = GlobalLock(src_stgm->u.hMetaFilePict);
METAFILEPICT *dest_mfpict;
if (!src_mfpict)
return DV_E_STGMEDIUM;
dest_stgm->u.hMetaFilePict = GlobalAlloc(GMEM_MOVEABLE, sizeof(METAFILEPICT));
dest_mfpict = GlobalLock(dest_stgm->u.hMetaFilePict);
if (!dest_mfpict)
{
GlobalUnlock(src_stgm->u.hMetaFilePict);
return E_OUTOFMEMORY;
}
*dest_mfpict = *src_mfpict;
dest_mfpict->hMF = CopyMetaFileW(src_mfpict->hMF, NULL);
GlobalUnlock(src_stgm->u.hMetaFilePict);
GlobalUnlock(dest_stgm->u.hMetaFilePict);
- }
- else if (src_stgm->tymed != TYMED_NULL)
- {
dest_stgm->u.hGlobal = OleDuplicateData(src_stgm->u.hGlobal, cf,
GMEM_MOVEABLE);
if (!dest_stgm->u.hGlobal)
return E_OUTOFMEMORY;
- }
- dest_stgm->tymed = src_stgm->tymed;
- dest_stgm->pUnkForRelease = src_stgm->pUnkForRelease;
- if (dest_stgm->pUnkForRelease)
IUnknown_AddRef(dest_stgm->pUnkForRelease);
- return S_OK;
+}
static HRESULT read_clipformat(IStream *stream, CLIPFORMAT *clipformat) { DWORD length; @@ -547,6 +586,30 @@ static HRESULT open_pres_stream( IStorage *stg, int stream_number, IStream **stm return IStorage_OpenStream( stg, name, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, stm ); }
+static HRESULT synthesize_emf( HMETAFILEPICT data, STGMEDIUM *med ) +{
- METAFILEPICT *pict;
- HRESULT hr = E_FAIL;
- UINT size;
- void *bits;
- if (!(pict = GlobalLock( data ))) return hr;
- size = GetMetaFileBitsEx( pict->hMF, 0, NULL );
- if ((bits = HeapAlloc( GetProcessHeap(), 0, size )))
- {
GetMetaFileBitsEx( pict->hMF, size, bits );
med->u.hEnhMetaFile = SetWinMetaFileBits( size, bits, NULL, pict );
HeapFree( GetProcessHeap(), 0, bits );
med->tymed = TYMED_ENHMF;
med->pUnkForRelease = NULL;
hr = S_OK;
- }
- GlobalUnlock( data );
- return hr;
+}
static HRESULT load_mf_pict( DataCacheEntry *cache_entry, IStream *stm ) { HRESULT hr; @@ -701,7 +764,61 @@ 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 );
ReleaseStgMedium( &cache_entry->stgmedium );
}
if (SUCCEEDED( hr ))
cache_entry->stgmedium = stgmed;
- }
- else
- {
STATSTG stat;
BYTE *data;
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, data + (read - size_bits) );
cache_entry->stgmedium.tymed = TYMED_ENHMF;
cache_entry->stgmedium.pUnkForRelease = NULL;
HeapFree( GetProcessHeap(), 0, data );
}
- }
- return hr;
}
/************************************************************************ @@ -736,6 +853,10 @@ static HRESULT DataCacheEntry_LoadData(DataCacheEntry *cache_entry, IStorage *st hr = load_dib( cache_entry, stm ); break;
- case CF_ENHMETAFILE:
hr = load_emf( cache_entry, stm );
break;
- default: FIXME( "Unimplemented clip format %x\n", cache_entry->fmtetc.cfFormat ); hr = E_NOTIMPL;
@@ -1030,45 +1151,6 @@ static HRESULT DataCacheEntry_Save(DataCacheEntry *cache_entry, IStorage *storag return hr; }
-/* helper for copying STGMEDIUM of type bitmap, MF, EMF or HGLOBAL. -* does no checking of whether src_stgm has a supported tymed, so this should be -* done in the caller */ -static HRESULT copy_stg_medium(CLIPFORMAT cf, STGMEDIUM *dest_stgm,
const STGMEDIUM *src_stgm)
-{
- if (src_stgm->tymed == TYMED_MFPICT)
- {
const METAFILEPICT *src_mfpict = GlobalLock(src_stgm->u.hMetaFilePict);
METAFILEPICT *dest_mfpict;
if (!src_mfpict)
return DV_E_STGMEDIUM;
dest_stgm->u.hMetaFilePict = GlobalAlloc(GMEM_MOVEABLE, sizeof(METAFILEPICT));
dest_mfpict = GlobalLock(dest_stgm->u.hMetaFilePict);
if (!dest_mfpict)
{
GlobalUnlock(src_stgm->u.hMetaFilePict);
return E_OUTOFMEMORY;
}
*dest_mfpict = *src_mfpict;
dest_mfpict->hMF = CopyMetaFileW(src_mfpict->hMF, NULL);
GlobalUnlock(src_stgm->u.hMetaFilePict);
GlobalUnlock(dest_stgm->u.hMetaFilePict);
- }
- else if (src_stgm->tymed != TYMED_NULL)
- {
dest_stgm->u.hGlobal = OleDuplicateData(src_stgm->u.hGlobal, cf,
GMEM_MOVEABLE);
if (!dest_stgm->u.hGlobal)
return E_OUTOFMEMORY;
- }
- dest_stgm->tymed = src_stgm->tymed;
- dest_stgm->pUnkForRelease = src_stgm->pUnkForRelease;
- if (dest_stgm->pUnkForRelease)
IUnknown_AddRef(dest_stgm->pUnkForRelease);
- return S_OK;
-}
static HRESULT synthesize_dib( HBITMAP bm, STGMEDIUM *med ) { HDC hdc = GetDC( 0 ); @@ -1118,30 +1200,6 @@ static HRESULT synthesize_bitmap( HGLOBAL dib, STGMEDIUM *med ) return hr; }
-static HRESULT synthesize_emf( HMETAFILEPICT data, STGMEDIUM *med ) -{
- METAFILEPICT *pict;
- HRESULT hr = E_FAIL;
- UINT size;
- void *bits;
- if (!(pict = GlobalLock( data ))) return hr;
- size = GetMetaFileBitsEx( pict->hMF, 0, NULL );
- if ((bits = HeapAlloc( GetProcessHeap(), 0, size )))
- {
GetMetaFileBitsEx( pict->hMF, size, bits );
med->u.hEnhMetaFile = SetWinMetaFileBits( size, bits, NULL, pict );
HeapFree( GetProcessHeap(), 0, bits );
med->tymed = TYMED_ENHMF;
med->pUnkForRelease = NULL;
hr = S_OK;
- }
- GlobalUnlock( data );
- return hr;
-}
static HRESULT DataCacheEntry_SetData(DataCacheEntry *cache_entry, const FORMATETC *formatetc, STGMEDIUM *stgmedium, -- 2.14.1