Nikolay Sivov : server: Use additional atom to keep base class name.
Alexandre Julliard
julliard at winehq.org
Mon Jun 11 13:10:50 CDT 2018
Module: wine
Branch: master
Commit: e7243523cbe7fc2c3512cdcf60290aa440cc6658
URL: https://source.winehq.org/git/wine.git/?a=commit;h=e7243523cbe7fc2c3512cdcf60290aa440cc6658
Author: Nikolay Sivov <nsivov at 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 at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at 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 );
}
More information about the wine-cvs
mailing list