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