From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/win32u/window.c | 1 - server/class.c | 14 +++++++++++--- server/protocol.def | 1 - server/user.h | 4 ++-- server/window.c | 20 ++++++++++++-------- 5 files changed, 25 insertions(+), 15 deletions(-) diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index 4b53686dba1..3e47becca16 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -1594,7 +1594,6 @@ BOOL WINAPI NtUserSetWindowFNID( HWND hwnd, WORD fnid ) { req->handle = wine_server_user_handle( hwnd ); req->atom = get_builtin_class_atom( fnid & 0x7fff ); - req->fnid = fnid; ret = !wine_server_call_err( req ); } SERVER_END_REQ; diff --git a/server/class.c b/server/class.c index 39a6ec6b818..e505fa46e58 100644 --- a/server/class.c +++ b/server/class.c @@ -116,14 +116,12 @@ static struct window_class *find_class( struct process *process, atom_t atom, mo return NULL; } -struct window_class *grab_class( struct process *process, atom_t atom, mod_handle_t instance, - int *extra_bytes, struct obj_locator *locator ) +struct window_class *grab_class( struct process *process, atom_t atom, mod_handle_t instance, struct obj_locator *locator ) { struct window_class *class = find_class( process, atom, instance ); if (class) { class->count++; - *extra_bytes = class->shared->info.win_extra; *locator = get_shared_object_locator( class->shared ); } else set_error( STATUS_INVALID_HANDLE ); @@ -160,6 +158,16 @@ atom_t get_class_atom( struct window_class *class ) return class->shared->info.atom; } +unsigned int get_class_fnid( struct window_class *class, data_size_t *extra_size, data_size_t *private_size ) +{ + *extra_size = class->shared->info.win_extra; + + if ((class->fnid & ~0x7fff) != 0x8000) *private_size = 0; + else *private_size = *extra_size; + + return class->fnid; +} + client_ptr_t get_class_client_ptr( struct window_class *class ) { return class->client_ptr; diff --git a/server/protocol.def b/server/protocol.def index f8b3de0d604..e7d966613ac 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -2699,7 +2699,6 @@ enum message_type @REQ(set_window_fnid) user_handle_t handle; /* handle to the window */ atom_t atom; /* class atom */ - unsigned int fnid; /* builtin class FNID */ @END diff --git a/server/user.h b/server/user.h index 060e54ec775..844e31f0386 100644 --- a/server/user.h +++ b/server/user.h @@ -189,13 +189,13 @@ extern struct window_class *get_window_class( user_handle_t window ); /* window class functions */ extern void destroy_process_classes( struct process *process ); -extern struct window_class *grab_class( struct process *process, atom_t atom, mod_handle_t instance, - int *extra_bytes, struct obj_locator *locator ); +extern struct window_class *grab_class( struct process *process, atom_t atom, mod_handle_t instance, struct obj_locator *locator ); extern void release_class( struct window_class *class ); extern int is_desktop_class( struct window_class *class ); extern int is_message_class( struct window_class *class ); extern int get_class_style( struct window_class *class ); extern atom_t get_class_atom( struct window_class *class ); +extern unsigned int get_class_fnid( struct window_class *class, data_size_t *extra_size, data_size_t *private_size ); extern client_ptr_t get_class_client_ptr( struct window_class *class ); /* windows station functions */ diff --git a/server/window.c b/server/window.c index 3fa71fc3f1c..72637901a0c 100644 --- a/server/window.c +++ b/server/window.c @@ -616,7 +616,7 @@ void post_desktop_message( struct desktop *desktop, unsigned int message, static struct window *create_window( struct window *parent, struct window *owner, atom_t atom, mod_handle_t class_instance, mod_handle_t instance ) { - int extra_bytes; + data_size_t extra_bytes, private_size; struct window *win = NULL; struct desktop *desktop; struct window_class *class; @@ -624,11 +624,12 @@ static struct window *create_window( struct window *parent, struct window *owner if (!(desktop = get_thread_desktop( current, DESKTOP_CREATEWINDOW ))) return NULL; - if (!(class = grab_class( current->process, atom, class_instance, &extra_bytes, &class_locator ))) + if (!(class = grab_class( current->process, atom, class_instance, &class_locator ))) { release_object( desktop ); return NULL; } + get_class_fnid( class, &extra_bytes, &private_size ); if (!parent) /* null parent is only allowed for desktop or HWND_MESSAGE top window */ { @@ -2279,20 +2280,23 @@ DECL_HANDLER(create_window) /* Set the window builtin class FNID */ DECL_HANDLER(set_window_fnid) { + data_size_t extra_bytes, private_size; struct obj_locator class_locator; struct window_class *class; struct window *win; - int extra_bytes; + unsigned int fnid; if (!(win = get_window( req->handle ))) return; if (is_desktop_window( win ) && win->thread != current) return set_error( STATUS_ACCESS_DENIED ); - if (win->shared->fnid && win->shared->fnid != req->fnid) 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 ) + if (!(class = grab_class( current->process, req->atom, 0, &class_locator ))) return; + fnid = get_class_fnid( class, &extra_bytes, &private_size ); + + if (win->shared->fnid && win->shared->fnid != fnid) set_error( STATUS_INVALID_PARAMETER ); + else SHARED_WRITE_BEGIN( win->shared, window_shm_t ) { - shared->fnid = req->fnid; - shared->private_size = extra_bytes; + shared->fnid = fnid; + shared->private_size = private_size; } SHARED_WRITE_END; release_class( class ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11044