[PATCH v2 0/6] MR10959: win32u: Move remaining class info to the shared memory.
-- v2: win32u: Move window class menu names to the shared memory. win32u: Move window class icons to the shared memory. win32u: Move class cursor and background to shared memory. server: Move class window proc to the shared memory. server: Introduce a struct class_info to wrap window class info. server: Move shared memory initialization out of create_class. https://gitlab.winehq.org/wine/wine/-/merge_requests/10959
From: Rémi Bernon <rbernon@codeweavers.com> --- server/class.c | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/server/class.c b/server/class.c index 8598c231a03..a71ee0a332a 100644 --- a/server/class.c +++ b/server/class.c @@ -52,8 +52,7 @@ struct window_class C_ASSERT( sizeof(class_shm_t) == offsetof(class_shm_t, extra[0]) ); -static struct window_class *create_class( struct process *process, int local, struct unicode_str *name, unsigned int name_offset, - atom_t atom, mod_handle_t instance, unsigned int style, int cls_extra, int win_extra ) +static struct window_class *create_class( struct process *process, int local, int cls_extra ) { struct window_class *class; @@ -64,19 +63,6 @@ static struct window_class *create_class( struct process *process, int local, st class->local = local; if (!(class->shared = alloc_shared_object( offsetof(class_shm_t, extra[cls_extra]) ))) goto failed; - SHARED_WRITE_BEGIN( class->shared, class_shm_t ) - { - memcpy( (void *)shared->name, name->str, name->len ); - shared->name_offset = name_offset; - shared->name_len = name->len; - shared->atom = atom; - shared->instance = instance; - shared->style = style; - shared->win_extra = win_extra; - shared->cls_extra = cls_extra; - memset( (void *)shared->extra, 0, cls_extra ); - } - SHARED_WRITE_END; /* other fields are initialized by caller */ @@ -196,7 +182,7 @@ DECL_HANDLER(create_class) struct unicode_str name = get_req_unicode_str(); struct atom_table *table = get_user_atom_table(); atom_t atom = req->atom, base_atom; - unsigned int offset = 0; + unsigned int name_offset = 0; WCHAR buffer[16]; if (atom && !name.len) name = integral_atom_name( buffer, atom ); @@ -206,9 +192,9 @@ DECL_HANDLER(create_class) { struct unicode_str base = name; - offset = req->name_offset; - base.str += offset; - base.len -= offset * sizeof(WCHAR); + name_offset = req->name_offset; + base.str += name_offset; + base.len -= name_offset * sizeof(WCHAR); if (!(base_atom = add_atom( table, &base ))) { @@ -238,8 +224,7 @@ DECL_HANDLER(create_class) return; } - if (!(class = create_class( current->process, req->local, &name, offset, base_atom, - req->instance, req->style, req->cls_extra, req->win_extra ))) + if (!(class = create_class( current->process, req->local, req->cls_extra ))) { release_atom( table, atom ); release_atom( table, base_atom ); @@ -247,6 +232,21 @@ DECL_HANDLER(create_class) } class->atom = atom; class->client_ptr = req->client_ptr; + + SHARED_WRITE_BEGIN( class->shared, class_shm_t ) + { + memcpy( (void *)shared->name, name.str, name.len ); + shared->name_offset = name_offset; + shared->name_len = name.len; + shared->atom = base_atom; + shared->instance = req->instance; + shared->style = req->style; + shared->win_extra = req->win_extra; + shared->cls_extra = req->cls_extra; + memset( (void *)shared->extra, 0, req->cls_extra ); + } + SHARED_WRITE_END; + reply->locator = get_shared_object_locator( class->shared ); reply->atom = base_atom; } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10959
From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/win32u/class.c | 36 ++++++++++++++----------- server/class.c | 66 +++++++++++++++++++++++---------------------- server/protocol.def | 12 +++++---- server/trace.c | 11 ++++++++ tools/make_requests | 1 + 5 files changed, 73 insertions(+), 53 deletions(-) diff --git a/dlls/win32u/class.c b/dlls/win32u/class.c index 5140430c558..c0ed05834cb 100644 --- a/dlls/win32u/class.c +++ b/dlls/win32u/class.c @@ -452,7 +452,7 @@ static UINT_PTR get_class_instance( CLASS *class ) NTSTATUS status; while ((status = get_shared_class( class, &lock, &class_shm )) == STATUS_PENDING) - instance = class_shm->instance; + instance = class_shm->info.instance; if (status) return 0; return instance; } @@ -552,11 +552,15 @@ ATOM WINAPI NtUserRegisterClassExWOW( const WNDCLASSEXW *wc, UNICODE_STRING *nam user_lock(); SERVER_START_REQ( create_class ) { + struct class_info info = + { + .style = wc->style, + .instance = wine_server_client_ptr( instance ), + .cls_extra = wc->cbClsExtra, + .win_extra = wc->cbWndExtra, + }; + wine_server_add_data( req, &info, sizeof(info) ); req->local = class->local; - req->style = wc->style; - req->instance = wine_server_client_ptr( instance ); - req->cls_extra = wc->cbClsExtra; - req->win_extra = wc->cbWndExtra; req->client_ptr = wine_server_client_ptr( class ); req->atom = wine_server_add_atom( req, name ); req->name_offset = version->Length / sizeof(WCHAR); @@ -669,10 +673,10 @@ ATOM WINAPI NtUserGetClassInfoEx( HINSTANCE instance, UNICODE_STRING *name, WNDC { if (wc) { - wc->style = class_shm->style; + wc->style = class_shm->info.style; wc->lpfnWndProc = get_winproc( class->winproc, ansi ); - wc->cbClsExtra = class_shm->cls_extra; - wc->cbWndExtra = class_shm->win_extra; + wc->cbClsExtra = class_shm->info.cls_extra; + wc->cbWndExtra = class_shm->info.win_extra; wc->hInstance = (instance == user32_module) ? 0 : instance; wc->hIcon = class->hIcon; wc->hIconSm = class->hIconSm; @@ -681,9 +685,9 @@ ATOM WINAPI NtUserGetClassInfoEx( HINSTANCE instance, UNICODE_STRING *name, WNDC wc->lpszMenuName = (WCHAR *)class->menu_name; wc->lpszClassName = name->Buffer; } - atom = class_shm->atom; + atom = class_shm->info.atom; } - if (!wc->hIconSm) wc->hIconSm = class->icon_internal; + if (wc && !wc->hIconSm) wc->hIconSm = class->icon_internal; *menu_name = class->menu_name; release_class_ptr( class ); return status ? 0 : atom; @@ -918,13 +922,13 @@ static ULONG_PTR get_class_long_shm( HWND hwnd, INT offset, UINT size, BOOL ansi { switch (offset) { - case GCW_ATOM: ret = class_shm->atom; break; - case GCL_STYLE: ret = class_shm->style; break; - case GCL_CBCLSEXTRA: ret = class_shm->cls_extra; break; - case GCL_CBWNDEXTRA: ret = class_shm->win_extra; break; - case GCLP_HMODULE: ret = class_shm->instance; break; + case GCW_ATOM: ret = class_shm->info.atom; break; + case GCL_STYLE: ret = class_shm->info.style; break; + case GCL_CBCLSEXTRA: ret = class_shm->info.cls_extra; break; + case GCL_CBWNDEXTRA: ret = class_shm->info.win_extra; break; + case GCLP_HMODULE: ret = class_shm->info.instance; break; default: - valid = offset >= 0 && offset <= (INT)(class_shm->cls_extra - size); + valid = offset >= 0 && offset <= (INT)(class_shm->info.cls_extra - size); if (valid) memcpy( &ret, (char *)class_shm->extra + offset, size ); break; } diff --git a/server/class.c b/server/class.c index a71ee0a332a..a35b2904d76 100644 --- a/server/class.c +++ b/server/class.c @@ -81,7 +81,7 @@ static void destroy_class( struct window_class *class ) struct atom_table *table = get_user_atom_table(); release_atom( table, class->atom ); - release_atom( table, class->shared->atom ); + release_atom( table, class->shared->info.atom ); list_remove( &class->entry ); release_object( class->process ); if (class->shared) free_shared_object( class->shared ); @@ -108,9 +108,9 @@ static struct window_class *find_class( struct process *process, atom_t atom, mo { const class_shm_t *shared = class->shared; if (class->atom != atom) continue; - is_win16 = !(shared->instance >> 16); - if (!instance || !class->local || shared->instance == instance || - (!is_win16 && ((shared->instance & ~0xffff) == (instance & ~0xffff)))) return class; + is_win16 = !(shared->info.instance >> 16); + if (!instance || !class->local || shared->info.instance == instance || + (!is_win16 && ((shared->info.instance & ~0xffff) == (instance & ~0xffff)))) return class; } return NULL; } @@ -122,7 +122,7 @@ struct window_class *grab_class( struct process *process, atom_t atom, mod_handl if (class) { class->count++; - *extra_bytes = class->shared->win_extra; + *extra_bytes = class->shared->info.win_extra; *locator = get_shared_object_locator( class->shared ); } else set_error( STATUS_INVALID_HANDLE ); @@ -137,7 +137,7 @@ void release_class( struct window_class *class ) int is_desktop_class( struct window_class *class ) { - return (class->shared->atom == DESKTOP_ATOM && !class->local); + return (class->shared->info.atom == DESKTOP_ATOM && !class->local); } int is_message_class( struct window_class *class ) @@ -146,17 +146,17 @@ int is_message_class( struct window_class *class ) static const struct unicode_str name = { messageW, sizeof(messageW) }; struct atom_table *table = get_user_atom_table(); - return (!class->local && class->shared->atom == find_atom( table, &name )); + return (!class->local && class->shared->info.atom == find_atom( table, &name )); } int get_class_style( struct window_class *class ) { - return class->shared->style; + return class->shared->info.style; } atom_t get_class_atom( struct window_class *class ) { - return class->shared->atom; + return class->shared->info.atom; } client_ptr_t get_class_client_ptr( struct window_class *class ) @@ -181,10 +181,16 @@ DECL_HANDLER(create_class) struct window_class *class; struct unicode_str name = get_req_unicode_str(); struct atom_table *table = get_user_atom_table(); - atom_t atom = req->atom, base_atom; unsigned int name_offset = 0; + atom_t atom = req->atom; + struct class_info info; WCHAR buffer[16]; + if (name.len < sizeof(info)) return set_error( STATUS_INVALID_PARAMETER ); + memcpy( &info, name.str, sizeof(info) ); + name.str += sizeof(info) / sizeof(WCHAR); + name.len -= sizeof(info); + if (atom && !name.len) name = integral_atom_name( buffer, atom ); if (!atom && !(atom = add_atom( table, &name ))) return; @@ -196,7 +202,7 @@ DECL_HANDLER(create_class) base.str += name_offset; base.len -= name_offset * sizeof(WCHAR); - if (!(base_atom = add_atom( table, &base ))) + if (!(info.atom = add_atom( table, &base ))) { release_atom( table, atom ); return; @@ -204,30 +210,30 @@ DECL_HANDLER(create_class) } else { - base_atom = grab_atom( table, atom ); + info.atom = grab_atom( table, atom ); } - class = find_class( current->process, atom, req->instance ); + class = find_class( current->process, atom, info.instance ); if (class && !class->local == !req->local) { set_win32_error( ERROR_CLASS_ALREADY_EXISTS ); release_atom( table, atom ); - release_atom( table, base_atom ); + release_atom( table, info.atom ); return; } - if (req->cls_extra < 0 || req->cls_extra > 4096 || req->win_extra < 0 || req->win_extra > 4096) + if (info.cls_extra > 4096 || info.win_extra > 4096) { /* don't allow stupid values here */ set_error( STATUS_INVALID_PARAMETER ); release_atom( table, atom ); - release_atom( table, base_atom ); + release_atom( table, info.atom ); return; } - if (!(class = create_class( current->process, req->local, req->cls_extra ))) + if (!(class = create_class( current->process, req->local, info.cls_extra ))) { release_atom( table, atom ); - release_atom( table, base_atom ); + release_atom( table, info.atom ); return; } class->atom = atom; @@ -238,17 +244,13 @@ DECL_HANDLER(create_class) memcpy( (void *)shared->name, name.str, name.len ); shared->name_offset = name_offset; shared->name_len = name.len; - shared->atom = base_atom; - shared->instance = req->instance; - shared->style = req->style; - shared->win_extra = req->win_extra; - shared->cls_extra = req->cls_extra; - memset( (void *)shared->extra, 0, req->cls_extra ); + memcpy( (void *)&shared->info, &info, sizeof(info) ); + memset( (void *)shared->extra, 0, info.cls_extra ); } SHARED_WRITE_END; reply->locator = get_shared_object_locator( class->shared ); - reply->atom = base_atom; + reply->atom = info.atom; } /* destroy a window class */ @@ -291,8 +293,8 @@ DECL_HANDLER(set_class_info) switch (req->offset) { case GCL_STYLE: - reply->old_info = shared->style; - shared->style = req->new_info; + reply->old_info = shared->info.style; + shared->info.style = req->new_info; break; case GCL_CBWNDEXTRA: if (req->new_info > 4096) @@ -300,19 +302,19 @@ DECL_HANDLER(set_class_info) set_error( STATUS_INVALID_PARAMETER ); return; } - reply->old_info = shared->win_extra; - shared->win_extra = req->new_info; + reply->old_info = shared->info.win_extra; + shared->info.win_extra = req->new_info; break; case GCL_CBCLSEXTRA: set_win32_error( ERROR_INVALID_INDEX ); break; case GCLP_HMODULE: - reply->old_info = shared->instance; - shared->instance = req->new_info; + reply->old_info = shared->info.instance; + shared->info.instance = req->new_info; break; default: if (req->size > sizeof(req->new_info) || req->offset < 0 || - req->offset > class->shared->cls_extra - (int)req->size) + req->offset > class->shared->info.cls_extra - (int)req->size) { set_win32_error( ERROR_INVALID_INDEX ); return; diff --git a/server/protocol.def b/server/protocol.def index 3ee3be605d4..ad14f20ba47 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -1038,17 +1038,22 @@ typedef volatile struct unsigned __int64 keystate_serial; /* keystate update counter at last sync */ } input_shm_t; -typedef volatile struct +struct class_info { atom_t atom; /* class atom */ unsigned int style; /* class style */ unsigned int cls_extra; /* number of class extra bytes */ unsigned int win_extra; /* number of window extra bytes */ mod_handle_t instance; /* module instance */ +}; + +typedef volatile struct +{ data_size_t name_offset; /* offset in WCHAR of the unversioned class name, constant */ data_size_t name_len; /* len in bytes of the class name, constant */ WCHAR name[MAX_ATOM_LEN]; /* class name, constant */ unsigned short __pad; + struct class_info info; /* class info (GCLP_*) */ char extra[]; /* extra bytes storage */ } class_shm_t; @@ -3268,12 +3273,9 @@ enum caret_state @REQ(create_class) int local; /* is it a local class? */ atom_t atom; /* class atom */ - unsigned int style; /* class style */ - mod_handle_t instance; /* module instance */ client_ptr_t client_ptr; /* pointer to class in client address space */ - short int cls_extra; /* number of extra class bytes */ - short int win_extra; /* number of window extra bytes */ data_size_t name_offset; /* base class name offset for specified atom */ + VARARG(info,class_info); /* class info */ VARARG(name,unicode_str); /* class name */ @REPLY struct obj_locator locator; /* locator for the shared class object */ diff --git a/server/trace.c b/server/trace.c index c9812d818bd..9ed682156b1 100644 --- a/server/trace.c +++ b/server/trace.c @@ -1654,6 +1654,17 @@ static void dump_varargs_monitor_infos( const char *prefix, data_size_t size ) remove_data( size ); } +static void dump_varargs_class_info( const char *prefix, data_size_t size ) +{ + const struct class_info *info = cur_data; + + fprintf( stderr, "%s{atom=%#x,style=%#x,cls_extra=%u,win_extra=%u", + prefix, info->atom, info->style, info->cls_extra, info->win_extra ); + dump_uint64( ",instance=", &info->instance ); + fputc( '}', stderr ); + remove_data( sizeof(*info) ); +} + void trace_request(void) { enum request req = current->req.request_header.req; diff --git a/tools/make_requests b/tools/make_requests index 17e425537b5..b4849e5f605 100755 --- a/tools/make_requests +++ b/tools/make_requests @@ -68,6 +68,7 @@ my %formats = "struct thread_info" => [ 40, 8 ], "union udp_endpoint" => [ 32, 4 ], "struct user_apc" => [ 40, 8 ], + "struct class_info" => [ 24, 8 ], ); my $file_header = -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10959
From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/win32u/class.c | 31 +++++++++++++++++++------------ server/class.c | 4 ++++ server/protocol.def | 1 + server/trace.c | 1 + tools/make_requests | 2 +- 5 files changed, 26 insertions(+), 13 deletions(-) diff --git a/dlls/win32u/class.c b/dlls/win32u/class.c index c0ed05834cb..1ec80f458f5 100644 --- a/dlls/win32u/class.c +++ b/dlls/win32u/class.c @@ -47,7 +47,6 @@ typedef struct tagCLASS { struct list entry; /* Entry in class list */ BOOL local; /* Local class? */ - WNDPROC winproc; /* Window procedure */ struct dce *dce; /* Opaque pointer to class DCE */ HICON hIcon; /* Default icon */ HICON hIconSm; /* Default small icon */ @@ -485,7 +484,15 @@ static CLASS *find_class( HINSTANCE module, UNICODE_STRING *name ) */ WNDPROC get_class_winproc( CLASS *class ) { - return class->winproc; + struct object_lock lock = OBJECT_LOCK_INIT; + const class_shm_t *class_shm; + WNDPROC wndproc = NULL; + NTSTATUS status; + + while ((status = get_shared_class( class, &lock, &class_shm )) == STATUS_PENDING) + wndproc = wine_server_get_ptr( class_shm->info.wndproc ); + if (status) return 0; + return wndproc; } /*********************************************************************** @@ -517,6 +524,7 @@ ATOM WINAPI NtUserRegisterClassExWOW( const WNDCLASSEXW *wc, UNICODE_STRING *nam struct obj_locator locator; HICON icon_internal; HINSTANCE instance; + WNDPROC wndproc; CLASS *class; ATOM atom; BOOL ret; @@ -531,6 +539,7 @@ ATOM WINAPI NtUserRegisterClassExWOW( const WNDCLASSEXW *wc, UNICODE_STRING *nam return 0; } if (!(instance = wc->hInstance)) instance = RtlGetCurrentPeb()->ImageBaseAddress; + wndproc = alloc_winproc( wc->lpfnWndProc, ansi ); TRACE( "name=%s hinst=%p style=0x%x clExtr=0x%x winExtr=0x%x\n", debugstr_us(name), instance, wc->style, wc->cbClsExtra, wc->cbWndExtra ); @@ -555,9 +564,10 @@ ATOM WINAPI NtUserRegisterClassExWOW( const WNDCLASSEXW *wc, UNICODE_STRING *nam struct class_info info = { .style = wc->style, - .instance = wine_server_client_ptr( instance ), .cls_extra = wc->cbClsExtra, .win_extra = wc->cbWndExtra, + .instance = wine_server_client_ptr( instance ), + .wndproc = wine_server_client_ptr( wndproc ), }; wine_server_add_data( req, &info, sizeof(info) ); req->local = class->local; @@ -597,7 +607,6 @@ ATOM WINAPI NtUserRegisterClassExWOW( const WNDCLASSEXW *wc, UNICODE_STRING *nam class->icon_internal = icon_internal; class->hCursor = wc->hCursor; class->hbrBackground = wc->hbrBackground; - class->winproc = alloc_winproc( wc->lpfnWndProc, ansi ); class->menu_name = menu_name; class->shared = shared; release_class_ptr( class ); @@ -674,7 +683,7 @@ ATOM WINAPI NtUserGetClassInfoEx( HINSTANCE instance, UNICODE_STRING *name, WNDC if (wc) { wc->style = class_shm->info.style; - wc->lpfnWndProc = get_winproc( class->winproc, ansi ); + wc->lpfnWndProc = get_winproc( wine_server_get_ptr( class_shm->info.wndproc ), ansi ); wc->cbClsExtra = class_shm->info.cls_extra; wc->cbWndExtra = class_shm->info.win_extra; wc->hInstance = (instance == user32_module) ? 0 : instance; @@ -836,8 +845,9 @@ static ULONG_PTR set_class_long_size( HWND hwnd, INT offset, LONG_PTR newval, UI class->menu_name = (void *)newval; break; case GCLP_WNDPROC: - retval = (ULONG_PTR)get_winproc( class->winproc, ansi ); - class->winproc = alloc_winproc( (WNDPROC)newval, ansi ); + newval = (ULONG_PTR)alloc_winproc( (WNDPROC)newval, ansi ); + if (!set_server_info( hwnd, offset, newval, size, &retval )) break; + retval = (ULONG_PTR)get_winproc( (WNDPROC)retval, ansi ); break; case GCLP_HBRBACKGROUND: retval = (ULONG_PTR)class->hbrBackground; @@ -924,6 +934,7 @@ static ULONG_PTR get_class_long_shm( HWND hwnd, INT offset, UINT size, BOOL ansi { case GCW_ATOM: ret = class_shm->info.atom; break; case GCL_STYLE: ret = class_shm->info.style; break; + case GCLP_WNDPROC: ret = class_shm->info.wndproc; break; case GCL_CBCLSEXTRA: ret = class_shm->info.cls_extra; break; case GCL_CBWNDEXTRA: ret = class_shm->info.win_extra; break; case GCLP_HMODULE: ret = class_shm->info.instance; break; @@ -945,6 +956,7 @@ static ULONG_PTR get_class_long_shm( HWND hwnd, INT offset, UINT size, BOOL ansi return 0; } + if (offset == GCLP_WNDPROC) return (ULONG_PTR)get_winproc( (WNDPROC)ret, ansi ); return ret; } @@ -956,7 +968,6 @@ static ULONG_PTR get_class_long_size( HWND hwnd, INT offset, UINT size, BOOL ans switch (offset) { case GCLP_HICONSM: - case GCLP_WNDPROC: case GCLP_HICON: case GCLP_HCURSOR: case GCLP_HBRBACKGROUND: @@ -983,7 +994,6 @@ static ULONG_PTR get_class_long_size( HWND hwnd, INT offset, UINT size, BOOL ans case GCLP_HCURSOR: case GCLP_HICON: case GCLP_HICONSM: - case GCLP_WNDPROC: case GCLP_MENUNAME: FIXME( "offset %d not supported on other process window %p\n", offset, hwnd ); break; @@ -1011,9 +1021,6 @@ static ULONG_PTR get_class_long_size( HWND hwnd, INT offset, UINT size, BOOL ans case GCLP_HICONSM: retvalue = (ULONG_PTR)(class->hIconSm ? class->hIconSm : class->icon_internal); break; - case GCLP_WNDPROC: - retvalue = (ULONG_PTR)get_winproc( class->winproc, ansi ); - break; case GCLP_MENUNAME: retvalue = (ULONG_PTR)class->menu_name; break; diff --git a/server/class.c b/server/class.c index a35b2904d76..bb78cf26b44 100644 --- a/server/class.c +++ b/server/class.c @@ -312,6 +312,10 @@ DECL_HANDLER(set_class_info) reply->old_info = shared->info.instance; shared->info.instance = req->new_info; break; + case GCLP_WNDPROC: + reply->old_info = shared->info.wndproc; + shared->info.wndproc = req->new_info; + break; default: if (req->size > sizeof(req->new_info) || req->offset < 0 || req->offset > class->shared->info.cls_extra - (int)req->size) diff --git a/server/protocol.def b/server/protocol.def index ad14f20ba47..9632b8d424b 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -1045,6 +1045,7 @@ struct class_info unsigned int cls_extra; /* number of class extra bytes */ unsigned int win_extra; /* number of window extra bytes */ mod_handle_t instance; /* module instance */ + client_ptr_t wndproc; /* class window proc */ }; typedef volatile struct diff --git a/server/trace.c b/server/trace.c index 9ed682156b1..a3cc1f5aeec 100644 --- a/server/trace.c +++ b/server/trace.c @@ -1661,6 +1661,7 @@ static void dump_varargs_class_info( const char *prefix, data_size_t size ) fprintf( stderr, "%s{atom=%#x,style=%#x,cls_extra=%u,win_extra=%u", prefix, info->atom, info->style, info->cls_extra, info->win_extra ); dump_uint64( ",instance=", &info->instance ); + dump_uint64( ",wndproc=", &info->wndproc ); fputc( '}', stderr ); remove_data( sizeof(*info) ); } diff --git a/tools/make_requests b/tools/make_requests index b4849e5f605..e92fb10d8f9 100755 --- a/tools/make_requests +++ b/tools/make_requests @@ -68,7 +68,7 @@ my %formats = "struct thread_info" => [ 40, 8 ], "union udp_endpoint" => [ 32, 4 ], "struct user_apc" => [ 40, 8 ], - "struct class_info" => [ 24, 8 ], + "struct class_info" => [ 32, 8 ], ); my $file_header = -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10959
From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/win32u/class.c | 55 ++++++++++++++++----------------------------- server/class.c | 8 +++++++ server/protocol.def | 3 +++ server/trace.c | 5 +++-- tools/make_requests | 2 +- 5 files changed, 34 insertions(+), 39 deletions(-) diff --git a/dlls/win32u/class.c b/dlls/win32u/class.c index 1ec80f458f5..9559f6d5fdf 100644 --- a/dlls/win32u/class.c +++ b/dlls/win32u/class.c @@ -51,8 +51,6 @@ typedef struct tagCLASS HICON hIcon; /* Default icon */ HICON hIconSm; /* Default small icon */ HICON icon_internal; /* internal small icon, derived from hIcon */ - HCURSOR hCursor; /* Default cursor */ - HBRUSH hbrBackground; /* Default background */ struct client_menu_name *menu_name; /* Default menu name */ const shared_object_t *shared; /* class object in session shared memory */ } CLASS; @@ -566,6 +564,8 @@ ATOM WINAPI NtUserRegisterClassExWOW( const WNDCLASSEXW *wc, UNICODE_STRING *nam .style = wc->style, .cls_extra = wc->cbClsExtra, .win_extra = wc->cbWndExtra, + .cursor = wine_server_user_handle( wc->hCursor ), + .background = wine_server_user_handle( wc->hbrBackground ), .instance = wine_server_client_ptr( instance ), .wndproc = wine_server_client_ptr( wndproc ), }; @@ -605,8 +605,6 @@ ATOM WINAPI NtUserRegisterClassExWOW( const WNDCLASSEXW *wc, UNICODE_STRING *nam class->hIcon = wc->hIcon; class->hIconSm = wc->hIconSm; class->icon_internal = icon_internal; - class->hCursor = wc->hCursor; - class->hbrBackground = wc->hbrBackground; class->menu_name = menu_name; class->shared = shared; release_class_ptr( class ); @@ -627,6 +625,7 @@ BOOL WINAPI NtUserUnregisterClass( UNICODE_STRING *name, HINSTANCE instance, str { struct list drawables = LIST_INIT( drawables ); CLASS *class = NULL; + HBRUSH background; /* create the desktop window to trigger builtin class registration */ get_desktop_window(); @@ -637,7 +636,9 @@ BOOL WINAPI NtUserUnregisterClass( UNICODE_STRING *name, HINSTANCE instance, str { req->instance = wine_server_client_ptr( instance ); req->atom = wine_server_add_atom( req, name ); - if (!wine_server_call_err( req )) class = wine_server_get_ptr( reply->client_ptr ); + wine_server_call_err( req ); + class = wine_server_get_ptr( reply->client_ptr ); + background = wine_server_ptr_handle( reply->background ); } SERVER_END_REQ; if (!class) @@ -650,8 +651,8 @@ BOOL WINAPI NtUserUnregisterClass( UNICODE_STRING *name, HINSTANCE instance, str if (class->dce) free_dce( class->dce, 0, &drawables ); list_remove( &class->entry ); - if (class->hbrBackground > (HBRUSH)(COLOR_GRADIENTINACTIVECAPTION + 1)) - NtGdiDeleteObjectApp( class->hbrBackground ); + if (background > (HBRUSH)(COLOR_GRADIENTINACTIVECAPTION + 1)) + NtGdiDeleteObjectApp( background ); *menu_name = class->menu_name; NtUserDestroyCursor( class->icon_internal, 0 ); free( class ); @@ -689,8 +690,8 @@ ATOM WINAPI NtUserGetClassInfoEx( HINSTANCE instance, UNICODE_STRING *name, WNDC wc->hInstance = (instance == user32_module) ? 0 : instance; wc->hIcon = class->hIcon; wc->hIconSm = class->hIconSm; - wc->hCursor = class->hCursor; - wc->hbrBackground = class->hbrBackground; + wc->hCursor = wine_server_ptr_handle( class_shm->info.cursor ); + wc->hbrBackground = wine_server_ptr_handle( class_shm->info.background ); wc->lpszMenuName = (WCHAR *)class->menu_name; wc->lpszClassName = name->Buffer; } @@ -840,6 +841,13 @@ static ULONG_PTR set_class_long_size( HWND hwnd, INT offset, LONG_PTR newval, UI switch(offset) { + case GCL_CBWNDEXTRA: + case GCL_STYLE: + case GCLP_HBRBACKGROUND: + case GCLP_HCURSOR: + case GCLP_HMODULE: + set_server_info( hwnd, offset, newval, size, &retval ); + break; case GCLP_MENUNAME: retval = (ULONG_PTR)class->menu_name; class->menu_name = (void *)newval; @@ -849,14 +857,6 @@ static ULONG_PTR set_class_long_size( HWND hwnd, INT offset, LONG_PTR newval, UI if (!set_server_info( hwnd, offset, newval, size, &retval )) break; retval = (ULONG_PTR)get_winproc( (WNDPROC)retval, ansi ); break; - case GCLP_HBRBACKGROUND: - retval = (ULONG_PTR)class->hbrBackground; - class->hbrBackground = (HBRUSH)newval; - break; - case GCLP_HCURSOR: - retval = (ULONG_PTR)class->hCursor; - class->hCursor = (HCURSOR)newval; - break; case GCLP_HICON: retval = (ULONG_PTR)class->hIcon; if (retval == newval) break; @@ -867,15 +867,6 @@ static ULONG_PTR set_class_long_size( HWND hwnd, INT offset, LONG_PTR newval, UI if (retval == newval) break; class->hIconSm = (HICON)newval; break; - case GCL_STYLE: - if (!set_server_info( hwnd, offset, newval, size, &retval )) break; - break; - case GCL_CBWNDEXTRA: - if (!set_server_info( hwnd, offset, newval, size, &retval )) break; - break; - case GCLP_HMODULE: - if (!set_server_info( hwnd, offset, newval, size, &retval )) break; - break; case GCL_CBCLSEXTRA: /* cannot change this one */ RtlSetLastWin32Error( ERROR_INVALID_PARAMETER ); break; @@ -938,6 +929,8 @@ static ULONG_PTR get_class_long_shm( HWND hwnd, INT offset, UINT size, BOOL ansi case GCL_CBCLSEXTRA: ret = class_shm->info.cls_extra; break; case GCL_CBWNDEXTRA: ret = class_shm->info.win_extra; break; case GCLP_HMODULE: ret = class_shm->info.instance; break; + case GCLP_HCURSOR: ret = class_shm->info.cursor; break; + case GCLP_HBRBACKGROUND: ret = class_shm->info.background; break; default: valid = offset >= 0 && offset <= (INT)(class_shm->info.cls_extra - size); if (valid) memcpy( &ret, (char *)class_shm->extra + offset, size ); @@ -969,8 +962,6 @@ static ULONG_PTR get_class_long_size( HWND hwnd, INT offset, UINT size, BOOL ans { case GCLP_HICONSM: case GCLP_HICON: - case GCLP_HCURSOR: - case GCLP_HBRBACKGROUND: case GCLP_MENUNAME: break; default: @@ -990,8 +981,6 @@ static ULONG_PTR get_class_long_size( HWND hwnd, INT offset, UINT size, BOOL ans { switch (offset) { - case GCLP_HBRBACKGROUND: - case GCLP_HCURSOR: case GCLP_HICON: case GCLP_HICONSM: case GCLP_MENUNAME: @@ -1009,12 +998,6 @@ static ULONG_PTR get_class_long_size( HWND hwnd, INT offset, UINT size, BOOL ans switch(offset) { - case GCLP_HBRBACKGROUND: - retvalue = (ULONG_PTR)class->hbrBackground; - break; - case GCLP_HCURSOR: - retvalue = (ULONG_PTR)class->hCursor; - break; case GCLP_HICON: retvalue = (ULONG_PTR)class->hIcon; break; diff --git a/server/class.c b/server/class.c index bb78cf26b44..bac616e294c 100644 --- a/server/class.c +++ b/server/class.c @@ -316,6 +316,14 @@ DECL_HANDLER(set_class_info) reply->old_info = shared->info.wndproc; shared->info.wndproc = req->new_info; break; + case GCLP_HCURSOR: + reply->old_info = shared->info.cursor; + shared->info.cursor = req->new_info; + break; + case GCLP_HBRBACKGROUND: + reply->old_info = shared->info.background; + shared->info.background = req->new_info; + break; default: if (req->size > sizeof(req->new_info) || req->offset < 0 || req->offset > class->shared->info.cls_extra - (int)req->size) diff --git a/server/protocol.def b/server/protocol.def index 9632b8d424b..f20488311fc 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -1044,6 +1044,8 @@ struct class_info unsigned int style; /* class style */ unsigned int cls_extra; /* number of class extra bytes */ unsigned int win_extra; /* number of window extra bytes */ + user_handle_t cursor; /* default cursor */ + user_handle_t background; /* default background */ mod_handle_t instance; /* module instance */ client_ptr_t wndproc; /* class window proc */ }; @@ -3291,6 +3293,7 @@ enum caret_state VARARG(name,unicode_str); /* class name */ @REPLY client_ptr_t client_ptr; /* pointer to class in client address space */ + user_handle_t background; /* class default background */ @END diff --git a/server/trace.c b/server/trace.c index a3cc1f5aeec..9fb3b3f2b1c 100644 --- a/server/trace.c +++ b/server/trace.c @@ -1658,8 +1658,9 @@ static void dump_varargs_class_info( const char *prefix, data_size_t size ) { const struct class_info *info = cur_data; - fprintf( stderr, "%s{atom=%#x,style=%#x,cls_extra=%u,win_extra=%u", - prefix, info->atom, info->style, info->cls_extra, info->win_extra ); + fprintf( stderr, "%s{atom=%#x,style=%#x,cls_extra=%u,win_extra=%u,cursor=%#x,background=%#x", + prefix, info->atom, info->style, info->cls_extra, info->win_extra, info->cursor, + info->background ); dump_uint64( ",instance=", &info->instance ); dump_uint64( ",wndproc=", &info->wndproc ); fputc( '}', stderr ); diff --git a/tools/make_requests b/tools/make_requests index e92fb10d8f9..3d15a10fbd4 100755 --- a/tools/make_requests +++ b/tools/make_requests @@ -68,7 +68,7 @@ my %formats = "struct thread_info" => [ 40, 8 ], "union udp_endpoint" => [ 32, 4 ], "struct user_apc" => [ 40, 8 ], - "struct class_info" => [ 32, 8 ], + "struct class_info" => [ 40, 8 ], ); my $file_header = -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10959
From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/win32u/class.c | 52 ++++++++++++++++++++++----------------------- server/class.c | 8 +++++++ server/protocol.def | 2 ++ server/trace.c | 4 ++-- tools/make_requests | 2 +- 5 files changed, 38 insertions(+), 30 deletions(-) diff --git a/dlls/win32u/class.c b/dlls/win32u/class.c index 9559f6d5fdf..50a39f67c80 100644 --- a/dlls/win32u/class.c +++ b/dlls/win32u/class.c @@ -48,8 +48,6 @@ typedef struct tagCLASS struct list entry; /* Entry in class list */ BOOL local; /* Local class? */ struct dce *dce; /* Opaque pointer to class DCE */ - HICON hIcon; /* Default icon */ - HICON hIconSm; /* Default small icon */ HICON icon_internal; /* internal small icon, derived from hIcon */ struct client_menu_name *menu_name; /* Default menu name */ const shared_object_t *shared; /* class object in session shared memory */ @@ -566,6 +564,8 @@ ATOM WINAPI NtUserRegisterClassExWOW( const WNDCLASSEXW *wc, UNICODE_STRING *nam .win_extra = wc->cbWndExtra, .cursor = wine_server_user_handle( wc->hCursor ), .background = wine_server_user_handle( wc->hbrBackground ), + .icon = wine_server_user_handle( wc->hIcon ), + .icon_small = wine_server_user_handle( wc->hIconSm ), .instance = wine_server_client_ptr( instance ), .wndproc = wine_server_client_ptr( wndproc ), }; @@ -602,8 +602,6 @@ ATOM WINAPI NtUserRegisterClassExWOW( const WNDCLASSEXW *wc, UNICODE_STRING *nam debugstr_w(wc->lpszClassName), debugstr_us(name), atom, wc->lpfnWndProc, instance, wc->hbrBackground, wc->style, wc->cbClsExtra, wc->cbWndExtra, class ); - class->hIcon = wc->hIcon; - class->hIconSm = wc->hIconSm; class->icon_internal = icon_internal; class->menu_name = menu_name; class->shared = shared; @@ -688,8 +686,8 @@ ATOM WINAPI NtUserGetClassInfoEx( HINSTANCE instance, UNICODE_STRING *name, WNDC wc->cbClsExtra = class_shm->info.cls_extra; wc->cbWndExtra = class_shm->info.win_extra; wc->hInstance = (instance == user32_module) ? 0 : instance; - wc->hIcon = class->hIcon; - wc->hIconSm = class->hIconSm; + wc->hIcon = wine_server_ptr_handle( class_shm->info.icon ); + wc->hIconSm = wine_server_ptr_handle( class_shm->info.icon_small ); wc->hCursor = wine_server_ptr_handle( class_shm->info.cursor ); wc->hbrBackground = wine_server_ptr_handle( class_shm->info.background ); wc->lpszMenuName = (WCHAR *)class->menu_name; @@ -845,6 +843,8 @@ static ULONG_PTR set_class_long_size( HWND hwnd, INT offset, LONG_PTR newval, UI case GCL_STYLE: case GCLP_HBRBACKGROUND: case GCLP_HCURSOR: + case GCLP_HICON: + case GCLP_HICONSM: case GCLP_HMODULE: set_server_info( hwnd, offset, newval, size, &retval ); break; @@ -857,16 +857,6 @@ static ULONG_PTR set_class_long_size( HWND hwnd, INT offset, LONG_PTR newval, UI if (!set_server_info( hwnd, offset, newval, size, &retval )) break; retval = (ULONG_PTR)get_winproc( (WNDPROC)retval, ansi ); break; - case GCLP_HICON: - retval = (ULONG_PTR)class->hIcon; - if (retval == newval) break; - class->hIcon = (HICON)newval; - break; - case GCLP_HICONSM: - retval = (ULONG_PTR)class->hIconSm; - if (retval == newval) break; - class->hIconSm = (HICON)newval; - break; case GCL_CBCLSEXTRA: /* cannot change this one */ RtlSetLastWin32Error( ERROR_INVALID_PARAMETER ); break; @@ -878,7 +868,17 @@ static ULONG_PTR set_class_long_size( HWND hwnd, INT offset, LONG_PTR newval, UI if (offset == GCLP_HICON || offset == GCLP_HICONSM) { - HICON icon = class->hIcon, icon_small = class->hIconSm; + struct object_lock lock = OBJECT_LOCK_INIT; + HICON icon = 0, icon_small = 0; + const class_shm_t *class_shm; + NTSTATUS status; + + while ((status = get_shared_class( class, &lock, &class_shm )) == STATUS_PENDING) + { + icon_small = wine_server_get_ptr( class_shm->info.icon_small ); + icon = wine_server_get_ptr( class_shm->info.icon ); + } + NtUserDestroyCursor( class->icon_internal, 0 ); class->icon_internal = icon_small ? 0 : create_small_icon( icon ); } @@ -918,6 +918,7 @@ static ULONG_PTR get_class_long_shm( HWND hwnd, INT offset, UINT size, BOOL ansi ULONG_PTR ret = 0; BOOL valid = TRUE; NTSTATUS status; + CLASS *class; while ((status = get_shared_window_class( hwnd, &lock, &class_shm )) == STATUS_PENDING) { @@ -929,6 +930,8 @@ static ULONG_PTR get_class_long_shm( HWND hwnd, INT offset, UINT size, BOOL ansi case GCL_CBCLSEXTRA: ret = class_shm->info.cls_extra; break; case GCL_CBWNDEXTRA: ret = class_shm->info.win_extra; break; case GCLP_HMODULE: ret = class_shm->info.instance; break; + case GCLP_HICON: ret = class_shm->info.icon; break; + case GCLP_HICONSM: ret = class_shm->info.icon_small; break; case GCLP_HCURSOR: ret = class_shm->info.cursor; break; case GCLP_HBRBACKGROUND: ret = class_shm->info.background; break; default: @@ -950,6 +953,11 @@ static ULONG_PTR get_class_long_shm( HWND hwnd, INT offset, UINT size, BOOL ansi } if (offset == GCLP_WNDPROC) return (ULONG_PTR)get_winproc( (WNDPROC)ret, ansi ); + if (offset == GCLP_HICONSM && !ret && (class = get_class_ptr( hwnd, FALSE ))) + { + ret = (UINT_PTR)class->icon_internal; + release_class_ptr( class ); + } return ret; } @@ -960,8 +968,6 @@ static ULONG_PTR get_class_long_size( HWND hwnd, INT offset, UINT size, BOOL ans switch (offset) { - case GCLP_HICONSM: - case GCLP_HICON: case GCLP_MENUNAME: break; default: @@ -981,8 +987,6 @@ static ULONG_PTR get_class_long_size( HWND hwnd, INT offset, UINT size, BOOL ans { switch (offset) { - case GCLP_HICON: - case GCLP_HICONSM: case GCLP_MENUNAME: FIXME( "offset %d not supported on other process window %p\n", offset, hwnd ); break; @@ -998,12 +1002,6 @@ static ULONG_PTR get_class_long_size( HWND hwnd, INT offset, UINT size, BOOL ans switch(offset) { - case GCLP_HICON: - retvalue = (ULONG_PTR)class->hIcon; - break; - case GCLP_HICONSM: - retvalue = (ULONG_PTR)(class->hIconSm ? class->hIconSm : class->icon_internal); - break; case GCLP_MENUNAME: retvalue = (ULONG_PTR)class->menu_name; break; diff --git a/server/class.c b/server/class.c index bac616e294c..4bdad4b026c 100644 --- a/server/class.c +++ b/server/class.c @@ -324,6 +324,14 @@ DECL_HANDLER(set_class_info) reply->old_info = shared->info.background; shared->info.background = req->new_info; break; + case GCLP_HICON: + reply->old_info = shared->info.icon; + shared->info.icon = req->new_info; + break; + case GCLP_HICONSM: + reply->old_info = shared->info.icon_small; + shared->info.icon_small = req->new_info; + break; default: if (req->size > sizeof(req->new_info) || req->offset < 0 || req->offset > class->shared->info.cls_extra - (int)req->size) diff --git a/server/protocol.def b/server/protocol.def index f20488311fc..6a1216066aa 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -1046,6 +1046,8 @@ struct class_info unsigned int win_extra; /* number of window extra bytes */ user_handle_t cursor; /* default cursor */ user_handle_t background; /* default background */ + user_handle_t icon; /* default icon */ + user_handle_t icon_small; /* default cursor (small) */ mod_handle_t instance; /* module instance */ client_ptr_t wndproc; /* class window proc */ }; diff --git a/server/trace.c b/server/trace.c index 9fb3b3f2b1c..5379c660aa2 100644 --- a/server/trace.c +++ b/server/trace.c @@ -1658,9 +1658,9 @@ static void dump_varargs_class_info( const char *prefix, data_size_t size ) { const struct class_info *info = cur_data; - fprintf( stderr, "%s{atom=%#x,style=%#x,cls_extra=%u,win_extra=%u,cursor=%#x,background=%#x", + fprintf( stderr, "%s{atom=%#x,style=%#x,cls_extra=%u,win_extra=%u,cursor=%#x,background=%#x,icon=%#x,icon_small=%#x", prefix, info->atom, info->style, info->cls_extra, info->win_extra, info->cursor, - info->background ); + info->background, info->icon, info->icon_small ); dump_uint64( ",instance=", &info->instance ); dump_uint64( ",wndproc=", &info->wndproc ); fputc( '}', stderr ); diff --git a/tools/make_requests b/tools/make_requests index 3d15a10fbd4..30dc400b801 100755 --- a/tools/make_requests +++ b/tools/make_requests @@ -68,7 +68,7 @@ my %formats = "struct thread_info" => [ 40, 8 ], "union udp_endpoint" => [ 32, 4 ], "struct user_apc" => [ 40, 8 ], - "struct class_info" => [ 40, 8 ], + "struct class_info" => [ 48, 8 ], ); my $file_header = -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10959
From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/win32u/class.c | 69 +++++---------------------------------------- server/class.c | 4 +++ server/protocol.def | 2 ++ server/trace.c | 1 + tools/make_requests | 2 +- 5 files changed, 15 insertions(+), 63 deletions(-) diff --git a/dlls/win32u/class.c b/dlls/win32u/class.c index 50a39f67c80..453335617d3 100644 --- a/dlls/win32u/class.c +++ b/dlls/win32u/class.c @@ -49,7 +49,6 @@ typedef struct tagCLASS BOOL local; /* Local class? */ struct dce *dce; /* Opaque pointer to class DCE */ HICON icon_internal; /* internal small icon, derived from hIcon */ - struct client_menu_name *menu_name; /* Default menu name */ const shared_object_t *shared; /* class object in session shared memory */ } CLASS; @@ -568,6 +567,7 @@ ATOM WINAPI NtUserRegisterClassExWOW( const WNDCLASSEXW *wc, UNICODE_STRING *nam .icon_small = wine_server_user_handle( wc->hIconSm ), .instance = wine_server_client_ptr( instance ), .wndproc = wine_server_client_ptr( wndproc ), + .menu_name = wine_server_client_ptr( menu_name ), }; wine_server_add_data( req, &info, sizeof(info) ); req->local = class->local; @@ -603,7 +603,6 @@ ATOM WINAPI NtUserRegisterClassExWOW( const WNDCLASSEXW *wc, UNICODE_STRING *nam wc->hbrBackground, wc->style, wc->cbClsExtra, wc->cbWndExtra, class ); class->icon_internal = icon_internal; - class->menu_name = menu_name; class->shared = shared; release_class_ptr( class ); return atom; @@ -637,6 +636,7 @@ BOOL WINAPI NtUserUnregisterClass( UNICODE_STRING *name, HINSTANCE instance, str wine_server_call_err( req ); class = wine_server_get_ptr( reply->client_ptr ); background = wine_server_ptr_handle( reply->background ); + *menu_name = wine_server_get_ptr( reply->menu_name ); } SERVER_END_REQ; if (!class) @@ -651,7 +651,6 @@ BOOL WINAPI NtUserUnregisterClass( UNICODE_STRING *name, HINSTANCE instance, str list_remove( &class->entry ); if (background > (HBRUSH)(COLOR_GRADIENTINACTIVECAPTION + 1)) NtGdiDeleteObjectApp( background ); - *menu_name = class->menu_name; NtUserDestroyCursor( class->icon_internal, 0 ); free( class ); user_unlock(); @@ -690,13 +689,13 @@ ATOM WINAPI NtUserGetClassInfoEx( HINSTANCE instance, UNICODE_STRING *name, WNDC wc->hIconSm = wine_server_ptr_handle( class_shm->info.icon_small ); wc->hCursor = wine_server_ptr_handle( class_shm->info.cursor ); wc->hbrBackground = wine_server_ptr_handle( class_shm->info.background ); - wc->lpszMenuName = (WCHAR *)class->menu_name; + wc->lpszMenuName = wine_server_get_ptr( class_shm->info.menu_name ); wc->lpszClassName = name->Buffer; + *menu_name = wine_server_get_ptr( class_shm->info.menu_name ); } atom = class_shm->info.atom; } if (wc && !wc->hIconSm) wc->hIconSm = class->icon_internal; - *menu_name = class->menu_name; release_class_ptr( class ); return status ? 0 : atom; } @@ -846,11 +845,8 @@ static ULONG_PTR set_class_long_size( HWND hwnd, INT offset, LONG_PTR newval, UI case GCLP_HICON: case GCLP_HICONSM: case GCLP_HMODULE: - set_server_info( hwnd, offset, newval, size, &retval ); - break; case GCLP_MENUNAME: - retval = (ULONG_PTR)class->menu_name; - class->menu_name = (void *)newval; + set_server_info( hwnd, offset, newval, size, &retval ); break; case GCLP_WNDPROC: newval = (ULONG_PTR)alloc_winproc( (WNDPROC)newval, ansi ); @@ -911,7 +907,7 @@ WORD WINAPI NtUserSetClassWord( HWND hwnd, INT offset, WORD newval ) return set_class_long_size( hwnd, offset, newval, sizeof(WORD), TRUE ); } -static ULONG_PTR get_class_long_shm( HWND hwnd, INT offset, UINT size, BOOL ansi ) +static ULONG_PTR get_class_long_size( HWND hwnd, INT offset, UINT size, BOOL ansi ) { struct object_lock lock = OBJECT_LOCK_INIT; const class_shm_t *class_shm; @@ -934,6 +930,7 @@ static ULONG_PTR get_class_long_shm( HWND hwnd, INT offset, UINT size, BOOL ansi case GCLP_HICONSM: ret = class_shm->info.icon_small; break; case GCLP_HCURSOR: ret = class_shm->info.cursor; break; case GCLP_HBRBACKGROUND: ret = class_shm->info.background; break; + case GCLP_MENUNAME: ret = (ULONG_PTR)wine_server_get_ptr( class_shm->info.menu_name ); break; default: valid = offset >= 0 && offset <= (INT)(class_shm->info.cls_extra - size); if (valid) memcpy( &ret, (char *)class_shm->extra + offset, size ); @@ -961,58 +958,6 @@ static ULONG_PTR get_class_long_shm( HWND hwnd, INT offset, UINT size, BOOL ansi return ret; } -static ULONG_PTR get_class_long_size( HWND hwnd, INT offset, UINT size, BOOL ansi ) -{ - CLASS *class; - ULONG_PTR retvalue = 0; - - switch (offset) - { - case GCLP_MENUNAME: - break; - default: - return get_class_long_shm( hwnd, offset, size, ansi ); - } - - if (!(class = get_class_ptr( hwnd, FALSE ))) return 0; - - if (class == OBJ_OTHER_PROCESS) - { - SERVER_START_REQ( get_class_info ) - { - req->window = wine_server_user_handle( hwnd ); - req->offset = offset; - req->size = size; - if (!wine_server_call_err( req )) - { - switch (offset) - { - case GCLP_MENUNAME: - FIXME( "offset %d not supported on other process window %p\n", offset, hwnd ); - break; - default: - retvalue = reply->info; - break; - } - } - } - SERVER_END_REQ; - return retvalue; - } - - switch(offset) - { - case GCLP_MENUNAME: - retvalue = (ULONG_PTR)class->menu_name; - break; - default: - RtlSetLastWin32Error( ERROR_INVALID_INDEX ); - break; - } - release_class_ptr( class ); - return retvalue; -} - DWORD get_class_long( HWND hwnd, INT offset, BOOL ansi ) { return get_class_long_size( hwnd, offset, sizeof(DWORD), ansi ); diff --git a/server/class.c b/server/class.c index 4bdad4b026c..2ca94bca7be 100644 --- a/server/class.c +++ b/server/class.c @@ -332,6 +332,10 @@ DECL_HANDLER(set_class_info) reply->old_info = shared->info.icon_small; shared->info.icon_small = req->new_info; break; + case GCLP_MENUNAME: + reply->old_info = shared->info.menu_name; + shared->info.menu_name = req->new_info; + break; default: if (req->size > sizeof(req->new_info) || req->offset < 0 || req->offset > class->shared->info.cls_extra - (int)req->size) diff --git a/server/protocol.def b/server/protocol.def index 6a1216066aa..c2cfa64d86d 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -1050,6 +1050,7 @@ struct class_info user_handle_t icon_small; /* default cursor (small) */ mod_handle_t instance; /* module instance */ client_ptr_t wndproc; /* class window proc */ + client_ptr_t menu_name; /* pointer to menu name in client address space */ }; typedef volatile struct @@ -3296,6 +3297,7 @@ enum caret_state @REPLY client_ptr_t client_ptr; /* pointer to class in client address space */ user_handle_t background; /* class default background */ + client_ptr_t menu_name; /* pointer to menu name in client address space */ @END diff --git a/server/trace.c b/server/trace.c index 5379c660aa2..b02e08fce03 100644 --- a/server/trace.c +++ b/server/trace.c @@ -1663,6 +1663,7 @@ static void dump_varargs_class_info( const char *prefix, data_size_t size ) info->background, info->icon, info->icon_small ); dump_uint64( ",instance=", &info->instance ); dump_uint64( ",wndproc=", &info->wndproc ); + dump_uint64( ",menu_name=", &info->menu_name ); fputc( '}', stderr ); remove_data( sizeof(*info) ); } diff --git a/tools/make_requests b/tools/make_requests index 30dc400b801..7e317647a51 100755 --- a/tools/make_requests +++ b/tools/make_requests @@ -68,7 +68,7 @@ my %formats = "struct thread_info" => [ 40, 8 ], "union udp_endpoint" => [ 32, 4 ], "struct user_apc" => [ 40, 8 ], - "struct class_info" => [ 48, 8 ], + "struct class_info" => [ 56, 8 ], ); my $file_header = -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10959
v2: Use a class_info struct to wrap window class infos. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10959#note_140930
participants (2)
-
Rémi Bernon -
Rémi Bernon (@rbernon)