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