[PATCH] ole32: Avoid the failure of flushing the ole clipboard when the clipboard manager gets the data.

Haoyang Chen chenhaoyang at uniontech.com
Thu May 20 02:07:01 CDT 2021


When ole has set the clipboard data, the clipboard manager may preempt
this data (by sending a WM_RENDERFORMAT message). At this point the
clipboard ownership may be occupied by the clipboard manager; resulting
in a failure to flush the ole clipboard.

Signed-off-by: Haoyang Chen <chenhaoyang at uniontech.com>
---
 dlls/ole32/clipboard.c       |  2 ++
 dlls/ole32/tests/clipboard.c | 10 ++++++++++
 2 files changed, 12 insertions(+)

diff --git a/dlls/ole32/clipboard.c b/dlls/ole32/clipboard.c
index e61b3076883..ebc498d52e7 100644
--- a/dlls/ole32/clipboard.c
+++ b/dlls/ole32/clipboard.c
@@ -2261,6 +2261,7 @@ HRESULT WINAPI OleFlushClipboard(void)
   HRESULT hr;
   ole_clipbrd *clipbrd;
   HWND wnd;
+  MSG msg;
 
   TRACE("()\n");
 
@@ -2273,6 +2274,7 @@ HRESULT WINAPI OleFlushClipboard(void)
    */
   if (!clipbrd->src_data) return S_OK;
 
+  PeekMessageW(&msg, wnd, WM_RENDERFORMAT, WM_RENDERFORMAT, PM_REMOVE);
   if (!OpenClipboard(wnd)) return CLIPBRD_E_CANT_OPEN;
 
   SendMessageW(wnd, WM_RENDERALLFORMATS, 0, 0);
diff --git a/dlls/ole32/tests/clipboard.c b/dlls/ole32/tests/clipboard.c
index fd8f287680b..47700e7f3fd 100644
--- a/dlls/ole32/tests/clipboard.c
+++ b/dlls/ole32/tests/clipboard.c
@@ -1085,6 +1085,7 @@ static void test_set_clipboard_DRAWCLIPBOARD(void)
     HWND viewer;
     int ret;
     HANDLE thread;
+    int i;
 
     hr = DataObjectImpl_CreateText("data", &data);
     ok(hr == S_OK, "Failed to create data object: 0x%08x\n", hr);
@@ -1120,6 +1121,15 @@ static void test_set_clipboard_DRAWCLIPBOARD(void)
     ret = SendMessageA( viewer, WM_USER, 0, 0 );
     ok( ret == 2, "%u WM_DRAWCLIPBOARD received\n", ret );
 
+    Sleep(500);
+
+    for (i = 0; i < 10; i++)
+    {
+        hr = OleFlushClipboard();
+        if (hr == S_OK) break;
+        Sleep(100);
+    }
+    ok(hr == S_OK, "got %08x\n", hr);
     clip_data = NULL;
     hr = OleFlushClipboard();
     ok(hr == S_OK, "failed to flush clipboard, hr = 0x%08x\n", hr);
-- 
2.20.1






More information about the wine-devel mailing list