Jacek Caban : wow64win: Implement more user callbacks.

Alexandre Julliard julliard at winehq.org
Tue Aug 16 16:02:11 CDT 2022


Module: wine
Branch: master
Commit: 6d8b1887a5e84dbda6c2abf778583d8397ab7dec
URL:    https://gitlab.winehq.org/wine/wine/-/commit/6d8b1887a5e84dbda6c2abf778583d8397ab7dec

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Tue Aug 16 14:22:21 2022 +0200

wow64win: Implement more user callbacks.

---

 dlls/user32/user_main.c |  25 ++++++++---
 dlls/win32u/font.c      |   4 +-
 dlls/win32u/message.c   |   1 +
 dlls/wow64win/user.c    | 115 +++++++++++++++++++++++++++++++++++++++++++++---
 include/ntuser.h        |   3 +-
 5 files changed, 134 insertions(+), 14 deletions(-)

diff --git a/dlls/user32/user_main.c b/dlls/user32/user_main.c
index bc817089e46..f16f8e04464 100644
--- a/dlls/user32/user_main.c
+++ b/dlls/user32/user_main.c
@@ -125,8 +125,17 @@ static NTSTATUS WINAPI User32DrawScrollBar( const struct draw_scroll_bar_params
 
 static NTSTATUS WINAPI User32DrawText( const struct draw_text_params *params, ULONG size )
 {
+    RECT rect = params->rect;
+    int ret;
+
     size -= FIELD_OFFSET( struct draw_text_params, str );
-    return DrawTextW( params->hdc, params->str, size / sizeof(WCHAR), params->rect, params->flags );
+    ret = DrawTextW( params->hdc, params->str, size / sizeof(WCHAR), &rect, params->flags );
+    if (params->ret_rect)
+    {
+        *params->ret_rect = rect;
+        return ret;
+    }
+    return NtCallbackReturn( &rect, sizeof(rect), ret );
 }
 
 static NTSTATUS WINAPI User32ImmProcessKey( const struct imm_process_key_params *params, ULONG size )
@@ -180,12 +189,16 @@ static BOOL WINAPI User32LoadDriver( const WCHAR *path, ULONG size )
 
 static NTSTATUS WINAPI User32UnpackDDEMessage( const struct unpack_dde_message_params *params, ULONG size )
 {
-    struct unpack_dde_message_result *result = params->result;
-    result->wparam = params->wparam;
-    result->lparam = params->lparam;
+    struct unpack_dde_message_result result = { .wparam = params->wparam, .lparam = params->lparam };
+
     size -= FIELD_OFFSET( struct unpack_dde_message_params, data );
-    return unpack_dde_message( params->hwnd, params->message, &result->wparam, &result->lparam,
-                               params->data, size );
+    if (!unpack_dde_message( params->hwnd, params->message, &result.wparam, &result.lparam,
+                             params->data, size ))
+        return FALSE;
+
+    if (params->result) *params->result = result;
+    else NtCallbackReturn( &result, sizeof(result), TRUE );
+    return TRUE;
 }
 
 static const void *kernel_callback_table[NtUserCallCount] =
diff --git a/dlls/win32u/font.c b/dlls/win32u/font.c
index 5ea89c9220e..e26c7bfa316 100644
--- a/dlls/win32u/font.c
+++ b/dlls/win32u/font.c
@@ -6610,10 +6610,12 @@ INT WINAPI DrawTextW( HDC hdc, const WCHAR *str, INT count, RECT *rect, UINT fla
     size = FIELD_OFFSET( struct draw_text_params, str[count] );
     if (!(params = malloc( size ))) return 0;
     params->hdc = hdc;
-    params->rect = rect;
+    params->rect = *rect;
+    params->ret_rect = rect;
     params->flags = flags;
     if (count) memcpy( params->str, str, count * sizeof(WCHAR) );
     ret = KeUserModeCallback( NtUserDrawText, params, size, &ret_ptr, &ret_len );
+    if (ret_len == sizeof(*rect)) *rect = *(const RECT *)ret_ptr;
     free( params );
     return ret;
 }
diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c
index 24e6dcf368c..f4f134e213b 100644
--- a/dlls/win32u/message.c
+++ b/dlls/win32u/message.c
@@ -2009,6 +2009,7 @@ static int peek_message( MSG *msg, HWND hwnd, UINT first, UINT last, UINT flags,
                 params->lparam  = info.msg.lParam;
                 if (size) memcpy( params->data, buffer, size );
                 ret = KeUserModeCallback( NtUserUnpackDDEMessage, params, len, &ret_ptr, &len );
+                if (len == sizeof(result)) result = *(struct unpack_dde_message_result *)ret_ptr;
                 free( params );
                 if (!ret) continue; /* ignore it */
                 info.msg.wParam = result.wparam;
diff --git a/dlls/wow64win/user.c b/dlls/wow64win/user.c
index 178b609e508..bb17e034eb2 100644
--- a/dlls/wow64win/user.c
+++ b/dlls/wow64win/user.c
@@ -287,6 +287,39 @@ struct win_proc_params32
     ULONG procW;
 };
 
+struct win_event_hook_params32
+{
+    DWORD event;
+    ULONG hwnd;
+    LONG object_id;
+    LONG child_id;
+    ULONG handle;
+    DWORD tid;
+    DWORD time;
+    ULONG proc;
+    WCHAR module[MAX_PATH];
+};
+
+struct draw_text_params32
+{
+    ULONG hdc;
+    int count;
+    RECT rect;
+    ULONG ret_rect;
+    UINT flags;
+    WCHAR str[1];
+};
+
+struct unpack_dde_message_params32
+{
+    ULONG result;
+    ULONG hwnd;
+    UINT message;
+    LONG wparam;
+    LONG lparam;
+    char data[1];
+};
+
 static MSG *msg_32to64( MSG *msg, const MSG32 *msg32 )
 {
     if (!msg32) return NULL;
@@ -480,8 +513,22 @@ static NTSTATUS WINAPI wow64_NtUserCallSendAsyncCallback( void *arg, ULONG size
 
 static NTSTATUS WINAPI wow64_NtUserCallWinEventHook( void *arg, ULONG size )
 {
-    FIXME( "\n" );
-    return 0;
+    struct win_event_hook_params *params = arg;
+    struct win_event_hook_params32 params32;
+
+    params32.event = params->event;
+    params32.hwnd = HandleToUlong( params->hwnd );
+    params32.object_id = params->object_id;
+    params32.child_id = params->child_id;
+    params32.handle = HandleToUlong( params->handle );
+    params32.tid = params->tid;
+    params32.time = params->time;
+    params32.proc = PtrToUlong( params->proc );
+
+    size -= FIELD_OFFSET( struct win_event_hook_params, module );
+    if (size) memcpy( params32.module, params->module, size );
+    return dispatch_callback( NtUserCallWinEventHook, &params32,
+                              FIELD_OFFSET( struct win_event_hook_params32, module ) + size);
 }
 
 static NTSTATUS WINAPI wow64_NtUserCallWinProc( void *arg, ULONG size )
@@ -766,8 +813,31 @@ static NTSTATUS WINAPI wow64_NtUserDrawScrollBar( void *arg, ULONG size )
 
 static NTSTATUS WINAPI wow64_NtUserDrawText( void *arg, ULONG size )
 {
-    FIXME( "\n" );
-    return 0;
+    struct draw_text_params *params = arg;
+    struct draw_text_params32 *params32;
+    RECT *rect_ptr = params->ret_rect;
+    ULONG ret_len, len;
+    void *ret_ptr;
+    NTSTATUS ret;
+
+    len = (size - FIELD_OFFSET( struct draw_text_params, str )) / sizeof(WCHAR);
+    if (!(params32 = Wow64AllocateTemp( FIELD_OFFSET( struct draw_text_params32, str[len] ))))
+        return 0;
+
+    params32->hdc = HandleToUlong( params->hdc );
+    params32->count = params->count;
+    params32->rect = params->rect;
+    params32->ret_rect = 0;
+    params32->flags = params->flags;
+    if (len) memcpy( params32->str, params->str, len * sizeof(WCHAR) );
+
+    ret = Wow64KiUserCallbackDispatcher( NtUserDrawText, params, size, &ret_ptr, &ret_len );
+    if (ret_len == sizeof(RECT) && rect_ptr)
+    {
+        *rect_ptr = *(const RECT *)ret_ptr;
+        return ret;
+    }
+    return NtCallbackReturn( ret_ptr, ret_len, ret );
 }
 
 static NTSTATUS WINAPI wow64_NtUserFreeCachedClipboardData( void *arg, ULONG size )
@@ -874,8 +944,41 @@ static NTSTATUS WINAPI wow64_NtUserRenderSynthesizedFormat( void *arg, ULONG siz
 
 static NTSTATUS WINAPI wow64_NtUserUnpackDDEMessage( void *arg, ULONG size )
 {
-    FIXME( "\n" );
-    return 0;
+    struct unpack_dde_message_params *params = arg;
+    struct unpack_dde_message_params32 *params32;
+    struct unpack_dde_message_result result;
+    struct
+    {
+        LONG wparam;
+        LONG lparam;
+    } *result32;
+    void *ret_ptr;
+    ULONG ret_len;
+
+    size -= FIELD_OFFSET( struct unpack_dde_message_params, data );
+    if (!(params32 = Wow64AllocateTemp( FIELD_OFFSET( struct unpack_dde_message_params32, data[size] ))))
+        return 0;
+
+    params32->result = 0;
+    params32->hwnd = HandleToUlong( params->hwnd );
+    params32->message = params->message;
+    params32->wparam = params->wparam;
+    params32->lparam = params->lparam;
+    if (size) memcpy( params32->data, params->data, size );
+    size = FIELD_OFFSET( struct unpack_dde_message_params32, data[size] );
+
+    if (!Wow64KiUserCallbackDispatcher( NtUserUnpackDDEMessage, params32, size, &ret_ptr, &ret_len ))
+        return FALSE;
+    if (ret_len == sizeof(*result32))
+    {
+        result32 = ret_ptr;
+        result.wparam = result32->wparam;
+        result.lparam = result32->lparam;
+    }
+
+    if (!params->result) NtCallbackReturn( &result, sizeof(result), TRUE );
+    *params->result = result;
+    return TRUE;
 }
 
 static NTSTATUS WINAPI wow64_NtUserCallFreeIcon( void *arg, ULONG size )
diff --git a/include/ntuser.h b/include/ntuser.h
index 7c375e43999..326d0371998 100644
--- a/include/ntuser.h
+++ b/include/ntuser.h
@@ -184,7 +184,8 @@ struct draw_text_params
 {
     HDC hdc;
     int count;
-    RECT *rect; /* FIXME: Use NtCallbackReturn instead */
+    RECT rect;
+    RECT *ret_rect; /* FIXME: Use NtCallbackReturn instead */
     UINT flags;
     WCHAR str[1];
 };




More information about the wine-cvs mailing list