Jacek Caban : wow64win: Implement wow64_NtUserCallWinProc.

Alexandre Julliard julliard at winehq.org
Mon Aug 15 15:23:44 CDT 2022


Module: wine
Branch: master
Commit: 9f63cbc052e72bbe16398cf45c8a1a43dc27ed4f
URL:    https://gitlab.winehq.org/wine/wine/-/commit/9f63cbc052e72bbe16398cf45c8a1a43dc27ed4f

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Mon Aug 15 00:11:49 2022 +0200

wow64win: Implement wow64_NtUserCallWinProc.

---

 dlls/user32/winproc.c | 16 +++++++++----
 dlls/win32u/message.c |  1 +
 dlls/wow64win/user.c  | 65 +++++++++++++++++++++++++++++++++++++++++++++++++--
 3 files changed, 76 insertions(+), 6 deletions(-)

diff --git a/dlls/user32/winproc.c b/dlls/user32/winproc.c
index ab28eecb67c..a22262b037b 100644
--- a/dlls/user32/winproc.c
+++ b/dlls/user32/winproc.c
@@ -1176,12 +1176,13 @@ static BOOL unpack_message( HWND hwnd, UINT message, WPARAM *wparam, LPARAM *lpa
 
 BOOL WINAPI User32CallWindowProc( struct win_proc_params *params, ULONG size )
 {
+    LRESULT result, *result_ptr = params->result;
+    params->result = &result;
 
     if (params->needs_unpack)
     {
         char stack_buffer[128];
         void *buffer;
-        LRESULT result;
 
         if (size > sizeof(*params))
         {
@@ -1196,8 +1197,6 @@ BOOL WINAPI User32CallWindowProc( struct win_proc_params *params, ULONG size )
         if (!unpack_message( params->hwnd, params->msg, &params->wparam,
                              &params->lparam, &buffer, size ))
             return 0;
-        params->result = &result;
-
 
         dispatch_win_proc_params( params );
 
@@ -1206,7 +1205,16 @@ BOOL WINAPI User32CallWindowProc( struct win_proc_params *params, ULONG size )
         if (buffer != stack_buffer && buffer != params + 1)
             HeapFree( GetProcessHeap(), 0, buffer );
     }
-    else dispatch_win_proc_params( params );
+    else
+    {
+        dispatch_win_proc_params( params );
+        if (result_ptr)
+        {
+            *result_ptr = result;
+            return TRUE;
+        }
+        NtCallbackReturn( &result, sizeof(result), TRUE );
+    }
     return TRUE;
 }
 
diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c
index a19b6bab230..bc932c5c820 100644
--- a/dlls/win32u/message.c
+++ b/dlls/win32u/message.c
@@ -265,6 +265,7 @@ static BOOL dispatch_win_proc_params( struct win_proc_params *params, size_t siz
     thread_info->recursion_count++;
 
     KeUserModeCallback( NtUserCallWinProc, params, size, &ret_ptr, &ret_len );
+    if (ret_len == sizeof(*params->result)) *params->result = *(LRESULT *)ret_ptr;
 
     thread_info->recursion_count--;
     return TRUE;
diff --git a/dlls/wow64win/user.c b/dlls/wow64win/user.c
index 6aecdacda39..ef817025dda 100644
--- a/dlls/wow64win/user.c
+++ b/dlls/wow64win/user.c
@@ -152,6 +152,23 @@ struct client_menu_name32
     ULONG nameUS;
 };
 
+struct win_proc_params32
+{
+    ULONG func;
+    ULONG hwnd;
+    UINT msg;
+    ULONG wparam;
+    ULONG lparam;
+    ULONG result;
+    BOOL ansi;
+    BOOL ansi_dst;
+    BOOL needs_unpack;
+    enum wm_char_mapping mapping;
+    ULONG dpi_awareness;
+    ULONG procA;
+    ULONG procW;
+};
+
 static MSG *msg_32to64( MSG *msg, const MSG32 *msg32 )
 {
     if (!msg32) return NULL;
@@ -200,6 +217,24 @@ static struct client_menu_name32 *client_menu_name_64to32( const struct client_m
     return name32;
 }
 
+static void win_proc_params_64to32( const struct win_proc_params *src, struct win_proc_params32 *dst,
+                                    ULONG *result )
+{
+    dst->func = PtrToUlong( src->func );
+    dst->hwnd = HandleToUlong( src->hwnd );
+    dst->msg = src->msg;
+    dst->wparam = src->wparam;
+    dst->lparam = src->lparam;
+    dst->result = PtrToUlong( result );
+    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 );
+}
+
 static NTSTATUS dispatch_callback( ULONG id, void *args, ULONG len )
 {
     void *ret_ptr;
@@ -256,8 +291,34 @@ static NTSTATUS WINAPI wow64_NtUserCallWinEventHook( void *arg, ULONG size )
 
 static NTSTATUS WINAPI wow64_NtUserCallWinProc( void *arg, ULONG size )
 {
-    FIXME( "\n" );
-    return 0;
+    struct win_proc_params *params = arg;
+    struct win_proc_params32 params32_buf, *params32 = &params32_buf;
+    LONG result32 = 0;
+    LRESULT result;
+    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, NULL );
+
+    status = Wow64KiUserCallbackDispatcher( NtUserCallWinProc, params32,
+                                            size - sizeof(*params) + sizeof(*params32),
+                                            &ret_ptr, &ret_len );
+    if (ret_len == sizeof(result32)) result32 = *(LONG *)ret_ptr;
+    result = result32;
+
+    if (params->result)
+    {
+        *params->result = result;
+        return status;
+    }
+    return NtCallbackReturn( &result, sizeof(result), status );
 }
 
 static NTSTATUS WINAPI wow64_NtUserCallWindowsHook( void *arg, ULONG size )




More information about the wine-cvs mailing list