From: Jacek Caban jacek@codeweavers.com
Instead of leaking kernel pointers. --- dlls/user32/hook.c | 38 +++++++++++- dlls/user32/user_private.h | 2 +- dlls/win32u/defwnd.c | 6 +- dlls/win32u/hook.c | 116 +++++++++++++++++++++++++++-------- dlls/win32u/input.c | 6 +- dlls/win32u/message.c | 28 +++++---- dlls/win32u/tests/win32u.c | 1 - dlls/win32u/win32u_private.h | 3 +- dlls/win32u/window.c | 10 +-- include/ntuser.h | 2 +- 10 files changed, 157 insertions(+), 55 deletions(-)
diff --git a/dlls/user32/hook.c b/dlls/user32/hook.c index 4ef1e029609..4201e2375ae 100644 --- a/dlls/user32/hook.c +++ b/dlls/user32/hook.c @@ -439,18 +439,52 @@ BOOL WINAPI User32CallWinEventHook( const struct win_event_hook_params *params, return TRUE; }
-BOOL WINAPI User32CallWindowsHook( const struct win_hook_params *params, ULONG size ) +BOOL WINAPI User32CallWindowsHook( struct win_hook_params *params, ULONG size ) { HOOKPROC proc = params->proc; + const WCHAR *module = NULL; HMODULE free_module = 0; + void *ret_lparam = NULL; + CBT_CREATEWNDW cbtc; + UINT ret_lparam_size = 0; LRESULT ret;
- if (params->module[0] && !(proc = get_hook_proc( proc, params->module, &free_module ))) return FALSE; + if (size > sizeof(*params) + params->lparam_size) + module = (const WCHAR *)((const char *)(params + 1) + params->lparam_size); + + if (params->lparam_size) + { + ret_lparam = (void *)params->lparam; + ret_lparam_size = params->lparam_size; + params->lparam = (LPARAM)(params + 1); + + if (params->id == WH_CBT && params->code == HCBT_CREATEWND) + { + CREATESTRUCTW *cs = (CREATESTRUCTW *)params->lparam; + const WCHAR *ptr = (const WCHAR *)(cs + 1); + + if (!IS_INTRESOURCE(cs->lpszName)) + { + cs->lpszName = ptr; + ptr += wcslen( ptr ) + 1; + } + if (!IS_INTRESOURCE(cs->lpszClass)) + cs->lpszClass = ptr; + + cbtc.hwndInsertAfter = HWND_TOP; + cbtc.lpcs = cs; + params->lparam = (LPARAM)&cbtc; + ret_lparam_size = sizeof(*cs); + } + } + if (module && !(proc = get_hook_proc( proc, module, &free_module ))) return FALSE;
ret = call_hook_proc( proc, params->id, params->code, params->wparam, params->lparam, params->prev_unicode, params->next_unicode );
if (free_module) FreeLibrary( free_module ); + if (ret_lparam) memcpy( ret_lparam, params + 1, ret_lparam_size ); + else if (ret_lparam_size) NtCallbackReturn( params + 1, ret_lparam_size, ret ); return ret; }
diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h index 06a358376a8..5944187d686 100644 --- a/dlls/user32/user_private.h +++ b/dlls/user32/user_private.h @@ -83,7 +83,7 @@ BOOL WINAPI User32CallEnumDisplayMonitor( struct enum_display_monitor_params *pa BOOL WINAPI User32CallSendAsyncCallback( const struct send_async_params *params, ULONG size ); BOOL WINAPI User32CallWinEventHook( const struct win_event_hook_params *params, ULONG size ); BOOL WINAPI User32CallWindowProc( struct win_proc_params *params, ULONG size ); -BOOL WINAPI User32CallWindowsHook( const struct win_hook_params *params, ULONG size ); +BOOL WINAPI User32CallWindowsHook( struct win_hook_params *params, ULONG size ); BOOL WINAPI User32InitBuiltinClasses( const struct win_hook_params *params, ULONG size );
/* message spy definitions */ diff --git a/dlls/win32u/defwnd.c b/dlls/win32u/defwnd.c index b9a74884c01..a5644f594ad 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 )) + if (call_hooks( WH_CBT, HCBT_MOVESIZE, (WPARAM)hwnd, (LPARAM)&sizing_rect, sizeof(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 )) + if (call_hooks( WH_CBT, HCBT_SYSCOMMAND, wparam, lparam, 0 )) 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 ); + call_hooks( WH_SHELL, HSHELL_APPCOMMAND, wparam, lparam, 0 ); else send_message( parent, msg, wparam, lparam ); break; diff --git a/dlls/win32u/hook.c b/dlls/win32u/hook.c index 95ce8ab7e9b..53b98108acc 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 )) return TRUE; - return call_hooks( WH_MSGFILTER, code, 0, (LPARAM)msg ); + if (call_hooks( WH_SYSMSGFILTER, code, 0, (LPARAM)msg, sizeof(*msg) )) return TRUE; + return call_hooks( WH_MSGFILTER, code, 0, (LPARAM)msg, sizeof(*msg) ); }
static UINT get_ll_hook_timeout(void) @@ -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 ) +static LRESULT call_hook( struct win_hook_params *info, const WCHAR *module ) { DWORD_PTR ret = 0;
@@ -231,10 +231,70 @@ static LRESULT call_hook( struct win_hook_params *info ) struct user_thread_info *thread_info = get_user_thread_info(); HHOOK prev = thread_info->hook; BOOL prev_unicode = thread_info->hook_unicode; - size_t len = lstrlenW( info->module ); + struct win_hook_params *params = info; + ULONG size = sizeof(*params); + ULONG lparam_ret_size = params->lparam_size; + CREATESTRUCTW *cs = NULL; void *ret_ptr; ULONG ret_len;
+ if (params->lparam_size) + { + lparam_ret_size = params->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); + if (!IS_INTRESOURCE( cs->lpszName )) + params->lparam_size += (wcslen( cs->lpszName ) + 1) * sizeof(WCHAR); + if (!IS_INTRESOURCE( cs->lpszClass )) + params->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 (!(params = malloc( size ))) return 0; + *params = *info; + } + + if (params->lparam_size) + { + if (cs) + { + CREATESTRUCTW *params_cs = (CREATESTRUCTW *)(params + 1); + 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 )) + { + wcscpy( ptr, cs->lpszClass ); + params_cs->lpszClass = inline_ptr; + } + } + else + { + memcpy( params + 1, (const void *)params->lparam, params->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. @@ -246,18 +306,20 @@ static LRESULT call_hook( struct win_hook_params *info ) }
TRACE( "calling hook %p %s code %x wp %lx lp %lx module %s\n", - info->proc, hook_names[info->id-WH_MINHOOK], info->code, info->wparam, - info->lparam, debugstr_w(info->module) ); + params->proc, hook_names[params->id-WH_MINHOOK], params->code, params->wparam, + params->lparam, debugstr_w(module) );
- thread_info->hook = info->handle; - thread_info->hook_unicode = info->next_unicode; + thread_info->hook = params->handle; + thread_info->hook_unicode = params->next_unicode; thread_info->hook_call_depth++; - ret = KeUserModeCallback( NtUserCallWindowsHook, info, - FIELD_OFFSET( struct win_hook_params, module[len + 1] ), - &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 ); thread_info->hook = prev; thread_info->hook_unicode = prev_unicode; thread_info->hook_call_depth--; + + if (params != info) free( params ); }
if (info->id == WH_KEYBOARD_LL || info->id == WH_MOUSE_LL) @@ -272,18 +334,19 @@ LRESULT WINAPI NtUserCallNextHookEx( HHOOK hhook, INT code, WPARAM wparam, LPARA { struct user_thread_info *thread_info = get_user_thread_info(); struct win_hook_params info; + WCHAR module[MAX_PATH];
- memset( &info, 0, sizeof(info) - sizeof(info.module) ); + memset( &info, 0, sizeof(info) );
SERVER_START_REQ( get_hook_info ) { req->handle = wine_server_user_handle( thread_info->hook ); req->get_next = 1; req->event = EVENT_MIN; - wine_server_set_reply( req, info.module, sizeof(info.module)-sizeof(WCHAR) ); + wine_server_set_reply( req, module, sizeof(module) - sizeof(WCHAR) ); if (!wine_server_call_err( req )) { - info.module[wine_server_reply_size(req) / sizeof(WCHAR)] = 0; + module[wine_server_reply_size(req) / sizeof(WCHAR)] = 0; info.handle = wine_server_ptr_handle( reply->handle ); info.id = reply->id; info.pid = reply->pid; @@ -298,24 +361,25 @@ 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 ); + return call_hook( &info, module ); }
LRESULT call_current_hook( HHOOK hhook, INT code, WPARAM wparam, LPARAM lparam ) { struct win_hook_params info; + WCHAR module[MAX_PATH];
- memset( &info, 0, sizeof(info) - sizeof(info.module) ); + memset( &info, 0, sizeof(info) );
SERVER_START_REQ( get_hook_info ) { req->handle = wine_server_user_handle( hhook ); req->get_next = 0; req->event = EVENT_MIN; - wine_server_set_reply( req, info.module, sizeof(info.module)-sizeof(WCHAR) ); + wine_server_set_reply( req, module, sizeof(module) ); if (!wine_server_call_err( req )) { - info.module[wine_server_reply_size(req) / sizeof(WCHAR)] = 0; + module[wine_server_reply_size(req) / sizeof(WCHAR)] = 0; info.handle = wine_server_ptr_handle( reply->handle ); info.id = reply->id; info.pid = reply->pid; @@ -330,13 +394,14 @@ 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 ); + return call_hook( &info, module ); }
-LRESULT call_hooks( INT id, INT code, WPARAM wparam, LPARAM lparam ) +LRESULT call_hooks( INT id, INT code, WPARAM wparam, LPARAM lparam, size_t lparam_size ) { struct user_thread_info *thread_info = get_user_thread_info(); struct win_hook_params info; + WCHAR module[MAX_PATH]; DWORD_PTR ret;
user_check_not_lock(); @@ -347,7 +412,7 @@ LRESULT call_hooks( INT id, INT code, WPARAM wparam, LPARAM lparam ) return 0; }
- memset( &info, 0, sizeof(info) - sizeof(info.module) ); + memset( &info, 0, sizeof(info) ); info.prev_unicode = TRUE; info.id = id;
@@ -355,10 +420,10 @@ LRESULT call_hooks( INT id, INT code, WPARAM wparam, LPARAM lparam ) { req->id = info.id; req->event = EVENT_MIN; - wine_server_set_reply( req, info.module, sizeof(info.module)-sizeof(WCHAR) ); + wine_server_set_reply( req, module, sizeof(module)-sizeof(WCHAR) ); if (!wine_server_call( req )) { - info.module[wine_server_reply_size(req) / sizeof(WCHAR)] = 0; + module[wine_server_reply_size(req) / sizeof(WCHAR)] = 0; info.handle = wine_server_ptr_handle( reply->handle ); info.pid = reply->pid; info.tid = reply->tid; @@ -373,7 +438,8 @@ LRESULT call_hooks( INT id, INT code, WPARAM wparam, LPARAM lparam ) info.code = code; info.wparam = wparam; info.lparam = lparam; - ret = call_hook( &info ); + info.lparam_size = lparam_size; + ret = call_hook( &info, module );
SERVER_START_REQ( finish_hook_chain ) { @@ -514,7 +580,7 @@ void WINAPI NtUserNotifyWinEvent( DWORD event, HWND hwnd, LONG object_id, LONG c
info.time = NtGetTickCount(); KeUserModeCallback( NtUserCallWinEventHook, &info, - FIELD_OFFSET( struct win_hook_params, module[lstrlenW(info.module) + 1] ), + FIELD_OFFSET( struct win_event_hook_params, module[lstrlenW(info.module) + 1] ), &ret_ptr, &ret_len );
SERVER_START_REQ( get_hook_info ) diff --git a/dlls/win32u/input.c b/dlls/win32u/input.c index ed0aa997894..f3b724e7010 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 )) return FALSE; + if (call_hooks( WH_CBT, HCBT_ACTIVATE, (WPARAM)hwnd, (LPARAM)&cbt, sizeof(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 )) return 0; + if (call_hooks( WH_CBT, HCBT_SETFOCUS, (WPARAM)hwnd, (LPARAM)previous, 0 )) 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 )) return 0; + if (call_hooks( WH_CBT, HCBT_SETFOCUS, 0, (LPARAM)previous, 0 )) return 0; }
/* change focus and send messages */ diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index bc932c5c820..24e6dcf368c 100644 --- a/dlls/win32u/message.c +++ b/dlls/win32u/message.c @@ -1365,7 +1365,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 ); + call_hooks( WH_CALLWNDPROC, HC_ACTION, same_thread, (LPARAM)&cwp, sizeof(cwp) );
dispatch_win_proc_params( params, sizeof(*params) + size ); if (params != &p) free( params ); @@ -1376,7 +1376,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 ); + call_hooks( WH_CALLWNDPROCRET, HC_ACTION, same_thread, (LPARAM)&cwpret, sizeof(cwpret) ); return result; }
@@ -1483,7 +1483,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 ); + call_hooks( WH_JOURNALRECORD, HC_ACTION, 0, (LPARAM)&event, sizeof(event) );
/* check message filters */ if (msg->message < first || msg->message > last) return FALSE; @@ -1516,10 +1516,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 )) + LOWORD(msg->wParam), msg->lParam, 0 )) { /* skip this message */ - call_hooks( WH_CBT, HCBT_KEYSKIPPED, LOWORD(msg->wParam), msg->lParam ); + call_hooks( WH_CBT, HCBT_KEYSKIPPED, LOWORD(msg->wParam), msg->lParam, 0 ); accept_hardware_message( hw_id ); return FALSE; } @@ -1591,7 +1591,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 ); + call_hooks( WH_JOURNALRECORD, HC_ACTION, 0, (LPARAM)&event, sizeof(event) );
if (!check_hwnd_filter( msg, hwnd_filter )) return FALSE;
@@ -1665,14 +1665,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 )) + if (call_hooks( WH_MOUSE, remove ? HC_ACTION : HC_NOREMOVE, message, (LPARAM)&hook, sizeof(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 ); + call_hooks( WH_CBT, HCBT_CLICKSKIPPED, message, (LPARAM)&hook, sizeof(hook) ); accept_hardware_message( hw_id ); return FALSE; } @@ -1896,7 +1896,7 @@ static int peek_message( MSG *msg, HWND hwnd, UINT first, UINT last, UINT flags, memcpy( params.module, &msg_data->winevent + 1, size ); } params.module[size / sizeof(WCHAR)] = 0; - size = FIELD_OFFSET( struct win_hook_params, module[size / sizeof(WCHAR) + 1] ); + size = FIELD_OFFSET( struct win_event_hook_params, module[size / sizeof(WCHAR) + 1] );
params.handle = wine_server_ptr_handle( msg_data->winevent.hook ); params.event = info.msg.message; @@ -1923,7 +1923,8 @@ 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 ); + result = call_hooks( WH_KEYBOARD_LL, HC_ACTION, info.msg.wParam, + (LPARAM)&hook, sizeof(hook) ); } else if (info.msg.message == WH_MOUSE_LL && size >= sizeof(msg_data->hardware)) { @@ -1936,7 +1937,8 @@ 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 ); + result = call_hooks( WH_MOUSE_LL, HC_ACTION, info.msg.wParam, + (LPARAM)&hook, sizeof(hook) ); } reply_message( &info, result, &info.msg ); continue; @@ -1966,7 +1968,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 ); + call_hooks( WH_GETMESSAGE, HC_ACTION, flags & PM_REMOVE, (LPARAM)msg, sizeof(*msg) ); return 1; } continue; @@ -2019,7 +2021,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 ); + call_hooks( WH_GETMESSAGE, HC_ACTION, flags & PM_REMOVE, (LPARAM)msg, sizeof(*msg) ); return 1; }
diff --git a/dlls/win32u/tests/win32u.c b/dlls/win32u/tests/win32u.c index 0985478b2f0..502b6b91b5a 100644 --- a/dlls/win32u/tests/win32u.c +++ b/dlls/win32u/tests/win32u.c @@ -618,7 +618,6 @@ static void test_message_filter(void) msg.lParam = 20; ret = NtUserCallMsgFilter( &msg, 100 ); ok( !ret, "CallMsgFilterW returned: %x\n", ret ); - todo_wine ok( msg_ptr != &msg, "our ptr was passed directly to hook\n" );
if (sizeof(void *) == 8) /* on some Windows versions, msg is not modified on wow64 */ diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index dcf8c901756..a0bc1d62882 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -251,7 +251,8 @@ 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 ) DECLSPEC_HIDDEN; +extern LRESULT call_hooks( INT id, INT code, WPARAM wparam, LPARAM lparam, + size_t lparam_size ) 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 b4a0256e1de..0aa10d9ec65 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 )) + if (call_hooks( WH_CBT, HCBT_MINMAX, (WPARAM)hwnd, cmd, 0 )) 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 )) return FALSE; + if (call_hooks( WH_CBT, HCBT_DESTROYWND, (WPARAM)hwnd, 0, 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, 0 ); + call_hooks( WH_SHELL, HSHELL_WINDOWDESTROYED, (WPARAM)hwnd, 0, 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 )) + if (call_hooks( WH_CBT, HCBT_CREATEWND, (WPARAM)hwnd, (LPARAM)&cbtc, sizeof(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 ); + call_hooks( WH_SHELL, HSHELL_WINDOWCREATED, (WPARAM)hwnd, 0, 0 );
TRACE( "created window %p\n", hwnd ); SetThreadDpiAwarenessContext( context ); diff --git a/include/ntuser.h b/include/ntuser.h index 17301562013..7c375e43999 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -164,9 +164,9 @@ struct win_hook_params int code; WPARAM wparam; LPARAM lparam; + UINT lparam_size; BOOL prev_unicode; BOOL next_unicode; - WCHAR module[MAX_PATH]; };
/* NtUserCopyImage params */
From: Jacek Caban jacek@codeweavers.com
--- dlls/wow64win/user.c | 251 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 248 insertions(+), 3 deletions(-)
diff --git a/dlls/wow64win/user.c b/dlls/wow64win/user.c index 0432d55ec9c..178b609e508 100644 --- a/dlls/wow64win/user.c +++ b/dlls/wow64win/user.c @@ -145,6 +145,15 @@ typedef struct DWORD dwExStyle; } CREATESTRUCT32;
+typedef struct +{ + LONG lResult; + LONG lParam; + LONG wParam; + DWORD message; + ULONG hwnd; +} CWPRETSTRUCT32; + typedef struct { ULONG hwnd; @@ -179,6 +188,56 @@ typedef struct ULONG itemData; } DRAWITEMSTRUCT32;
+typedef struct +{ + ULONG lParam; + ULONG wParam; + UINT message; + ULONG hwnd; +} CWPSTRUCT32; + +typedef struct +{ + POINT pt; + ULONG hwnd; + UINT wHitTestCode; + ULONG dwExtraInfo; + DWORD mouseData; +} MOUSEHOOKSTRUCTEX32; + +typedef struct +{ + POINT pt; + DWORD mouseData; + DWORD flags; + DWORD time; + ULONG dwExtraInfo; +} MSLLHOOKSTRUCT32; + +typedef struct +{ + DWORD vkCode; + DWORD scanCode; + DWORD flags; + DWORD time; + ULONG dwExtraInfo; +} KBDLLHOOKSTRUCT32; + +typedef struct +{ + UINT message; + UINT paramL; + UINT paramH; + DWORD time; + ULONG hwnd; +} EVENTMSG32; + +typedef struct +{ + BOOL fMouse; + ULONG hWndActive; +} CBTACTIVATESTRUCT32; + typedef struct { UINT CtlType; @@ -241,7 +300,7 @@ static MSG *msg_32to64( MSG *msg, const MSG32 *msg32 ) return msg; }
-static MSG32 *msg_64to32( MSG *msg, MSG32 *msg32 ) +static MSG32 *msg_64to32( const MSG *msg, MSG32 *msg32 ) { if (!msg32) return NULL;
@@ -358,6 +417,19 @@ static PAINTSTRUCT *paintstruct_32to64( PAINTSTRUCT *ps, const PAINTSTRUCT32 *ps return ps; }
+static MOUSEHOOKSTRUCTEX32 *mousehookstruct_64to32( const MOUSEHOOKSTRUCTEX *hook, + MOUSEHOOKSTRUCTEX32 *hook32 ) +{ + if (!hook) return NULL; + + hook32->pt = hook->pt; + hook32->hwnd = HandleToUlong( hook->hwnd ); + hook32->wHitTestCode = hook->wHitTestCode; + hook32->dwExtraInfo = hook->dwExtraInfo; + hook32->mouseData = hook->mouseData; + return hook32; +} + static NTSTATUS dispatch_callback( ULONG id, void *args, ULONG len ) { void *ret_ptr; @@ -444,10 +516,183 @@ static NTSTATUS WINAPI wow64_NtUserCallWinProc( void *arg, ULONG size ) return NtCallbackReturn( &result, sizeof(result), status ); }
+static UINT hook_lparam_64to32( struct win_hook_params *params, const void *lp, void *lp32 ) +{ + if (!params->lparam_size) return 0; + + switch (params->id) + { + case WH_SYSMSGFILTER: + case WH_MSGFILTER: + case WH_GETMESSAGE: + msg_64to32( lp, lp32 ); + return sizeof(MSG32); + + case WH_CBT: + switch (params->code) + { + case HCBT_CREATEWND: + if (lp) + { + const CREATESTRUCTW *cs = lp; + CREATESTRUCT32 *cs32 = lp32; + createstruct_64to32( cs, cs32 ); + cs32->lpszName = PtrToUlong( cs->lpszName ); + cs32->lpszClass = PtrToUlong( cs->lpszClass ); + } + return sizeof(CREATESTRUCT32); + + case HCBT_ACTIVATE: + if (lp) + { + const CBTACTIVATESTRUCT *cbt = lp; + CBTACTIVATESTRUCT32 *cbt32 = lp32; + cbt32->fMouse = cbt->fMouse; + cbt32->hWndActive = HandleToUlong( cbt->hWndActive ); + } + return sizeof(CBTACTIVATESTRUCT32); + + case HCBT_CLICKSKIPPED: + mousehookstruct_64to32( lp, lp32 ); + return sizeof(MOUSEHOOKSTRUCTEX32); + } + break; + + case WH_CALLWNDPROC: + if (lp) + { + const CWPSTRUCT *cwp = lp; + CWPSTRUCT32 *cwp32 = lp32; + cwp32->lParam = cwp->lParam; + cwp32->wParam = cwp->wParam; + cwp32->message = cwp->message; + cwp32->hwnd = HandleToUlong( cwp->hwnd ); + } + return sizeof(CWPSTRUCT32); + + case WH_CALLWNDPROCRET: + if (lp) + { + const CWPRETSTRUCT *cwpret = lp; + CWPRETSTRUCT32 *cwpret32 = lp32; + cwpret32->lResult = cwpret->lResult; + cwpret32->lParam = cwpret->lParam; + cwpret32->wParam = cwpret->wParam; + cwpret32->message = cwpret->message; + cwpret32->hwnd = HandleToUlong( cwpret->hwnd ); + } + return sizeof(CWPRETSTRUCT32); + + case WH_MOUSE: + mousehookstruct_64to32( lp, lp32 ); + return sizeof(MOUSEHOOKSTRUCTEX32); + + case WH_MOUSE_LL: + if (lp) + { + const MSLLHOOKSTRUCT *hook = lp; + MSLLHOOKSTRUCT32 *hook32 = lp32; + hook32->pt = hook->pt; + hook32->mouseData = hook->mouseData; + hook32->flags = hook->flags; + hook32->time = hook->time; + hook32->dwExtraInfo = hook->dwExtraInfo; + } + return sizeof(MSLLHOOKSTRUCT32); + + case WH_KEYBOARD_LL: + if (lp) + { + const KBDLLHOOKSTRUCT *hook = lp; + KBDLLHOOKSTRUCT32 *hook32 = lp32; + hook32->vkCode = hook->vkCode; + hook32->scanCode = hook->scanCode; + hook32->flags = hook->flags; + hook32->time = hook->time; + hook32->dwExtraInfo = hook->dwExtraInfo; + } + return sizeof(KBDLLHOOKSTRUCT32); + + case WH_JOURNALRECORD: + if (lp) + { + const EVENTMSG *event = lp; + EVENTMSG32 *event32 = lp32; + + event32->message = event->message; + event32->paramL = event->paramL; + event32->paramH = event->paramH; + event32->time = event->time; + event32->hwnd = HandleToUlong( event->hwnd ); + } + return sizeof(EVENTMSG32); + } + + if (lp) memcpy( lp32, lp, params->lparam_size ); + return params->lparam_size; +} + static NTSTATUS WINAPI wow64_NtUserCallWindowsHook( void *arg, ULONG size ) { - FIXME( "\n" ); - return 0; + struct win_hook_params *params = arg; + struct + { + ULONG proc; + ULONG handle; + DWORD pid; + DWORD tid; + int id; + int code; + ULONG wparam; + ULONG lparam; + UINT lparam_size; + BOOL prev_unicode; + BOOL next_unicode; + } *params32; + void *ret_lparam = (void *)params->lparam; + UINT lparam32_size = 0, module_size, size32; + void *ret_ptr; + ULONG ret_len; + NTSTATUS ret; + + lparam32_size = hook_lparam_64to32( params, NULL, NULL ); + module_size = size - params->lparam_size - sizeof(*params); + + size32 = sizeof(*params32) + lparam32_size + module_size; + if (!(params32 = Wow64AllocateTemp( size32 ))) return 0; + params32->proc = (UINT_PTR)params->proc; + params32->handle = HandleToUlong( params->handle ); + params32->pid = params->pid; + params32->tid = params->tid; + params32->id = params->id; + params32->code = params->code; + params32->wparam = params->wparam; + params32->lparam = params->lparam_size ? 0 : params->lparam; + params32->lparam_size = lparam32_size; + params32->prev_unicode = params->prev_unicode; + params32->next_unicode = params->next_unicode; + if (lparam32_size) hook_lparam_64to32( params, params + 1, params32 + 1 ); + if (module_size) + memcpy( (char *)(params32 + 1) + params32->lparam_size, + (const char *)params + size - module_size, module_size ); + + ret = Wow64KiUserCallbackDispatcher( NtUserCallWindowsHook, params32, size32, &ret_ptr, &ret_len ); + + switch (params->id) + { + case WH_SYSMSGFILTER: + case WH_MSGFILTER: + case WH_GETMESSAGE: + msg_32to64( (MSG *)(params + 1), (const MSG32 *)(params32 + 1) ); + if (ret_lparam) + { + memcpy( ret_lparam, params + 1, params->lparam_size ); + return ret; + } + return NtCallbackReturn( params + 1, params->lparam_size, ret ); + } + + return ret; }
static NTSTATUS WINAPI wow64_NtUserCopyImage( void *arg, ULONG size )
From: Jacek Caban jacek@codeweavers.com
--- dlls/user32/user_main.c | 25 ++++++--- dlls/win32u/font.c | 4 +- dlls/win32u/message.c | 1 + dlls/wow64win/user.c | 115 +++++++++++++++++++++++++++++++++++++--- include/ntuser.h | 3 +- 5 files changed, 134 insertions(+), 14 deletions(-)
diff --git a/dlls/user32/user_main.c b/dlls/user32/user_main.c index bc817089e46..f16f8e04464 100644 --- a/dlls/user32/user_main.c +++ b/dlls/user32/user_main.c @@ -125,8 +125,17 @@ static NTSTATUS WINAPI User32DrawScrollBar( const struct draw_scroll_bar_params
static NTSTATUS WINAPI User32DrawText( const struct draw_text_params *params, ULONG size ) { + RECT rect = params->rect; + int ret; + size -= FIELD_OFFSET( struct draw_text_params, str ); - return DrawTextW( params->hdc, params->str, size / sizeof(WCHAR), params->rect, params->flags ); + ret = DrawTextW( params->hdc, params->str, size / sizeof(WCHAR), &rect, params->flags ); + if (params->ret_rect) + { + *params->ret_rect = rect; + return ret; + } + return NtCallbackReturn( &rect, sizeof(rect), ret ); }
static NTSTATUS WINAPI User32ImmProcessKey( const struct imm_process_key_params *params, ULONG size ) @@ -180,12 +189,16 @@ static BOOL WINAPI User32LoadDriver( const WCHAR *path, ULONG size )
static NTSTATUS WINAPI User32UnpackDDEMessage( const struct unpack_dde_message_params *params, ULONG size ) { - struct unpack_dde_message_result *result = params->result; - result->wparam = params->wparam; - result->lparam = params->lparam; + struct unpack_dde_message_result result = { .wparam = params->wparam, .lparam = params->lparam }; + size -= FIELD_OFFSET( struct unpack_dde_message_params, data ); - return unpack_dde_message( params->hwnd, params->message, &result->wparam, &result->lparam, - params->data, size ); + if (!unpack_dde_message( params->hwnd, params->message, &result.wparam, &result.lparam, + params->data, size )) + return FALSE; + + if (params->result) *params->result = result; + else NtCallbackReturn( &result, sizeof(result), TRUE ); + return TRUE; }
static const void *kernel_callback_table[NtUserCallCount] = diff --git a/dlls/win32u/font.c b/dlls/win32u/font.c index 5ea89c9220e..e26c7bfa316 100644 --- a/dlls/win32u/font.c +++ b/dlls/win32u/font.c @@ -6610,10 +6610,12 @@ INT WINAPI DrawTextW( HDC hdc, const WCHAR *str, INT count, RECT *rect, UINT fla size = FIELD_OFFSET( struct draw_text_params, str[count] ); if (!(params = malloc( size ))) return 0; params->hdc = hdc; - params->rect = rect; + params->rect = *rect; + params->ret_rect = rect; params->flags = flags; if (count) memcpy( params->str, str, count * sizeof(WCHAR) ); ret = KeUserModeCallback( NtUserDrawText, params, size, &ret_ptr, &ret_len ); + if (ret_len == sizeof(*rect)) *rect = *(const RECT *)ret_ptr; free( params ); return ret; } diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index 24e6dcf368c..f4f134e213b 100644 --- a/dlls/win32u/message.c +++ b/dlls/win32u/message.c @@ -2009,6 +2009,7 @@ static int peek_message( MSG *msg, HWND hwnd, UINT first, UINT last, UINT flags, params->lparam = info.msg.lParam; if (size) memcpy( params->data, buffer, size ); ret = KeUserModeCallback( NtUserUnpackDDEMessage, params, len, &ret_ptr, &len ); + if (len == sizeof(result)) result = *(struct unpack_dde_message_result *)ret_ptr; free( params ); if (!ret) continue; /* ignore it */ info.msg.wParam = result.wparam; diff --git a/dlls/wow64win/user.c b/dlls/wow64win/user.c index 178b609e508..bb17e034eb2 100644 --- a/dlls/wow64win/user.c +++ b/dlls/wow64win/user.c @@ -287,6 +287,39 @@ struct win_proc_params32 ULONG procW; };
+struct win_event_hook_params32 +{ + DWORD event; + ULONG hwnd; + LONG object_id; + LONG child_id; + ULONG handle; + DWORD tid; + DWORD time; + ULONG proc; + WCHAR module[MAX_PATH]; +}; + +struct draw_text_params32 +{ + ULONG hdc; + int count; + RECT rect; + ULONG ret_rect; + UINT flags; + WCHAR str[1]; +}; + +struct unpack_dde_message_params32 +{ + ULONG result; + ULONG hwnd; + UINT message; + LONG wparam; + LONG lparam; + char data[1]; +}; + static MSG *msg_32to64( MSG *msg, const MSG32 *msg32 ) { if (!msg32) return NULL; @@ -480,8 +513,22 @@ static NTSTATUS WINAPI wow64_NtUserCallSendAsyncCallback( void *arg, ULONG size
static NTSTATUS WINAPI wow64_NtUserCallWinEventHook( void *arg, ULONG size ) { - FIXME( "\n" ); - return 0; + struct win_event_hook_params *params = arg; + struct win_event_hook_params32 params32; + + params32.event = params->event; + params32.hwnd = HandleToUlong( params->hwnd ); + params32.object_id = params->object_id; + params32.child_id = params->child_id; + params32.handle = HandleToUlong( params->handle ); + params32.tid = params->tid; + params32.time = params->time; + params32.proc = PtrToUlong( params->proc ); + + size -= FIELD_OFFSET( struct win_event_hook_params, module ); + if (size) memcpy( params32.module, params->module, size ); + return dispatch_callback( NtUserCallWinEventHook, ¶ms32, + FIELD_OFFSET( struct win_event_hook_params32, module ) + size); }
static NTSTATUS WINAPI wow64_NtUserCallWinProc( void *arg, ULONG size ) @@ -766,8 +813,31 @@ static NTSTATUS WINAPI wow64_NtUserDrawScrollBar( void *arg, ULONG size )
static NTSTATUS WINAPI wow64_NtUserDrawText( void *arg, ULONG size ) { - FIXME( "\n" ); - return 0; + struct draw_text_params *params = arg; + struct draw_text_params32 *params32; + RECT *rect_ptr = params->ret_rect; + ULONG ret_len, len; + void *ret_ptr; + NTSTATUS ret; + + len = (size - FIELD_OFFSET( struct draw_text_params, str )) / sizeof(WCHAR); + if (!(params32 = Wow64AllocateTemp( FIELD_OFFSET( struct draw_text_params32, str[len] )))) + return 0; + + params32->hdc = HandleToUlong( params->hdc ); + params32->count = params->count; + params32->rect = params->rect; + params32->ret_rect = 0; + params32->flags = params->flags; + if (len) memcpy( params32->str, params->str, len * sizeof(WCHAR) ); + + ret = Wow64KiUserCallbackDispatcher( NtUserDrawText, params, size, &ret_ptr, &ret_len ); + if (ret_len == sizeof(RECT) && rect_ptr) + { + *rect_ptr = *(const RECT *)ret_ptr; + return ret; + } + return NtCallbackReturn( ret_ptr, ret_len, ret ); }
static NTSTATUS WINAPI wow64_NtUserFreeCachedClipboardData( void *arg, ULONG size ) @@ -874,8 +944,41 @@ static NTSTATUS WINAPI wow64_NtUserRenderSynthesizedFormat( void *arg, ULONG siz
static NTSTATUS WINAPI wow64_NtUserUnpackDDEMessage( void *arg, ULONG size ) { - FIXME( "\n" ); - return 0; + struct unpack_dde_message_params *params = arg; + struct unpack_dde_message_params32 *params32; + struct unpack_dde_message_result result; + struct + { + LONG wparam; + LONG lparam; + } *result32; + void *ret_ptr; + ULONG ret_len; + + size -= FIELD_OFFSET( struct unpack_dde_message_params, data ); + if (!(params32 = Wow64AllocateTemp( FIELD_OFFSET( struct unpack_dde_message_params32, data[size] )))) + return 0; + + params32->result = 0; + params32->hwnd = HandleToUlong( params->hwnd ); + params32->message = params->message; + params32->wparam = params->wparam; + params32->lparam = params->lparam; + if (size) memcpy( params32->data, params->data, size ); + size = FIELD_OFFSET( struct unpack_dde_message_params32, data[size] ); + + if (!Wow64KiUserCallbackDispatcher( NtUserUnpackDDEMessage, params32, size, &ret_ptr, &ret_len )) + return FALSE; + if (ret_len == sizeof(*result32)) + { + result32 = ret_ptr; + result.wparam = result32->wparam; + result.lparam = result32->lparam; + } + + if (!params->result) NtCallbackReturn( &result, sizeof(result), TRUE ); + *params->result = result; + return TRUE; }
static NTSTATUS WINAPI wow64_NtUserCallFreeIcon( void *arg, ULONG size ) diff --git a/include/ntuser.h b/include/ntuser.h index 7c375e43999..326d0371998 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -184,7 +184,8 @@ struct draw_text_params { HDC hdc; int count; - RECT *rect; /* FIXME: Use NtCallbackReturn instead */ + RECT rect; + RECT *ret_rect; /* FIXME: Use NtCallbackReturn instead */ UINT flags; WCHAR str[1]; };
From: Jacek Caban jacek@codeweavers.com
--- dlls/wow64win/user.c | 47 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 3 deletions(-)
diff --git a/dlls/wow64win/user.c b/dlls/wow64win/user.c index bb17e034eb2..8fb70c39fb5 100644 --- a/dlls/wow64win/user.c +++ b/dlls/wow64win/user.c @@ -119,6 +119,14 @@ typedef struct } DUMMYUNIONNAME; } INPUT32;
+typedef struct +{ + int x; + int y; + DWORD time; + ULONG dwExtraInfo; +} MOUSEMOVEPOINT32; + typedef struct { UINT32 hdc; @@ -2107,12 +2115,45 @@ NTSTATUS WINAPI wow64_NtUserGetMessage( UINT *args ) NTSTATUS WINAPI wow64_NtUserGetMouseMovePointsEx( UINT *args ) { UINT size = get_ulong( &args ); - MOUSEMOVEPOINT *ptin = get_ptr( &args ); - MOUSEMOVEPOINT *ptout = get_ptr( &args ); + MOUSEMOVEPOINT32 *ptin32 = get_ptr( &args ); + MOUSEMOVEPOINT32 *ptout32 = get_ptr( &args ); int count = get_ulong( &args ); DWORD resolution = get_ulong( &args );
- return NtUserGetMouseMovePointsEx( size, ptin, ptout, count, resolution ); + MOUSEMOVEPOINT ptin[64], ptout[64]; + int ret, i; + + if (size != sizeof(MOUSEMOVEPOINT32) || count < 0 || count > ARRAYSIZE( ptin )) + { + RtlSetLastWin32Error( ERROR_INVALID_PARAMETER ); + return -1; + } + + if (!ptin32 || (!ptout32 && count)) + { + set_last_error32( ERROR_NOACCESS ); + return -1; + } + + for (i = 0; i < count; i++) + { + ptin[i].x = ptin32[i].x; + ptin[i].y = ptin32[i].y; + ptin[i].time = ptin32[i].time; + ptin[i].dwExtraInfo = ptin32[i].dwExtraInfo; + } + + ret = NtUserGetMouseMovePointsEx( sizeof(MOUSEMOVEPOINT), ptin, ptout, count, resolution ); + + for (i = 0; i < ret; i++) + { + ptout32[i].x = ptout[i].x; + ptout32[i].y = ptout[i].y; + ptout32[i].time = ptout[i].time; + ptout32[i].dwExtraInfo = ptout[i].dwExtraInfo; + } + + return ret; }
NTSTATUS WINAPI wow64_NtUserGetObjectInformation( UINT *args )
From: Jacek Caban jacek@codeweavers.com
--- dlls/wow64win/user.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/dlls/wow64win/user.c b/dlls/wow64win/user.c index 8fb70c39fb5..5474abd76da 100644 --- a/dlls/wow64win/user.c +++ b/dlls/wow64win/user.c @@ -1759,11 +1759,12 @@ NTSTATUS WINAPI wow64_NtUserGetClassInfoEx( UINT *args ) struct client_menu_name client_name; UNICODE_STRING name; WNDCLASSEXW wc; + ATOM ret;
wc.cbSize = sizeof(wc); - if (!NtUserGetClassInfoEx( instance, unicode_str_32to64( &name, name32 ), &wc, - &client_name, ansi )) - return FALSE; + if (!(ret = NtUserGetClassInfoEx( instance, unicode_str_32to64( &name, name32 ), &wc, + &client_name, ansi ))) + return 0;
wc32->style = wc.style; wc32->lpfnWndProc = PtrToUlong( wc.lpfnWndProc ); @@ -1777,7 +1778,7 @@ NTSTATUS WINAPI wow64_NtUserGetClassInfoEx( UINT *args ) wc32->lpszClassName = PtrToUlong( wc.lpszClassName ); wc32->hIconSm = HandleToUlong( wc.hIconSm ); client_menu_name_64to32( &client_name, client_name32 ); - return TRUE; + return ret; }
NTSTATUS WINAPI wow64_NtUserGetClassName( UINT *args )
This merge request was approved by Huw Davies.