Some applications are dependent on the correct spelling of "ComboBox", it can't be the "Combobox" from the comctl32 manifest. We have to take it from the base class instead of the versioned class name.
Supersedes 150043
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45689 Signed-off-by: Fabian Maurer dark.shadow4@web.de --- dlls/comctl32/tests/combo.c | 15 +++++++++++++ dlls/user32/class.c | 41 ++++++++++++++++------------------ dlls/user32/user_private.h | 3 +-- dlls/user32/win.c | 2 +- include/wine/server_protocol.h | 9 ++++---- server/class.c | 14 +++++++----- server/protocol.def | 6 +++-- server/request.h | 3 ++- server/trace.c | 6 +++-- 9 files changed, 59 insertions(+), 40 deletions(-)
diff --git a/dlls/comctl32/tests/combo.c b/dlls/comctl32/tests/combo.c index 923d826b30..065ce1a620 100644 --- a/dlls/comctl32/tests/combo.c +++ b/dlls/comctl32/tests/combo.c @@ -1254,6 +1254,20 @@ static void test_combo_dropdown_size(DWORD style) } }
+static void test_combo(void) +{ + HWND handle_combo; + char classname[10]; + + handle_combo = create_combobox(CBS_DROPDOWNLIST); + + GetClassNameA(handle_combo, classname, sizeof(classname)); + + ok(strcmp(classname, "ComboBox") == 0, "Got wrong classname: %s\n", classname); + + DestroyWindow(handle_combo); +} + START_TEST(combo) { ULONG_PTR ctx_cookie; @@ -1281,6 +1295,7 @@ START_TEST(combo) }
/* ComboBox control tests. */ + test_combo(); test_combo_WS_VSCROLL(); test_combo_setfont(CBS_DROPDOWN); test_combo_setfont(CBS_DROPDOWNLIST); diff --git a/dlls/user32/class.c b/dlls/user32/class.c index 07d36f05d7..3d4105d91b 100644 --- a/dlls/user32/class.c +++ b/dlls/user32/class.c @@ -61,7 +61,7 @@ typedef struct tagCLASS HBRUSH hbrBackground; /* Default background */ ATOM atomName; /* Name of the class */ WCHAR name[MAX_ATOM_LEN + 1]; - WCHAR *basename; /* Base name for redirected classes, pointer within 'name'. */ + WCHAR basename[MAX_ATOM_LEN + 1]; /* Base name for redirected classes */ } CLASS;
static struct list class_list = LIST_INIT( class_list ); @@ -320,7 +320,7 @@ static void CLASS_FreeClass( CLASS *classPtr ) USER_Unlock(); }
-const WCHAR *CLASS_GetVersionedName( const WCHAR *name, UINT *basename_offset, BOOL register_class ) +const WCHAR *CLASS_GetVersionedName( const WCHAR *name, BOOL register_class ) { ACTCTX_SECTION_KEYED_DATA data; struct wndclass_redirect_data @@ -336,9 +336,6 @@ const WCHAR *CLASS_GetVersionedName( const WCHAR *name, UINT *basename_offset, B UNICODE_STRING name_us; HMODULE hmod;
- if (basename_offset) - *basename_offset = 0; - if (IS_INTRESOURCE( name )) return name;
@@ -352,8 +349,6 @@ const WCHAR *CLASS_GetVersionedName( const WCHAR *name, UINT *basename_offset, B return name;
wndclass = (struct wndclass_redirect_data *)data.lpData; - if (basename_offset) - *basename_offset = wndclass->name_len / sizeof(WCHAR) - strlenW(name);
module = (const WCHAR *)((BYTE *)data.lpSectionBase + wndclass->module_offset); if (!(hmod = GetModuleHandleW( module ))) @@ -409,7 +404,7 @@ static CLASS *CLASS_FindClass( LPCWSTR name, HINSTANCE hinstance )
if (!name) return NULL;
- name = CLASS_GetVersionedName( name, NULL, TRUE ); + name = CLASS_GetVersionedName( name, TRUE );
for (;;) { @@ -450,11 +445,12 @@ static CLASS *CLASS_FindClass( LPCWSTR name, HINSTANCE hinstance ) * * The real RegisterClass() functionality. */ -static CLASS *CLASS_RegisterClass( LPCWSTR name, UINT basename_offset, HINSTANCE hInstance, BOOL local, +static CLASS *CLASS_RegisterClass( LPCWSTR name, LPCWSTR basename, HINSTANCE hInstance, BOOL local, DWORD style, INT classExtra, INT winExtra ) { CLASS *classPtr; BOOL ret; + int name_len = 0, basename_len = 0;
TRACE("name=%s hinst=%p style=0x%x clExtr=0x%x winExtr=0x%x\n", debugstr_w(name), hInstance, style, classExtra, winExtra ); @@ -470,11 +466,12 @@ static CLASS *CLASS_RegisterClass( LPCWSTR name, UINT basename_offset, HINSTANCE if (!classPtr) return NULL;
classPtr->atomName = get_int_atom_value( name ); - classPtr->basename = classPtr->name; if (!classPtr->atomName && name) { strcpyW( classPtr->name, name ); - classPtr->basename += basename_offset; + name_len = strlenW(name) * sizeof(WCHAR); + strcpyW( classPtr->basename, basename ); + basename_len = strlenW(basename) * sizeof(WCHAR); } else GlobalGetAtomNameW( classPtr->atomName, classPtr->name, ARRAY_SIZE( classPtr->name ));
@@ -487,8 +484,10 @@ static CLASS *CLASS_RegisterClass( LPCWSTR name, UINT basename_offset, HINSTANCE req->win_extra = winExtra; req->client_ptr = wine_server_client_ptr( classPtr ); req->atom = classPtr->atomName; - req->name_offset = basename_offset; - if (!req->atom && name) wine_server_add_data( req, name, strlenW(name) * sizeof(WCHAR) ); + req->name_len = name_len; + req->basename_len = basename_len; + if (name_len) wine_server_add_data( req, name, name_len); + if (basename_len) wine_server_add_data( req, basename, basename_len); ret = !wine_server_call_err( req ); classPtr->atomName = reply->atom; } @@ -524,7 +523,7 @@ static void register_builtin( const struct builtin_class_descr *descr ) { CLASS *classPtr;
- if (!(classPtr = CLASS_RegisterClass( descr->name, 0, user32_module, FALSE, + if (!(classPtr = CLASS_RegisterClass( descr->name, descr->name, user32_module, FALSE, descr->style, 0, descr->extra ))) return;
if (descr->cursor) classPtr->hCursor = LoadCursorA( 0, (LPSTR)descr->cursor ); @@ -680,15 +679,14 @@ ATOM WINAPI RegisterClassExA( const WNDCLASSEXA* wc )
if (!IS_INTRESOURCE(wc->lpszClassName)) { - UINT basename_offset; if (!MultiByteToWideChar( CP_ACP, 0, wc->lpszClassName, -1, name, MAX_ATOM_LEN + 1 )) return 0; - classname = CLASS_GetVersionedName( name, &basename_offset, FALSE ); - classPtr = CLASS_RegisterClass( classname, basename_offset, instance, !(wc->style & CS_GLOBALCLASS), + classname = CLASS_GetVersionedName( name, FALSE ); + classPtr = CLASS_RegisterClass( classname, name, instance, !(wc->style & CS_GLOBALCLASS), wc->style, wc->cbClsExtra, wc->cbWndExtra ); } else { - classPtr = CLASS_RegisterClass( (LPCWSTR)wc->lpszClassName, 0, instance, + classPtr = CLASS_RegisterClass( (LPCWSTR)wc->lpszClassName, (LPCWSTR)wc->lpszClassName, instance, !(wc->style & CS_GLOBALCLASS), wc->style, wc->cbClsExtra, wc->cbWndExtra ); } @@ -721,7 +719,6 @@ ATOM WINAPI RegisterClassExA( const WNDCLASSEXA* wc ) ATOM WINAPI RegisterClassExW( const WNDCLASSEXW* wc ) { const WCHAR *classname; - UINT basename_offset; ATOM atom; CLASS *classPtr; HINSTANCE instance; @@ -736,8 +733,8 @@ ATOM WINAPI RegisterClassExW( const WNDCLASSEXW* wc ) } if (!(instance = wc->hInstance)) instance = GetModuleHandleW( NULL );
- classname = CLASS_GetVersionedName( wc->lpszClassName, &basename_offset, FALSE ); - if (!(classPtr = CLASS_RegisterClass( classname, basename_offset, instance, !(wc->style & CS_GLOBALCLASS), + classname = CLASS_GetVersionedName( wc->lpszClassName, FALSE ); + if (!(classPtr = CLASS_RegisterClass( classname, wc->lpszClassName, instance, !(wc->style & CS_GLOBALCLASS), wc->style, wc->cbClsExtra, wc->cbWndExtra ))) return 0;
@@ -789,7 +786,7 @@ BOOL WINAPI UnregisterClassW( LPCWSTR className, HINSTANCE hInstance )
GetDesktopWindow(); /* create the desktop window to trigger builtin class registration */
- className = CLASS_GetVersionedName( className, NULL, FALSE ); + className = CLASS_GetVersionedName( className, FALSE ); SERVER_START_REQ( destroy_class ) { req->instance = wine_server_client_ptr( hInstance ); diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h index 73a2badc7d..8051f15d30 100644 --- a/dlls/user32/user_private.h +++ b/dlls/user32/user_private.h @@ -272,8 +272,7 @@ extern INT_PTR WINPROC_CallDlgProcW( DLGPROC func, HWND hwnd, UINT msg, WPARAM w extern BOOL WINPROC_call_window( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, LRESULT *result, BOOL unicode, enum wm_char_mapping mapping ) DECLSPEC_HIDDEN;
-extern const WCHAR *CLASS_GetVersionedName(const WCHAR *classname, UINT *basename_offset, - BOOL register_class) DECLSPEC_HIDDEN; +extern const WCHAR *CLASS_GetVersionedName(const WCHAR *classname, BOOL register_class) DECLSPEC_HIDDEN;
/* message spy definitions */
diff --git a/dlls/user32/win.c b/dlls/user32/win.c index cbfd8bb14a..48cf947b36 100644 --- a/dlls/user32/win.c +++ b/dlls/user32/win.c @@ -1323,7 +1323,7 @@ HWND WIN_CreateWindowEx( CREATESTRUCTW *cs, LPCWSTR className, HINSTANCE module, CBT_CREATEWNDW cbtc; CREATESTRUCTW cbcs;
- className = CLASS_GetVersionedName(className, NULL, TRUE); + className = CLASS_GetVersionedName(className, TRUE);
TRACE("%s %s%s%s ex=%08x style=%08x %d,%d %dx%d parent=%p menu=%p inst=%p params=%p\n", unicode ? debugstr_w(cs->lpszName) : debugstr_a((LPCSTR)cs->lpszName), diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index c636bacb35..4f29006036 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -4496,9 +4496,10 @@ struct create_class_request int extra; int win_extra; client_ptr_t client_ptr; - data_size_t name_offset; - /* VARARG(name,unicode_str); */ - char __pad_52[4]; + data_size_t name_len; + data_size_t basename_len; + /* VARARG(name,unicode_str,name_len); */ + /* VARARG(name,unicode_str,basename_len); */ }; struct create_class_reply { @@ -6533,6 +6534,6 @@ union generic_reply struct terminate_job_reply terminate_job_reply; };
-#define SERVER_PROTOCOL_VERSION 556 +#define SERVER_PROTOCOL_VERSION 557
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */ diff --git a/server/class.c b/server/class.c index 6a7de7843e..da6191d6aa 100644 --- a/server/class.c +++ b/server/class.c @@ -151,19 +151,21 @@ client_ptr_t get_class_client_ptr( struct window_class *class ) DECL_HANDLER(create_class) { struct window_class *class; - struct unicode_str name = get_req_unicode_str(); + struct unicode_str name, basename; atom_t atom, base_atom;
+ name.len = req->name_len; + name.str = get_req_data(); + basename.len = req->basename_len; + basename.str = (WCHAR *)((char *)get_req_data() + req->name_len); + if (name.len) { atom = add_global_atom( NULL, &name ); if (!atom) return; - if (req->name_offset && req->name_offset < name.len / sizeof(WCHAR)) + if (basename.len) { - name.str += req->name_offset; - name.len -= req->name_offset * sizeof(WCHAR); - - base_atom = add_global_atom( NULL, &name ); + base_atom = add_global_atom( NULL, &basename ); if (!base_atom) { release_global_atom( NULL, atom ); diff --git a/server/protocol.def b/server/protocol.def index c8bb3b1100..c55f888a6d 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -3159,8 +3159,10 @@ enum caret_state int extra; /* number of extra class bytes */ int win_extra; /* number of window extra bytes */ client_ptr_t client_ptr; /* pointer to class in client address space */ - data_size_t name_offset; /* base class name offset for specified atom */ - VARARG(name,unicode_str); /* class name */ + data_size_t name_len; /* class name length */ + data_size_t basename_len; /* base class name length */ + VARARG(name,unicode_str,name_len); /* class name */ + VARARG(name,unicode_str,basename_len); /* base class name */ @REPLY atom_t atom; /* resulting class atom */ @END diff --git a/server/request.h b/server/request.h index d3028f0b1d..56562be81c 100644 --- a/server/request.h +++ b/server/request.h @@ -2044,7 +2044,8 @@ C_ASSERT( FIELD_OFFSET(struct create_class_request, instance) == 24 ); C_ASSERT( FIELD_OFFSET(struct create_class_request, extra) == 32 ); C_ASSERT( FIELD_OFFSET(struct create_class_request, win_extra) == 36 ); C_ASSERT( FIELD_OFFSET(struct create_class_request, client_ptr) == 40 ); -C_ASSERT( FIELD_OFFSET(struct create_class_request, name_offset) == 48 ); +C_ASSERT( FIELD_OFFSET(struct create_class_request, name_len) == 48 ); +C_ASSERT( FIELD_OFFSET(struct create_class_request, basename_len) == 52 ); C_ASSERT( sizeof(struct create_class_request) == 56 ); C_ASSERT( FIELD_OFFSET(struct create_class_reply, atom) == 8 ); C_ASSERT( sizeof(struct create_class_reply) == 16 ); diff --git a/server/trace.c b/server/trace.c index 68e47d49b8..966022aaac 100644 --- a/server/trace.c +++ b/server/trace.c @@ -3770,8 +3770,10 @@ static void dump_create_class_request( const struct create_class_request *req ) fprintf( stderr, ", extra=%d", req->extra ); fprintf( stderr, ", win_extra=%d", req->win_extra ); dump_uint64( ", client_ptr=", &req->client_ptr ); - fprintf( stderr, ", name_offset=%u", req->name_offset ); - dump_varargs_unicode_str( ", name=", cur_size ); + fprintf( stderr, ", name_len=%u", req->name_len ); + fprintf( stderr, ", basename_len=%u", req->basename_len ); + dump_varargs_unicode_str( ", name=", min(cur_size,req->name_len) ); + dump_varargs_unicode_str( ", name=", min(cur_size,req->basename_len) ); }
static void dump_create_class_reply( const struct create_class_reply *req )
On 08/23/2018 10:36 PM, Fabian Maurer wrote:
Some applications are dependent on the correct spelling of "ComboBox", it can't be the "Combobox" from the comctl32 manifest. We have to take it from the base class instead of the versioned class name.
Supersedes 150043
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45689 Signed-off-by: Fabian Maurer dark.shadow4@web.de
dlls/comctl32/tests/combo.c | 15 +++++++++++++ dlls/user32/class.c | 41 ++++++++++++++++------------------ dlls/user32/user_private.h | 3 +-- dlls/user32/win.c | 2 +- include/wine/server_protocol.h | 9 ++++---- server/class.c | 14 +++++++----- server/protocol.def | 6 +++-- server/request.h | 3 ++- server/trace.c | 6 +++-- 9 files changed, 59 insertions(+), 40 deletions(-)
That looks too complicated, I don't see why server changes are necessary. It should be enough to fix up what CLASS_GetVersionedName() returns.
diff --git a/dlls/comctl32/tests/combo.c b/dlls/comctl32/tests/combo.c index 923d826b30..065ce1a620 100644 --- a/dlls/comctl32/tests/combo.c +++ b/dlls/comctl32/tests/combo.c @@ -1254,6 +1254,20 @@ static void test_combo_dropdown_size(DWORD style) } }
+static void test_combo(void) +{
- HWND handle_combo;
- char classname[10];
- handle_combo = create_combobox(CBS_DROPDOWNLIST);
- GetClassNameA(handle_combo, classname, sizeof(classname));
- ok(strcmp(classname, "ComboBox") == 0, "Got wrong classname: %s\n", classname);
- DestroyWindow(handle_combo);
+}
- START_TEST(combo) { ULONG_PTR ctx_cookie;
@@ -1281,6 +1295,7 @@ START_TEST(combo) }
/* ComboBox control tests. */
- test_combo(); test_combo_WS_VSCROLL(); test_combo_setfont(CBS_DROPDOWN); test_combo_setfont(CBS_DROPDOWNLIST);
diff --git a/dlls/user32/class.c b/dlls/user32/class.c index 07d36f05d7..3d4105d91b 100644 --- a/dlls/user32/class.c +++ b/dlls/user32/class.c @@ -61,7 +61,7 @@ typedef struct tagCLASS HBRUSH hbrBackground; /* Default background */ ATOM atomName; /* Name of the class */ WCHAR name[MAX_ATOM_LEN + 1];
- WCHAR *basename; /* Base name for redirected classes, pointer within 'name'. */
WCHAR basename[MAX_ATOM_LEN + 1]; /* Base name for redirected classes */ } CLASS;
static struct list class_list = LIST_INIT( class_list );
@@ -320,7 +320,7 @@ static void CLASS_FreeClass( CLASS *classPtr ) USER_Unlock(); }
-const WCHAR *CLASS_GetVersionedName( const WCHAR *name, UINT *basename_offset, BOOL register_class ) +const WCHAR *CLASS_GetVersionedName( const WCHAR *name, BOOL register_class ) { ACTCTX_SECTION_KEYED_DATA data; struct wndclass_redirect_data @@ -336,9 +336,6 @@ const WCHAR *CLASS_GetVersionedName( const WCHAR *name, UINT *basename_offset, B UNICODE_STRING name_us; HMODULE hmod;
- if (basename_offset)
*basename_offset = 0;
if (IS_INTRESOURCE( name )) return name;
@@ -352,8 +349,6 @@ const WCHAR *CLASS_GetVersionedName( const WCHAR *name, UINT *basename_offset, B return name;
wndclass = (struct wndclass_redirect_data *)data.lpData;
if (basename_offset)
*basename_offset = wndclass->name_len / sizeof(WCHAR) - strlenW(name); module = (const WCHAR *)((BYTE *)data.lpSectionBase + wndclass->module_offset); if (!(hmod = GetModuleHandleW( module )))
@@ -409,7 +404,7 @@ static CLASS *CLASS_FindClass( LPCWSTR name, HINSTANCE hinstance )
if (!name) return NULL;
- name = CLASS_GetVersionedName( name, NULL, TRUE );
name = CLASS_GetVersionedName( name, TRUE );
for (;;) {
@@ -450,11 +445,12 @@ static CLASS *CLASS_FindClass( LPCWSTR name, HINSTANCE hinstance )
- The real RegisterClass() functionality.
*/ -static CLASS *CLASS_RegisterClass( LPCWSTR name, UINT basename_offset, HINSTANCE hInstance, BOOL local, +static CLASS *CLASS_RegisterClass( LPCWSTR name, LPCWSTR basename, HINSTANCE hInstance, BOOL local, DWORD style, INT classExtra, INT winExtra ) { CLASS *classPtr; BOOL ret;
int name_len = 0, basename_len = 0;
TRACE("name=%s hinst=%p style=0x%x clExtr=0x%x winExtr=0x%x\n", debugstr_w(name), hInstance, style, classExtra, winExtra );
@@ -470,11 +466,12 @@ static CLASS *CLASS_RegisterClass( LPCWSTR name, UINT basename_offset, HINSTANCE if (!classPtr) return NULL;
classPtr->atomName = get_int_atom_value( name );
- classPtr->basename = classPtr->name; if (!classPtr->atomName && name) { strcpyW( classPtr->name, name );
classPtr->basename += basename_offset;
name_len = strlenW(name) * sizeof(WCHAR);
strcpyW( classPtr->basename, basename );
basename_len = strlenW(basename) * sizeof(WCHAR); } else GlobalGetAtomNameW( classPtr->atomName, classPtr->name, ARRAY_SIZE( classPtr->name ));
@@ -487,8 +484,10 @@ static CLASS *CLASS_RegisterClass( LPCWSTR name, UINT basename_offset, HINSTANCE req->win_extra = winExtra; req->client_ptr = wine_server_client_ptr( classPtr ); req->atom = classPtr->atomName;
req->name_offset = basename_offset;
if (!req->atom && name) wine_server_add_data( req, name, strlenW(name) * sizeof(WCHAR) );
req->name_len = name_len;
req->basename_len = basename_len;
if (name_len) wine_server_add_data( req, name, name_len);
if (basename_len) wine_server_add_data( req, basename, basename_len); ret = !wine_server_call_err( req ); classPtr->atomName = reply->atom; }
@@ -524,7 +523,7 @@ static void register_builtin( const struct builtin_class_descr *descr ) { CLASS *classPtr;
- if (!(classPtr = CLASS_RegisterClass( descr->name, 0, user32_module, FALSE,
if (!(classPtr = CLASS_RegisterClass( descr->name, descr->name, user32_module, FALSE, descr->style, 0, descr->extra ))) return;
if (descr->cursor) classPtr->hCursor = LoadCursorA( 0, (LPSTR)descr->cursor );
@@ -680,15 +679,14 @@ ATOM WINAPI RegisterClassExA( const WNDCLASSEXA* wc )
if (!IS_INTRESOURCE(wc->lpszClassName)) {
UINT basename_offset; if (!MultiByteToWideChar( CP_ACP, 0, wc->lpszClassName, -1, name, MAX_ATOM_LEN + 1 )) return 0;
classname = CLASS_GetVersionedName( name, &basename_offset, FALSE );
classPtr = CLASS_RegisterClass( classname, basename_offset, instance, !(wc->style & CS_GLOBALCLASS),
classname = CLASS_GetVersionedName( name, FALSE );
classPtr = CLASS_RegisterClass( classname, name, instance, !(wc->style & CS_GLOBALCLASS), wc->style, wc->cbClsExtra, wc->cbWndExtra ); } else {
classPtr = CLASS_RegisterClass( (LPCWSTR)wc->lpszClassName, 0, instance,
classPtr = CLASS_RegisterClass( (LPCWSTR)wc->lpszClassName, (LPCWSTR)wc->lpszClassName, instance, !(wc->style & CS_GLOBALCLASS), wc->style, wc->cbClsExtra, wc->cbWndExtra ); }
@@ -721,7 +719,6 @@ ATOM WINAPI RegisterClassExA( const WNDCLASSEXA* wc ) ATOM WINAPI RegisterClassExW( const WNDCLASSEXW* wc ) { const WCHAR *classname;
- UINT basename_offset; ATOM atom; CLASS *classPtr; HINSTANCE instance;
@@ -736,8 +733,8 @@ ATOM WINAPI RegisterClassExW( const WNDCLASSEXW* wc ) } if (!(instance = wc->hInstance)) instance = GetModuleHandleW( NULL );
- classname = CLASS_GetVersionedName( wc->lpszClassName, &basename_offset, FALSE );
- if (!(classPtr = CLASS_RegisterClass( classname, basename_offset, instance, !(wc->style & CS_GLOBALCLASS),
- classname = CLASS_GetVersionedName( wc->lpszClassName, FALSE );
- if (!(classPtr = CLASS_RegisterClass( classname, wc->lpszClassName, instance, !(wc->style & CS_GLOBALCLASS), wc->style, wc->cbClsExtra, wc->cbWndExtra ))) return 0;
@@ -789,7 +786,7 @@ BOOL WINAPI UnregisterClassW( LPCWSTR className, HINSTANCE hInstance )
GetDesktopWindow(); /* create the desktop window to trigger builtin class registration */
- className = CLASS_GetVersionedName( className, NULL, FALSE );
- className = CLASS_GetVersionedName( className, FALSE ); SERVER_START_REQ( destroy_class ) { req->instance = wine_server_client_ptr( hInstance );
diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h index 73a2badc7d..8051f15d30 100644 --- a/dlls/user32/user_private.h +++ b/dlls/user32/user_private.h @@ -272,8 +272,7 @@ extern INT_PTR WINPROC_CallDlgProcW( DLGPROC func, HWND hwnd, UINT msg, WPARAM w extern BOOL WINPROC_call_window( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, LRESULT *result, BOOL unicode, enum wm_char_mapping mapping ) DECLSPEC_HIDDEN;
-extern const WCHAR *CLASS_GetVersionedName(const WCHAR *classname, UINT *basename_offset,
BOOL register_class) DECLSPEC_HIDDEN;
+extern const WCHAR *CLASS_GetVersionedName(const WCHAR *classname, BOOL register_class) DECLSPEC_HIDDEN;
/* message spy definitions */
diff --git a/dlls/user32/win.c b/dlls/user32/win.c index cbfd8bb14a..48cf947b36 100644 --- a/dlls/user32/win.c +++ b/dlls/user32/win.c @@ -1323,7 +1323,7 @@ HWND WIN_CreateWindowEx( CREATESTRUCTW *cs, LPCWSTR className, HINSTANCE module, CBT_CREATEWNDW cbtc; CREATESTRUCTW cbcs;
- className = CLASS_GetVersionedName(className, NULL, TRUE);
className = CLASS_GetVersionedName(className, TRUE);
TRACE("%s %s%s%s ex=%08x style=%08x %d,%d %dx%d parent=%p menu=%p inst=%p params=%p\n", unicode ? debugstr_w(cs->lpszName) : debugstr_a((LPCSTR)cs->lpszName),
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index c636bacb35..4f29006036 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -4496,9 +4496,10 @@ struct create_class_request int extra; int win_extra; client_ptr_t client_ptr;
- data_size_t name_offset;
- /* VARARG(name,unicode_str); */
- char __pad_52[4];
- data_size_t name_len;
- data_size_t basename_len;
- /* VARARG(name,unicode_str,name_len); */
- /* VARARG(name,unicode_str,basename_len); */ }; struct create_class_reply {
@@ -6533,6 +6534,6 @@ union generic_reply struct terminate_job_reply terminate_job_reply; };
-#define SERVER_PROTOCOL_VERSION 556 +#define SERVER_PROTOCOL_VERSION 557
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */ diff --git a/server/class.c b/server/class.c index 6a7de7843e..da6191d6aa 100644 --- a/server/class.c +++ b/server/class.c @@ -151,19 +151,21 @@ client_ptr_t get_class_client_ptr( struct window_class *class ) DECL_HANDLER(create_class) { struct window_class *class;
- struct unicode_str name = get_req_unicode_str();
struct unicode_str name, basename; atom_t atom, base_atom;
name.len = req->name_len;
name.str = get_req_data();
basename.len = req->basename_len;
basename.str = (WCHAR *)((char *)get_req_data() + req->name_len);
if (name.len) { atom = add_global_atom( NULL, &name ); if (!atom) return;
if (req->name_offset && req->name_offset < name.len / sizeof(WCHAR))
if (basename.len) {
name.str += req->name_offset;
name.len -= req->name_offset * sizeof(WCHAR);
base_atom = add_global_atom( NULL, &name );
base_atom = add_global_atom( NULL, &basename ); if (!base_atom) { release_global_atom( NULL, atom );
diff --git a/server/protocol.def b/server/protocol.def index c8bb3b1100..c55f888a6d 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -3159,8 +3159,10 @@ enum caret_state int extra; /* number of extra class bytes */ int win_extra; /* number of window extra bytes */ client_ptr_t client_ptr; /* pointer to class in client address space */
- data_size_t name_offset; /* base class name offset for specified atom */
- VARARG(name,unicode_str); /* class name */
- data_size_t name_len; /* class name length */
- data_size_t basename_len; /* base class name length */
- VARARG(name,unicode_str,name_len); /* class name */
- VARARG(name,unicode_str,basename_len); /* base class name */ @REPLY atom_t atom; /* resulting class atom */ @END
diff --git a/server/request.h b/server/request.h index d3028f0b1d..56562be81c 100644 --- a/server/request.h +++ b/server/request.h @@ -2044,7 +2044,8 @@ C_ASSERT( FIELD_OFFSET(struct create_class_request, instance) == 24 ); C_ASSERT( FIELD_OFFSET(struct create_class_request, extra) == 32 ); C_ASSERT( FIELD_OFFSET(struct create_class_request, win_extra) == 36 ); C_ASSERT( FIELD_OFFSET(struct create_class_request, client_ptr) == 40 ); -C_ASSERT( FIELD_OFFSET(struct create_class_request, name_offset) == 48 ); +C_ASSERT( FIELD_OFFSET(struct create_class_request, name_len) == 48 ); +C_ASSERT( FIELD_OFFSET(struct create_class_request, basename_len) == 52 ); C_ASSERT( sizeof(struct create_class_request) == 56 ); C_ASSERT( FIELD_OFFSET(struct create_class_reply, atom) == 8 ); C_ASSERT( sizeof(struct create_class_reply) == 16 ); diff --git a/server/trace.c b/server/trace.c index 68e47d49b8..966022aaac 100644 --- a/server/trace.c +++ b/server/trace.c @@ -3770,8 +3770,10 @@ static void dump_create_class_request( const struct create_class_request *req ) fprintf( stderr, ", extra=%d", req->extra ); fprintf( stderr, ", win_extra=%d", req->win_extra ); dump_uint64( ", client_ptr=", &req->client_ptr );
- fprintf( stderr, ", name_offset=%u", req->name_offset );
- dump_varargs_unicode_str( ", name=", cur_size );
fprintf( stderr, ", name_len=%u", req->name_len );
fprintf( stderr, ", basename_len=%u", req->basename_len );
dump_varargs_unicode_str( ", name=", min(cur_size,req->name_len) );
dump_varargs_unicode_str( ", name=", min(cur_size,req->basename_len) ); }
static void dump_create_class_reply( const struct create_class_reply *req )
On 08/23/2018 10:59 PM, Nikolay Sivov wrote:
On 08/23/2018 10:36 PM, Fabian Maurer wrote:
Some applications are dependent on the correct spelling of "ComboBox", it can't be the "Combobox" from the comctl32 manifest. We have to take it from the base class instead of the versioned class name.
Supersedes 150043
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45689 Signed-off-by: Fabian Maurer dark.shadow4@web.de
dlls/comctl32/tests/combo.c | 15 +++++++++++++ dlls/user32/class.c | 41 ++++++++++++++++------------------ dlls/user32/user_private.h | 3 +-- dlls/user32/win.c | 2 +- include/wine/server_protocol.h | 9 ++++---- server/class.c | 14 +++++++----- server/protocol.def | 6 +++-- server/request.h | 3 ++- server/trace.c | 6 +++-- 9 files changed, 59 insertions(+), 40 deletions(-)
That looks too complicated, I don't see why server changes are necessary. It should be enough to fix up what CLASS_GetVersionedName() returns.
For example like this.
That looks too complicated, I don't see why server changes are necessary. It should be enough to fix up what
CLASS_GetVersionedName()
returns.
For example like this.
Wouldn't this mean we register a class like "6.0.2600.2180!Combobox" as "6.0.2600.2180!ComboBox" instead? AFAIK that's wrong, that's why I did it the way I did.
Regards, Fabian Maurer
On 08/24/2018 12:34 AM, Fabian Maurer wrote:
That looks too complicated, I don't see why server changes are
necessary. It should be enough to fix up what CLASS_GetVersionedName()
returns.
For example like this.
Wouldn't this mean we register a class like "6.0.2600.2180!Combobox" as "6.0.2600.2180!ComboBox" instead? AFAIK that's wrong, that's why I did it the way I did.
Why is that wrong?
Regards,
Fabian Maurer
Wouldn't this mean we register a class like "6.0.2600.2180!Combobox" as "6.0.2600.2180!ComboBox" instead? AFAIK that's wrong, that's why I did it the way I did.
Why is that wrong?
I entered different version strings into google, and every occurance has had it lowercase, leading me to believe it's that way on windows, too. Besides, currently Wine also registers it with lowercase "Combobox". I don't know how important that is though, can an application get the versioned string (except from the activation context)?
Regards, Fabian Maurer
On 08/24/2018 12:50 AM, Fabian Maurer wrote:
Wouldn't this mean we register a class like "6.0.2600.2180!Combobox"
as "6.0.2600.2180!ComboBox" instead? AFAIK that's wrong, that's why I
did it the way I did.
Why is that wrong?
I entered different version strings into google, and every occurance has had it lowercase, leading me to believe it's that way on windows, too.
...
Besides, currently Wine also registers it with lowercase "Combobox". I don't know how important that is though, can an application get the versioned string (except from the activation context)?
I don't think you can, on Windows. It's not using global atom table for class names, versioned or not.
Regards,
Fabian Maurer
On Donnerstag, 23. August 2018 23:59:55 CEST Nikolay Sivov wrote:
I don't think you can, on Windows. It's not using global atom table for class names, versioned or not.
Thanks, then it doesn't matter either way. I send an updated patch, basically my tests plus your suggestion.
Regards,
Fabian Maurer