Huw Davies : ole32: Add support for getting global handle objects from a flushed clipboard.
Alexandre Julliard
julliard at winehq.org
Thu Apr 16 14:34:51 CDT 2009
Module: wine
Branch: master
Commit: f8a9ca2cface5a57088a139ca4e082004a12a15f
URL: http://source.winehq.org/git/wine.git/?a=commit;h=f8a9ca2cface5a57088a139ca4e082004a12a15f
Author: Huw Davies <huw at 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 );
More information about the wine-cvs
mailing list