Huw Davies : ole32: OleUninitialize() does not release the reference to the clipboard's source dataobject.

Alexandre Julliard julliard at winehq.org
Tue May 23 18:01:26 CDT 2017


Module: wine
Branch: master
Commit: 8fc1a4cd863aad02761f015bf5a5f67f94934aac
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=8fc1a4cd863aad02761f015bf5a5f67f94934aac

Author: Huw Davies <huw at codeweavers.com>
Date:   Tue May 23 09:33:02 2017 +0100

ole32: OleUninitialize() does not release the reference to the clipboard's source dataobject.

Signed-off-by: Huw Davies <huw at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 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)




More information about the wine-cvs mailing list