Passing every atom as UNICODE_STRING to win32u.
-- v3: server: Return the class base atom from create_class. win32u: Remove now unnecessary integral atom specific handling. user32: Implement integral class name versioning support. win32u: Introduce helpers to check desktop and message class. win32u: Forbid setting GCW_ATOM class info. user32/tests: Add more GetClassInfo tests.
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/user32/tests/class.c | 164 +++++++++++++++++++++++++------------- 1 file changed, 108 insertions(+), 56 deletions(-)
diff --git a/dlls/user32/tests/class.c b/dlls/user32/tests/class.c index 480f528e015..fdd49157721 100644 --- a/dlls/user32/tests/class.c +++ b/dlls/user32/tests/class.c @@ -1446,15 +1446,15 @@ static void test_IME(void) #define IS_INTRESOURCE(x) (((ULONG_PTR)(x) >> 16) == 0)
#define check_class_info_a( inst, name, expect ) check_class_info_a_( __FILE__, __LINE__, inst, name, expect, FALSE ) -static void check_class_info_a_( const char *file, int line, HINSTANCE instance, const char *name, const WNDCLASSA *expect, BOOL todo ) +static ATOM check_class_info_a_( const char *file, int line, HINSTANCE instance, const char *name, const WNDCLASSA *expect, BOOL todo ) { WNDCLASSA wc = {0}; - UINT ret; + UINT atom;
- ret = GetClassInfoA( instance, name, &wc ); - if (!expect) ok_(file, line)( !ret, "GetClassInfoA succeeded\n" ); - else ok_(file, line)( ret, "GetClassInfoA failed, error %lu\n", GetLastError() ); - if (!expect || !ret) return; + atom = GetClassInfoA( instance, name, &wc ); + if (!expect) ok_(file, line)( !atom, "GetClassInfoA succeeded\n" ); + else ok_(file, line)( atom, "GetClassInfoA failed, error %lu\n", GetLastError() ); + if (!expect || !atom) return atom;
ok_(file, line)( expect->style == wc.style, "got style %#x\n", wc.style ); todo_wine_if( todo ) ok_(file, line)( expect->lpfnWndProc == wc.lpfnWndProc, "got lpfnWndProc %p\n", wc.lpfnWndProc ); @@ -1470,6 +1470,8 @@ static void check_class_info_a_( const char *file, int line, HINSTANCE instance,
if (IS_INTRESOURCE(name)) ok_(file, line)( name == wc.lpszClassName, "got lpszClassName %s\n", debugstr_a( wc.lpszClassName ) ); else ok_(file, line)( !strcmp( name, wc.lpszClassName ), "got lpszClassName %s\n", debugstr_a( wc.lpszClassName ) ); + + return atom; }
#define check_atom_name_a( atom, expect ) check_atom_name_a_( __FILE__, __LINE__, atom, expect ) @@ -1642,7 +1644,8 @@ static void test_actctx_classes(void) class = RegisterClassA( &wc ); ok( class != 0, "RegisterClassA failed, error %lu\n", GetLastError() ); check_atom_name_a( class, wc.lpszClassName ); - check_class_info_a( hinst, MAKEINTRESOURCEA( class ), &wc ); + tmp_class = check_class_info_a( hinst, MAKEINTRESOURCEA( class ), &wc ); + check_atom_name_a( tmp_class, wc.lpszClassName ); ret = UnregisterClassA( wc.lpszClassName, hinst ); ok( ret, "UnregisterClassA failed, error %lu\n", GetLastError() ); check_atom_name_a( class, NULL ); @@ -1657,7 +1660,8 @@ static void test_actctx_classes(void) class = RegisterClassA( &wc_double_version ); ok( class != 0, "RegisterClassA failed, error %lu\n", GetLastError() ); todo_wine check_atom_name_a( class, wc_double_version.lpszClassName ); - check_class_info_a( hinst, "4.3.2.1!4.3.2.1!ClassVersion", &wc_double_version ); + tmp_class = check_class_info_a( hinst, "4.3.2.1!4.3.2.1!ClassVersion", &wc_double_version ); + todo_wine check_atom_name_a( tmp_class, "4.3.2.1!ClassVersion" ); ret = UnregisterClassA( "4.3.2.1!4.3.2.1!ClassVersion", hinst ); ok( ret, "UnregisterClassA failed, error %lu\n", GetLastError() ); check_atom_name_a( class, NULL ); @@ -1674,7 +1678,8 @@ static void test_actctx_classes(void) class = RegisterClassA( &wc ); ok( class != 0, "RegisterClassA failed, error %lu\n", GetLastError() ); todo_wine check_atom_name_a( class, wc.lpszClassName ); - check_class_info_a( hinst, MAKEINTRESOURCEA( class ), &wc ); + tmp_class = check_class_info_a( hinst, MAKEINTRESOURCEA( class ), &wc ); + todo_wine check_atom_name_a( tmp_class, wc.lpszClassName ); ret = DeactivateActCtx( 0, cookie ); ok( ret, "DeactivateActCtx failed, error %lu\n", GetLastError() ); todo_wine check_atom_name_a( class, wc.lpszClassName ); @@ -1718,18 +1723,23 @@ static void test_actctx_classes(void) class = RegisterClassA( &wc_versioned ); ok( class != 0, "RegisterClassA failed, error %lu\n", GetLastError() ); check_atom_name_a( class, wc_versioned.lpszClassName ); - check_class_info_a( hinst, MAKEINTRESOURCEA( class ), &wc_versioned ); + tmp_class = check_class_info_a( hinst, MAKEINTRESOURCEA( class ), &wc_versioned ); + check_atom_name_a( tmp_class, wc_versioned.lpszClassName ); check_class_info_a( hinst, wc.lpszClassName, NULL ); - check_class_info_a( hinst, wc_versioned.lpszClassName, &wc_versioned ); + tmp_class = check_class_info_a( hinst, wc_versioned.lpszClassName, &wc_versioned ); + check_atom_name_a( tmp_class, wc_versioned.lpszClassName );
ret = ActivateActCtx( context, &cookie ); ok( ret, "ActivateActCtx failed, error %lu\n", GetLastError() ); check_atom_name_a( class, wc_versioned.lpszClassName );
/* GetClassInfoA now works with base name */ - check_class_info_a( hinst, MAKEINTRESOURCEA( class ), &wc_versioned ); - check_class_info_a( hinst, wc.lpszClassName, &wc_versioned ); - check_class_info_a( hinst, wc_versioned.lpszClassName, &wc_versioned ); + tmp_class = check_class_info_a( hinst, MAKEINTRESOURCEA( class ), &wc_versioned ); + check_atom_name_a( tmp_class, wc_versioned.lpszClassName ); + tmp_class = check_class_info_a( hinst, wc.lpszClassName, &wc_versioned ); + check_atom_name_a( tmp_class, wc_versioned.lpszClassName ); + tmp_class = check_class_info_a( hinst, wc_versioned.lpszClassName, &wc_versioned ); + check_atom_name_a( tmp_class, wc_versioned.lpszClassName );
/* prevents the class to be registered when context is active */ tmp_class = RegisterClassA( &wc_versioned ); @@ -1756,21 +1766,29 @@ static void test_actctx_classes(void) ok( class_versioned != 0, "RegisterClassA failed, error %lu\n", GetLastError() ); check_atom_name_a( class_versioned, wc_versioned.lpszClassName );
- check_class_info_a( hinst, MAKEINTRESOURCEA( class ), &wc ); - check_class_info_a( hinst, wc.lpszClassName, &wc ); - check_class_info_a( hinst, MAKEINTRESOURCEA( class_versioned ), &wc_versioned ); - check_class_info_a( hinst, wc_versioned.lpszClassName, &wc_versioned ); + tmp_class = check_class_info_a( hinst, MAKEINTRESOURCEA( class ), &wc ); + check_atom_name_a( tmp_class, wc.lpszClassName ); + tmp_class = check_class_info_a( hinst, wc.lpszClassName, &wc ); + check_atom_name_a( tmp_class, wc.lpszClassName ); + tmp_class = check_class_info_a( hinst, MAKEINTRESOURCEA( class_versioned ), &wc_versioned ); + check_atom_name_a( tmp_class, wc_versioned.lpszClassName ); + tmp_class = check_class_info_a( hinst, wc_versioned.lpszClassName, &wc_versioned ); + check_atom_name_a( tmp_class, wc_versioned.lpszClassName );
ret = ActivateActCtx( context, &cookie ); ok( ret, "ActivateActCtx failed, error %lu\n", GetLastError() );
/* unversioned class redirects to the versioned class now */ check_atom_name_a( class, wc.lpszClassName ); - check_class_info_a_( __FILE__, __LINE__, hinst, MAKEINTRESOURCEA( class ), &wc_versioned, TRUE ); - check_class_info_a( hinst, wc.lpszClassName, &wc_versioned ); + tmp_class = check_class_info_a_( __FILE__, __LINE__, hinst, MAKEINTRESOURCEA( class ), &wc_versioned, TRUE ); + todo_wine check_atom_name_a( tmp_class, wc_versioned.lpszClassName ); + tmp_class = check_class_info_a( hinst, wc.lpszClassName, &wc_versioned ); + check_atom_name_a( tmp_class, wc_versioned.lpszClassName ); check_atom_name_a( class_versioned, wc_versioned.lpszClassName ); - check_class_info_a( hinst, MAKEINTRESOURCEA( class_versioned ), &wc_versioned ); - check_class_info_a( hinst, wc_versioned.lpszClassName, &wc_versioned ); + tmp_class = check_class_info_a( hinst, MAKEINTRESOURCEA( class_versioned ), &wc_versioned ); + check_atom_name_a( tmp_class, wc_versioned.lpszClassName ); + tmp_class = check_class_info_a( hinst, wc_versioned.lpszClassName, &wc_versioned ); + check_atom_name_a( tmp_class, wc_versioned.lpszClassName );
/* prevents the class to be registered when context is active */ tmp_class = RegisterClassA( &wc_versioned ); @@ -1796,8 +1814,10 @@ static void test_actctx_classes(void) ret = DeactivateActCtx( 0, cookie ); ok( ret, "DeactivateActCtx failed, error %lu\n", GetLastError() ); check_atom_name_a( class, wc.lpszClassName ); - check_class_info_a( hinst, MAKEINTRESOURCEA( class ), &wc ); - check_class_info_a( hinst, wc.lpszClassName, &wc ); + tmp_class = check_class_info_a( hinst, MAKEINTRESOURCEA( class ), &wc ); + check_atom_name_a( tmp_class, wc.lpszClassName ); + tmp_class = check_class_info_a( hinst, wc.lpszClassName, &wc ); + check_atom_name_a( tmp_class, wc.lpszClassName );
/* unversioned class can be unregistered after context is deactivated */ ret = UnregisterClassA( wc.lpszClassName, hinst ); @@ -1816,8 +1836,10 @@ static void test_actctx_classes(void) class = RegisterClassA( &wc_leak ); ok( class != 0, "RegisterClassA failed, error %lu\n", GetLastError() ); check_atom_name_a( class, wc_leak.lpszClassName ); - check_class_info_a( hinst, MAKEINTRESOURCEA( class ), &wc_leak ); - check_class_info_a( hinst, wc_leak.lpszClassName, &wc_leak ); + tmp_class = check_class_info_a( hinst, MAKEINTRESOURCEA( class ), &wc_leak ); + check_atom_name_a( tmp_class, wc_leak.lpszClassName ); + tmp_class = check_class_info_a( hinst, wc_leak.lpszClassName, &wc_leak ); + check_atom_name_a( tmp_class, wc_leak.lpszClassName ); check_class_info_a( hinst, wc_leak_versioned.lpszClassName, NULL );
ret = ActivateActCtx( context, &cookie ); @@ -1833,9 +1855,12 @@ static void test_actctx_classes(void) tmp_class = RegisterClassA( &wc_leak ); todo_wine ok( tmp_class == class, "RegisterClassA failed, error %lu\n", GetLastError() ); check_atom_name_a( class, wc_leak.lpszClassName ); - check_class_info_a( hinst, MAKEINTRESOURCEA( class ), &wc_leak ); - check_class_info_a( hinst, wc_leak.lpszClassName, &wc_leak ); - check_class_info_a( hinst, wc_leak_versioned.lpszClassName, &wc ); + tmp_class = check_class_info_a( hinst, MAKEINTRESOURCEA( class ), &wc_leak ); + check_atom_name_a( tmp_class, wc_leak.lpszClassName ); + tmp_class = check_class_info_a( hinst, wc_leak.lpszClassName, &wc_leak ); + todo_wine check_atom_name_a( tmp_class, wc_leak.lpszClassName ); + tmp_class = check_class_info_a( hinst, wc_leak_versioned.lpszClassName, &wc ); + todo_wine check_atom_name_a( tmp_class, wc_leak.lpszClassName );
/* versioned class can be unregistered with its base name */ ret = UnregisterClassA( wc_leak.lpszClassName, hinst ); @@ -1858,8 +1883,10 @@ static void test_actctx_classes(void) ret = DeactivateActCtx( 0, cookie ); ok( ret, "DeactivateActCtx failed, error %lu\n", GetLastError() ); todo_wine check_atom_name_a( class, wc_leak.lpszClassName ); - todo_wine check_class_info_a( hinst, MAKEINTRESOURCEA( class ), &wc_leak ); - todo_wine check_class_info_a( hinst, wc_leak.lpszClassName, &wc_leak ); + todo_wine tmp_class = check_class_info_a( hinst, MAKEINTRESOURCEA( class ), &wc_leak ); + todo_wine check_atom_name_a( tmp_class, wc_leak.lpszClassName ); + todo_wine tmp_class = check_class_info_a( hinst, wc_leak.lpszClassName, &wc_leak ); + todo_wine check_atom_name_a( tmp_class, wc_leak.lpszClassName ); check_class_info_a( hinst, wc_leak_versioned.lpszClassName, NULL );
/* unversioned class can be unregistered now */ @@ -1880,9 +1907,12 @@ static void test_actctx_classes(void) class = RegisterClassA( &wc ); ok( class != 0, "RegisterClassA failed, error %lu\n", GetLastError() ); todo_wine check_atom_name_a( class, wc.lpszClassName ); - check_class_info_a( hinst, MAKEINTRESOURCEA( class ), &wc ); - check_class_info_a( hinst, wc.lpszClassName, &wc ); - check_class_info_a( hinst, wc_versioned.lpszClassName, &wc ); + tmp_class = check_class_info_a( hinst, MAKEINTRESOURCEA( class ), &wc ); + todo_wine check_atom_name_a( tmp_class, wc.lpszClassName ); + tmp_class = check_class_info_a( hinst, wc.lpszClassName, &wc ); + todo_wine check_atom_name_a( tmp_class, wc.lpszClassName ); + tmp_class = check_class_info_a( hinst, wc_versioned.lpszClassName, &wc ); + todo_wine check_atom_name_a( tmp_class, wc.lpszClassName );
/* when context isn't active, class info is available by versioned name only */ ret = DeactivateActCtx( 0, cookie ); @@ -1890,7 +1920,8 @@ static void test_actctx_classes(void) todo_wine check_atom_name_a( class, wc.lpszClassName ); todo_wine check_class_info_a( hinst, MAKEINTRESOURCEA( class ), NULL ); check_class_info_a( hinst, wc.lpszClassName, NULL ); - check_class_info_a( hinst, wc_versioned.lpszClassName, &wc ); + tmp_class = check_class_info_a( hinst, wc_versioned.lpszClassName, &wc ); + todo_wine check_atom_name_a( tmp_class, wc.lpszClassName );
/* when context is active, CreateWindow is allowed by atom, versioned, base names */ @@ -2012,14 +2043,18 @@ static void test_actctx_classes(void) check_class_info_a( hinst, wc_integral.lpszClassName, NULL ); class = RegisterClassA( &wc_integral_int ); ok( class == 1234, "RegisterClassA failed, error %lu\n", GetLastError() ); - check_class_info_a( hinst, MAKEINTRESOURCEA(1234), &wc_integral_int ); - todo_wine check_class_info_a( hinst, wc_integral.lpszClassName, &wc_integral_int ); + tmp_class = check_class_info_a( hinst, MAKEINTRESOURCEA(1234), &wc_integral_int ); + ok( tmp_class == 1234, "GetClassInfoA failed, error %lu\n", GetLastError() ); + todo_wine tmp_class = check_class_info_a( hinst, wc_integral.lpszClassName, &wc_integral_int ); + todo_wine ok( tmp_class == 1234, "GetClassInfoA failed, error %lu\n", GetLastError() ); ret = UnregisterClassA( MAKEINTRESOURCEA( class ), hinst ); ok( ret, "UnregisterClassA failed, error %lu\n", GetLastError() ); class = RegisterClassA( &wc_integral ); todo_wine ok( class == 1234, "RegisterClassA failed, error %lu\n", GetLastError() ); - todo_wine check_class_info_a( hinst, MAKEINTRESOURCEA(1234), &wc_integral ); - check_class_info_a( hinst, wc_integral.lpszClassName, &wc_integral ); + todo_wine tmp_class = check_class_info_a( hinst, MAKEINTRESOURCEA(1234), &wc_integral ); + todo_wine ok( tmp_class == 1234, "GetClassInfoA failed, error %lu\n", GetLastError() ); + tmp_class = check_class_info_a( hinst, wc_integral.lpszClassName, &wc_integral ); + todo_wine ok( tmp_class == 1234, "GetClassInfoA failed, error %lu\n", GetLastError() ); ret = DeactivateActCtx( 0, cookie ); ok( ret, "DeactivateActCtx failed, error %lu\n", GetLastError() );
@@ -2054,17 +2089,22 @@ static void test_actctx_classes(void) /* registering versioned class while context isn't active */ class = RegisterClassA( &wc_integral_versioned ); ok( class != 1234, "RegisterClassA failed, error %lu\n", GetLastError() ); - check_class_info_a( hinst, MAKEINTRESOURCEA( class ), &wc_integral_versioned ); + tmp_class = check_class_info_a( hinst, MAKEINTRESOURCEA( class ), &wc_integral_versioned ); + check_atom_name_a( tmp_class, wc_integral_versioned.lpszClassName ); check_class_info_a( hinst, wc_integral.lpszClassName, NULL ); - check_class_info_a( hinst, wc_integral_versioned.lpszClassName, &wc_integral_versioned ); + tmp_class = check_class_info_a( hinst, wc_integral_versioned.lpszClassName, &wc_integral_versioned ); + check_atom_name_a( tmp_class, wc_integral_versioned.lpszClassName );
ret = ActivateActCtx( context, &cookie ); ok( ret, "ActivateActCtx failed, error %lu\n", GetLastError() );
/* GetClassInfoA now works with base name */ - check_class_info_a( hinst, MAKEINTRESOURCEA( class ), &wc_integral_versioned ); - check_class_info_a( hinst, wc_integral.lpszClassName, &wc_integral_versioned ); - check_class_info_a( hinst, wc_integral_versioned.lpszClassName, &wc_integral_versioned ); + tmp_class = check_class_info_a( hinst, MAKEINTRESOURCEA( class ), &wc_integral_versioned ); + check_atom_name_a( tmp_class, wc_integral_versioned.lpszClassName ); + tmp_class = check_class_info_a( hinst, wc_integral.lpszClassName, &wc_integral_versioned ); + check_atom_name_a( tmp_class, wc_integral_versioned.lpszClassName ); + tmp_class = check_class_info_a( hinst, wc_integral_versioned.lpszClassName, &wc_integral_versioned ); + check_atom_name_a( tmp_class, wc_integral_versioned.lpszClassName );
/* prevents the class to be registered when context is active */ tmp_class = RegisterClassA( &wc_integral_versioned ); @@ -2072,9 +2112,12 @@ static void test_actctx_classes(void) tmp_class = RegisterClassA( &wc_integral ); ok( !tmp_class, "RegisterClassA succeeded, error %lu\n", GetLastError() );
- check_class_info_a( hinst, MAKEINTRESOURCEA( class ), &wc_integral_versioned ); - check_class_info_a( hinst, wc_integral.lpszClassName, &wc_integral_versioned ); - check_class_info_a( hinst, wc_integral_versioned.lpszClassName, &wc_integral_versioned ); + tmp_class = check_class_info_a( hinst, MAKEINTRESOURCEA( class ), &wc_integral_versioned ); + check_atom_name_a( tmp_class, wc_integral_versioned.lpszClassName ); + tmp_class = check_class_info_a( hinst, wc_integral.lpszClassName, &wc_integral_versioned ); + check_atom_name_a( tmp_class, wc_integral_versioned.lpszClassName ); + tmp_class = check_class_info_a( hinst, wc_integral_versioned.lpszClassName, &wc_integral_versioned ); + check_atom_name_a( tmp_class, wc_integral_versioned.lpszClassName );
/* versioned class can be unregistered with its base name */ ret = UnregisterClassA( wc_integral.lpszClassName, hinst ); @@ -2086,8 +2129,10 @@ static void test_actctx_classes(void) /* registering unversioned class before context is activated */ class = RegisterClassA( &wc_integral ); ok( class == 1234, "RegisterClassA failed, error %lu\n", GetLastError() ); - check_class_info_a( hinst, MAKEINTRESOURCEA( class ), &wc_integral ); - check_class_info_a( hinst, wc_integral.lpszClassName, &wc_integral ); + tmp_class = check_class_info_a( hinst, MAKEINTRESOURCEA( class ), &wc_integral ); + ok( tmp_class == 1234, "GetClassInfoA failed, error %lu\n", GetLastError() ); + tmp_class = check_class_info_a( hinst, wc_integral.lpszClassName, &wc_integral ); + ok( tmp_class == 1234, "GetClassInfoA failed, error %lu\n", GetLastError() ); check_class_info_a( hinst, wc_integral_versioned.lpszClassName, NULL );
ret = ActivateActCtx( context, &cookie ); @@ -2102,9 +2147,12 @@ static void test_actctx_classes(void) tmp_class = RegisterClassA( &wc_integral ); todo_wine ok( tmp_class == class, "RegisterClassA failed, error %lu\n", GetLastError() );
- check_class_info_a( hinst, MAKEINTRESOURCEA( class ), &wc_integral ); - check_class_info_a( hinst, wc_integral.lpszClassName, &wc_integral ); - check_class_info_a( hinst, wc_integral_versioned.lpszClassName, &wc_integral ); + tmp_class = check_class_info_a( hinst, MAKEINTRESOURCEA( class ), &wc_integral ); + ok( tmp_class == 1234, "GetClassInfoA failed, error %lu\n", GetLastError() ); + tmp_class = check_class_info_a( hinst, wc_integral.lpszClassName, &wc_integral ); + todo_wine ok( tmp_class == 1234, "GetClassInfoA failed, error %lu\n", GetLastError() ); + tmp_class = check_class_info_a( hinst, wc_integral_versioned.lpszClassName, &wc_integral ); + todo_wine ok( tmp_class == 1234, "GetClassInfoA failed, error %lu\n", GetLastError() );
/* versioned class can be unregistered with its base name */ ret = UnregisterClassA( wc_integral.lpszClassName, hinst ); @@ -2126,16 +2174,20 @@ static void test_actctx_classes(void) ok( ret, "ActivateActCtx failed, error %lu\n", GetLastError() ); class = RegisterClassA( &wc_integral ); todo_wine ok( class == 1234, "RegisterClassA failed, error %lu\n", GetLastError() ); - check_class_info_a( hinst, MAKEINTRESOURCEA( class ), &wc_integral ); - check_class_info_a( hinst, wc_integral.lpszClassName, &wc_integral ); - check_class_info_a( hinst, wc_integral_versioned.lpszClassName, &wc_integral ); + tmp_class = check_class_info_a( hinst, MAKEINTRESOURCEA( class ), &wc_integral ); + todo_wine ok( tmp_class == 1234, "GetClassInfoA failed, error %lu\n", GetLastError() ); + tmp_class = check_class_info_a( hinst, wc_integral.lpszClassName, &wc_integral ); + todo_wine ok( tmp_class == 1234, "GetClassInfoA failed, error %lu\n", GetLastError() ); + tmp_class = check_class_info_a( hinst, wc_integral_versioned.lpszClassName, &wc_integral ); + todo_wine ok( tmp_class == 1234, "GetClassInfoA failed, error %lu\n", GetLastError() );
/* class info is available by versioned name only, if context isn't active. */ ret = DeactivateActCtx( 0, cookie ); ok( ret, "DeactivateActCtx failed, error %lu\n", GetLastError() ); todo_wine check_class_info_a( hinst, MAKEINTRESOURCEA( class ), NULL ); check_class_info_a( hinst, wc_integral.lpszClassName, NULL ); - check_class_info_a( hinst, wc_integral_versioned.lpszClassName, &wc_integral ); + tmp_class = check_class_info_a( hinst, wc_integral_versioned.lpszClassName, &wc_integral ); + todo_wine ok( tmp_class == 1234, "GetClassInfoA failed, error %lu\n", GetLastError() );
/* CreateWindow is allowed by atom, versioned, base names when context is active */
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 fdd49157721..4cee5f358d9 100644 --- a/dlls/user32/tests/class.c +++ b/dlls/user32/tests/class.c @@ -2398,11 +2398,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, "SetClassWord 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);
@@ -2420,15 +2420,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, "SetClassWord 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, "SetClassWord 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 1b4a410123d..f92bee2ef08 100644 --- a/dlls/win32u/class.c +++ b/dlls/win32u/class.c @@ -754,10 +754,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; @@ -915,17 +911,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 0e66dfb2fb3..424d9aad25e 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -4530,7 +4530,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 3c9dd8acf05..ab89b4dd4d7 100644 --- a/server/class.c +++ b/server/class.c @@ -241,7 +241,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;
@@ -280,12 +279,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/win32u/class.c | 22 +++++++++++++++++----- dlls/win32u/ntuser_private.h | 2 ++ dlls/win32u/window.c | 11 ++++++----- server/class.c | 2 +- server/user.h | 2 +- server/window.c | 2 +- 6 files changed, 28 insertions(+), 13 deletions(-)
diff --git a/dlls/win32u/class.c b/dlls/win32u/class.c index f92bee2ef08..cafd39f7fea 100644 --- a/dlls/win32u/class.c +++ b/dlls/win32u/class.c @@ -312,6 +312,22 @@ atom_t wine_server_add_atom( void *req, UNICODE_STRING *str ) return atom; }
+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; @@ -588,15 +604,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 601cb784733..f5559c5ca4f 100644 --- a/dlls/win32u/ntuser_private.h +++ b/dlls/win32u/ntuser_private.h @@ -182,6 +182,8 @@ 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 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 17625e9f52e..58bb27d75e4 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -5413,7 +5413,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 )); @@ -5542,7 +5542,10 @@ 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'}; + TRACE( "ex_style %#x, class_name %s, version %s, window_name %s, style %#x, x %u, y %u, cx %u, cy %u, " + "parent %p, menu %p, class_instance %p, params %p, flags %#x, instance %p, unk %u, ansi %u\n", + ex_style, debugstr_us(class_name), debugstr_us(version), debugstr_us(window_name), style, x, y, cx, cy, + parent, menu, class_instance, params, flags, instance, unk, ansi );
cs.lpCreateParams = params; cs.hInstance = instance ? instance : class_instance; @@ -5586,9 +5589,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 ab89b4dd4d7..c98c171e035 100644 --- a/server/class.c +++ b/server/class.c @@ -134,7 +134,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 58b510c2eb0..e237d40a153 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
Passing every atom as UNICODE_STRING to win32u. --- dlls/user32/class.c | 31 ++++---------------------- dlls/user32/controls.h | 3 --- dlls/user32/tests/class.c | 46 +++++++++++++++++++-------------------- dlls/win32u/class.c | 20 +++++------------ dlls/win32u/menu.c | 3 ++- 5 files changed, 35 insertions(+), 68 deletions(-)
diff --git a/dlls/user32/class.c b/dlls/user32/class.c index 24e3b1e9200..3b84d0840f3 100644 --- a/dlls/user32/class.c +++ b/dlls/user32/class.c @@ -35,29 +35,6 @@ static inline const char *debugstr_us( const UNICODE_STRING *us ) return debugstr_wn( us->Buffer, us->Length / sizeof(WCHAR) ); }
- -/*********************************************************************** - * get_int_atom_value - */ -ATOM get_int_atom_value( UNICODE_STRING *name ) -{ - const WCHAR *ptr = name->Buffer; - const WCHAR *end = ptr + name->Length / sizeof(WCHAR); - UINT 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; -} - - /*********************************************************************** * is_comctl32_class */ @@ -124,8 +101,8 @@ void init_class_name_ansi( UNICODE_STRING *str, const char *name ) { if (IS_INTRESOURCE( name )) { - str->Buffer = (WCHAR *)name; - str->Length = str->MaximumLength = 0; + UINT len = NtUserGetAtomName( (UINT_PTR)name, str ); + str->Length = len * sizeof(WCHAR); } else { @@ -138,8 +115,8 @@ void init_class_name( UNICODE_STRING *str, const WCHAR *name ) { if (IS_INTRESOURCE( name )) { - str->Buffer = (WCHAR *)name; - str->Length = str->MaximumLength = 0; + UINT len = NtUserGetAtomName( (UINT_PTR)name, str ); + str->Length = len * sizeof(WCHAR); } else { diff --git a/dlls/user32/controls.h b/dlls/user32/controls.h index d6dd4c17969..69c8fd9b982 100644 --- a/dlls/user32/controls.h +++ b/dlls/user32/controls.h @@ -78,9 +78,6 @@ extern LRESULT MDIClientWndProc_common(HWND,UINT,WPARAM,LPARAM,BOOL); extern LRESULT ScrollBarWndProc_common(HWND,UINT,WPARAM,LPARAM,BOOL); extern LRESULT StaticWndProc_common(HWND,UINT,WPARAM,LPARAM,BOOL);
-/* Class functions */ -extern ATOM get_int_atom_value( UNICODE_STRING *name ); - /* desktop */ extern BOOL update_wallpaper( const WCHAR *wallpaper, const WCHAR *pattern );
diff --git a/dlls/user32/tests/class.c b/dlls/user32/tests/class.c index 4cee5f358d9..e6c841857cf 100644 --- a/dlls/user32/tests/class.c +++ b/dlls/user32/tests/class.c @@ -1780,8 +1780,8 @@ static void test_actctx_classes(void)
/* unversioned class redirects to the versioned class now */ check_atom_name_a( class, wc.lpszClassName ); - tmp_class = check_class_info_a_( __FILE__, __LINE__, hinst, MAKEINTRESOURCEA( class ), &wc_versioned, TRUE ); - todo_wine check_atom_name_a( tmp_class, wc_versioned.lpszClassName ); + tmp_class = check_class_info_a( hinst, MAKEINTRESOURCEA( class ), &wc_versioned ); + check_atom_name_a( tmp_class, wc_versioned.lpszClassName ); tmp_class = check_class_info_a( hinst, wc.lpszClassName, &wc_versioned ); check_atom_name_a( tmp_class, wc_versioned.lpszClassName ); check_atom_name_a( class_versioned, wc_versioned.lpszClassName ); @@ -1800,7 +1800,7 @@ static void test_actctx_classes(void) ret = UnregisterClassA( wc_versioned.lpszClassName, hinst ); ok( ret, "UnregisterClassA failed, error %lu\n", GetLastError() ); check_atom_name_a( class, wc.lpszClassName ); - todo_wine check_class_info_a( hinst, MAKEINTRESOURCEA( class ), NULL ); + check_class_info_a( hinst, MAKEINTRESOURCEA( class ), NULL ); check_class_info_a( hinst, wc.lpszClassName, NULL ); check_atom_name_a( class_versioned, NULL ); check_class_info_a( hinst, MAKEINTRESOURCEA( class_versioned ), NULL ); @@ -1847,7 +1847,7 @@ static void test_actctx_classes(void)
/* unversioned class is innaccessible now */ check_atom_name_a( class, wc_leak.lpszClassName ); - todo_wine check_class_info_a( hinst, MAKEINTRESOURCEA( class ), NULL ); + check_class_info_a( hinst, MAKEINTRESOURCEA( class ), NULL ); check_class_info_a( hinst, wc_leak.lpszClassName, NULL ); check_class_info_a( hinst, wc_leak_versioned.lpszClassName, NULL );
@@ -1856,7 +1856,7 @@ static void test_actctx_classes(void) todo_wine ok( tmp_class == class, "RegisterClassA failed, error %lu\n", GetLastError() ); check_atom_name_a( class, wc_leak.lpszClassName ); tmp_class = check_class_info_a( hinst, MAKEINTRESOURCEA( class ), &wc_leak ); - check_atom_name_a( tmp_class, wc_leak.lpszClassName ); + todo_wine check_atom_name_a( tmp_class, wc_leak.lpszClassName ); tmp_class = check_class_info_a( hinst, wc_leak.lpszClassName, &wc_leak ); todo_wine check_atom_name_a( tmp_class, wc_leak.lpszClassName ); tmp_class = check_class_info_a( hinst, wc_leak_versioned.lpszClassName, &wc ); @@ -1866,7 +1866,7 @@ static void test_actctx_classes(void) ret = UnregisterClassA( wc_leak.lpszClassName, hinst ); ok( ret, "UnregisterClassA failed, error %lu\n", GetLastError() ); check_atom_name_a( class, wc_leak.lpszClassName ); - todo_wine check_class_info_a( hinst, MAKEINTRESOURCEA( class ), NULL ); + check_class_info_a( hinst, MAKEINTRESOURCEA( class ), NULL ); check_class_info_a( hinst, wc_leak.lpszClassName, NULL ); check_class_info_a( hinst, wc_leak_versioned.lpszClassName, NULL );
@@ -1874,24 +1874,24 @@ static void test_actctx_classes(void) ret = UnregisterClassA( wc_leak.lpszClassName, hinst ); ok( !ret, "UnregisterClassA succeeded\n" ); ret = UnregisterClassA( MAKEINTRESOURCEA( class ), hinst ); - todo_wine ok( !ret, "UnregisterClassA succeeded\n" ); - todo_wine check_atom_name_a( class, wc_leak.lpszClassName ); + ok( !ret, "UnregisterClassA succeeded\n" ); + check_atom_name_a( class, wc_leak.lpszClassName ); check_class_info_a( hinst, MAKEINTRESOURCEA( class ), NULL ); check_class_info_a( hinst, wc_leak.lpszClassName, NULL ); check_class_info_a( hinst, wc_leak_versioned.lpszClassName, NULL );
ret = DeactivateActCtx( 0, cookie ); ok( ret, "DeactivateActCtx failed, error %lu\n", GetLastError() ); - todo_wine check_atom_name_a( class, wc_leak.lpszClassName ); - todo_wine tmp_class = check_class_info_a( hinst, MAKEINTRESOURCEA( class ), &wc_leak ); - todo_wine check_atom_name_a( tmp_class, wc_leak.lpszClassName ); - todo_wine tmp_class = check_class_info_a( hinst, wc_leak.lpszClassName, &wc_leak ); - todo_wine check_atom_name_a( tmp_class, wc_leak.lpszClassName ); + check_atom_name_a( class, wc_leak.lpszClassName ); + tmp_class = check_class_info_a( hinst, MAKEINTRESOURCEA( class ), &wc_leak ); + check_atom_name_a( tmp_class, wc_leak.lpszClassName ); + tmp_class = check_class_info_a( hinst, wc_leak.lpszClassName, &wc_leak ); + check_atom_name_a( tmp_class, wc_leak.lpszClassName ); check_class_info_a( hinst, wc_leak_versioned.lpszClassName, NULL );
/* unversioned class can be unregistered now */ ret = UnregisterClassA( MAKEINTRESOURCEA( class ), hinst ); - todo_wine ok( ret, "UnregisterClassA failed, error %lu\n", GetLastError() ); + ok( ret, "UnregisterClassA failed, error %lu\n", GetLastError() ); ret = UnregisterClassA( MAKEINTRESOURCEA( class ), hinst ); ok( !ret, "UnregisterClassA failed, error %lu\n", GetLastError() ); /* base atom name is leaked */ @@ -2042,16 +2042,16 @@ static void test_actctx_classes(void) check_class_info_a( hinst, MAKEINTRESOURCEA(1234), NULL ); check_class_info_a( hinst, wc_integral.lpszClassName, NULL ); class = RegisterClassA( &wc_integral_int ); - ok( class == 1234, "RegisterClassA failed, error %lu\n", GetLastError() ); + todo_wine ok( class == 1234, "RegisterClassA failed, error %lu\n", GetLastError() ); tmp_class = check_class_info_a( hinst, MAKEINTRESOURCEA(1234), &wc_integral_int ); - ok( tmp_class == 1234, "GetClassInfoA failed, error %lu\n", GetLastError() ); - todo_wine tmp_class = check_class_info_a( hinst, wc_integral.lpszClassName, &wc_integral_int ); + todo_wine ok( tmp_class == 1234, "GetClassInfoA failed, error %lu\n", GetLastError() ); + tmp_class = check_class_info_a( hinst, wc_integral.lpszClassName, &wc_integral_int ); todo_wine ok( tmp_class == 1234, "GetClassInfoA failed, error %lu\n", GetLastError() ); ret = UnregisterClassA( MAKEINTRESOURCEA( class ), hinst ); ok( ret, "UnregisterClassA failed, error %lu\n", GetLastError() ); class = RegisterClassA( &wc_integral ); todo_wine ok( class == 1234, "RegisterClassA failed, error %lu\n", GetLastError() ); - todo_wine tmp_class = check_class_info_a( hinst, MAKEINTRESOURCEA(1234), &wc_integral ); + tmp_class = check_class_info_a( hinst, MAKEINTRESOURCEA(1234), &wc_integral ); todo_wine ok( tmp_class == 1234, "GetClassInfoA failed, error %lu\n", GetLastError() ); tmp_class = check_class_info_a( hinst, wc_integral.lpszClassName, &wc_integral ); todo_wine ok( tmp_class == 1234, "GetClassInfoA failed, error %lu\n", GetLastError() ); @@ -2063,7 +2063,7 @@ static void test_actctx_classes(void) ret = ActivateActCtx( context, &cookie ); ok( ret, "ActivateActCtx failed, error %lu\n", GetLastError() ); ret = UnregisterClassA( MAKEINTRESOURCEA(1234), hinst ); - todo_wine ok( ret, "UnregisterClassA failed, error %lu\n", GetLastError() ); + ok( ret, "UnregisterClassA failed, error %lu\n", GetLastError() ); class = RegisterClassA( &wc_integral ); todo_wine ok( class == 1234, "RegisterClassA failed, error %lu\n", GetLastError() ); ret = UnregisterClassA( wc_integral.lpszClassName, hinst ); @@ -2139,7 +2139,7 @@ static void test_actctx_classes(void) ok( ret, "ActivateActCtx failed, error %lu\n", GetLastError() );
/* unversioned class is innaccessible now */ - todo_wine check_class_info_a( hinst, MAKEINTRESOURCEA( class ), NULL ); + check_class_info_a( hinst, MAKEINTRESOURCEA( class ), NULL ); check_class_info_a( hinst, wc_integral.lpszClassName, NULL ); check_class_info_a( hinst, wc_integral_versioned.lpszClassName, NULL );
@@ -2148,7 +2148,7 @@ static void test_actctx_classes(void) todo_wine ok( tmp_class == class, "RegisterClassA failed, error %lu\n", GetLastError() );
tmp_class = check_class_info_a( hinst, MAKEINTRESOURCEA( class ), &wc_integral ); - ok( tmp_class == 1234, "GetClassInfoA failed, error %lu\n", GetLastError() ); + todo_wine ok( tmp_class == 1234, "GetClassInfoA failed, error %lu\n", GetLastError() ); tmp_class = check_class_info_a( hinst, wc_integral.lpszClassName, &wc_integral ); todo_wine ok( tmp_class == 1234, "GetClassInfoA failed, error %lu\n", GetLastError() ); tmp_class = check_class_info_a( hinst, wc_integral_versioned.lpszClassName, &wc_integral ); @@ -2161,12 +2161,12 @@ static void test_actctx_classes(void) ret = UnregisterClassA( wc_integral.lpszClassName, hinst ); ok( !ret, "UnregisterClassA succeeded\n" ); ret = UnregisterClassA( MAKEINTRESOURCEA( class ), hinst ); - todo_wine ok( !ret, "UnregisterClassA succeeded\n" ); + ok( !ret, "UnregisterClassA succeeded\n" ); ret = DeactivateActCtx( 0, cookie ); ok( ret, "DeactivateActCtx failed, error %lu\n", GetLastError() ); /* unversioned class can be unregistered now */ ret = UnregisterClassA( MAKEINTRESOURCEA( class ), hinst ); - todo_wine ok( ret, "UnregisterClassA failed, error %lu\n", GetLastError() ); + ok( ret, "UnregisterClassA failed, error %lu\n", GetLastError() );
/* class info is available by atom, versioned, base names when context is active */ diff --git a/dlls/win32u/class.c b/dlls/win32u/class.c index cafd39f7fea..4b1f69bcb41 100644 --- a/dlls/win32u/class.c +++ b/dlls/win32u/class.c @@ -1164,7 +1164,7 @@ BOOL needs_ime_window( HWND hwnd )
static const struct builtin_class_descr desktop_builtin_class = { - .name = MAKEINTRESOURCEA(DESKTOP_CLASS_ATOM), + .name = "#32769", /* DESKTOP_CLASS_ATOM */ .style = CS_DBLCLKS, .proc = NTUSER_WNDPROC_DESKTOP, .brush = (HBRUSH)(COLOR_BACKGROUND + 1), @@ -1204,7 +1204,7 @@ static const struct builtin_class_descr builtin_classes[] = }, /* dialog */ { - .name = MAKEINTRESOURCEA(DIALOG_CLASS_ATOM), + .name = "#32770", /* DIALOG_CLASS_ATOM */ .style = CS_SAVEBITS | CS_DBLCLKS, .proc = NTUSER_WNDPROC_DIALOG, .extra = DLGWINDOWEXTRA, @@ -1212,7 +1212,7 @@ static const struct builtin_class_descr builtin_classes[] = }, /* icon title */ { - .name = MAKEINTRESOURCEA(ICONTITLE_CLASS_ATOM), + .name = "#32772", /* ICONTITLE_CLASS_ATOM */ .proc = NTUSER_WNDPROC_ICONTITLE, .cursor = IDC_ARROW, }, @@ -1233,7 +1233,7 @@ static const struct builtin_class_descr builtin_classes[] = }, /* menu */ { - .name = MAKEINTRESOURCEA(POPUPMENU_CLASS_ATOM), + .name = "#32768", /* POPUPMENU_CLASS_ATOM */ .style = CS_DROPSHADOW | CS_SAVEBITS | CS_DBLCLKS, .proc = NTUSER_WNDPROC_MENU, .extra = sizeof(HMENU), @@ -1290,16 +1290,8 @@ static void register_builtin( const struct builtin_class_descr *descr ) class.hCursor = LoadImageW( 0, (const WCHAR *)descr->cursor, IMAGE_CURSOR, 0, 0, LR_SHARED | LR_DEFAULTSIZE );
- if (IS_INTRESOURCE( descr->name )) - { - name.Buffer = (WCHAR *)descr->name; - name.Length = name.MaximumLength = 0; - } - else - { - asciiz_to_unicode( nameW, descr->name ); - RtlInitUnicodeString( &name, nameW ); - } + asciiz_to_unicode( nameW, descr->name ); + RtlInitUnicodeString( &name, nameW );
if (!NtUserRegisterClassExWOW( &class, &name, &version, &menu_name, 1, 0, NULL ) && class.hCursor) NtUserDestroyCursor( class.hCursor, 0 ); diff --git a/dlls/win32u/menu.c b/dlls/win32u/menu.c index bce8e0af79b..c3917ab391c 100644 --- a/dlls/win32u/menu.c +++ b/dlls/win32u/menu.c @@ -3324,7 +3324,8 @@ static void init_sys_menu_popup( HMENU hmenu, DWORD style, DWORD class_style )
static BOOL init_popup( HWND owner, HMENU hmenu, UINT flags ) { - UNICODE_STRING class_name = { .Buffer = MAKEINTRESOURCEW( POPUPMENU_CLASS_ATOM ) }; + static const WCHAR atomW[] = {'#','3','2','7','6','8',0}; /* POPUPMENU_CLASS_ATOM */ + UNICODE_STRING class_name = RTL_CONSTANT_STRING(atomW); DWORD ex_style = 0; struct menu *menu;
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/class.c | 32 +++++--------------------------- 1 file changed, 5 insertions(+), 27 deletions(-)
diff --git a/dlls/win32u/class.c b/dlls/win32u/class.c index 4b1f69bcb41..6695c06acbb 100644 --- a/dlls/win32u/class.c +++ b/dlls/win32u/class.c @@ -315,16 +315,12 @@ atom_t wine_server_add_atom( void *req, UNICODE_STRING *str ) 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) ); }
@@ -404,7 +400,6 @@ static void release_class_ptr( CLASS *ptr )
static CLASS *find_class( HINSTANCE module, UNICODE_STRING *name ) { - ATOM atom = get_int_atom_value( name ); ULONG_PTR instance = (UINT_PTR)module; CLASS *class; int is_win16; @@ -412,15 +407,8 @@ static CLASS *find_class( HINSTANCE module, UNICODE_STRING *name ) user_lock(); LIST_FOR_EACH_ENTRY( class, &class_list, CLASS, entry ) { - if (atom) - { - if (class->atomName != atom) continue; - } - else - { - if (wcsnicmp( class->name, name->Buffer, name->Length / sizeof(WCHAR) ) || - class->name[name->Length / sizeof(WCHAR)]) continue; - } + if (wcsnicmp( class->name, name->Buffer, name->Length / sizeof(WCHAR) ) || + class->name[name->Length / sizeof(WCHAR)]) continue; is_win16 = !(class->instance >> 16); if (!instance || !class->local || class->instance == instance || (!is_win16 && ((class->instance & ~0xffff) == (instance & ~0xffff)))) @@ -496,19 +484,9 @@ 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) - { - memcpy( class->name, name->Buffer, name->Length ); - class->name[name->Length / sizeof(WCHAR)] = 0; - class->basename += version->Length / sizeof(WCHAR); - } - else - { - UNICODE_STRING str = { .MaximumLength = sizeof(class->name), .Buffer = class->name }; - NtUserGetAtomName( class->atomName, &str ); - } + memcpy( class->name, name->Buffer, name->Length ); + class->name[name->Length / sizeof(WCHAR)] = 0; + class->basename = class->name + version->Length / sizeof(WCHAR);
class->style = wc->style; class->local = !is_builtin && !(wc->style & CS_GLOBALCLASS);
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/user32/tests/class.c | 104 +++++++++++++++++++------------------- dlls/win32u/class.c | 13 +++-- server/atom.c | 21 ++++++++ server/class.c | 3 +- server/protocol.def | 3 +- 5 files changed, 80 insertions(+), 64 deletions(-)
diff --git a/dlls/user32/tests/class.c b/dlls/user32/tests/class.c index e6c841857cf..38490ae2049 100644 --- a/dlls/user32/tests/class.c +++ b/dlls/user32/tests/class.c @@ -1659,9 +1659,9 @@ static void test_actctx_classes(void) check_class_info_a( hinst, wc.lpszClassName, NULL ); class = RegisterClassA( &wc_double_version ); ok( class != 0, "RegisterClassA failed, error %lu\n", GetLastError() ); - todo_wine check_atom_name_a( class, wc_double_version.lpszClassName ); + check_atom_name_a( class, wc_double_version.lpszClassName ); tmp_class = check_class_info_a( hinst, "4.3.2.1!4.3.2.1!ClassVersion", &wc_double_version ); - todo_wine check_atom_name_a( tmp_class, "4.3.2.1!ClassVersion" ); + check_atom_name_a( tmp_class, "4.3.2.1!ClassVersion" ); ret = UnregisterClassA( "4.3.2.1!4.3.2.1!ClassVersion", hinst ); ok( ret, "UnregisterClassA failed, error %lu\n", GetLastError() ); check_atom_name_a( class, NULL ); @@ -1677,13 +1677,13 @@ static void test_actctx_classes(void) check_class_info_a( hinst, wc.lpszClassName, NULL ); class = RegisterClassA( &wc ); ok( class != 0, "RegisterClassA failed, error %lu\n", GetLastError() ); - todo_wine check_atom_name_a( class, wc.lpszClassName ); + check_atom_name_a( class, wc.lpszClassName ); tmp_class = check_class_info_a( hinst, MAKEINTRESOURCEA( class ), &wc ); - todo_wine check_atom_name_a( tmp_class, wc.lpszClassName ); + check_atom_name_a( tmp_class, wc.lpszClassName ); ret = DeactivateActCtx( 0, cookie ); ok( ret, "DeactivateActCtx failed, error %lu\n", GetLastError() ); - todo_wine check_atom_name_a( class, wc.lpszClassName ); - todo_wine check_class_info_a( hinst, MAKEINTRESOURCEA( class ), NULL ); + check_atom_name_a( class, wc.lpszClassName ); + check_class_info_a( hinst, MAKEINTRESOURCEA( class ), NULL );
/* when context is active, UnregisterClassA is possible by atom, versioned, base names */ @@ -1712,11 +1712,11 @@ static void test_actctx_classes(void)
/* when context isn't active, UnregisterClassA is possible by versioned name only */ ret = UnregisterClassA( MAKEINTRESOURCEA( class ), hinst ); - todo_wine ok( !ret, "UnregisterClassA succeeded\n" ); + ok( !ret, "UnregisterClassA succeeded\n" ); ret = UnregisterClassA( wc.lpszClassName, hinst ); ok( !ret, "UnregisterClassA succeeded\n" ); ret = UnregisterClassA( wc_versioned.lpszClassName, hinst ); - todo_wine ok( ret, "UnregisterClassA failed, error %lu\n", GetLastError() ); + ok( ret, "UnregisterClassA failed, error %lu\n", GetLastError() );
/* registering versioned class while context isn't active */ @@ -1853,14 +1853,14 @@ static void test_actctx_classes(void)
/* versioned class can be registered when context is active, returns same atom as unversioned */ tmp_class = RegisterClassA( &wc_leak ); - todo_wine ok( tmp_class == class, "RegisterClassA failed, error %lu\n", GetLastError() ); + ok( tmp_class == class, "RegisterClassA failed, error %lu\n", GetLastError() ); check_atom_name_a( class, wc_leak.lpszClassName ); tmp_class = check_class_info_a( hinst, MAKEINTRESOURCEA( class ), &wc_leak ); - todo_wine check_atom_name_a( tmp_class, wc_leak.lpszClassName ); + check_atom_name_a( tmp_class, wc_leak.lpszClassName ); tmp_class = check_class_info_a( hinst, wc_leak.lpszClassName, &wc_leak ); - todo_wine check_atom_name_a( tmp_class, wc_leak.lpszClassName ); + check_atom_name_a( tmp_class, wc_leak.lpszClassName ); tmp_class = check_class_info_a( hinst, wc_leak_versioned.lpszClassName, &wc ); - todo_wine check_atom_name_a( tmp_class, wc_leak.lpszClassName ); + check_atom_name_a( tmp_class, wc_leak.lpszClassName );
/* versioned class can be unregistered with its base name */ ret = UnregisterClassA( wc_leak.lpszClassName, hinst ); @@ -1906,22 +1906,22 @@ static void test_actctx_classes(void) ok( ret, "ActivateActCtx failed, error %lu\n", GetLastError() ); class = RegisterClassA( &wc ); ok( class != 0, "RegisterClassA failed, error %lu\n", GetLastError() ); - todo_wine check_atom_name_a( class, wc.lpszClassName ); + check_atom_name_a( class, wc.lpszClassName ); tmp_class = check_class_info_a( hinst, MAKEINTRESOURCEA( class ), &wc ); - todo_wine check_atom_name_a( tmp_class, wc.lpszClassName ); + check_atom_name_a( tmp_class, wc.lpszClassName ); tmp_class = check_class_info_a( hinst, wc.lpszClassName, &wc ); - todo_wine check_atom_name_a( tmp_class, wc.lpszClassName ); + check_atom_name_a( tmp_class, wc.lpszClassName ); tmp_class = check_class_info_a( hinst, wc_versioned.lpszClassName, &wc ); - todo_wine check_atom_name_a( tmp_class, wc.lpszClassName ); + check_atom_name_a( tmp_class, wc.lpszClassName );
/* when context isn't active, class info is available by versioned name only */ ret = DeactivateActCtx( 0, cookie ); ok( ret, "DeactivateActCtx failed, error %lu\n", GetLastError() ); - todo_wine check_atom_name_a( class, wc.lpszClassName ); - todo_wine check_class_info_a( hinst, MAKEINTRESOURCEA( class ), NULL ); + check_atom_name_a( class, wc.lpszClassName ); + check_class_info_a( hinst, MAKEINTRESOURCEA( class ), NULL ); check_class_info_a( hinst, wc.lpszClassName, NULL ); tmp_class = check_class_info_a( hinst, wc_versioned.lpszClassName, &wc ); - todo_wine check_atom_name_a( tmp_class, wc.lpszClassName ); + check_atom_name_a( tmp_class, wc.lpszClassName );
/* when context is active, CreateWindow is allowed by atom, versioned, base names */ @@ -1944,8 +1944,7 @@ static void test_actctx_classes(void) ret = DeactivateActCtx( 0, cookie ); ok( ret, "DeactivateActCtx failed, error %lu\n", GetLastError() ); hwnd = CreateWindowExA( 0, MAKEINTRESOURCEA( class ), NULL, 0, 0, 0, 0, 0, 0, 0, hinst, 0 ); - todo_wine ok( !hwnd, "CreateWindowExA succeeded\n" ); - if (hwnd) DestroyWindow( hwnd ); + ok( !hwnd, "CreateWindowExA succeeded\n" ); hwnd = CreateWindowExA( 0, wc.lpszClassName, NULL, 0, 0, 0, 0, 0, 0, 0, hinst, 0 ); ok( !hwnd, "CreateWindowExA succeeded\n" ); hwnd = CreateWindowExA( 0, wc_versioned.lpszClassName, NULL, 0, 0, 0, 0, 0, 0, 0, hinst, 0 ); @@ -1999,12 +1998,12 @@ static void test_actctx_classes(void) ok( ret, "ActivateActCtx failed, error %lu\n", GetLastError() ); class = RegisterClassA( &wc ); ok( class != 0, "RegisterClassA failed, error %lu\n", GetLastError() ); - todo_wine check_atom_name_a( class, wc.lpszClassName ); + check_atom_name_a( class, wc.lpszClassName );
hwnd = CreateWindowExA( 0, wc_versioned.lpszClassName, NULL, 0, 0, 0, 0, 0, 0, 0, hinst, 0 ); ok( hwnd != NULL, "CreateWindowExA failed, error %lu\n", GetLastError() ); tmp_hwnd = FindWindowExA( NULL, NULL, MAKEINTRESOURCEA( class ), 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.lpszClassName, NULL ); ok( tmp_hwnd == hwnd, "FindWindowExA returned %p, error %lu\n", tmp_hwnd, GetLastError() ); tmp_hwnd = FindWindowExA(NULL, NULL, wc_versioned.lpszClassName, NULL); @@ -2014,7 +2013,7 @@ static void test_actctx_classes(void) ok( ret, "DeactivateActCtx failed, error %lu\n", GetLastError() );
tmp_hwnd = FindWindowExA( NULL, NULL, MAKEINTRESOURCEA( class ), 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.lpszClassName, NULL ); ok( tmp_hwnd == hwnd, "FindWindowExA returned %p, error %lu\n", tmp_hwnd, GetLastError() ); tmp_hwnd = FindWindowExA(NULL, NULL, wc_versioned.lpszClassName, NULL); @@ -2024,7 +2023,7 @@ static void test_actctx_classes(void) hwnd = CreateWindowExA( 0, wc_versioned.lpszClassName, NULL, 0, 0, 0, 0, 0, 0, 0, hinst, 0 ); ok( hwnd != NULL, "CreateWindowExA failed, error %lu\n", GetLastError() ); tmp_hwnd = FindWindowExA( NULL, NULL, MAKEINTRESOURCEA( class ), 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.lpszClassName, NULL ); ok( tmp_hwnd == hwnd, "FindWindowExA returned %p, error %lu\n", tmp_hwnd, GetLastError() ); tmp_hwnd = FindWindowExA( NULL, NULL, wc_versioned.lpszClassName, NULL ); @@ -2042,19 +2041,19 @@ static void test_actctx_classes(void) check_class_info_a( hinst, MAKEINTRESOURCEA(1234), NULL ); check_class_info_a( hinst, wc_integral.lpszClassName, NULL ); class = RegisterClassA( &wc_integral_int ); - todo_wine ok( class == 1234, "RegisterClassA failed, error %lu\n", GetLastError() ); + ok( class == 1234, "RegisterClassA failed, error %lu\n", GetLastError() ); tmp_class = check_class_info_a( hinst, MAKEINTRESOURCEA(1234), &wc_integral_int ); - todo_wine ok( tmp_class == 1234, "GetClassInfoA failed, error %lu\n", GetLastError() ); + ok( tmp_class == 1234, "GetClassInfoA failed, error %lu\n", GetLastError() ); tmp_class = check_class_info_a( hinst, wc_integral.lpszClassName, &wc_integral_int ); - todo_wine ok( tmp_class == 1234, "GetClassInfoA failed, error %lu\n", GetLastError() ); + ok( tmp_class == 1234, "GetClassInfoA failed, error %lu\n", GetLastError() ); ret = UnregisterClassA( MAKEINTRESOURCEA( class ), hinst ); ok( ret, "UnregisterClassA failed, error %lu\n", GetLastError() ); class = RegisterClassA( &wc_integral ); - todo_wine ok( class == 1234, "RegisterClassA failed, error %lu\n", GetLastError() ); + ok( class == 1234, "RegisterClassA failed, error %lu\n", GetLastError() ); tmp_class = check_class_info_a( hinst, MAKEINTRESOURCEA(1234), &wc_integral ); - todo_wine ok( tmp_class == 1234, "GetClassInfoA failed, error %lu\n", GetLastError() ); + ok( tmp_class == 1234, "GetClassInfoA failed, error %lu\n", GetLastError() ); tmp_class = check_class_info_a( hinst, wc_integral.lpszClassName, &wc_integral ); - todo_wine ok( tmp_class == 1234, "GetClassInfoA failed, error %lu\n", GetLastError() ); + ok( tmp_class == 1234, "GetClassInfoA failed, error %lu\n", GetLastError() ); ret = DeactivateActCtx( 0, cookie ); ok( ret, "DeactivateActCtx failed, error %lu\n", GetLastError() );
@@ -2065,15 +2064,15 @@ static void test_actctx_classes(void) ret = UnregisterClassA( MAKEINTRESOURCEA(1234), hinst ); ok( ret, "UnregisterClassA failed, error %lu\n", GetLastError() ); class = RegisterClassA( &wc_integral ); - todo_wine ok( class == 1234, "RegisterClassA failed, error %lu\n", GetLastError() ); + ok( class == 1234, "RegisterClassA failed, error %lu\n", GetLastError() ); ret = UnregisterClassA( wc_integral.lpszClassName, hinst ); ok( ret, "UnregisterClassA failed, error %lu\n", GetLastError() ); class = RegisterClassA( &wc_integral ); - todo_wine ok( class == 1234, "RegisterClassA failed, error %lu\n", GetLastError() ); + ok( class == 1234, "RegisterClassA failed, error %lu\n", GetLastError() ); ret = UnregisterClassA( wc_integral_versioned.lpszClassName, hinst ); ok( ret, "UnregisterClassA failed, error %lu\n", GetLastError() ); class = RegisterClassA( &wc_integral ); - todo_wine ok( class == 1234, "RegisterClassA failed, error %lu\n", GetLastError() ); + ok( class == 1234, "RegisterClassA failed, error %lu\n", GetLastError() ); ret = DeactivateActCtx( 0, cookie ); ok( ret, "DeactivateActCtx failed, error %lu\n", GetLastError() );
@@ -2145,14 +2144,14 @@ static void test_actctx_classes(void)
/* versioned class can be registered when context is active, returns same atom as unversioned */ tmp_class = RegisterClassA( &wc_integral ); - todo_wine ok( tmp_class == class, "RegisterClassA failed, error %lu\n", GetLastError() ); + ok( tmp_class == class, "RegisterClassA failed, error %lu\n", GetLastError() );
tmp_class = check_class_info_a( hinst, MAKEINTRESOURCEA( class ), &wc_integral ); - todo_wine ok( tmp_class == 1234, "GetClassInfoA failed, error %lu\n", GetLastError() ); + ok( tmp_class == 1234, "GetClassInfoA failed, error %lu\n", GetLastError() ); tmp_class = check_class_info_a( hinst, wc_integral.lpszClassName, &wc_integral ); - todo_wine ok( tmp_class == 1234, "GetClassInfoA failed, error %lu\n", GetLastError() ); + ok( tmp_class == 1234, "GetClassInfoA failed, error %lu\n", GetLastError() ); tmp_class = check_class_info_a( hinst, wc_integral_versioned.lpszClassName, &wc_integral ); - todo_wine ok( tmp_class == 1234, "GetClassInfoA failed, error %lu\n", GetLastError() ); + ok( tmp_class == 1234, "GetClassInfoA failed, error %lu\n", GetLastError() );
/* versioned class can be unregistered with its base name */ ret = UnregisterClassA( wc_integral.lpszClassName, hinst ); @@ -2173,21 +2172,21 @@ static void test_actctx_classes(void) ret = ActivateActCtx( context, &cookie ); ok( ret, "ActivateActCtx failed, error %lu\n", GetLastError() ); class = RegisterClassA( &wc_integral ); - todo_wine ok( class == 1234, "RegisterClassA failed, error %lu\n", GetLastError() ); + ok( class == 1234, "RegisterClassA failed, error %lu\n", GetLastError() ); tmp_class = check_class_info_a( hinst, MAKEINTRESOURCEA( class ), &wc_integral ); - todo_wine ok( tmp_class == 1234, "GetClassInfoA failed, error %lu\n", GetLastError() ); + ok( tmp_class == 1234, "GetClassInfoA failed, error %lu\n", GetLastError() ); tmp_class = check_class_info_a( hinst, wc_integral.lpszClassName, &wc_integral ); - todo_wine ok( tmp_class == 1234, "GetClassInfoA failed, error %lu\n", GetLastError() ); + ok( tmp_class == 1234, "GetClassInfoA failed, error %lu\n", GetLastError() ); tmp_class = check_class_info_a( hinst, wc_integral_versioned.lpszClassName, &wc_integral ); - todo_wine ok( tmp_class == 1234, "GetClassInfoA failed, error %lu\n", GetLastError() ); + ok( tmp_class == 1234, "GetClassInfoA failed, error %lu\n", GetLastError() );
/* class info is available by versioned name only, if context isn't active. */ ret = DeactivateActCtx( 0, cookie ); ok( ret, "DeactivateActCtx failed, error %lu\n", GetLastError() ); - todo_wine check_class_info_a( hinst, MAKEINTRESOURCEA( class ), NULL ); + check_class_info_a( hinst, MAKEINTRESOURCEA( class ), NULL ); check_class_info_a( hinst, wc_integral.lpszClassName, NULL ); tmp_class = check_class_info_a( hinst, wc_integral_versioned.lpszClassName, &wc_integral ); - todo_wine ok( tmp_class == 1234, "GetClassInfoA failed, error %lu\n", GetLastError() ); + ok( tmp_class == 1234, "GetClassInfoA failed, error %lu\n", GetLastError() );
/* CreateWindow is allowed by atom, versioned, base names when context is active */ @@ -2210,8 +2209,7 @@ static void test_actctx_classes(void) ret = DeactivateActCtx( 0, cookie ); ok( ret, "DeactivateActCtx failed, error %lu\n", GetLastError() ); hwnd = CreateWindowExA( 0, MAKEINTRESOURCEA( class ), NULL, 0, 0, 0, 0, 0, 0, 0, hinst, 0 ); - todo_wine ok( !hwnd, "CreateWindowExA succeeded\n" ); - if (hwnd) DestroyWindow( hwnd ); + ok( !hwnd, "CreateWindowExA succeeded\n" ); hwnd = CreateWindowExA( 0, wc_integral.lpszClassName, NULL, 0, 0, 0, 0, 0, 0, 0, hinst, 0 ); ok( !hwnd, "CreateWindowExA succeeded\n" ); hwnd = CreateWindowExA( 0, wc_integral_versioned.lpszClassName, NULL, 0, 0, 0, 0, 0, 0, 0, hinst, 0 ); @@ -2263,14 +2261,14 @@ static void test_actctx_classes(void) ret = ActivateActCtx( context, &cookie ); ok( ret, "ActivateActCtx failed, error %lu\n", GetLastError() ); class = RegisterClassA( &wc_integral ); - todo_wine ok( class == 1234, "RegisterClassA failed, error %lu\n", GetLastError() ); + ok( class == 1234, "RegisterClassA failed, error %lu\n", GetLastError() );
hwnd = CreateWindowExA( 0, wc_integral_versioned.lpszClassName, NULL, 0, 0, 0, 0, 0, 0, 0, hinst, 0 ); ok( hwnd != NULL, "CreateWindowExA failed, error %lu\n", GetLastError() ); tmp_hwnd = FindWindowExA( NULL, NULL, MAKEINTRESOURCEA( class ), 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.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() );
@@ -2278,9 +2276,9 @@ static void test_actctx_classes(void) ok( ret, "DeactivateActCtx failed, error %lu\n", GetLastError() );
tmp_hwnd = FindWindowExA( NULL, NULL, MAKEINTRESOURCEA( class ), 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.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 ); @@ -2288,9 +2286,9 @@ static void test_actctx_classes(void) hwnd = CreateWindowExA( 0, wc_integral_versioned.lpszClassName, NULL, 0, 0, 0, 0, 0, 0, 0, hinst, 0 ); ok( hwnd != NULL, "CreateWindowExA failed, error %lu\n", GetLastError() ); tmp_hwnd = FindWindowExA( NULL, NULL, MAKEINTRESOURCEA( class ), 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.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/dlls/win32u/class.c b/dlls/win32u/class.c index 6695c06acbb..3f241501e83 100644 --- a/dlls/win32u/class.c +++ b/dlls/win32u/class.c @@ -59,7 +59,7 @@ typedef struct tagCLASS HICON hIconSmIntern; /* Internal small icon, derived from hIcon */ HCURSOR hCursor; /* Default cursor */ HBRUSH hbrBackground; /* Default background */ - ATOM atomName; /* Name of the class */ + ATOM atom; /* name of the class */ WCHAR name[MAX_ATOM_LEN + 1]; WCHAR *basename; /* Base name for redirected classes, pointer within 'name'. */ struct client_menu_name menu_name; /* Default menu name */ @@ -505,7 +505,7 @@ ATOM WINAPI NtUserRegisterClassExWOW( const WNDCLASSEXW *wc, UNICODE_STRING *nam req->atom = wine_server_add_atom( req, name ); req->name_offset = version->Length / sizeof(WCHAR); ret = !wine_server_call_err( req ); - class->atomName = reply->atom; + atom = reply->atom; } SERVER_END_REQ; if (!ret) @@ -525,8 +525,6 @@ ATOM WINAPI NtUserRegisterClassExWOW( const WNDCLASSEXW *wc, UNICODE_STRING *nam if (class->local) list_add_head( &class_list, &class->entry ); else list_add_tail( &class_list, &class->entry );
- atom = class->atomName; - TRACE( "name=%s->%s atom=%04x wndproc=%p hinst=%p bg=%p style=%08x clsExt=%d winExt=%d class=%p\n", debugstr_w(wc->lpszClassName), debugstr_us(name), atom, wc->lpfnWndProc, instance, wc->hbrBackground, wc->style, wc->cbClsExtra, wc->cbWndExtra, class ); @@ -536,6 +534,7 @@ ATOM WINAPI NtUserRegisterClassExWOW( const WNDCLASSEXW *wc, UNICODE_STRING *nam class->hIconSmIntern = sm_icon; class->hCursor = wc->hCursor; class->hbrBackground = wc->hbrBackground; + class->atom = atom; class->winproc = alloc_winproc( wc->lpfnWndProc, ansi ); if (client_menu_name) class->menu_name = *client_menu_name; release_class_ptr( class ); @@ -606,7 +605,7 @@ ATOM WINAPI NtUserGetClassInfoEx( HINSTANCE instance, UNICODE_STRING *name, WNDC }
if (menu_name) *menu_name = class->menu_name; - atom = class->atomName; + atom = class->atom; release_class_ptr( class ); return atom; } @@ -719,7 +718,7 @@ INT WINAPI NtUserGetClassName( HWND hwnd, BOOL real, UNICODE_STRING *name ) req->extra_offset = -1; req->extra_size = 0; if (!wine_server_call_err( req )) - atom = reply->base_atom; + atom = reply->old_atom; } SERVER_END_REQ;
@@ -1076,7 +1075,7 @@ static ULONG_PTR get_class_long_size( HWND hwnd, INT offset, UINT size, BOOL ans retvalue = ansi ? (ULONG_PTR)class->menu_name.nameA : (ULONG_PTR)class->menu_name.nameW; break; case GCW_ATOM: - retvalue = class->atomName; + retvalue = class->atom; break; default: RtlSetLastWin32Error( ERROR_INVALID_INDEX ); diff --git a/server/atom.c b/server/atom.c index 41b2f48928d..2995ee0b2d9 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 ))) diff --git a/server/class.c b/server/class.c index c98c171e035..3b2d38a3bfd 100644 --- a/server/class.c +++ b/server/class.c @@ -212,7 +212,7 @@ DECL_HANDLER(create_class) class->style = req->style; class->win_extra = req->win_extra; class->client_ptr = req->client_ptr; - reply->atom = atom; + reply->atom = base_atom; }
/* destroy a window class */ @@ -277,7 +277,6 @@ DECL_HANDLER(set_class_info) reply->old_extra = class->nb_extra_bytes; reply->old_win_extra = class->win_extra; reply->old_instance = class->instance; - reply->base_atom = class->base_atom;
if (req->flags & SET_CLASS_STYLE) class->style = req->style; if (req->flags & SET_CLASS_WINEXTRA) class->win_extra = req->win_extra; diff --git a/server/protocol.def b/server/protocol.def index f7f4d463b7d..1d8ef4ac930 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -3262,8 +3262,7 @@ enum caret_state data_size_t extra_size; /* size to set in extra bytes */ lparam_t extra_value; /* value to set in extra bytes */ @REPLY - atom_t old_atom; /* previous class atom */ - atom_t base_atom; /* base class atom */ + atom_t old_atom; /* previous class base atom */ mod_handle_t old_instance; /* previous module instance */ lparam_t old_extra_value; /* old value in extra bytes */ unsigned int old_style; /* previous class style */
v2: Also get rid of now unnecessary `set_class_info` base_atom member, the returned class atom is always the base atom.
Alexandre Julliard (@julliard) commented about server/atom.c:
- 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;
+}
Shouldn't that be handled client-side now?
On Mon Aug 25 19:47:14 2025 +0000, Alexandre Julliard wrote:
Shouldn't that be handled client-side now?
With integral class versioning there are still cases where we need to send the class name as string to server (because it has a version number) but the base atom is an integral atom nonetheless.
On Mon Aug 25 20:01:19 2025 +0000, Rémi Bernon wrote:
With integral class versioning there are still cases where we need to send the class name as string to server (because it has a version number) but the base atom is an integral atom nonetheless.
I see, thanks. Note that IS_INTRESOURCE doesn't make sense on the server side.
On Mon Aug 25 20:17:32 2025 +0000, Alexandre Julliard wrote:
I see, thanks. Note that IS_INTRESOURCE doesn't make sense on the server side.
Yes, though I didn't want to introduce a difference in the helper which is copied around several times already. I can remove it if it matters.