Piotr Caban : server: Don' t create new handle when DUP_HANDLE_CLOSE_SOURCE is used if possible.

Alexandre Julliard julliard at winehq.org
Wed Jun 5 13:47:02 CDT 2013


Module: wine
Branch: master
Commit: 76bfbf43e99d102a2ae701b5e1a9cc9682f2494a
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=76bfbf43e99d102a2ae701b5e1a9cc9682f2494a

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Wed Jun  5 11:33:17 2013 +0200

server: Don't create new handle when DUP_HANDLE_CLOSE_SOURCE is used if possible.

---

 dlls/ntdll/om.c |   11 +++--------
 server/handle.c |   12 ++++++++++--
 2 files changed, 13 insertions(+), 10 deletions(-)

diff --git a/dlls/ntdll/om.c b/dlls/ntdll/om.c
index 18da18d..8b92f1b 100644
--- a/dlls/ntdll/om.c
+++ b/dlls/ntdll/om.c
@@ -332,16 +332,11 @@ NTSTATUS WINAPI NtDuplicateObject( HANDLE source_process, HANDLE source,
         if (!(ret = wine_server_call( req )))
         {
             if (dest) *dest = wine_server_ptr_handle( reply->handle );
-            if (reply->closed)
+            if (reply->closed && reply->self)
             {
-                if (reply->self)
-                {
-                    int fd = server_remove_fd_from_cache( source );
-                    if (fd != -1) close( fd );
-                }
+                int fd = server_remove_fd_from_cache( source );
+                if (fd != -1) close( fd );
             }
-            else if (options & DUPLICATE_CLOSE_SOURCE)
-                WARN( "failed to close handle %p in process %p\n", source, source_process );
         }
     }
     SERVER_END_REQ;
diff --git a/server/handle.c b/server/handle.c
index 1d8087b..28c49c2 100644
--- a/server/handle.c
+++ b/server/handle.c
@@ -531,6 +531,13 @@ obj_handle_t duplicate_handle( struct process *src, obj_handle_t src_handle, str
     {
         if (options & DUP_HANDLE_MAKE_GLOBAL)
             res = alloc_global_handle_no_access_check( obj, access );
+        else if ((options & DUP_HANDLE_CLOSE_SOURCE) && src == dst &&
+                 entry && !(entry->access & RESERVED_CLOSE_PROTECT))
+        {
+            if (attr & OBJ_INHERIT) access |= RESERVED_INHERIT;
+            entry->access = access;
+            res = src_handle;
+        }
         else
             res = alloc_handle_no_access_check( dst, obj, access, attr );
     }
@@ -581,7 +588,7 @@ DECL_HANDLER(set_handle_info)
 /* duplicate a handle */
 DECL_HANDLER(dup_handle)
 {
-    struct process *src, *dst;
+    struct process *src, *dst = NULL;
 
     reply->handle = 0;
     if ((src = get_process_from_handle( req->src_process, PROCESS_DUP_HANDLE )))
@@ -598,7 +605,8 @@ DECL_HANDLER(dup_handle)
             release_object( dst );
         }
         /* close the handle no matter what happened */
-        if (req->options & DUP_HANDLE_CLOSE_SOURCE) reply->closed = !close_handle( src, req->src_handle );
+        if ((req->options & DUP_HANDLE_CLOSE_SOURCE) && (src != dst || req->src_handle != reply->handle))
+            reply->closed = !close_handle( src, req->src_handle );
         reply->self = (src == current->process);
         release_object( src );
     }




More information about the wine-cvs mailing list