[PATCH 0/5] MR10959: win32u: Move remaining class info to the shared memory.
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 | 28 +++++++++++++++++----------- server/class.c | 5 +++++ server/protocol.def | 2 ++ 3 files changed, 24 insertions(+), 11 deletions(-) diff --git a/dlls/win32u/class.c b/dlls/win32u/class.c index 5140430c558..ea814d8696b 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->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 ); @@ -558,6 +567,7 @@ ATOM WINAPI NtUserRegisterClassExWOW( const WNDCLASSEXW *wc, UNICODE_STRING *nam req->cls_extra = wc->cbClsExtra; req->win_extra = wc->cbWndExtra; req->client_ptr = wine_server_client_ptr( class ); + req->wndproc = wine_server_client_ptr( wndproc ); req->atom = wine_server_add_atom( req, name ); req->name_offset = version->Length / sizeof(WCHAR); ret = !wine_server_call_err( req ); @@ -593,7 +603,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 ); @@ -670,7 +679,7 @@ ATOM WINAPI NtUserGetClassInfoEx( HINSTANCE instance, UNICODE_STRING *name, WNDC if (wc) { wc->style = class_shm->style; - wc->lpfnWndProc = get_winproc( class->winproc, ansi ); + wc->lpfnWndProc = get_winproc( wine_server_get_ptr( class_shm->wndproc ), ansi ); wc->cbClsExtra = class_shm->cls_extra; wc->cbWndExtra = class_shm->win_extra; wc->hInstance = (instance == user32_module) ? 0 : instance; @@ -832,8 +841,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; @@ -920,6 +930,7 @@ static ULONG_PTR get_class_long_shm( HWND hwnd, INT offset, UINT size, BOOL ansi { case GCW_ATOM: ret = class_shm->atom; break; case GCL_STYLE: ret = class_shm->style; break; + case GCLP_WNDPROC: ret = (ULONG_PTR)get_winproc( wine_server_get_ptr( class_shm->wndproc ), ansi ); 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; @@ -952,7 +963,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: @@ -979,7 +989,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; @@ -1007,9 +1016,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 a71ee0a332a..1faf8618ebc 100644 --- a/server/class.c +++ b/server/class.c @@ -241,6 +241,7 @@ DECL_HANDLER(create_class) shared->atom = base_atom; shared->instance = req->instance; shared->style = req->style; + shared->wndproc = req->wndproc; shared->win_extra = req->win_extra; shared->cls_extra = req->cls_extra; memset( (void *)shared->extra, 0, req->cls_extra ); @@ -310,6 +311,10 @@ DECL_HANDLER(set_class_info) reply->old_info = shared->instance; shared->instance = req->new_info; break; + case GCLP_WNDPROC: + reply->old_info = shared->wndproc; + shared->wndproc = 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 3ee3be605d4..a10e2c0ca08 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -1042,6 +1042,7 @@ typedef volatile struct { atom_t atom; /* class atom */ unsigned int style; /* class style */ + client_ptr_t wndproc; /* class window proc */ unsigned int cls_extra; /* number of class extra bytes */ unsigned int win_extra; /* number of window extra bytes */ mod_handle_t instance; /* module instance */ @@ -3271,6 +3272,7 @@ enum caret_state unsigned int style; /* class style */ mod_handle_t instance; /* module instance */ client_ptr_t client_ptr; /* pointer to class in client address space */ + client_ptr_t wndproc; /* class window proc client pointer */ 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 */ -- 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 | 10 +++++++++ server/protocol.def | 5 +++++ 3 files changed, 34 insertions(+), 36 deletions(-) diff --git a/dlls/win32u/class.c b/dlls/win32u/class.c index ea814d8696b..1212e1c3e0c 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; @@ -563,6 +561,8 @@ ATOM WINAPI NtUserRegisterClassExWOW( const WNDCLASSEXW *wc, UNICODE_STRING *nam { req->local = class->local; req->style = wc->style; + req->cursor = wine_server_user_handle( wc->hCursor ); + req->background = wine_server_user_handle( wc->hbrBackground ); req->instance = wine_server_client_ptr( instance ); req->cls_extra = wc->cbClsExtra; req->win_extra = wc->cbWndExtra; @@ -601,8 +601,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 ); @@ -623,6 +621,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(); @@ -633,7 +632,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) @@ -646,8 +647,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 ); @@ -685,8 +686,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->cursor ); + wc->hbrBackground = wine_server_ptr_handle( class_shm->background ); wc->lpszMenuName = (WCHAR *)class->menu_name; wc->lpszClassName = name->Buffer; } @@ -836,6 +837,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; @@ -845,14 +853,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; @@ -863,15 +863,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; @@ -934,6 +925,8 @@ static ULONG_PTR get_class_long_shm( HWND hwnd, INT offset, UINT size, BOOL ansi 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 GCLP_HCURSOR: ret = class_shm->cursor; break; + case GCLP_HBRBACKGROUND: ret = class_shm->background; break; default: valid = offset >= 0 && offset <= (INT)(class_shm->cls_extra - size); if (valid) memcpy( &ret, (char *)class_shm->extra + offset, size ); @@ -964,8 +957,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: @@ -985,8 +976,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: @@ -1004,12 +993,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 1faf8618ebc..59fc4aecc1e 100644 --- a/server/class.c +++ b/server/class.c @@ -239,6 +239,8 @@ DECL_HANDLER(create_class) shared->name_offset = name_offset; shared->name_len = name.len; shared->atom = base_atom; + shared->cursor = req->cursor; + shared->background = req->background; shared->instance = req->instance; shared->style = req->style; shared->wndproc = req->wndproc; @@ -315,6 +317,14 @@ DECL_HANDLER(set_class_info) reply->old_info = shared->wndproc; shared->wndproc = req->new_info; break; + case GCLP_HCURSOR: + reply->old_info = shared->cursor; + shared->cursor = req->new_info; + break; + case GCLP_HBRBACKGROUND: + reply->old_info = shared->background; + shared->background = 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 a10e2c0ca08..4aab2d11cf1 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -1045,6 +1045,8 @@ typedef volatile struct client_ptr_t wndproc; /* class window proc */ 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 */ 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 */ @@ -3270,6 +3272,8 @@ enum caret_state int local; /* is it a local class? */ atom_t atom; /* class atom */ unsigned int style; /* class style */ + user_handle_t cursor; /* class default cursor */ + user_handle_t background; /* class default background */ mod_handle_t instance; /* module instance */ client_ptr_t client_ptr; /* pointer to class in client address space */ client_ptr_t wndproc; /* class window proc client pointer */ @@ -3290,6 +3294,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 -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10959
From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/win32u/class.c | 64 +++++++++++++++++++++++++-------------------- server/class.c | 31 ++++++++++++++++++++-- server/protocol.def | 10 ++++++- 3 files changed, 74 insertions(+), 31 deletions(-) diff --git a/dlls/win32u/class.c b/dlls/win32u/class.c index 1212e1c3e0c..973b06c1117 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 */ @@ -559,7 +557,18 @@ ATOM WINAPI NtUserRegisterClassExWOW( const WNDCLASSEXW *wc, UNICODE_STRING *nam user_lock(); SERVER_START_REQ( create_class ) { - req->local = class->local; + user_handle_t icon, icon_sm; + if (class->local) req->flags |= CREATE_CLASS_LOCAL; + if ((icon = wine_server_user_handle( wc->hIcon ))) + { + wine_server_add_data( req, &icon, sizeof(icon) ); + req->flags |= CREATE_CLASS_ICON; + } + if ((icon_sm = wine_server_user_handle( wc->hIconSm ))) + { + wine_server_add_data( req, &icon_sm, sizeof(icon_sm) ); + req->flags |= CREATE_CLASS_ICONSM; + } req->style = wc->style; req->cursor = wine_server_user_handle( wc->hCursor ); req->background = wine_server_user_handle( wc->hbrBackground ); @@ -598,8 +607,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; @@ -684,8 +691,8 @@ ATOM WINAPI NtUserGetClassInfoEx( HINSTANCE instance, UNICODE_STRING *name, WNDC wc->cbClsExtra = class_shm->cls_extra; wc->cbWndExtra = class_shm->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->icon ); + 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; @@ -841,6 +848,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; @@ -853,16 +862,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; @@ -874,7 +873,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->icon_small ); + icon = wine_server_get_ptr( class_shm->icon ); + } + NtUserDestroyCursor( class->icon_internal, 0 ); class->icon_internal = icon_small ? 0 : create_small_icon( icon ); } @@ -914,6 +923,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) { @@ -925,6 +935,8 @@ static ULONG_PTR get_class_long_shm( HWND hwnd, INT offset, UINT size, BOOL ansi 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 GCLP_HICON: ret = class_shm->icon; break; + 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; default: @@ -945,6 +957,12 @@ static ULONG_PTR get_class_long_shm( HWND hwnd, INT offset, UINT size, BOOL ansi return 0; } + if (offset == GCLP_HICONSM && !ret && (class = get_class_ptr( hwnd, FALSE ))) + { + ret = (UINT_PTR)class->icon_internal; + release_class_ptr( class ); + } + return ret; } @@ -955,8 +973,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: @@ -976,8 +992,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; @@ -993,12 +1007,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 59fc4aecc1e..0a802651a90 100644 --- a/server/class.c +++ b/server/class.c @@ -181,10 +181,27 @@ DECL_HANDLER(create_class) struct window_class *class; struct unicode_str name = get_req_unicode_str(); struct atom_table *table = get_user_atom_table(); + int local = !!(req->flags & CREATE_CLASS_LOCAL); + user_handle_t icon = 0, icon_small = 0; atom_t atom = req->atom, base_atom; unsigned int name_offset = 0; WCHAR buffer[16]; + if (req->flags & CREATE_CLASS_ICON) + { + if (name.len < sizeof(icon)) return set_error( STATUS_INVALID_PARAMETER ); + memcpy( &icon, name.str, sizeof(icon) ); + name.str += sizeof(icon) / sizeof(WCHAR); + name.len -= sizeof(icon); + } + if (req->flags & CREATE_CLASS_ICONSM) + { + if (name.len < sizeof(icon_small)) return set_error( STATUS_INVALID_PARAMETER ); + memcpy( &icon_small, name.str, sizeof(icon_small) ); + name.str += sizeof(icon_small) / sizeof(WCHAR); + name.len -= sizeof(icon_small); + } + if (atom && !name.len) name = integral_atom_name( buffer, atom ); if (!atom && !(atom = add_atom( table, &name ))) return; @@ -208,7 +225,7 @@ DECL_HANDLER(create_class) } class = find_class( current->process, atom, req->instance ); - if (class && !class->local == !req->local) + if (class && !class->local == !local) { set_win32_error( ERROR_CLASS_ALREADY_EXISTS ); release_atom( table, atom ); @@ -224,7 +241,7 @@ DECL_HANDLER(create_class) return; } - if (!(class = create_class( current->process, req->local, req->cls_extra ))) + if (!(class = create_class( current->process, local, req->cls_extra ))) { release_atom( table, atom ); release_atom( table, base_atom ); @@ -246,6 +263,8 @@ DECL_HANDLER(create_class) shared->wndproc = req->wndproc; shared->win_extra = req->win_extra; shared->cls_extra = req->cls_extra; + shared->icon = icon; + shared->icon_small = icon_small; memset( (void *)shared->extra, 0, req->cls_extra ); } SHARED_WRITE_END; @@ -325,6 +344,14 @@ DECL_HANDLER(set_class_info) reply->old_info = shared->background; shared->background = req->new_info; break; + case GCLP_HICON: + reply->old_info = shared->icon; + shared->icon = req->new_info; + break; + case GCLP_HICONSM: + reply->old_info = shared->icon_small; + shared->icon_small = 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 4aab2d11cf1..e5afcefd791 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -1047,6 +1047,8 @@ typedef volatile struct 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 */ 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 */ @@ -3269,7 +3271,7 @@ enum caret_state /* Create a window class */ @REQ(create_class) - int local; /* is it a local class? */ + unsigned int flags; /* flags, see below */ atom_t atom; /* class atom */ unsigned int style; /* class style */ user_handle_t cursor; /* class default cursor */ @@ -3280,12 +3282,18 @@ enum caret_state 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(icon,uints); /* class default icon */ + VARARG(icon_small,uints); /* class default icon (small) */ VARARG(name,unicode_str); /* class name */ @REPLY struct obj_locator locator; /* locator for the shared class object */ atom_t atom; /* resulting class atom */ @END +#define CREATE_CLASS_LOCAL 1 +#define CREATE_CLASS_ICON 2 +#define CREATE_CLASS_ICONSM 4 + /* Destroy a window class */ @REQ(destroy_class) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10959
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
Alexandre Julliard (@julliard) commented about server/protocol.def:
@REQ(create_class) - int local; /* is it a local class? */ + unsigned int flags; /* flags, see below */ atom_t atom; /* class atom */ unsigned int style; /* class style */ + user_handle_t cursor; /* class default cursor */ + user_handle_t background; /* class default background */ mod_handle_t instance; /* module instance */ client_ptr_t client_ptr; /* pointer to class in client address space */ + client_ptr_t wndproc; /* class window proc client pointer */ 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(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 */ This had me confused for a while. Please define a proper structure for class data instead of abusing uint arrays.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/10959#note_140852
participants (3)
-
Alexandre Julliard (@julliard) -
Rémi Bernon -
Rémi Bernon (@rbernon)