From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/win32u/class.c | 75 ++++++++------------------------------------- server/class.c | 13 ++++++++ server/protocol.def | 4 +++ 3 files changed, 30 insertions(+), 62 deletions(-) diff --git a/dlls/win32u/class.c b/dlls/win32u/class.c index 973b06c1117..803c3a4ba08 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; @@ -558,6 +557,8 @@ ATOM WINAPI NtUserRegisterClassExWOW( const WNDCLASSEXW *wc, UNICODE_STRING *nam SERVER_START_REQ( create_class ) { user_handle_t icon, icon_sm; + client_ptr_t menu_ptr; + if (class->local) req->flags |= CREATE_CLASS_LOCAL; if ((icon = wine_server_user_handle( wc->hIcon ))) { @@ -569,6 +570,11 @@ ATOM WINAPI NtUserRegisterClassExWOW( const WNDCLASSEXW *wc, UNICODE_STRING *nam wine_server_add_data( req, &icon_sm, sizeof(icon_sm) ); req->flags |= CREATE_CLASS_ICONSM; } + if ((menu_ptr = wine_server_client_ptr( menu_name ))) + { + wine_server_add_data( req, &menu_ptr, sizeof(menu_ptr) ); + req->flags |= CREATE_CLASS_MENU; + } req->style = wc->style; req->cursor = wine_server_user_handle( wc->hCursor ); req->background = wine_server_user_handle( wc->hbrBackground ); @@ -608,7 +614,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; @@ -642,6 +647,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) @@ -656,7 +662,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(); @@ -695,13 +700,13 @@ ATOM WINAPI NtUserGetClassInfoEx( HINSTANCE instance, UNICODE_STRING *name, WNDC wc->hIconSm = wine_server_ptr_handle( class_shm->icon_small ); wc->hCursor = wine_server_ptr_handle( class_shm->cursor ); wc->hbrBackground = wine_server_ptr_handle( class_shm->background ); - wc->lpszMenuName = (WCHAR *)class->menu_name; + wc->lpszMenuName = wine_server_get_ptr( class_shm->menu_name ); wc->lpszClassName = name->Buffer; + *menu_name = wine_server_get_ptr( class_shm->menu_name ); } atom = class_shm->atom; } if (!wc->hIconSm) wc->hIconSm = class->icon_internal; - *menu_name = class->menu_name; release_class_ptr( class ); return status ? 0 : atom; } @@ -851,11 +856,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 ); @@ -916,7 +918,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; @@ -939,6 +941,7 @@ static ULONG_PTR get_class_long_shm( HWND hwnd, INT offset, UINT size, BOOL ansi case GCLP_HICONSM: ret = class_shm->icon_small; break; case GCLP_HCURSOR: ret = class_shm->cursor; break; case GCLP_HBRBACKGROUND: ret = class_shm->background; break; + case GCLP_MENUNAME: ret = (ULONG_PTR)wine_server_get_ptr( class_shm->menu_name ); break; default: valid = offset >= 0 && offset <= (INT)(class_shm->cls_extra - size); if (valid) memcpy( &ret, (char *)class_shm->extra + offset, size ); @@ -966,58 +969,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 0a802651a90..7738ff14fed 100644 --- a/server/class.c +++ b/server/class.c @@ -185,6 +185,7 @@ DECL_HANDLER(create_class) user_handle_t icon = 0, icon_small = 0; atom_t atom = req->atom, base_atom; unsigned int name_offset = 0; + client_ptr_t menu_name = 0; WCHAR buffer[16]; if (req->flags & CREATE_CLASS_ICON) @@ -201,6 +202,13 @@ DECL_HANDLER(create_class) name.str += sizeof(icon_small) / sizeof(WCHAR); name.len -= sizeof(icon_small); } + if (req->flags & CREATE_CLASS_MENU) + { + if (name.len < sizeof(menu_name)) return set_error( STATUS_INVALID_PARAMETER ); + memcpy( &menu_name, name.str, sizeof(menu_name) ); + name.str += sizeof(menu_name) / sizeof(WCHAR); + name.len -= sizeof(menu_name); + } if (atom && !name.len) name = integral_atom_name( buffer, atom ); if (!atom && !(atom = add_atom( table, &name ))) return; @@ -265,6 +273,7 @@ DECL_HANDLER(create_class) shared->cls_extra = req->cls_extra; shared->icon = icon; shared->icon_small = icon_small; + shared->menu_name = menu_name; memset( (void *)shared->extra, 0, req->cls_extra ); } SHARED_WRITE_END; @@ -352,6 +361,10 @@ DECL_HANDLER(set_class_info) reply->old_info = shared->icon_small; shared->icon_small = req->new_info; break; + case GCLP_MENUNAME: + reply->old_info = shared->menu_name; + shared->menu_name = req->new_info; + break; default: if (req->size > sizeof(req->new_info) || req->offset < 0 || req->offset > class->shared->cls_extra - (int)req->size) diff --git a/server/protocol.def b/server/protocol.def index e5afcefd791..4b13da8b70a 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -1050,6 +1050,7 @@ typedef volatile struct user_handle_t icon; /* default icon */ user_handle_t icon_small; /* default cursor (small) */ mod_handle_t instance; /* module instance */ + client_ptr_t menu_name; /* pointer to menu name in client address space */ 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 */ @@ -3284,6 +3285,7 @@ enum caret_state data_size_t name_offset; /* base class name offset for specified atom */ VARARG(icon,uints); /* class default icon */ VARARG(icon_small,uints); /* class default icon (small) */ + VARARG(menu_name,uints64); /* pointer to menu name in client address space */ VARARG(name,unicode_str); /* class name */ @REPLY struct obj_locator locator; /* locator for the shared class object */ @@ -3293,6 +3295,7 @@ enum caret_state #define CREATE_CLASS_LOCAL 1 #define CREATE_CLASS_ICON 2 #define CREATE_CLASS_ICONSM 4 +#define CREATE_CLASS_MENU 8 /* Destroy a window class */ @@ -3303,6 +3306,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 -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10959