win32u: Pass module name before packed lparam in win_hook_params.
This commit is contained in:
parent
730d462b7f
commit
36384097c7
4 changed files with 51 additions and 45 deletions
|
@ -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 );
|
||||
|
|
|
@ -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 )
|
||||
{
|
||||
|
|
|
@ -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, ¶ms32, sizeof(params32) );
|
||||
if (module_size)
|
||||
memmove( (char *)arg + sizeof(params32) + params32.lparam_size,
|
||||
(const char *)arg + size - module_size, module_size );
|
||||
memcpy( arg, ¶ms32, 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)
|
||||
{
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Add table
Reference in a new issue