[PATCH 1/5] ole32: Refactor OLE's data cache Save implementation.
Sergio Gómez Del Real
sdelreal at codeweavers.com
Wed Dec 6 09:52:23 CST 2017
Signed-off-by: Sergio Gómez Del Real <sdelreal at codeweavers.com>
---
dlls/ole32/datacache.c | 239 ++++++++++++++++++++++++-------------------------
1 file changed, 119 insertions(+), 120 deletions(-)
diff --git a/dlls/ole32/datacache.c b/dlls/ole32/datacache.c
index c550c75cd3..f46f71215d 100644
--- a/dlls/ole32/datacache.c
+++ b/dlls/ole32/datacache.c
@@ -775,16 +775,118 @@ static HRESULT DataCacheEntry_LoadData(DataCacheEntry *cache_entry)
return hr;
}
-static HRESULT DataCacheEntry_CreateStream(DataCacheEntry *cache_entry,
- IStorage *storage, IStream **stream)
+static void init_stream_header(DataCacheEntry *entry, PresentationDataHeader *header)
{
- WCHAR wszName[] = {2,'O','l','e','P','r','e','s',
+ if (entry->fmtetc.ptd)
+ FIXME("ptd not serialized\n");
+ header->tdSize = sizeof(header->tdSize);
+ header->dvAspect = entry->fmtetc.dwAspect;
+ header->lindex = entry->fmtetc.lindex;
+ header->advf = entry->advise_flags;
+ header->unknown7 = 0;
+ header->dwObjectExtentX = 0;
+ header->dwObjectExtentY = 0;
+ header->dwSize = 0;
+}
+
+static HRESULT save_dib(DataCacheEntry *entry, BOOL contents, IStream *stream)
+{
+ HRESULT hr = S_OK;
+ int data_size = GlobalSize(entry->stgmedium.u.hGlobal);
+ BITMAPINFO *bmi = GlobalLock(entry->stgmedium.u.hGlobal);
+
+ if (!contents)
+ {
+ PresentationDataHeader header;
+
+ init_stream_header(entry, &header);
+ hr = write_clipformat(stream, entry->fmtetc.cfFormat);
+ if (FAILED(hr)) goto end;
+ if (data_size)
+ {
+ header.dwSize = data_size;
+ /* 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);
+ }
+ }
+ hr = IStream_Write(stream, &header, sizeof(PresentationDataHeader), NULL);
+ if (hr == S_OK && data_size)
+ hr = IStream_Write(stream, bmi, data_size, NULL);
+ }
+
+end:
+ if (bmi) GlobalUnlock(entry->stgmedium.u.hGlobal);
+ return hr;
+}
+
+static HRESULT save_mfpict(DataCacheEntry *entry, BOOL contents, IStream *stream)
+{
+ HRESULT hr = S_OK;
+ int data_size = 0;
+ void *data = NULL;
+ METAFILEPICT *mfpict = NULL;
+
+ if (!contents)
+ {
+ PresentationDataHeader header;
+
+ init_stream_header(entry, &header);
+ hr = write_clipformat(stream, entry->fmtetc.cfFormat);
+ if (FAILED(hr)) return hr;
+ if (entry->stgmedium.tymed != TYMED_NULL)
+ {
+ mfpict = GlobalLock(entry->stgmedium.u.hMetaFilePict);
+ if (!mfpict)
+ return DV_E_STGMEDIUM;
+ data_size = GetMetaFileBitsEx(mfpict->hMF, 0, NULL);
+ header.dwObjectExtentX = mfpict->xExt;
+ header.dwObjectExtentY = mfpict->yExt;
+ header.dwSize = data_size;
+ data = HeapAlloc(GetProcessHeap(), 0, header.dwSize);
+ if (!data)
+ {
+ GlobalUnlock(entry->stgmedium.u.hMetaFilePict);
+ return E_OUTOFMEMORY;
+ }
+ GetMetaFileBitsEx(mfpict->hMF, header.dwSize, data);
+ GlobalUnlock(entry->stgmedium.u.hMetaFilePict);
+ }
+ hr = IStream_Write(stream, &header, sizeof(PresentationDataHeader), NULL);
+ if (hr == S_OK && data_size)
+ hr = IStream_Write(stream, data, data_size, NULL);
+ HeapFree(GetProcessHeap(), 0, data);
+ }
+
+ return hr;
+}
+
+static const WCHAR CONTENTS[] = {'C','O','N','T','E','N','T','S',0};
+
+static HRESULT create_stream(DataCacheEntry *cache_entry, IStorage *storage,
+ BOOL contents, IStream **stream)
+{
+ WCHAR pres[] = {2,'O','l','e','P','r','e','s',
'0' + (cache_entry->stream_number / 100) % 10,
'0' + (cache_entry->stream_number / 10) % 10,
'0' + cache_entry->stream_number % 10, 0};
+ const WCHAR *name;
- /* FIXME: cache the created stream in This? */
- return IStorage_CreateStream(storage, wszName,
+ if (contents)
+ name = CONTENTS;
+ else
+ name = pres;
+
+ return IStorage_CreateStream(storage, name,
STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE,
0, 0, stream);
}
@@ -792,130 +894,29 @@ static HRESULT DataCacheEntry_CreateStream(DataCacheEntry *cache_entry,
static HRESULT DataCacheEntry_Save(DataCacheEntry *cache_entry, IStorage *storage,
BOOL same_as_load)
{
- PresentationDataHeader header;
HRESULT hr;
- IStream *pres_stream;
- void *data = NULL;
+ IStream *stream;
+ BOOL contents = (cache_entry->id == 1);
TRACE("stream_number = %d, fmtetc = %s\n", cache_entry->stream_number, debugstr_formatetc(&cache_entry->fmtetc));
- hr = DataCacheEntry_CreateStream(cache_entry, storage, &pres_stream);
+ hr = create_stream(cache_entry, storage, contents, &stream);
if (FAILED(hr))
return hr;
- hr = write_clipformat(pres_stream, cache_entry->fmtetc.cfFormat);
- if (FAILED(hr))
- return hr;
-
- if (cache_entry->fmtetc.ptd)
- FIXME("ptd not serialized\n");
- header.tdSize = sizeof(header.tdSize);
- header.dvAspect = cache_entry->fmtetc.dwAspect;
- header.lindex = cache_entry->fmtetc.lindex;
- header.advf = cache_entry->advise_flags;
- header.unknown7 = 0;
- header.dwObjectExtentX = 0;
- header.dwObjectExtentY = 0;
- header.dwSize = 0;
-
- /* size the data */
- switch (cache_entry->fmtetc.cfFormat)
- {
- case CF_METAFILEPICT:
- {
- if (cache_entry->stgmedium.tymed != TYMED_NULL)
- {
- const METAFILEPICT *mfpict = GlobalLock(cache_entry->stgmedium.u.hMetaFilePict);
- if (!mfpict)
- {
- IStream_Release(pres_stream);
- return DV_E_STGMEDIUM;
- }
- header.dwObjectExtentX = mfpict->xExt;
- header.dwObjectExtentY = mfpict->yExt;
- header.dwSize = GetMetaFileBitsEx(mfpict->hMF, 0, NULL);
- GlobalUnlock(cache_entry->stgmedium.u.hMetaFilePict);
- }
- 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;
- }
-
- /*
- * Write the header.
- */
- hr = IStream_Write(pres_stream, &header, sizeof(PresentationDataHeader),
- NULL);
- if (FAILED(hr))
- {
- IStream_Release(pres_stream);
- return hr;
- }
-
- /* get the data */
switch (cache_entry->fmtetc.cfFormat)
{
- case CF_METAFILEPICT:
- {
- if (cache_entry->stgmedium.tymed != TYMED_NULL)
- {
- const METAFILEPICT *mfpict = GlobalLock(cache_entry->stgmedium.u.hMetaFilePict);
- if (!mfpict)
- {
- IStream_Release(pres_stream);
- return DV_E_STGMEDIUM;
- }
- 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;
+ case CF_DIB:
+ hr = save_dib(cache_entry, contents, stream);
+ break;
+ case CF_METAFILEPICT:
+ hr = save_mfpict(cache_entry, contents, stream);
+ break;
+ default:
+ FIXME("got unsupported clipboard format %x\n", cache_entry->fmtetc.cfFormat);
}
- IStream_Release(pres_stream);
+ IStream_Release(stream);
return hr;
}
@@ -1651,8 +1652,6 @@ static HRESULT parse_contents_stream( DataCache *This, IStorage *stg, IStream *s
return add_cache_entry( This, fmt, 0, stm, contents_stream );
}
-static const WCHAR CONTENTS[] = {'C','O','N','T','E','N','T','S',0};
-
/************************************************************************
* DataCache_Load (IPersistStorage)
*
--
2.14.1
More information about the wine-devel
mailing list