Module: wine Branch: master Commit: 74bf784b29ae03d97bc4b527526b3345f5335838 URL: https://gitlab.winehq.org/wine/wine/-/commit/74bf784b29ae03d97bc4b527526b334...
Author: Rémi Bernon rbernon@codeweavers.com Date: Wed Feb 21 20:11:55 2024 +0100
server: Use the startup info to connect the process winstation.
This changes the todos in the tests as it fixes the thread input not being attached, but then exposes a different todo.
---
dlls/dinput/tests/joystick8.c | 23 +++++++++-------------- dlls/user32/tests/input.c | 8 ++++---- server/process.c | 6 ++++-- server/user.h | 5 +++-- server/winstation.c | 27 +++++++++++++++++++++++++-- 5 files changed, 45 insertions(+), 24 deletions(-)
diff --git a/dlls/dinput/tests/joystick8.c b/dlls/dinput/tests/joystick8.c index 0553cb96a63..428fc59c1af 100644 --- a/dlls/dinput/tests/joystick8.c +++ b/dlls/dinput/tests/joystick8.c @@ -5756,23 +5756,23 @@ static DWORD WINAPI test_rawinput_desktop_thread( void *args ) rawbuffer_size = sizeof(rawbuffer); memset( rawbuffer, 0, sizeof(rawbuffer) ); res = msg_wait_for_events( 1, &rawinput_event, 100 ); - todo_wine + todo_wine_if( params->input ) ok( res == 0, "WaitForSingleObject returned %#lx\n", res ); - todo_wine + todo_wine_if( params->input ) ok( rawinput_calls == 1, "got %u WM_INPUT messages\n", rawinput_calls );
rawinput = (RAWINPUT *)rawbuffer; - todo_wine + todo_wine_if( params->input ) ok( rawinput->header.dwType == RIM_TYPEHID, "got dwType %lu\n", rawinput->header.dwType ); - todo_wine + todo_wine_if( params->input ) ok( rawinput->header.dwSize == offsetof(RAWINPUT, data.hid.bRawData[desc.caps.InputReportByteLength * rawinput->data.hid.dwCount]), "got header.dwSize %lu\n", rawinput->header.dwSize ); - todo_wine + todo_wine_if( params->input ) ok( rawinput->header.hDevice != 0, "got hDevice %p\n", rawinput->header.hDevice ); ok( rawinput->header.wParam == 0, "got wParam %#Ix\n", rawinput->header.wParam ); - todo_wine + todo_wine_if( params->input ) ok( rawinput->data.hid.dwSizeHid == desc.caps.InputReportByteLength, "got dwSizeHid %lu\n", rawinput->data.hid.dwSizeHid ); - todo_wine + todo_wine_if( params->input ) ok( rawinput->data.hid.dwCount >= 1, "got dwCount %lu\n", rawinput->data.hid.dwCount );
@@ -5864,28 +5864,23 @@ static void test_rawinput_desktop( const char *path, BOOL input ) res = msg_wait_for_events( 1, &rawinput_event, 100 ); if (input) { - todo_wine ok( res == 0, "WaitForSingleObject returned %#lx\n", res ); - todo_wine ok( rawinput_calls == 1, "got %u WM_INPUT messages\n", rawinput_calls );
rawinput = (RAWINPUT *)rawbuffer; - todo_wine ok( rawinput->header.dwType == RIM_TYPEHID, "got dwType %lu\n", rawinput->header.dwType ); - todo_wine ok( rawinput->header.dwSize == offsetof(RAWINPUT, data.hid.bRawData[desc.caps.InputReportByteLength * rawinput->data.hid.dwCount]), "got header.dwSize %lu\n", rawinput->header.dwSize ); - todo_wine ok( rawinput->header.hDevice != 0, "got hDevice %p\n", rawinput->header.hDevice ); ok( rawinput->header.wParam == 0, "got wParam %#Ix\n", rawinput->header.wParam ); - todo_wine ok( rawinput->data.hid.dwSizeHid == desc.caps.InputReportByteLength, "got dwSizeHid %lu\n", rawinput->data.hid.dwSizeHid ); - todo_wine ok( rawinput->data.hid.dwCount >= 1, "got dwCount %lu\n", rawinput->data.hid.dwCount ); } else { + todo_wine ok( res == WAIT_TIMEOUT, "WaitForSingleObject returned %#lx\n", res ); + todo_wine ok( rawinput_calls == 0, "got %u WM_INPUT messages\n", rawinput_calls ); }
diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c index be95bd150b4..a78ea3b7c43 100644 --- a/dlls/user32/tests/input.c +++ b/dlls/user32/tests/input.c @@ -3855,19 +3855,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 ) ); diff --git a/server/process.c b/server/process.c index 3651696f505..b6c21d15752 100644 --- a/server/process.c +++ b/server/process.c @@ -1133,7 +1133,7 @@ DECL_HANDLER(new_process) { struct startup_info *info; const void *info_ptr; - struct unicode_str name; + struct unicode_str name, desktop_path = {0}; const struct security_descriptor *sd; const struct object_attributes *objattr = get_req_object_attributes( &sd, &name, NULL ); struct process *process = NULL; @@ -1276,7 +1276,9 @@ DECL_HANDLER(new_process) FIXUP_LEN( info->data->imagepath_len ); FIXUP_LEN( info->data->cmdline_len ); FIXUP_LEN( info->data->title_len ); + desktop_path.str = (WCHAR *)((char *)info->data + pos); FIXUP_LEN( info->data->desktop_len ); + desktop_path.len = info->data->desktop_len; FIXUP_LEN( info->data->shellinfo_len ); FIXUP_LEN( info->data->runtime_len ); #undef FIXUP_LEN @@ -1327,7 +1329,7 @@ DECL_HANDLER(new_process) }
/* connect to the window station */ - connect_process_winstation( process, parent_thread, parent ); + connect_process_winstation( process, &desktop_path, parent_thread, parent );
/* inherit the process console, but keep pseudo handles (< 0), and 0 (= not attached to a console) as is */ if ((int)info->data->console > 0) diff --git a/server/user.h b/server/user.h index 8fa55e09b0f..bc58c93200d 100644 --- a/server/user.h +++ b/server/user.h @@ -22,6 +22,7 @@ #define __WINE_SERVER_USER_H
#include "wine/server_protocol.h" +#include "unicode.h"
struct thread; struct region; @@ -186,8 +187,8 @@ extern client_ptr_t get_class_client_ptr( struct window_class *class ); extern struct desktop *get_desktop_obj( struct process *process, obj_handle_t handle, unsigned int access ); extern struct winstation *get_process_winstation( struct process *process, unsigned int access ); extern struct desktop *get_thread_desktop( struct thread *thread, unsigned int access ); -extern void connect_process_winstation( struct process *process, struct thread *parent_thread, - struct process *parent_process ); +extern void connect_process_winstation( struct process *process, struct unicode_str *desktop_path, + struct thread *parent_thread, struct process *parent_process ); extern void set_process_default_desktop( struct process *process, struct desktop *desktop, obj_handle_t handle ); extern void close_process_desktop( struct process *process ); diff --git a/server/winstation.c b/server/winstation.c index 930c5c90d97..c3ea69c8a29 100644 --- a/server/winstation.c +++ b/server/winstation.c @@ -373,18 +373,37 @@ void set_process_default_desktop( struct process *process, struct desktop *deskt }
/* connect a process to its window station */ -void connect_process_winstation( struct process *process, struct thread *parent_thread, - struct process *parent_process ) +void connect_process_winstation( struct process *process, struct unicode_str *desktop_path, + struct thread *parent_thread, struct process *parent_process ) { + struct unicode_str desktop_name = *desktop_path, winstation_name = {0}; + const int attributes = OBJ_CASE_INSENSITIVE | OBJ_OPENIF; struct winstation *winstation = NULL; struct desktop *desktop = NULL; + const WCHAR *wch, *end; obj_handle_t handle;
+ for (wch = desktop_name.str, end = wch + desktop_name.len / sizeof(WCHAR); wch != end; wch++) + { + if (*wch == '\') + { + winstation_name.str = desktop_name.str; + winstation_name.len = (wch - winstation_name.str) * sizeof(WCHAR); + desktop_name.str = wch + 1; + desktop_name.len = (end - desktop_name.str) * sizeof(WCHAR); + break; + } + } + /* check for an inherited winstation handle (don't ask...) */ if ((handle = find_inherited_handle( process, &winstation_ops ))) { winstation = (struct winstation *)get_handle_obj( process, handle, 0, &winstation_ops ); } + else if (winstation_name.len && (winstation = open_named_object( NULL, &winstation_ops, &winstation_name, attributes ))) + { + handle = alloc_handle( process, winstation, STANDARD_RIGHTS_REQUIRED | WINSTA_ALL_ACCESS, 0 ); + } else if (parent_process->winstation) { handle = duplicate_handle( parent_process, parent_process->winstation, @@ -399,6 +418,10 @@ void connect_process_winstation( struct process *process, struct thread *parent_ desktop = get_desktop_obj( process, handle, 0 ); if (!desktop || desktop->winstation != winstation) goto done; } + else if (desktop_name.len && (desktop = open_named_object( &winstation->obj, &desktop_ops, &desktop_name, attributes ))) + { + handle = alloc_handle( process, desktop, STANDARD_RIGHTS_REQUIRED | DESKTOP_ALL_ACCESS, 0 ); + } else { if (parent_thread && parent_thread->desktop)