From: Torge Matthies tmatthies@codeweavers.com
Signed-off-by: Torge Matthies tmatthies@codeweavers.com --- dlls/user32/user32.spec | 5 +++++ dlls/user32/user_main.c | 35 +++++++++++++++++++++++++++++++++++ dlls/wow64win/user.c | 24 ++++++++++++++++++++++++ include/ntuser.h | 22 ++++++++++++++++++++++ 4 files changed, 86 insertions(+)
diff --git a/dlls/user32/user32.spec b/dlls/user32/user32.spec index 1bf3ebdc90d..73b810bc035 100644 --- a/dlls/user32/user32.spec +++ b/dlls/user32/user32.spec @@ -831,3 +831,8 @@ @ varargs wsprintfW(wstr wstr) @ stdcall wvsprintfA(ptr str ptr) @ stdcall wvsprintfW(ptr wstr ptr) + +################################################################ +# Wine internal extensions + +@ cdecl __wine_set_user32_callback_table(long ptr long) diff --git a/dlls/user32/user_main.c b/dlls/user32/user_main.c index 963f07b70ef..0de165ec68c 100644 --- a/dlls/user32/user_main.c +++ b/dlls/user32/user_main.c @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
+#include "ntstatus.h" +#define WIN32_NO_STATUS #include "user_private.h" #include "controls.h" #include "imm.h" @@ -192,6 +194,23 @@ static NTSTATUS WINAPI User32UnpackDDEMessage( const struct unpack_dde_message_p return TRUE; }
+struct dispatch_callback_table +{ + ULONG num_callbacks; + const user32_callback_func *callbacks; +} user32_callback_tables[user32_callback_destination_count]; + +static NTSTATUS WINAPI User32DispatchCallback( const struct user32_callback_params *params, ULONG size ) +{ + struct dispatch_callback_table *table; + if (!params || size < sizeof(*params) || params->destination >= user32_callback_destination_count) + return STATUS_INVALID_PARAMETER; + table = &user32_callback_tables[params->destination]; + if (!table || params->id >= table->num_callbacks) + return STATUS_INVALID_PARAMETER; + return table->callbacks[params->id]( params->args, params->len ); +} + static const void *kernel_callback_table[NtUserCallCount] = { User32CallEnumDisplayMonitor, @@ -212,9 +231,25 @@ static const void *kernel_callback_table[NtUserCallCount] = User32PostDDEMessage, User32RenderSsynthesizedFormat, User32UnpackDDEMessage, + User32DispatchCallback, };
+/********************************************************************** + * __wine_set_user32_callback_table (user32.@) + */ +BOOL CDECL __wine_set_user32_callback_table( enum user32_callback_destination destination, + const user32_callback_func *callbacks, ULONG count ) +{ + if (destination >= user32_callback_destination_count || !callbacks || + user32_callback_tables[destination].callbacks) + return FALSE; + user32_callback_tables[destination].num_callbacks = count; + user32_callback_tables[destination].callbacks = callbacks; + return TRUE; +} + + /*********************************************************************** * USER initialisation routine */ diff --git a/dlls/wow64win/user.c b/dlls/wow64win/user.c index 041285fa37f..d4043ef3e52 100644 --- a/dlls/wow64win/user.c +++ b/dlls/wow64win/user.c @@ -328,6 +328,14 @@ struct unpack_dde_message_params32 char data[1]; };
+struct user32_callback_params32 +{ + enum user32_callback_destination destination; + ULONG id; + ULONG args; + ULONG len; +}; + static MSG *msg_32to64( MSG *msg, const MSG32 *msg32 ) { if (!msg32) return NULL; @@ -986,6 +994,21 @@ static NTSTATUS WINAPI wow64_NtUserUnpackDDEMessage( void *arg, ULONG size ) return TRUE; }
+static NTSTATUS WINAPI wow64_NtUserDispatchCallback( void *arg, ULONG size ) +{ + struct user32_callback_params *params = arg; + struct user32_callback_params32 params32; + + if (!params || size < sizeof(*params) || (ULONG)params->args != (ULONG_PTR)params->args) + return STATUS_INVALID_PARAMETER; + + params32.destination = params->destination; + params32.id = params->id; + params32.args = (ULONG)params->args; + params32.len = params->len; + return dispatch_callback( NtUserDispatchCallback, ¶ms32, sizeof(params32) ); +} + static NTSTATUS WINAPI wow64_NtUserCallFreeIcon( void *arg, ULONG size ) { return dispatch_callback( NtUserCallFreeIcon, arg, size ); @@ -1079,6 +1102,7 @@ user_callback user_callbacks[] = wow64_NtUserPostDDEMessage, wow64_NtUserRenderSynthesizedFormat, wow64_NtUserUnpackDDEMessage, + wow64_NtUserDispatchCallback, /* win16 hooks */ wow64_NtUserCallFreeIcon, wow64_NtUserThunkLock, diff --git a/include/ntuser.h b/include/ntuser.h index d724ccad103..a60dd98f1d3 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -46,6 +46,7 @@ enum NtUserPostDDEMessage, NtUserRenderSynthesizedFormat, NtUserUnpackDDEMessage, + NtUserDispatchCallback, /* win16 hooks */ NtUserCallFreeIcon, NtUserThunkLock, @@ -267,6 +268,27 @@ struct unpack_dde_message_params char data[1]; };
+enum user32_callback_destination +{ + user32_callback_destination_user16, + user32_callback_destination_vulkan, + user32_callback_destination_driver, + user32_callback_destination_count +}; + +struct user32_callback_params +{ + enum user32_callback_destination destination; + ULONG id; + void *args; + ULONG len; +}; + +typedef NTSTATUS (WINAPI *user32_callback_func)( void *args, ULONG len ); + +extern BOOL CDECL __wine_set_user32_callback_table( enum user32_callback_destination destination, + const user32_callback_func *callbacks, ULONG count ); + /* process DPI awareness contexts */ #define NTUSER_DPI_UNAWARE 0x00006010 #define NTUSER_DPI_SYSTEM_AWARE 0x00006011