[Wine-patches] [eter-2.0.0] server: Remove mapping name when closing handle (eterbug #7400).

Alexander Morozov amorozov на etersoft.ru
Чт Июн 28 20:57:58 MSK 2012


---
 server/handle.c  |    5 +++--
 server/handle.h  |    3 +++
 server/mapping.c |   25 ++++++++++++++++++++++++-
 3 files changed, 30 insertions(+), 3 deletions(-)

diff --git a/server/handle.c b/server/handle.c
index 0fd155a..4cd7374 100644
--- a/server/handle.c
+++ b/server/handle.c
@@ -61,7 +61,8 @@ static struct handle_table *global_table;
 #define RESERVED_SHIFT         26
 #define RESERVED_INHERIT       (HANDLE_FLAG_INHERIT << RESERVED_SHIFT)
 #define RESERVED_CLOSE_PROTECT (HANDLE_FLAG_PROTECT_FROM_CLOSE << RESERVED_SHIFT)
-#define RESERVED_ALL           (RESERVED_INHERIT | RESERVED_CLOSE_PROTECT)
+#define RESERVED_WINE          (HANDLE_FLAG_WINE << RESERVED_SHIFT)
+#define RESERVED_ALL           (RESERVED_INHERIT | RESERVED_CLOSE_PROTECT | RESERVED_WINE)
 
 #define MIN_HANDLE_ENTRIES  32
 #define MAX_HANDLE_ENTRIES  0x00ffffff
@@ -475,7 +476,7 @@ obj_handle_t enumerate_handles( struct process *process, const struct object_ops
 
 /* get/set the handle reserved flags */
 /* return the old flags (or -1 on error) */
-static int set_handle_flags( struct process *process, obj_handle_t handle, int mask, int flags )
+int set_handle_flags( struct process *process, obj_handle_t handle, int mask, int flags )
 {
     struct handle_entry *entry;
     unsigned int old_access;
diff --git a/server/handle.h b/server/handle.h
index 821c4ef..1ae4317 100644
--- a/server/handle.h
+++ b/server/handle.h
@@ -30,6 +30,8 @@ struct object_ops;
 struct namespace;
 struct unicode_str;
 
+#define HANDLE_FLAG_WINE 0x00000004
+
 /* handle functions */
 
 /* alloc_handle takes a void *obj for convenience, but you better make sure */
@@ -49,6 +51,7 @@ extern obj_handle_t open_object( const struct namespace *namespace, const struct
 extern obj_handle_t find_inherited_handle( struct process *process, const struct object_ops *ops );
 extern obj_handle_t enumerate_handles( struct process *process, const struct object_ops *ops,
                                        unsigned int *index );
+extern int set_handle_flags( struct process *process, obj_handle_t handle, int mask, int flags );
 extern void close_process_handles( struct process *process );
 extern struct handle_table *alloc_handle_table( struct process *process, int count );
 extern struct handle_table *copy_handle_table( struct process *process, struct process *parent );
diff --git a/server/mapping.c b/server/mapping.c
index f37016f..0652aeb 100644
--- a/server/mapping.c
+++ b/server/mapping.c
@@ -65,12 +65,14 @@ struct mapping
     struct ranges  *committed;       /* list of committed ranges in this mapping */
     struct file    *shared_file;     /* temp file for shared PE mapping */
     struct list     shared_entry;    /* entry in global shared PE mappings list */
+    unsigned int    ref;             /* count of handles for internal using */
 };
 
 static void mapping_dump( struct object *obj, int verbose );
 static struct object_type *mapping_get_type( struct object *obj );
 static struct fd *mapping_get_fd( struct object *obj );
 static unsigned int mapping_map_access( struct object *obj, unsigned int access );
+static int mapping_close_handle( struct object *obj, struct process *process, obj_handle_t handle );
 static void mapping_destroy( struct object *obj );
 static enum server_fd_type mapping_get_fd_type( struct fd *fd );
 
@@ -90,7 +92,7 @@ static const struct object_ops mapping_ops =
     default_set_sd,              /* set_sd */
     no_lookup_name,              /* lookup_name */
     no_open_file,                /* open_file */
-    fd_close_handle,             /* close_handle */
+    mapping_close_handle,        /* close_handle */
     mapping_destroy              /* destroy */
 };
 
@@ -490,6 +492,7 @@ static struct object *create_mapping( struct directory *root, const struct unico
     mapping->fd          = NULL;
     mapping->shared_file = NULL;
     mapping->committed   = NULL;
+    mapping->ref         = 0;
 
     if (protect & VPROT_READ) access |= FILE_READ_DATA;
     if (protect & VPROT_WRITE) access |= FILE_WRITE_DATA;
@@ -627,6 +630,21 @@ static unsigned int mapping_map_access( struct object *obj, unsigned int access
     return access & ~(GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL);
 }
 
+static int mapping_close_handle( struct object *obj, struct process *process, obj_handle_t handle )
+{
+    if (fd_close_handle( obj, process, handle ))
+    {
+        struct mapping *mapping = (struct mapping *)obj;
+
+        if (set_handle_flags( process, handle, 0, 0 ) & HANDLE_FLAG_WINE)
+            --mapping->ref;
+        else if (mapping->ref + 1 == obj->refcount)
+            unlink_named_object( obj );
+        return 1;
+    }
+    return 0;
+}
+
 static void mapping_destroy( struct object *obj )
 {
     struct mapping *mapping = (struct mapping *)obj;
@@ -719,7 +737,12 @@ DECL_HANDLER(get_mapping_info)
         if ((fd = get_obj_fd( &mapping->obj )))
         {
             if (!is_fd_removable(fd))
+            {
                 reply->mapping = alloc_handle( current->process, mapping, 0, 0 );
+                set_handle_flags( current->process, reply->mapping,
+                                  HANDLE_FLAG_WINE, HANDLE_FLAG_WINE );
+                ++mapping->ref;
+            }
             release_object( fd );
         }
         if (mapping->shared_file)
-- 
1.7.10.5



Подробная информация о списке рассылки Wine-patches