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 ...@@ -170,7 +170,7 @@ typedef struct PresentationDataHeader
} 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; static ole_clipbrd* theOleClipboard;
...@@ -202,9 +202,6 @@ UINT ole_private_data_clipboard_format = 0; ...@@ -202,9 +202,6 @@ UINT ole_private_data_clipboard_format = 0;
static UINT wine_marshal_clipboard_format; static UINT wine_marshal_clipboard_format;
/*********************************************************
* register_clipboard_formats
*/
static void register_clipboard_formats(void) static void register_clipboard_formats(void)
{ {
ownerlink_clipboard_format = RegisterClipboardFormatW(L"OwnerLink"); ownerlink_clipboard_format = RegisterClipboardFormatW(L"OwnerLink");
...@@ -222,56 +219,58 @@ static void register_clipboard_formats(void) ...@@ -222,56 +219,58 @@ static void register_clipboard_formats(void)
wine_marshal_clipboard_format = RegisterClipboardFormatW(L"Wine Marshalled DataObject"); wine_marshal_clipboard_format = RegisterClipboardFormatW(L"Wine Marshalled DataObject");
} }
/*********************************************************************** static BOOL WINAPI clipbrd_create(INIT_ONCE *init_once, void *parameter, void **context)
* OLEClipbrd_Initialize()
* Initializes the OLE clipboard.
*/
void OLEClipbrd_Initialize(void)
{ {
register_clipboard_formats(); ole_clipbrd* clipbrd;
HGLOBAL h;
if ( !theOleClipboard )
{
ole_clipbrd* clipbrd;
HGLOBAL h;
TRACE("()\n"); TRACE("()\n");
clipbrd = HeapAlloc( GetProcessHeap(), 0, sizeof(*clipbrd) ); register_clipboard_formats();
if (!clipbrd) return;
clipbrd->latest_snapshot = NULL; clipbrd = HeapAlloc( GetProcessHeap(), 0, sizeof(*clipbrd) );
clipbrd->window = NULL; if (!clipbrd)
clipbrd->src_data = NULL; {
clipbrd->cached_enum = NULL; ERR("No memory.\n");
return FALSE;
}
h = GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE, 0); clipbrd->latest_snapshot = NULL;
if(!h) clipbrd->window = NULL;
{ clipbrd->src_data = NULL;
HeapFree(GetProcessHeap(), 0, clipbrd); clipbrd->cached_enum = NULL;
return;
}
if(FAILED(CreateStreamOnHGlobal(h, TRUE, &clipbrd->marshal_data))) h = GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE, 0);
{ if(!h)
GlobalFree(h); {
HeapFree(GetProcessHeap(), 0, clipbrd); ERR("No memory.\n");
return; 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) static inline HRESULT get_ole_clipbrd(ole_clipbrd **clipbrd)
{ {
struct oletls *info = COM_CurrentInfo(); static INIT_ONCE init_once = INIT_ONCE_STATIC_INIT;
*clipbrd = NULL;
if(!info->ole_inits) if (!InitOnceExecuteOnce(&init_once, clipbrd_create, NULL, NULL))
{
*clipbrd = NULL;
return CO_E_NOTINITIALIZED; return CO_E_NOTINITIALIZED;
*clipbrd = theOleClipboard; }
*clipbrd = theOleClipboard;
return S_OK; return S_OK;
} }
...@@ -2000,10 +1999,10 @@ static HRESULT set_src_dataobject(ole_clipbrd *clipbrd, IDataObject *data) ...@@ -2000,10 +1999,10 @@ static HRESULT set_src_dataobject(ole_clipbrd *clipbrd, IDataObject *data)
} }
/*********************************************************************** /***********************************************************************
* OLEClipbrd_UnInitialize() * clipbrd_uninitialize()
* Un-Initializes the OLE clipboard * Un-Initializes the OLE clipboard
*/ */
void OLEClipbrd_UnInitialize(void) void clipbrd_uninitialize(void)
{ {
ole_clipbrd *clipbrd = theOleClipboard; ole_clipbrd *clipbrd = theOleClipboard;
...@@ -2023,15 +2022,29 @@ void OLEClipbrd_UnInitialize(void) ...@@ -2023,15 +2022,29 @@ void OLEClipbrd_UnInitialize(void)
{ {
DestroyWindow(clipbrd->window); DestroyWindow(clipbrd->window);
UnregisterClassW( clipbrd_wndclass, GetModuleHandleW(L"ole32") ); 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 * clipbrd_wndproc
*/ */
static LRESULT CALLBACK clipbrd_wndproc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) static LRESULT CALLBACK clipbrd_wndproc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
...@@ -2164,12 +2177,16 @@ static HRESULT set_dataobject_format(HWND hwnd) ...@@ -2164,12 +2177,16 @@ static HRESULT set_dataobject_format(HWND hwnd)
HRESULT WINAPI OleSetClipboard(IDataObject* data) HRESULT WINAPI OleSetClipboard(IDataObject* data)
{ {
struct oletls *info = COM_CurrentInfo();
HRESULT hr; HRESULT hr;
ole_clipbrd *clipbrd; ole_clipbrd *clipbrd;
HWND wnd; HWND wnd;
TRACE("(%p)\n", data); 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_ole_clipbrd(&clipbrd))) return hr;
if(FAILED(hr = get_clipbrd_window(clipbrd, &wnd))) return hr; if(FAILED(hr = get_clipbrd_window(clipbrd, &wnd))) return hr;
...@@ -2258,6 +2275,7 @@ HRESULT WINAPI OleGetClipboard(IDataObject **obj) ...@@ -2258,6 +2275,7 @@ HRESULT WINAPI OleGetClipboard(IDataObject **obj)
*/ */
HRESULT WINAPI OleFlushClipboard(void) HRESULT WINAPI OleFlushClipboard(void)
{ {
struct oletls *info = COM_CurrentInfo();
HRESULT hr; HRESULT hr;
ole_clipbrd *clipbrd; ole_clipbrd *clipbrd;
HWND wnd; HWND wnd;
...@@ -2266,6 +2284,9 @@ HRESULT WINAPI OleFlushClipboard(void) ...@@ -2266,6 +2284,9 @@ HRESULT WINAPI OleFlushClipboard(void)
if(FAILED(hr = get_ole_clipbrd(&clipbrd))) return hr; 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; if(FAILED(hr = get_clipbrd_window(clipbrd, &wnd))) return hr;
/* /*
......
...@@ -937,6 +937,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID reserved) ...@@ -937,6 +937,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID reserved)
break; break;
case DLL_PROCESS_DETACH: case DLL_PROCESS_DETACH:
clipbrd_destroy();
if (reserved) break; if (reserved) break;
release_std_git(); release_std_git();
break; break;
......
...@@ -132,6 +132,8 @@ extern UINT object_descriptor_clipboard_format DECLSPEC_HIDDEN; ...@@ -132,6 +132,8 @@ extern UINT object_descriptor_clipboard_format DECLSPEC_HIDDEN;
extern UINT link_source_descriptor_clipboard_format DECLSPEC_HIDDEN; extern UINT link_source_descriptor_clipboard_format DECLSPEC_HIDDEN;
extern UINT ole_private_data_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 create_classes_key(HKEY, const WCHAR *, REGSAM, HKEY *) DECLSPEC_HIDDEN;
extern LSTATUS open_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 ...@@ -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); 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 clipbrd_uninitialize(void);
extern void OLEClipbrd_Initialize(void);
/****************************************************************************** /******************************************************************************
* These are the prototypes of the utility methods used for OLE Drag n Drop * 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) ...@@ -198,11 +197,6 @@ HRESULT WINAPI DECLSPEC_HOTPATCH OleInitialize(LPVOID reserved)
TRACE("() - Initializing the OLE libraries\n"); TRACE("() - Initializing the OLE libraries\n");
/* /*
* OLE Clipboard
*/
OLEClipbrd_Initialize();
/*
* Drag and Drop * Drag and Drop
*/ */
OLEDD_Initialize(); OLEDD_Initialize();
...@@ -241,7 +235,7 @@ void WINAPI DECLSPEC_HOTPATCH OleUninitialize(void) ...@@ -241,7 +235,7 @@ void WINAPI DECLSPEC_HOTPATCH OleUninitialize(void)
/* /*
* OLE Clipboard * OLE Clipboard
*/ */
OLEClipbrd_UnInitialize(); clipbrd_uninitialize();
/* /*
* OLE shared menu * OLE shared menu
......
...@@ -503,13 +503,27 @@ static HRESULT DataObjectImpl_CreateComplex(LPDATAOBJECT *lplpdataobj) ...@@ -503,13 +503,27 @@ static HRESULT DataObjectImpl_CreateComplex(LPDATAOBJECT *lplpdataobj)
static void test_get_clipboard_uninitialized(void) static void test_get_clipboard_uninitialized(void)
{ {
HRESULT hr; REFCLSID rclsid = &CLSID_InternetZoneManager;
IDataObject *pDObj; IDataObject *pDObj;
IUnknown *pUnk;
HRESULT hr;
pDObj = (IDataObject *)0xdeadbeef; pDObj = (IDataObject *)0xdeadbeef;
hr = OleGetClipboard(&pDObj); hr = OleGetClipboard(&pDObj);
todo_wine ok(hr == S_OK, "OleGetClipboard() got 0x%08x instead of 0x%08x\n", hr, S_OK); 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(!!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) static void test_get_clipboard(void)
...@@ -1288,6 +1302,15 @@ static void test_consumer_refs(void) ...@@ -1288,6 +1302,15 @@ static void test_consumer_refs(void)
refs = count_refs(src); refs = count_refs(src);
ok(refs == 2, "%d\n", refs); 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); 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