From 51c8fa65740ce9b3c041493fba052500d0f82e7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20G=C3=B3mez=20Del=20Real?= Date: Tue, 28 Nov 2017 13:01:06 -0500 Subject: [PATCH] ole32: Add DIB saving in data cache, and relevant tests. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sergio Gómez Del Real Signed-off-by: Huw Davies Signed-off-by: Alexandre Julliard --- dlls/ole32/datacache.c | 49 +++++++++++++++++++++++++++++++++++------ dlls/ole32/tests/ole2.c | 35 +++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+), 7 deletions(-) diff --git a/dlls/ole32/datacache.c b/dlls/ole32/datacache.c index 0256957419e..da7a536835b 100644 --- a/dlls/ole32/datacache.c +++ b/dlls/ole32/datacache.c @@ -838,6 +838,29 @@ static HRESULT DataCacheEntry_Save(DataCacheEntry *cache_entry, IStorage *storag } break; } + case CF_DIB: + { + header.dwSize = GlobalSize(cache_entry->stgmedium.u.hGlobal); + if (header.dwSize) + { + const BITMAPINFO *bmi = GlobalLock(cache_entry->stgmedium.u.hGlobal); + /* Size in units of 0.01mm (ie. MM_HIMETRIC) */ + if (bmi->bmiHeader.biXPelsPerMeter != 0 && bmi->bmiHeader.biYPelsPerMeter != 0) + { + header.dwObjectExtentX = MulDiv( bmi->bmiHeader.biWidth, 100000, bmi->bmiHeader.biXPelsPerMeter ); + header.dwObjectExtentY = MulDiv( bmi->bmiHeader.biHeight, 100000, bmi->bmiHeader.biYPelsPerMeter ); + } + else + { + HDC hdc = GetDC(0); + header.dwObjectExtentX = MulDiv( bmi->bmiHeader.biWidth, 2540, GetDeviceCaps(hdc, LOGPIXELSX) ); + header.dwObjectExtentY = MulDiv( bmi->bmiHeader.biHeight, 2540, GetDeviceCaps(hdc, LOGPIXELSY) ); + ReleaseDC(0, hdc); + } + GlobalUnlock(cache_entry->stgmedium.u.hGlobal); + } + break; + } default: break; } @@ -866,20 +889,32 @@ static HRESULT DataCacheEntry_Save(DataCacheEntry *cache_entry, IStorage *storag IStream_Release(pres_stream); return DV_E_STGMEDIUM; } - data = HeapAlloc(GetProcessHeap(), 0, header.dwSize); - GetMetaFileBitsEx(mfpict->hMF, header.dwSize, data); - GlobalUnlock(cache_entry->stgmedium.u.hMetaFilePict); + if (header.dwSize) + { + data = HeapAlloc(GetProcessHeap(), 0, header.dwSize); + GetMetaFileBitsEx(mfpict->hMF, header.dwSize, data); + GlobalUnlock(cache_entry->stgmedium.u.hMetaFilePict); + if (data) + { + hr = IStream_Write(pres_stream, data, header.dwSize, NULL); + HeapFree(GetProcessHeap(), 0, data); + } + } } break; } + case CF_DIB: + { + data = GlobalLock(cache_entry->stgmedium.u.hGlobal); + if (header.dwSize) + hr = IStream_Write(pres_stream, data, header.dwSize, NULL); + GlobalUnlock(cache_entry->stgmedium.u.hGlobal); + break; + } default: break; } - if (data) - hr = IStream_Write(pres_stream, data, header.dwSize, NULL); - HeapFree(GetProcessHeap(), 0, data); - IStream_Release(pres_stream); return hr; } diff --git a/dlls/ole32/tests/ole2.c b/dlls/ole32/tests/ole2.c index 59a0fe172fd..88ad207521a 100644 --- a/dlls/ole32/tests/ole2.c +++ b/dlls/ole32/tests/ole2.c @@ -4092,6 +4092,12 @@ static IStorage *create_storage_from_def(const struct storage_def *stg_def) return stg; } +static const BYTE dib_inf[] = +{ + 0x42, 0x4d, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x36, 0x00, 0x00, 0x00 +}; + static const BYTE mf_rec[] = { 0xd7, 0xcd, 0xc6, 0x9a, 0x00, 0x00, 0x00, 0x00, @@ -4107,6 +4113,23 @@ static void get_stgdef(struct storage_def *stg_def, CLIPFORMAT cf, STGMEDIUM *st switch (cf) { + case CF_DIB: + data_size = sizeof(dib); + if (!strcmp(stg_def->stream[stm_idx].name, "CONTENTS")) + { + data_size += sizeof(dib_inf); + data = HeapAlloc(GetProcessHeap(), 0, data_size); + memcpy(data, dib_inf, sizeof(dib_inf)); + memcpy(data + sizeof(dib_inf), dib, sizeof(dib)); + } + else + { + data = HeapAlloc(GetProcessHeap(), 0, data_size); + memcpy(data, dib, sizeof(dib)); + } + stg_def->stream[stm_idx].data = data; + stg_def->stream[stm_idx].data_size = data_size; + break; case CF_METAFILEPICT: mfpict = GlobalLock(U(stg_med)->hMetaFilePict); data_size = GetMetaFileBitsEx(mfpict->hMF, 0, NULL); @@ -4133,6 +4156,9 @@ static void get_stgmedium(CLIPFORMAT cfFormat, STGMEDIUM *stgmedium) { switch (cfFormat) { + case CF_DIB: + create_dib(stgmedium); + break; case CF_METAFILEPICT: create_mfpict(stgmedium); break; @@ -4162,6 +4188,15 @@ static void test_data_cache_save_data(void) static struct tests_data_cache *pdata, data[] = { + { + { + { CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, + }, + 1, 1, &CLSID_WineTest, + { + &CLSID_WineTest, 1, { { "\2OlePres000", CF_DIB, DVASPECT_CONTENT, 0, NULL, 0 } } + } + }, { { { CF_METAFILEPICT, 0, DVASPECT_CONTENT, -1, TYMED_MFPICT },