diff --git a/server/handle.c b/server/handle.c index 5ba8d26920605388a33422118ad7f928af7ded3f..996d1d14c2f126bb902624b4e4735232668ff5c7 100644 --- a/server/handle.c +++ b/server/handle.c @@ -245,14 +245,25 @@ int duplicate_handle( struct process *src, int src_handle, struct process *dst, unsigned int access, int inherit, int options ) { int res; - struct handle_entry *entry = get_handle( src, src_handle ); - if (!entry) return -1; + struct object *obj = get_handle_obj( src, src_handle, 0, NULL ); - if (options & DUP_HANDLE_SAME_ACCESS) access = entry->access; + if (!obj) return -1; + if (options & DUP_HANDLE_SAME_ACCESS) + { + struct handle_entry *entry = get_handle( src, src_handle ); + if (entry) + access = entry->access; + else /* pseudo-handle, give it full access */ + { + access = STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL; + CLEAR_ERROR(); + } + } if (options & DUP_HANDLE_MAKE_GLOBAL) dst = initial_process; access &= ~RESERVED_ALL; - res = alloc_handle( dst, entry->ptr, access, inherit ); - if (options & DUP_HANDLE_MAKE_GLOBAL) res = HANDLE_LOCAL_TO_GLOBAL(res); + res = alloc_handle( dst, obj, access, inherit ); + release_object( obj ); + if ((options & DUP_HANDLE_MAKE_GLOBAL) && (res != -1)) res = HANDLE_LOCAL_TO_GLOBAL(res); return res; }