server: Don't create new handle when DUP_HANDLE_CLOSE_SOURCE is used if possible.
This commit is contained in:
parent
8c882f6819
commit
76bfbf43e9
|
@ -332,17 +332,12 @@ 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 );
|
int fd = server_remove_fd_from_cache( source );
|
||||||
if (fd != -1) close( fd );
|
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;
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -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)
|
||||||
/* 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)
|
||||||
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 );
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue