Module: wine Branch: master Commit: f8a9ca2cface5a57088a139ca4e082004a12a15f URL: http://source.winehq.org/git/wine.git/?a=commit;h=f8a9ca2cface5a57088a139ca4...
Author: Huw Davies huw@codeweavers.com Date: Thu Apr 16 12:32:58 2009 +0100
ole32: Add support for getting global handle objects from a flushed clipboard.
---
dlls/ole32/clipboard.c | 143 +++++++++++++++++++++++++++++------------------ 1 files changed, 88 insertions(+), 55 deletions(-)
diff --git a/dlls/ole32/clipboard.c b/dlls/ole32/clipboard.c index c1ef5d3..57a48fb 100644 --- a/dlls/ole32/clipboard.c +++ b/dlls/ole32/clipboard.c @@ -904,20 +904,76 @@ end: return hr; }
+/*********************************************************** + * get_priv_data + * + * Returns a copy of the Ole Private Data + */ +static HRESULT get_priv_data(ole_priv_data **data) +{ + HGLOBAL handle; + HRESULT hr = S_OK; + + *data = NULL; + + handle = GetClipboardData( ole_priv_data_clipboard_format ); + if(handle) + { + ole_priv_data *src = GlobalLock(handle); + if(src) + { + /* FIXME: sanity check on size */ + *data = HeapAlloc(GetProcessHeap(), 0, src->size); + if(!*data) + { + GlobalUnlock(handle); + return E_OUTOFMEMORY; + } + memcpy(*data, src, src->size); + GlobalUnlock(handle); + } + } + + if(!*data) hr = create_empty_priv_data(data); + + return hr; +} + +/************************************************************************ + * get_stgmed_for_global + * + * Returns a stg medium with a copy of the global handle + */ +static HRESULT get_stgmed_for_global(HGLOBAL h, STGMEDIUM *med) +{ + HRESULT hr; + + med->pUnkForRelease = NULL; + med->tymed = TYMED_NULL; + + hr = dup_global_mem(h, GMEM_MOVEABLE, &med->u.hGlobal); + + if(SUCCEEDED(hr)) med->tymed = TYMED_HGLOBAL; + + return hr; +} + /************************************************************************ * snapshot_GetData */ -static HRESULT WINAPI snapshot_GetData(IDataObject *iface, - FORMATETC *pformatetcIn, - STGMEDIUM *pmedium) +static HRESULT WINAPI snapshot_GetData(IDataObject *iface, FORMATETC *fmt, + STGMEDIUM *med) { snapshot *This = impl_from_IDataObject(iface); - HANDLE h, hData = 0; + HANDLE h; HRESULT hr; + ole_priv_data *enum_data = NULL; + ole_priv_data_entry *entry; + DWORD mask;
- TRACE("(%p,%p,%p)\n", iface, pformatetcIn, pmedium); + TRACE("(%p,%p,%p)\n", iface, fmt, med);
- if ( !pformatetcIn || !pmedium ) return E_INVALIDARG; + if ( !fmt || !med ) return E_INVALIDARG;
if ( !OpenClipboard(NULL)) return CLIPBRD_E_CANT_OPEN;
@@ -926,43 +982,39 @@ static HRESULT WINAPI snapshot_GetData(IDataObject *iface,
if(This->data) { - hr = IDataObject_GetData(This->data, pformatetcIn, pmedium); + hr = IDataObject_GetData(This->data, fmt, med); CloseClipboard(); return hr; }
+ h = GetClipboardData(fmt->cfFormat); + if(!h) + { + hr = DV_E_FORMATETC; + goto end; + }
- /* - * Otherwise, get the data from the windows clipboard using GetClipboardData - */ - - if ( pformatetcIn->lindex != -1 ) - { - hr = DV_E_FORMATETC; - goto end; - } - - if ( (pformatetcIn->tymed & TYMED_HGLOBAL) != TYMED_HGLOBAL ) - { - hr = DV_E_TYMED; - goto end; - } + hr = get_priv_data(&enum_data); + if(FAILED(hr)) goto end;
- h = GetClipboardData(pformatetcIn->cfFormat); - hr = dup_global_mem(h, GMEM_MOVEABLE, &hData); + entry = find_format_in_list(enum_data->entries, enum_data->count, fmt->cfFormat); + if(entry) + mask = fmt->tymed & entry->fmtetc.tymed; + else /* non-Ole format */ + mask = fmt->tymed & TYMED_HGLOBAL;
- /* - * Return the clipboard data in the storage medium structure - */ - pmedium->tymed = (hData == 0) ? TYMED_NULL : TYMED_HGLOBAL; - pmedium->u.hGlobal = hData; - pmedium->pUnkForRelease = NULL; + if(mask & TYMED_HGLOBAL) + hr = get_stgmed_for_global(h, med); + else + { + FIXME("Unhandled tymed - emum tymed %x req tymed %x\n", entry->fmtetc.tymed, fmt->tymed); + hr = E_FAIL; + goto end; + }
end: - if ( !CloseClipboard() ) return CLIPBRD_E_CANT_CLOSE; - - if(FAILED(hr)) return hr; - return (hData == 0) ? DV_E_FORMATETC : S_OK; + if ( !CloseClipboard() ) hr = CLIPBRD_E_CANT_CLOSE; + return hr; }
/************************************************************************ @@ -1029,8 +1081,7 @@ static HRESULT WINAPI snapshot_SetData(IDataObject *iface, FORMATETC *fmt, static HRESULT WINAPI snapshot_EnumFormatEtc(IDataObject *iface, DWORD dir, IEnumFORMATETC **enum_fmt) { - HRESULT hr = S_OK; - HGLOBAL handle; + HRESULT hr; ole_priv_data *data = NULL;
TRACE("(%p, %x, %p)\n", iface, dir, enum_fmt); @@ -1040,26 +1091,8 @@ static HRESULT WINAPI snapshot_EnumFormatEtc(IDataObject *iface, DWORD dir, if ( dir != DATADIR_GET ) return E_NOTIMPL; if ( !OpenClipboard(NULL) ) return CLIPBRD_E_CANT_OPEN;
- handle = GetClipboardData( ole_priv_data_clipboard_format ); - if(handle) - { - ole_priv_data *src = GlobalLock(handle); - if(src) - { - /* FIXME: sanity check on size */ - data = HeapAlloc(GetProcessHeap(), 0, src->size); - if(!data) - { - GlobalUnlock(handle); - hr = E_OUTOFMEMORY; - goto end; - } - memcpy(data, src, src->size); - GlobalUnlock(handle); - } - } + hr = get_priv_data(&data);
- if(!data) hr = create_empty_priv_data(&data); if(FAILED(hr)) goto end;
hr = enum_fmtetc_construct( data, 0, enum_fmt );