From: Jacek Caban jacek@codeweavers.com
Its implementation doesn't seem to be exposed from win32u and it generally fits well in user space. It will be also useful for drivers.
Signed-off-by: Jacek Caban jacek@codeweavers.com --- dlls/user32/user_main.c | 8 +++++++- dlls/win32u/class.c | 30 +++++++++++++++--------------- dlls/win32u/cursoricon.c | 15 +++++++++++++++ dlls/win32u/defwnd.c | 16 ++++++++-------- dlls/win32u/ntuser_private.h | 1 - include/ntuser.h | 11 +++++++++++ 6 files changed, 56 insertions(+), 25 deletions(-)
diff --git a/dlls/user32/user_main.c b/dlls/user32/user_main.c index b282056d8c8..9cd9bd60146 100644 --- a/dlls/user32/user_main.c +++ b/dlls/user32/user_main.c @@ -159,7 +159,6 @@ static void CDECL free_win_ptr( WND *win )
static const struct user_callbacks user_funcs = { - CopyImage, EndMenu, ImmProcessKey, ImmTranslateMessage, @@ -176,6 +175,12 @@ static const struct user_callbacks user_funcs = unregister_imm, };
+static NTSTATUS WINAPI User32CopyImage( const struct copy_image_params *params, ULONG size ) +{ + HANDLE ret = CopyImage( params->hwnd, params->type, params->dx, params->dy, params->flags ); + return HandleToUlong( ret ); +} + static NTSTATUS WINAPI User32FreeCachedClipboardData( const struct free_cached_data_params *params, ULONG size ) { @@ -202,6 +207,7 @@ static const void *kernel_callback_table[NtUserCallCount] = User32CallWinEventHook, User32CallWindowProc, User32CallWindowsHook, + User32CopyImage, User32FreeCachedClipboardData, User32LoadDriver, User32RegisterBuiltinClasses, diff --git a/dlls/win32u/class.c b/dlls/win32u/class.c index fd74f63291a..1a6c92edc3a 100644 --- a/dlls/win32u/class.c +++ b/dlls/win32u/class.c @@ -444,11 +444,11 @@ ATOM WINAPI NtUserRegisterClassExWOW( const WNDCLASSEXW *wc, UNICODE_STRING *nam class->hbrBackground = wc->hbrBackground; class->winproc = alloc_winproc( wc->lpfnWndProc, ansi ); if (client_menu_name) class->menu_name = *client_menu_name; - if (wc->hIcon && !wc->hIconSm && user_callbacks) - class->hIconSmIntern = user_callbacks->pCopyImage( wc->hIcon, IMAGE_ICON, - get_system_metrics( SM_CXSMICON ), - get_system_metrics( SM_CYSMICON ), - LR_COPYFROMRESOURCE ); + if (wc->hIcon && !wc->hIconSm) + class->hIconSmIntern = CopyImage( wc->hIcon, IMAGE_ICON, + get_system_metrics( SM_CXSMICON ), + get_system_metrics( SM_CYSMICON ), + LR_COPYFROMRESOURCE ); release_class_ptr( class ); return atom; } @@ -699,20 +699,20 @@ static ULONG_PTR set_class_long( HWND hwnd, INT offset, LONG_PTR newval, UINT si NtUserDestroyCursor( class->hIconSmIntern, 0 ); class->hIconSmIntern = NULL; } - if (newval && !class->hIconSm && user_callbacks) - class->hIconSmIntern = user_callbacks->pCopyImage( (HICON)newval, IMAGE_ICON, - get_system_metrics( SM_CXSMICON ), - get_system_metrics( SM_CYSMICON ), - LR_COPYFROMRESOURCE ); + if (newval && !class->hIconSm) + class->hIconSmIntern = CopyImage( (HICON)newval, IMAGE_ICON, + get_system_metrics( SM_CXSMICON ), + get_system_metrics( SM_CYSMICON ), + LR_COPYFROMRESOURCE ); class->hIcon = (HICON)newval; break; case GCLP_HICONSM: retval = (ULONG_PTR)class->hIconSm; - if (retval && !newval && class->hIcon && user_callbacks) - class->hIconSmIntern = user_callbacks->pCopyImage( class->hIcon, IMAGE_ICON, - get_system_metrics( SM_CXSMICON ), - get_system_metrics( SM_CYSMICON ), - LR_COPYFROMRESOURCE ); + if (retval && !newval && class->hIcon) + class->hIconSmIntern = CopyImage( class->hIcon, IMAGE_ICON, + get_system_metrics( SM_CXSMICON ), + get_system_metrics( SM_CYSMICON ), + LR_COPYFROMRESOURCE ); else if (newval && class->hIconSmIntern) { NtUserDestroyCursor( class->hIconSmIntern, 0 ); diff --git a/dlls/win32u/cursoricon.c b/dlls/win32u/cursoricon.c index 0249eb3da50..032110b26d0 100644 --- a/dlls/win32u/cursoricon.c +++ b/dlls/win32u/cursoricon.c @@ -786,3 +786,18 @@ ULONG_PTR set_icon_param( HICON handle, ULONG_PTR param ) } return ret; } + +/****************************************************************************** + * CopyImage (win32u.so) + */ +HANDLE WINAPI CopyImage( HANDLE hwnd, UINT type, INT dx, INT dy, UINT flags ) +{ + void *ret_ptr; + ULONG ret_len; + NTSTATUS ret; + struct copy_image_params params = + { .hwnd = hwnd, .type = type, .dx = dx, .dy = dy, .flags = flags }; + + ret = KeUserModeCallback( NtUserCopyImage, ¶ms, sizeof(params), &ret_ptr, &ret_len ); + return UlongToHandle( ret ); +} diff --git a/dlls/win32u/defwnd.c b/dlls/win32u/defwnd.c index 7455a91980c..1fa80928c65 100644 --- a/dlls/win32u/defwnd.c +++ b/dlls/win32u/defwnd.c @@ -123,11 +123,11 @@ static HICON set_window_icon( HWND hwnd, WPARAM type, HICON icon ) { case ICON_SMALL: ret = win->hIconSmall; - if (ret && !icon && win->hIcon && user_callbacks) + if (ret && !icon && win->hIcon) { - win->hIconSmall2 = user_callbacks->pCopyImage( win->hIcon, IMAGE_ICON, - get_system_metrics( SM_CXSMICON ), - get_system_metrics( SM_CYSMICON ), 0 ); + win->hIconSmall2 = CopyImage( win->hIcon, IMAGE_ICON, + get_system_metrics( SM_CXSMICON ), + get_system_metrics( SM_CYSMICON ), 0 ); } else if (icon && win->hIconSmall2) { @@ -144,11 +144,11 @@ static HICON set_window_icon( HWND hwnd, WPARAM type, HICON icon ) NtUserDestroyCursor( win->hIconSmall2, 0 ); win->hIconSmall2 = NULL; } - if (icon && !win->hIconSmall && user_callbacks) + if (icon && !win->hIconSmall) { - win->hIconSmall2 = user_callbacks->pCopyImage( icon, IMAGE_ICON, - get_system_metrics( SM_CXSMICON ), - get_system_metrics( SM_CYSMICON ), 0 ); + win->hIconSmall2 = CopyImage( icon, IMAGE_ICON, + get_system_metrics( SM_CXSMICON ), + get_system_metrics( SM_CYSMICON ), 0 ); } win->hIcon = icon; break; diff --git a/dlls/win32u/ntuser_private.h b/dlls/win32u/ntuser_private.h index 6e25e0ec0db..931c87a6e1c 100644 --- a/dlls/win32u/ntuser_private.h +++ b/dlls/win32u/ntuser_private.h @@ -32,7 +32,6 @@ struct hardware_msg_data;
struct user_callbacks { - HANDLE (WINAPI *pCopyImage)( HANDLE, UINT, INT, INT, UINT ); BOOL (WINAPI *pEndMenu)(void); BOOL (WINAPI *pImmProcessKey)(HWND, HKL, UINT, LPARAM, DWORD); BOOL (WINAPI *pImmTranslateMessage)(HWND, UINT, WPARAM, LPARAM); diff --git a/include/ntuser.h b/include/ntuser.h index bc44ac76d4e..a39fffaedf9 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -32,6 +32,7 @@ enum NtUserCallWinEventHook, NtUserCallWinProc, NtUserCallWindowsHook, + NtUserCopyImage, NtUserFreeCachedClipboardData, NtUserLoadDriver, NtUserRegisterBuiltinClasses, @@ -146,6 +147,16 @@ struct win_hook_params WCHAR module[MAX_PATH]; };
+/* NtUserCopyMessage params */ +struct copy_image_params +{ + HANDLE hwnd; + UINT type; + INT dx; + INT dy; + UINT flags; +}; + /* NtUserFreeCachedClipboardData params */ struct free_cached_data_params {