ole32: OleUninitialize() does not release the reference to the clipboard's source dataobject.
Signed-off-by: Huw Davies <huw@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
b8a8e1bde9
commit
8fc1a4cd86
|
@ -1786,35 +1786,6 @@ void OLEClipbrd_Initialize(void)
|
|||
}
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* OLEClipbrd_UnInitialize()
|
||||
* Un-Initializes the OLE clipboard
|
||||
*/
|
||||
void OLEClipbrd_UnInitialize(void)
|
||||
{
|
||||
ole_clipbrd *clipbrd = theOleClipboard;
|
||||
|
||||
TRACE("()\n");
|
||||
|
||||
if ( clipbrd )
|
||||
{
|
||||
static const WCHAR ole32W[] = {'o','l','e','3','2',0};
|
||||
HINSTANCE hinst = GetModuleHandleW(ole32W);
|
||||
|
||||
if ( clipbrd->window )
|
||||
{
|
||||
DestroyWindow(clipbrd->window);
|
||||
UnregisterClassW( clipbrd_wndclass, hinst );
|
||||
}
|
||||
|
||||
IStream_Release(clipbrd->marshal_data);
|
||||
if (clipbrd->src_data) IDataObject_Release(clipbrd->src_data);
|
||||
HeapFree(GetProcessHeap(), 0, clipbrd->cached_enum);
|
||||
HeapFree(GetProcessHeap(), 0, clipbrd);
|
||||
theOleClipboard = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* set_clipboard_formats
|
||||
*
|
||||
|
@ -2014,6 +1985,41 @@ static HRESULT set_src_dataobject(ole_clipbrd *clipbrd, IDataObject *data)
|
|||
return hr;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* OLEClipbrd_UnInitialize()
|
||||
* Un-Initializes the OLE clipboard
|
||||
*/
|
||||
void OLEClipbrd_UnInitialize(void)
|
||||
{
|
||||
ole_clipbrd *clipbrd = theOleClipboard;
|
||||
|
||||
TRACE("()\n");
|
||||
|
||||
if ( clipbrd )
|
||||
{
|
||||
static const WCHAR ole32W[] = {'o','l','e','3','2',0};
|
||||
HINSTANCE hinst = GetModuleHandleW(ole32W);
|
||||
|
||||
/* OleUninitialize() does not release the reference to the dataobject, so
|
||||
take an additional reference here. This reference is then leaked. */
|
||||
if (clipbrd->src_data)
|
||||
{
|
||||
IDataObject_AddRef(clipbrd->src_data);
|
||||
set_src_dataobject(clipbrd, NULL);
|
||||
}
|
||||
|
||||
if ( clipbrd->window )
|
||||
{
|
||||
DestroyWindow(clipbrd->window);
|
||||
UnregisterClassW( clipbrd_wndclass, hinst );
|
||||
}
|
||||
|
||||
IStream_Release(clipbrd->marshal_data);
|
||||
HeapFree(GetProcessHeap(), 0, clipbrd);
|
||||
theOleClipboard = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* clipbrd_wndproc
|
||||
*/
|
||||
|
|
|
@ -1187,9 +1187,21 @@ static void test_consumer_refs(void)
|
|||
IDataObject_Release(get1);
|
||||
|
||||
IDataObject_Release(src2);
|
||||
IDataObject_Release(src);
|
||||
|
||||
/* Show that OleUninitialize() doesn't release the
|
||||
dataobject's ref, and thus the object is leaked. */
|
||||
old_refs = count_refs(src);
|
||||
ok(old_refs == 1, "%d\n", old_refs);
|
||||
|
||||
OleSetClipboard(src);
|
||||
refs = count_refs(src);
|
||||
ok(refs > old_refs, "%d %d\n", refs, old_refs);
|
||||
|
||||
OleUninitialize();
|
||||
refs = count_refs(src);
|
||||
ok(refs == 2, "%d\n", refs);
|
||||
|
||||
IDataObject_Release(src);
|
||||
}
|
||||
|
||||
static void test_flushed_getdata(void)
|
||||
|
|
Loading…
Reference in New Issue