Module: wine Branch: master Commit: e7243523cbe7fc2c3512cdcf60290aa440cc6658 URL: https://source.winehq.org/git/wine.git/?a=commit;h=e7243523cbe7fc2c3512cdcf6...
Author: Nikolay Sivov nsivov@codeweavers.com Date: Mon Jun 11 10:42:34 2018 +0300
server: Use additional atom to keep base class name.
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/user32/class.c | 1 + include/wine/server_protocol.h | 4 +++- server/class.c | 27 +++++++++++++++++++++++++-- server/protocol.def | 1 + server/request.h | 3 ++- server/trace.c | 1 + 6 files changed, 33 insertions(+), 4 deletions(-)
diff --git a/dlls/user32/class.c b/dlls/user32/class.c index ce2830f..2b2d07f 100644 --- a/dlls/user32/class.c +++ b/dlls/user32/class.c @@ -487,6 +487,7 @@ 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) ); ret = !wine_server_call_err( req ); classPtr->atomName = reply->atom; diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index 98dbcb7..e4c2d92 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -4480,7 +4480,9 @@ 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]; }; struct create_class_reply { @@ -6510,6 +6512,6 @@ union generic_reply struct terminate_job_reply terminate_job_reply; };
-#define SERVER_PROTOCOL_VERSION 553 +#define SERVER_PROTOCOL_VERSION 554
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */ diff --git a/server/class.c b/server/class.c index cc6e52d..d5f6712 100644 --- a/server/class.c +++ b/server/class.c @@ -46,6 +46,7 @@ struct window_class int count; /* reference count */ int local; /* local class? */ atom_t atom; /* class atom */ + atom_t base_atom; /* base class atom for versioned class */ mod_handle_t instance; /* module instance */ unsigned int style; /* class style */ int win_extra; /* number of window extra bytes */ @@ -151,17 +152,35 @@ DECL_HANDLER(create_class) { struct window_class *class; struct unicode_str name = get_req_unicode_str(); - atom_t atom; + atom_t atom, base_atom;
if (name.len) { atom = add_global_atom( NULL, &name ); if (!atom) return; + if (req->name_offset && req->name_offset < name.len / sizeof(WCHAR)) + { + name.str += req->name_offset; + name.len -= req->name_offset * sizeof(WCHAR); + + base_atom = add_global_atom( NULL, &name ); + if (!base_atom) + { + release_global_atom( NULL, atom ); + return; + } + } + else + { + base_atom = atom; + grab_global_atom( NULL, atom ); + } } else { - atom = req->atom; + base_atom = atom = req->atom; if (!grab_global_atom( NULL, atom )) return; + grab_global_atom( NULL, base_atom ); }
class = find_class( current->process, atom, req->instance ); @@ -169,6 +188,7 @@ DECL_HANDLER(create_class) { set_win32_error( ERROR_CLASS_ALREADY_EXISTS ); release_global_atom( NULL, atom ); + release_global_atom( NULL, base_atom ); return; } if (req->extra < 0 || req->extra > 4096 || req->win_extra < 0 || req->win_extra > 4096) @@ -176,15 +196,18 @@ DECL_HANDLER(create_class) /* don't allow stupid values here */ set_error( STATUS_INVALID_PARAMETER ); release_global_atom( NULL, atom ); + release_global_atom( NULL, base_atom ); return; }
if (!(class = create_class( current->process, req->extra, req->local ))) { release_global_atom( NULL, atom ); + release_global_atom( NULL, base_atom ); return; } class->atom = atom; + class->base_atom = base_atom; class->instance = req->instance; class->style = req->style; class->win_extra = req->win_extra; diff --git a/server/protocol.def b/server/protocol.def index 99e7221..c533f1b 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -3149,6 +3149,7 @@ 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 */ @REPLY atom_t atom; /* resulting class atom */ diff --git a/server/request.h b/server/request.h index 2d55dfb..8b823ba 100644 --- a/server/request.h +++ b/server/request.h @@ -2036,7 +2036,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( sizeof(struct create_class_request) == 48 ); +C_ASSERT( FIELD_OFFSET(struct create_class_request, name_offset) == 48 ); +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 ); C_ASSERT( FIELD_OFFSET(struct destroy_class_request, atom) == 12 ); diff --git a/server/trace.c b/server/trace.c index e2980a3..c602043 100644 --- a/server/trace.c +++ b/server/trace.c @@ -3758,6 +3758,7 @@ 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 ); }