From: Jacek Caban jacek@codeweavers.com
--- dlls/user32/winproc.c | 30 ++++----------- dlls/win32u/hook.c | 8 ++-- dlls/win32u/message.c | 74 +++++++++++++++++++++++++++--------- dlls/win32u/tests/win32u.c | 29 +++++++++++--- dlls/win32u/win32u_private.h | 6 +-- dlls/wow64win/user.c | 48 +++++++++++++++++++---- 6 files changed, 136 insertions(+), 59 deletions(-)
diff --git a/dlls/user32/winproc.c b/dlls/user32/winproc.c index d79f37b80b8..1f9b42d0c06 100644 --- a/dlls/user32/winproc.c +++ b/dlls/user32/winproc.c @@ -824,6 +824,13 @@ BOOL unpack_message( HWND hwnd, UINT message, WPARAM *wparam, LPARAM *lparam, } break; } + case WM_NCCALCSIZE: + if (*wparam) + { + NCCALCSIZE_PARAMS *ncp = *buffer; + ncp->lppos = (WINDOWPOS *)((NCCALCSIZE_PARAMS *)ncp + 1); + } + break; case WM_GETTEXT: case WM_ASKCBFORMATNAME: if (!get_buffer_space( buffer, (*wparam * sizeof(WCHAR)), size )) return FALSE; @@ -952,28 +959,6 @@ BOOL unpack_message( HWND hwnd, UINT message, WPARAM *wparam, LPARAM *lparam, case WM_STYLECHANGED: minsize = sizeof(STYLESTRUCT); break; - case WM_NCCALCSIZE: - if (!*wparam) minsize = sizeof(RECT); - else - { - NCCALCSIZE_PARAMS ncp; - WINDOWPOS wp; - if (size < sizeof(ps->ncp)) return FALSE; - ncp.rgrc[0] = ps->ncp.rgrc[0]; - ncp.rgrc[1] = ps->ncp.rgrc[1]; - ncp.rgrc[2] = ps->ncp.rgrc[2]; - wp.hwnd = unpack_handle( ps->ncp.hwnd ); - wp.hwndInsertAfter = unpack_handle( ps->ncp.hwndInsertAfter ); - wp.x = ps->ncp.x; - wp.y = ps->ncp.y; - wp.cx = ps->ncp.cx; - wp.cy = ps->ncp.cy; - wp.flags = ps->ncp.flags; - ncp.lppos = (WINDOWPOS *)((NCCALCSIZE_PARAMS *)&ps->ncp + 1); - memcpy( &ps->ncp, &ncp, sizeof(ncp) ); - *ncp.lppos = wp; - } - break; case WM_GETDLGCODE: if (*lparam) { @@ -1197,6 +1182,7 @@ BOOL WINAPI User32CallWindowProc( struct win_proc_params *params, ULONG size ) { case WM_NCCREATE: case WM_CREATE: + case WM_NCCALCSIZE: { LRESULT *result_ptr = (LRESULT *)buffer - 1; *result_ptr = result; diff --git a/dlls/win32u/hook.c b/dlls/win32u/hook.c index e3c3a0ce5ba..c53ec57c32b 100644 --- a/dlls/win32u/hook.c +++ b/dlls/win32u/hook.c @@ -246,7 +246,7 @@ static LRESULT call_hook( struct win_hook_params *info, const WCHAR *module, siz if (params->id == WH_CBT && params->code == HCBT_CREATEWND) { CBT_CREATEWNDW *cbtc = (CBT_CREATEWNDW *)params->lparam; - message_size = user_message_size( WM_NCCREATE, (LPARAM)cbtc->lpcs, FALSE ); + message_size = user_message_size( WM_NCCREATE, 0, (LPARAM)cbtc->lpcs, FALSE ); lparam_size = lparam_ret_size = 0; }
@@ -285,21 +285,21 @@ static LRESULT call_hook( struct win_hook_params *info, const WCHAR *module, siz CBT_CREATEWNDW *cbtc = (CBT_CREATEWNDW *)params->lparam; LPARAM lp = (LPARAM)cbtc->lpcs; pack_user_message( (char *)params + message_offset, message_size, - WM_CREATE, lp, FALSE ); + WM_CREATE, 0, lp, FALSE ); } break; case WH_CALLWNDPROC: { CWPSTRUCT *cwp = (CWPSTRUCT *)((char *)params + lparam_offset); pack_user_message( (char *)params + message_offset, message_size, - cwp->message, cwp->lParam, ansi ); + cwp->message, cwp->wParam, cwp->lParam, ansi ); } break; case WH_CALLWNDPROCRET: { CWPRETSTRUCT *cwpret = (CWPRETSTRUCT *)((char *)params + lparam_offset); pack_user_message( (char *)params + message_offset, message_size, - cwpret->message, cwpret->lParam, ansi ); + cwpret->message, cwpret->wParam, cwpret->lParam, ansi ); } break; } diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index 5aec4c5eb95..58294f4d385 100644 --- a/dlls/win32u/message.c +++ b/dlls/win32u/message.c @@ -387,6 +387,28 @@ static BOOL unpack_message( HWND hwnd, UINT message, WPARAM *wparam, LPARAM *lpa memcpy( *buffer, &cs, sizeof(cs) ); break; } + case WM_NCCALCSIZE: + if (!*wparam) minsize = sizeof(RECT); + else + { + NCCALCSIZE_PARAMS ncp; + WINDOWPOS wp; + if (size < sizeof(ps->ncp)) return FALSE; + ncp.rgrc[0] = ps->ncp.rgrc[0]; + ncp.rgrc[1] = ps->ncp.rgrc[1]; + ncp.rgrc[2] = ps->ncp.rgrc[2]; + wp.hwnd = wine_server_ptr_handle( ps->ncp.hwnd ); + wp.hwndInsertAfter = wine_server_ptr_handle( ps->ncp.hwndInsertAfter ); + wp.x = ps->ncp.x; + wp.y = ps->ncp.y; + wp.cx = ps->ncp.cx; + wp.cy = ps->ncp.cy; + wp.flags = ps->ncp.flags; + ncp.lppos = (WINDOWPOS *)((NCCALCSIZE_PARAMS *)&ps->ncp + 1); + memcpy( &ps->ncp, &ncp, sizeof(ncp) ); + *ncp.lppos = wp; + } + break; case WM_WINE_SETWINDOWPOS: { WINDOWPOS wp; @@ -1134,7 +1156,7 @@ static size_t copy_string( void *ptr, const void *str, BOOL ansi ) * * Calculate size of packed message buffer. */ -size_t user_message_size( UINT message, LPARAM lparam, BOOL ansi ) +size_t user_message_size( UINT message, WPARAM wparam, LPARAM lparam, BOOL ansi ) { const void *lparam_ptr = (const void *)lparam; size_t size = 0; @@ -1150,6 +1172,9 @@ size_t user_message_size( UINT message, LPARAM lparam, BOOL ansi ) if (!IS_INTRESOURCE(cs->lpszClass)) size += string_size( cs->lpszClass, ansi ); break; } + case WM_NCCALCSIZE: + size = wparam ? sizeof(NCCALCSIZE_PARAMS) + sizeof(WINDOWPOS) : sizeof(RECT); + break; }
return size; @@ -1160,7 +1185,8 @@ size_t user_message_size( UINT message, LPARAM lparam, BOOL ansi ) * * Copy message to a buffer for passing to client. */ -void pack_user_message( void *buffer, size_t size, UINT message, LPARAM lparam, BOOL ansi ) +void pack_user_message( void *buffer, size_t size, UINT message, + WPARAM wparam, LPARAM lparam, BOOL ansi ) { const void *lparam_ptr = (const void *)lparam; void const *inline_ptr = (void *)0xffffffff; @@ -1188,8 +1214,17 @@ void pack_user_message( void *buffer, size_t size, UINT message, LPARAM lparam, } return; } + case WM_NCCALCSIZE: + if (wparam) + { + const NCCALCSIZE_PARAMS *ncp = lparam_ptr; + memcpy( (char *)buffer + sizeof(*ncp), ncp->lppos, sizeof(*ncp->lppos) ); + size = sizeof(*ncp); + } + break; }
+ if (size) memcpy( buffer, lparam_ptr, size ); }
/*********************************************************************** @@ -1200,6 +1235,7 @@ void pack_user_message( void *buffer, size_t size, UINT message, LPARAM lparam, static void copy_user_result( void *buffer, size_t size, UINT message, WPARAM wparam, LPARAM lparam ) { void *lparam_ptr = (void *)lparam; + size_t copy_size = 0;
if (!size) return;
@@ -1224,9 +1260,26 @@ static void copy_user_result( void *buffer, size_t size, UINT message, WPARAM wp /* don't allow changing name and class pointers */ } return; + case WM_NCCALCSIZE: + if (wparam) + { + NCCALCSIZE_PARAMS *dst = lparam_ptr; + const NCCALCSIZE_PARAMS *src = buffer; + const WINDOWPOS *winpos = (const WINDOWPOS *)(src + 1); + dst->rgrc[0] = src->rgrc[0]; + dst->rgrc[1] = src->rgrc[1]; + dst->rgrc[2] = src->rgrc[2]; + *dst->lppos = *winpos; + return; + } + copy_size = sizeof(RECT); + break; default: return; } + + if (copy_size > size) copy_size = size; + if (copy_size) memcpy( lparam_ptr, buffer, copy_size ); }
/*********************************************************************** @@ -1290,19 +1343,6 @@ static void copy_reply( LRESULT result, HWND hwnd, UINT message, WPARAM wparam, 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: @@ -1522,7 +1562,7 @@ static LRESULT call_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpar if (!needs_unpack) size = 0; if (!is_current_thread_window( hwnd )) return 0;
- packed_size = user_message_size( msg, lparam, ansi ); + packed_size = user_message_size( msg, wparam, lparam, ansi ); if (packed_size) size = packed_size;
/* first the WH_CALLWNDPROC hook */ @@ -1543,7 +1583,7 @@ static LRESULT call_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpar if (needs_unpack) params->ansi = FALSE; params->needs_unpack = needs_unpack || packed_size; if (packed_size) - pack_user_message( params + 1, packed_size, msg, lparam, ansi ); + pack_user_message( params + 1, packed_size, msg, wparam, lparam, ansi ); else if (size) memcpy( params + 1, buffer, size );
diff --git a/dlls/win32u/tests/win32u.c b/dlls/win32u/tests/win32u.c index fc1b610063b..7ce6e990874 100644 --- a/dlls/win32u/tests/win32u.c +++ b/dlls/win32u/tests/win32u.c @@ -1364,6 +1364,7 @@ struct lparam_hook_test size_t lparam_size; size_t check_size; BOOL poison_lparam; + BOOL todo; };
static const struct lparam_hook_test *current_hook_test; @@ -1535,7 +1536,7 @@ static void test_msg_output( const struct lparam_hook_test *test, LRESULT result todo_wine_if( test->message == WM_GETTEXT && !test->msg_result ) ok( !memcmp( lparam_buffer, expected, test->lparam_size ), "unexpected lparam content\n" );
- todo_wine + todo_wine_if(test->todo) ok( wndproc_lparam != orig, "wndproc_lparam unmodified\n" ); if (!hooks_called) return; @@ -1545,13 +1546,13 @@ static void test_msg_output( const struct lparam_hook_test *test, LRESULT result ok( retwnd_hook_lparam, "retwnd_hook_lparam not called\n" ); ok( retwnd_hook_lparam2, "retwnd_hook_lparam2 not called\n" );
- todo_wine + todo_wine_if(test->todo) ok( orig != callwnd_hook_lparam, "callwnd_hook_lparam not modified\n" ); - todo_wine + todo_wine_if(test->todo) ok( orig != callwnd_hook_lparam2, "callwnd_hook_lparam2 not modified\n" ); - todo_wine + todo_wine_if(test->todo) ok( orig != retwnd_hook_lparam, "retwnd_hook_lparam not modified\n" ); - todo_wine + todo_wine_if(test->todo) ok( orig != retwnd_hook_lparam2, "retwnd_hook_lparam2 not modified\n" );
/* @@ -1609,67 +1610,83 @@ static void test_wndproc_hook(void) "WM_MOVING", WM_MOVING, .lparam = &rect_in, .lparam_size = sizeof(RECT), .check_size = sizeof(RECT), + .todo = TRUE }, { "LB_GETITEMRECT", LB_GETITEMRECT, .lparam = &rect_in, .lparam_size = sizeof(RECT), .change_lparam = &rect_out, .check_size = sizeof(RECT), + .todo = TRUE }, { "CB_GETDROPPEDCONTROLRECT", CB_GETDROPPEDCONTROLRECT, - .lparam = &rect_in, .lparam_size = sizeof(RECT), .change_lparam = &rect_out + .lparam = &rect_in, .lparam_size = sizeof(RECT), .change_lparam = &rect_out, + .todo = TRUE }, { "WM_GETTEXT", WM_GETTEXT, .wparam = 8, .lparam_size = sizeof(strbufW), .change_lparam = strbufW, .check_lparam = strbuf2W, + .todo = TRUE }, { "WM_GETTEXT2", WM_GETTEXT, .wparam = 8, .msg_result = 1, .lparam_size = sizeof(strbufW), .change_lparam = strbufW, .check_lparam = strbufW, + .todo = TRUE }, { "WM_GETTEXT3", WM_GETTEXT, .wparam = 8, .msg_result = 9, .lparam_size = sizeof(strbufW), .change_lparam = strbufW, .check_lparam = strbufW, + .todo = TRUE }, { "WM_ASKCBFORMATNAME", WM_ASKCBFORMATNAME, .wparam = 8, .lparam_size = sizeof(strbufW), .change_lparam = strbufW, .check_lparam = strbufW, + .todo = TRUE }, { "WM_ASKCBFORMATNAME2", WM_ASKCBFORMATNAME, .wparam = 8, .msg_result = 1, .lparam_size = sizeof(strbufW), .change_lparam = strbufW, .check_lparam = strbufW, + .todo = TRUE }, { "WM_ASKCBFORMATNAME3", WM_ASKCBFORMATNAME, .wparam = 8, .msg_result = 9, .lparam_size = sizeof(strbufW), .change_lparam = strbufW, .check_lparam = strbufW, + .todo = TRUE }, { "CB_GETLBTEXT", CB_GETLBTEXT, .msg_result = 7, .check_result = 4, .todo_result = TRUE, .lparam_size = sizeof(strbufW), .change_lparam = strbufW, .check_lparam = strbufW, + .todo = TRUE }, { "CB_GETLBTEXT2", CB_GETLBTEXT, .msg_result = 9, .check_result = 8, .todo_result = TRUE, .lparam_size = sizeof(strbufW), .change_lparam = strbuf3W, .check_lparam = strbuf3W, + .todo = TRUE }, { "CB_GETLBTEXT3", CB_GETLBTEXT, .lparam_size = sizeof(strbufW), .change_lparam = strbuf3W, .check_lparam = strbuf3W, + .todo = TRUE }, { "LB_GETTEXT", LB_GETTEXT, .msg_result = 7, .check_result = 4, .todo_result = TRUE, .lparam_size = sizeof(strbufW), .change_lparam = strbufW, .check_lparam = strbufW, + .todo = TRUE }, { "LB_GETTEXT2", LB_GETTEXT, .msg_result = 9, .check_result = 8, .todo_result = TRUE, .lparam_size = sizeof(strbufW), .change_lparam = strbuf3W, .check_lparam = strbuf3W, + .todo = TRUE }, { "LB_GETTEXT3", LB_GETTEXT, .lparam_size = sizeof(strbufW), .change_lparam = strbuf3W, .check_lparam = strbuf3W, + .todo = TRUE }, { "WM_MDIGETACTIVE", WM_MDIGETACTIVE, .lparam_size = sizeof(BOOL), .change_lparam = &false_lparam, + .todo = TRUE }, { "WM_USER", WM_USER }, { "WM_NOTIFY", WM_NOTIFY }, diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index b27ba7fab14..27a3d1a0305 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -140,9 +140,9 @@ extern LRESULT send_message( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) extern BOOL send_notify_message( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, BOOL ansi ) DECLSPEC_HIDDEN; extern LRESULT send_message_timeout( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, UINT flags, UINT timeout, BOOL ansi ) DECLSPEC_HIDDEN; -extern size_t user_message_size( UINT message, LPARAM lparam, BOOL ansi ) DECLSPEC_HIDDEN; -extern void pack_user_message( void *buffer, size_t size, UINT message, LPARAM lparam, - BOOL ansi ) DECLSPEC_HIDDEN; +extern size_t user_message_size( UINT message, WPARAM wparam, LPARAM lparam, BOOL ansi ) DECLSPEC_HIDDEN; +extern void pack_user_message( void *buffer, size_t size, UINT message, + WPARAM wparam, LPARAM lparam, BOOL ansi ) DECLSPEC_HIDDEN;
/* rawinput.c */ extern BOOL process_rawinput_message( MSG *msg, UINT hw_id, const struct hardware_msg_data *msg_data ) DECLSPEC_HIDDEN; diff --git a/dlls/wow64win/user.c b/dlls/wow64win/user.c index 7e77e5a2f73..7aea543ea6a 100644 --- a/dlls/wow64win/user.c +++ b/dlls/wow64win/user.c @@ -614,7 +614,8 @@ static NTSTATUS WINAPI wow64_NtUserCallWinEventHook( void *arg, ULONG size ) FIELD_OFFSET( struct win_event_hook_params32, module ) + size); }
-static size_t packed_message_64to32( UINT message, const void *params64, void *params32, size_t size ) +static size_t packed_message_64to32( UINT message, WPARAM wparam, + const void *params64, void *params32, size_t size ) { if (!size) return 0;
@@ -631,14 +632,33 @@ static size_t packed_message_64to32( UINT message, const void *params64, void *p if (size) memmove( cs32 + 1, cs64 + 1, size ); return sizeof(*cs32) + size; } + + case WM_NCCALCSIZE: + if (wparam) + { + NCCALCSIZE_PARAMS32 ncp32; + const NCCALCSIZE_PARAMS *ncp64 = params64; + + ncp32.rgrc[0] = ncp64->rgrc[0]; + ncp32.rgrc[1] = ncp64->rgrc[1]; + ncp32.rgrc[2] = ncp64->rgrc[2]; + winpos_64to32( (const WINDOWPOS *)(ncp64 + 1), + (WINDOWPOS32 *)((const char *)params32 + sizeof(ncp32)) ); + memcpy( params32, &ncp32, sizeof(ncp32) ); + return sizeof(ncp32) + sizeof(WINDOWPOS32); + } + break; }
memmove( params32, params64, size ); return size; }
-static size_t packed_result_32to64( UINT message, const void *params32, size_t size, void *params64 ) +static size_t packed_result_32to64( UINT message, WPARAM wparam, const void *params32, + size_t size, void *params64 ) { + if (!size) return 0; + switch (message) { case WM_NCCREATE: @@ -661,6 +681,20 @@ static size_t packed_result_32to64( UINT message, const void *params32, size_t s return sizeof(*cs64); }
+ case WM_NCCALCSIZE: + if (wparam) + { + const NCCALCSIZE_PARAMS32 *ncp32 = params32; + NCCALCSIZE_PARAMS *ncp64 = params64; + + ncp64->rgrc[0] = ncp32->rgrc[0]; + ncp64->rgrc[1] = ncp32->rgrc[1]; + ncp64->rgrc[2] = ncp32->rgrc[2]; + winpos_32to64( (WINDOWPOS *)(ncp64 + 1), (const WINDOWPOS32 *)(ncp32 + 1) ); + return sizeof(*ncp64) + sizeof(WINDOWPOS); + } + break; + default: return 0; } @@ -681,7 +715,7 @@ static NTSTATUS WINAPI wow64_NtUserCallWinProc( void *arg, ULONG size )
win_proc_params_64to32( params, params32 ); if (size > sizeof(*params)) - lparam_size = packed_message_64to32( params32->msg, params + 1, params32 + 1, + lparam_size = packed_message_64to32( params32->msg, params32->wparam, params + 1, params32 + 1, size - sizeof(*params) );
status = Wow64KiUserCallbackDispatcher( NtUserCallWinProc, params32, @@ -692,7 +726,7 @@ static NTSTATUS WINAPI wow64_NtUserCallWinProc( void *arg, ULONG size ) { LRESULT *result_ptr = arg; result = *(LONG *)ret_ptr; - ret_len = packed_result_32to64( params32->msg, (LONG *)ret_ptr + 1, + ret_len = packed_result_32to64( params32->msg, params32->wparam, (LONG *)ret_ptr + 1, ret_len - sizeof(LONG), result_ptr + 1 ); *result_ptr = result; return NtCallbackReturn( result_ptr, sizeof(*result_ptr) + ret_len, status ); @@ -717,7 +751,7 @@ static UINT hook_lparam_64to32( int id, int code, const void *lp, size_t size, v switch (code) { case HCBT_CREATEWND: - return packed_message_64to32( WM_CREATE, lp, lp32, size ); + return packed_message_64to32( WM_CREATE, 0, lp, lp32, size );
case HCBT_ACTIVATE: { @@ -748,7 +782,7 @@ static UINT hook_lparam_64to32( int id, int code, const void *lp, size_t size, v { const size_t offset64 = (sizeof(*cwp) + 15) & ~15; const size_t offset32 = (sizeof(cwp32) + 15) & ~15; - size = packed_message_64to32( cwp32.message, + size = packed_message_64to32( cwp32.message, cwp32.wParam, (const char *)lp + offset64, (char *)lp32 + offset32, size - offset64 ); return offset32 + size; @@ -770,7 +804,7 @@ static UINT hook_lparam_64to32( int id, int code, const void *lp, size_t size, v { const size_t offset64 = (sizeof(*cwpret) + 15) & ~15; const size_t offset32 = (sizeof(cwpret32) + 15) & ~15; - size = packed_message_64to32( cwpret32.message, + size = packed_message_64to32( cwpret32.message, cwpret32.wParam, (const char *)lp + offset64, (char *)lp32 + offset32, size - offset64 ); return offset32 + size;