From: Rémi Bernon rbernon@codeweavers.com
And use it for User16CallFreeIcon.
Based on a patch from Torge Matthies. --- dlls/user.exe16/message.c | 9 --------- dlls/user.exe16/user.c | 13 +++++++++++-- dlls/user32/user_main.c | 8 ++++++++ dlls/win32u/cursoricon.c | 2 +- dlls/wow64win/user.c | 8 ++++---- dlls/wow64win/wow64win_private.h | 4 ++-- include/ntuser.h | 23 ++++++++++++++++++++--- include/wine/unixlib.h | 1 - 8 files changed, 46 insertions(+), 22 deletions(-)
diff --git a/dlls/user.exe16/message.c b/dlls/user.exe16/message.c index 0334aba28e4..fb4950c6121 100644 --- a/dlls/user.exe16/message.c +++ b/dlls/user.exe16/message.c @@ -2583,14 +2583,6 @@ HWND create_window16( CREATESTRUCTW *cs, LPCWSTR className, HINSTANCE instance, }
-static NTSTATUS WINAPI User16CallFreeIcon( void *args, ULONG size ) -{ - const struct free_icon_params *params = args; - GlobalFree16( LOWORD(params->param) ); - return STATUS_SUCCESS; -} - - static NTSTATUS WINAPI User16ThunkLock( void *args, ULONG size ) { const struct thunk_lock_params *params = args; @@ -2618,7 +2610,6 @@ void register_wow_handlers(void) call_dialog_proc_Ato16, };
- callback_table[NtUserCallFreeIcon] = User16CallFreeIcon; callback_table[NtUserThunkLock] = User16ThunkLock;
NtUserEnableThunkLock( TRUE ); diff --git a/dlls/user.exe16/user.c b/dlls/user.exe16/user.c index ef3ccc8a9da..799e4e35411 100644 --- a/dlls/user.exe16/user.c +++ b/dlls/user.exe16/user.c @@ -26,6 +26,8 @@
#define OEMRESOURCE
+#include "ntstatus.h" +#define WIN32_NO_STATUS #include "wine/winuser16.h" #include "windef.h" #include "winbase.h" @@ -287,6 +289,13 @@ static void release_icon_ptr( HICON16 handle, CURSORICONINFO *ptr ) GlobalUnlock16( handle ); }
+static NTSTATUS WINAPI free_icon_callback( void *args, ULONG size ) +{ + const struct free_icon_params *params = args; + GlobalFree16( LOWORD(params->param) ); + return STATUS_SUCCESS; +} + static HICON store_icon_32( HICON16 icon16, HICON icon ) { HICON ret = 0; @@ -300,7 +309,7 @@ static HICON store_icon_32( HICON16 icon16, HICON icon ) { memcpy( &ret, (char *)(ptr + 1) + and_size + xor_size, sizeof(ret) ); memcpy( (char *)(ptr + 1) + and_size + xor_size, &icon, sizeof(icon) ); - NtUserSetIconParam( icon, icon16 ); + NtUserSetIconParam( icon, icon16, free_icon_callback ); } release_icon_ptr( icon16, ptr ); } @@ -342,7 +351,7 @@ HICON get_icon_32( HICON16 icon16 ) DeleteObject( iinfo.hbmMask ); DeleteObject( iinfo.hbmColor ); memcpy( (char *)(ptr + 1) + xor_size + and_size, &ret, sizeof(ret) ); - NtUserSetIconParam( ret, icon16 ); + NtUserSetIconParam( ret, icon16, free_icon_callback ); } } release_icon_ptr( icon16, ptr ); diff --git a/dlls/user32/user_main.c b/dlls/user32/user_main.c index ee4dbc190cd..03b88c07bed 100644 --- a/dlls/user32/user_main.c +++ b/dlls/user32/user_main.c @@ -215,8 +215,16 @@ static NTSTATUS WINAPI User32UnpackDDEMessage( void *args, ULONG size ) return NtCallbackReturn( &result, sizeof(result), STATUS_SUCCESS ); }
+static NTSTATUS WINAPI User32CallDispatchCallback( void *args, ULONG size ) +{ + struct dispatch_callback_params *params = args; + ntuser_callback callback = (void *)(UINT_PTR)params->callback; + return callback( params, size ); +} + static KERNEL_CALLBACK_PROC kernel_callback_table[NtUserCallCount] = { + User32CallDispatchCallback, User32CallEnumDisplayMonitor, User32CallSendAsyncCallback, User32CallWinEventHook, diff --git a/dlls/win32u/cursoricon.c b/dlls/win32u/cursoricon.c index 5f94fb3342e..fedd122eeed 100644 --- a/dlls/win32u/cursoricon.c +++ b/dlls/win32u/cursoricon.c @@ -213,7 +213,7 @@ static BOOL free_icon_handle( HICON handle ) } if (!IS_INTRESOURCE( obj->resname )) free( obj->resname ); free( obj ); - if (params.param) KeUserModeCallback( NtUserCallFreeIcon, ¶ms, sizeof(params), &ret_ptr, &ret_len ); + KeUserDispatchCallback( ¶ms.dispatch, sizeof(params), &ret_ptr, &ret_len ); user_driver->pDestroyCursorIcon( handle ); return TRUE; } diff --git a/dlls/wow64win/user.c b/dlls/wow64win/user.c index db0fed3d97d..f60db58e181 100644 --- a/dlls/wow64win/user.c +++ b/dlls/wow64win/user.c @@ -1445,9 +1445,9 @@ static NTSTATUS WINAPI wow64_NtUserUnpackDDEMessage( void *arg, ULONG size ) return status; }
-static NTSTATUS WINAPI wow64_NtUserCallFreeIcon( void *arg, ULONG size ) +static NTSTATUS WINAPI wow64_NtUserCallDispatchCallback( void *arg, ULONG size ) { - return dispatch_callback( NtUserCallFreeIcon, arg, size ); + return dispatch_callback( NtUserCallDispatchCallback, arg, size ); }
static NTSTATUS WINAPI wow64_NtUserThunkLock( void *arg, ULONG size ) @@ -1520,9 +1520,10 @@ static NTSTATUS WINAPI wow64_NtUserDriverCallbackFirst9( void *arg, ULONG size ) return dispatch_callback( NtUserDriverCallbackFirst + 9, arg, size ); }
-user_callback user_callbacks[] = +ntuser_callback user_callbacks[] = { /* user32 callbacks */ + wow64_NtUserCallDispatchCallback, wow64_NtUserCallEnumDisplayMonitor, wow64_NtUserCallSendAsyncCallback, wow64_NtUserCallWinEventHook, @@ -1543,7 +1544,6 @@ user_callback user_callbacks[] = wow64_NtUserRenderSynthesizedFormat, wow64_NtUserUnpackDDEMessage, /* win16 hooks */ - wow64_NtUserCallFreeIcon, wow64_NtUserThunkLock, /* Vulkan support */ wow64_NtUserCallVulkanDebugReportCallback, diff --git a/dlls/wow64win/wow64win_private.h b/dlls/wow64win/wow64win_private.h index a4fa1ad2a06..956e38636a9 100644 --- a/dlls/wow64win/wow64win_private.h +++ b/dlls/wow64win/wow64win_private.h @@ -22,13 +22,13 @@ #define __WOW64WIN_PRIVATE_H
#include "../win32u/win32syscalls.h" +#include "ntuser.h"
#define SYSCALL_ENTRY(id,name,_args) extern NTSTATUS WINAPI wow64_ ## name( UINT *args ); ALL_SYSCALLS32 #undef SYSCALL_ENTRY
-typedef NTSTATUS (WINAPI *user_callback)( void *params, ULONG size ); -extern user_callback user_callbacks[]; +extern ntuser_callback user_callbacks[];
struct object_attr64 { diff --git a/include/ntuser.h b/include/ntuser.h index 6a6c344e484..da7c2e53594 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -34,10 +34,14 @@ # endif #endif
+typedef NTSTATUS (WINAPI *ntuser_callback)( void *args, ULONG len ); +NTSYSAPI NTSTATUS KeUserModeCallback( ULONG id, const void *args, ULONG len, void **ret_ptr, ULONG *ret_len ); + /* KernelCallbackTable codes, not compatible with Windows */ enum { /* user32 callbacks */ + NtUserCallDispatchCallback, NtUserCallEnumDisplayMonitor, NtUserCallSendAsyncCallback, NtUserCallWinEventHook, @@ -58,7 +62,6 @@ enum NtUserRenderSynthesizedFormat, NtUserUnpackDDEMessage, /* win16 hooks */ - NtUserCallFreeIcon, NtUserThunkLock, /* Vulkan support */ NtUserCallVulkanDebugReportCallback, @@ -71,6 +74,19 @@ enum NtUserCallCount };
+/* NtUserCallDispatchCallback params */ +struct dispatch_callback_params +{ + UINT64 callback; +}; + +static inline NTSTATUS KeUserDispatchCallback( const struct dispatch_callback_params *params, ULONG len, + void **ret_ptr, ULONG *ret_len ) +{ + if (!params->callback) return STATUS_ENTRYPOINT_NOT_FOUND; + return KeUserModeCallback( NtUserCallDispatchCallback, params, len, ret_ptr, ret_len ); +} + /* TEB thread info, not compatible with Windows */ struct ntuser_thread_info { @@ -1102,12 +1118,13 @@ static inline BOOL NtUserSetCaretPos( int x, int y )
struct free_icon_params { + struct dispatch_callback_params dispatch; UINT64 param; };
-static inline UINT_PTR NtUserSetIconParam( HICON icon, ULONG_PTR param ) +static inline UINT_PTR NtUserSetIconParam( HICON icon, ULONG_PTR param, ntuser_callback callback ) { - struct free_icon_params params = {.param = param}; + struct free_icon_params params = {.dispatch = {.callback = (UINT_PTR)callback}, .param = param}; return NtUserCallTwoParam( HandleToUlong(icon), (UINT_PTR)¶ms, NtUserCallTwoParam_SetIconParam ); }
diff --git a/include/wine/unixlib.h b/include/wine/unixlib.h index 9a342fada73..7d8b6c59ab5 100644 --- a/include/wine/unixlib.h +++ b/include/wine/unixlib.h @@ -72,7 +72,6 @@ NTSYSAPI void ntdll_set_exception_jmp_buf( jmp_buf jmp );
NTSYSAPI BOOLEAN KeAddSystemServiceTable( ULONG_PTR *funcs, ULONG_PTR *counters, ULONG limit, BYTE *arguments, ULONG index ); -NTSYSAPI NTSTATUS KeUserModeCallback( ULONG id, const void *args, ULONG len, void **ret_ptr, ULONG *ret_len );
/* wide char string functions */