mirror of
https://github.com/reactos/wine.git
synced 2025-02-02 18:25:19 +00:00
ole32: Implement GetDataHere.
This commit is contained in:
parent
8a03ac58c5
commit
66d04f8eb6
@ -1197,7 +1197,7 @@ static HRESULT WINAPI snapshot_GetData(IDataObject *iface, FORMATETC *fmt,
|
||||
hr = get_stgmed_for_stream(h, med);
|
||||
else
|
||||
{
|
||||
FIXME("Unhandled tymed - emum tymed %x req tymed %x\n", entry->fmtetc.tymed, fmt->tymed);
|
||||
FIXME("Unhandled tymed - mask %x req tymed %x\n", mask, fmt->tymed);
|
||||
hr = E_FAIL;
|
||||
goto end;
|
||||
}
|
||||
@ -1214,8 +1214,108 @@ end:
|
||||
static HRESULT WINAPI snapshot_GetDataHere(IDataObject *iface, FORMATETC *fmt,
|
||||
STGMEDIUM *med)
|
||||
{
|
||||
FIXME("(%p, %p {%s}, %p): stub\n", iface, fmt, dump_fmtetc(fmt), med);
|
||||
return E_NOTIMPL;
|
||||
snapshot *This = impl_from_IDataObject(iface);
|
||||
HANDLE h;
|
||||
HRESULT hr;
|
||||
ole_priv_data *enum_data = NULL;
|
||||
ole_priv_data_entry *entry;
|
||||
TYMED supported;
|
||||
|
||||
TRACE("(%p, %p {%s}, %p (tymed %x)\n", iface, fmt, dump_fmtetc(fmt), med, med->tymed);
|
||||
|
||||
if ( !fmt || !med ) return E_INVALIDARG;
|
||||
|
||||
if ( !OpenClipboard(NULL)) return CLIPBRD_E_CANT_OPEN;
|
||||
|
||||
if(!This->data)
|
||||
hr = get_current_dataobject(&This->data);
|
||||
|
||||
if(This->data)
|
||||
{
|
||||
hr = IDataObject_GetDataHere(This->data, fmt, med);
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
CloseClipboard();
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
|
||||
h = GetClipboardData(fmt->cfFormat);
|
||||
if(!h)
|
||||
{
|
||||
hr = DV_E_FORMATETC;
|
||||
goto end;
|
||||
}
|
||||
|
||||
hr = get_priv_data(&enum_data);
|
||||
if(FAILED(hr)) goto end;
|
||||
|
||||
entry = find_format_in_list(enum_data->entries, enum_data->count, fmt->cfFormat);
|
||||
if(entry)
|
||||
{
|
||||
if(!td_equal(fmt->ptd, entry->fmtetc.ptd))
|
||||
{
|
||||
hr = DV_E_FORMATETC;
|
||||
goto end;
|
||||
}
|
||||
supported = entry->fmtetc.tymed;
|
||||
}
|
||||
else /* non-Ole format */
|
||||
supported = TYMED_HGLOBAL;
|
||||
|
||||
switch(med->tymed)
|
||||
{
|
||||
case TYMED_HGLOBAL:
|
||||
{
|
||||
DWORD src_size = GlobalSize(h);
|
||||
DWORD dst_size = GlobalSize(med->u.hGlobal);
|
||||
hr = E_FAIL;
|
||||
if(dst_size >= src_size)
|
||||
{
|
||||
void *src = GlobalLock(h);
|
||||
void *dst = GlobalLock(med->u.hGlobal);
|
||||
|
||||
memcpy(dst, src, src_size);
|
||||
GlobalUnlock(med->u.hGlobal);
|
||||
GlobalUnlock(h);
|
||||
hr = S_OK;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TYMED_ISTREAM:
|
||||
{
|
||||
DWORD src_size = GlobalSize(h);
|
||||
void *src = GlobalLock(h);
|
||||
hr = IStream_Write(med->u.pstm, src, src_size, NULL);
|
||||
GlobalUnlock(h);
|
||||
break;
|
||||
}
|
||||
case TYMED_ISTORAGE:
|
||||
{
|
||||
STGMEDIUM copy;
|
||||
if(!(supported & TYMED_ISTORAGE))
|
||||
{
|
||||
hr = E_FAIL;
|
||||
goto end;
|
||||
}
|
||||
hr = get_stgmed_for_storage(h, ©);
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
hr = IStorage_CopyTo(copy.u.pstg, 0, NULL, NULL, med->u.pstg);
|
||||
ReleaseStgMedium(©);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
FIXME("Unhandled tymed - supported %x req tymed %x\n", supported, med->tymed);
|
||||
hr = E_FAIL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
end:
|
||||
HeapFree(GetProcessHeap(), 0, enum_data);
|
||||
if ( !CloseClipboard() ) hr = CLIPBRD_E_CANT_CLOSE;
|
||||
return hr;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
|
@ -1361,10 +1361,160 @@ static void test_nonole_clipboard(void)
|
||||
OleUninitialize();
|
||||
}
|
||||
|
||||
static void test_getdatahere(void)
|
||||
{
|
||||
HRESULT hr;
|
||||
IDataObject *src, *get;
|
||||
FORMATETC fmt;
|
||||
STGMEDIUM med;
|
||||
|
||||
OleInitialize(NULL);
|
||||
|
||||
hr = DataObjectImpl_CreateComplex(&src);
|
||||
ok(hr == S_OK, "got %08x\n", hr);
|
||||
|
||||
hr = OleSetClipboard(src);
|
||||
ok(hr == S_OK, "got %08x\n", hr);
|
||||
|
||||
hr = OleGetClipboard(&get);
|
||||
ok(hr == S_OK, "got %08x\n", hr);
|
||||
|
||||
/* global format -> global & stream */
|
||||
|
||||
DataObjectImpl_GetData_calls = 0;
|
||||
DataObjectImpl_GetDataHere_calls = 0;
|
||||
|
||||
InitFormatEtc(fmt, CF_TEXT, TYMED_HGLOBAL);
|
||||
|
||||
med.pUnkForRelease = NULL;
|
||||
med.tymed = TYMED_HGLOBAL;
|
||||
U(med).hGlobal = GlobalAlloc(GMEM_MOVEABLE, 100);
|
||||
hr = IDataObject_GetDataHere(get, &fmt, &med);
|
||||
ok(hr == S_OK, "got %08x\n", hr);
|
||||
ok(med.tymed == TYMED_HGLOBAL, "got %x\n", med.tymed);
|
||||
ReleaseStgMedium(&med);
|
||||
ok(DataObjectImpl_GetDataHere_calls == 1, "called %d\n", DataObjectImpl_GetDataHere_calls);
|
||||
ok(DataObjectImpl_GetData_calls == 1, "called %d\n", DataObjectImpl_GetData_calls);
|
||||
|
||||
InitFormatEtc(fmt, CF_TEXT, 0);
|
||||
|
||||
med.pUnkForRelease = NULL;
|
||||
med.tymed = TYMED_HGLOBAL;
|
||||
U(med).hGlobal = GlobalAlloc(GMEM_MOVEABLE, 100);
|
||||
hr = IDataObject_GetDataHere(get, &fmt, &med);
|
||||
ok(hr == S_OK, "got %08x\n", hr);
|
||||
ok(med.tymed == TYMED_HGLOBAL, "got %x\n", med.tymed);
|
||||
ReleaseStgMedium(&med);
|
||||
ok(DataObjectImpl_GetDataHere_calls == 2, "called %d\n", DataObjectImpl_GetDataHere_calls);
|
||||
ok(DataObjectImpl_GetData_calls == 1, "called %d\n", DataObjectImpl_GetData_calls);
|
||||
|
||||
med.pUnkForRelease = NULL;
|
||||
med.tymed = TYMED_HGLOBAL;
|
||||
U(med).hGlobal = GlobalAlloc(GMEM_MOVEABLE, 1);
|
||||
hr = IDataObject_GetDataHere(get, &fmt, &med);
|
||||
ok(hr == E_FAIL, "got %08x\n", hr);
|
||||
ok(med.tymed == TYMED_HGLOBAL, "got %x\n", med.tymed);
|
||||
ReleaseStgMedium(&med);
|
||||
ok(DataObjectImpl_GetDataHere_calls == 3, "called %d\n", DataObjectImpl_GetDataHere_calls);
|
||||
ok(DataObjectImpl_GetData_calls == 1, "called %d\n", DataObjectImpl_GetData_calls);
|
||||
|
||||
med.pUnkForRelease = NULL;
|
||||
med.tymed = TYMED_ISTREAM;
|
||||
CreateStreamOnHGlobal(NULL, TRUE, &U(med).pstm);
|
||||
hr = IDataObject_GetDataHere(get, &fmt, &med);
|
||||
ok(hr == S_OK, "got %08x\n", hr);
|
||||
ok(med.tymed == TYMED_ISTREAM, "got %x\n", med.tymed);
|
||||
ReleaseStgMedium(&med);
|
||||
ok(DataObjectImpl_GetDataHere_calls == 4, "called %d\n", DataObjectImpl_GetDataHere_calls);
|
||||
ok(DataObjectImpl_GetData_calls == 1, "called %d\n", DataObjectImpl_GetData_calls);
|
||||
|
||||
med.pUnkForRelease = NULL;
|
||||
med.tymed = TYMED_ISTORAGE;
|
||||
StgCreateDocfile(NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_DELETEONRELEASE, 0, &U(med).pstg);
|
||||
hr = IDataObject_GetDataHere(get, &fmt, &med);
|
||||
ok(hr == E_FAIL, "got %08x\n", hr);
|
||||
ok(med.tymed == TYMED_ISTORAGE, "got %x\n", med.tymed);
|
||||
ReleaseStgMedium(&med);
|
||||
ok(DataObjectImpl_GetDataHere_calls == 5, "called %d\n", DataObjectImpl_GetDataHere_calls);
|
||||
ok(DataObjectImpl_GetData_calls == 1, "called %d\n", DataObjectImpl_GetData_calls);
|
||||
|
||||
InitFormatEtc(fmt, cf_stream, 0);
|
||||
|
||||
med.pUnkForRelease = NULL;
|
||||
med.tymed = TYMED_HGLOBAL;
|
||||
U(med).hGlobal = GlobalAlloc(GMEM_MOVEABLE, 100);
|
||||
hr = IDataObject_GetDataHere(get, &fmt, &med);
|
||||
ok(hr == S_OK, "got %08x\n", hr);
|
||||
ok(med.tymed == TYMED_HGLOBAL, "got %x\n", med.tymed);
|
||||
ReleaseStgMedium(&med);
|
||||
ok(DataObjectImpl_GetDataHere_calls == 7, "called %d\n", DataObjectImpl_GetDataHere_calls);
|
||||
ok(DataObjectImpl_GetData_calls == 2, "called %d\n", DataObjectImpl_GetData_calls);
|
||||
|
||||
med.pUnkForRelease = NULL;
|
||||
med.tymed = TYMED_ISTREAM;
|
||||
CreateStreamOnHGlobal(NULL, TRUE, &U(med).pstm);
|
||||
hr = IDataObject_GetDataHere(get, &fmt, &med);
|
||||
ok(hr == S_OK, "got %08x\n", hr);
|
||||
ok(med.tymed == TYMED_ISTREAM, "got %x\n", med.tymed);
|
||||
ReleaseStgMedium(&med);
|
||||
ok(DataObjectImpl_GetDataHere_calls == 8, "called %d\n", DataObjectImpl_GetDataHere_calls);
|
||||
ok(DataObjectImpl_GetData_calls == 2, "called %d\n", DataObjectImpl_GetData_calls);
|
||||
|
||||
med.pUnkForRelease = NULL;
|
||||
med.tymed = TYMED_ISTORAGE;
|
||||
StgCreateDocfile(NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_DELETEONRELEASE, 0, &U(med).pstg);
|
||||
hr = IDataObject_GetDataHere(get, &fmt, &med);
|
||||
ok(hr == E_FAIL, "got %08x\n", hr);
|
||||
ok(med.tymed == TYMED_ISTORAGE, "got %x\n", med.tymed);
|
||||
ReleaseStgMedium(&med);
|
||||
ok(DataObjectImpl_GetDataHere_calls == 9, "called %d\n", DataObjectImpl_GetDataHere_calls);
|
||||
ok(DataObjectImpl_GetData_calls == 2, "called %d\n", DataObjectImpl_GetData_calls);
|
||||
|
||||
InitFormatEtc(fmt, cf_storage, 0);
|
||||
|
||||
med.pUnkForRelease = NULL;
|
||||
med.tymed = TYMED_HGLOBAL;
|
||||
U(med).hGlobal = GlobalAlloc(GMEM_MOVEABLE, 3000);
|
||||
hr = IDataObject_GetDataHere(get, &fmt, &med);
|
||||
ok(hr == S_OK, "got %08x\n", hr);
|
||||
ok(med.tymed == TYMED_HGLOBAL, "got %x\n", med.tymed);
|
||||
ReleaseStgMedium(&med);
|
||||
ok(DataObjectImpl_GetDataHere_calls == 11, "called %d\n", DataObjectImpl_GetDataHere_calls);
|
||||
ok(DataObjectImpl_GetData_calls == 3, "called %d\n", DataObjectImpl_GetData_calls);
|
||||
|
||||
med.pUnkForRelease = NULL;
|
||||
med.tymed = TYMED_ISTREAM;
|
||||
CreateStreamOnHGlobal(NULL, TRUE, &U(med).pstm);
|
||||
hr = IDataObject_GetDataHere(get, &fmt, &med);
|
||||
ok(hr == S_OK, "got %08x\n", hr);
|
||||
ok(med.tymed == TYMED_ISTREAM, "got %x\n", med.tymed);
|
||||
ReleaseStgMedium(&med);
|
||||
ok(DataObjectImpl_GetDataHere_calls == 12, "called %d\n", DataObjectImpl_GetDataHere_calls);
|
||||
ok(DataObjectImpl_GetData_calls == 3, "called %d\n", DataObjectImpl_GetData_calls);
|
||||
|
||||
med.pUnkForRelease = NULL;
|
||||
med.tymed = TYMED_ISTORAGE;
|
||||
StgCreateDocfile(NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_DELETEONRELEASE, 0, &U(med).pstg);
|
||||
hr = IDataObject_GetDataHere(get, &fmt, &med);
|
||||
ok(hr == S_OK, "got %08x\n", hr);
|
||||
ok(med.tymed == TYMED_ISTORAGE, "got %x\n", med.tymed);
|
||||
ReleaseStgMedium(&med);
|
||||
ok(DataObjectImpl_GetDataHere_calls == 13, "called %d\n", DataObjectImpl_GetDataHere_calls);
|
||||
ok(DataObjectImpl_GetData_calls == 3, "called %d\n", DataObjectImpl_GetData_calls);
|
||||
|
||||
|
||||
IDataObject_Release(get);
|
||||
IDataObject_Release(src);
|
||||
|
||||
OleUninitialize();
|
||||
|
||||
}
|
||||
|
||||
START_TEST(clipboard)
|
||||
{
|
||||
test_set_clipboard();
|
||||
test_consumer_refs();
|
||||
test_flushed_getdata();
|
||||
test_nonole_clipboard();
|
||||
test_getdatahere();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user