From: Rémi Bernon rbernon@codeweavers.com
--- dlls/user32/class.c | 99 +++++++++++++++++++++------------------------ dlls/user32/win.c | 7 +++- 2 files changed, 50 insertions(+), 56 deletions(-)
diff --git a/dlls/user32/class.c b/dlls/user32/class.c index 156881fe253..dedba766921 100644 --- a/dlls/user32/class.c +++ b/dlls/user32/class.c @@ -120,6 +120,19 @@ static BOOL is_builtin_class( const WCHAR *name ) return FALSE; }
+static void init_class_name_ansi( UNICODE_STRING *str, const char *name ) +{ + if (IS_INTRESOURCE( name )) + { + str->Buffer = (WCHAR *)name; + str->Length = str->MaximumLength = 0; + } + else + { + UINT len = MultiByteToWideChar( CP_ACP, 0, name, -1, str->Buffer, str->MaximumLength / sizeof(WCHAR) ); + str->Length = (len - 1) * sizeof(WCHAR); + } +}
void init_class_name( UNICODE_STRING *str, const WCHAR *name ) { @@ -128,7 +141,11 @@ void init_class_name( UNICODE_STRING *str, const WCHAR *name ) str->Buffer = (WCHAR *)name; str->Length = str->MaximumLength = 0; } - else RtlInitUnicodeString( str, name ); + else + { + str->Length = min( str->MaximumLength, wcslen( name ) * sizeof(WCHAR) ); + memcpy( str->Buffer, name, str->Length + sizeof(WCHAR) ); + } }
static BOOL alloc_menu_nameA( struct client_menu_name *ret, const char *menu_name ) @@ -200,7 +217,7 @@ void get_class_version( UNICODE_STRING *name, UNICODE_STRING *version, BOOL load const WCHAR *class_name = name->Buffer; HMODULE hmod = NULL;
- if (version) version->Length = 0; + memset( version, 0, sizeof(*version) );
if (IS_INTRESOURCE( name->Buffer ) || is_builtin_class( name->Buffer )) return;
@@ -220,26 +237,18 @@ void get_class_version( UNICODE_STRING *name, UNICODE_STRING *version, BOOL load ULONG module_offset; } *wndclass = (struct wndclass_redirect_data *)data.lpData; const WCHAR *module, *ptr; - UINT offset; - - offset = (wndclass->name_len - name->Length) / sizeof(WCHAR);
module = (const WCHAR *)((BYTE *)data.lpSectionBase + wndclass->module_offset); if (load && !(hmod = GetModuleHandleW( module ))) hmod = LoadLibraryW( module );
- /* Combined name is used to register versioned class name. Base name part will match exactly - original class name and won't be reused from context data. */ - ptr = (const WCHAR *)((BYTE *)wndclass + wndclass->name_offset); - if (version) - { - WCHAR *combined = version->Buffer; - memcpy( combined, ptr, offset * sizeof(WCHAR) ); - lstrcpyW( &combined[offset], name->Buffer ); - version->Length = offset * sizeof(WCHAR); - ptr = combined; - } + *version = *name; + version->Length = wndclass->name_len - name->Length; + class_name += version->Length / sizeof(WCHAR);
- init_class_name( name, ptr ); + ptr = (const WCHAR *)((BYTE *)wndclass + wndclass->name_offset); + memcpy( name->Buffer, ptr, wndclass->name_len ); + name->Length = wndclass->name_len; + name->Buffer[name->Length / sizeof(WCHAR)] = 0; }
if (load && hmod) @@ -247,7 +256,7 @@ void get_class_version( UNICODE_STRING *name, UNICODE_STRING *version, BOOL load BOOL (WINAPI *pRegisterClassNameW)( const WCHAR *class ); if ((pRegisterClassNameW = (void *)GetProcAddress( hmod, "RegisterClassNameW" ))) { - TRACE( "registering %s\n", debugstr_us(name) ); + TRACE( "registering %s version %s\n", debugstr_us(name), debugstr_us(version) ); pRegisterClassNameW( class_name ); } } @@ -342,19 +351,12 @@ ATOM WINAPI RegisterClassW( const WNDCLASSW* wc ) */ ATOM WINAPI RegisterClassExA( const WNDCLASSEXA* wc ) { - WCHAR nameW[MAX_ATOM_LEN + 1], combined[MAX_ATOM_LEN + 1]; struct client_menu_name menu_name; - UNICODE_STRING name, version; + WCHAR nameW[MAX_ATOM_LEN + 1]; + UNICODE_STRING name = RTL_CONSTANT_STRING(nameW), version; ATOM atom;
- version.Buffer = combined; - version.MaximumLength = sizeof(combined); - if (IS_INTRESOURCE( wc->lpszClassName )) init_class_name( &name, (const WCHAR *)wc->lpszClassName ); - else - { - if (!MultiByteToWideChar( CP_ACP, 0, wc->lpszClassName, -1, nameW, MAX_ATOM_LEN + 1 )) return 0; - RtlInitUnicodeString( &name, nameW ); - } + init_class_name_ansi( &name, wc->lpszClassName ); get_class_version( &name, &version, FALSE );
if (!alloc_menu_nameA( &menu_name, wc->lpszMenuName )) return 0; @@ -370,13 +372,11 @@ ATOM WINAPI RegisterClassExA( const WNDCLASSEXA* wc ) */ ATOM WINAPI RegisterClassExW( const WNDCLASSEXW* wc ) { - WCHAR combined[MAX_ATOM_LEN + 1]; struct client_menu_name menu_name; - UNICODE_STRING name, version; + WCHAR nameW[MAX_ATOM_LEN + 1]; + UNICODE_STRING name = RTL_CONSTANT_STRING(nameW), version; ATOM atom;
- version.Buffer = combined; - version.MaximumLength = sizeof(combined); init_class_name( &name, wc->lpszClassName ); get_class_version( &name, &version, FALSE );
@@ -395,16 +395,11 @@ BOOL WINAPI UnregisterClassA( LPCSTR class_name, HINSTANCE instance ) { struct client_menu_name menu_name; WCHAR nameW[MAX_ATOM_LEN + 1]; - UNICODE_STRING name; + UNICODE_STRING name = RTL_CONSTANT_STRING(nameW), version; BOOL ret;
- if (IS_INTRESOURCE( class_name )) init_class_name( &name, (const WCHAR *)class_name ); - else - { - if (!MultiByteToWideChar( CP_ACP, 0, class_name, -1, nameW, MAX_ATOM_LEN + 1 )) return 0; - RtlInitUnicodeString( &name, nameW ); - } - get_class_version( &name, NULL, FALSE ); + init_class_name_ansi( &name, class_name ); + get_class_version( &name, &version, FALSE );
ret = NtUserUnregisterClass( &name, instance, &menu_name ); if (ret) free_menu_name( &menu_name ); @@ -417,11 +412,12 @@ BOOL WINAPI UnregisterClassA( LPCSTR class_name, HINSTANCE instance ) BOOL WINAPI UnregisterClassW( LPCWSTR class_name, HINSTANCE instance ) { struct client_menu_name menu_name; - UNICODE_STRING name; + WCHAR nameW[MAX_ATOM_LEN + 1]; + UNICODE_STRING name = RTL_CONSTANT_STRING(nameW), version; BOOL ret;
init_class_name( &name, class_name ); - get_class_version( &name, NULL, FALSE ); + get_class_version( &name, &version, FALSE );
ret = NtUserUnregisterClass( &name, instance, &menu_name ); if (ret) free_menu_name( &menu_name ); @@ -575,7 +571,8 @@ BOOL WINAPI GetClassInfoW( HINSTANCE hInstance, LPCWSTR name, WNDCLASSW *wc ) */ BOOL WINAPI GetClassInfoExA( HINSTANCE instance, const char *class_name, WNDCLASSEXA *wc ) { - UNICODE_STRING name; + WCHAR nameW[MAX_ATOM_LEN + 1]; + UNICODE_STRING name = RTL_CONSTANT_STRING(nameW), version; ATOM atom;
TRACE( "%p %s %p\n", instance, debugstr_a(class_name), wc ); @@ -586,15 +583,8 @@ BOOL WINAPI GetClassInfoExA( HINSTANCE instance, const char *class_name, WNDCLAS return FALSE; }
- if (IS_INTRESOURCE( class_name )) init_class_name( &name, (const WCHAR *)class_name ); - else - { - WCHAR nameW[MAX_ATOM_LEN + 1]; - if (!MultiByteToWideChar( CP_ACP, 0, class_name, -1, nameW, ARRAY_SIZE( nameW ))) return FALSE; - RtlInitUnicodeString( &name, nameW ); - } - - get_class_version( &name, NULL, TRUE ); + init_class_name_ansi( &name, class_name ); + get_class_version( &name, &version, TRUE );
if (!instance) instance = user32_module; if (!(atom = NtUserGetClassInfoEx( instance, &name, (WNDCLASSEXW *)wc, NULL, TRUE ))) @@ -615,7 +605,8 @@ BOOL WINAPI GetClassInfoExA( HINSTANCE instance, const char *class_name, WNDCLAS */ BOOL WINAPI GetClassInfoExW( HINSTANCE instance, const WCHAR *class_name, WNDCLASSEXW *wc ) { - UNICODE_STRING name; + WCHAR nameW[MAX_ATOM_LEN + 1]; + UNICODE_STRING name = RTL_CONSTANT_STRING(nameW), version; ATOM atom;
TRACE( "%p %s %p\n", instance, debugstr_w(class_name), wc ); @@ -627,7 +618,7 @@ BOOL WINAPI GetClassInfoExW( HINSTANCE instance, const WCHAR *class_name, WNDCLA }
init_class_name( &name, class_name ); - get_class_version( &name, NULL, TRUE ); + get_class_version( &name, &version, TRUE );
if (!instance) instance = user32_module; if (!(atom = NtUserGetClassInfoEx( instance, &name, wc, NULL, FALSE ))) diff --git a/dlls/user32/win.c b/dlls/user32/win.c index b1e8842b9e8..18866ac694e 100644 --- a/dlls/user32/win.c +++ b/dlls/user32/win.c @@ -29,6 +29,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(win);
+#define MAX_ATOM_LEN 255 /* from dlls/kernel32/atom.c */ + static const char *debugstr_us( const UNICODE_STRING *us ) { if (!us) return "<null>"; @@ -280,7 +282,8 @@ static BOOL is_default_coord( int x ) */ HWND WIN_CreateWindowEx( CREATESTRUCTW *cs, LPCWSTR className, HINSTANCE module, BOOL unicode ) { - UNICODE_STRING class, window_name = {0}; + WCHAR nameW[MAX_ATOM_LEN + 1]; + UNICODE_STRING class = RTL_CONSTANT_STRING(nameW), version, window_name = {0}; HWND hwnd, top_child = 0; MDICREATESTRUCTW mdi_cs; WNDCLASSEXW info; @@ -288,7 +291,7 @@ HWND WIN_CreateWindowEx( CREATESTRUCTW *cs, LPCWSTR className, HINSTANCE module, HMENU menu;
init_class_name( &class, className ); - get_class_version( &class, NULL, TRUE ); + get_class_version( &class, &version, TRUE );
if (!NtUserGetClassInfoEx( module, &class, &info, NULL, FALSE )) {