[PATCH 1/2] server: Use additional atom to keep base class name.

Nikolay Sivov nsivov at codeweavers.com
Mon Jun 11 02:42:34 CDT 2018


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/user32/class.c            |  1 +
 include/wine/server_protocol.h |  4 +++-
 server/class.c                 | 27 +++++++++++++++++++++++++--
 server/protocol.def            |  2 ++
 server/request.h               | 14 ++++++++------
 server/trace.c                 |  2 ++
 6 files changed, 41 insertions(+), 9 deletions(-)

diff --git a/dlls/user32/class.c b/dlls/user32/class.c
index ce2830fe25..2b2d07f888 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 98dbcb7e61..5358af20b8 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -4475,6 +4475,8 @@ struct create_class_request
     struct request_header __header;
     int            local;
     atom_t         atom;
+    int            name_offset;
+    int            _pad;
     unsigned int   style;
     mod_handle_t   instance;
     int            extra;
@@ -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 cc6e52d9b1..d5f6712006 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 99e7221c4b..032b03822b 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -3144,6 +3144,8 @@ enum caret_state
 @REQ(create_class)
     int            local;          /* is it a local class? */
     atom_t         atom;           /* class atom */
+    int            name_offset;    /* base class name offset for specified atom */
+    int            _pad;
     unsigned int   style;          /* class style */
     mod_handle_t   instance;       /* module instance */
     int            extra;          /* number of extra class bytes */
diff --git a/server/request.h b/server/request.h
index 2d55dfbd98..9cf81a1f09 100644
--- a/server/request.h
+++ b/server/request.h
@@ -2031,12 +2031,14 @@ C_ASSERT( FIELD_OFFSET(struct get_hook_info_reply, unicode) == 32 );
 C_ASSERT( sizeof(struct get_hook_info_reply) == 40 );
 C_ASSERT( FIELD_OFFSET(struct create_class_request, local) == 12 );
 C_ASSERT( FIELD_OFFSET(struct create_class_request, atom) == 16 );
-C_ASSERT( FIELD_OFFSET(struct create_class_request, style) == 20 );
-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) == 20 );
+C_ASSERT( FIELD_OFFSET(struct create_class_request, _pad) == 24 );
+C_ASSERT( FIELD_OFFSET(struct create_class_request, style) == 28 );
+C_ASSERT( FIELD_OFFSET(struct create_class_request, instance) == 32 );
+C_ASSERT( FIELD_OFFSET(struct create_class_request, extra) == 40 );
+C_ASSERT( FIELD_OFFSET(struct create_class_request, win_extra) == 44 );
+C_ASSERT( FIELD_OFFSET(struct create_class_request, client_ptr) == 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 e2980a3e31..999532a425 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -3753,6 +3753,8 @@ static void dump_create_class_request( const struct create_class_request *req )
 {
     fprintf( stderr, " local=%d", req->local );
     fprintf( stderr, ", atom=%04x", req->atom );
+    fprintf( stderr, ", name_offset=%d", req->name_offset );
+    fprintf( stderr, ", _pad=%d", req->_pad );
     fprintf( stderr, ", style=%08x", req->style );
     dump_uint64( ", instance=", &req->instance );
     fprintf( stderr, ", extra=%d", req->extra );
-- 
2.17.1




More information about the wine-devel mailing list