From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/window.c | 2 +- include/ntuser.h | 2 +- server/hook.c | 2 +- server/protocol.def | 6 ++++++ server/user.c | 14 ++++++++------ server/user.h | 2 +- server/window.c | 14 +++++++++++++- 7 files changed, 31 insertions(+), 11 deletions(-)
diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index 3cc3addc298..5a9a727f9ca 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -97,7 +97,7 @@ static BOOL read_acquire_user_entry( HANDLE handle, unsigned short type, const v dst->offset = src->offset; dst->tid = src->tid; dst->pid = src->pid; - dst->padding = src->padding; + dst->id = src->id; __SHARED_READ_FENCE; dst->uniq = ReadNoFence64( &src->uniq ); return dst->uniq == uniq; diff --git a/include/ntuser.h b/include/ntuser.h index 41c9fc84cd2..49bf0d03855 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -51,7 +51,7 @@ struct user_entry ULONG64 offset; /* shared user object offset */ ULONG tid; /* owner thread id */ ULONG pid; /* owner process id */ - ULONG64 padding; + ULONG64 id; /* shared user object id */ union { struct diff --git a/server/hook.c b/server/hook.c index bf2ad266e76..4c55c565968 100644 --- a/server/hook.c +++ b/server/hook.c @@ -153,7 +153,7 @@ static struct hook *add_hook( struct desktop *desktop, struct process *process, } if (!(hook = mem_alloc( sizeof(*hook) ))) return NULL;
- if (!(hook->handle = alloc_user_handle( hook, NTUSER_OBJ_HOOK ))) + if (!(hook->handle = alloc_user_handle( hook, NULL, NTUSER_OBJ_HOOK ))) { free( hook ); return NULL; diff --git a/server/protocol.def b/server/protocol.def index 26c411d0c62..bdd3c526890 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -1009,11 +1009,17 @@ typedef volatile struct int keystate_lock; /* keystate is locked */ } input_shm_t;
+typedef volatile struct +{ + int placeholder; +} window_shm_t; + typedef volatile union { desktop_shm_t desktop; queue_shm_t queue; input_shm_t input; + window_shm_t window; } object_shm_t;
typedef volatile struct diff --git a/server/user.c b/server/user.c index d4ce8194cee..a4a06455275 100644 --- a/server/user.c +++ b/server/user.c @@ -73,7 +73,7 @@ static user_handle_t entry_to_handle( const user_entry_t *entry ) return (index << 1) + FIRST_USER_HANDLE + (entry->generation << 16); }
-static const user_entry_t *alloc_user_entry( unsigned short type ) +static const user_entry_t *alloc_user_entry( struct obj_locator locator, unsigned short type ) { user_entry_t *entry, *handles = shared_session->user_entries; unsigned short generation; @@ -93,10 +93,10 @@ static const user_entry_t *alloc_user_entry( unsigned short type )
if (generation == 0 || generation == 0xffff) generation = 1;
- entry->offset = -1; + entry->offset = locator.offset; entry->tid = get_thread_id( current ); entry->pid = get_process_id( current->process ); - entry->padding = -1; + entry->id = locator.id; WriteRelease64( &entry->uniq, MAKELONG(type, generation) ); return entry; } @@ -112,11 +112,13 @@ static void free_user_entry( user_entry_t *entry ) }
/* allocate a user handle for a given object */ -user_handle_t alloc_user_handle( void *ptr, unsigned short type ) +user_handle_t alloc_user_handle( void *ptr, volatile void *shared, unsigned short type ) { + struct obj_locator locator = {0}; const user_entry_t *entry;
- if (!(entry = alloc_user_entry( type ))) return 0; + if (shared) locator = get_shared_object_locator( shared ); + if (!(entry = alloc_user_entry( locator, type ))) return 0; set_server_object( entry, ptr ); return entry_to_handle( entry ); } @@ -220,7 +222,7 @@ void free_process_user_handles( struct process *process ) /* allocate an arbitrary user handle */ DECL_HANDLER(alloc_user_handle) { - reply->handle = alloc_user_handle( (void *)-1 /* never used */, req->type ); + reply->handle = alloc_user_handle( (void *)-1 /* never used */, NULL, req->type ); }
diff --git a/server/user.h b/server/user.h index 50b275e4eb2..ee0042b8755 100644 --- a/server/user.h +++ b/server/user.h @@ -90,7 +90,7 @@ struct desktop
/* user handles functions */
-extern user_handle_t alloc_user_handle( void *ptr, unsigned short type ); +extern user_handle_t alloc_user_handle( void *ptr, volatile void *shared, unsigned short type ); extern void *get_user_object( user_handle_t handle, unsigned short type ); extern void *get_user_object_handle( user_handle_t *handle, unsigned short type ); extern user_handle_t get_user_full_handle( user_handle_t handle ); diff --git a/server/window.c b/server/window.c index c59b8646118..415957a027b 100644 --- a/server/window.c +++ b/server/window.c @@ -30,6 +30,7 @@ #include "ntuser.h"
#include "object.h" +#include "file.h" #include "request.h" #include "thread.h" #include "process.h" @@ -94,6 +95,7 @@ struct window struct property *properties; /* window properties array */ int nb_extra_bytes; /* number of extra bytes */ char *extra_bytes; /* extra bytes storage */ + window_shm_t *shared; /* window in session shared memory */ };
static void window_dump( struct object *obj, int verbose ); @@ -180,6 +182,8 @@ static void window_destroy( struct object *obj ) memset( win->extra_bytes, 0x55, win->nb_extra_bytes ); free( win->extra_bytes ); } + + if (win->shared) free_shared_object( win->shared ); }
/* retrieve a pointer to a window from its handle */ @@ -662,17 +666,25 @@ static struct window *create_window( struct window *parent, struct window *owner win->properties = NULL; win->nb_extra_bytes = 0; win->extra_bytes = NULL; + win->shared = NULL; win->window_rect = win->visible_rect = win->surface_rect = win->client_rect = empty_rect; list_init( &win->children ); list_init( &win->unlinked );
+ if (!(win->shared = alloc_shared_object())) goto failed; + SHARED_WRITE_BEGIN( win->shared, window_shm_t ) + { + shared->placeholder = 0; + } + SHARED_WRITE_END; + if (extra_bytes) { if (!(win->extra_bytes = mem_alloc( extra_bytes ))) goto failed; memset( win->extra_bytes, 0, extra_bytes ); win->nb_extra_bytes = extra_bytes; } - if (!(win->handle = alloc_user_handle( win, NTUSER_OBJ_WINDOW ))) goto failed; + if (!(win->handle = alloc_user_handle( win, win->shared, NTUSER_OBJ_WINDOW ))) goto failed; win->last_active = win->handle;
/* if parent belongs to a different thread and the window isn't */