user32: Don't allow SetClipboardData if the clipboard is not open.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2016-08-23 17:35:18 +09:00
parent 79d2e0a9be
commit 42c221db6c
5 changed files with 23 additions and 14 deletions

View File

@ -345,9 +345,15 @@ HANDLE WINAPI SetClipboardData(UINT wFormat, HANDLE hData)
return 0; 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 /* If it's not owned, data can only be set if the format isn't
available and its rendering is not delayed */ available and its rendering is not delayed */
flags = get_clipboard_flags();
if (!(flags & CB_OWNER) && !hData) if (!(flags & CB_OWNER) && !hData)
{ {
WARN("Clipboard not owned by calling task. Operation failed.\n"); WARN("Clipboard not owned by calling task. Operation failed.\n");

View File

@ -72,13 +72,13 @@ static DWORD WINAPI set_clipboard_data_thread(LPVOID arg)
else else
{ {
SetClipboardData( CF_WAVE, 0 ); SetClipboardData( CF_WAVE, 0 );
todo_wine ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN, "%u: wrong error %u\n", ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN, "%u: wrong error %u\n",
thread_from_line, GetLastError()); thread_from_line, GetLastError());
ok( !IsClipboardFormatAvailable( CF_WAVE ), "%u: SetClipboardData succeeded\n", thread_from_line ); ok( !IsClipboardFormatAvailable( CF_WAVE ), "%u: SetClipboardData succeeded\n", thread_from_line );
ret = SetClipboardData( CF_WAVE, GlobalAlloc( GMEM_DDESHARE | GMEM_ZEROINIT, 100 )); ret = SetClipboardData( CF_WAVE, GlobalAlloc( GMEM_DDESHARE | GMEM_ZEROINIT, 100 ));
todo_wine ok( !ret, "%u: SetClipboardData succeeded\n", thread_from_line ); ok( !ret, "%u: SetClipboardData succeeded\n", thread_from_line );
todo_wine ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN, "%u: wrong error %u\n", ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN, "%u: wrong error %u\n",
thread_from_line, GetLastError()); thread_from_line, GetLastError());
} }
return 0; return 0;
} }
@ -99,12 +99,12 @@ static void set_clipboard_data_process( int arg )
else else
{ {
SetClipboardData( CF_WAVE, 0 ); 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()); 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 )); ret = SetClipboardData( CF_WAVE, GlobalAlloc( GMEM_DDESHARE | GMEM_ZEROINIT, 100 ));
ok( !ret, "process %u: SetClipboardData succeeded\n", arg ); 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()); arg, GetLastError());
} }
} }
@ -256,10 +256,10 @@ static void test_ClipboardOwner(void)
ok( ret, "CloseClipboard error %d\n", GetLastError()); ok( ret, "CloseClipboard error %d\n", GetLastError());
SetLastError( 0xdeadbeef ); SetLastError( 0xdeadbeef );
todo_wine ok( !SetClipboardData( CF_WAVE, GlobalAlloc( GMEM_DDESHARE | GMEM_ZEROINIT, 100 )), ok( !SetClipboardData( CF_WAVE, GlobalAlloc( GMEM_DDESHARE | GMEM_ZEROINIT, 100 )),
"SetClipboardData succeeded\n" ); "SetClipboardData succeeded\n" );
todo_wine ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN, "wrong error %u\n", GetLastError() ); ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN, "wrong error %u\n", GetLastError() );
todo_wine ok( !IsClipboardFormatAvailable( CF_WAVE ), "SetClipboardData succeeded\n" ); ok( !IsClipboardFormatAvailable( CF_WAVE ), "SetClipboardData succeeded\n" );
} }

View File

@ -4508,6 +4508,7 @@ struct set_clipboard_info_reply
#define SET_CB_SEQNO 0x008 #define SET_CB_SEQNO 0x008
#define SET_CB_RELOWNER 0x010 #define SET_CB_RELOWNER 0x010
#define CB_OPEN_ANY 0x020
#define CB_OPEN 0x040 #define CB_OPEN 0x040
#define CB_OWNER 0x080 #define CB_OWNER 0x080
#define CB_PROCESS 0x100 #define CB_PROCESS 0x100
@ -6317,6 +6318,6 @@ union generic_reply
struct terminate_job_reply terminate_job_reply; struct terminate_job_reply terminate_job_reply;
}; };
#define SERVER_PROTOCOL_VERSION 512 #define SERVER_PROTOCOL_VERSION 513
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */ #endif /* __WINE_WINE_SERVER_PROTOCOL_H */

View File

@ -223,6 +223,7 @@ DECL_HANDLER(set_clipboard_info)
reply->seqno = get_seqno( clipboard ); 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->open_thread == current) reply->flags |= CB_OPEN;
if (clipboard->owner_thread == current) reply->flags |= CB_OWNER; if (clipboard->owner_thread == current) reply->flags |= CB_OWNER;
if (clipboard->owner_thread && clipboard->owner_thread->process == current->process) if (clipboard->owner_thread && clipboard->owner_thread->process == current->process)

View File

@ -3189,6 +3189,7 @@ enum caret_state
#define SET_CB_SEQNO 0x008 #define SET_CB_SEQNO 0x008
#define SET_CB_RELOWNER 0x010 #define SET_CB_RELOWNER 0x010
#define CB_OPEN_ANY 0x020
#define CB_OPEN 0x040 #define CB_OPEN 0x040
#define CB_OWNER 0x080 #define CB_OWNER 0x080
#define CB_PROCESS 0x100 #define CB_PROCESS 0x100