Implemented NtDuplicateObject.
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
index c7db90d..fdc0ffa 100644
--- a/dlls/ntdll/ntdll.spec
+++ b/dlls/ntdll/ntdll.spec
@@ -99,7 +99,7 @@
@ stdcall NtDeleteValueKey(long ptr) NtDeleteValueKey
@ stdcall NtDeviceIoControlFile(long long long long long long long long long long) NtDeviceIoControlFile
@ stdcall NtDisplayString(ptr)NtDisplayString
-@ stdcall NtDuplicateObject(long long long long long long long) NtDuplicateObject
+@ stdcall NtDuplicateObject(long long long ptr long long long) NtDuplicateObject
@ stdcall NtDuplicateToken(long long long long long long) NtDuplicateToken
@ stub NtEnumerateBus
@ stdcall NtEnumerateKey (long long long long long long) NtEnumerateKey
@@ -616,7 +616,7 @@
@ stdcall ZwDeleteValueKey(long ptr) NtDeleteValueKey
@ stdcall ZwDeviceIoControlFile(long long long long long long long long long long) NtDeviceIoControlFile
@ stub ZwDisplayString
-@ stdcall ZwDuplicateObject(long long long long long long long) NtDuplicateObject
+@ stdcall ZwDuplicateObject(long long long ptr long long long) NtDuplicateObject
@ stdcall ZwDuplicateToken(long long long long long long) NtDuplicateToken
@ stub ZwEnumerateBus
@ stdcall ZwEnumerateKey(long long long ptr long ptr) NtEnumerateKey
diff --git a/dlls/ntdll/om.c b/dlls/ntdll/om.c
index fbcefa2..14efc7d 100644
--- a/dlls/ntdll/om.c
+++ b/dlls/ntdll/om.c
@@ -213,24 +213,34 @@
return STATUS_SUCCESS;
}
+
+
/******************************************************************************
* NtDuplicateObject [NTDLL.@]
* ZwDuplicateObject [NTDLL.@]
*/
-NTSTATUS WINAPI NtDuplicateObject(
- IN HANDLE SourceProcessHandle,
- IN PHANDLE SourceHandle,
- IN HANDLE TargetProcessHandle,
- OUT PHANDLE TargetHandle,
- IN ACCESS_MASK DesiredAccess,
- IN BOOLEAN InheritHandle,
- ULONG Options)
+NTSTATUS WINAPI NtDuplicateObject( HANDLE source_process, HANDLE source,
+ HANDLE dest_process, PHANDLE dest,
+ ACCESS_MASK access, ULONG attributes, ULONG options )
{
- FIXME("(0x%08x,%p,0x%08x,%p,0x%08lx,0x%08x,0x%08lx) stub!\n",
- SourceProcessHandle,SourceHandle,TargetProcessHandle,TargetHandle,
- DesiredAccess,InheritHandle,Options);
- *TargetHandle = 0;
- return 0;
+ NTSTATUS ret;
+ SERVER_START_REQ( dup_handle )
+ {
+ req->src_process = source_process;
+ req->src_handle = source;
+ req->dst_process = dest_process;
+ req->access = access;
+ req->inherit = (attributes & OBJ_INHERIT) != 0;
+ req->options = options;
+
+ if (!(ret = wine_server_call( req )))
+ {
+ if (dest) *dest = reply->handle;
+ if (reply->fd != -1) close( reply->fd );
+ }
+ }
+ SERVER_END_REQ;
+ return ret;
}
/**************************************************************************
diff --git a/include/winternl.h b/include/winternl.h
index 4c32a7f..43ddb17 100644
--- a/include/winternl.h
+++ b/include/winternl.h
@@ -762,6 +762,7 @@
NTSTATUS WINAPI NtDeleteKey(HANDLE);
NTSTATUS WINAPI NtDeleteValueKey(HANDLE,const UNICODE_STRING *);
NTSTATUS WINAPI NtDeviceIoControlFile(HANDLE,HANDLE,PIO_APC_ROUTINE,PVOID,PIO_STATUS_BLOCK,ULONG,PVOID,ULONG,PVOID,ULONG);
+NTSTATUS WINAPI NtDuplicateObject(HANDLE,HANDLE,HANDLE,PHANDLE,ACCESS_MASK,ULONG,ULONG);
NTSTATUS WINAPI NtEnumerateKey(HANDLE,ULONG,KEY_INFORMATION_CLASS,void *,DWORD,DWORD *);
NTSTATUS WINAPI NtEnumerateValueKey(HANDLE,ULONG,KEY_VALUE_INFORMATION_CLASS,PVOID,ULONG,PULONG);
NTSTATUS WINAPI NtFlushKey(HANDLE);
diff --git a/scheduler/handle.c b/scheduler/handle.c
index 3e828fe..1155da9 100644
--- a/scheduler/handle.c
+++ b/scheduler/handle.c
@@ -98,28 +98,13 @@
* DuplicateHandle (KERNEL32.@)
*/
BOOL WINAPI DuplicateHandle( HANDLE source_process, HANDLE source,
- HANDLE dest_process, HANDLE *dest,
- DWORD access, BOOL inherit, DWORD options )
+ HANDLE dest_process, HANDLE *dest,
+ DWORD access, BOOL inherit, DWORD options )
{
- BOOL ret;
- SERVER_START_REQ( dup_handle )
- {
- req->src_process = source_process;
- req->src_handle = source;
- req->dst_process = dest_process;
- req->access = access;
- req->inherit = inherit;
- req->options = options;
-
- ret = !wine_server_call_err( req );
- if (ret)
- {
- if (dest) *dest = reply->handle;
- if (reply->fd != -1) close( reply->fd );
- }
- }
- SERVER_END_REQ;
- return ret;
+ NTSTATUS status = NtDuplicateObject( source_process, source, dest_process, dest,
+ access, inherit ? OBJ_INHERIT : 0, options );
+ if (status) SetLastError( RtlNtStatusToDosError(status) );
+ return !status;
}