From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/class.c | 2 +- server/class.c | 34 +++++++++++++++++----------------- server/protocol.def | 7 +++++-- 3 files changed, 23 insertions(+), 20 deletions(-)
diff --git a/dlls/win32u/class.c b/dlls/win32u/class.c index 493079908aa..ad031aa86a0 100644 --- a/dlls/win32u/class.c +++ b/dlls/win32u/class.c @@ -554,7 +554,7 @@ ATOM WINAPI NtUserRegisterClassExWOW( const WNDCLASSEXW *wc, UNICODE_STRING *nam req->local = class->local; req->style = wc->style; req->instance = wine_server_client_ptr( instance ); - req->extra = class->cbClsExtra; + req->cls_extra = class->cbClsExtra; req->win_extra = wc->cbWndExtra; req->client_ptr = wine_server_client_ptr( class ); req->atom = wine_server_add_atom( req, name ); diff --git a/server/class.c b/server/class.c index a5cd765bc2b..1f223dbecc0 100644 --- a/server/class.c +++ b/server/class.c @@ -49,24 +49,22 @@ struct window_class atom_t atom; /* class atom for versioned class */ client_ptr_t client_ptr; /* pointer to class in client address space */ class_shm_t *shared; /* class in session shared memory */ - int nb_extra_bytes; /* number of extra bytes */ - char extra_bytes[1]; /* extra bytes storage */ };
-static struct window_class *create_class( struct process *process, int extra_bytes, int local, struct unicode_str *name, unsigned int name_offset, - atom_t atom, mod_handle_t instance, unsigned int style, int win_extra ) +C_ASSERT( sizeof(class_shm_t) == offsetof(class_shm_t, extra[0]) ); + +static struct window_class *create_class( struct process *process, int local, struct unicode_str *name, unsigned int name_offset, + atom_t atom, mod_handle_t instance, unsigned int style, int cls_extra, int win_extra ) { struct window_class *class;
- if (!(class = mem_alloc( sizeof(*class) + extra_bytes - 1 ))) return NULL; + if (!(class = mem_alloc( sizeof(*class) ))) return NULL;
class->process = (struct process *)grab_object( process ); class->count = 0; class->local = local; - class->nb_extra_bytes = extra_bytes; - memset( class->extra_bytes, 0, extra_bytes );
- if (!(class->shared = alloc_shared_object( sizeof(*class->shared) ))) goto failed; + if (!(class->shared = alloc_shared_object( offsetof(class_shm_t, extra[cls_extra]) ))) goto failed; SHARED_WRITE_BEGIN( class->shared, class_shm_t ) { memcpy( (void *)shared->name, name->str, name->len ); @@ -76,6 +74,8 @@ static struct window_class *create_class( struct process *process, int extra_byt shared->instance = instance; shared->style = style; shared->win_extra = win_extra; + shared->cls_extra = cls_extra; + memset( (void *)shared->extra, 0, cls_extra ); } SHARED_WRITE_END;
@@ -230,7 +230,7 @@ DECL_HANDLER(create_class) release_atom( table, base_atom ); return; } - if (req->extra < 0 || req->extra > 4096 || req->win_extra < 0 || req->win_extra > 4096) + if (req->cls_extra < 0 || req->cls_extra > 4096 || req->win_extra < 0 || req->win_extra > 4096) { /* don't allow stupid values here */ set_error( STATUS_INVALID_PARAMETER ); @@ -239,8 +239,8 @@ DECL_HANDLER(create_class) return; }
- if (!(class = create_class( current->process, req->extra, req->local, &name, offset, - base_atom, req->instance, req->style, req->win_extra ))) + if (!(class = create_class( current->process, req->local, &name, offset, base_atom, + req->instance, req->style, req->cls_extra, req->win_extra ))) { release_atom( table, atom ); release_atom( table, base_atom ); @@ -313,13 +313,13 @@ DECL_HANDLER(set_class_info) break; default: if (req->size > sizeof(req->new_info) || req->offset < 0 || - req->offset > class->nb_extra_bytes - (int)req->size) + req->offset > class->shared->cls_extra - (int)req->size) { set_win32_error( ERROR_INVALID_INDEX ); return; } - memcpy( &reply->old_info, class->extra_bytes + req->offset, req->size ); - memcpy( class->extra_bytes + req->offset, &req->new_info, req->size ); + memcpy( &reply->old_info, (char *)shared->extra + req->offset, req->size ); + memcpy( (char *)shared->extra + req->offset, &req->new_info, req->size ); break; } } @@ -345,15 +345,15 @@ DECL_HANDLER(get_class_info) /* not supported */ set_win32_error( ERROR_INVALID_HANDLE ); break; - case GCL_CBCLSEXTRA: reply->info = class->nb_extra_bytes; break; + case GCL_CBCLSEXTRA: reply->info = class->shared->cls_extra; break; default: if (req->size > sizeof(reply->info) || req->offset < 0 || - req->offset > class->nb_extra_bytes - (int)req->size) + req->offset > class->shared->cls_extra - (int)req->size) { set_win32_error( ERROR_INVALID_INDEX ); return; } - memcpy( &reply->info, class->extra_bytes + req->offset, req->size ); + memcpy( &reply->info, (char *)class->shared->extra + req->offset, req->size ); break; } } diff --git a/server/protocol.def b/server/protocol.def index 37c5e8be83f..a70696b9c96 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -1041,11 +1041,14 @@ typedef volatile struct { atom_t atom; /* class atom */ unsigned int style; /* class style */ + unsigned int cls_extra; /* number of class extra bytes */ unsigned int win_extra; /* number of window extra bytes */ mod_handle_t instance; /* module instance */ data_size_t name_offset; /* offset in WCHAR of the unversioned class name, constant */ data_size_t name_len; /* len in bytes of the class name, constant */ WCHAR name[MAX_ATOM_LEN]; /* class name, constant */ + unsigned short __pad; + char extra[]; /* extra bytes storage */ } class_shm_t;
typedef volatile struct @@ -3248,10 +3251,10 @@ enum caret_state @REQ(create_class) int local; /* is it a local class? */ atom_t atom; /* class atom */ + short int cls_extra; /* number of extra class bytes */ + short int win_extra; /* number of window extra bytes */ unsigned int style; /* class style */ mod_handle_t instance; /* module instance */ - 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 */