server: Store a duplicate of the file descriptor for file mappings.
diff --git a/server/mapping.c b/server/mapping.c
index 67760c9..e3f69a8 100644
--- a/server/mapping.c
+++ b/server/mapping.c
@@ -70,6 +70,7 @@
 static struct fd *mapping_get_fd( struct object *obj );
 static unsigned int mapping_map_access( struct object *obj, unsigned int access );
 static void mapping_destroy( struct object *obj );
+static enum server_fd_type mapping_get_fd_type( struct fd *fd );
 
 static const struct object_ops mapping_ops =
 {
@@ -91,6 +92,18 @@
     mapping_destroy              /* destroy */
 };
 
+static const struct fd_ops mapping_fd_ops =
+{
+    default_fd_get_poll_events,   /* get_poll_events */
+    default_poll_event,           /* poll_event */
+    no_flush,                     /* flush */
+    mapping_get_fd_type,          /* get_fd_type */
+    no_fd_ioctl,                  /* ioctl */
+    no_fd_queue_async,            /* queue_async */
+    default_fd_reselect_async,    /* reselect_async */
+    default_fd_cancel_async       /* cancel_async */
+};
+
 static struct list shared_list = LIST_INIT(shared_list);
 
 #ifdef __i386__
@@ -396,6 +409,8 @@
                                       obj_handle_t handle, const struct security_descriptor *sd )
 {
     struct mapping *mapping;
+    struct file *file;
+    struct fd *fd;
     int access = 0;
     int unix_fd;
     struct stat st;
@@ -428,8 +443,14 @@
             set_error( STATUS_INVALID_PARAMETER );
             goto error;
         }
-        if (!(mapping->file = get_file_obj( current->process, handle, access ))) goto error;
-        mapping->fd = get_obj_fd( (struct object *)mapping->file );
+        if (!(file = get_file_obj( current->process, handle, access ))) goto error;
+        fd = get_obj_fd( (struct object *)file );
+        mapping->fd = dup_fd_object( fd );
+        release_object( file );
+        release_object( fd );
+        if (!mapping->fd) goto error;
+
+        set_fd_user( mapping->fd, &mapping_fd_ops, &mapping->obj );
         if ((unix_fd = get_unix_fd( mapping->fd )) == -1) goto error;
         if (protect & VPROT_IMAGE)
         {
@@ -527,6 +548,11 @@
     free( mapping->committed );
 }
 
+static enum server_fd_type mapping_get_fd_type( struct fd *fd )
+{
+    return FD_TYPE_FILE;
+}
+
 int get_page_size(void)
 {
     if (!page_mask) init_page_size();