Commit f8a9ca2c authored by Huw Davies's avatar Huw Davies Committed by Alexandre Julliard

ole32: Add support for getting global handle objects from a flushed clipboard.

parent 718831b7
...@@ -904,20 +904,76 @@ end: ...@@ -904,20 +904,76 @@ end:
return hr; 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 * snapshot_GetData
*/ */
static HRESULT WINAPI snapshot_GetData(IDataObject *iface, static HRESULT WINAPI snapshot_GetData(IDataObject *iface, FORMATETC *fmt,
FORMATETC *pformatetcIn, STGMEDIUM *med)
STGMEDIUM *pmedium)
{ {
snapshot *This = impl_from_IDataObject(iface); snapshot *This = impl_from_IDataObject(iface);
HANDLE h, hData = 0; HANDLE h;
HRESULT hr; 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; if ( !OpenClipboard(NULL)) return CLIPBRD_E_CANT_OPEN;
...@@ -926,43 +982,39 @@ static HRESULT WINAPI snapshot_GetData(IDataObject *iface, ...@@ -926,43 +982,39 @@ static HRESULT WINAPI snapshot_GetData(IDataObject *iface,
if(This->data) if(This->data)
{ {
hr = IDataObject_GetData(This->data, pformatetcIn, pmedium); hr = IDataObject_GetData(This->data, fmt, med);
CloseClipboard(); CloseClipboard();
return hr; return hr;
} }
h = GetClipboardData(fmt->cfFormat);
if(!h)
{
hr = DV_E_FORMATETC;
goto end;
}
/* hr = get_priv_data(&enum_data);
* Otherwise, get the data from the windows clipboard using GetClipboardData if(FAILED(hr)) goto end;
*/
if ( pformatetcIn->lindex != -1 )
{
hr = DV_E_FORMATETC;
goto end;
}
if ( (pformatetcIn->tymed & TYMED_HGLOBAL) != TYMED_HGLOBAL )
{
hr = DV_E_TYMED;
goto end;
}
h = GetClipboardData(pformatetcIn->cfFormat); entry = find_format_in_list(enum_data->entries, enum_data->count, fmt->cfFormat);
hr = dup_global_mem(h, GMEM_MOVEABLE, &hData); if(entry)
mask = fmt->tymed & entry->fmtetc.tymed;
else /* non-Ole format */
mask = fmt->tymed & TYMED_HGLOBAL;
/* if(mask & TYMED_HGLOBAL)
* Return the clipboard data in the storage medium structure hr = get_stgmed_for_global(h, med);
*/ else
pmedium->tymed = (hData == 0) ? TYMED_NULL : TYMED_HGLOBAL; {
pmedium->u.hGlobal = hData; FIXME("Unhandled tymed - emum tymed %x req tymed %x\n", entry->fmtetc.tymed, fmt->tymed);
pmedium->pUnkForRelease = NULL; hr = E_FAIL;
goto end;
}
end: end:
if ( !CloseClipboard() ) return CLIPBRD_E_CANT_CLOSE; if ( !CloseClipboard() ) hr = CLIPBRD_E_CANT_CLOSE;
return hr;
if(FAILED(hr)) return hr;
return (hData == 0) ? DV_E_FORMATETC : S_OK;
} }
/************************************************************************ /************************************************************************
...@@ -1029,8 +1081,7 @@ static HRESULT WINAPI snapshot_SetData(IDataObject *iface, FORMATETC *fmt, ...@@ -1029,8 +1081,7 @@ static HRESULT WINAPI snapshot_SetData(IDataObject *iface, FORMATETC *fmt,
static HRESULT WINAPI snapshot_EnumFormatEtc(IDataObject *iface, DWORD dir, static HRESULT WINAPI snapshot_EnumFormatEtc(IDataObject *iface, DWORD dir,
IEnumFORMATETC **enum_fmt) IEnumFORMATETC **enum_fmt)
{ {
HRESULT hr = S_OK; HRESULT hr;
HGLOBAL handle;
ole_priv_data *data = NULL; ole_priv_data *data = NULL;
TRACE("(%p, %x, %p)\n", iface, dir, enum_fmt); TRACE("(%p, %x, %p)\n", iface, dir, enum_fmt);
...@@ -1040,26 +1091,8 @@ static HRESULT WINAPI snapshot_EnumFormatEtc(IDataObject *iface, DWORD dir, ...@@ -1040,26 +1091,8 @@ static HRESULT WINAPI snapshot_EnumFormatEtc(IDataObject *iface, DWORD dir,
if ( dir != DATADIR_GET ) return E_NOTIMPL; if ( dir != DATADIR_GET ) return E_NOTIMPL;
if ( !OpenClipboard(NULL) ) return CLIPBRD_E_CANT_OPEN; if ( !OpenClipboard(NULL) ) return CLIPBRD_E_CANT_OPEN;
handle = GetClipboardData( ole_priv_data_clipboard_format ); hr = get_priv_data(&data);
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);
}
}
if(!data) hr = create_empty_priv_data(&data);
if(FAILED(hr)) goto end; if(FAILED(hr)) goto end;
hr = enum_fmtetc_construct( data, 0, enum_fmt ); hr = enum_fmtetc_construct( data, 0, enum_fmt );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment