Commit b68e03f9 authored by Vincent Povirk's avatar Vincent Povirk Committed by Alexandre Julliard

user32: Don't regard the clipboard as changed if we don't own it.

I ran into a situation where user32 will call EndClipboardUpdate even though the clipboard hasn't changed. It went something like this: * Program A acquires the clipboard and adds some delay-rendered data. * Program B requests data from the clipboard, causing program A to receive WM_RENDERFORMAT. * Program A calls SetClipboardData to fulfill the request, setting bCBHasChanged to TRUE. * Program C acquires the clipboard. * Program A opens the clipboard to enumerate the formats. When it closes the clipboard, EndClipboardUpdate is called. Signed-off-by: 's avatarVincent Povirk <vincent@codeweavers.com> Signed-off-by: 's avatarAlexandre Julliard <julliard@winehq.org>
parent 13830123
...@@ -178,6 +178,7 @@ INT WINAPI GetClipboardFormatNameA(UINT wFormat, LPSTR retStr, INT maxlen) ...@@ -178,6 +178,7 @@ INT WINAPI GetClipboardFormatNameA(UINT wFormat, LPSTR retStr, INT maxlen)
BOOL WINAPI OpenClipboard( HWND hWnd ) BOOL WINAPI OpenClipboard( HWND hWnd )
{ {
BOOL bRet; BOOL bRet;
UINT flags;
TRACE("(%p)...\n", hWnd); TRACE("(%p)...\n", hWnd);
...@@ -185,10 +186,16 @@ BOOL WINAPI OpenClipboard( HWND hWnd ) ...@@ -185,10 +186,16 @@ BOOL WINAPI OpenClipboard( HWND hWnd )
{ {
req->flags = SET_CB_OPEN; req->flags = SET_CB_OPEN;
req->clipboard = wine_server_user_handle( hWnd ); req->clipboard = wine_server_user_handle( hWnd );
bRet = !wine_server_call( req ); if ((bRet = !wine_server_call( req )))
flags = reply->flags;
} }
SERVER_END_REQ; SERVER_END_REQ;
if (bRet && !(flags & CB_PROCESS))
{
bCBHasChanged = FALSE;
}
TRACE(" returning %i\n", bRet); TRACE(" returning %i\n", bRet);
return bRet; return bRet;
...@@ -201,6 +208,7 @@ BOOL WINAPI OpenClipboard( HWND hWnd ) ...@@ -201,6 +208,7 @@ BOOL WINAPI OpenClipboard( HWND hWnd )
BOOL WINAPI CloseClipboard(void) BOOL WINAPI CloseClipboard(void)
{ {
HWND viewer = 0; HWND viewer = 0;
UINT flags;
BOOL ret; BOOL ret;
TRACE("() Changed=%d\n", bCBHasChanged); TRACE("() Changed=%d\n", bCBHasChanged);
...@@ -210,18 +218,21 @@ BOOL WINAPI CloseClipboard(void) ...@@ -210,18 +218,21 @@ BOOL WINAPI CloseClipboard(void)
req->flags = SET_CB_CLOSE; req->flags = SET_CB_CLOSE;
if (bCBHasChanged) req->flags |= SET_CB_SEQNO; if (bCBHasChanged) req->flags |= SET_CB_SEQNO;
if ((ret = !wine_server_call_err( req ))) if ((ret = !wine_server_call_err( req )))
{
viewer = wine_server_ptr_handle( reply->old_viewer ); viewer = wine_server_ptr_handle( reply->old_viewer );
flags = reply->flags;
}
} }
SERVER_END_REQ; SERVER_END_REQ;
if (!ret) return FALSE; if (!ret) return FALSE;
if (bCBHasChanged) if (bCBHasChanged && (flags & CB_PROCESS))
{ {
USER_Driver->pEndClipboardUpdate(); USER_Driver->pEndClipboardUpdate();
bCBHasChanged = FALSE;
if (viewer) SendNotifyMessageW(viewer, WM_DRAWCLIPBOARD, (WPARAM) GetClipboardOwner(), 0); if (viewer) SendNotifyMessageW(viewer, WM_DRAWCLIPBOARD, (WPARAM) GetClipboardOwner(), 0);
} }
bCBHasChanged = FALSE;
return TRUE; return TRUE;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment