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, ¶ms->wparam,
¶ms->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 = ¶ms32_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