From: Rémi Bernon rbernon@codeweavers.com
To avoid the new process inheriting the old desktop as default. Changes the todos in the tests as it fixes the thread input not being attached, but then exposes a different todo.
This works around an issue with the way Wine implements its process default desktop when handles aren't inherited: it uses the old process desktop right away instead of using the one provided in the process startup info. --- dlls/user32/tests/input.c | 60 ++++++++++++++++++++++++++++++++------- 1 file changed, 49 insertions(+), 11 deletions(-)
diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c index be95bd150b4..d0a3a9f6f55 100644 --- a/dlls/user32/tests/input.c +++ b/dlls/user32/tests/input.c @@ -428,15 +428,52 @@ static void run_in_process_( const char *file, int line, char **argv, const char CloseHandle( info.hProcess ); }
+struct run_in_desktop_params +{ + const char *file; + int line; + + HDESK desktop; + char *cmdline; + STARTUPINFOA *startup; +}; + +static DWORD WINAPI run_in_desktop_thread( void *args ) +{ + struct run_in_desktop_params *params = args; + PROCESS_INFORMATION info = {0}; + HDESK old_desktop; + DWORD ret; + + old_desktop = GetThreadDesktop( GetCurrentThreadId() ); + ok_(params->file, params->line)( old_desktop != NULL, "GetThreadDesktop error %lu\n", GetLastError() ); + ret = SetThreadDesktop( params->desktop ); + ok_(params->file, params->line)( !!ret, "SetThreadDesktop failed, error %lu\n", GetLastError() ); + + ret = CreateProcessA( NULL, params->cmdline, NULL, NULL, FALSE, 0, NULL, NULL, params->startup, &info ); + ok_(params->file, params->line)( ret, "CreateProcessA failed, error %lu\n", GetLastError() ); + if (ret) + { + wait_child_process( info.hProcess ); + CloseHandle( info.hThread ); + CloseHandle( info.hProcess ); + } + + ret = SetThreadDesktop( old_desktop ); + ok_(params->file, params->line)( !!ret, "SetThreadDesktop failed, error %lu\n", GetLastError() ); + return 0; +} + #define run_in_desktop( a, b, c ) run_in_desktop_( __FILE__, __LINE__, a, b, c ) static void run_in_desktop_( const char *file, int line, char **argv, const char *args, BOOL input ) { + struct run_in_desktop_params params = {.file = file, .line = line}; const char *desktop_name = "WineTest Desktop"; STARTUPINFOA startup = {.cb = sizeof(STARTUPINFOA)}; - PROCESS_INFORMATION info = {0}; HDESK old_desktop, desktop; char cmdline[MAX_PATH * 2]; + HANDLE thread; DWORD ret;
old_desktop = OpenInputDesktop( 0, FALSE, DESKTOP_ALL_ACCESS ); @@ -451,13 +488,14 @@ static void run_in_desktop_( const char *file, int line, char **argv,
startup.lpDesktop = (char *)desktop_name; sprintf( cmdline, "%s %s %s", argv[0], argv[1], args ); - ret = CreateProcessA( NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info ); - ok_(file, line)( ret, "CreateProcessA failed, error %lu\n", GetLastError() ); - if (!ret) return;
- wait_child_process( info.hProcess ); - CloseHandle( info.hThread ); - CloseHandle( info.hProcess ); + params.startup = &startup; + params.cmdline = cmdline; + params.desktop = desktop; + thread = CreateThread( NULL, 0, run_in_desktop_thread, ¶ms, 0, NULL ); + ok_(file, line)( thread != NULL, "CreateThread error %lu\n", GetLastError() ); + ret = WaitForSingleObject( thread, INFINITE ); + ok_(file, line)( ret == WAIT_OBJECT_0, "WaitForSingleObject returned %lu, error %lu\n", ret, GetLastError() );
if (input) { @@ -3855,19 +3893,19 @@ static void test_SendInput_mouse_messages(void) ok_ne( NULL, thread, HANDLE, "%p" );
ok_ret( 0, WaitForSingleObject( params.start_event, 5000 ) ); - todo_wine ok_ret( 1, AttachThreadInput( thread_id, GetCurrentThreadId(), TRUE ) ); + ok_ret( 1, AttachThreadInput( thread_id, GetCurrentThreadId(), TRUE ) ); ok_ret( 0, SendMessageW( params.hwnd, WM_USER, 0, 0 ) );
mouse_event( MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0 ); wait_messages( 5, FALSE ); - button_down_hwnd[1].message.hwnd = hwnd; - ok_seq( button_down_hwnd ); + button_down_hwnd_todo[1].message.hwnd = hwnd; + ok_seq( button_down_hwnd_todo ); mouse_event( MOUSEEVENTF_LEFTUP, 0, 0, 0, 0 ); wait_messages( 5, FALSE ); button_up_hwnd[1].message.hwnd = hwnd; ok_seq( button_up_hwnd );
- todo_wine ok_ret( 1, AttachThreadInput( thread_id, GetCurrentThreadId(), FALSE ) ); + ok_ret( 1, AttachThreadInput( thread_id, GetCurrentThreadId(), FALSE ) ); ok_ret( 1, SetEvent( params.end_event ) ); ok_ret( 0, WaitForSingleObject( thread, 5000 ) ); ok_ret( 1, CloseHandle( thread ) );