From: Jacek Caban jacek@codeweavers.com
--- dlls/user32/hook.c | 23 +++++------- dlls/user32/user_private.h | 2 ++ dlls/user32/winproc.c | 4 +-- dlls/win32u/hook.c | 70 ++++++++++++++++-------------------- dlls/win32u/message.c | 4 +-- dlls/win32u/win32u_private.h | 3 ++ dlls/wow64win/user.c | 9 +---- 7 files changed, 50 insertions(+), 65 deletions(-)
diff --git a/dlls/user32/hook.c b/dlls/user32/hook.c index e17f23fde5c..1465712adb2 100644 --- a/dlls/user32/hook.c +++ b/dlls/user32/hook.c @@ -471,23 +471,18 @@ BOOL WINAPI User32CallWindowsHook( struct win_hook_params *params, ULONG size ) ret_ptr = (char *)params + lparam_offset; params->lparam = (LPARAM)ret_ptr;
- if (params->id == WH_CBT && params->code == HCBT_CREATEWND) + switch (params->id) { - CREATESTRUCTW *cs = (CREATESTRUCTW *)params->lparam; - const WCHAR *ptr = (const WCHAR *)(cs + 1); - - if (!IS_INTRESOURCE(cs->lpszName)) + case WH_CBT: + if (params->code == HCBT_CREATEWND) { - cs->lpszName = ptr; - ptr += wcslen( ptr ) + 1; + cbtc.hwndInsertAfter = HWND_TOP; + unpack_message( (HWND)params->wparam, WM_CREATE, NULL, (LPARAM *)&cbtc.lpcs, + &ret_ptr, ret_size, FALSE ); + params->lparam = (LPARAM)&cbtc; + ret_size = sizeof(*cbtc.lpcs); } - if (!IS_INTRESOURCE(cs->lpszClass)) - cs->lpszClass = ptr; - - cbtc.hwndInsertAfter = HWND_TOP; - cbtc.lpcs = cs; - params->lparam = (LPARAM)&cbtc; - ret_size = sizeof(*cs); + break; } } if (params->module[0] && !(proc = get_hook_proc( proc, params->module, &free_module ))) diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h index 10f5d83b6f1..267c535defe 100644 --- a/dlls/user32/user_private.h +++ b/dlls/user32/user_private.h @@ -51,6 +51,8 @@ extern BOOL unpack_dde_message( HWND hwnd, UINT message, WPARAM *wparam, LPARAM const void *buffer, size_t size ) DECLSPEC_HIDDEN; extern void free_cached_data( UINT format, HANDLE handle ) DECLSPEC_HIDDEN; extern HANDLE render_synthesized_format( UINT format, UINT from ) DECLSPEC_HIDDEN; +extern BOOL unpack_message( HWND hwnd, UINT message, WPARAM *wparam, LPARAM *lparam, + void **buffer, size_t size, BOOL ansi );
extern void CLIPBOARD_ReleaseOwner( HWND hwnd ) DECLSPEC_HIDDEN; extern HDC get_display_dc(void) DECLSPEC_HIDDEN; diff --git a/dlls/user32/winproc.c b/dlls/user32/winproc.c index 8b5b65296f4..d79f37b80b8 100644 --- a/dlls/user32/winproc.c +++ b/dlls/user32/winproc.c @@ -799,8 +799,8 @@ static size_t string_size( const void *str, BOOL ansi ) * * Unpack a message received from another process. */ -static BOOL unpack_message( HWND hwnd, UINT message, WPARAM *wparam, LPARAM *lparam, - void **buffer, size_t size, BOOL ansi ) +BOOL unpack_message( HWND hwnd, UINT message, WPARAM *wparam, LPARAM *lparam, + void **buffer, size_t size, BOOL ansi ) { size_t minsize = 0, prev_size = size; union packed_structs *ps = *buffer; diff --git a/dlls/win32u/hook.c b/dlls/win32u/hook.c index 59c5df33f59..b880c8d37e0 100644 --- a/dlls/win32u/hook.c +++ b/dlls/win32u/hook.c @@ -230,12 +230,11 @@ static LRESULT call_hook( struct win_hook_params *info, const WCHAR *module, siz else if (info->proc) { struct user_thread_info *thread_info = get_user_thread_info(); + size_t size, lparam_offset = 0, message_offset = 0, message_size = 0; + size_t lparam_ret_size = lparam_size; HHOOK prev = thread_info->hook; BOOL prev_unicode = thread_info->hook_unicode; struct win_hook_params *params = info; - ULONG lparam_ret_size = lparam_size; - ULONG size = sizeof(*params); - CREATESTRUCTW *cs = NULL; void *ret_ptr; ULONG ret_len;
@@ -243,25 +242,29 @@ static LRESULT call_hook( struct win_hook_params *info, const WCHAR *module, siz
if (lparam_size) { - size = (size + 15) & ~15; /* align offset */ - lparam_ret_size = lparam_size; - if (params->id == WH_CBT && params->code == HCBT_CREATEWND) { - cs = ((CBT_CREATEWNDW *)params->lparam)->lpcs; - params->lparam = 0; - lparam_ret_size = 0; - lparam_size = sizeof(*cs); - if (!IS_INTRESOURCE( cs->lpszName )) - lparam_size += (wcslen( cs->lpszName ) + 1) * sizeof(WCHAR); - if (!IS_INTRESOURCE( cs->lpszClass )) - lparam_size += (wcslen( cs->lpszClass ) + 1) * sizeof(WCHAR); + CBT_CREATEWNDW *cbtc = (CBT_CREATEWNDW *)params->lparam; + message_size = user_message_size( WM_NCCREATE, (LPARAM)cbtc->lpcs, FALSE ); + lparam_size = lparam_ret_size = 0; + } + + if (lparam_size) + { + lparam_offset = (size + 15) & ~15; /* align offset */ + size = lparam_offset + lparam_size; + } + + if (message_size) + { + message_offset = (size + 15) & ~15; /* align offset */ + size = message_offset + message_size; } }
- if (size + lparam_size > sizeof(*info)) + if (size > sizeof(*info)) { - if (!(params = malloc( size + lparam_size ))) return 0; + if (!(params = malloc( size ))) return 0; memcpy( params, info, FIELD_OFFSET( struct win_hook_params, module )); } if (module) @@ -270,31 +273,20 @@ static LRESULT call_hook( struct win_hook_params *info, const WCHAR *module, siz params->module[0] = 0;
if (lparam_size) + memcpy( (char *)params + lparam_offset, (const void *)params->lparam, lparam_size ); + + if (message_size) { - void *lparam_ptr = (char *)params + size; - if (cs) + switch (params->id) { - CREATESTRUCTW *params_cs = lparam_ptr; - WCHAR *ptr = (WCHAR *)(params_cs + 1); - const void *inline_ptr = (void *)0xffffffff; - - *params_cs = *cs; - if (!IS_INTRESOURCE( cs->lpszName )) - { - UINT len = wcslen( cs->lpszName ) + 1; - memcpy( ptr, cs->lpszName, len * sizeof(WCHAR) ); - ptr += len; - params_cs->lpszName = inline_ptr; - } - if (!IS_INTRESOURCE( cs->lpszClass )) + case WH_CBT: { - wcscpy( ptr, cs->lpszClass ); - params_cs->lpszClass = inline_ptr; + 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 ); } - } - else - { - memcpy( lparam_ptr, (const void *)params->lparam, lparam_size ); + break; } }
@@ -316,9 +308,9 @@ static LRESULT call_hook( struct win_hook_params *info, const WCHAR *module, siz thread_info->hook = params->handle; thread_info->hook_unicode = params->next_unicode; thread_info->hook_call_depth++; - ret = KeUserModeCallback( NtUserCallWindowsHook, params, size + lparam_size, &ret_ptr, &ret_len ); + ret = KeUserModeCallback( NtUserCallWindowsHook, params, size, &ret_ptr, &ret_len ); if (ret_len && ret_len == lparam_ret_size) - memcpy( (void *)params->lparam, ret_ptr, lparam_ret_size ); + memcpy( (void *)params->lparam, ret_ptr, ret_len ); thread_info->hook = prev; thread_info->hook_unicode = prev_unicode; thread_info->hook_call_depth--; diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index 3cb9c4107c1..fe048e0ee38 100644 --- a/dlls/win32u/message.c +++ b/dlls/win32u/message.c @@ -1134,7 +1134,7 @@ static size_t copy_string( void *ptr, const void *str, BOOL ansi ) * * Calculate size of packed message buffer. */ -static size_t user_message_size( UINT message, LPARAM lparam, BOOL ansi ) +size_t user_message_size( UINT message, LPARAM lparam, BOOL ansi ) { const void *lparam_ptr = (const void *)lparam; size_t size = 0; @@ -1160,7 +1160,7 @@ static size_t user_message_size( UINT message, LPARAM lparam, BOOL ansi ) * * Copy message to a buffer for passing to client. */ -static 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, LPARAM lparam, BOOL ansi ) { const void *lparam_ptr = (const void *)lparam; void const *inline_ptr = (void *)0xffffffff; diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index 005ab53cc01..8d6fb34776d 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -138,6 +138,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;
/* 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 de221658a94..1fad0f566fd 100644 --- a/dlls/wow64win/user.c +++ b/dlls/wow64win/user.c @@ -717,14 +717,7 @@ static UINT hook_lparam_64to32( int id, int code, const void *lp, size_t size, v switch (code) { case HCBT_CREATEWND: - { - const CREATESTRUCTW *cs64 = lp; - CREATESTRUCT32 *cs32 = lp32; - createstruct_64to32( cs64, cs32 ); - size -= sizeof(*cs64); - if (size) memmove( cs32 + 1, cs64 + 1, size ); - return sizeof(*cs32) + size; - } + return packed_message_64to32( WM_CREATE, lp, lp32, size );
case HCBT_ACTIVATE: {