server: Refuse to close handles in other processes if they have an associated fd.
diff --git a/server/change.c b/server/change.c
index e046181..5468e85 100644
--- a/server/change.c
+++ b/server/change.c
@@ -177,7 +177,7 @@
     dir_get_fd,               /* get_fd */
     dir_map_access,           /* map_access */
     no_lookup_name,           /* lookup_name */
-    no_close_handle,          /* close_handle */
+    fd_close_handle,          /* close_handle */
     dir_destroy               /* destroy */
 };
 
diff --git a/server/fd.c b/server/fd.c
index 25b9a7c..4fbecbe 100644
--- a/server/fd.c
+++ b/server/fd.c
@@ -1658,6 +1658,12 @@
     return fd1->inode == fd2->inode;
 }
 
+/* handler for close_handle that refuses to close fd-associated handles in other processes */
+int fd_close_handle( struct object *obj, struct process *process, obj_handle_t handle )
+{
+    return (!current || current->process == process);
+}
+
 /* callback for event happening in the main poll() loop */
 void fd_poll_event( struct fd *fd, int event )
 {
diff --git a/server/file.c b/server/file.c
index 0f90019..ec34295 100644
--- a/server/file.c
+++ b/server/file.c
@@ -84,7 +84,7 @@
     file_get_fd,                  /* get_fd */
     file_map_access,              /* map_access */
     no_lookup_name,               /* lookup_name */
-    no_close_handle,              /* close_handle */
+    fd_close_handle,              /* close_handle */
     file_destroy                  /* destroy */
 };
 
diff --git a/server/file.h b/server/file.h
index 16d4399..fc8b904 100644
--- a/server/file.h
+++ b/server/file.h
@@ -55,6 +55,7 @@
 extern void set_fd_user( struct fd *fd, const struct fd_ops *ops, struct object *user );
 extern int get_unix_fd( struct fd *fd );
 extern int is_same_file_fd( struct fd *fd1, struct fd *fd2 );
+extern int fd_close_handle( struct object *obj, struct process *process, obj_handle_t handle );
 extern void fd_poll_event( struct fd *fd, int event );
 extern int check_fd_events( struct fd *fd, int events );
 extern void set_fd_events( struct fd *fd, int events );
diff --git a/server/mailslot.c b/server/mailslot.c
index 6c4fc1c..7015f41 100644
--- a/server/mailslot.c
+++ b/server/mailslot.c
@@ -80,7 +80,7 @@
     mailslot_get_fd,           /* get_fd */
     mailslot_map_access,       /* map_access */
     no_lookup_name,            /* lookup_name */
-    no_close_handle,           /* close_handle */
+    fd_close_handle,           /* close_handle */
     mailslot_destroy           /* destroy */
 };
 
@@ -124,7 +124,7 @@
     mail_writer_get_fd,         /* get_fd */
     mail_writer_map_access,     /* map_access */
     no_lookup_name,             /* lookup_name */
-    no_close_handle,            /* close_handle */
+    fd_close_handle,            /* close_handle */
     mail_writer_destroy         /* destroy */
 };
 
@@ -167,7 +167,7 @@
     mailslot_device_get_fd,         /* get_fd */
     no_map_access,                  /* map_access */
     mailslot_device_lookup_name,    /* lookup_name */
-    no_close_handle,                /* close_handle */
+    fd_close_handle,                /* close_handle */
     mailslot_device_destroy         /* destroy */
 };
 
diff --git a/server/mapping.c b/server/mapping.c
index 212af1b..d526e75 100644
--- a/server/mapping.c
+++ b/server/mapping.c
@@ -68,7 +68,7 @@
     mapping_get_fd,              /* get_fd */
     mapping_map_access,          /* map_access */
     no_lookup_name,              /* lookup_name */
-    no_close_handle,             /* close_handle */
+    fd_close_handle,             /* close_handle */
     mapping_destroy              /* destroy */
 };
 
diff --git a/server/named_pipe.c b/server/named_pipe.c
index bb0e741..e58f5b0 100644
--- a/server/named_pipe.c
+++ b/server/named_pipe.c
@@ -148,7 +148,7 @@
     pipe_server_get_fd,           /* get_fd */
     pipe_map_access,              /* map_access */
     no_lookup_name,               /* lookup_name */
-    no_close_handle,              /* close_handle */
+    fd_close_handle,              /* close_handle */
     pipe_server_destroy           /* destroy */
 };
 
@@ -181,7 +181,7 @@
     pipe_client_get_fd,           /* get_fd */
     pipe_map_access,              /* map_access */
     no_lookup_name,               /* lookup_name */
-    no_close_handle,              /* close_handle */
+    fd_close_handle,              /* close_handle */
     pipe_client_destroy           /* destroy */
 };
 
@@ -214,7 +214,7 @@
     named_pipe_device_get_fd,         /* get_fd */
     pipe_map_access,                  /* map_access */
     named_pipe_device_lookup_name,    /* lookup_name */
-    no_close_handle,                  /* close_handle */
+    fd_close_handle,                  /* close_handle */
     named_pipe_device_destroy         /* destroy */
 };
 
diff --git a/server/serial.c b/server/serial.c
index 49d3f79..a772256 100644
--- a/server/serial.c
+++ b/server/serial.c
@@ -104,7 +104,7 @@
     serial_get_fd,                /* get_fd */
     serial_map_access,            /* map_access */
     no_lookup_name,               /* lookup_name */
-    no_close_handle,              /* close_handle */
+    fd_close_handle,              /* close_handle */
     serial_destroy                /* destroy */
 };
 
diff --git a/server/sock.c b/server/sock.c
index c1a7a8d..9637469 100644
--- a/server/sock.c
+++ b/server/sock.c
@@ -114,7 +114,7 @@
     sock_get_fd,                  /* get_fd */
     sock_map_access,              /* map_access */
     no_lookup_name,               /* lookup_name */
-    no_close_handle,              /* close_handle */
+    fd_close_handle,              /* close_handle */
     sock_destroy                  /* destroy */
 };