Jacek Caban : wow64win: Implement NtUserCallWindowsHook thunk.
Alexandre Julliard
julliard at winehq.org
Tue Aug 16 16:02:11 CDT 2022
Module: wine
Branch: master
Commit: 57d66ecc5ff2d7fd78628c74d81c4e6c1a4469c5
URL: https://gitlab.winehq.org/wine/wine/-/commit/57d66ecc5ff2d7fd78628c74d81c4e6c1a4469c5
Author: Jacek Caban <jacek at codeweavers.com>
Date: Tue Aug 16 13:23:21 2022 +0200
wow64win: Implement NtUserCallWindowsHook thunk.
---
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 )
More information about the wine-cvs
mailing list