From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/win32u/class.c | 11 ++++++----- server/class.c | 7 +++++++ server/protocol.def | 2 ++ server/user.h | 1 + server/window.c | 5 ++++- 5 files changed, 20 insertions(+), 6 deletions(-) diff --git a/dlls/win32u/class.c b/dlls/win32u/class.c index f65da58658c..43663797f4a 100644 --- a/dlls/win32u/class.c +++ b/dlls/win32u/class.c @@ -614,7 +614,7 @@ struct dce *set_class_dce( CLASS *class, struct dce *dce ) ATOM WINAPI NtUserRegisterClassExWOW( const WNDCLASSEXW *wc, UNICODE_STRING *name, UNICODE_STRING *version, struct client_menu_name *menu_name, DWORD fnid, DWORD flags, DWORD *wow ) { - const BOOL is_builtin = fnid, ansi = flags; + const BOOL ansi = flags; const shared_object_t *shared; struct obj_locator locator; HICON icon_internal; @@ -625,10 +625,10 @@ ATOM WINAPI NtUserRegisterClassExWOW( const WNDCLASSEXW *wc, UNICODE_STRING *nam BOOL ret; /* create the desktop window to trigger builtin class registration */ - if (!is_builtin) get_desktop_window(); + if (!fnid) get_desktop_window(); if (wc->cbSize != sizeof(*wc) || wc->cbClsExtra < 0 || wc->cbWndExtra < 0 || - (!is_builtin && wc->hInstance == user32_module)) /* we can't register a class for user32 */ + (!fnid && wc->hInstance == user32_module)) /* we can't register a class for user32 */ { RtlSetLastWin32Error( ERROR_INVALID_PARAMETER ); return 0; @@ -648,7 +648,7 @@ ATOM WINAPI NtUserRegisterClassExWOW( const WNDCLASSEXW *wc, UNICODE_STRING *nam if (!(class = calloc( 1, sizeof(*class) ))) return 0; - class->local = !is_builtin && !(wc->style & CS_GLOBALCLASS); + class->local = !fnid && !(wc->style & CS_GLOBALCLASS); /* Other non-null values must be set by caller */ icon_internal = wc->hIconSm ? 0 : create_small_icon( wc->hIcon ); @@ -673,6 +673,7 @@ ATOM WINAPI NtUserRegisterClassExWOW( const WNDCLASSEXW *wc, UNICODE_STRING *nam req->local = class->local; req->client_ptr = wine_server_client_ptr( class ); req->atom = wine_server_add_atom( req, name ); + req->fnid = fnid; req->name_offset = version->Length / sizeof(WCHAR); ret = !wine_server_call_err( req ); locator = reply->locator; @@ -1107,7 +1108,7 @@ static void register_builtin( enum ntuser_client_procs proc ) asciiz_to_unicode( nameW, descr->name ); RtlInitUnicodeString( &name, nameW ); - if ((descr->atom = NtUserRegisterClassExWOW( &class, &name, &version, NULL, 1, 0, NULL ))) return; + if ((descr->atom = NtUserRegisterClassExWOW( &class, &name, &version, NULL, MAKE_FNID(proc), 0, NULL ))) return; if (class.hCursor) NtUserDestroyCursor( class.hCursor, 0 ); } diff --git a/server/class.c b/server/class.c index 2ca94bca7be..fa84b363391 100644 --- a/server/class.c +++ b/server/class.c @@ -46,6 +46,7 @@ struct window_class int count; /* reference count */ int local; /* local class? */ atom_t atom; /* class atom for versioned class */ + unsigned int fnid; /* builtin control FNID, or 0 */ client_ptr_t client_ptr; /* pointer to class in client address space */ class_shm_t *shared; /* class in session shared memory */ }; @@ -159,6 +160,11 @@ atom_t get_class_atom( struct window_class *class ) return class->shared->info.atom; } +unsigned short get_class_fnid( struct window_class *class ) +{ + return class->fnid; +} + client_ptr_t get_class_client_ptr( struct window_class *class ) { return class->client_ptr; @@ -237,6 +243,7 @@ DECL_HANDLER(create_class) return; } class->atom = atom; + class->fnid = req->fnid; class->client_ptr = req->client_ptr; SHARED_WRITE_BEGIN( class->shared, class_shm_t ) diff --git a/server/protocol.def b/server/protocol.def index c2cfa64d86d..673383f7463 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -1067,6 +1067,7 @@ typedef volatile struct { struct obj_locator class; /* object locator for the window class shared object */ unsigned int dpi_context; /* DPI awareness context */ + unsigned int fnid; /* builtin class FNID, or 0 */ } window_shm_t; typedef volatile union @@ -3279,6 +3280,7 @@ enum caret_state @REQ(create_class) int local; /* is it a local class? */ atom_t atom; /* class atom */ + unsigned int fnid; /* FNID for builtin classes, or 0 */ client_ptr_t client_ptr; /* pointer to class in client address space */ data_size_t name_offset; /* base class name offset for specified atom */ VARARG(info,class_info); /* class info */ diff --git a/server/user.h b/server/user.h index 060e54ec775..a985283c31b 100644 --- a/server/user.h +++ b/server/user.h @@ -196,6 +196,7 @@ 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 short get_class_fnid( struct window_class *class ); 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 5d2966453bf..f6a91466e98 100644 --- a/server/window.c +++ b/server/window.c @@ -622,6 +622,7 @@ static struct window *create_window( struct window *parent, struct window *owner struct desktop *desktop; struct window_class *class; struct obj_locator class_locator; + unsigned int fnid; if (!(desktop = get_thread_desktop( current, DESKTOP_CREATEWINDOW ))) return NULL; @@ -630,6 +631,7 @@ static struct window *create_window( struct window *parent, struct window *owner release_object( desktop ); return NULL; } + fnid = get_class_fnid( class ); if (!parent) /* null parent is only allowed for desktop or HWND_MESSAGE top window */ { @@ -678,7 +680,7 @@ static struct window *create_window( struct window *parent, struct window *owner win->prop_inuse = 0; win->prop_alloc = 0; win->properties = NULL; - win->private_len = 0; + win->private_len = fnid ? extra_bytes : 0; win->nb_extra_bytes = 0; win->extra_bytes = NULL; win->shared = NULL; @@ -691,6 +693,7 @@ static struct window *create_window( struct window *parent, struct window *owner { shared->class = class_locator; shared->dpi_context = NTUSER_DPI_PER_MONITOR_AWARE; + shared->fnid = fnid; } SHARED_WRITE_END; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10999