This is a preparation for better handling of message packing between win32u and user32. It also removes some hacks that were needed before syscall separation completion.
-- v2: win32u: Pass module name before packed lparam in win_hook_params. user32: Always use NtCallbackReturn to pass result from User32CallWindowsHook. wow64win: Convert parameters in place in wow64_NtUserCallWindowsHook. wow64win: Conver parameters in place in wow64_NtUserCallWinProc.
From: Jacek Caban jacek@codeweavers.com
--- dlls/wow64win/user.c | 120 ++++++++++++++++++++++++------------------- 1 file changed, 66 insertions(+), 54 deletions(-)
diff --git a/dlls/wow64win/user.c b/dlls/wow64win/user.c index 602ccfa79b9..7c3a6ddd7ab 100644 --- a/dlls/wow64win/user.c +++ b/dlls/wow64win/user.c @@ -153,6 +153,26 @@ typedef struct DWORD dwExStyle; } CREATESTRUCT32;
+typedef struct +{ + ULONG szClass; + ULONG szTitle; + ULONG hOwner; + INT x; + INT y; + INT cx; + INT cy; + DWORD style; + ULONG lParam; +} MDICREATESTRUCT32; + +typedef struct +{ + ULONG hmenuIn; + ULONG hmenuNext; + ULONG hwndNext; +} MDINEXTMENU32; + typedef struct { LONG lResult; @@ -173,6 +193,31 @@ typedef struct UINT flags; } WINDOWPOS32;
+typedef struct +{ + RECT rgrc[3]; + ULONG lppos; +} NCCALCSIZE_PARAMS32; + +typedef struct +{ + UINT CtlType; + UINT CtlID; + ULONG hwndItem; + UINT itemID1; + ULONG itemData1; + UINT itemID2; + ULONG itemData2; + DWORD dwLocaleId; +} COMPAREITEMSTRUCT32; + +typedef struct +{ + ULONG dwData; + DWORD cbData; + ULONG lpData; +} COPYDATASTRUCT32; + typedef struct { UINT CtlType; @@ -294,6 +339,21 @@ struct win_proc_params32 ULONG procW; };
+struct win_hook_params32 +{ + 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; +}; + struct win_event_hook_params32 { DWORD event; @@ -679,20 +739,7 @@ static UINT hook_lparam_64to32( struct win_hook_params *params, const void *lp, static NTSTATUS WINAPI wow64_NtUserCallWindowsHook( void *arg, ULONG size ) { 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; + struct win_hook_params32 *params32; UINT lparam32_size = 0, module_size, size32; void *ret_ptr; ULONG ret_len; @@ -2853,18 +2900,7 @@ static LRESULT message_call_32to64( HWND hwnd, UINT msg, WPARAM wparam, LPARAM l
case WM_MDICREATE: { - struct - { - ULONG szClass; - ULONG szTitle; - ULONG hOwner; - INT x; - INT y; - INT cx; - INT cy; - DWORD style; - ULONG lParam; - } *cs32 = (void *)lparam; + MDICREATESTRUCT32 *cs32 = (void *)lparam; MDICREATESTRUCTW cs;
cs.szClass = UlongToPtr( cs32->szClass ); @@ -2895,11 +2931,7 @@ static LRESULT message_call_32to64( HWND hwnd, UINT msg, WPARAM wparam, LPARAM l case WM_NCCALCSIZE: if (wparam) { - struct - { - RECT rgrc[3]; - ULONG lppos; - } *params32 = (void *)lparam; + NCCALCSIZE_PARAMS32 *params32 = (void *)lparam; NCCALCSIZE_PARAMS params; WINDOWPOS winpos;
@@ -2919,17 +2951,7 @@ static LRESULT message_call_32to64( HWND hwnd, UINT msg, WPARAM wparam, LPARAM l
case WM_COMPAREITEM: { - struct - { - UINT CtlType; - UINT CtlID; - ULONG hwndItem; - UINT itemID1; - ULONG itemData1; - UINT itemID2; - ULONG itemData2; - DWORD dwLocaleId; - } *cis32 = (void *)lparam; + COMPAREITEMSTRUCT32 *cis32 = (void *)lparam; COMPAREITEMSTRUCT cis;
cis.CtlType = cis32->CtlType; @@ -2994,12 +3016,7 @@ static LRESULT message_call_32to64( HWND hwnd, UINT msg, WPARAM wparam, LPARAM l
case WM_COPYDATA: { - struct - { - ULONG dwData; - DWORD cbData; - ULONG lpData; - } *cds32 = (void *)lparam; + COPYDATASTRUCT32 *cds32 = (void *)lparam; COPYDATASTRUCT cds;
cds.dwData = cds32->dwData; @@ -3021,12 +3038,7 @@ static LRESULT message_call_32to64( HWND hwnd, UINT msg, WPARAM wparam, LPARAM l
case WM_NEXTMENU: { - struct - { - ULONG hmenuIn; - ULONG hmenuNext; - ULONG hwndNext; - } *next32 = (void *)lparam; + MDINEXTMENU32 *next32 = (void *)lparam; MDINEXTMENU next;
next.hmenuIn = LongToHandle( next32->hmenuIn );
From: Jacek Caban jacek@codeweavers.com
--- dlls/wow64win/user.c | 111 +++++++++++++++++++++++++------------------ 1 file changed, 64 insertions(+), 47 deletions(-)
diff --git a/dlls/wow64win/user.c b/dlls/wow64win/user.c index 7c3a6ddd7ab..553d40a8f29 100644 --- a/dlls/wow64win/user.c +++ b/dlls/wow64win/user.c @@ -399,16 +399,19 @@ static MSG *msg_32to64( MSG *msg, const MSG32 *msg32 ) return msg; }
-static MSG32 *msg_64to32( const MSG *msg, MSG32 *msg32 ) +static MSG32 *msg_64to32( const MSG *msg64, MSG32 *msg32 ) { + MSG32 msg; + if (!msg32) return NULL;
- msg32->hwnd = HandleToUlong( msg->hwnd ); - msg32->message = msg->message; - msg32->wParam = msg->wParam; - msg32->lParam = msg->lParam; - msg32->time = msg->time; - msg32->pt = msg->pt; + msg.hwnd = HandleToLong( msg64->hwnd ); + msg.message = msg64->message; + msg.wParam = msg64->wParam; + msg.lParam = msg64->lParam; + msg.time = msg64->time; + msg.pt = msg64->pt; + memcpy( msg32, &msg, sizeof(msg) ); return msg32; }
@@ -422,32 +425,37 @@ static struct client_menu_name *client_menu_name_32to64( struct client_menu_name return name; }
-static struct client_menu_name32 *client_menu_name_64to32( const struct client_menu_name *name, +static struct client_menu_name32 *client_menu_name_64to32( const struct client_menu_name *name64, struct client_menu_name32 *name32 ) { if (name32) { - name32->nameA = PtrToUlong( name->nameA ); - name32->nameW = PtrToUlong( name->nameW ); - name32->nameUS = PtrToUlong( name->nameUS ); + struct client_menu_name32 name; + name.nameA = PtrToUlong( name64->nameA ); + name.nameW = PtrToUlong( name64->nameW ); + name.nameUS = PtrToUlong( name64->nameUS ); + memcpy( name32, &name, sizeof(name) ); } return name32; }
static void win_proc_params_64to32( const struct win_proc_params *src, struct win_proc_params32 *dst ) { - dst->func = PtrToUlong( src->func ); - dst->hwnd = HandleToUlong( src->hwnd ); - dst->msg = src->msg; - dst->wparam = src->wparam; - dst->lparam = src->lparam; - dst->ansi = src->ansi; - dst->ansi_dst = src->ansi_dst; - dst->needs_unpack = src->needs_unpack; - dst->mapping = src->mapping; - dst->dpi_awareness = HandleToUlong( src->dpi_awareness ); - dst->procA = PtrToUlong( src->procA ); - dst->procW = PtrToUlong( src->procW ); + struct win_proc_params32 params; + + params.func = PtrToUlong( src->func ); + params.hwnd = HandleToUlong( src->hwnd ); + params.msg = src->msg; + params.wparam = src->wparam; + params.lparam = src->lparam; + params.ansi = src->ansi; + params.ansi_dst = src->ansi_dst; + params.needs_unpack = src->needs_unpack; + params.mapping = src->mapping; + params.dpi_awareness = HandleToUlong( src->dpi_awareness ); + params.procA = PtrToUlong( src->procA ); + params.procW = PtrToUlong( src->procW ); + memcpy( dst, ¶ms, sizeof(params) ); }
static void createstruct_32to64( const CREATESTRUCT32 *from, CREATESTRUCTW *to ) @@ -469,16 +477,19 @@ static void createstruct_32to64( const CREATESTRUCT32 *from, CREATESTRUCTW *to )
static void createstruct_64to32( const CREATESTRUCTW *from, CREATESTRUCT32 *to ) { - to->lpCreateParams = PtrToUlong( from->lpCreateParams ); - to->hInstance = PtrToUlong( from->hInstance ); - to->hMenu = HandleToUlong( from->hMenu ); - to->hwndParent = HandleToUlong( from->hwndParent ); - to->cy = from->cy; - to->cx = from->cx; - to->y = from->y; - to->x = from->x; - to->style = from->style; - to->dwExStyle = from->dwExStyle; + CREATESTRUCT32 cs; + + cs.lpCreateParams = PtrToUlong( from->lpCreateParams ); + cs.hInstance = PtrToUlong( from->hInstance ); + cs.hMenu = HandleToUlong( from->hMenu ); + cs.hwndParent = HandleToUlong( from->hwndParent ); + cs.cy = from->cy; + cs.cx = from->cx; + cs.y = from->y; + cs.x = from->x; + cs.style = from->style; + cs.dwExStyle = from->dwExStyle; + memcpy( to, &cs, sizeof(cs) ); }
static void winpos_32to64( WINDOWPOS *dst, const WINDOWPOS32 *src ) @@ -494,13 +505,16 @@ static void winpos_32to64( WINDOWPOS *dst, const WINDOWPOS32 *src )
static void winpos_64to32( const WINDOWPOS *src, WINDOWPOS32 *dst ) { - dst->hwnd = HandleToUlong( src->hwnd ); - dst->hwndInsertAfter = HandleToUlong( src->hwndInsertAfter ); - dst->x = src->x; - dst->y = src->y; - dst->cx = src->cx; - dst->cy = src->cy; - dst->flags = src->flags; + WINDOWPOS32 wp; + + wp.hwnd = HandleToUlong( src->hwnd ); + wp.hwndInsertAfter = HandleToUlong( src->hwndInsertAfter ); + wp.x = src->x; + wp.y = src->y; + wp.cx = src->cx; + wp.cy = src->cy; + wp.flags = src->flags; + memcpy( dst, &wp, sizeof(wp) ); }
static PAINTSTRUCT *paintstruct_32to64( PAINTSTRUCT *ps, const PAINTSTRUCT32 *ps32 ) @@ -514,16 +528,19 @@ static PAINTSTRUCT *paintstruct_32to64( PAINTSTRUCT *ps, const PAINTSTRUCT32 *ps return ps; }
-static MOUSEHOOKSTRUCTEX32 *mousehookstruct_64to32( const MOUSEHOOKSTRUCTEX *hook, +static MOUSEHOOKSTRUCTEX32 *mousehookstruct_64to32( const MOUSEHOOKSTRUCTEX *hook64, MOUSEHOOKSTRUCTEX32 *hook32 ) { - if (!hook) return NULL; + MOUSEHOOKSTRUCTEX32 hook; + + if (!hook64) return NULL;
- hook32->pt = hook->pt; - hook32->hwnd = HandleToUlong( hook->hwnd ); - hook32->wHitTestCode = hook->wHitTestCode; - hook32->dwExtraInfo = hook->dwExtraInfo; - hook32->mouseData = hook->mouseData; + hook.pt = hook64->pt; + hook.hwnd = HandleToUlong( hook64->hwnd ); + hook.wHitTestCode = hook64->wHitTestCode; + hook.dwExtraInfo = hook64->dwExtraInfo; + hook.mouseData = hook64->mouseData; + memcpy( hook32, &hook, sizeof(hook) ); return hook32; }
From: Jacek Caban jacek@codeweavers.com
--- dlls/wow64win/user.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/dlls/wow64win/user.c b/dlls/wow64win/user.c index 553d40a8f29..c5506304718 100644 --- a/dlls/wow64win/user.c +++ b/dlls/wow64win/user.c @@ -615,19 +615,15 @@ static NTSTATUS WINAPI wow64_NtUserCallWinEventHook( void *arg, ULONG size ) static NTSTATUS WINAPI wow64_NtUserCallWinProc( void *arg, ULONG size ) { struct win_proc_params *params = arg; - struct win_proc_params32 params32_buf, *params32 = ¶ms32_buf; + struct win_proc_params32 *params32 = arg; LRESULT result = 0; void *ret_ptr; ULONG ret_len; NTSTATUS status;
- if (size > sizeof(*params)) - { - if (!(params32 = Wow64AllocateTemp( size - sizeof(*params) + sizeof(*params32) ))) - return 0; - memcpy( params32 + 1, params + 1, size - sizeof(*params) ); - } win_proc_params_64to32( params, params32 ); + if (size > sizeof(*params)) + memmove( params32 + 1, params + 1, size - sizeof(*params) );
status = Wow64KiUserCallbackDispatcher( NtUserCallWinProc, params32, size - sizeof(*params) + sizeof(*params32),
From: Jacek Caban jacek@codeweavers.com
--- dlls/wow64win/user.c | 178 +++++++++++++++++++++++-------------------- 1 file changed, 95 insertions(+), 83 deletions(-)
diff --git a/dlls/wow64win/user.c b/dlls/wow64win/user.c index c5506304718..37eeb0b7ed3 100644 --- a/dlls/wow64win/user.c +++ b/dlls/wow64win/user.c @@ -488,6 +488,8 @@ static void createstruct_64to32( const CREATESTRUCTW *from, CREATESTRUCT32 *to ) cs.y = from->y; cs.x = from->x; cs.style = from->style; + cs.lpszName = PtrToUlong( from->lpszName ); + cs.lpszClass = PtrToUlong( from->lpszClass ); cs.dwExStyle = from->dwExStyle; memcpy( to, &cs, sizeof(cs) ); } @@ -633,11 +635,11 @@ 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 ) +static UINT hook_lparam_64to32( int id, int code, const void *lp, size_t size, void *lp32 ) { - if (!params->lparam_size) return 0; + if (!size) return 0;
- switch (params->id) + switch (id) { case WH_SYSMSGFILTER: case WH_MSGFILTER: @@ -646,28 +648,27 @@ static UINT hook_lparam_64to32( struct win_hook_params *params, const void *lp, return sizeof(MSG32);
case WH_CBT: - switch (params->code) + switch (code) { case HCBT_CREATEWND: - if (lp) { - const CREATESTRUCTW *cs = lp; + const CREATESTRUCTW *cs64 = lp; CREATESTRUCT32 *cs32 = lp32; - createstruct_64to32( cs, cs32 ); - cs32->lpszName = PtrToUlong( cs->lpszName ); - cs32->lpszClass = PtrToUlong( cs->lpszClass ); + createstruct_64to32( cs64, cs32 ); + size -= sizeof(*cs64); + if (size) memmove( cs32 + 1, cs64 + 1, size ); + return sizeof(*cs32) + size; } - return sizeof(CREATESTRUCT32);
case HCBT_ACTIVATE: - if (lp) { const CBTACTIVATESTRUCT *cbt = lp; - CBTACTIVATESTRUCT32 *cbt32 = lp32; - cbt32->fMouse = cbt->fMouse; - cbt32->hWndActive = HandleToUlong( cbt->hWndActive ); + CBTACTIVATESTRUCT32 cbt32; + cbt32.fMouse = cbt->fMouse; + cbt32.hWndActive = HandleToUlong( cbt->hWndActive ); + memcpy( lp32, &cbt32, sizeof(cbt32) ); + return sizeof(cbt32); } - return sizeof(CBTACTIVATESTRUCT32);
case HCBT_CLICKSKIPPED: mousehookstruct_64to32( lp, lp32 ); @@ -676,120 +677,122 @@ static UINT hook_lparam_64to32( struct win_hook_params *params, const void *lp, 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 ); + CWPSTRUCT32 cwp32; + cwp32.lParam = cwp->lParam; + cwp32.wParam = cwp->wParam; + cwp32.message = cwp->message; + cwp32.hwnd = HandleToUlong( cwp->hwnd ); + memcpy( lp32, &cwp32, sizeof(cwp32) ); + return sizeof(cwp32); } - 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 ); + CWPRETSTRUCT32 cwpret32; + cwpret32.lResult = cwpret->lResult; + cwpret32.lParam = cwpret->lParam; + cwpret32.wParam = cwpret->wParam; + cwpret32.message = cwpret->message; + cwpret32.hwnd = HandleToUlong( cwpret->hwnd ); + memcpy( lp32, &cwpret32, sizeof(cwpret32) ); + return sizeof(cwpret32); } - 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; + MSLLHOOKSTRUCT32 hook32; + hook32.pt = hook->pt; + hook32.mouseData = hook->mouseData; + hook32.flags = hook->flags; + hook32.time = hook->time; + hook32.dwExtraInfo = hook->dwExtraInfo; + memcpy( lp32, &hook32, sizeof(hook32) ); + return sizeof(hook32); } - 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; + KBDLLHOOKSTRUCT32 hook32; + hook32.vkCode = hook->vkCode; + hook32.scanCode = hook->scanCode; + hook32.flags = hook->flags; + hook32.time = hook->time; + hook32.dwExtraInfo = hook->dwExtraInfo; + memcpy( lp32, &hook32, sizeof(hook32) ); + return sizeof(hook32); } - 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 ); + EVENTMSG32 event32; + + event32.message = event->message; + event32.paramL = event->paramL; + event32.paramH = event->paramH; + event32.time = event->time; + event32.hwnd = HandleToUlong( event->hwnd ); + memcpy( lp32, &event32, sizeof(event32) ); + return sizeof(event32); } - return sizeof(EVENTMSG32); }
- if (lp) memcpy( lp32, lp, params->lparam_size ); - return params->lparam_size; + memmove( lp32, lp, size ); + return size; }
static NTSTATUS WINAPI wow64_NtUserCallWindowsHook( void *arg, ULONG size ) { struct win_hook_params *params = arg; - struct win_hook_params32 *params32; - UINT lparam32_size = 0, module_size, size32; + struct win_hook_params32 params32; + UINT lparam64_size, module_size; 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 ); + lparam64_size = params->lparam_size; + + params32.proc = PtrToUlong( 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 = lparam64_size ? 0 : 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) - memcpy( (char *)(params32 + 1) + params32->lparam_size, - (const char *)params + size - module_size, module_size ); + memmove( (char *)arg + sizeof(params32) + params32.lparam_size, + (const char *)arg + size - module_size, module_size );
- ret = Wow64KiUserCallbackDispatcher( NtUserCallWindowsHook, params32, size32, &ret_ptr, &ret_len ); + ret = Wow64KiUserCallbackDispatcher( NtUserCallWindowsHook, arg, + sizeof(params32) + params32.lparam_size + module_size, + &ret_ptr, &ret_len );
- switch (params->id) + switch (params32.id) { case WH_SYSMSGFILTER: case WH_MSGFILTER: case WH_GETMESSAGE: - if (params->lparam_size == sizeof(MSG)) + if (ret_len == sizeof(MSG32)) { - msg_32to64( (MSG *)(params + 1), (const MSG32 *)(params32 + 1) ); - return NtCallbackReturn( params + 1, params->lparam_size, ret ); + MSG msg; + msg_32to64( &msg, ret_ptr ); + return NtCallbackReturn( &msg, sizeof(msg), ret ); } }
@@ -2907,7 +2910,16 @@ static LRESULT message_call_32to64( HWND hwnd, UINT msg, WPARAM wparam, LPARAM l
createstruct_32to64( cs32, &cs ); ret = NtUserMessageCall( hwnd, msg, wparam, (LPARAM)&cs, result_info, type, ansi ); - createstruct_64to32( &cs, cs32 ); + cs32->lpCreateParams = PtrToUlong( cs.lpCreateParams ); + cs32->hInstance = PtrToUlong( cs.hInstance ); + cs32->hMenu = HandleToLong( cs.hMenu ); + cs32->hwndParent = HandleToLong( cs.hwndParent ); + cs32->cy = cs.cy; + cs32->cx = cs.cx; + cs32->y = cs.y; + cs32->x = cs.x; + cs32->style = cs.style; + cs32->dwExStyle = cs.dwExStyle; return ret; }
From: Jacek Caban jacek@codeweavers.com
--- dlls/user32/hook.c | 16 +++++++--------- dlls/wow64win/user.c | 2 +- 2 files changed, 8 insertions(+), 10 deletions(-)
diff --git a/dlls/user32/hook.c b/dlls/user32/hook.c index 9fea8a59e0e..6f202a0f5d9 100644 --- a/dlls/user32/hook.c +++ b/dlls/user32/hook.c @@ -457,9 +457,9 @@ 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; + void *ret_ptr = NULL; CBT_CREATEWNDW cbtc; - UINT ret_lparam_size = 0; + UINT ret_size = 0; LRESULT ret;
if (size > sizeof(*params) + params->lparam_size) @@ -467,9 +467,9 @@ BOOL WINAPI User32CallWindowsHook( struct win_hook_params *params, ULONG size )
if (params->lparam_size) { - ret_lparam = (void *)params->lparam; - ret_lparam_size = params->lparam_size; - params->lparam = (LPARAM)(params + 1); + ret_size = params->lparam_size; + ret_ptr = params + 1; + params->lparam = (LPARAM)ret_ptr;
if (params->id == WH_CBT && params->code == HCBT_CREATEWND) { @@ -487,7 +487,7 @@ BOOL WINAPI User32CallWindowsHook( struct win_hook_params *params, ULONG size ) cbtc.hwndInsertAfter = HWND_TOP; cbtc.lpcs = cs; params->lparam = (LPARAM)&cbtc; - ret_lparam_size = sizeof(*cs); + ret_size = sizeof(*cs); } } if (module && !(proc = get_hook_proc( proc, module, &free_module ))) return FALSE; @@ -496,9 +496,7 @@ BOOL WINAPI User32CallWindowsHook( struct win_hook_params *params, ULONG size ) 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; + return NtCallbackReturn( ret_ptr, ret_size, ret ); }
/*********************************************************************** diff --git a/dlls/wow64win/user.c b/dlls/wow64win/user.c index 37eeb0b7ed3..c60df5052dc 100644 --- a/dlls/wow64win/user.c +++ b/dlls/wow64win/user.c @@ -769,7 +769,7 @@ static NTSTATUS WINAPI wow64_NtUserCallWindowsHook( void *arg, ULONG size ) params32.id = params->id; params32.code = params->code; params32.wparam = params->wparam; - params32.lparam = lparam64_size ? 0 : params->lparam; + 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,
From: Jacek Caban jacek@codeweavers.com
--- dlls/user32/hook.c | 15 +++++++------- dlls/win32u/hook.c | 49 ++++++++++++++++++++++---------------------- dlls/wow64win/user.c | 32 ++++++++++++++++------------- include/ntuser.h | 2 +- 4 files changed, 52 insertions(+), 46 deletions(-)
diff --git a/dlls/user32/hook.c b/dlls/user32/hook.c index 6f202a0f5d9..e17f23fde5c 100644 --- a/dlls/user32/hook.c +++ b/dlls/user32/hook.c @@ -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 ); diff --git a/dlls/win32u/hook.c b/dlls/win32u/hook.c index 4b9f22f7afd..59c5df33f59 100644 --- a/dlls/win32u/hook.c +++ b/dlls/win32u/hook.c @@ -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 ) { diff --git a/dlls/wow64win/user.c b/dlls/wow64win/user.c index c60df5052dc..fcd19c7f798 100644 --- a/dlls/wow64win/user.c +++ b/dlls/wow64win/user.c @@ -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 ); - - ret = Wow64KiUserCallbackDispatcher( NtUserCallWindowsHook, arg, - sizeof(params32) + params32.lparam_size + module_size, - &ret_ptr, &ret_len ); + memcpy( arg, ¶ms32, FIELD_OFFSET( struct win_hook_params32, module )); + memmove( ((struct win_hook_params32 *)arg)->module, params->module, + (module_len + 1) * sizeof(WCHAR) ); + + 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) { diff --git a/include/ntuser.h b/include/ntuser.h index 195d4e1322a..7d679e9ede1 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -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 */