[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 05:07:53 CDT 2021


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 <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);





More information about the wine-devel mailing list