From fac940dfac314c2b1c120cf9ff8503259153c5a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Bernon?= Date: Mon, 19 Feb 2024 21:38:21 +0100 Subject: [PATCH] server: Create a global session shared mapping. --- include/wine/server_protocol.h | 18 +++++++++++++- server/directory.c | 7 ++++++ server/file.h | 19 ++++++++++++++ server/mapping.c | 45 ++++++++++++++++++++++++++++++++++ server/object.c | 13 +++++++++- server/object.h | 2 ++ server/protocol.def | 16 ++++++++++++ server/request.h | 1 + tools/make_requests | 1 + 9 files changed, 120 insertions(+), 2 deletions(-) diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index e16f1ceb7c3..0b5aca33c69 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -29,6 +29,7 @@ typedef unsigned __int64 mem_size_t; typedef unsigned __int64 file_pos_t; typedef unsigned __int64 client_ptr_t; typedef unsigned __int64 affinity_t; +typedef unsigned __int64 object_id_t; typedef client_ptr_t mod_handle_t; struct request_header @@ -882,6 +883,21 @@ struct directory_entry +typedef volatile union +{ + char placeholder; +} object_shm_t; + +typedef volatile struct +{ + LONG64 seq; + object_id_t id; + object_shm_t shm; +} shared_object_t; + + + + struct new_process_request { @@ -6531,7 +6547,7 @@ union generic_reply /* ### protocol_version begin ### */ -#define SERVER_PROTOCOL_VERSION 808 +#define SERVER_PROTOCOL_VERSION 809 /* ### protocol_version end ### */ diff --git a/server/directory.c b/server/directory.c index 8a140309871..b3f055dfd01 100644 --- a/server/directory.c +++ b/server/directory.c @@ -439,11 +439,14 @@ void init_directories( struct fd *intl_fd ) /* mappings */ static const WCHAR intlW[] = {'N','l','s','S','e','c','t','i','o','n','L','A','N','G','_','I','N','T','L'}; static const WCHAR user_dataW[] = {'_','_','w','i','n','e','_','u','s','e','r','_','s','h','a','r','e','d','_','d','a','t','a'}; + static const WCHAR sessionW[] = {'_','_','w','i','n','e','_','s','e','s','s','i','o','n'}; static const struct unicode_str intl_str = {intlW, sizeof(intlW)}; static const struct unicode_str user_data_str = {user_dataW, sizeof(user_dataW)}; + static const struct unicode_str session_str = {sessionW, sizeof(sessionW)}; struct directory *dir_driver, *dir_device, *dir_global, *dir_kernel, *dir_nls; struct object *named_pipe_device, *mailslot_device, *null_device; + struct mapping *session_mapping; unsigned int i; root_directory = create_directory( NULL, NULL, OBJ_PERMANENT, HASH_SIZE, NULL ); @@ -491,6 +494,10 @@ void init_directories( struct fd *intl_fd ) release_object( create_user_data_mapping( &dir_kernel->obj, &user_data_str, OBJ_PERMANENT, NULL )); release_object( intl_fd ); + session_mapping = create_session_mapping( &dir_kernel->obj, &session_str, OBJ_PERMANENT, NULL ); + set_session_mapping( session_mapping ); + release_object( session_mapping ); + release_object( named_pipe_device ); release_object( mailslot_device ); release_object( null_device ); diff --git a/server/file.h b/server/file.h index 7f2d1637863..661e8f9d159 100644 --- a/server/file.h +++ b/server/file.h @@ -188,6 +188,25 @@ extern struct mapping *create_fd_mapping( struct object *root, const struct unic unsigned int attr, const struct security_descriptor *sd ); extern struct object *create_user_data_mapping( struct object *root, const struct unicode_str *name, unsigned int attr, const struct security_descriptor *sd ); +extern struct mapping *create_session_mapping( struct object *root, const struct unicode_str *name, + unsigned int attr, const struct security_descriptor *sd ); +extern void set_session_mapping( struct mapping *mapping ); + +#define SHARED_WRITE_BEGIN( object_shm, type ) \ + do { \ + const type *__shared = (object_shm); \ + type *shared = (type *)__shared; \ + shared_object_t *__obj = CONTAINING_RECORD( shared, shared_object_t, shm ); \ + LONG64 __seq = __obj->seq + 1, __end = __seq + 1; \ + assert( (__seq & 1) != 0 ); \ + __WINE_ATOMIC_STORE_RELEASE( &__obj->seq, &__seq ); \ + do + +#define SHARED_WRITE_END \ + while(0); \ + assert( __seq == __obj->seq ); \ + __WINE_ATOMIC_STORE_RELEASE( &__obj->seq, &__end ); \ + } while(0) /* device functions */ diff --git a/server/mapping.c b/server/mapping.c index ff99b45ce51..6605c111beb 100644 --- a/server/mapping.c +++ b/server/mapping.c @@ -225,6 +225,23 @@ static const mem_size_t granularity_mask = 0xffff; static struct addr_range ranges32; static struct addr_range ranges64; +struct session_block +{ + struct list entry; /* entry in the session block list */ + const char *data; /* base pointer for the mmaped data */ +}; + +struct session +{ + struct list blocks; +}; + +static struct mapping *session_mapping; +static struct session session = +{ + .blocks = LIST_INIT(session.blocks), +}; + #define ROUND_SIZE(size) (((size) + page_mask) & ~page_mask) void init_memory(void) @@ -1256,6 +1273,34 @@ int get_page_size(void) return page_mask + 1; } +struct mapping *create_session_mapping( struct object *root, const struct unicode_str *name, + unsigned int attr, const struct security_descriptor *sd ) +{ + static const unsigned int access = FILE_READ_DATA | FILE_WRITE_DATA; + mem_size_t size = max( sizeof(shared_object_t) * 512, 0x10000 ); + + return create_mapping( root, name, attr, size, SEC_COMMIT, 0, access, sd ); +} + +void set_session_mapping( struct mapping *mapping ) +{ + int unix_fd = get_unix_fd( mapping->fd ); + mem_size_t size = mapping->size; + struct session_block *block; + void *tmp; + + if (!(block = mem_alloc( sizeof(*block) ))) return; + if ((tmp = mmap( NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, unix_fd, 0 )) == MAP_FAILED) + { + free( block ); + return; + } + + block->data = tmp; + session_mapping = mapping; + list_add_tail( &session.blocks, &block->entry ); +} + struct object *create_user_data_mapping( struct object *root, const struct unicode_str *name, unsigned int attr, const struct security_descriptor *sd ) { diff --git a/server/object.c b/server/object.c index 459ead5f3a5..3b72b576d50 100644 --- a/server/object.c +++ b/server/object.c @@ -102,8 +102,19 @@ void close_objects(void) /*****************************************************************/ +/* mark a block of memory as not accessible for debugging purposes */ +void mark_block_noaccess( void *ptr, size_t size ) +{ + memset( ptr, 0xfe, size ); +#if defined(VALGRIND_MAKE_MEM_NOACCESS) + VALGRIND_DISCARD( VALGRIND_MAKE_MEM_NOACCESS( ptr, size ) ); +#elif defined(VALGRIND_MAKE_NOACCESS) + VALGRIND_DISCARD( VALGRIND_MAKE_NOACCESS( ptr, size ) ); +#endif +} + /* mark a block of memory as uninitialized for debugging purposes */ -static inline void mark_block_uninitialized( void *ptr, size_t size ) +void mark_block_uninitialized( void *ptr, size_t size ) { memset( ptr, 0x55, size ); #if defined(VALGRIND_MAKE_MEM_UNDEFINED) diff --git a/server/object.h b/server/object.h index d4d66536b81..2337ee88231 100644 --- a/server/object.h +++ b/server/object.h @@ -139,6 +139,8 @@ struct wait_queue_entry struct thread_wait *wait; }; +extern void mark_block_noaccess( void *ptr, size_t size ); +extern void mark_block_uninitialized( void *ptr, size_t size ); extern void *mem_alloc( size_t size ) __WINE_ALLOC_SIZE(1) __WINE_DEALLOC(free) __WINE_MALLOC; extern void *memdup( const void *data, size_t len ) __WINE_ALLOC_SIZE(2) __WINE_DEALLOC(free); extern void *alloc_object( const struct object_ops *ops ); diff --git a/server/protocol.def b/server/protocol.def index 766674d3e30..aad95db1195 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -45,6 +45,7 @@ typedef unsigned __int64 mem_size_t; typedef unsigned __int64 file_pos_t; typedef unsigned __int64 client_ptr_t; typedef unsigned __int64 affinity_t; +typedef unsigned __int64 object_id_t; typedef client_ptr_t mod_handle_t; struct request_header @@ -895,6 +896,21 @@ struct directory_entry /* VARARG(type,unicode_str,type_len); */ }; +/****************************************************************/ +/* shared session mapping structures */ + +typedef volatile union +{ + char placeholder; +} object_shm_t; + +typedef volatile struct +{ + LONG64 seq; /* sequence number - server updating if (seq & 1) != 0 */ + object_id_t id; /* object unique id, object data is valid if != 0 */ + object_shm_t shm; /* object shared data */ +} shared_object_t; + /****************************************************************/ /* Request declarations */ diff --git a/server/request.h b/server/request.h index 67de9bb1779..fe323d4785a 100644 --- a/server/request.h +++ b/server/request.h @@ -721,6 +721,7 @@ C_ASSERT( sizeof(mem_size_t) == 8 ); C_ASSERT( sizeof(message_data_t) == 48 ); C_ASSERT( sizeof(mod_handle_t) == 8 ); C_ASSERT( sizeof(obj_handle_t) == 4 ); +C_ASSERT( sizeof(object_id_t) == 8 ); C_ASSERT( sizeof(pe_image_info_t) == 88 ); C_ASSERT( sizeof(process_id_t) == 4 ); C_ASSERT( sizeof(property_data_t) == 16 ); diff --git a/tools/make_requests b/tools/make_requests index 419b1264ea4..b20b53096ca 100755 --- a/tools/make_requests +++ b/tools/make_requests @@ -42,6 +42,7 @@ my %formats = "file_pos_t" => [ 8, 8, "&dump_uint64" ], "mem_size_t" => [ 8, 8, "&dump_uint64" ], "affinity_t" => [ 8, 8, "&dump_uint64" ], + "object_id_t" => [ 8, 8, "&dump_uint64" ], "timeout_t" => [ 8, 8, "&dump_timeout" ], "abstime_t" => [ 8, 8, "&dump_abstime" ], "rectangle_t" => [ 16, 4, "&dump_rectangle" ],