Module: wine Branch: master Commit: 01c6002a490d986b6959f2f62aeef488877dd48b URL: https://source.winehq.org/git/wine.git/?a=commit;h=01c6002a490d986b6959f2f62...
Author: Piotr Caban piotr@codeweavers.com Date: Wed Sep 26 14:52:39 2018 +0200
ole32: Improve OleClipboardData GetData implementation.
Signed-off-by: Piotr Caban piotr@codeweavers.com Signed-off-by: Huw Davies huw@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/ole32/clipboard.c | 47 +++++++++++++++++++++++++++++++++++--------- dlls/ole32/tests/clipboard.c | 14 ++++++------- 2 files changed, 45 insertions(+), 16 deletions(-)
diff --git a/dlls/ole32/clipboard.c b/dlls/ole32/clipboard.c index cb005d3..7ee611f 100644 --- a/dlls/ole32/clipboard.c +++ b/dlls/ole32/clipboard.c @@ -1296,6 +1296,14 @@ static HRESULT get_stgmed_for_storage(HGLOBAL h, STGMEDIUM *med) return hr; }
+ hr = StgIsStorageILockBytes(lbs); + if(hr!=S_OK) + { + ILockBytes_Release(lbs); + GlobalFree(dst); + return SUCCEEDED(hr) ? E_FAIL : hr; + } + hr = StgOpenStorageOnILockBytes(lbs, NULL, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, NULL, 0, &med->u.pstg); ILockBytes_Release(lbs); if(FAILED(hr)) @@ -1402,12 +1410,19 @@ static HRESULT WINAPI snapshot_GetData(IDataObject *iface, FORMATETC *fmt, if(This->data) { hr = IDataObject_GetData(This->data, fmt, med); - CloseClipboard(); - return hr; + if(SUCCEEDED(hr)) + { + CloseClipboard(); + return hr; + } + } + if(fmt->lindex != -1) + { + hr = DV_E_FORMATETC; + goto end; }
- h = GetClipboardData(fmt->cfFormat); - if(!h) + if(!IsClipboardFormatAvailable(fmt->cfFormat)) { hr = DV_E_FORMATETC; goto end; @@ -1425,17 +1440,31 @@ static HRESULT WINAPI snapshot_GetData(IDataObject *iface, FORMATETC *fmt, goto end; } mask = fmt->tymed & entry->fmtetc.tymed; - if(!mask) mask = fmt->tymed & (TYMED_ISTREAM | TYMED_HGLOBAL); + if(!mask && (entry->fmtetc.tymed & (TYMED_ISTREAM | TYMED_HGLOBAL | TYMED_ISTORAGE))) + mask = fmt->tymed & (TYMED_ISTREAM | TYMED_HGLOBAL | TYMED_ISTORAGE); } else /* non-Ole format */ - mask = fmt->tymed & TYMED_HGLOBAL; + mask = fmt->tymed & get_tymed_from_nonole_cf(fmt->cfFormat);
- if(mask & TYMED_ISTORAGE) - hr = get_stgmed_for_storage(h, med); - else if(mask & TYMED_HGLOBAL) + if(!mask) + { + hr = DV_E_TYMED; + goto end; + } + + h = GetClipboardData(fmt->cfFormat); + if(!h) + { + hr = DV_E_FORMATETC; + goto end; + } + + if(mask & TYMED_HGLOBAL) hr = get_stgmed_for_global(h, med); else if(mask & TYMED_ISTREAM) hr = get_stgmed_for_stream(h, med); + else if(mask & TYMED_ISTORAGE) + hr = get_stgmed_for_storage(h, med); else if(mask & TYMED_ENHMF) hr = get_stgmed_for_emf((HENHMETAFILE)h, med); else if(mask & TYMED_GDI) diff --git a/dlls/ole32/tests/clipboard.c b/dlls/ole32/tests/clipboard.c index dc3ce5a..f5ad98e 100644 --- a/dlls/ole32/tests/clipboard.c +++ b/dlls/ole32/tests/clipboard.c @@ -586,12 +586,12 @@ static void test_get_clipboard(void)
InitFormatEtc(fmtetc, CF_RIFF, TYMED_HGLOBAL); hr = IDataObject_GetData(data_obj, &fmtetc, &stgmedium); - todo_wine ok(hr == DV_E_FORMATETC, "IDataObject_GetData should have failed with DV_E_FORMATETC instead of 0x%08x\n", hr); + ok(hr == DV_E_FORMATETC, "IDataObject_GetData should have failed with DV_E_FORMATETC instead of 0x%08x\n", hr); if(SUCCEEDED(hr)) ReleaseStgMedium(&stgmedium);
InitFormatEtc(fmtetc, CF_TEXT, TYMED_FILE); hr = IDataObject_GetData(data_obj, &fmtetc, &stgmedium); - todo_wine ok(hr == DV_E_TYMED, "IDataObject_GetData should have failed with DV_E_TYMED instead of 0x%08x\n", hr); + ok(hr == DV_E_TYMED, "IDataObject_GetData should have failed with DV_E_TYMED instead of 0x%08x\n", hr); if(SUCCEEDED(hr)) ReleaseStgMedium(&stgmedium);
ok(DataObjectImpl_GetData_calls == 6, "DataObjectImpl_GetData should have been called 6 times instead of %d times\n", DataObjectImpl_GetData_calls); @@ -878,20 +878,20 @@ static void test_complex_get_clipboard(void)
InitFormatEtc(fmtetc, CF_METAFILEPICT, TYMED_HGLOBAL); hr = IDataObject_GetData(data_obj, &fmtetc, &stgmedium); - todo_wine ok(hr == DV_E_TYMED, "IDataObject_GetData failed with error 0x%08x\n", hr); + ok(hr == DV_E_TYMED, "IDataObject_GetData failed with error 0x%08x\n", hr); if(SUCCEEDED(hr)) ReleaseStgMedium(&stgmedium);
InitFormatEtc(fmtetc, CF_ENHMETAFILE, TYMED_HGLOBAL); hr = IDataObject_GetData(data_obj, &fmtetc, &stgmedium); - todo_wine ok(hr == DV_E_TYMED, "IDataObject_GetData failed with error 0x%08x\n", hr); + ok(hr == DV_E_TYMED, "IDataObject_GetData failed with error 0x%08x\n", hr); if(SUCCEEDED(hr)) ReleaseStgMedium(&stgmedium);
InitFormatEtc(fmtetc, CF_ENHMETAFILE, TYMED_ENHMF); hr = IDataObject_GetData(data_obj, &fmtetc, &stgmedium); - todo_wine ok(hr == S_OK, "IDataObject_GetData failed with error 0x%08x\n", hr); + ok(hr == S_OK, "IDataObject_GetData failed with error 0x%08x\n", hr); if(SUCCEEDED(hr)) ReleaseStgMedium(&stgmedium);
- todo_wine ok(DataObjectImpl_GetData_calls == 5, + ok(DataObjectImpl_GetData_calls == 5, "DataObjectImpl_GetData called 5 times instead of %d times\n", DataObjectImpl_GetData_calls); IDataObject_Release(data_obj); @@ -1422,7 +1422,7 @@ static void test_flushed_getdata(void) /* CF_ENHMETAFILE format */ InitFormatEtc(fmt, CF_ENHMETAFILE, TYMED_ENHMF); hr = IDataObject_GetData(get, &fmt, &med); - todo_wine ok(hr == S_OK, "got %08x\n", hr); + ok(hr == S_OK, "got %08x\n", hr); if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
IDataObject_Release(get);