Commit 76bfbf43 authored by Piotr Caban's avatar Piotr Caban Committed by Alexandre Julliard

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

parent 8c882f68
...@@ -332,16 +332,11 @@ NTSTATUS WINAPI NtDuplicateObject( HANDLE source_process, HANDLE source, ...@@ -332,16 +332,11 @@ NTSTATUS WINAPI NtDuplicateObject( HANDLE source_process, HANDLE source,
if (!(ret = wine_server_call( req ))) if (!(ret = wine_server_call( req )))
{ {
if (dest) *dest = wine_server_ptr_handle( reply->handle ); 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; SERVER_END_REQ;
......
...@@ -531,6 +531,13 @@ obj_handle_t duplicate_handle( struct process *src, obj_handle_t src_handle, str ...@@ -531,6 +531,13 @@ obj_handle_t duplicate_handle( struct process *src, obj_handle_t src_handle, str
{ {
if (options & DUP_HANDLE_MAKE_GLOBAL) if (options & DUP_HANDLE_MAKE_GLOBAL)
res = alloc_global_handle_no_access_check( obj, access ); 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 else
res = alloc_handle_no_access_check( dst, obj, access, attr ); res = alloc_handle_no_access_check( dst, obj, access, attr );
} }
...@@ -581,7 +588,7 @@ DECL_HANDLER(set_handle_info) ...@@ -581,7 +588,7 @@ DECL_HANDLER(set_handle_info)
/* duplicate a handle */ /* duplicate a handle */
DECL_HANDLER(dup_handle) DECL_HANDLER(dup_handle)
{ {
struct process *src, *dst; struct process *src, *dst = NULL;
reply->handle = 0; reply->handle = 0;
if ((src = get_process_from_handle( req->src_process, PROCESS_DUP_HANDLE ))) if ((src = get_process_from_handle( req->src_process, PROCESS_DUP_HANDLE )))
...@@ -598,7 +605,8 @@ DECL_HANDLER(dup_handle) ...@@ -598,7 +605,8 @@ DECL_HANDLER(dup_handle)
release_object( dst ); release_object( dst );
} }
/* close the handle no matter what happened */ /* 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); reply->self = (src == current->process);
release_object( src ); release_object( src );
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment