[Wine-patches] [eterhack] server: Remove mapping name when closing handle (eterbug #7400).
Alexander Morozov
amorozov на etersoft.ru
Чт Июн 28 20:57:19 MSK 2012
---
dlls/kernel32/tests/virtual.c | 7 -------
server/handle.c | 5 +++--
server/handle.h | 3 +++
server/mapping.c | 25 ++++++++++++++++++++++++-
4 files changed, 30 insertions(+), 10 deletions(-)
diff --git a/dlls/kernel32/tests/virtual.c b/dlls/kernel32/tests/virtual.c
index d02ca34..1042583 100644
--- a/dlls/kernel32/tests/virtual.c
+++ b/dlls/kernel32/tests/virtual.c
@@ -814,15 +814,11 @@ static void test_MapViewOfFile(void)
SetLastError(0xdeadbeef);
map2 = OpenFileMappingA(FILE_MAP_READ, FALSE, name);
- todo_wine
ok( map2 == 0, "OpenFileMappingA succeeded\n" );
- todo_wine
ok( GetLastError() == ERROR_FILE_NOT_FOUND, "OpenFileMappingA set error %d\n", GetLastError() );
- if (map2) CloseHandle(map2); /* FIXME: remove once Wine is fixed */
SetLastError(0xdeadbeef);
mapping = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, MAPPING_SIZE, name);
ok( mapping != 0, "CreateFileMappingA failed\n" );
- todo_wine
ok( GetLastError() == ERROR_SUCCESS, "CreateFileMappingA set error %d\n", GetLastError() );
SetLastError(0xdeadbeef);
ret = CloseHandle(mapping);
@@ -894,15 +890,12 @@ static void test_MapViewOfFile(void)
SetLastError(0xdeadbeef);
map2 = OpenFileMappingA(FILE_MAP_READ, FALSE, name);
- todo_wine
ok( map2 == 0, "OpenFileMappingA succeeded\n" );
- todo_wine
ok( GetLastError() == ERROR_FILE_NOT_FOUND, "OpenFileMappingA set error %d\n", GetLastError() );
CloseHandle(map2);
SetLastError(0xdeadbeef);
mapping = CreateFileMappingA(file, NULL, PAGE_READWRITE, 0, MAPPING_SIZE, name);
ok( mapping != 0, "CreateFileMappingA failed\n" );
- todo_wine
ok( GetLastError() == ERROR_SUCCESS, "CreateFileMappingA set error %d\n", GetLastError() );
SetLastError(0xdeadbeef);
ret = CloseHandle(mapping);
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 90956e9..ad2e1d2 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