In preparation / instead of https://gitlab.winehq.org/wine/wine/-/merge_requests/8486
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/user32/class.c | 2 +- dlls/user32/user_private.h | 1 + dlls/user32/win.c | 34 ++++++++++------------------------ 3 files changed, 12 insertions(+), 25 deletions(-)
diff --git a/dlls/user32/class.c b/dlls/user32/class.c index b51783da64e..24e3b1e9200 100644 --- a/dlls/user32/class.c +++ b/dlls/user32/class.c @@ -120,7 +120,7 @@ static BOOL is_builtin_class( const WCHAR *name ) return FALSE; }
-static void init_class_name_ansi( UNICODE_STRING *str, const char *name ) +void init_class_name_ansi( UNICODE_STRING *str, const char *name ) { if (IS_INTRESOURCE( name )) { diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h index 2cb54211db6..900bf4a4424 100644 --- a/dlls/user32/user_private.h +++ b/dlls/user32/user_private.h @@ -82,6 +82,7 @@ extern void winproc_init(void); extern LRESULT dispatch_win_proc_params( struct win_proc_params *params );
extern void init_class_name( UNICODE_STRING *str, const WCHAR *name ); +extern void init_class_name_ansi( UNICODE_STRING *str, const char *name ); extern void get_class_version( UNICODE_STRING *name, UNICODE_STRING *version, BOOL load );
/* kernel callbacks */ diff --git a/dlls/user32/win.c b/dlls/user32/win.c index 18866ac694e..330b827f0a3 100644 --- a/dlls/user32/win.c +++ b/dlls/user32/win.c @@ -511,19 +511,11 @@ BOOL WINAPI OpenIcon( HWND hwnd ) */ HWND WINAPI FindWindowExW( HWND parent, HWND child, const WCHAR *class, const WCHAR *title ) { - UNICODE_STRING class_str, title_str; + WCHAR class_nameW[MAX_ATOM_LEN + 1]; + UNICODE_STRING class_str = RTL_CONSTANT_STRING(class_nameW), title_str;
if (title) RtlInitUnicodeString( &title_str, title ); - - if (class) - { - if (IS_INTRESOURCE(class)) - { - class_str.Buffer = (WCHAR *)class; - class_str.Length = class_str.MaximumLength = 0; - } - else RtlInitUnicodeString( &class_str, class ); - } + if (class) init_class_name( &class_str, class );
return NtUserFindWindowEx( parent, child, class ? &class_str : NULL, title ? &title_str : NULL, 0 ); @@ -545,9 +537,10 @@ HWND WINAPI FindWindowA( LPCSTR className, LPCSTR title ) /*********************************************************************** * FindWindowExA (USER32.@) */ -HWND WINAPI FindWindowExA( HWND parent, HWND child, LPCSTR className, LPCSTR title ) +HWND WINAPI FindWindowExA( HWND parent, HWND child, const char *class, const char *title ) { - LPWSTR titleW = NULL; + WCHAR *titleW = NULL, class_nameW[MAX_ATOM_LEN + 1]; + UNICODE_STRING class_str = RTL_CONSTANT_STRING(class_nameW), title_str; HWND hwnd = 0;
if (title) @@ -555,19 +548,12 @@ HWND WINAPI FindWindowExA( HWND parent, HWND child, LPCSTR className, LPCSTR tit DWORD len = MultiByteToWideChar( CP_ACP, 0, title, -1, NULL, 0 ); if (!(titleW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return 0; MultiByteToWideChar( CP_ACP, 0, title, -1, titleW, len ); + RtlInitUnicodeString( &title_str, titleW ); } + if (class) init_class_name_ansi( &class_str, class );
- if (!IS_INTRESOURCE(className)) - { - WCHAR classW[256]; - if (MultiByteToWideChar( CP_ACP, 0, className, -1, classW, ARRAY_SIZE( classW ))) - hwnd = FindWindowExW( parent, child, classW, titleW ); - } - else - { - hwnd = FindWindowExW( parent, child, (LPCWSTR)className, titleW ); - } - + hwnd = NtUserFindWindowEx( parent, child, class ? &class_str : NULL, + title ? &title_str : NULL, 0 ); HeapFree( GetProcessHeap(), 0, titleW ); return hwnd; }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/imm.c | 2 +- dlls/win32u/menu.c | 2 +- dlls/win32u/vulkan.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/dlls/win32u/imm.c b/dlls/win32u/imm.c index e5a416d9add..cd94f56d678 100644 --- a/dlls/win32u/imm.c +++ b/dlls/win32u/imm.c @@ -297,7 +297,7 @@ BOOL register_imm_window( HWND hwnd ) UNICODE_STRING class_name = RTL_CONSTANT_STRING( imeW ); UNICODE_STRING name = RTL_CONSTANT_STRING( default_imeW );
- thread_data->default_hwnd = NtUserCreateWindowEx( 0, &class_name, &class_name, &name, + thread_data->default_hwnd = NtUserCreateWindowEx( 0, &class_name, NULL, &name, WS_POPUP | WS_DISABLED | WS_CLIPSIBLINGS, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, FALSE ); } diff --git a/dlls/win32u/menu.c b/dlls/win32u/menu.c index 1bcc7fadd76..bce8e0af79b 100644 --- a/dlls/win32u/menu.c +++ b/dlls/win32u/menu.c @@ -3343,7 +3343,7 @@ static BOOL init_popup( HWND owner, HMENU hmenu, UINT flags ) if (flags & TPM_LAYOUTRTL) ex_style = WS_EX_LAYOUTRTL;
/* NOTE: In Windows, top menu popup is not owned. */ - menu->hWnd = NtUserCreateWindowEx( ex_style, &class_name, &class_name, NULL, + menu->hWnd = NtUserCreateWindowEx( ex_style, &class_name, NULL, NULL, WS_POPUP, 0, 0, 0, 0, owner, 0, (HINSTANCE)get_window_long_ptr( owner, GWLP_HINSTANCE, FALSE ), (void *)hmenu, 0, NULL, 0, FALSE ); diff --git a/dlls/win32u/vulkan.c b/dlls/win32u/vulkan.c index 722bdd845cf..301dbf5579d 100644 --- a/dlls/win32u/vulkan.c +++ b/dlls/win32u/vulkan.c @@ -91,7 +91,7 @@ static VkResult win32u_vkCreateWin32SurfaceKHR( VkInstance client_instance, cons { static const WCHAR staticW[] = {'s','t','a','t','i','c',0}; UNICODE_STRING static_us = RTL_CONSTANT_STRING( staticW ); - dummy = NtUserCreateWindowEx( 0, &static_us, &static_us, &static_us, WS_POPUP, 0, 0, 0, 0, + dummy = NtUserCreateWindowEx( 0, &static_us, NULL, &static_us, WS_POPUP, 0, 0, 0, 0, NULL, NULL, NULL, NULL, 0, NULL, 0, FALSE ); WARN( "Created dummy window %p for null surface window\n", dummy ); surface->hwnd = dummy;
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/class.c | 15 ++++++++++----- dlls/win32u/ntuser_private.h | 2 +- dlls/win32u/window.c | 9 +++------ 3 files changed, 14 insertions(+), 12 deletions(-)
diff --git a/dlls/win32u/class.c b/dlls/win32u/class.c index 2c960a4060a..1b4a410123d 100644 --- a/dlls/win32u/class.c +++ b/dlls/win32u/class.c @@ -287,7 +287,7 @@ NTSTATUS WINAPI NtUserInitializeClientPfnArrays( const ntuser_client_func_ptr *c /*********************************************************************** * get_int_atom_value */ -ATOM get_int_atom_value( UNICODE_STRING *name ) +static ATOM get_int_atom_value( UNICODE_STRING *name ) { const WCHAR *ptr = name->Buffer; const WCHAR *end = ptr + name->Length / sizeof(WCHAR); @@ -305,6 +305,13 @@ ATOM get_int_atom_value( UNICODE_STRING *name ) return ret; }
+atom_t wine_server_add_atom( void *req, UNICODE_STRING *str ) +{ + atom_t atom; + if (!(atom = get_int_atom_value( str ))) wine_server_add_data( req, str->Buffer, str->Length ); + return atom; +} + static unsigned int is_integral_atom( const WCHAR *atomstr, ULONG len, RTL_ATOM *ret_atom ) { RTL_ATOM atom; @@ -501,9 +508,8 @@ ATOM WINAPI NtUserRegisterClassExWOW( const WNDCLASSEXW *wc, UNICODE_STRING *nam req->extra = class->cbClsExtra; req->win_extra = class->cbWndExtra; req->client_ptr = wine_server_client_ptr( class ); - req->atom = class->atomName; + req->atom = wine_server_add_atom( req, name ); req->name_offset = version->Length / sizeof(WCHAR); - if (!req->atom && name) wine_server_add_data( req, name->Buffer, name->Length ); ret = !wine_server_call_err( req ); class->atomName = reply->atom; } @@ -556,8 +562,7 @@ BOOL WINAPI NtUserUnregisterClass( UNICODE_STRING *name, HINSTANCE instance, SERVER_START_REQ( destroy_class ) { req->instance = wine_server_client_ptr( instance ); - if (!(req->atom = get_int_atom_value( name )) && name->Length) - wine_server_add_data( req, name->Buffer, name->Length ); + req->atom = wine_server_add_atom( req, name ); if (!wine_server_call_err( req )) class = wine_server_get_ptr( reply->client_ptr ); } SERVER_END_REQ; diff --git a/dlls/win32u/ntuser_private.h b/dlls/win32u/ntuser_private.h index 27a723b4c2f..601cb784733 100644 --- a/dlls/win32u/ntuser_private.h +++ b/dlls/win32u/ntuser_private.h @@ -176,12 +176,12 @@ WNDPROC get_class_winproc( struct tagCLASS *class ); ULONG_PTR get_class_long_ptr( HWND hwnd, INT offset, BOOL ansi ); WORD get_class_word( HWND hwnd, INT offset ); DLGPROC get_dialog_proc( DLGPROC proc, BOOL ansi ); -ATOM get_int_atom_value( UNICODE_STRING *name ); WNDPROC get_winproc( WNDPROC proc, BOOL ansi ); void get_winproc_params( struct win_proc_params *params, BOOL fixup_ansi_dst ); struct dce *get_class_dce( struct tagCLASS *class ); struct dce *set_class_dce( struct tagCLASS *class, struct dce *dce ); BOOL needs_ime_window( HWND hwnd ); +extern atom_t wine_server_add_atom( void *req, UNICODE_STRING *str ); extern void register_builtin_classes(void); extern void register_desktop_class(void);
diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index 62d6ace72a5..17625e9f52e 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -3024,11 +3024,10 @@ HWND WINAPI NtUserFindWindowEx( HWND parent, HWND child, UNICODE_STRING *class, user_handle_t *list; HWND retvalue = 0; int i = 0, size = 128, title_len; - ATOM atom = class ? get_int_atom_value( class ) : 0; NTSTATUS status;
/* empty class is not the same as NULL class */ - if (!atom && class && !class->Length) return 0; + if (class && !class->Length && !IS_INTRESOURCE(class->Buffer)) return 0;
if (parent == HWND_MESSAGE) parent = get_hwnd_message_parent();
@@ -3040,8 +3039,7 @@ HWND WINAPI NtUserFindWindowEx( HWND parent, HWND child, UNICODE_STRING *class, { req->parent = wine_server_user_handle( parent ); req->child = wine_server_user_handle( child ); - req->atom = atom; - if (!atom && class) wine_server_add_data( req, class->Buffer, class->Length ); + if (class) req->atom = wine_server_add_atom( req, class ); wine_server_set_reply( req, list, size * sizeof(user_handle_t) ); status = wine_server_call( req ); size = reply->count; @@ -5381,8 +5379,7 @@ static WND *create_window_handle( HWND parent, HWND owner, UNICODE_STRING *name, req->dpi_context = dpi_context; req->style = style; req->ex_style = ex_style; - if (!(req->atom = get_int_atom_value( name )) && name->Length) - wine_server_add_data( req, name->Buffer, name->Length ); + req->atom = wine_server_add_atom( req, name ); if (!wine_server_call_err( req )) { handle = wine_server_ptr_handle( reply->handle );
From: Rémi Bernon rbernon@codeweavers.com
--- server/atom.c | 8 ++++---- server/class.c | 32 ++++++++++---------------------- server/object.h | 2 +- 3 files changed, 15 insertions(+), 27 deletions(-)
diff --git a/server/atom.c b/server/atom.c index f3b0d1abffb..41b2f48928d 100644 --- a/server/atom.c +++ b/server/atom.c @@ -350,15 +350,15 @@ atom_t find_atom( struct atom_table *table, const struct unicode_str *str ) }
/* increment the ref count of a global atom; used for window properties */ -int grab_atom( struct atom_table *table, atom_t atom ) +atom_t grab_atom( struct atom_table *table, atom_t atom ) { if (atom >= MIN_STR_ATOM) { struct atom_entry *entry = get_atom_entry( table, atom ); - if (entry) entry->count++; - return (entry != NULL); + if (!entry) return 0; + entry->count++; } - else return 1; + return atom; }
/* decrement the ref count of a global atom; used for window properties */ diff --git a/server/class.c b/server/class.c index 5ecf60044da..4e02b08bca4 100644 --- a/server/class.c +++ b/server/class.c @@ -165,35 +165,23 @@ 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, base_atom; + atom_t atom = req->atom, base_atom;
- if (name.len) + if (!atom && !(atom = add_atom( table, &name ))) return; + + if (req->name_offset && req->name_offset < name.len / sizeof(WCHAR)) { - atom = add_atom( table, &name ); - if (!atom) return; - if (req->name_offset && req->name_offset < name.len / sizeof(WCHAR)) - { - name.str += req->name_offset; - name.len -= req->name_offset * sizeof(WCHAR); - - base_atom = add_atom( table, &name ); - if (!base_atom) - { - release_atom( table, atom ); - return; - } - } - else + name.str += req->name_offset; + name.len -= req->name_offset * sizeof(WCHAR); + if (!(base_atom = add_atom( table, &name ))) { - base_atom = atom; - grab_atom( table, atom ); + release_atom( table, atom ); + return; } } else { - base_atom = atom = req->atom; - if (!grab_atom( table, atom )) return; - grab_atom( table, base_atom ); + base_atom = grab_atom( table, atom ); }
class = find_class( current->process, atom, req->instance ); diff --git a/server/object.h b/server/object.h index 1622e93f784..0e74b9ba9d7 100644 --- a/server/object.h +++ b/server/object.h @@ -296,7 +296,7 @@ extern struct atom_table *get_global_atom_table(void); extern struct atom_table *get_user_atom_table(void); extern atom_t add_atom( struct atom_table *table, const struct unicode_str *str ); extern atom_t find_atom( struct atom_table *table, const struct unicode_str *str ); -extern int grab_atom( struct atom_table *table, atom_t atom ); +extern atom_t grab_atom( struct atom_table *table, atom_t atom ); extern void release_atom( struct atom_table *table, atom_t atom );
/* directory functions */
From: Rémi Bernon rbernon@codeweavers.com
--- server/class.c | 2 +- server/window.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/server/class.c b/server/class.c index 4e02b08bca4..698b50de5a4 100644 --- a/server/class.c +++ b/server/class.c @@ -224,7 +224,7 @@ DECL_HANDLER(destroy_class) struct atom_table *table = get_user_atom_table(); atom_t atom = req->atom;
- if (name.len) atom = find_atom( table, &name ); + if (!atom) atom = find_atom( table, &name );
if (!(class = find_class( current->process, atom, req->instance ))) set_win32_error( ERROR_CLASS_DOES_NOT_EXIST ); diff --git a/server/window.c b/server/window.c index 0729534ad6c..58b510c2eb0 100644 --- a/server/window.c +++ b/server/window.c @@ -2205,7 +2205,7 @@ DECL_HANDLER(create_window) struct unicode_str cls_name = get_req_unicode_str(); struct atom_table *table = get_user_atom_table(); unsigned int dpi_context; - atom_t atom; + atom_t atom = req->atom;
reply->handle = 0; if (req->parent) @@ -2233,7 +2233,7 @@ DECL_HANDLER(create_window) owner = owner->parent; }
- atom = cls_name.len ? find_atom( table, &cls_name ) : req->atom; + if (!atom) atom = find_atom( table, &cls_name );
if (!(win = create_window( parent, owner, atom, req->class_instance, req->instance ))) return;
@@ -2538,7 +2538,7 @@ DECL_HANDLER(get_class_windows) user_handle_t *data; unsigned int count = 0, max_count = get_reply_max_size() / sizeof(*data);
- if (cls_name.len && !(atom = find_atom( table, &cls_name ))) return; + if (!atom && cls_name.len && !(atom = find_atom( table, &cls_name ))) return; if (req->parent && !(parent = get_window( req->parent ))) return;
if (req->child)