ole32: Add support for getting global handle objects from a flushed clipboard.
This commit is contained in:
parent
718831b77c
commit
f8a9ca2cfa
|
@ -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,
|
||||||
|
|
||||||
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 )
|
entry = find_format_in_list(enum_data->entries, enum_data->count, fmt->cfFormat);
|
||||||
{
|
if(entry)
|
||||||
hr = DV_E_FORMATETC;
|
mask = fmt->tymed & entry->fmtetc.tymed;
|
||||||
goto end;
|
else /* non-Ole format */
|
||||||
}
|
mask = fmt->tymed & TYMED_HGLOBAL;
|
||||||
|
|
||||||
if ( (pformatetcIn->tymed & TYMED_HGLOBAL) != TYMED_HGLOBAL )
|
if(mask & TYMED_HGLOBAL)
|
||||||
{
|
hr = get_stgmed_for_global(h, med);
|
||||||
hr = DV_E_TYMED;
|
else
|
||||||
goto end;
|
{
|
||||||
}
|
FIXME("Unhandled tymed - emum tymed %x req tymed %x\n", entry->fmtetc.tymed, fmt->tymed);
|
||||||
|
hr = E_FAIL;
|
||||||
h = GetClipboardData(pformatetcIn->cfFormat);
|
goto end;
|
||||||
hr = dup_global_mem(h, GMEM_MOVEABLE, &hData);
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Return the clipboard data in the storage medium structure
|
|
||||||
*/
|
|
||||||
pmedium->tymed = (hData == 0) ? TYMED_NULL : TYMED_HGLOBAL;
|
|
||||||
pmedium->u.hGlobal = hData;
|
|
||||||
pmedium->pUnkForRelease = NULL;
|
|
||||||
|
|
||||||
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,
|
||||||
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,
|
||||||
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 );
|
||||||
|
|
Loading…
Reference in New Issue