From: Rémi Bernon rbernon@codeweavers.com
--- dlls/user32/tests/class.c | 16 ++++++++-------- dlls/win32u/class.c | 15 --------------- include/wine/server_protocol.h | 1 - server/class.c | 7 ------- 4 files changed, 8 insertions(+), 31 deletions(-)
diff --git a/dlls/user32/tests/class.c b/dlls/user32/tests/class.c index 480f528e015..76adaa1ce0b 100644 --- a/dlls/user32/tests/class.c +++ b/dlls/user32/tests/class.c @@ -2346,11 +2346,11 @@ static void test_class_name(void) ok(res != 0, "unexpected class atom %#Ix\n", res); SetLastError(0xdeadbeef); res = SetClassWord(hwnd, GCW_ATOM, 2); - todo_wine ok(res == 0, "SetClassLongPtrA returned %#Ix\n", res); - todo_wine ok(GetLastError() == ERROR_INVALID_INDEX, "got error %lu\n", GetLastError()); + ok(res == 0, "SetClassLongPtrA returned %#Ix\n", res); + ok(GetLastError() == ERROR_INVALID_INDEX, "got error %lu\n", GetLastError()); SetLastError(0xdeadbeef); res = SetClassLongPtrA(hwnd, GCW_ATOM, 2); - todo_wine ok(res == 0, "SetClassLongPtrA returned %#Ix\n", res); + ok(res == 0, "SetClassLongPtrA returned %#Ix\n", res); todo_wine ok(GetLastError() == ERROR_INVALID_PARAMETER, "got error %lu\n", GetLastError()); SetLastError(0xdeadbeef);
@@ -2368,15 +2368,15 @@ static void test_class_name(void) ok(res == 1, "unexpected class atom %#Ix\n", res); SetLastError(0xdeadbeef); res = SetClassWord(hwnd, GCW_ATOM, 2); - todo_wine ok(res == 0, "SetClassLongPtrA returned %#Ix\n", res); - todo_wine ok(GetLastError() == ERROR_INVALID_INDEX, "got error %lu\n", GetLastError()); + ok(res == 0, "SetClassLongPtrA returned %#Ix\n", res); + ok(GetLastError() == ERROR_INVALID_INDEX, "got error %lu\n", GetLastError()); SetLastError(0xdeadbeef); res = SetClassWord(hwnd, GCW_ATOM, 1); - todo_wine ok(res == 0, "SetClassLongPtrA returned %#Ix\n", res); - todo_wine ok(GetLastError() == ERROR_INVALID_INDEX, "got error %lu\n", GetLastError()); + ok(res == 0, "SetClassLongPtrA returned %#Ix\n", res); + ok(GetLastError() == ERROR_INVALID_INDEX, "got error %lu\n", GetLastError()); SetLastError(0xdeadbeef); res = SetClassLongPtrA(hwnd, GCW_ATOM, 2); - todo_wine ok(res == 0, "SetClassLongPtrA returned %#Ix\n", res); + ok(res == 0, "SetClassLongPtrA returned %#Ix\n", res); todo_wine ok(GetLastError() == ERROR_INVALID_PARAMETER, "got error %lu\n", GetLastError());
nameA = (const char *)GetClassLongPtrA(hwnd, GCLP_MENUNAME); diff --git a/dlls/win32u/class.c b/dlls/win32u/class.c index 2c960a4060a..2b47776ee4b 100644 --- a/dlls/win32u/class.c +++ b/dlls/win32u/class.c @@ -749,10 +749,6 @@ static BOOL set_server_info( HWND hwnd, INT offset, LONG_PTR newval, UINT size ) req->extra_offset = -1; switch(offset) { - case GCW_ATOM: - req->flags = SET_CLASS_ATOM; - req->atom = LOWORD(newval); - break; case GCL_STYLE: req->flags = SET_CLASS_STYLE; req->style = newval; @@ -910,17 +906,6 @@ static ULONG_PTR set_class_long( HWND hwnd, INT offset, LONG_PTR newval, UINT si retval = class->instance; class->instance = newval; break; - case GCW_ATOM: - { - UNICODE_STRING us; - if (!set_server_info( hwnd, offset, newval, size )) break; - retval = class->atomName; - class->atomName = newval; - us.Buffer = class->name; - us.MaximumLength = sizeof(class->name); - NtUserGetAtomName( newval, &us ); - } - break; case GCL_CBCLSEXTRA: /* cannot change this one */ RtlSetLastWin32Error( ERROR_INVALID_PARAMETER ); break; diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index 1f9348e9e86..7dbd9446ea2 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -4517,7 +4517,6 @@ struct set_class_info_reply int old_win_extra; char __pad_44[4]; }; -#define SET_CLASS_ATOM 0x0001 #define SET_CLASS_STYLE 0x0002 #define SET_CLASS_WINEXTRA 0x0004 #define SET_CLASS_INSTANCE 0x0008 diff --git a/server/class.c b/server/class.c index 5ecf60044da..6563a87fce5 100644 --- a/server/class.c +++ b/server/class.c @@ -254,7 +254,6 @@ DECL_HANDLER(destroy_class) DECL_HANDLER(set_class_info) { struct window_class *class = get_window_class( req->window ); - struct atom_table *table = get_user_atom_table();
if (!class) return;
@@ -293,12 +292,6 @@ DECL_HANDLER(set_class_info) reply->old_instance = class->instance; reply->base_atom = class->base_atom;
- if (req->flags & SET_CLASS_ATOM) - { - if (!grab_atom( table, req->atom )) return; - release_atom( table, class->atom ); - class->atom = req->atom; - } if (req->flags & SET_CLASS_STYLE) class->style = req->style; if (req->flags & SET_CLASS_WINEXTRA) class->win_extra = req->win_extra; if (req->flags & SET_CLASS_INSTANCE) class->instance = req->instance;
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/class.c | 22 +++++++++++++++++----- dlls/win32u/ntuser_private.h | 2 ++ dlls/win32u/window.c | 8 ++------ server/class.c | 2 +- server/user.h | 2 +- server/window.c | 2 +- 6 files changed, 24 insertions(+), 14 deletions(-)
diff --git a/dlls/win32u/class.c b/dlls/win32u/class.c index 2b47776ee4b..c1fe4b0be76 100644 --- a/dlls/win32u/class.c +++ b/dlls/win32u/class.c @@ -305,6 +305,22 @@ ATOM get_int_atom_value( UNICODE_STRING *name ) return ret; }
+BOOL is_desktop_class( UNICODE_STRING *name ) +{ + static const WCHAR desktopW[] = {'#','3','2','7','6','9'}; + ATOM atom; + if ((atom = get_int_atom_value( name ))) return atom == DESKTOP_CLASS_ATOM; + return name->Length == sizeof(desktopW) && !wcsnicmp( name->Buffer, desktopW, ARRAY_SIZE(desktopW) ); +} + +BOOL is_message_class( UNICODE_STRING *name ) +{ + static const WCHAR messageW[] = {'M','e','s','s','a','g','e'}; + ATOM atom; + if ((atom = get_int_atom_value( name ))) return FALSE; + return name->Length == sizeof(messageW) && !wcsnicmp( name->Buffer, messageW, ARRAY_SIZE(messageW) ); +} + static unsigned int is_integral_atom( const WCHAR *atomstr, ULONG len, RTL_ATOM *ret_atom ) { RTL_ATOM atom; @@ -583,15 +599,11 @@ BOOL WINAPI NtUserUnregisterClass( UNICODE_STRING *name, HINSTANCE instance, ATOM WINAPI NtUserGetClassInfoEx( HINSTANCE instance, UNICODE_STRING *name, WNDCLASSEXW *wc, struct client_menu_name *menu_name, BOOL ansi ) { - static const WCHAR messageW[] = {'M','e','s','s','a','g','e'}; CLASS *class; ATOM atom;
/* create the desktop window to trigger builtin class registration */ - if (name->Buffer != (const WCHAR *)DESKTOP_CLASS_ATOM && - (IS_INTRESOURCE(name->Buffer) || name->Length != sizeof(messageW) || - wcsnicmp( name->Buffer, messageW, ARRAYSIZE(messageW) ))) - get_desktop_window(); + if (!is_desktop_class( name ) && !is_message_class( name )) get_desktop_window();
if (!(class = find_class( instance, name ))) return 0;
diff --git a/dlls/win32u/ntuser_private.h b/dlls/win32u/ntuser_private.h index f010ca4ac88..8504eb0332d 100644 --- a/dlls/win32u/ntuser_private.h +++ b/dlls/win32u/ntuser_private.h @@ -183,6 +183,8 @@ 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 BOOL is_desktop_class( UNICODE_STRING *name ); +extern BOOL is_message_class( UNICODE_STRING *name ); 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 e7914e24a69..d75cc4febed 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -5312,7 +5312,7 @@ static WND *create_window_handle( HWND parent, HWND owner, UNICODE_STRING *name, { struct ntuser_thread_info *thread_info = NtUserGetThreadInfo();
- if (name->Buffer == (const WCHAR *)DESKTOP_CLASS_ATOM) + if (is_desktop_class( name )) { if (!thread_info->top_window) thread_info->top_window = HandleToUlong( full_parent ? full_parent : handle ); else assert( full_parent == UlongToHandle( thread_info->top_window )); @@ -5442,8 +5442,6 @@ HWND WINAPI NtUserCreateWindowEx( DWORD ex_style, UNICODE_STRING *class_name, RECT surface_rect; WND *win;
- static const WCHAR messageW[] = {'M','e','s','s','a','g','e'}; - cs.lpCreateParams = params; cs.hInstance = instance ? instance : class_instance; cs.hMenu = menu; @@ -5486,9 +5484,7 @@ HWND WINAPI NtUserCreateWindowEx( DWORD ex_style, UNICODE_STRING *class_name, }
/* are we creating the desktop or HWND_MESSAGE parent itself? */ - if (class_name->Buffer != (LPCWSTR)DESKTOP_CLASS_ATOM && - (class_name->Length != sizeof(messageW) || - wcsnicmp( class_name->Buffer, messageW, ARRAYSIZE(messageW) ))) + if (!is_desktop_class( class_name ) && !is_message_class( class_name )) { if (get_process_layout() & LAYOUT_RTL) cs.dwExStyle |= WS_EX_LAYOUTRTL; parent = get_desktop_window(); diff --git a/server/class.c b/server/class.c index 6563a87fce5..2790ff7ce6a 100644 --- a/server/class.c +++ b/server/class.c @@ -135,7 +135,7 @@ int is_desktop_class( struct window_class *class ) return (class->atom == DESKTOP_ATOM && !class->local); }
-int is_hwnd_message_class( struct window_class *class ) +int is_message_class( struct window_class *class ) { static const WCHAR messageW[] = {'M','e','s','s','a','g','e'}; static const struct unicode_str name = { messageW, sizeof(messageW) }; diff --git a/server/user.h b/server/user.h index ee0042b8755..0ebda06b49b 100644 --- a/server/user.h +++ b/server/user.h @@ -192,7 +192,7 @@ extern struct window_class *grab_class( struct process *process, atom_t atom, mod_handle_t instance, int *extra_bytes ); extern void release_class( struct window_class *class ); extern int is_desktop_class( struct window_class *class ); -extern int is_hwnd_message_class( struct window_class *class ); +extern int is_message_class( struct window_class *class ); extern int get_class_style( struct window_class *class ); extern atom_t get_class_atom( struct window_class *class ); extern client_ptr_t get_class_client_ptr( struct window_class *class ); diff --git a/server/window.c b/server/window.c index 0729534ad6c..4b1acba1adb 100644 --- a/server/window.c +++ b/server/window.c @@ -631,7 +631,7 @@ static struct window *create_window( struct window *parent, struct window *owner { if (is_desktop_class( class )) parent = desktop->top_window; /* use existing desktop if any */ - else if (is_hwnd_message_class( class )) + else if (is_message_class( class )) /* use desktop window if message window is already created */ parent = desktop->msg_window ? desktop->top_window : NULL; else if (!(parent = desktop->top_window)) /* must already have a desktop then */
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/user32/tests/class.c | 6 +++--- server/atom.c | 21 +++++++++++++++++++++ 2 files changed, 24 insertions(+), 3 deletions(-)
diff --git a/dlls/user32/tests/class.c b/dlls/user32/tests/class.c index 76adaa1ce0b..0950b9f173a 100644 --- a/dlls/user32/tests/class.c +++ b/dlls/user32/tests/class.c @@ -2218,7 +2218,7 @@ static void test_actctx_classes(void) tmp_hwnd = FindWindowExA( NULL, NULL, MAKEINTRESOURCEA( class ), NULL ); todo_wine ok( tmp_hwnd == hwnd, "FindWindowExA returned %p, error %lu\n", tmp_hwnd, GetLastError() ); tmp_hwnd = FindWindowExA( NULL, NULL, wc_integral.lpszClassName, NULL ); - todo_wine ok( tmp_hwnd == hwnd, "FindWindowExA returned %p, error %lu\n", tmp_hwnd, GetLastError() ); + ok( tmp_hwnd == hwnd, "FindWindowExA returned %p, error %lu\n", tmp_hwnd, GetLastError() ); tmp_hwnd = FindWindowExA(NULL, NULL, wc_integral_versioned.lpszClassName, NULL); ok( tmp_hwnd == NULL, "FindWindowExA returned %p, error %lu\n", tmp_hwnd, GetLastError() );
@@ -2228,7 +2228,7 @@ static void test_actctx_classes(void) tmp_hwnd = FindWindowExA( NULL, NULL, MAKEINTRESOURCEA( class ), NULL ); todo_wine ok( tmp_hwnd == hwnd, "FindWindowExA returned %p, error %lu\n", tmp_hwnd, GetLastError() ); tmp_hwnd = FindWindowExA( NULL, NULL, wc_integral.lpszClassName, NULL ); - todo_wine ok( tmp_hwnd == hwnd, "FindWindowExA returned %p, error %lu\n", tmp_hwnd, GetLastError() ); + ok( tmp_hwnd == hwnd, "FindWindowExA returned %p, error %lu\n", tmp_hwnd, GetLastError() ); tmp_hwnd = FindWindowExA(NULL, NULL, wc_integral_versioned.lpszClassName, NULL); ok( tmp_hwnd == NULL, "FindWindowExA returned %p, error %lu\n", tmp_hwnd, GetLastError() ); DestroyWindow( hwnd ); @@ -2238,7 +2238,7 @@ static void test_actctx_classes(void) tmp_hwnd = FindWindowExA( NULL, NULL, MAKEINTRESOURCEA( class ), NULL ); todo_wine ok( tmp_hwnd == hwnd, "FindWindowExA returned %p, error %lu\n", tmp_hwnd, GetLastError() ); tmp_hwnd = FindWindowExA( NULL, NULL, wc_integral.lpszClassName, NULL ); - todo_wine ok( tmp_hwnd == hwnd, "FindWindowExA returned %p, error %lu\n", tmp_hwnd, GetLastError() ); + ok( tmp_hwnd == hwnd, "FindWindowExA returned %p, error %lu\n", tmp_hwnd, GetLastError() ); tmp_hwnd = FindWindowExA( NULL, NULL, wc_integral_versioned.lpszClassName, NULL ); ok( tmp_hwnd == NULL, "FindWindowExA returned %p, error %lu\n", tmp_hwnd, GetLastError() ); DestroyWindow( hwnd ); diff --git a/server/atom.c b/server/atom.c index f3b0d1abffb..dcb3d275db0 100644 --- a/server/atom.c +++ b/server/atom.c @@ -248,6 +248,24 @@ static void atom_table_destroy( struct object *obj ) for (i = 0; i < table->count; i++) free( table->atoms[i] ); }
+static atom_t get_int_atom_value( const struct unicode_str *name ) +{ + const WCHAR *ptr = name->str; + const WCHAR *end = ptr + name->len / sizeof(WCHAR); + unsigned int ret = 0; + + if (IS_INTRESOURCE(ptr)) return LOWORD(ptr); + + if (*ptr++ != '#') return 0; + while (ptr < end) + { + if (*ptr < '0' || *ptr > '9') return 0; + ret = ret * 10 + *ptr++ - '0'; + if (ret >= MAXINTATOM) return 0; + } + return ret; +} + /* find an atom entry in its hash list */ static struct atom_entry *find_atom_entry( struct atom_table *table, const struct unicode_str *str, unsigned short hash ) @@ -278,6 +296,7 @@ atom_t add_atom( struct atom_table *table, const struct unicode_str *str ) set_error( STATUS_INVALID_PARAMETER ); return 0; } + if ((atom = get_int_atom_value( str ))) return atom;
hash = hash_strW( str->str, str->len, ARRAY_SIZE(table->entries) ); if ((entry = find_atom_entry( table, str, hash ))) /* exists already */ @@ -328,6 +347,7 @@ atom_t find_atom( struct atom_table *table, const struct unicode_str *str ) { struct atom_entry *entry; unsigned short hash; + atom_t atom;
if (!str->len) { @@ -339,6 +359,7 @@ atom_t find_atom( struct atom_table *table, const struct unicode_str *str ) set_error( STATUS_INVALID_PARAMETER ); return 0; } + if ((atom = get_int_atom_value( str ))) return atom;
hash = hash_strW( str->str, str->len, ARRAY_SIZE(table->entries) ); if (!(entry = find_atom_entry( table, str, hash )))
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/class.c | 23 +++++++++++++++-------- dlls/win32u/window.c | 25 ++++++++++++++++++++----- server/class.c | 40 +++++++++++++++------------------------- server/protocol.def | 4 ---- server/window.c | 5 ++--- 5 files changed, 52 insertions(+), 45 deletions(-)
diff --git a/dlls/win32u/class.c b/dlls/win32u/class.c index c1fe4b0be76..cf850d5f8c9 100644 --- a/dlls/win32u/class.c +++ b/dlls/win32u/class.c @@ -489,9 +489,8 @@ ATOM WINAPI NtUserRegisterClassExWOW( const WNDCLASSEXW *wc, UNICODE_STRING *nam
if (!(class = calloc( 1, sizeof(CLASS) + wc->cbClsExtra ))) return 0;
- class->atomName = get_int_atom_value( name ); class->basename = class->name; - if (!class->atomName && name) + if (!(atom = get_int_atom_value( name ))) { memcpy( class->name, name->Buffer, name->Length ); class->name[name->Length / sizeof(WCHAR)] = 0; @@ -499,8 +498,9 @@ ATOM WINAPI NtUserRegisterClassExWOW( const WNDCLASSEXW *wc, UNICODE_STRING *nam } else { - UNICODE_STRING str = { .MaximumLength = sizeof(class->name), .Buffer = class->name }; - NtUserGetAtomName( class->atomName, &str ); + name->Buffer = class->name; + name->MaximumLength = sizeof(class->name); + name->Length = NtUserGetAtomName( atom, name ) * sizeof(WCHAR); }
class->style = wc->style; @@ -517,9 +517,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->name_offset = version->Length / sizeof(WCHAR); - if (!req->atom && name) wine_server_add_data( req, name->Buffer, name->Length ); + wine_server_add_data( req, name->Buffer, name->Length ); ret = !wine_server_call_err( req ); class->atomName = reply->atom; } @@ -564,16 +563,24 @@ ATOM WINAPI NtUserRegisterClassExWOW( const WNDCLASSEXW *wc, UNICODE_STRING *nam BOOL WINAPI NtUserUnregisterClass( UNICODE_STRING *name, HINSTANCE instance, struct client_menu_name *client_menu_name ) { + WCHAR nameW[MAX_ATOM_LEN + 1]; CLASS *class = NULL; + ATOM atom;
/* create the desktop window to trigger builtin class registration */ get_desktop_window();
+ if ((atom = get_int_atom_value( name ))) + { + name->Buffer = nameW; + name->MaximumLength = sizeof(nameW); + name->Length = NtUserGetAtomName( atom, name ) * sizeof(WCHAR); + } + 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 ); + wine_server_add_data( req, name->Buffer, name->Length ); if (!wine_server_call_err( req )) class = wine_server_get_ptr( reply->client_ptr ); } SERVER_END_REQ; diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index d75cc4febed..df0b6bc7d41 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -2914,9 +2914,17 @@ 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; + WCHAR nameW[MAX_ATOM_LEN + 1]; + ATOM atom; NTSTATUS status;
+ if ((atom = class ? get_int_atom_value( class ) : 0)) + { + class->Buffer = nameW; + class->MaximumLength = sizeof(nameW); + class->Length = NtUserGetAtomName( atom, class ) * sizeof(WCHAR); + } + /* empty class is not the same as NULL class */ if (!atom && class && !class->Length) return 0;
@@ -2930,8 +2938,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) wine_server_add_data( req, class->Buffer, class->Length ); wine_server_set_reply( req, list, size * sizeof(user_handle_t) ); status = wine_server_call( req ); size = reply->count; @@ -5264,10 +5271,19 @@ static WND *create_window_handle( HWND parent, HWND owner, UNICODE_STRING *name, { UINT dpi_context = get_thread_dpi_awareness_context(); HWND handle = 0, full_parent = 0, full_owner = 0; + WCHAR nameW[MAX_ATOM_LEN + 1]; struct tagCLASS *class = NULL; int extra_bytes = 0; + ATOM atom; WND *win;
+ if ((atom = get_int_atom_value( name ))) + { + name->Buffer = nameW; + name->MaximumLength = sizeof(nameW); + name->Length = NtUserGetAtomName( atom, name ) * sizeof(WCHAR); + } + SERVER_START_REQ( create_window ) { req->parent = wine_server_user_handle( parent ); @@ -5277,8 +5293,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 ); + wine_server_add_data( req, name->Buffer, name->Length ); if (!wine_server_call_err( req )) { handle = wine_server_ptr_handle( reply->handle ); diff --git a/server/class.c b/server/class.c index 2790ff7ce6a..c7c600b6280 100644 --- a/server/class.c +++ b/server/class.c @@ -167,33 +167,23 @@ DECL_HANDLER(create_class) struct atom_table *table = get_user_atom_table(); atom_t atom, base_atom;
- if (name.len) + if (!(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); + + base_atom = add_atom( table, &name ); + if (!base_atom) { - 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 = atom; + grab_atom( table, atom ); }
class = find_class( current->process, atom, req->instance ); @@ -234,11 +224,11 @@ DECL_HANDLER(destroy_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; + atom_t atom;
- if (name.len) atom = find_atom( table, &name ); - - if (!(class = find_class( current->process, atom, req->instance ))) + if (!(atom = find_atom( table, &name ))) + set_win32_error( ERROR_CLASS_DOES_NOT_EXIST ); + else if (!(class = find_class( current->process, atom, req->instance ))) set_win32_error( ERROR_CLASS_DOES_NOT_EXIST ); else if (class->count) set_win32_error( ERROR_CLASS_HAS_WINDOWS ); diff --git a/server/protocol.def b/server/protocol.def index 22470e33ae0..91a19d9c4e5 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -2560,7 +2560,6 @@ enum message_type @REQ(create_window) user_handle_t parent; /* parent window */ user_handle_t owner; /* owner window */ - atom_t atom; /* class atom */ mod_handle_t class_instance; /* class module instance */ mod_handle_t instance; /* module instance */ unsigned int dpi_context; /* thread DPI context */ @@ -2669,7 +2668,6 @@ enum message_type @REQ(get_class_windows) user_handle_t parent; /* parent window */ user_handle_t child; /* first child window */ - atom_t atom; /* class atom for the listed siblings */ VARARG(class,unicode_str); /* class name */ @REPLY int count; /* total count of siblings */ @@ -3217,7 +3215,6 @@ enum caret_state /* Create a window class */ @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 */ int extra; /* number of extra class bytes */ @@ -3232,7 +3229,6 @@ enum caret_state
/* Destroy a window class */ @REQ(destroy_class) - atom_t atom; /* class atom */ mod_handle_t instance; /* module instance */ VARARG(name,unicode_str); /* class name */ @REPLY diff --git a/server/window.c b/server/window.c index 4b1acba1adb..90e93f4ae06 100644 --- a/server/window.c +++ b/server/window.c @@ -2233,8 +2233,7 @@ DECL_HANDLER(create_window) owner = owner->parent; }
- atom = cls_name.len ? find_atom( table, &cls_name ) : req->atom; - + if (!(atom = find_atom( table, &cls_name ))) return; if (!(win = create_window( parent, owner, atom, req->class_instance, req->instance ))) return;
if (parent && !is_desktop_window( parent )) @@ -2534,7 +2533,7 @@ DECL_HANDLER(get_class_windows) struct window *parent = NULL, *win = NULL; struct unicode_str cls_name = get_req_unicode_str(); struct atom_table *table = get_user_atom_table(); - atom_t atom = req->atom; + atom_t atom = 0; user_handle_t *data; unsigned int count = 0, max_count = get_reply_max_size() / sizeof(*data);
Dmitry Timoshkov (@dmitry) commented about dlls/user32/tests/class.c:
ok(res != 0, "unexpected class atom %#Ix\n", res); SetLastError(0xdeadbeef); res = SetClassWord(hwnd, GCW_ATOM, 2);
- todo_wine ok(res == 0, "SetClassLongPtrA returned %#Ix\n", res);
- todo_wine ok(GetLastError() == ERROR_INVALID_INDEX, "got error %lu\n", GetLastError());
- ok(res == 0, "SetClassLongPtrA returned %#Ix\n", res);
It's an existing typo (SetClassWord/SetClassLongPtrA), but since the lines are changed this could be fixed as well.