From: Rémi Bernon rbernon@codeweavers.com
--- server/atom.c | 5 ++--- server/class.c | 33 +++++++++++++++++++++++++++------ server/protocol.def | 6 +++++- 3 files changed, 34 insertions(+), 10 deletions(-)
diff --git a/server/atom.c b/server/atom.c index 0bba828e300..307634124f5 100644 --- a/server/atom.c +++ b/server/atom.c @@ -42,7 +42,6 @@ #define MIN_HASH_SIZE 4 #define MAX_HASH_SIZE 0x200
-#define MAX_ATOM_LEN (255 * sizeof(WCHAR)) #define MIN_STR_ATOM 0xc000 #define MAX_ATOMS 0x4000
@@ -289,7 +288,7 @@ atom_t add_atom( struct atom_table *table, const struct unicode_str *str ) set_error( STATUS_OBJECT_NAME_INVALID ); return 0; } - if (str->len > MAX_ATOM_LEN) + if (str->len > MAX_ATOM_LEN * sizeof(WCHAR)) { set_error( STATUS_INVALID_PARAMETER ); return 0; @@ -352,7 +351,7 @@ atom_t find_atom( struct atom_table *table, const struct unicode_str *str ) set_error( STATUS_OBJECT_NAME_INVALID ); return 0; } - if (str->len > MAX_ATOM_LEN) + if (str->len > MAX_ATOM_LEN * sizeof(WCHAR)) { set_error( STATUS_INVALID_PARAMETER ); return 0; diff --git a/server/class.c b/server/class.c index 9db68fdced6..0e336bab897 100644 --- a/server/class.c +++ b/server/class.c @@ -57,7 +57,8 @@ struct window_class char extra_bytes[1]; /* extra bytes storage */ };
-static struct window_class *create_class( struct process *process, int extra_bytes, int local ) +static struct window_class *create_class( struct process *process, int extra_bytes, int local, + struct unicode_str *name, unsigned int name_offset ) { struct window_class *class;
@@ -72,7 +73,9 @@ static struct window_class *create_class( struct process *process, int extra_byt if (!(class->shared = alloc_shared_object())) goto failed; SHARED_WRITE_BEGIN( class->shared, class_shm_t ) { - shared->placeholder = 0; + memcpy( (void *)shared->name, name->str, name->len ); + shared->name_offset = name_offset; + shared->name_len = name->len; } SHARED_WRITE_END;
@@ -174,6 +177,17 @@ client_ptr_t get_class_client_ptr( struct window_class *class ) return class->client_ptr; }
+static struct unicode_str integral_atom_name( WCHAR *buffer, atom_t atom ) +{ + struct unicode_str name; + char tmp[16]; + int ret = snprintf( tmp, sizeof(tmp), "#%u", atom ); + for (int i = ret; i >= 0; i--) buffer[i] = tmp[i]; + name.len = ret * sizeof(WCHAR); + name.str = buffer; + return name; +} + /* create a window class */ DECL_HANDLER(create_class) { @@ -181,14 +195,21 @@ DECL_HANDLER(create_class) struct unicode_str name = get_req_unicode_str(); struct atom_table *table = get_user_atom_table(); atom_t atom = req->atom, base_atom; + unsigned int offset = 0; + WCHAR buffer[16];
+ if (atom && !name.len) name = integral_atom_name( buffer, atom ); if (!atom && !(atom = add_atom( table, &name ))) return;
if (req->name_offset && req->name_offset < name.len / sizeof(WCHAR)) { - name.str += req->name_offset; - name.len -= req->name_offset * sizeof(WCHAR); - if (!(base_atom = add_atom( table, &name ))) + struct unicode_str base = name; + + offset = req->name_offset; + base.str += offset; + base.len -= offset * sizeof(WCHAR); + + if (!(base_atom = add_atom( table, &base ))) { release_atom( table, atom ); return; @@ -216,7 +237,7 @@ DECL_HANDLER(create_class) return; }
- if (!(class = create_class( current->process, req->extra, req->local ))) + if (!(class = create_class( current->process, req->extra, req->local, &name, offset ))) { release_atom( table, atom ); release_atom( table, base_atom ); diff --git a/server/protocol.def b/server/protocol.def index 5b2b1709499..4e6f08d1d4a 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -971,6 +971,8 @@ union udp_endpoint /****************************************************************/ /* shared session mapping structures */
+#define MAX_ATOM_LEN 255 + struct shared_cursor { int x; /* cursor position */ @@ -1016,7 +1018,9 @@ typedef volatile struct
typedef volatile struct { - int placeholder; + WCHAR name[MAX_ATOM_LEN]; /* class name */ + data_size_t name_offset; /* offset in WCHAR of the unversioned class name */ + data_size_t name_len; /* len in bytes of the class name */ } class_shm_t;
typedef volatile struct