From 42c221db6c61966486344fb65231ae35d9f4ea49 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Tue, 23 Aug 2016 17:35:18 +0900 Subject: [PATCH] user32: Don't allow SetClipboardData if the clipboard is not open. Signed-off-by: Alexandre Julliard --- dlls/user32/clipboard.c | 8 +++++++- dlls/user32/tests/clipboard.c | 24 ++++++++++++------------ include/wine/server_protocol.h | 3 ++- server/clipboard.c | 1 + server/protocol.def | 1 + 5 files changed, 23 insertions(+), 14 deletions(-) diff --git a/dlls/user32/clipboard.c b/dlls/user32/clipboard.c index 6292076eb0f..c72a76b8842 100644 --- a/dlls/user32/clipboard.c +++ b/dlls/user32/clipboard.c @@ -345,9 +345,15 @@ HANDLE WINAPI SetClipboardData(UINT wFormat, HANDLE hData) return 0; } + flags = get_clipboard_flags(); + if (!(flags & CB_OPEN_ANY)) + { + SetLastError( ERROR_CLIPBOARD_NOT_OPEN ); + return 0; + } + /* If it's not owned, data can only be set if the format isn't available and its rendering is not delayed */ - flags = get_clipboard_flags(); if (!(flags & CB_OWNER) && !hData) { WARN("Clipboard not owned by calling task. Operation failed.\n"); diff --git a/dlls/user32/tests/clipboard.c b/dlls/user32/tests/clipboard.c index f51c1628367..33a9c6916c6 100644 --- a/dlls/user32/tests/clipboard.c +++ b/dlls/user32/tests/clipboard.c @@ -72,13 +72,13 @@ static DWORD WINAPI set_clipboard_data_thread(LPVOID arg) else { SetClipboardData( CF_WAVE, 0 ); - todo_wine ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN, "%u: wrong error %u\n", - thread_from_line, GetLastError()); + ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN, "%u: wrong error %u\n", + thread_from_line, GetLastError()); ok( !IsClipboardFormatAvailable( CF_WAVE ), "%u: SetClipboardData succeeded\n", thread_from_line ); ret = SetClipboardData( CF_WAVE, GlobalAlloc( GMEM_DDESHARE | GMEM_ZEROINIT, 100 )); - todo_wine ok( !ret, "%u: SetClipboardData succeeded\n", thread_from_line ); - todo_wine ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN, "%u: wrong error %u\n", - thread_from_line, GetLastError()); + ok( !ret, "%u: SetClipboardData succeeded\n", thread_from_line ); + ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN, "%u: wrong error %u\n", + thread_from_line, GetLastError()); } return 0; } @@ -99,12 +99,12 @@ static void set_clipboard_data_process( int arg ) else { SetClipboardData( CF_WAVE, 0 ); - todo_wine ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN, "process %u: wrong error %u\n", + ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN, "process %u: wrong error %u\n", arg, GetLastError()); - todo_wine ok( !IsClipboardFormatAvailable( CF_WAVE ), "process %u: SetClipboardData succeeded\n", arg ); + ok( !IsClipboardFormatAvailable( CF_WAVE ), "process %u: SetClipboardData succeeded\n", arg ); ret = SetClipboardData( CF_WAVE, GlobalAlloc( GMEM_DDESHARE | GMEM_ZEROINIT, 100 )); ok( !ret, "process %u: SetClipboardData succeeded\n", arg ); - todo_wine ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN, "process %u: wrong error %u\n", + ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN, "process %u: wrong error %u\n", arg, GetLastError()); } } @@ -256,10 +256,10 @@ static void test_ClipboardOwner(void) ok( ret, "CloseClipboard error %d\n", GetLastError()); SetLastError( 0xdeadbeef ); - todo_wine ok( !SetClipboardData( CF_WAVE, GlobalAlloc( GMEM_DDESHARE | GMEM_ZEROINIT, 100 )), - "SetClipboardData succeeded\n" ); - todo_wine ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN, "wrong error %u\n", GetLastError() ); - todo_wine ok( !IsClipboardFormatAvailable( CF_WAVE ), "SetClipboardData succeeded\n" ); + ok( !SetClipboardData( CF_WAVE, GlobalAlloc( GMEM_DDESHARE | GMEM_ZEROINIT, 100 )), + "SetClipboardData succeeded\n" ); + ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN, "wrong error %u\n", GetLastError() ); + ok( !IsClipboardFormatAvailable( CF_WAVE ), "SetClipboardData succeeded\n" ); } diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index 2b17ef62ced..a52c001e394 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -4508,6 +4508,7 @@ struct set_clipboard_info_reply #define SET_CB_SEQNO 0x008 #define SET_CB_RELOWNER 0x010 +#define CB_OPEN_ANY 0x020 #define CB_OPEN 0x040 #define CB_OWNER 0x080 #define CB_PROCESS 0x100 @@ -6317,6 +6318,6 @@ union generic_reply struct terminate_job_reply terminate_job_reply; }; -#define SERVER_PROTOCOL_VERSION 512 +#define SERVER_PROTOCOL_VERSION 513 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */ diff --git a/server/clipboard.c b/server/clipboard.c index 5c4f6000f16..ca0067ab411 100644 --- a/server/clipboard.c +++ b/server/clipboard.c @@ -223,6 +223,7 @@ DECL_HANDLER(set_clipboard_info) reply->seqno = get_seqno( clipboard ); + if (clipboard->open_thread) reply->flags |= CB_OPEN_ANY; if (clipboard->open_thread == current) reply->flags |= CB_OPEN; if (clipboard->owner_thread == current) reply->flags |= CB_OWNER; if (clipboard->owner_thread && clipboard->owner_thread->process == current->process) diff --git a/server/protocol.def b/server/protocol.def index 5b207847d4b..523f5bfcf1f 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -3189,6 +3189,7 @@ enum caret_state #define SET_CB_SEQNO 0x008 #define SET_CB_RELOWNER 0x010 +#define CB_OPEN_ANY 0x020 #define CB_OPEN 0x040 #define CB_OWNER 0x080 #define CB_PROCESS 0x100