Instead of leaking kernel pointers.
From: Jacek Caban jacek@codeweavers.com
--- dlls/user32/winproc.c | 62 +++--------------------------------- dlls/win32u/class.c | 19 ++++++++++- dlls/win32u/message.c | 8 ++--- dlls/win32u/ntuser_private.h | 2 +- include/ntuser.h | 1 - 5 files changed, 27 insertions(+), 65 deletions(-)
diff --git a/dlls/user32/winproc.c b/dlls/user32/winproc.c index 2c0aaf03da5..ab28eecb67c 100644 --- a/dlls/user32/winproc.c +++ b/dlls/user32/winproc.c @@ -719,78 +719,24 @@ void dispatch_win_proc_params( struct win_proc_params *params ) if (params->procW == WINPROC_PROC16) WINPROC_CallProcWtoA( wow_handlers.call_window_proc, params->hwnd, params->msg, params->wparam, params->lparam, params->result, params->func ); - else if (params->is_dialog) - { - if (!params->ansi_dst) - { - if (params->procW) - call_window_proc( params->hwnd, params->msg, params->wparam, params->lparam, - params->result, params->procW ); - else - call_window_proc( params->hwnd, params->msg, params->wparam, params->lparam, - params->result, params->func ); - } - else - { - if (params->procA) - WINPROC_CallProcWtoA( call_window_proc, params->hwnd, params->msg, params->wparam, - params->lparam, params->result, params->procA ); - else - WINPROC_CallProcWtoA( call_window_proc, params->hwnd, params->msg, params->wparam, - params->lparam, params->result, params->func ); - } - } - else if (params->procW) - call_window_proc( params->hwnd, params->msg, params->wparam, params->lparam, - params->result, params->procW ); - else if (params->procA) - WINPROC_CallProcWtoA( call_window_proc, params->hwnd, params->msg, params->wparam, - params->lparam, params->result, params->procA ); else if (!params->ansi_dst) call_window_proc( params->hwnd, params->msg, params->wparam, params->lparam, - params->result, params->func ); + params->result, params->procW ); else WINPROC_CallProcWtoA( call_window_proc, params->hwnd, params->msg, params->wparam, - params->lparam, params->result, params->func ); + params->lparam, params->result, params->procA ); } else { if (params->procA == WINPROC_PROC16) wow_handlers.call_window_proc( params->hwnd, params->msg, params->wparam, params->lparam, params->result, params->func ); - else if (params->is_dialog) - { - if (!params->ansi_dst) - { - if (params->procW) - WINPROC_CallProcAtoW( call_window_proc, params->hwnd, params->msg, params->wparam, - params->lparam, params->result, params->procW, params->mapping ); - else - WINPROC_CallProcAtoW( call_window_proc, params->hwnd, params->msg, params->wparam, - params->lparam, params->result, params->func, params->mapping ); - } - else - { - if (params->procA) - call_window_proc( params->hwnd, params->msg, params->wparam, params->lparam, - params->result, params->procA ); - else - call_window_proc( params->hwnd, params->msg, params->wparam, params->lparam, - params->result, params->func ); - } - } - else if (params->procA) - call_window_proc( params->hwnd, params->msg, params->wparam, params->lparam, - params->result, params->procA ); - else if (params->procW) - WINPROC_CallProcAtoW( call_window_proc, params->hwnd, params->msg, params->wparam, - params->lparam, params->result, params->procW, params->mapping ); else if (!params->ansi_dst) WINPROC_CallProcAtoW( call_window_proc, params->hwnd, params->msg, params->wparam, - params->lparam, params->result, params->func, params->mapping ); + params->lparam, params->result, params->procW, params->mapping ); else call_window_proc( params->hwnd, params->msg, params->wparam, params->lparam, - params->result, params->func ); + params->result, params->procA ); }
SetThreadDpiAwarenessContext( context ); diff --git a/dlls/win32u/class.c b/dlls/win32u/class.c index f8a7e67ddd1..6058617b80e 100644 --- a/dlls/win32u/class.c +++ b/dlls/win32u/class.c @@ -201,7 +201,7 @@ BOOL is_winproc_unicode( WNDPROC proc, BOOL def_val ) return ptr->procW != NULL; }
-void get_winproc_params( struct win_proc_params *params ) +void get_winproc_params( struct win_proc_params *params, BOOL fixup_ansi_dst ) { WINDOWPROC *proc = get_winproc_ptr( params->func );
@@ -217,7 +217,24 @@ void get_winproc_params( struct win_proc_params *params ) { params->procA = proc->procA; params->procW = proc->procW; + + if (fixup_ansi_dst) + { + if (params->ansi) + { + if (params->procA) params->ansi_dst = TRUE; + else if (params->procW) params->ansi_dst = FALSE; + } + else + { + if (params->procW) params->ansi_dst = FALSE; + else if (params->procA) params->ansi_dst = TRUE; + } + } } + + if (!params->procA) params->procA = params->func; + if (!params->procW) params->procW = params->func; }
DLGPROC get_dialog_proc( HWND hwnd, enum dialog_proc_type type ) diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index 6506a201559..b0c444f5407 100644 --- a/dlls/win32u/message.c +++ b/dlls/win32u/message.c @@ -202,11 +202,10 @@ static BOOL init_win_proc_params( struct win_proc_params *params, HWND hwnd, UIN params->wparam = wparam; params->lparam = lparam; params->ansi = params->ansi_dst = ansi; - params->is_dialog = FALSE; params->needs_unpack = FALSE; params->mapping = WMCHAR_MAP_CALLWINDOWPROC; params->dpi_awareness = get_window_dpi_awareness_context( params->hwnd ); - get_winproc_params( params ); + get_winproc_params( params, TRUE ); return TRUE; }
@@ -214,6 +213,7 @@ static BOOL init_window_call_params( struct win_proc_params *params, HWND hwnd, LPARAM lParam, LRESULT *result, BOOL ansi, enum wm_char_mapping mapping ) { + BOOL is_dialog; WND *win;
user_check_not_lock(); @@ -227,11 +227,10 @@ static BOOL init_window_call_params( struct win_proc_params *params, HWND hwnd, } params->func = win->winproc; params->ansi_dst = !(win->flags & WIN_ISUNICODE); - params->is_dialog = win->dlgInfo != NULL; + is_dialog = win->dlgInfo != NULL; release_win_ptr( win );
params->hwnd = get_full_window_handle( hwnd ); - get_winproc_params( params ); params->msg = msg; params->wparam = wParam; params->lparam = lParam; @@ -240,6 +239,7 @@ static BOOL init_window_call_params( struct win_proc_params *params, HWND hwnd, params->needs_unpack = FALSE; params->mapping = mapping; params->dpi_awareness = get_window_dpi_awareness_context( params->hwnd ); + get_winproc_params( params, !is_dialog ); return TRUE; }
diff --git a/dlls/win32u/ntuser_private.h b/dlls/win32u/ntuser_private.h index 1be8eed3020..c8ba7522278 100644 --- a/dlls/win32u/ntuser_private.h +++ b/dlls/win32u/ntuser_private.h @@ -235,7 +235,7 @@ WORD get_class_word( HWND hwnd, INT offset ) DECLSPEC_HIDDEN; DLGPROC get_dialog_proc( HWND hwnd, enum dialog_proc_type type ) DECLSPEC_HIDDEN; ATOM get_int_atom_value( UNICODE_STRING *name ) DECLSPEC_HIDDEN; WNDPROC get_winproc( WNDPROC proc, BOOL ansi ) DECLSPEC_HIDDEN; -void get_winproc_params( struct win_proc_params *params ) DECLSPEC_HIDDEN; +void get_winproc_params( struct win_proc_params *params, BOOL fixup_ansi_dst ) DECLSPEC_HIDDEN; struct dce *get_class_dce( struct tagCLASS *class ) DECLSPEC_HIDDEN; struct dce *set_class_dce( struct tagCLASS *class, struct dce *dce ) DECLSPEC_HIDDEN; BOOL needs_ime_window( HWND hwnd ) DECLSPEC_HIDDEN; diff --git a/include/ntuser.h b/include/ntuser.h index 053f60b8d1e..17301562013 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -146,7 +146,6 @@ struct win_proc_params LRESULT *result; BOOL ansi; BOOL ansi_dst; - BOOL is_dialog; BOOL needs_unpack; enum wm_char_mapping mapping; DPI_AWARENESS_CONTEXT dpi_awareness;
From: Jacek Caban jacek@codeweavers.com
--- dlls/win32u/clipboard.c | 4 ++-- dlls/win32u/input.c | 2 +- dlls/win32u/message.c | 22 +++++++++++++++------- dlls/win32u/palette.c | 2 +- dlls/win32u/sysparams.c | 4 ++-- dlls/win32u/win32u_private.h | 2 +- 6 files changed, 22 insertions(+), 14 deletions(-)
diff --git a/dlls/win32u/clipboard.c b/dlls/win32u/clipboard.c index d91d4339493..dfc0b629763 100644 --- a/dlls/win32u/clipboard.c +++ b/dlls/win32u/clipboard.c @@ -232,8 +232,8 @@ BOOL WINAPI NtUserEmptyClipboard(void)
TRACE( "owner %p\n", owner );
- if (owner) send_message_timeout( owner, WM_DESTROYCLIPBOARD, 0, 0, SMTO_ABORTIFHUNG, - 5000, NULL, FALSE ); + if (owner) + send_message_timeout( owner, WM_DESTROYCLIPBOARD, 0, 0, SMTO_ABORTIFHUNG, 5000, FALSE );
pthread_mutex_lock( &clipboard_mutex );
diff --git a/dlls/win32u/input.c b/dlls/win32u/input.c index 19233af4418..1344ab997cd 100644 --- a/dlls/win32u/input.c +++ b/dlls/win32u/input.c @@ -1636,7 +1636,7 @@ static BOOL set_active_window( HWND hwnd, HWND *prev, BOOL mouse, BOOL focus ) /* send palette messages */ if (send_message( hwnd, WM_QUERYNEWPALETTE, 0, 0 )) send_message_timeout( HWND_BROADCAST, WM_PALETTEISCHANGING, (WPARAM)hwnd, 0, - SMTO_ABORTIFHUNG, 2000, NULL, FALSE ); + SMTO_ABORTIFHUNG, 2000, FALSE ); if (!is_window(hwnd)) return FALSE; }
diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index b0c444f5407..f1ff3da2cd6 100644 --- a/dlls/win32u/message.c +++ b/dlls/win32u/message.c @@ -2609,11 +2609,11 @@ static BOOL broadcast_message( struct send_message_info *info, DWORD_PTR *res_pt { case MSG_UNICODE: send_message_timeout( list[i], info->msg, info->wparam, info->lparam, - info->flags, info->timeout, NULL, FALSE ); + info->flags, info->timeout, FALSE ); break; case MSG_ASCII: send_message_timeout( list[i], info->msg, info->wparam, info->lparam, - info->flags, info->timeout, NULL, TRUE ); + info->flags, info->timeout, TRUE ); break; case MSG_NOTIFY: NtUserMessageCall( list[i], info->msg, info->wparam, info->lparam, @@ -2810,8 +2810,8 @@ static LRESULT send_window_message( HWND hwnd, UINT msg, WPARAM wparam, LPARAM l }
/* see SendMessageTimeoutW */ -LRESULT send_message_timeout( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, - UINT flags, UINT timeout, DWORD_PTR *res_ptr, BOOL ansi ) +static LRESULT send_client_message( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, + UINT flags, UINT timeout, DWORD_PTR *res_ptr, BOOL ansi ) { struct send_message_info info;
@@ -2828,10 +2828,18 @@ LRESULT send_message_timeout( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, return process_message( &info, res_ptr, ansi ); }
+LRESULT send_message_timeout( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, + UINT flags, UINT timeout, BOOL ansi ) +{ + DWORD_PTR res = 0; + send_client_message( hwnd, msg, wparam, lparam, flags, timeout, &res, ansi ); + return res; +} + /* see SendMessageW */ LRESULT send_message( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) { - return send_window_message( hwnd, msg, wparam, lparam, NULL, FALSE ); + return send_message_timeout( hwnd, msg, wparam, lparam, SMTO_NORMAL, 0, FALSE ); }
/* see SendNotifyMessageW */ @@ -2971,8 +2979,8 @@ LRESULT WINAPI NtUserMessageCall( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpa { struct send_message_timeout_params *params = (void *)result_info; DWORD_PTR res = 0; - params->result = send_message_timeout( hwnd, msg, wparam, lparam, params->flags, - params->timeout, &res, ansi ); + params->result = send_client_message( hwnd, msg, wparam, lparam, params->flags, + params->timeout, &res, ansi ); return res; }
diff --git a/dlls/win32u/palette.c b/dlls/win32u/palette.c index 217a96bb027..e8fd51dba22 100644 --- a/dlls/win32u/palette.c +++ b/dlls/win32u/palette.c @@ -584,7 +584,7 @@ UINT realize_palette( HDC hdc ) /* send palette change notification */ HWND hwnd = NtUserWindowFromDC( hdc ); if (hwnd) send_message_timeout( HWND_BROADCAST, WM_PALETTECHANGED, HandleToUlong(hwnd), 0, - SMTO_ABORTIFHUNG, 2000, NULL, FALSE ); + SMTO_ABORTIFHUNG, 2000, FALSE ); } return realized; } diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 99495349246..52665f7a641 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -4397,7 +4397,7 @@ BOOL WINAPI NtUserSystemParametersInfo( UINT action, UINT val, void *ptr, UINT w static const WCHAR emptyW[1]; if (winini & (SPIF_SENDWININICHANGE | SPIF_SENDCHANGE)) send_message_timeout( HWND_BROADCAST, WM_SETTINGCHANGE, action, (LPARAM) emptyW, - SMTO_ABORTIFHUNG, 2000, NULL, FALSE ); + SMTO_ABORTIFHUNG, 2000, FALSE ); } TRACE( "(%u, %u, %p, %u) ret %d\n", action, val, ptr, winini, ret ); return ret; @@ -4840,7 +4840,7 @@ BOOL WINAPI NtUserSetSysColors( INT count, const INT *colors, const COLORREF *va
/* Send WM_SYSCOLORCHANGE message to all windows */ send_message_timeout( HWND_BROADCAST, WM_SYSCOLORCHANGE, 0, 0, - SMTO_ABORTIFHUNG, 2000, NULL, FALSE ); + SMTO_ABORTIFHUNG, 2000, FALSE ); /* Repaint affected portions of all visible windows */ NtUserRedrawWindow( 0, NULL, 0, RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW | RDW_ALLCHILDREN ); return TRUE; diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index ba6479a5426..a243afd668c 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -308,7 +308,7 @@ extern LRESULT send_internal_message_timeout( DWORD dest_pid, DWORD dest_tid, UI PDWORD_PTR res_ptr ) DECLSPEC_HIDDEN; extern LRESULT send_message( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) DECLSPEC_HIDDEN; extern LRESULT send_message_timeout( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, - UINT flags, UINT timeout, PDWORD_PTR res_ptr, BOOL ansi ); + UINT flags, UINT timeout, BOOL ansi );
/* rawinput.c */ extern BOOL process_rawinput_message( MSG *msg, UINT hw_id, const struct hardware_msg_data *msg_data ) DECLSPEC_HIDDEN;
From: Jacek Caban jacek@codeweavers.com
Instead of leaking kernel pointers. --- dlls/win32u/message.c | 218 +++++++++++++++++++++++++++++++++-- dlls/win32u/ntuser_private.h | 9 -- 2 files changed, 209 insertions(+), 18 deletions(-)
diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index f1ff3da2cd6..d41b68122bb 100644 --- a/dlls/win32u/message.c +++ b/dlls/win32u/message.c @@ -47,6 +47,18 @@ WINE_DECLARE_DEBUG_CHANNEL(relay);
#define MAX_PACK_COUNT 4
+/* info about the message currently being received by the current thread */ +struct received_message_info +{ + UINT type; + MSG msg; + UINT flags; /* InSendMessageEx return flags */ + LRESULT result; + struct received_message_info *prev; +}; + +#define MSG_CLIENT_MESSAGE 0xff + struct packed_hook_extra_info { user_handle_t handle; @@ -1029,6 +1041,117 @@ static void unpack_reply( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam, } }
+/*********************************************************************** + * copy_reply + * + * Copy a message reply received from client. + */ +static void copy_reply( LRESULT result, HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam, + WPARAM wparam_src, LPARAM lparam_src ) +{ + size_t copy_size = 0; + + switch(message) + { + case WM_NCCREATE: + case WM_CREATE: + { + CREATESTRUCTW *dst = (CREATESTRUCTW *)lparam; + CREATESTRUCTW *src = (CREATESTRUCTW *)lparam_src; + dst->lpCreateParams = src->lpCreateParams; + dst->hInstance = src->hInstance; + dst->hMenu = src->hMenu; + dst->hwndParent = src->hwndParent; + dst->cy = src->cy; + dst->cx = src->cx; + dst->y = src->y; + dst->x = src->x; + dst->style = src->style; + dst->dwExStyle = src->dwExStyle; + /* don't allow changing name and class pointers */ + } + return; + case WM_GETTEXT: + case CB_GETLBTEXT: + case LB_GETTEXT: + copy_size = (result + 1) * sizeof(WCHAR); + break; + case WM_GETMINMAXINFO: + copy_size = sizeof(MINMAXINFO); + break; + case WM_MEASUREITEM: + copy_size = sizeof(MEASUREITEMSTRUCT); + break; + case WM_WINDOWPOSCHANGING: + case WM_WINDOWPOSCHANGED: + copy_size = sizeof(WINDOWPOS); + break; + case WM_STYLECHANGING: + copy_size = sizeof(STYLESTRUCT); + break; + case WM_GETDLGCODE: + if (lparam) copy_size = sizeof(MSG); + break; + case SBM_GETSCROLLINFO: + copy_size = sizeof(SCROLLINFO); + break; + case SBM_GETSCROLLBARINFO: + copy_size = sizeof(SCROLLBARINFO); + break; + case EM_GETRECT: + case LB_GETITEMRECT: + case CB_GETDROPPEDCONTROLRECT: + case WM_SIZING: + case WM_MOVING: + copy_size = sizeof(RECT); + break; + case EM_GETLINE: + { + WORD *ptr = (WORD *)lparam; + copy_size = ptr[-1] * sizeof(WCHAR); + break; + } + case LB_GETSELITEMS: + copy_size = wparam * sizeof(UINT); + break; + case WM_MDIGETACTIVE: + if (lparam) copy_size = sizeof(BOOL); + break; + case WM_NCCALCSIZE: + if (wparam) + { + NCCALCSIZE_PARAMS *dst = (NCCALCSIZE_PARAMS *)lparam; + NCCALCSIZE_PARAMS *src = (NCCALCSIZE_PARAMS *)lparam_src; + dst->rgrc[0] = src->rgrc[0]; + dst->rgrc[1] = src->rgrc[1]; + dst->rgrc[2] = src->rgrc[2]; + *dst->lppos = *src->lppos; + return; + } + copy_size = sizeof(RECT); + break; + case EM_GETSEL: + case SBM_GETRANGE: + case CB_GETEDITSEL: + if (wparam) *(DWORD *)wparam = *(DWORD *)wparam_src; + if (lparam) copy_size = sizeof(DWORD); + break; + case WM_NEXTMENU: + copy_size = sizeof(MDINEXTMENU); + break; + case WM_MDICREATE: + copy_size = sizeof(MDICREATESTRUCTW); + break; + case WM_ASKCBFORMATNAME: + copy_size = (lstrlenW((WCHAR *)lparam) + 1) * sizeof(WCHAR); + break; + default: + return; + } + + if (copy_size) memcpy( (void *)lparam, (void *)lparam_src, copy_size ); +} + /*********************************************************************** * reply_message * @@ -1074,6 +1197,7 @@ BOOL reply_message_result( LRESULT result ) struct user_thread_info *thread_info = get_user_thread_info(); struct received_message_info *info = thread_info->receive_info;
+ while (info && info->type == MSG_CLIENT_MESSAGE) info = info->prev; if (!info) return FALSE; reply_message( info, result, NULL ); return TRUE; @@ -1092,6 +1216,13 @@ static BOOL reply_winproc_result( LRESULT result, HWND hwnd, UINT message, WPARA
if (!info) return FALSE;
+ if (info->type == MSG_CLIENT_MESSAGE) + { + copy_reply( result, hwnd, message, info->msg.wParam, info->msg.lParam, wparam, lparam ); + info->result = result; + return TRUE; + } + msg.hwnd = hwnd; msg.message = message; msg.wParam = wparam; @@ -1221,8 +1352,12 @@ static LRESULT call_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpar return 0; }
- params->needs_unpack = needs_unpack; - if (size) memcpy( params + 1, buffer, size ); + if (needs_unpack) + { + params->needs_unpack = TRUE; + params->ansi = FALSE; + if (size) memcpy( params + 1, buffer, size ); + }
/* first the WH_CALLWNDPROC hook */ cwp.lParam = lparam; @@ -2608,6 +2743,7 @@ static BOOL broadcast_message( struct send_message_info *info, DWORD_PTR *res_pt switch(info->type) { case MSG_UNICODE: + case MSG_OTHER_PROCESS: send_message_timeout( list[i], info->msg, info->wparam, info->lparam, info->flags, info->timeout, FALSE ); break; @@ -2641,6 +2777,48 @@ static BOOL broadcast_message( struct send_message_info *info, DWORD_PTR *res_pt return TRUE; }
+static BOOL process_packed_message( struct send_message_info *info, LRESULT *res_ptr, BOOL ansi ) +{ + struct user_thread_info *thread_info = get_user_thread_info(); + struct received_message_info receive_info; + struct packed_message data; + size_t buffer_size = 0, i; + void *buffer = NULL; + char *ptr; + + pack_message( info->hwnd, info->msg, info->wparam, info->lparam, &data ); + if (data.count == -1) return FALSE; + + for (i = 0; i < data.count; i++) buffer_size += data.size[i]; + if (!(buffer = malloc( buffer_size ))) return FALSE; + for (ptr = buffer, i = 0; i < data.count; i++) + { + memcpy( ptr, data.data[i], data.size[i] ); + ptr += data.size[i]; + } + + receive_info.type = MSG_CLIENT_MESSAGE; + receive_info.msg.hwnd = info->hwnd; + receive_info.msg.message = info->msg; + receive_info.msg.wParam = info->wparam; + receive_info.msg.lParam = info->lparam; + receive_info.flags = 0; + receive_info.prev = thread_info->receive_info; + receive_info.result = 0; + thread_info->receive_info = &receive_info; + + *res_ptr = call_window_proc( info->hwnd, info->msg, info->wparam, info->lparam, + !ansi, TRUE, info->wm_char, TRUE, buffer, buffer_size ); + if (thread_info->receive_info == &receive_info) + { + thread_info->receive_info = receive_info.prev; + *res_ptr = receive_info.result; + } + free( buffer ); + return TRUE; +} + + /*********************************************************************** * process_message * @@ -2652,7 +2830,7 @@ static BOOL process_message( struct send_message_info *info, DWORD_PTR *res_ptr, INPUT_MESSAGE_SOURCE prev_source = thread_info->msg_source; DWORD dest_pid; BOOL ret; - LRESULT result; + LRESULT result = 0;
if (is_broadcast( info->hwnd )) return broadcast_message( info, res_ptr );
@@ -2672,7 +2850,13 @@ static BOOL process_message( struct send_message_info *info, DWORD_PTR *res_ptr, thread_info->msg_source = msg_source_unavailable; spy_enter_message( SPY_SENDMESSAGE, info->hwnd, info->msg, info->wparam, info->lparam );
- if (info->dest_tid == GetCurrentThreadId()) + if (info->dest_tid != GetCurrentThreadId()) + { + if (dest_pid != GetCurrentProcessId() && (info->type == MSG_ASCII || info->type == MSG_UNICODE)) + info->type = MSG_OTHER_PROCESS; + ret = send_inter_thread_message( info, &result ); + } + else if (info->type != MSG_OTHER_PROCESS) { result = call_window_proc( info->hwnd, info->msg, info->wparam, info->lparam, !ansi, TRUE, info->wm_char, FALSE, NULL, 0 ); @@ -2682,9 +2866,7 @@ static BOOL process_message( struct send_message_info *info, DWORD_PTR *res_ptr, } else { - if (dest_pid != GetCurrentProcessId() && (info->type == MSG_ASCII || info->type == MSG_UNICODE)) - info->type = MSG_OTHER_PROCESS; - ret = send_inter_thread_message( info, &result ); + ret = process_packed_message( info, &result, ansi ); }
spy_exit_message( SPY_RESULT_OK, info->hwnd, info->msg, result, info->wparam, info->lparam ); @@ -2831,8 +3013,26 @@ static LRESULT send_client_message( HWND hwnd, UINT msg, WPARAM wparam, LPARAM l LRESULT send_message_timeout( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, UINT flags, UINT timeout, BOOL ansi ) { - DWORD_PTR res = 0; - send_client_message( hwnd, msg, wparam, lparam, flags, timeout, &res, ansi ); + struct send_message_info info; + DWORD_PTR res; + + if (!is_pointer_message( msg, wparam )) + { + send_client_message( hwnd, msg, wparam, lparam, flags, timeout, &res, ansi ); + return res; + } + + info.type = MSG_OTHER_PROCESS; + info.hwnd = hwnd; + info.msg = msg; + info.wparam = wparam; + info.lparam = lparam; + info.flags = flags; + info.timeout = timeout; + info.wm_char = WMCHAR_MAP_SENDMESSAGETIMEOUT; + info.params = NULL; + + process_message( &info, &res, ansi ); return res; }
diff --git a/dlls/win32u/ntuser_private.h b/dlls/win32u/ntuser_private.h index c8ba7522278..9f93feea407 100644 --- a/dlls/win32u/ntuser_private.h +++ b/dlls/win32u/ntuser_private.h @@ -209,15 +209,6 @@ struct scroll_bar_win_data #define WINSWITCH_CLASS_ATOM MAKEINTATOM(32771) /* WinSwitch */ #define ICONTITLE_CLASS_ATOM MAKEINTATOM(32772) /* IconTitle */
-/* info about the message currently being received by the current thread */ -struct received_message_info -{ - UINT type; - MSG msg; - UINT flags; /* InSendMessageEx return flags */ - struct received_message_info *prev; -}; - extern const char *debugstr_msg_name( UINT msg, HWND hwnd ) DECLSPEC_HIDDEN; extern const char *debugstr_vkey_name( WPARAM wParam ) DECLSPEC_HIDDEN; extern void spy_enter_message( INT flag, HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) DECLSPEC_HIDDEN;
From: Jacek Caban jacek@codeweavers.com
--- dlls/user32/win.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/dlls/user32/win.c b/dlls/user32/win.c index e246d112383..77bd2bfa3fe 100644 --- a/dlls/user32/win.c +++ b/dlls/user32/win.c @@ -300,9 +300,9 @@ static BOOL is_default_coord( int x ) */ HWND WIN_CreateWindowEx( CREATESTRUCTW *cs, LPCWSTR className, HINSTANCE module, BOOL unicode ) { + UNICODE_STRING class, window_name; HWND hwnd, top_child = 0; MDICREATESTRUCTW mdi_cs; - UNICODE_STRING class; CBT_CREATEWNDW cbtc; WNDCLASSEXW info; HMENU menu; @@ -399,15 +399,21 @@ HWND WIN_CreateWindowEx( CREATESTRUCTW *cs, LPCWSTR className, HINSTANCE module, } }
+ if (unicode || !cs->lpszName) + RtlInitUnicodeString( &window_name, cs->lpszName ); + else if (!RtlCreateUnicodeStringFromAsciiz( &window_name, (const char *)cs->lpszName )) + return 0; + menu = cs->hMenu; if (!menu && info.lpszMenuName && (cs->style & (WS_CHILD | WS_POPUP)) != WS_CHILD) menu = LoadMenuW( cs->hInstance, info.lpszMenuName );
cbtc.lpcs = cs; - hwnd = NtUserCreateWindowEx( cs->dwExStyle, &class, NULL, NULL, cs->style, cs->x, cs->y, - cs->cx, cs->cy, cs->hwndParent, menu, module, + hwnd = NtUserCreateWindowEx( cs->dwExStyle, &class, NULL, &window_name, cs->style, + cs->x, cs->y, cs->cx, cs->cy, cs->hwndParent, menu, module, cs->lpCreateParams, 0, &cbtc, 0, !unicode ); if (!hwnd && menu && menu != cs->hMenu) NtUserDestroyMenu( menu ); + if (!unicode) RtlFreeUnicodeString( &window_name ); return hwnd; }
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=121216
Your paranoid android.
=== debian11 (32 bit report) ===
user32: win.c:413: Test failed: Set GWL_HWNDPARENT succeeded on desktop
=== debian11 (32 bit Chinese:China report) ===
user32: win.c:413: Test failed: Set GWL_HWNDPARENT succeeded on desktop
=== debian11 (32 bit WoW report) ===
user32: win.c:413: Test failed: Set GWL_HWNDPARENT succeeded on desktop
=== debian11 (64 bit WoW report) ===
user32: win.c:413: Test failed: Set GWL_HWNDPARENT succeeded on desktop
From: Jacek Caban jacek@codeweavers.com
--- dlls/user32/win.c | 4 +--- dlls/win32u/window.c | 38 +++++++++++--------------------------- 2 files changed, 12 insertions(+), 30 deletions(-)
diff --git a/dlls/user32/win.c b/dlls/user32/win.c index 77bd2bfa3fe..d0a34841ce0 100644 --- a/dlls/user32/win.c +++ b/dlls/user32/win.c @@ -303,7 +303,6 @@ HWND WIN_CreateWindowEx( CREATESTRUCTW *cs, LPCWSTR className, HINSTANCE module, UNICODE_STRING class, window_name; HWND hwnd, top_child = 0; MDICREATESTRUCTW mdi_cs; - CBT_CREATEWNDW cbtc; WNDCLASSEXW info; HMENU menu;
@@ -408,10 +407,9 @@ HWND WIN_CreateWindowEx( CREATESTRUCTW *cs, LPCWSTR className, HINSTANCE module, if (!menu && info.lpszMenuName && (cs->style & (WS_CHILD | WS_POPUP)) != WS_CHILD) menu = LoadMenuW( cs->hInstance, info.lpszMenuName );
- cbtc.lpcs = cs; hwnd = NtUserCreateWindowEx( cs->dwExStyle, &class, NULL, &window_name, cs->style, cs->x, cs->y, cs->cx, cs->cy, cs->hwndParent, menu, module, - cs->lpCreateParams, 0, &cbtc, 0, !unicode ); + cs->lpCreateParams, 0, NULL, 0, !unicode ); if (!hwnd && menu && menu != cs->hMenu) NtUserDestroyMenu( menu ); if (!unicode) RtlFreeUnicodeString( &window_name ); return hwnd; diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index 6e41bc8d27f..0eac0a6320b 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -5050,41 +5050,27 @@ HWND WINAPI NtUserCreateWindowEx( DWORD ex_style, UNICODE_STRING *class_name, UNICODE_STRING *version, UNICODE_STRING *window_name, DWORD style, INT x, INT y, INT cx, INT cy, HWND parent, HMENU menu, HINSTANCE instance, void *params, - DWORD flags, CBT_CREATEWNDW *cbtc, DWORD unk, BOOL ansi ) + DWORD flags, CBT_CREATEWNDW *client_cbtc, DWORD unk, BOOL ansi ) { - CREATESTRUCTW cs, *client_cs, cs_buf; UINT win_dpi, thread_dpi = get_thread_dpi(); DPI_AWARENESS_CONTEXT context; - CBT_CREATEWNDW cbtc_buf; + CBT_CREATEWNDW cbtc; HWND hwnd, owner = 0; + CREATESTRUCTW cs; INT sw = SW_SHOW; RECT rect; WND *win;
static const WCHAR messageW[] = {'M','e','s','s','a','g','e'};
- /* FIXME: We should pass a packed struct to client instead of using client_cs */ - if (cbtc) - { - client_cs = cbtc->lpcs; - cs.lpszName = client_cs->lpszName; - cs.lpszClass = client_cs->lpszClass; - cs.hInstance = client_cs->hInstance; /* may be different than instance for win16 */ - } - else - { - cbtc = &cbtc_buf; - client_cs = cbtc->lpcs = &cs_buf; - cs.lpszName = window_name ? window_name->Buffer : NULL; - cs.lpszClass = class_name->Buffer; - cs.hInstance = instance; - } - cs.lpCreateParams = params; + cs.hInstance = instance; cs.hMenu = menu; cs.hwndParent = parent; cs.style = style; cs.dwExStyle = ex_style; + cs.lpszName = window_name ? window_name->Buffer : NULL; + cs.lpszClass = class_name ? class_name->Buffer : NULL; cs.x = x; cs.y = y; cs.cx = cx; @@ -5166,9 +5152,9 @@ HWND WINAPI NtUserCreateWindowEx( DWORD ex_style, UNICODE_STRING *class_name, /* call the WH_CBT hook */
release_win_ptr( win ); - *client_cs = cs; - cbtc->hwndInsertAfter = HWND_TOP; - if (call_hooks( WH_CBT, HCBT_CREATEWND, (WPARAM)hwnd, (LPARAM)cbtc, !ansi )) + cbtc.hwndInsertAfter = HWND_TOP; + cbtc.lpcs = &cs; + if (call_hooks( WH_CBT, HCBT_CREATEWND, (WPARAM)hwnd, (LPARAM)&cbtc, TRUE )) { free_window_handle( hwnd ); return 0; @@ -5250,8 +5236,7 @@ HWND WINAPI NtUserCreateWindowEx( DWORD ex_style, UNICODE_STRING *class_name, /* send WM_NCCREATE */
TRACE( "hwnd %p cs %d,%d %dx%d %s\n", hwnd, cs.x, cs.y, cs.cx, cs.cy, wine_dbgstr_rect(&rect) ); - *client_cs = cs; - if (!NtUserMessageCall( hwnd, WM_NCCREATE, 0, (LPARAM)client_cs, NULL, NtUserSendMessage, ansi )) + if (!send_message_timeout( hwnd, WM_NCCREATE, 0, (LPARAM)&cs, SMTO_NORMAL, 0, ansi )) { WARN( "%p: aborted by WM_NCCREATE\n", hwnd ); goto failed; @@ -5283,9 +5268,8 @@ HWND WINAPI NtUserCreateWindowEx( DWORD ex_style, UNICODE_STRING *class_name, else goto failed;
/* send WM_CREATE */ - if (NtUserMessageCall( hwnd, WM_CREATE, 0, (LPARAM)client_cs, 0, NtUserSendMessage, ansi ) == -1) + if (send_message_timeout( hwnd, WM_CREATE, 0, (LPARAM)&cs, SMTO_NORMAL, 0, ansi ) == -1) goto failed; - cs = *client_cs;
/* call the driver */
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=121217
Your paranoid android.
=== debian11 (32 bit report) ===
user32: win.c:413: Test failed: Set GWL_HWNDPARENT succeeded on desktop
=== debian11 (32 bit Chinese:China report) ===
user32: win.c:413: Test failed: Set GWL_HWNDPARENT succeeded on desktop
=== debian11 (32 bit WoW report) ===
user32: win.c:413: Test failed: Set GWL_HWNDPARENT succeeded on desktop
=== debian11 (64 bit WoW report) ===
user32: win.c:413: Test failed: Set GWL_HWNDPARENT succeeded on desktop
From: Jacek Caban jacek@codeweavers.com
--- dlls/win32u/defwnd.c | 6 +++--- dlls/win32u/hook.c | 8 ++++---- dlls/win32u/input.c | 6 +++--- dlls/win32u/message.c | 24 ++++++++++++------------ dlls/win32u/win32u_private.h | 2 +- dlls/win32u/window.c | 10 +++++----- 6 files changed, 28 insertions(+), 28 deletions(-)
diff --git a/dlls/win32u/defwnd.c b/dlls/win32u/defwnd.c index 3d3a40ac9e4..b9a74884c01 100644 --- a/dlls/win32u/defwnd.c +++ b/dlls/win32u/defwnd.c @@ -883,7 +883,7 @@ static void sys_command_size_move( HWND hwnd, WPARAM wparam ) NtUserReleaseDC( parent, hdc ); if (parent) map_window_points( 0, parent, (POINT *)&sizing_rect, 2, get_thread_dpi() );
- if (call_hooks( WH_CBT, HCBT_MOVESIZE, (WPARAM)hwnd, (LPARAM)&sizing_rect, TRUE )) + if (call_hooks( WH_CBT, HCBT_MOVESIZE, (WPARAM)hwnd, (LPARAM)&sizing_rect )) moved = FALSE;
send_message( hwnd, WM_EXITSIZEMOVE, 0, 0 ); @@ -950,7 +950,7 @@ static LRESULT handle_sys_command( HWND hwnd, WPARAM wparam, LPARAM lparam )
if (!is_window_enabled( hwnd )) return 0;
- if (call_hooks( WH_CBT, HCBT_SYSCOMMAND, wparam, lparam, TRUE )) + if (call_hooks( WH_CBT, HCBT_SYSCOMMAND, wparam, lparam )) return 0;
if (!user_driver->pSysCommand( hwnd, wparam, lparam )) @@ -2811,7 +2811,7 @@ LRESULT default_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, { HWND parent = get_parent( hwnd ); if (!parent) - call_hooks( WH_SHELL, HSHELL_APPCOMMAND, wparam, lparam, TRUE ); + call_hooks( WH_SHELL, HSHELL_APPCOMMAND, wparam, lparam ); else send_message( parent, msg, wparam, lparam ); break; diff --git a/dlls/win32u/hook.c b/dlls/win32u/hook.c index 0f4ec338b77..95ce8ab7e9b 100644 --- a/dlls/win32u/hook.c +++ b/dlls/win32u/hook.c @@ -179,8 +179,8 @@ BOOL WINAPI NtUserCallMsgFilter( MSG *msg, INT code ) { /* FIXME: We should use NtCallbackReturn instead of passing (potentially kernel) pointer * like that, but we need to consequently use syscall thunks first for that to work. */ - if (call_hooks( WH_SYSMSGFILTER, code, 0, (LPARAM)msg, TRUE )) return TRUE; - return call_hooks( WH_MSGFILTER, code, 0, (LPARAM)msg, TRUE ); + if (call_hooks( WH_SYSMSGFILTER, code, 0, (LPARAM)msg )) return TRUE; + return call_hooks( WH_MSGFILTER, code, 0, (LPARAM)msg ); }
static UINT get_ll_hook_timeout(void) @@ -333,7 +333,7 @@ LRESULT call_current_hook( HHOOK hhook, INT code, WPARAM wparam, LPARAM lparam ) return call_hook( &info ); }
-LRESULT call_hooks( INT id, INT code, WPARAM wparam, LPARAM lparam, BOOL unicode ) +LRESULT call_hooks( INT id, INT code, WPARAM wparam, LPARAM lparam ) { struct user_thread_info *thread_info = get_user_thread_info(); struct win_hook_params info; @@ -348,7 +348,7 @@ LRESULT call_hooks( INT id, INT code, WPARAM wparam, LPARAM lparam, BOOL unicode }
memset( &info, 0, sizeof(info) - sizeof(info.module) ); - info.prev_unicode = unicode; + info.prev_unicode = TRUE; info.id = id;
SERVER_START_REQ( start_hook_chain ) diff --git a/dlls/win32u/input.c b/dlls/win32u/input.c index 1344ab997cd..ed0aa997894 100644 --- a/dlls/win32u/input.c +++ b/dlls/win32u/input.c @@ -1611,7 +1611,7 @@ static BOOL set_active_window( HWND hwnd, HWND *prev, BOOL mouse, BOOL focus ) /* call CBT hook chain */ cbt.fMouse = mouse; cbt.hWndActive = previous; - if (call_hooks( WH_CBT, HCBT_ACTIVATE, (WPARAM)hwnd, (LPARAM)&cbt, TRUE )) return FALSE; + if (call_hooks( WH_CBT, HCBT_ACTIVATE, (WPARAM)hwnd, (LPARAM)&cbt )) return FALSE;
if (is_window( previous )) { @@ -1763,7 +1763,7 @@ HWND WINAPI NtUserSetFocus( HWND hwnd ) }
/* call hooks */ - if (call_hooks( WH_CBT, HCBT_SETFOCUS, (WPARAM)hwnd, (LPARAM)previous, TRUE )) return 0; + if (call_hooks( WH_CBT, HCBT_SETFOCUS, (WPARAM)hwnd, (LPARAM)previous )) return 0;
/* activate hwndTop if needed. */ if (hwndTop != get_active_window()) @@ -1778,7 +1778,7 @@ HWND WINAPI NtUserSetFocus( HWND hwnd ) else /* NULL hwnd passed in */ { if (!previous) return 0; /* nothing to do */ - if (call_hooks( WH_CBT, HCBT_SETFOCUS, 0, (LPARAM)previous, TRUE )) return 0; + if (call_hooks( WH_CBT, HCBT_SETFOCUS, 0, (LPARAM)previous )) return 0; }
/* change focus and send messages */ diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index d41b68122bb..55b67a08d8f 100644 --- a/dlls/win32u/message.c +++ b/dlls/win32u/message.c @@ -1364,7 +1364,7 @@ static LRESULT call_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpar cwp.wParam = wparam; cwp.message = msg; cwp.hwnd = params->hwnd; - call_hooks( WH_CALLWNDPROC, HC_ACTION, same_thread, (LPARAM)&cwp, unicode ); + call_hooks( WH_CALLWNDPROC, HC_ACTION, same_thread, (LPARAM)&cwp );
dispatch_win_proc_params( params, sizeof(*params) + size ); if (params != &p) free( params ); @@ -1375,7 +1375,7 @@ static LRESULT call_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpar cwpret.wParam = wparam; cwpret.message = msg; cwpret.hwnd = params->hwnd; - call_hooks( WH_CALLWNDPROCRET, HC_ACTION, same_thread, (LPARAM)&cwpret, unicode ); + call_hooks( WH_CALLWNDPROCRET, HC_ACTION, same_thread, (LPARAM)&cwpret ); return result; }
@@ -1482,7 +1482,7 @@ static BOOL process_keyboard_message( MSG *msg, UINT hw_id, HWND hwnd_filter, event.paramL = (msg->wParam & 0xFF) | (HIWORD(msg->lParam) << 8); event.paramH = msg->lParam & 0x7FFF; if (HIWORD(msg->lParam) & 0x0100) event.paramH |= 0x8000; /* special_key - bit */ - call_hooks( WH_JOURNALRECORD, HC_ACTION, 0, (LPARAM)&event, TRUE ); + call_hooks( WH_JOURNALRECORD, HC_ACTION, 0, (LPARAM)&event );
/* check message filters */ if (msg->message < first || msg->message > last) return FALSE; @@ -1515,10 +1515,10 @@ static BOOL process_keyboard_message( MSG *msg, UINT hw_id, HWND hwnd_filter, }
if (call_hooks( WH_KEYBOARD, remove ? HC_ACTION : HC_NOREMOVE, - LOWORD(msg->wParam), msg->lParam, TRUE )) + LOWORD(msg->wParam), msg->lParam )) { /* skip this message */ - call_hooks( WH_CBT, HCBT_KEYSKIPPED, LOWORD(msg->wParam), msg->lParam, TRUE ); + call_hooks( WH_CBT, HCBT_KEYSKIPPED, LOWORD(msg->wParam), msg->lParam ); accept_hardware_message( hw_id ); return FALSE; } @@ -1590,7 +1590,7 @@ static BOOL process_mouse_message( MSG *msg, UINT hw_id, ULONG_PTR extra_info, H event.hwnd = msg->hwnd; event.paramL = msg->pt.x; event.paramH = msg->pt.y; - call_hooks( WH_JOURNALRECORD, HC_ACTION, 0, (LPARAM)&event, TRUE ); + call_hooks( WH_JOURNALRECORD, HC_ACTION, 0, (LPARAM)&event );
if (!check_hwnd_filter( msg, hwnd_filter )) return FALSE;
@@ -1664,14 +1664,14 @@ static BOOL process_mouse_message( MSG *msg, UINT hw_id, ULONG_PTR extra_info, H hook.wHitTestCode = hittest; hook.dwExtraInfo = extra_info; hook.mouseData = msg->wParam; - if (call_hooks( WH_MOUSE, remove ? HC_ACTION : HC_NOREMOVE, message, (LPARAM)&hook, TRUE )) + if (call_hooks( WH_MOUSE, remove ? HC_ACTION : HC_NOREMOVE, message, (LPARAM)&hook )) { hook.pt = msg->pt; hook.hwnd = msg->hwnd; hook.wHitTestCode = hittest; hook.dwExtraInfo = extra_info; hook.mouseData = msg->wParam; - call_hooks( WH_CBT, HCBT_CLICKSKIPPED, message, (LPARAM)&hook, TRUE ); + call_hooks( WH_CBT, HCBT_CLICKSKIPPED, message, (LPARAM)&hook ); accept_hardware_message( hw_id ); return FALSE; } @@ -1922,7 +1922,7 @@ static int peek_message( MSG *msg, HWND hwnd, UINT first, UINT last, UINT flags, hook.dwExtraInfo = msg_data->hardware.info; TRACE( "calling keyboard LL hook vk %x scan %x flags %x time %u info %lx\n", hook.vkCode, hook.scanCode, hook.flags, hook.time, hook.dwExtraInfo ); - result = call_hooks( WH_KEYBOARD_LL, HC_ACTION, info.msg.wParam, (LPARAM)&hook, TRUE ); + result = call_hooks( WH_KEYBOARD_LL, HC_ACTION, info.msg.wParam, (LPARAM)&hook ); } else if (info.msg.message == WH_MOUSE_LL && size >= sizeof(msg_data->hardware)) { @@ -1935,7 +1935,7 @@ static int peek_message( MSG *msg, HWND hwnd, UINT first, UINT last, UINT flags, hook.dwExtraInfo = msg_data->hardware.info; TRACE( "calling mouse LL hook pos %d,%d data %x flags %x time %u info %lx\n", hook.pt.x, hook.pt.y, hook.mouseData, hook.flags, hook.time, hook.dwExtraInfo ); - result = call_hooks( WH_MOUSE_LL, HC_ACTION, info.msg.wParam, (LPARAM)&hook, TRUE ); + result = call_hooks( WH_MOUSE_LL, HC_ACTION, info.msg.wParam, (LPARAM)&hook ); } reply_message( &info, result, &info.msg ); continue; @@ -1965,7 +1965,7 @@ static int peek_message( MSG *msg, HWND hwnd, UINT first, UINT last, UINT flags, thread_info->client_info.message_time = info.msg.time; thread_info->client_info.message_extra = msg_data->hardware.info; free( buffer ); - call_hooks( WH_GETMESSAGE, HC_ACTION, flags & PM_REMOVE, (LPARAM)msg, TRUE ); + call_hooks( WH_GETMESSAGE, HC_ACTION, flags & PM_REMOVE, (LPARAM)msg ); return 1; } continue; @@ -2018,7 +2018,7 @@ static int peek_message( MSG *msg, HWND hwnd, UINT first, UINT last, UINT flags, thread_info->client_info.message_extra = 0; thread_info->client_info.msg_source = msg_source_unavailable; free( buffer ); - call_hooks( WH_GETMESSAGE, HC_ACTION, flags & PM_REMOVE, (LPARAM)msg, TRUE ); + call_hooks( WH_GETMESSAGE, HC_ACTION, flags & PM_REMOVE, (LPARAM)msg ); return 1; }
diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index a243afd668c..dcf8c901756 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -251,7 +251,7 @@ extern LRESULT handle_nc_hit_test( HWND hwnd, POINT pt ) DECLSPEC_HIDDEN;
/* hook.c */ extern LRESULT call_current_hook( HHOOK hhook, INT code, WPARAM wparam, LPARAM lparam ) DECLSPEC_HIDDEN; -extern LRESULT call_hooks( INT id, INT code, WPARAM wparam, LPARAM lparam, BOOL unicode ) DECLSPEC_HIDDEN; +extern LRESULT call_hooks( INT id, INT code, WPARAM wparam, LPARAM lparam ) DECLSPEC_HIDDEN; extern BOOL is_hooked( INT id ) DECLSPEC_HIDDEN; extern BOOL unhook_windows_hook( INT id, HOOKPROC proc ) DECLSPEC_HIDDEN;
diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index 0eac0a6320b..b4a0256e1de 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -4040,7 +4040,7 @@ static UINT window_min_maximize( HWND hwnd, UINT cmd, RECT *rect ) wpl.length = sizeof(wpl); NtUserGetWindowPlacement( hwnd, &wpl );
- if (call_hooks( WH_CBT, HCBT_MINMAX, (WPARAM)hwnd, cmd, TRUE )) + if (call_hooks( WH_CBT, HCBT_MINMAX, (WPARAM)hwnd, cmd )) return SWP_NOSIZE | SWP_NOMOVE;
if (is_iconic( hwnd )) @@ -4752,7 +4752,7 @@ BOOL WINAPI NtUserDestroyWindow( HWND hwnd )
TRACE( "(%p)\n", hwnd );
- if (call_hooks( WH_CBT, HCBT_DESTROYWND, (WPARAM)hwnd, 0, TRUE )) return FALSE; + if (call_hooks( WH_CBT, HCBT_DESTROYWND, (WPARAM)hwnd, 0 )) return FALSE;
if (is_menu_active() == hwnd) NtUserEndMenu();
@@ -4765,7 +4765,7 @@ BOOL WINAPI NtUserDestroyWindow( HWND hwnd ) } else if (!get_window_relative( hwnd, GW_OWNER )) { - call_hooks( WH_SHELL, HSHELL_WINDOWDESTROYED, (WPARAM)hwnd, 0L, TRUE ); + call_hooks( WH_SHELL, HSHELL_WINDOWDESTROYED, (WPARAM)hwnd, 0 ); /* FIXME: clean up palette - see "Internals" p.352 */ }
@@ -5154,7 +5154,7 @@ HWND WINAPI NtUserCreateWindowEx( DWORD ex_style, UNICODE_STRING *class_name, release_win_ptr( win ); cbtc.hwndInsertAfter = HWND_TOP; cbtc.lpcs = &cs; - if (call_hooks( WH_CBT, HCBT_CREATEWND, (WPARAM)hwnd, (LPARAM)&cbtc, TRUE )) + if (call_hooks( WH_CBT, HCBT_CREATEWND, (WPARAM)hwnd, (LPARAM)&cbtc )) { free_window_handle( hwnd ); return 0; @@ -5334,7 +5334,7 @@ HWND WINAPI NtUserCreateWindowEx( DWORD ex_style, UNICODE_STRING *class_name, /* Call WH_SHELL hook */
if (!(get_window_long( hwnd, GWL_STYLE ) & WS_CHILD) && !get_window_relative( hwnd, GW_OWNER )) - call_hooks( WH_SHELL, HSHELL_WINDOWCREATED, (WPARAM)hwnd, 0, TRUE ); + call_hooks( WH_SHELL, HSHELL_WINDOWCREATED, (WPARAM)hwnd, 0 );
TRACE( "created window %p\n", hwnd ); SetThreadDpiAwarenessContext( context );
From: Jacek Caban jacek@codeweavers.com
--- dlls/user32/winproc.c | 16 ++++++++--- dlls/win32u/message.c | 1 + dlls/wow64win/user.c | 66 +++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 77 insertions(+), 6 deletions(-)
diff --git a/dlls/user32/winproc.c b/dlls/user32/winproc.c index ab28eecb67c..a22262b037b 100644 --- a/dlls/user32/winproc.c +++ b/dlls/user32/winproc.c @@ -1176,12 +1176,13 @@ static BOOL unpack_message( HWND hwnd, UINT message, WPARAM *wparam, LPARAM *lpa
BOOL WINAPI User32CallWindowProc( struct win_proc_params *params, ULONG size ) { + LRESULT result, *result_ptr = params->result; + params->result = &result;
if (params->needs_unpack) { char stack_buffer[128]; void *buffer; - LRESULT result;
if (size > sizeof(*params)) { @@ -1196,8 +1197,6 @@ BOOL WINAPI User32CallWindowProc( struct win_proc_params *params, ULONG size ) if (!unpack_message( params->hwnd, params->msg, ¶ms->wparam, ¶ms->lparam, &buffer, size )) return 0; - params->result = &result; -
dispatch_win_proc_params( params );
@@ -1206,7 +1205,16 @@ BOOL WINAPI User32CallWindowProc( struct win_proc_params *params, ULONG size ) if (buffer != stack_buffer && buffer != params + 1) HeapFree( GetProcessHeap(), 0, buffer ); } - else dispatch_win_proc_params( params ); + else + { + dispatch_win_proc_params( params ); + if (result_ptr) + { + *result_ptr = result; + return TRUE; + } + NtCallbackReturn( &result, sizeof(result), TRUE ); + } return TRUE; }
diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index 55b67a08d8f..7fde0867462 100644 --- a/dlls/win32u/message.c +++ b/dlls/win32u/message.c @@ -265,6 +265,7 @@ static BOOL dispatch_win_proc_params( struct win_proc_params *params, size_t siz thread_info->recursion_count++;
KeUserModeCallback( NtUserCallWinProc, params, size, &ret_ptr, &ret_len ); + if (ret_len == sizeof(*params->result)) *params->result = *(LRESULT *)ret_ptr;
thread_info->recursion_count--; return TRUE; diff --git a/dlls/wow64win/user.c b/dlls/wow64win/user.c index 6aecdacda39..8e0ab7bc68d 100644 --- a/dlls/wow64win/user.c +++ b/dlls/wow64win/user.c @@ -152,6 +152,23 @@ struct client_menu_name32 ULONG nameUS; };
+struct win_proc_params32 +{ + ULONG func; + ULONG hwnd; + UINT msg; + ULONG wparam; + ULONG lparam; + ULONG result; + BOOL ansi; + BOOL ansi_dst; + BOOL needs_unpack; + enum wm_char_mapping mapping; + ULONG dpi_awareness; + ULONG procA; + ULONG procW; +}; + static MSG *msg_32to64( MSG *msg, const MSG32 *msg32 ) { if (!msg32) return NULL; @@ -200,6 +217,25 @@ static struct client_menu_name32 *client_menu_name_64to32( const struct client_m return name32; }
+static void win_proc_params_64to32( const struct win_proc_params *src, struct win_proc_params32 *dst, + ULONG *result ) +{ + + dst->func = PtrToUlong( src->func ); + dst->hwnd = HandleToUlong( src->hwnd ); + dst->msg = src->msg; + dst->wparam = src->wparam; + dst->lparam = src->lparam; + dst->result = PtrToUlong( result ); + dst->ansi = src->ansi; + dst->ansi_dst = src->ansi_dst; + dst->needs_unpack = src->needs_unpack; + dst->mapping = src->mapping; + dst->dpi_awareness = HandleToUlong( src->dpi_awareness ); + dst->procA = PtrToUlong( src->procA ); + dst->procW = PtrToUlong( src->procW ); +} + static NTSTATUS dispatch_callback( ULONG id, void *args, ULONG len ) { void *ret_ptr; @@ -256,8 +292,34 @@ static NTSTATUS WINAPI wow64_NtUserCallWinEventHook( void *arg, ULONG size )
static NTSTATUS WINAPI wow64_NtUserCallWinProc( void *arg, ULONG size ) { - FIXME( "\n" ); - return 0; + struct win_proc_params *params = arg; + struct win_proc_params32 params32_buf, *params32 = ¶ms32_buf; + LONG result32 = 0; + LRESULT result; + void *ret_ptr; + ULONG ret_len; + NTSTATUS status; + + if (size > sizeof(*params)) + { + if (!(params32 = Wow64AllocateTemp( size - sizeof(*params) + sizeof(*params32) ))) + return 0; + memcpy( params32 + 1, params + 1, size - sizeof(*params) ); + } + win_proc_params_64to32( params, params32, NULL ); + + status = Wow64KiUserCallbackDispatcher( NtUserCallWinProc, params32, + size - sizeof(*params) + sizeof(*params32), + &ret_ptr, &ret_len ); + if (ret_len == sizeof(result32)) result32 = *(LONG *)ret_ptr; + result = result32; + + if (params->result) + { + *params->result = result; + return status; + } + return NtCallbackReturn( &result, sizeof(result), status ); }
static NTSTATUS WINAPI wow64_NtUserCallWindowsHook( void *arg, ULONG size )
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=121219
Your paranoid android.
=== debian11 (32 bit report) ===
user32: win.c:413: Test failed: Set GWL_HWNDPARENT succeeded on desktop
=== debian11 (32 bit Chinese:China report) ===
user32: win.c:413: Test failed: Set GWL_HWNDPARENT succeeded on desktop
=== debian11 (32 bit WoW report) ===
user32: win.c:413: Test failed: Set GWL_HWNDPARENT succeeded on desktop
=== debian11 (64 bit WoW report) ===
user32: win.c:413: Test failed: Set GWL_HWNDPARENT succeeded on desktop
From: Jacek Caban jacek@codeweavers.com
--- dlls/wow64win/user.c | 427 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 423 insertions(+), 4 deletions(-)
diff --git a/dlls/wow64win/user.c b/dlls/wow64win/user.c index 8e0ab7bc68d..8d5385c9086 100644 --- a/dlls/wow64win/user.c +++ b/dlls/wow64win/user.c @@ -129,6 +129,65 @@ typedef struct BYTE rgbReserved[32]; } PAINTSTRUCT32;
+typedef struct +{ + ULONG lpCreateParams; + ULONG hInstance; + ULONG hMenu; + ULONG hwndParent; + INT cy; + INT cx; + INT y; + INT x; + LONG style; + ULONG lpszName; + ULONG lpszClass; + DWORD dwExStyle; +} CREATESTRUCT32; + +typedef struct +{ + ULONG hwnd; + ULONG hwndInsertAfter; + INT x; + INT y; + INT cx; + INT cy; + UINT flags; +} WINDOWPOS32; + +typedef struct +{ + UINT CtlType; + UINT CtlID; + UINT itemID; + UINT itemWidth; + UINT itemHeight; + ULONG itemData; +} MEASUREITEMSTRUCT32; + +typedef struct +{ + UINT CtlType; + UINT CtlID; + UINT itemID; + UINT itemAction; + UINT itemState; + ULONG hwndItem; + ULONG hDC; + RECT rcItem; + ULONG itemData; +} DRAWITEMSTRUCT32; + +typedef struct +{ + UINT CtlType; + UINT CtlID; + UINT itemID; + ULONG hwndItem; + ULONG itemData; +} DELETEITEMSTRUCT32; + typedef struct { UINT cbSize; @@ -236,6 +295,70 @@ static void win_proc_params_64to32( const struct win_proc_params *src, struct wi dst->procW = PtrToUlong( src->procW ); }
+static void createstruct_32to64( const CREATESTRUCT32 *from, CREATESTRUCTW *to ) + +{ + to->lpCreateParams = UlongToPtr( from->lpCreateParams ); + to->hInstance = UlongToPtr( from->hInstance ); + to->hMenu = LongToHandle( from->hMenu ); + to->hwndParent = LongToHandle( from->hwndParent ); + to->cy = from->cy; + to->cx = from->cx; + to->y = from->y; + to->x = from->x; + to->style = from->style; + to->dwExStyle = from->dwExStyle; + to->lpszName = UlongToPtr( from->lpszName ); + to->lpszClass = UlongToPtr( from->lpszClass ); +} + +static void createstruct_64to32( const CREATESTRUCTW *from, CREATESTRUCT32 *to ) +{ + to->lpCreateParams = PtrToUlong( from->lpCreateParams ); + to->hInstance = PtrToUlong( from->hInstance ); + to->hMenu = HandleToUlong( from->hMenu ); + to->hwndParent = HandleToUlong( from->hwndParent ); + to->cy = from->cy; + to->cx = from->cx; + to->y = from->y; + to->x = from->x; + to->style = from->style; + to->dwExStyle = from->dwExStyle; +} + +static void winpos_32to64( WINDOWPOS *dst, const WINDOWPOS32 *src ) +{ + dst->hwnd = LongToHandle( src->hwnd ); + dst->hwndInsertAfter = LongToHandle( src->hwndInsertAfter ); + dst->x = src->x; + dst->y = src->y; + dst->cx = src->cx; + dst->cy = src->cy; + dst->flags = src->flags; +} + +static void winpos_64to32( const WINDOWPOS *src, WINDOWPOS32 *dst ) +{ + dst->hwnd = HandleToUlong( src->hwnd ); + dst->hwndInsertAfter = HandleToUlong( src->hwndInsertAfter ); + dst->x = src->x; + dst->y = src->y; + dst->cx = src->cx; + dst->cy = src->cy; + dst->flags = src->flags; +} + +static PAINTSTRUCT *paintstruct_32to64( PAINTSTRUCT *ps, const PAINTSTRUCT32 *ps32 ) +{ + if (!ps32) return NULL; + ps->hdc = ULongToHandle( ps32->hdc ); + ps->fErase = ps32->fErase; + ps->rcPaint = ps32->rcPaint; + ps->fRestore = ps32->fRestore; + ps->fIncUpdate = ps32->fIncUpdate; + return ps; +} + static NTSTATUS dispatch_callback( ULONG id, void *args, ULONG len ) { void *ret_ptr; @@ -2164,18 +2287,314 @@ NTSTATUS WINAPI wow64_NtUserMenuItemFromPoint( UINT *args ) return NtUserMenuItemFromPoint( hwnd, handle, x, y ); }
+static LRESULT message_call_32to64( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, + void *result_info, DWORD type, BOOL ansi ) +{ + LRESULT ret = 0; + + switch (msg) + { + case WM_NCCREATE: + case WM_CREATE: + { + CREATESTRUCT32 *cs32 = (void *)lparam; + CREATESTRUCTW cs; + + createstruct_32to64( cs32, &cs ); + ret = NtUserMessageCall( hwnd, msg, wparam, (LPARAM)&cs, result_info, type, ansi ); + createstruct_64to32( &cs, cs32 ); + return ret; + } + + case WM_MDICREATE: + { + struct + { + ULONG szClass; + ULONG szTitle; + ULONG hOwner; + INT x; + INT y; + INT cx; + INT cy; + DWORD style; + ULONG lParam; + } *cs32 = (void *)lparam; + MDICREATESTRUCTW cs; + + cs.szClass = UlongToPtr( cs32->szClass ); + cs.szTitle = UlongToPtr( cs32->szTitle ); + cs.hOwner = LongToHandle( cs32->hOwner ); + cs.x = cs32->x; + cs.y = cs32->y; + cs.cx = cs32->cx; + cs.cy = cs32->cy; + cs.style = cs32->style; + cs.lParam = cs32->lParam; + + return NtUserMessageCall( hwnd, msg, wparam, (LPARAM)&cs, result_info, type, ansi ); + } + + case WM_WINDOWPOSCHANGING: + case WM_WINDOWPOSCHANGED: + { + WINDOWPOS32 *winpos32 = (void *)lparam; + WINDOWPOS winpos; + + winpos_32to64( &winpos, winpos32 ); + ret = NtUserMessageCall( hwnd, msg, wparam, (LPARAM)&winpos, result_info, type, ansi ); + winpos_64to32( &winpos, winpos32 ); + return ret; + } + + case WM_NCCALCSIZE: + if (wparam) + { + struct + { + RECT rgrc[3]; + ULONG lppos; + } *params32 = (void *)lparam; + NCCALCSIZE_PARAMS params; + WINDOWPOS winpos; + + params.rgrc[0] = params32->rgrc[0]; + params.rgrc[1] = params32->rgrc[1]; + params.rgrc[2] = params32->rgrc[2]; + params.lppos = &winpos; + winpos_32to64( &winpos, UlongToPtr( params32->lppos )); + ret = NtUserMessageCall( hwnd, msg, wparam, (LPARAM)¶ms, result_info, type, ansi ); + params32->rgrc[0] = params.rgrc[0]; + params32->rgrc[1] = params.rgrc[1]; + params32->rgrc[2] = params.rgrc[2]; + winpos_64to32( &winpos, UlongToPtr( params32->lppos )); + return ret; + } + return NtUserMessageCall( hwnd, msg, wparam, lparam, result_info, type, ansi ); + + case WM_COMPAREITEM: + { + struct + { + UINT CtlType; + UINT CtlID; + ULONG hwndItem; + UINT itemID1; + ULONG itemData1; + UINT itemID2; + ULONG itemData2; + DWORD dwLocaleId; + } *cis32 = (void *)lparam; + COMPAREITEMSTRUCT cis; + + cis.CtlType = cis32->CtlType; + cis.CtlID = cis32->CtlID; + cis.hwndItem = LongToHandle( cis32->hwndItem ); + cis.itemID1 = cis32->itemID1; + cis.itemData1 = cis32->itemData1; + cis.itemID2 = cis32->itemID2; + cis.itemData2 = cis32->itemData2; + cis.dwLocaleId = cis32->dwLocaleId; + return NtUserMessageCall( hwnd, msg, wparam, (LPARAM)&cis, result_info, type, ansi ); + } + + case WM_DELETEITEM: + { + DELETEITEMSTRUCT32 *dis32 = (void *)lparam; + DELETEITEMSTRUCT dis; + + dis.CtlType = dis32->CtlType; + dis.CtlID = dis32->CtlID; + dis.hwndItem = LongToHandle( dis32->hwndItem ); + dis.itemData = dis32->itemData; + return NtUserMessageCall( hwnd, msg, wparam, (LPARAM)&dis, result_info, type, ansi ); + } + + case WM_MEASUREITEM: + { + MEASUREITEMSTRUCT32 *mis32 = (void *)lparam; + MEASUREITEMSTRUCT mis; + + mis.CtlType = mis32->CtlType; + mis.CtlID = mis32->CtlID; + mis.itemID = mis32->itemID; + mis.itemWidth = mis32->itemWidth; + mis.itemHeight = mis32->itemHeight; + mis.itemData = mis32->itemData; + ret = NtUserMessageCall( hwnd, msg, wparam, (LPARAM)&mis, result_info, type, ansi ); + mis32->itemWidth = mis.itemWidth; + mis32->itemHeight = mis.itemHeight; + return ret; + } + + case WM_DRAWITEM: + { + DRAWITEMSTRUCT32 *dis32 = (void *)lparam; + DRAWITEMSTRUCT dis; + + dis.CtlType = dis32->CtlType; + dis.CtlID = dis32->CtlID; + dis.itemID = dis32->itemID; + dis.itemAction = dis32->itemAction; + dis.itemState = dis32->itemState; + dis.hwndItem = LongToHandle( dis32->hwndItem ); + dis.hDC = LongToHandle( dis32->hDC ); + dis.itemData = dis32->itemData; + dis.rcItem.left = dis32->rcItem.left; + dis.rcItem.top = dis32->rcItem.top; + dis.rcItem.right = dis32->rcItem.right; + dis.rcItem.bottom = dis32->rcItem.bottom; + return NtUserMessageCall( hwnd, msg, wparam, (LPARAM)&dis, result_info, type, ansi ); + } + + case WM_COPYDATA: + { + struct + { + ULONG dwData; + DWORD cbData; + ULONG lpData; + } *cds32 = (void *)lparam; + COPYDATASTRUCT cds; + + cds.dwData = cds32->dwData; + cds.cbData = cds32->cbData; + cds.lpData = UlongToPtr( cds32->lpData ); + return NtUserMessageCall( hwnd, msg, wparam, (LPARAM)&cds, result_info, type, ansi ); + } + + case WM_GETDLGCODE: + if (lparam) + { + MSG32 *msg32 = (MSG32 *)lparam; + MSG msg64; + + return NtUserMessageCall( hwnd, msg, wparam, (LPARAM)msg_32to64( &msg64, msg32 ), + result_info, type, ansi ); + } + return NtUserMessageCall( hwnd, msg, wparam, lparam, result_info, type, ansi ); + + case WM_NEXTMENU: + { + struct + { + ULONG hmenuIn; + ULONG hmenuNext; + ULONG hwndNext; + } *next32 = (void *)lparam; + MDINEXTMENU next; + + next.hmenuIn = LongToHandle( next32->hmenuIn ); + next.hmenuNext = LongToHandle( next32->hmenuNext ); + next.hwndNext = LongToHandle( next32->hwndNext ); + return NtUserMessageCall( hwnd, msg, wparam, (LPARAM)&next, result_info, type, ansi ); + } + + case WM_PAINTCLIPBOARD: + { + PAINTSTRUCT ps; + + paintstruct_32to64( &ps, (PAINTSTRUCT32 *)lparam ); + return NtUserMessageCall( hwnd, msg, wparam, (LPARAM)&ps, result_info, type, ansi ); + } + + default: + return NtUserMessageCall( hwnd, msg, wparam, lparam, result_info, type, ansi ); + } +} + NTSTATUS WINAPI wow64_NtUserMessageCall( UINT *args ) { HWND hwnd = get_handle( &args ); UINT msg = get_ulong( &args ); - UINT wparam = get_ulong( &args ); - UINT lparam = get_ulong( &args ); + LONG wparam = get_ulong( &args ); + LONG lparam = get_ulong( &args ); void *result_info = get_ptr( &args ); UINT type = get_ulong ( &args ); BOOL ansi = get_ulong( &args );
- FIXME( "%p %x %x %x %p %x %x\n", hwnd, msg, wparam, lparam, result_info, type, ansi ); - return 0; + switch (type) + { + case NtUserGetDispatchParams: + case NtUserCallWindowProc: + { + struct win_proc_params32 *params32 = result_info; + struct win_proc_params params; + ULONG *result32; + + result32 = UlongToPtr( params32->result ); + if (type == NtUserCallWindowProc) params.func = UlongToPtr( params32->func ); + + if (!NtUserMessageCall( hwnd, msg, wparam, lparam, ¶ms, type, ansi )) + return FALSE; + + win_proc_params_64to32( ¶ms, params32, result32 ); + return TRUE; + } + + case NtUserSendMessage: + { + struct win_proc_params32 *params32 = result_info; + + if (params32) + { + struct win_proc_params params; + NTSTATUS ret; + + params.hwnd = 0; + ret = message_call_32to64( hwnd, msg, wparam, lparam, ¶ms, type, ansi ); + if (params.hwnd) win_proc_params_64to32( ¶ms, params32, NULL ); + return ret; + } + + return message_call_32to64( hwnd, msg, wparam, lparam, result_info, type, ansi ); + } + + case NtUserSendMessageTimeout: + { + struct + { + UINT flags; + UINT timeout; + DWORD result; + } *params32 = result_info; + struct send_message_timeout_params params; + LRESULT ret; + + params.flags = params32->flags; + params.timeout = params32->timeout; + ret = message_call_32to64( hwnd, msg, wparam, lparam, ¶ms, type, ansi ); + params32->result = params.result; + return ret; + } + + case NtUserSendMessageCallback: + { + struct + { + ULONG callback; + ULONG data; + } *params32 = result_info; + struct send_message_callback_params params; + + params.callback = UlongToPtr( params32->callback ); + params.data = params32->data; + return message_call_32to64( hwnd, msg, wparam, lparam, ¶ms, type, ansi ); + } + + case NtUserSpyGetMsgName: + /* no argument conversion */ + return NtUserMessageCall( hwnd, msg, wparam, lparam, result_info, type, ansi ); + + case NtUserWinProcResult: + { + LONG result32 = PtrToLong( result_info ); + return message_call_32to64( hwnd, msg, wparam, lparam, + LongToPtr( result32 ), type, ansi ); + } + } + + return message_call_32to64( hwnd, msg, wparam, lparam, result_info, type, ansi ); }
NTSTATUS WINAPI wow64_NtUserMoveWindow( UINT *args )
From: Jacek Caban jacek@codeweavers.com
--- dlls/user32/message.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/dlls/user32/message.c b/dlls/user32/message.c index f6431e0c28a..7be93d94e39 100644 --- a/dlls/user32/message.c +++ b/dlls/user32/message.c @@ -588,7 +588,7 @@ LRESULT WINAPI SendMessageTimeoutA( HWND hwnd, UINT msg, WPARAM wparam, LPARAM l }
-static LRESULT dispatch_send_message( struct win_proc_params *params ) +static LRESULT dispatch_send_message( struct win_proc_params *params, WPARAM wparam, LPARAM lparam ) { struct ntuser_thread_info *thread_info = NtUserGetThreadInfo(); INPUT_MESSAGE_SOURCE prev_source = thread_info->msg_source; @@ -596,6 +596,10 @@ static LRESULT dispatch_send_message( struct win_proc_params *params )
static const INPUT_MESSAGE_SOURCE msg_source_unavailable = { IMDT_UNAVAILABLE, IMO_UNAVAILABLE };
+ /* params may contain arguments modified by wow, use original parameters instead */ + params->wparam = wparam; + params->lparam = lparam; + thread_info->recursion_count++;
params->result = &retval; @@ -621,7 +625,7 @@ LRESULT WINAPI SendMessageW( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam )
params.hwnd = 0; retval = NtUserMessageCall( hwnd, msg, wparam, lparam, ¶ms, NtUserSendMessage, FALSE ); - if (params.hwnd) retval = dispatch_send_message( ¶ms ); + if (params.hwnd) retval = dispatch_send_message( ¶ms, wparam, lparam ); return retval; }
@@ -643,7 +647,7 @@ LRESULT WINAPI SendMessageA( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam )
params.hwnd = 0; retval = NtUserMessageCall( hwnd, msg, wparam, lparam, ¶ms, NtUserSendMessage, TRUE ); - if (params.hwnd) retval = dispatch_send_message( ¶ms ); + if (params.hwnd) retval = dispatch_send_message( ¶ms, wparam, lparam ); return retval; }
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=121221
Your paranoid android.
=== debian11 (32 bit report) ===
user32: win.c:413: Test failed: Set GWL_HWNDPARENT succeeded on desktop
=== debian11 (32 bit Chinese:China report) ===
user32: win.c:413: Test failed: Set GWL_HWNDPARENT succeeded on desktop
=== debian11 (32 bit WoW report) ===
user32: win.c:413: Test failed: Set GWL_HWNDPARENT succeeded on desktop
=== debian11 (64 bit WoW report) ===
user32: win.c:413: Test failed: Set GWL_HWNDPARENT succeeded on desktop