Instead of leaking kernel pointers.
-- v2: user32: Always use original parameter values in dispatch_send_message. wow64win: Implement wow64_NtUserMessageCall. wow64win: Implement wow64_NtUserCallWinProc. win32u: Remove no longer needed unicode call_hooks argument. win32u: Use send_message_timeout for WM_CREATE and WM_NCCREATE. user32: Pass window name as UNICODE_STRING to NtUserCreateWindowEx. win32u: Pack messages sent directly from win32u.
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 | 216 +++++++++++++++++++++++++++++++++-- dlls/win32u/ntuser_private.h | 9 -- 2 files changed, 208 insertions(+), 17 deletions(-)
diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index f1ff3da2cd6..6af909b7ed5 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 ) { + struct send_message_info info; DWORD_PTR res = 0; - send_client_message( hwnd, msg, wparam, lparam, flags, timeout, &res, ansi ); + + 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; }
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 */
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 6af909b7ed5..a19b6bab230 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 a19b6bab230..bc932c5c820 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 )
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; }
The new version should fix test failures.