[PATCH] ole32: OleUninitialize() does not release the reference to the clipboard's source dataobject.
Huw Davies
huw at codeweavers.com
Tue May 23 03:33:02 CDT 2017
Signed-off-by: Huw Davies <huw at codeweavers.com>
---
dlls/ole32/clipboard.c | 64 ++++++++++++++++++++++++--------------------
dlls/ole32/tests/clipboard.c | 14 +++++++++-
2 files changed, 48 insertions(+), 30 deletions(-)
diff --git a/dlls/ole32/clipboard.c b/dlls/ole32/clipboard.c
index b3c7665..919d9e3 100644
--- a/dlls/ole32/clipboard.c
+++ b/dlls/ole32/clipboard.c
@@ -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
*
@@ -2015,6 +1986,41 @@ static HRESULT set_src_dataobject(ole_clipbrd *clipbrd, IDataObject *data)
}
/***********************************************************************
+ * 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
*/
static LRESULT CALLBACK clipbrd_wndproc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
diff --git a/dlls/ole32/tests/clipboard.c b/dlls/ole32/tests/clipboard.c
index 1c8923e..4890782 100644
--- a/dlls/ole32/tests/clipboard.c
+++ b/dlls/ole32/tests/clipboard.c
@@ -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)
--
2.7.4
More information about the wine-patches
mailing list