From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/win32u/class.c | 4 ++-- dlls/win32u/ntuser_private.h | 2 +- dlls/win32u/window.c | 18 ++++-------------- include/ntuser.h | 1 - server/protocol.def | 7 +++++++ server/window.c | 30 ++++++++++++++++++++++-------- 6 files changed, 36 insertions(+), 26 deletions(-) diff --git a/dlls/win32u/class.c b/dlls/win32u/class.c index f65da58658c..1bde8453ace 100644 --- a/dlls/win32u/class.c +++ b/dlls/win32u/class.c @@ -1073,10 +1073,10 @@ WORD get_class_word( HWND hwnd, INT offset ) return get_class_long_size( hwnd, offset, sizeof(WORD), TRUE ); } -DWORD get_builtin_class_extra( enum ntuser_client_procs proc ) +ATOM get_builtin_class_atom( enum ntuser_client_procs proc ) { get_desktop_window(); /* create the desktop window to trigger builtin class registration */ - return builtin_classes[proc].extra; + return builtin_classes[proc].atom; } /*********************************************************************** diff --git a/dlls/win32u/ntuser_private.h b/dlls/win32u/ntuser_private.h index 432d2af9abd..98ed3afd852 100644 --- a/dlls/win32u/ntuser_private.h +++ b/dlls/win32u/ntuser_private.h @@ -197,7 +197,7 @@ struct dce *set_class_dce( struct tagCLASS *class, struct dce *dce ); extern atom_t wine_server_add_atom( void *req, UNICODE_STRING *str ); extern BOOL is_desktop_class( UNICODE_STRING *name ); extern BOOL is_message_class( UNICODE_STRING *name ); -extern DWORD get_builtin_class_extra( enum ntuser_client_procs proc ); +extern ATOM get_builtin_class_atom( enum ntuser_client_procs proc ); extern void register_builtin_classes(void); extern void register_desktop_class(void); diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index bee254005cb..5262be4c149 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -1567,33 +1567,23 @@ LONG_PTR set_window_long( HWND hwnd, INT offset, UINT size, LONG_PTR newval, BOO */ BOOL WINAPI NtUserSetWindowFNID( HWND hwnd, WORD fnid ) { - DWORD len = get_builtin_class_extra( fnid & 0x7fff ); - WND *win; BOOL ret; TRACE( "%p %x\n", hwnd, fnid ); - if (!(win = get_win_ptr( hwnd ))) + if (!(fnid & 0x8000) || (fnid & 0x7fff) >= NTUSER_NB_PROCS) { - RtlSetLastWin32Error( ERROR_INVALID_WINDOW_HANDLE ); - return FALSE; - } - - if (win == WND_DESKTOP || win == WND_OTHER_PROCESS) - { - RtlSetLastWin32Error( ERROR_ACCESS_DENIED ); + RtlSetLastWin32Error( ERROR_INVALID_PARAMETER ); return FALSE; } - SERVER_START_REQ( set_window_info ) + SERVER_START_REQ( set_window_fnid ) { req->handle = wine_server_user_handle( hwnd ); - req->offset = GWLP_FNID_INTERNAL; - req->new_info = len; + req->atom = get_builtin_class_atom( fnid & 0x7fff ); ret = !wine_server_call_err( req ); } SERVER_END_REQ; - release_win_ptr( win ); return ret; } diff --git a/include/ntuser.h b/include/ntuser.h index 846f75b7975..2bbf77a4cf1 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -658,7 +658,6 @@ enum wine_internal_message #define IMN_WINE_SET_COMP_STRING 0x0010 /* not compatible with Windows */ -#define GWLP_FNID_INTERNAL (-1000) #define MAKE_FNID(index) ((WORD)(0x8000 | (index))) /* builtin IME driver calls */ diff --git a/server/protocol.def b/server/protocol.def index c6b4937ca3c..c24eb3d9e11 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -2694,6 +2694,13 @@ enum message_type @END +/* Set the window builtin class FNID */ +@REQ(set_window_fnid) + user_handle_t handle; /* handle to the window */ + atom_t atom; /* class atom */ +@END + + /* Set the parent of a window */ @REQ(set_parent) user_handle_t handle; /* handle to the window */ diff --git a/server/window.c b/server/window.c index 0f19ccb87ee..9d0568130f8 100644 --- a/server/window.c +++ b/server/window.c @@ -2275,6 +2275,28 @@ DECL_HANDLER(create_window) } +/* Set the window builtin class FNID */ +DECL_HANDLER(set_window_fnid) +{ + struct obj_locator class_locator; + struct window_class *class; + struct window *win; + int extra_bytes; + + if (!(win = get_window( req->handle ))) return; + if (is_desktop_window( win ) && win->thread != current) return set_error( STATUS_ACCESS_DENIED ); + if (win->shared->private_size) return set_error( STATUS_INVALID_PARAMETER ); + + if (!(class = grab_class( current->process, req->atom, 0, &extra_bytes, &class_locator ))) return; + SHARED_WRITE_BEGIN( win->shared, window_shm_t ) + { + shared->private_size = extra_bytes; + } + SHARED_WRITE_END; + release_class( class ); +} + + /* set the parent of a window */ DECL_HANDLER(set_parent) { @@ -2465,14 +2487,6 @@ DECL_HANDLER(set_window_info) reply->old_info = win->user_data; win->user_data = req->new_info; break; - case GWLP_FNID_INTERNAL: - if (win->shared->private_size) set_error( STATUS_INVALID_PARAMETER ); - else SHARED_WRITE_BEGIN( win->shared, window_shm_t ) - { - shared->private_size = req->new_info; - } - SHARED_WRITE_END; - break; default: if (req->size > sizeof(req->new_info) || req->offset < 0 || req->offset > win->nb_extra_bytes - (int)req->size) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10999