From: Haoyang Chen Subject: Re: [PATCH] ole32: Avoid the failure of flushing the ole clipboard when the clipboard manager gets the data. Message-Id: Date: Thu, 20 May 2021 18:07:53 +0800 In-Reply-To: <20210520070701.18505-1-chenhaoyang@uniontech.com> References: <20210520070701.18505-1-chenhaoyang@uniontech.com> Please ignore it, it needs more testing. ÔÚ 2021/5/20 ÏÂÎç3:07, Haoyang Chen дµÀ: > 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 > --- > 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);