From: Rémi Bernon <rbernon(a)codeweavers.com>
---
server/directory.c | 7 +++++++
server/file.h | 19 +++++++++++++++++++
server/mapping.c | 43 +++++++++++++++++++++++++++++++++++++++++++
server/object.c | 13 ++++++++++++-
server/object.h | 2 ++
server/protocol.def | 16 ++++++++++++++++
tools/make_requests | 1 +
7 files changed, 100 insertions(+), 1 deletion(-)
diff --git a/server/directory.c b/server/directory.c
index e521a7b38c9..224bd999219 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..a7397ffd093 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; \
+ session_object_t *__obj = CONTAINING_RECORD( shared, session_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..79072c8b9c8 100644
--- a/server/mapping.c
+++ b/server/mapping.c
@@ -225,6 +225,14 @@ static const mem_size_t granularity_mask = 0xffff;
static struct addr_range ranges32;
static struct addr_range ranges64;
+struct session
+{
+ const session_object_t *objects;
+ unsigned int object_capacity;
+};
+static struct mapping *session_mapping;
+static struct session session;
+
#define ROUND_SIZE(size) (((size) + page_mask) & ~page_mask)
void init_memory(void)
@@ -1256,6 +1264,41 @@ 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(*session.objects) * 512, 0x10000 );
+
+ return create_mapping( root, name, attr, size, SEC_COMMIT, 0, access, sd );
+}
+
+static void mark_session_object_free( const session_object_t *object )
+{
+ SHARED_WRITE_BEGIN( &object->shm, object_shm_t )
+ {
+ /* mark the object data as not accessible */
+ mark_block_noaccess( (void *)shared, sizeof(*shared) );
+ CONTAINING_RECORD( shared, session_object_t, shm )->id = 0;
+ }
+ SHARED_WRITE_END;
+}
+
+void set_session_mapping( struct mapping *mapping )
+{
+ unsigned int index;
+
+ session.objects = mmap( NULL, mapping->size, PROT_READ | PROT_WRITE, MAP_SHARED,
get_unix_fd( mapping->fd ), 0 );
+ if (session.objects == MAP_FAILED) return;
+
+ session_mapping = mapping;
+ session.object_capacity = mapping->size / sizeof(*session.objects);
+ assert( session.object_capacity != -1 );
+
+ for (index = 0; index < session.object_capacity; index++)
+ mark_session_object_free( &session.objects[index] );
+}
+
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 89e541ffb6b..9204593cb6c 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 f6d644d6182..81ac7a65c14 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
@@ -887,6 +888,21 @@ typedef struct
lparam_t info;
} cursor_pos_t;
+/****************************************************************/
+/* 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 */
+} session_object_t;
+
/****************************************************************/
/* Request declarations */
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" ],
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/3103