win32u: Pass module name before packed lparam in win_hook_params.

This commit is contained in:
Jacek Caban 2023-07-11 16:03:26 +02:00 committed by Alexandre Julliard
parent 730d462b7f
commit 36384097c7
4 changed files with 51 additions and 45 deletions

View file

@ -455,20 +455,20 @@ BOOL WINAPI User32CallWinEventHook( const struct win_event_hook_params *params,
BOOL WINAPI User32CallWindowsHook( struct win_hook_params *params, ULONG size )
{
HOOKPROC proc = params->proc;
const WCHAR *module = NULL;
HMODULE free_module = 0;
void *ret_ptr = NULL;
CBT_CREATEWNDW cbtc;
UINT ret_size = 0;
size_t lparam_offset;
LRESULT ret;
if (size > sizeof(*params) + params->lparam_size)
module = (const WCHAR *)((const char *)(params + 1) + params->lparam_size);
lparam_offset = FIELD_OFFSET( struct win_hook_params, module[wcslen( params->module ) + 1]);
if (params->lparam_size)
if (lparam_offset < size)
{
ret_size = params->lparam_size;
ret_ptr = params + 1;
lparam_offset = (lparam_offset + 15) & ~15; /* align */
ret_size = size - lparam_offset;
ret_ptr = (char *)params + lparam_offset;
params->lparam = (LPARAM)ret_ptr;
if (params->id == WH_CBT && params->code == HCBT_CREATEWND)
@ -490,7 +490,8 @@ BOOL WINAPI User32CallWindowsHook( struct win_hook_params *params, ULONG size )
ret_size = sizeof(*cs);
}
}
if (module && !(proc = get_hook_proc( proc, module, &free_module ))) return FALSE;
if (params->module[0] && !(proc = get_hook_proc( proc, params->module, &free_module )))
return FALSE;
ret = call_hook_proc( proc, params->id, params->code, params->wparam, params->lparam,
params->prev_unicode, params->next_unicode );

View file

@ -195,7 +195,7 @@ static UINT get_ll_hook_timeout(void)
* Call hook either in current thread or send message to the destination
* thread.
*/
static LRESULT call_hook( struct win_hook_params *info, const WCHAR *module )
static LRESULT call_hook( struct win_hook_params *info, const WCHAR *module, size_t lparam_size )
{
DWORD_PTR ret = 0;
@ -233,43 +233,48 @@ static LRESULT call_hook( struct win_hook_params *info, const WCHAR *module )
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);
ULONG lparam_ret_size = params->lparam_size;
CREATESTRUCTW *cs = NULL;
void *ret_ptr;
ULONG ret_len;
if (params->lparam_size)
size = FIELD_OFFSET( struct win_hook_params, module[module ? lstrlenW( module ) + 1 : 1] );
if (lparam_size)
{
lparam_ret_size = params->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;
params->lparam_size = sizeof(*cs);
lparam_size = sizeof(*cs);
if (!IS_INTRESOURCE( cs->lpszName ))
params->lparam_size += (wcslen( cs->lpszName ) + 1) * sizeof(WCHAR);
lparam_size += (wcslen( cs->lpszName ) + 1) * sizeof(WCHAR);
if (!IS_INTRESOURCE( cs->lpszClass ))
params->lparam_size += (wcslen( cs->lpszClass ) + 1) * sizeof(WCHAR);
lparam_size += (wcslen( cs->lpszClass ) + 1) * sizeof(WCHAR);
}
size += params->lparam_size;
}
if (module && module[0]) size += (lstrlenW( module ) + 1) * sizeof(WCHAR);
if (size != sizeof(*params))
if (size + lparam_size > sizeof(*info))
{
if (!(params = malloc( size ))) return 0;
*params = *info;
if (!(params = malloc( size + lparam_size ))) return 0;
memcpy( params, info, FIELD_OFFSET( struct win_hook_params, module ));
}
if (module)
wcscpy( params->module, module );
else
params->module[0] = 0;
if (params->lparam_size)
if (lparam_size)
{
void *lparam_ptr = (char *)params + size;
if (cs)
{
CREATESTRUCTW *params_cs = (CREATESTRUCTW *)(params + 1);
CREATESTRUCTW *params_cs = lparam_ptr;
WCHAR *ptr = (WCHAR *)(params_cs + 1);
const void *inline_ptr = (void *)0xffffffff;
@ -289,13 +294,10 @@ static LRESULT call_hook( struct win_hook_params *info, const WCHAR *module )
}
else
{
memcpy( params + 1, (const void *)params->lparam, params->lparam_size );
memcpy( lparam_ptr, (const void *)params->lparam, lparam_size );
}
}
if (module && module[0])
wcscpy( (WCHAR *)((char *)(params + 1) + params->lparam_size), module );
/*
* Windows protects from stack overflow in recursive hook calls. Different Windows
* allow different depths.
@ -314,7 +316,7 @@ static LRESULT call_hook( struct win_hook_params *info, const WCHAR *module )
thread_info->hook = params->handle;
thread_info->hook_unicode = params->next_unicode;
thread_info->hook_call_depth++;
ret = KeUserModeCallback( NtUserCallWindowsHook, params, size, &ret_ptr, &ret_len );
ret = KeUserModeCallback( NtUserCallWindowsHook, params, size + lparam_size, &ret_ptr, &ret_len );
if (ret_len && ret_len == lparam_ret_size)
memcpy( (void *)params->lparam, ret_ptr, lparam_ret_size );
thread_info->hook = prev;
@ -363,7 +365,7 @@ LRESULT WINAPI NtUserCallNextHookEx( HHOOK hhook, INT code, WPARAM wparam, LPARA
info.wparam = wparam;
info.lparam = lparam;
info.prev_unicode = thread_info->hook_unicode;
return call_hook( &info, module );
return call_hook( &info, module, 0 );
}
LRESULT call_current_hook( HHOOK hhook, INT code, WPARAM wparam, LPARAM lparam )
@ -396,7 +398,7 @@ LRESULT call_current_hook( HHOOK hhook, INT code, WPARAM wparam, LPARAM lparam )
info.wparam = wparam;
info.lparam = lparam;
info.prev_unicode = TRUE; /* assume Unicode for this function */
return call_hook( &info, module );
return call_hook( &info, module, 0 );
}
LRESULT call_hooks( INT id, INT code, WPARAM wparam, LPARAM lparam, size_t lparam_size )
@ -440,8 +442,7 @@ LRESULT call_hooks( INT id, INT code, WPARAM wparam, LPARAM lparam, size_t lpara
info.code = code;
info.wparam = wparam;
info.lparam = lparam;
info.lparam_size = lparam_size;
ret = call_hook( &info, module );
ret = call_hook( &info, module, lparam_size );
SERVER_START_REQ( finish_hook_chain )
{

View file

@ -349,9 +349,9 @@ struct win_hook_params32
int code;
ULONG wparam;
ULONG lparam;
UINT lparam_size;
BOOL prev_unicode;
BOOL next_unicode;
WCHAR module[1];
};
struct win_event_hook_params32
@ -754,13 +754,14 @@ static NTSTATUS WINAPI wow64_NtUserCallWindowsHook( void *arg, ULONG size )
{
struct win_hook_params *params = arg;
struct win_hook_params32 params32;
UINT lparam64_size, module_size;
UINT module_len, size32, offset;
void *ret_ptr;
ULONG ret_len;
NTSTATUS ret;
module_size = size - params->lparam_size - sizeof(*params);
lparam64_size = params->lparam_size;
module_len = wcslen( params->module );
size32 = FIELD_OFFSET( struct win_hook_params32, module[module_len + 1] );
offset = FIELD_OFFSET( struct win_hook_params, module[module_len + 1] );
params32.proc = PtrToUlong( params->proc );
params32.handle = HandleToUlong( params->handle );
@ -772,16 +773,19 @@ static NTSTATUS WINAPI wow64_NtUserCallWindowsHook( void *arg, ULONG size )
params32.lparam = params->lparam;
params32.prev_unicode = params->prev_unicode;
params32.next_unicode = params->next_unicode;
params32.lparam_size = hook_lparam_64to32( params32.id, params32.code, params + 1,
lparam64_size, (char *)arg + sizeof(params32) );
memcpy( arg, &params32, sizeof(params32) );
if (module_size)
memmove( (char *)arg + sizeof(params32) + params32.lparam_size,
(const char *)arg + size - module_size, module_size );
memcpy( arg, &params32, FIELD_OFFSET( struct win_hook_params32, module ));
memmove( ((struct win_hook_params32 *)arg)->module, params->module,
(module_len + 1) * sizeof(WCHAR) );
ret = Wow64KiUserCallbackDispatcher( NtUserCallWindowsHook, arg,
sizeof(params32) + params32.lparam_size + module_size,
&ret_ptr, &ret_len );
if (size > offset)
{
size32 = (size32 + 15) & ~15;
offset = (offset + 15) & ~15;
size32 += hook_lparam_64to32( params32.id, params32.code, (char *)params + offset,
size - offset, (char *)arg + size32 );
}
ret = Wow64KiUserCallbackDispatcher( NtUserCallWindowsHook, arg, size32, &ret_ptr, &ret_len );
switch (params32.id)
{

View file

@ -167,9 +167,9 @@ struct win_hook_params
int code;
WPARAM wparam;
LPARAM lparam;
UINT lparam_size;
BOOL prev_unicode;
BOOL next_unicode;
WCHAR module[1];
};
/* NtUserCopyImage params */