Commit 71aeb64c authored by Paul Gofman's avatar Paul Gofman Committed by Alexandre Julliard

ole32: Do not link OLE clipboard object lifecycle to OLE initialization state.

Fixes text paste in Origin launcher and overlay. Signed-off-by: 's avatarPaul Gofman <pgofman@codeweavers.com> Signed-off-by: 's avatarHuw Davies <huw@codeweavers.com> Signed-off-by: 's avatarAlexandre Julliard <julliard@winehq.org>
parent 949a4849
......@@ -170,7 +170,7 @@ typedef struct PresentationDataHeader
} PresentationDataHeader;
/*
* The one and only ole_clipbrd object which is created by OLEClipbrd_Initialize()
* The one and only ole_clipbrd object which is created by clipbrd_create()
*/
static ole_clipbrd* theOleClipboard;
......@@ -202,9 +202,6 @@ UINT ole_private_data_clipboard_format = 0;
static UINT wine_marshal_clipboard_format;
/*********************************************************
* register_clipboard_formats
*/
static void register_clipboard_formats(void)
{
ownerlink_clipboard_format = RegisterClipboardFormatW(L"OwnerLink");
......@@ -222,56 +219,58 @@ static void register_clipboard_formats(void)
wine_marshal_clipboard_format = RegisterClipboardFormatW(L"Wine Marshalled DataObject");
}
/***********************************************************************
* OLEClipbrd_Initialize()
* Initializes the OLE clipboard.
*/
void OLEClipbrd_Initialize(void)
static BOOL WINAPI clipbrd_create(INIT_ONCE *init_once, void *parameter, void **context)
{
register_clipboard_formats();
if ( !theOleClipboard )
{
ole_clipbrd* clipbrd;
HGLOBAL h;
ole_clipbrd* clipbrd;
HGLOBAL h;
TRACE("()\n");
TRACE("()\n");
clipbrd = HeapAlloc( GetProcessHeap(), 0, sizeof(*clipbrd) );
if (!clipbrd) return;
register_clipboard_formats();
clipbrd->latest_snapshot = NULL;
clipbrd->window = NULL;
clipbrd->src_data = NULL;
clipbrd->cached_enum = NULL;
clipbrd = HeapAlloc( GetProcessHeap(), 0, sizeof(*clipbrd) );
if (!clipbrd)
{
ERR("No memory.\n");
return FALSE;
}
h = GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE, 0);
if(!h)
{
HeapFree(GetProcessHeap(), 0, clipbrd);
return;
}
clipbrd->latest_snapshot = NULL;
clipbrd->window = NULL;
clipbrd->src_data = NULL;
clipbrd->cached_enum = NULL;
if(FAILED(CreateStreamOnHGlobal(h, TRUE, &clipbrd->marshal_data)))
{
GlobalFree(h);
HeapFree(GetProcessHeap(), 0, clipbrd);
return;
}
h = GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE, 0);
if(!h)
{
ERR("No memory.\n");
HeapFree(GetProcessHeap(), 0, clipbrd);
return FALSE;
}
theOleClipboard = clipbrd;
if(FAILED(CreateStreamOnHGlobal(h, TRUE, &clipbrd->marshal_data)))
{
ERR("CreateStreamOnHGlobal failed.\n");
GlobalFree(h);
HeapFree(GetProcessHeap(), 0, clipbrd);
return FALSE;
}
theOleClipboard = clipbrd;
return TRUE;
}
static inline HRESULT get_ole_clipbrd(ole_clipbrd **clipbrd)
{
struct oletls *info = COM_CurrentInfo();
*clipbrd = NULL;
static INIT_ONCE init_once = INIT_ONCE_STATIC_INIT;
if(!info->ole_inits)
if (!InitOnceExecuteOnce(&init_once, clipbrd_create, NULL, NULL))
{
*clipbrd = NULL;
return CO_E_NOTINITIALIZED;
*clipbrd = theOleClipboard;
}
*clipbrd = theOleClipboard;
return S_OK;
}
......@@ -2000,10 +1999,10 @@ static HRESULT set_src_dataobject(ole_clipbrd *clipbrd, IDataObject *data)
}
/***********************************************************************
* OLEClipbrd_UnInitialize()
* clipbrd_uninitialize()
* Un-Initializes the OLE clipboard
*/
void OLEClipbrd_UnInitialize(void)
void clipbrd_uninitialize(void)
{
ole_clipbrd *clipbrd = theOleClipboard;
......@@ -2023,15 +2022,29 @@ void OLEClipbrd_UnInitialize(void)
{
DestroyWindow(clipbrd->window);
UnregisterClassW( clipbrd_wndclass, GetModuleHandleW(L"ole32") );
clipbrd->window = NULL;
}
IStream_Release(clipbrd->marshal_data);
HeapFree(GetProcessHeap(), 0, clipbrd);
theOleClipboard = NULL;
}
}
/***********************************************************************
* clipbrd_destroy()
* Destroy the OLE clipboard
*/
void clipbrd_destroy(void)
{
ole_clipbrd *clipbrd = theOleClipboard;
if (!clipbrd) return;
clipbrd_uninitialize();
IStream_Release(clipbrd->marshal_data);
HeapFree(GetProcessHeap(), 0, clipbrd);
theOleClipboard = NULL;
}
/***********************************************************************
* clipbrd_wndproc
*/
static LRESULT CALLBACK clipbrd_wndproc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
......@@ -2164,12 +2177,16 @@ static HRESULT set_dataobject_format(HWND hwnd)
HRESULT WINAPI OleSetClipboard(IDataObject* data)
{
struct oletls *info = COM_CurrentInfo();
HRESULT hr;
ole_clipbrd *clipbrd;
HWND wnd;
TRACE("(%p)\n", data);
if(!info->ole_inits)
return CO_E_NOTINITIALIZED;
if(FAILED(hr = get_ole_clipbrd(&clipbrd))) return hr;
if(FAILED(hr = get_clipbrd_window(clipbrd, &wnd))) return hr;
......@@ -2258,6 +2275,7 @@ HRESULT WINAPI OleGetClipboard(IDataObject **obj)
*/
HRESULT WINAPI OleFlushClipboard(void)
{
struct oletls *info = COM_CurrentInfo();
HRESULT hr;
ole_clipbrd *clipbrd;
HWND wnd;
......@@ -2266,6 +2284,9 @@ HRESULT WINAPI OleFlushClipboard(void)
if(FAILED(hr = get_ole_clipbrd(&clipbrd))) return hr;
if(!info->ole_inits)
return E_FAIL;
if(FAILED(hr = get_clipbrd_window(clipbrd, &wnd))) return hr;
/*
......
......@@ -937,6 +937,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID reserved)
break;
case DLL_PROCESS_DETACH:
clipbrd_destroy();
if (reserved) break;
release_std_git();
break;
......
......@@ -132,6 +132,8 @@ extern UINT object_descriptor_clipboard_format DECLSPEC_HIDDEN;
extern UINT link_source_descriptor_clipboard_format DECLSPEC_HIDDEN;
extern UINT ole_private_data_clipboard_format DECLSPEC_HIDDEN;
void clipbrd_destroy(void) DECLSPEC_HIDDEN;
extern LSTATUS create_classes_key(HKEY, const WCHAR *, REGSAM, HKEY *) DECLSPEC_HIDDEN;
extern LSTATUS open_classes_key(HKEY, const WCHAR *, REGSAM, HKEY *) DECLSPEC_HIDDEN;
......
......@@ -133,10 +133,9 @@ static LRESULT CALLBACK OLEMenu_CallWndProc(INT code, WPARAM wParam, LPARAM lPar
static LRESULT CALLBACK OLEMenu_GetMsgProc(INT code, WPARAM wParam, LPARAM lParam);
/******************************************************************************
* These are the prototypes of the OLE Clipboard initialization methods (in clipboard.c)
* This is a prototype of the OLE Clipboard uninitialization method (in clipboard.c)
*/
extern void OLEClipbrd_UnInitialize(void);
extern void OLEClipbrd_Initialize(void);
extern void clipbrd_uninitialize(void);
/******************************************************************************
* These are the prototypes of the utility methods used for OLE Drag n Drop
......@@ -198,11 +197,6 @@ HRESULT WINAPI DECLSPEC_HOTPATCH OleInitialize(LPVOID reserved)
TRACE("() - Initializing the OLE libraries\n");
/*
* OLE Clipboard
*/
OLEClipbrd_Initialize();
/*
* Drag and Drop
*/
OLEDD_Initialize();
......@@ -241,7 +235,7 @@ void WINAPI DECLSPEC_HOTPATCH OleUninitialize(void)
/*
* OLE Clipboard
*/
OLEClipbrd_UnInitialize();
clipbrd_uninitialize();
/*
* OLE shared menu
......
......@@ -503,13 +503,27 @@ static HRESULT DataObjectImpl_CreateComplex(LPDATAOBJECT *lplpdataobj)
static void test_get_clipboard_uninitialized(void)
{
HRESULT hr;
REFCLSID rclsid = &CLSID_InternetZoneManager;
IDataObject *pDObj;
IUnknown *pUnk;
HRESULT hr;
pDObj = (IDataObject *)0xdeadbeef;
hr = OleGetClipboard(&pDObj);
todo_wine ok(hr == S_OK, "OleGetClipboard() got 0x%08x instead of 0x%08x\n", hr, S_OK);
if (pDObj && pDObj != (IDataObject *)0xdeadbeef) IDataObject_Release(pDObj);
ok(hr == S_OK, "OleGetClipboard() got 0x%08x instead of 0x%08x\n", hr, S_OK);
ok(!!pDObj && pDObj != (IDataObject *)0xdeadbeef, "Got unexpected pDObj %p.\n", pDObj);
/* COM is still not initialized. */
hr = CoCreateInstance(rclsid, NULL, 0x17, &IID_IUnknown, (void **)&pUnk);
ok(hr == CO_E_NOTINITIALIZED, "Got unexpected hr %#x.\n", hr);
hr = OleFlushClipboard();
ok(hr == E_FAIL, "Got unexpected hr %#x.\n", hr);
hr = OleIsCurrentClipboard(pDObj);
ok(hr == S_FALSE, "Got unexpected hr %#x.\n", hr);
IDataObject_Release(pDObj);
}
static void test_get_clipboard(void)
......@@ -1288,6 +1302,15 @@ static void test_consumer_refs(void)
refs = count_refs(src);
ok(refs == 2, "%d\n", refs);
OleInitialize(NULL);
hr = OleSetClipboard(NULL);
ok(hr == S_OK, "Failed to clear clipboard, hr %#x.\n", hr);
OleUninitialize();
refs = count_refs(src);
ok(refs == 2, "%d\n", refs);
IDataObject_Release(src);
}
......
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