[ros-kernel] attempt to fix Nt/ZwDuplicateObject() and
ObCreateHandle() functions
Thomas Weidenmueller
thomas at reactsoft.com
Fri Jul 30 15:18:56 CEST 2004
Hi,
I attempted to fix the Nt/ZwDuplicateObject() and ObCreateHandle()
functions (the Inherit parameter is supposed to be HandleAttributes
instead). I also added a few access checks on some places. However, I
don't remember if the changes worked properly, I just thought I might
submit it, in case someone finds it useful. Patch is attached.
Regards
Thomas
-------------- next part --------------
Index: include/ntos/ntdef.h
===================================================================
RCS file: /CVS/ReactOS/reactos/include/ntos/ntdef.h,v
retrieving revision 1.8
diff -u -r1.8 ntdef.h
--- include/ntos/ntdef.h 13 Jul 2004 16:57:10 -0000 1.8
+++ include/ntos/ntdef.h 23 Jul 2004 13:09:19 -0000
@@ -25,6 +25,7 @@
#define DUPLICATE_CLOSE_SOURCE (1)
#define DUPLICATE_SAME_ACCESS (2)
+#define DUPLICATE_SAME_ATTRIBUTES (4)
#define INVALID_HANDLE_VALUE ((HANDLE)-1)
Index: include/ntos/zw.h
===================================================================
RCS file: /CVS/ReactOS/reactos/include/ntos/zw.h,v
retrieving revision 1.28
diff -u -r1.28 zw.h
--- include/ntos/zw.h 17 Jul 2004 05:13:05 -0000 1.28
+++ include/ntos/zw.h 23 Jul 2004 12:59:14 -0000
@@ -5662,7 +5662,7 @@
* TargetProcessHandle = The destination process owning the handle
* TargetHandle (OUT) = Caller should supply storage for the duplicated handle.
* DesiredAccess = The desired access to the handle.
- * InheritHandle = Indicates wheter the new handle will be inheritable or not.
+ * HandleAttributes = Specifies the handle attributes for the new handle.
* Options = Specifies special actions upon duplicating the handle. Can be
* one of the values DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS.
* DUPLICATE_CLOSE_SOURCE specifies that the source handle should be
@@ -5681,7 +5681,7 @@
IN HANDLE TargetProcessHandle,
OUT PHANDLE TargetHandle,
IN ACCESS_MASK DesiredAccess,
- IN BOOLEAN InheritHandle,
+ IN ULONG HandleAttributes,
IN ULONG Options
);
@@ -5693,7 +5693,7 @@
IN HANDLE TargetProcessHandle,
OUT PHANDLE TargetHandle,
IN ACCESS_MASK DesiredAccess,
- IN BOOLEAN InheritHandle,
+ IN ULONG HandleAttributes,
IN ULONG Options
);
Index: lib/kernel32/misc/handle.c
===================================================================
RCS file: /CVS/ReactOS/reactos/lib/kernel32/misc/handle.c,v
retrieving revision 1.16
diff -u -r1.16 handle.c
--- lib/kernel32/misc/handle.c 23 Jan 2004 21:16:03 -0000 1.16
+++ lib/kernel32/misc/handle.c 23 Jul 2004 12:54:00 -0000
@@ -171,7 +171,7 @@
hTargetProcessHandle,
lpTargetHandle,
dwDesiredAccess,
- (BOOLEAN)bInheritHandle,
+ (bInheritHandle ? OBJ_INHERIT: 0),
dwOptions);
if (!NT_SUCCESS(errCode))
{
Index: lib/kernel32/process/create.c
===================================================================
RCS file: /CVS/ReactOS/reactos/lib/kernel32/process/create.c,v
retrieving revision 1.87
diff -u -r1.87 create.c
--- lib/kernel32/process/create.c 7 Jul 2004 16:32:02 -0000 1.87
+++ lib/kernel32/process/create.c 23 Jul 2004 13:18:28 -0000
@@ -1061,7 +1061,7 @@
hProcess,
&Ppb->CurrentDirectoryHandle,
0,
- TRUE,
+ OBJ_INHERIT,
DUPLICATE_SAME_ACCESS);
}
@@ -1208,7 +1208,7 @@
hProcess,
&Ppb->hStdInput,
0,
- TRUE,
+ OBJ_INHERIT,
DUPLICATE_SAME_ACCESS);
if(!NT_SUCCESS(Status))
{
@@ -1231,7 +1231,7 @@
hProcess,
&Ppb->hStdOutput,
0,
- TRUE,
+ OBJ_INHERIT,
DUPLICATE_SAME_ACCESS);
if(!NT_SUCCESS(Status))
{
@@ -1268,7 +1268,7 @@
hProcess,
&Ppb->hStdError,
0,
- TRUE,
+ OBJ_INHERIT,
DUPLICATE_SAME_ACCESS);
if(!NT_SUCCESS(Status))
{
Index: lib/kernel32/process/proc.c
===================================================================
RCS file: /CVS/ReactOS/reactos/lib/kernel32/process/proc.c,v
retrieving revision 1.63
diff -u -r1.63 proc.c
--- lib/kernel32/process/proc.c 2 Jul 2004 12:18:04 -0000 1.63
+++ lib/kernel32/process/proc.c 23 Jul 2004 13:19:16 -0000
@@ -731,7 +731,7 @@
GetCurrentProcess(),
&hProcessTmp,
(PROCESS_SET_INFORMATION | PROCESS_QUERY_INFORMATION),
- FALSE,
+ 0,
0);
if (!NT_SUCCESS(Status))
{
@@ -793,7 +793,7 @@
GetCurrentProcess(),
&hProcessTmp,
(PROCESS_SET_INFORMATION | PROCESS_QUERY_INFORMATION),
- FALSE,
+ 0,
0);
if (!NT_SUCCESS(Status))
{
Index: lib/ntdll/rtl/registry.c
===================================================================
RCS file: /CVS/ReactOS/reactos/lib/ntdll/rtl/registry.c,v
retrieving revision 1.28
diff -u -r1.28 registry.c
--- lib/ntdll/rtl/registry.c 20 Mar 2004 15:56:00 -0000 1.28
+++ lib/ntdll/rtl/registry.c 23 Jul 2004 13:20:30 -0000
@@ -48,7 +48,7 @@
NtCurrentProcess(),
KeyHandle,
0,
- FALSE,
+ 0,
DUPLICATE_SAME_ACCESS);
return(Status);
}
Index: ntoskrnl/cm/rtlfunc.c
===================================================================
RCS file: /CVS/ReactOS/reactos/ntoskrnl/cm/rtlfunc.c,v
retrieving revision 1.38
diff -u -r1.38 rtlfunc.c
--- ntoskrnl/cm/rtlfunc.c 3 Apr 2004 13:45:00 -0000 1.38
+++ ntoskrnl/cm/rtlfunc.c 23 Jul 2004 13:21:43 -0000
@@ -42,7 +42,7 @@
NtCurrentProcess(),
KeyHandle,
0,
- FALSE,
+ 0,
DUPLICATE_SAME_ACCESS);
return(Status);
}
Index: ntoskrnl/include/internal/ob.h
===================================================================
RCS file: /CVS/ReactOS/reactos/ntoskrnl/include/internal/ob.h,v
retrieving revision 1.20
diff -u -r1.20 ob.h
--- ntoskrnl/include/internal/ob.h 23 Jul 2004 21:43:11 -0000 1.20
+++ ntoskrnl/include/internal/ob.h 25 Jul 2004 13:45:30 -0000
@@ -94,7 +94,7 @@
NTSTATUS ObCreateHandle(struct _EPROCESS* Process,
PVOID ObjectBody,
ACCESS_MASK GrantedAccess,
- BOOLEAN Inherit,
+ ULONG HandleAttributes,
PHANDLE Handle);
VOID ObCreateHandleTable(struct _EPROCESS* Parent,
BOOLEAN Inherit,
@@ -111,26 +111,26 @@
HANDLE Handle,
PVOID *ObjectBody);
-NTSTATUS
+NTSTATUS FASTCALL
ObpQueryHandleAttributes(HANDLE Handle,
- POBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo);
+ POBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo);
-NTSTATUS
+NTSTATUS FASTCALL
ObpSetHandleAttributes(HANDLE Handle,
- POBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo);
+ POBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo);
NTSTATUS
ObpCreateTypeObject(POBJECT_TYPE ObjectType);
ULONG
ObGetObjectHandleCount(PVOID Object);
-NTSTATUS
+NTSTATUS FASTCALL
ObDuplicateObject(PEPROCESS SourceProcess,
PEPROCESS TargetProcess,
HANDLE SourceHandle,
PHANDLE TargetHandle,
ACCESS_MASK DesiredAccess,
- BOOLEAN InheritHandle,
+ ULONG HandleAttributes,
ULONG Options);
ULONG
@@ -155,5 +155,4 @@
VOID
ObpDereferenceCachedSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor);
-
#endif /* __INCLUDE_INTERNAL_OBJMGR_H */
Index: ntoskrnl/ob/handle.c
===================================================================
RCS file: /CVS/ReactOS/reactos/ntoskrnl/ob/handle.c,v
retrieving revision 1.57
diff -u -r1.57 handle.c
--- ntoskrnl/ob/handle.c 16 Jul 2004 19:54:05 -0000 1.57
+++ ntoskrnl/ob/handle.c 23 Jul 2004 13:15:58 -0000
@@ -48,20 +48,20 @@
{
PVOID ObjectBody;
ACCESS_MASK GrantedAccess;
+ OBJECT_ATTRIBUTES Attributes;
} HANDLE_REP, *PHANDLE_REP;
#define HANDLE_BLOCK_ENTRIES ((PAGE_SIZE-sizeof(LIST_ENTRY))/sizeof(HANDLE_REP))
-#define OB_HANDLE_FLAG_MASK 0x00000007
#define OB_HANDLE_FLAG_AUDIT 0x00000004
#define OB_HANDLE_FLAG_PROTECT 0x00000002
#define OB_HANDLE_FLAG_INHERIT 0x00000001
-#define OB_POINTER_TO_ENTRY(Pointer) \
- (PVOID)((ULONG_PTR)(Pointer) & ~OB_HANDLE_FLAG_MASK)
+#define ObpLockProcessHandles(Process, OldIrql) \
+ KeAcquireSpinLock(&(Process)->HandleTable.ListLock, &(OldIrql))
-#define OB_ENTRY_TO_POINTER(Entry) \
- (PVOID)((ULONG_PTR)(Entry) & ~OB_HANDLE_FLAG_MASK)
+#define ObpUnlockProcessHandles(Process, OldIrql) \
+ KeReleaseSpinLock(&(Process)->HandleTable.ListLock, (OldIrql))
/*
* PURPOSE: Defines a page's worth of handles
@@ -79,46 +79,40 @@
/* FUNCTIONS ***************************************************************/
-
-static PHANDLE_REP ObpGetObjectByHandle(PHANDLE_TABLE HandleTable, HANDLE h)
-/*
- * FUNCTION: Get the data structure for a handle
- * ARGUMENTS:
- * Process = Process to get the handle for
- * h = Handle
- * ARGUMENTS: A pointer to the information about the handle on success,
- * NULL on failure
- */
+PHANDLE_REP FASTCALL
+ObpGetObjectByHandle(PHANDLE_TABLE HandleTable,
+ HANDLE Handle)
{
- PLIST_ENTRY current;
- unsigned int handle = (((unsigned int)h) >> 2) - 1;
- unsigned int count=handle/HANDLE_BLOCK_ENTRIES;
- HANDLE_BLOCK* blk = NULL;
- unsigned int i;
-
- DPRINT("ObpGetObjectByHandle(HandleTable %x, h %x)\n",HandleTable,h);
-
- current = HandleTable->ListHead.Flink;
- DPRINT("current %x\n",current);
-
- for (i=0;i<count;i++)
- {
- current = current->Flink;
- if (current == (&(HandleTable->ListHead)))
- {
- return(NULL);
- }
- }
-
- blk = CONTAINING_RECORD(current,HANDLE_BLOCK,entry);
- DPRINT("object: %p\n",&(blk->handles[handle%HANDLE_BLOCK_ENTRIES]));
- return(&(blk->handles[handle%HANDLE_BLOCK_ENTRIES]));
-}
+ PLIST_ENTRY Current;
+ ULONG i, h;
+ HANDLE_BLOCK *HandleBlock;
+
+ DPRINT("ObpGetObjectByHandle(HandleTable 0x%x, h 0x%x)\n", HandleTable, Handle);
+
+ Current = HandleTable->ListHead.Flink;
+ h = ((ULONG)Handle >> 2) - 1;
+ i = h / HANDLE_BLOCK_ENTRIES;
+
+ while(i-- > 0)
+ {
+ Current = Current->Flink;
+ if(Current == &HandleTable->ListHead)
+ {
+ return NULL;
+ }
+ }
+
+ HandleBlock = CONTAINING_RECORD(Current, HANDLE_BLOCK, entry);
-NTSTATUS
+ DPRINT("object: 0x%x\n", &(HandleBlock->handles[h % HANDLE_BLOCK_ENTRIES]));
+
+ return &(HandleBlock->handles[h % HANDLE_BLOCK_ENTRIES]);
+}
+
+NTSTATUS FASTCALL
ObpQueryHandleAttributes(HANDLE Handle,
- POBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo)
+ POBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo)
{
PEPROCESS Process;
KIRQL oldIrql;
@@ -128,29 +122,27 @@
Process = PsGetCurrentProcess();
- KeAcquireSpinLock(&Process->HandleTable.ListLock, &oldIrql);
+ ObpLockProcessHandles(Process, oldIrql);
HandleRep = ObpGetObjectByHandle(&Process->HandleTable,
- Handle);
+ Handle);
if (HandleRep == NULL)
- {
- KeReleaseSpinLock(&Process->HandleTable.ListLock, oldIrql);
- return STATUS_INVALID_HANDLE;
- }
+ {
+ ObpUnlockProcessHandles(Process, oldIrql);
+ return STATUS_INVALID_HANDLE;
+ }
- HandleInfo->Inherit =
- ((ULONG_PTR)HandleRep->ObjectBody & OB_HANDLE_FLAG_INHERIT);
- HandleInfo->ProtectFromClose =
- ((ULONG_PTR)HandleRep->ObjectBody & OB_HANDLE_FLAG_PROTECT);
+ HandleInfo->Inherit = ((HandleRep->Attributes.Attributes & OB_HANDLE_FLAG_INHERIT) != 0);
+ HandleInfo->ProtectFromClose = ((HandleRep->Attributes.Attributes & OB_HANDLE_FLAG_PROTECT) != 0);
- KeReleaseSpinLock(&Process->HandleTable.ListLock, oldIrql);
+ ObpUnlockProcessHandles(Process, oldIrql);
return STATUS_SUCCESS;
}
-NTSTATUS
+NTSTATUS FASTCALL
ObpSetHandleAttributes(HANDLE Handle,
- POBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo)
+ POBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo)
{
PEPROCESS Process;
KIRQL oldIrql;
@@ -160,92 +152,117 @@
Process = PsGetCurrentProcess();
- KeAcquireSpinLock(&Process->HandleTable.ListLock, &oldIrql);
+ ObpLockProcessHandles(Process, oldIrql);
HandleRep = ObpGetObjectByHandle(&Process->HandleTable,
- Handle);
+ Handle);
if (HandleRep == NULL)
- {
- KeReleaseSpinLock(&Process->HandleTable.ListLock, oldIrql);
- return STATUS_INVALID_HANDLE;
- }
+ {
+ ObpUnlockProcessHandles(Process, oldIrql);
+ return STATUS_INVALID_HANDLE;
+ }
if (HandleInfo->Inherit)
- HandleRep->ObjectBody = (PVOID)((ULONG_PTR)HandleRep->ObjectBody | OB_HANDLE_FLAG_INHERIT);
+ HandleRep->Attributes.Attributes |= OB_HANDLE_FLAG_INHERIT;
else
- HandleRep->ObjectBody = (PVOID)((ULONG_PTR)HandleRep->ObjectBody & ~OB_HANDLE_FLAG_INHERIT);
+ HandleRep->Attributes.Attributes &= ~OB_HANDLE_FLAG_INHERIT;
- if (HandleInfo->ProtectFromClose)
- HandleRep->ObjectBody = (PVOID)((ULONG_PTR)HandleRep->ObjectBody | OB_HANDLE_FLAG_PROTECT);
+ if (HandleInfo->Inherit)
+ HandleRep->Attributes.Attributes |= OB_HANDLE_FLAG_PROTECT;
else
- HandleRep->ObjectBody = (PVOID)((ULONG_PTR)HandleRep->ObjectBody & ~OB_HANDLE_FLAG_PROTECT);
-
+ HandleRep->Attributes.Attributes &= ~OB_HANDLE_FLAG_PROTECT;
+
/* FIXME: Do we need to set anything in the object header??? */
- KeReleaseSpinLock(&Process->HandleTable.ListLock, oldIrql);
+ ObpUnlockProcessHandles(Process, oldIrql);
return STATUS_SUCCESS;
}
-NTSTATUS
+NTSTATUS FASTCALL
ObDuplicateObject(PEPROCESS SourceProcess,
- PEPROCESS TargetProcess,
- HANDLE SourceHandle,
- PHANDLE TargetHandle,
- ACCESS_MASK DesiredAccess,
- BOOLEAN InheritHandle,
- ULONG Options)
+ PEPROCESS TargetProcess,
+ HANDLE SourceHandle,
+ PHANDLE TargetHandle,
+ ACCESS_MASK DesiredAccess,
+ ULONG HandleAttributes,
+ ULONG Options)
{
KIRQL oldIrql;
PHANDLE_REP SourceHandleRep;
PVOID ObjectBody;
+ KPROCESSOR_MODE PreviousMode;
+ NTSTATUS Status;
- KeAcquireSpinLock(&SourceProcess->HandleTable.ListLock, &oldIrql);
+ PreviousMode = ExGetPreviousMode();
+
+ #if 0
+ if(PreviousMode != KernelMode)
+ {
+ /* FIXME - probe TargetHandle buffer */
+ }
+ #endif
+
+ ObpLockProcessHandles(SourceProcess, oldIrql);
SourceHandleRep = ObpGetObjectByHandle(&SourceProcess->HandleTable,
- SourceHandle);
+ SourceHandle);
if (SourceHandleRep == NULL)
- {
- KeReleaseSpinLock(&SourceProcess->HandleTable.ListLock, oldIrql);
- return(STATUS_INVALID_HANDLE);
- }
- ObjectBody = OB_ENTRY_TO_POINTER(SourceHandleRep->ObjectBody);
- ObReferenceObjectByPointer(ObjectBody,
- 0,
- NULL,
- UserMode);
+ {
+ ObpUnlockProcessHandles(SourceProcess, oldIrql);
+ return STATUS_INVALID_HANDLE;
+ }
+
+ ObjectBody = SourceHandleRep->ObjectBody;
+ Status = ObReferenceObjectByPointer(ObjectBody,
+ (PreviousMode == KernelMode ? 0 : DesiredAccess),
+ NULL,
+ PreviousMode);
+ if(!NT_SUCCESS(Status))
+ {
+ DPRINT("Failed to duplicated object due to missing access rights!\n");
+ return Status;
+ }
if (Options & DUPLICATE_SAME_ACCESS)
- {
- DesiredAccess = SourceHandleRep->GrantedAccess;
- }
+ {
+ DesiredAccess = SourceHandleRep->GrantedAccess;
+ }
- KeReleaseSpinLock(&SourceProcess->HandleTable.ListLock, oldIrql);
- ObCreateHandle(TargetProcess,
- ObjectBody,
- DesiredAccess,
- InheritHandle,
- TargetHandle);
+ ObpUnlockProcessHandles(SourceProcess, oldIrql);
+
+ Status = ObCreateHandle(TargetProcess,
+ ObjectBody,
+ DesiredAccess,
+ HandleAttributes,
+ TargetHandle);
+ if(!NT_SUCCESS(Status))
+ {
+ ObDereferenceObject(ObjectBody);
+
+ DPRINT("Failed to duplicate object, couldn't create new handle!\n");
+ return Status;
+ }
if (Options & DUPLICATE_CLOSE_SOURCE)
- {
- ZwClose(SourceHandle);
- }
+ {
+ ZwClose(SourceHandle);
+ }
ObDereferenceObject(ObjectBody);
- return(STATUS_SUCCESS);
+ return STATUS_SUCCESS;
}
/*
* @implemented
*/
NTSTATUS STDCALL
-NtDuplicateObject (IN HANDLE SourceProcessHandle,
- IN HANDLE SourceHandle,
- IN HANDLE TargetProcessHandle,
- OUT PHANDLE UnsafeTargetHandle,
- IN ACCESS_MASK DesiredAccess,
- IN BOOLEAN InheritHandle,
- ULONG Options)
+NtDuplicateObject(IN HANDLE SourceProcessHandle,
+ IN HANDLE SourceHandle,
+ IN HANDLE TargetProcessHandle,
+ OUT PHANDLE UnsafeTargetHandle,
+ IN ACCESS_MASK DesiredAccess,
+ IN ULONG HandleAttributes,
+ IN ULONG Options)
/*
* FUNCTION: Copies a handle from one process space to another
* ARGUMENTS:
@@ -258,8 +275,7 @@
* TargetHandle (OUT) = Caller should supply storage for the
* duplicated handle.
* DesiredAccess = The desired access to the handle.
- * InheritHandle = Indicates wheter the new handle will be inheritable
- * or not.
+ * HandleAttributes = Specifies the handle attributes for the new handle.
* Options = Specifies special actions upon duplicating the handle.
* Can be one of the values DUPLICATE_CLOSE_SOURCE |
* DUPLICATE_SAME_ACCESS. DUPLICATE_CLOSE_SOURCE specifies
@@ -271,39 +287,142 @@
* REMARKS: This function maps to the win32 DuplicateHandle.
*/
{
- PEPROCESS SourceProcess;
- PEPROCESS TargetProcess;
- PHANDLE_REP SourceHandleRep;
- KIRQL oldIrql;
- PVOID ObjectBody;
- HANDLE TargetHandle;
- NTSTATUS Status;
-
- ASSERT_IRQL(PASSIVE_LEVEL);
-
- Status = ObReferenceObjectByHandle(SourceProcessHandle,
- PROCESS_DUP_HANDLE,
- NULL,
- UserMode,
- (PVOID*)&SourceProcess,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- return(Status);
- }
- Status = ObReferenceObjectByHandle(TargetProcessHandle,
- PROCESS_DUP_HANDLE,
- NULL,
- UserMode,
- (PVOID*)&TargetProcess,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- ObDereferenceObject(SourceProcess);
- return(Status);
- }
+ PEPROCESS SourceProcess;
+ PEPROCESS TargetProcess;
+ KPROCESSOR_MODE PreviousMode;
+ PVOID ObjectBody;
+ HANDLE TargetHandle;
+ OBJECT_HANDLE_INFORMATION HandleInformation;
+ BOOL IsSourceProcess;
+ NTSTATUS Status;
+
+ ASSERT_IRQL(PASSIVE_LEVEL);
+
+ PreviousMode = ExGetPreviousMode();
+
+ Status = ObReferenceObjectByHandle(SourceProcessHandle,
+ PROCESS_DUP_HANDLE,
+ PsProcessType,
+ PreviousMode,
+ (PVOID*)&SourceProcess,
+ NULL);
+ if(!NT_SUCCESS(Status))
+ {
+ DPRINT("Failed to reference source process handle\n");
+ return Status;
+ }
- /* Check for magic handle first */
+ IsSourceProcess = (PsGetCurrentProcess() == SourceProcess);
+
+ if(!IsSourceProcess)
+ {
+ KeAttachProcess(SourceProcess);
+ }
+
+ Status = ObReferenceObjectByHandle(SourceHandle,
+ 0,
+ NULL,
+ PreviousMode,
+ &ObjectBody,
+ &HandleInformation);
+ if(!IsSourceProcess)
+ {
+ KeDetachProcess();
+ }
+
+ if(!NT_SUCCESS(Status))
+ {
+ DPRINT("Failed to reference the source handle!\n");
+
+ ObDereferenceObject(SourceProcess);
+ return Status;
+ }
+
+ if(TargetProcessHandle == NULL)
+ {
+ DPRINT("No target process handle specified, unable to duplicated the object\n");
+
+ /* All we can do is close the handle, the caller didn't specify a target process
+ for this object so we can't copy it! */
+
+ if(Options & DUPLICATE_CLOSE_SOURCE)
+ {
+ /* we need to switch into the source process context in order to correctly
+ close the handle! */
+ if(!IsSourceProcess)
+ {
+ KeAttachProcess(SourceProcess);
+ }
+
+ ZwClose(SourceHandle);
+
+ if(!IsSourceProcess)
+ {
+ KeDetachProcess();
+ }
+ }
+
+ ObDereferenceObject(SourceHandle);
+ ObDereferenceObject(SourceProcess);
+
+ return STATUS_SUCCESS;
+ }
+
+ /*
+ * We can actually duplicate the handle, a target process is specified
+ */
+
+ Status = ObReferenceObjectByHandle(TargetProcessHandle,
+ PROCESS_DUP_HANDLE,
+ PsProcessType,
+ PreviousMode,
+ (PVOID*)&TargetProcess,
+ NULL);
+ if(!NT_SUCCESS(Status))
+ {
+ DPRINT("Failed to reference target process handle\n");
+
+ /* We couldn't reference the target process, now let's just close the source
+ handle if required! */
+
+ if(Options & DUPLICATE_CLOSE_SOURCE)
+ {
+ /* we need to switch into the source process context in order to correctly
+ close the handle! */
+ if(!IsSourceProcess)
+ {
+ KeAttachProcess(SourceProcess);
+ }
+
+ ZwClose(SourceHandle);
+
+ if(!IsSourceProcess)
+ {
+ KeDetachProcess();
+ }
+ }
+
+ ObDereferenceObject(SourceHandle);
+ ObDereferenceObject(SourceProcess);
+ return Status;
+ }
+
+ /* FIXME - Don't we have to check if the target process is about to terminate?!
+ We don't want to create a handle in a process that is terminated already. */
+
+ if(Options & DUPLICATE_SAME_ACCESS)
+ {
+ DesiredAccess = HandleInformation.GrantedAccess;
+ }
+
+ HandleAttributes = ((Options & DUPLICATE_SAME_ATTRIBUTES) ?
+ HandleInformation.HandleAttributes : /* copy the same attributes */
+ HandleAttributes | HandleInformation.HandleAttributes); /* copy at least the same attributes */
+
+
+
+ #if 0
+ /* Check for magic handle first */
if (SourceHandle == NtCurrentThread())
{
ObReferenceObjectByHandle(SourceHandle,
@@ -365,7 +484,7 @@
ObDereferenceObject(TargetProcess);
ObDereferenceObject(SourceProcess);
ObDereferenceObject(ObjectBody);
-
+ #endif
Status = MmCopyToCaller(UnsafeTargetHandle, &TargetHandle, sizeof(HANDLE));
if (!NT_SUCCESS(Status))
{
@@ -398,7 +517,7 @@
for (i = 0; i < HANDLE_BLOCK_ENTRIES; i++)
{
- ObjectBody = OB_ENTRY_TO_POINTER(current->handles[i].ObjectBody);
+ ObjectBody = current->handles[i].ObjectBody;
if (ObjectBody != NULL)
{
@@ -522,7 +641,7 @@
current_block->handles[i].ObjectBody;
new_block->handles[i].GrantedAccess =
current_block->handles[i].GrantedAccess;
- InterlockedIncrement(&(BODY_TO_HEADER(OB_ENTRY_TO_POINTER(current_block->handles[i].ObjectBody))->HandleCount));
+ InterlockedIncrement(&(BODY_TO_HEADER(current_block->handles[i].ObjectBody)->HandleCount));
}
}
}
@@ -567,7 +686,7 @@
return STATUS_HANDLE_NOT_CLOSABLE;
}
- Body = OB_ENTRY_TO_POINTER(Rep->ObjectBody);
+ Body = Rep->ObjectBody;
DPRINT("ObjectBody %x\n", Body);
if (Body == NULL)
{
@@ -603,7 +722,7 @@
NTSTATUS ObCreateHandle(PEPROCESS Process,
PVOID ObjectBody,
ACCESS_MASK GrantedAccess,
- BOOLEAN Inherit,
+ ULONG HandleAttributes,
PHANDLE HandleReturn)
/*
* FUNCTION: Add a handle referencing an object
@@ -646,9 +765,8 @@
DPRINT("Considering slot %d containing %x\n",i,blk->handles[i]);
if (blk->handles[i].ObjectBody == NULL)
{
- blk->handles[i].ObjectBody = OB_POINTER_TO_ENTRY(ObjectBody);
- if (Inherit)
- blk->handles[i].ObjectBody = (PVOID)((ULONG_PTR)blk->handles[i].ObjectBody | OB_HANDLE_FLAG_INHERIT);
+ blk->handles[i].ObjectBody = ObjectBody;
+ blk->handles[i].Attributes.Attributes = HandleAttributes;
blk->handles[i].GrantedAccess = GrantedAccess;
KeReleaseSpinLock(&HandleTable->ListLock, oldlvl);
*HandleReturn = (HANDLE)((handle + i) << 2);
@@ -674,9 +792,8 @@
RtlZeroMemory(new_blk,sizeof(HANDLE_BLOCK));
InsertTailList(&(Process->HandleTable.ListHead),
&new_blk->entry);
- new_blk->handles[0].ObjectBody = OB_POINTER_TO_ENTRY(ObjectBody);
- if (Inherit)
- new_blk->handles[0].ObjectBody = (PVOID)((ULONG_PTR)new_blk->handles[0].ObjectBody | OB_HANDLE_FLAG_INHERIT);
+ new_blk->handles[0].ObjectBody = ObjectBody;
+ new_blk->handles[i].Attributes.Attributes = HandleAttributes;
new_blk->handles[0].GrantedAccess = GrantedAccess;
KeReleaseSpinLock(&HandleTable->ListLock, oldlvl);
*HandleReturn = (HANDLE)(handle << 2);
@@ -824,7 +941,7 @@
oldIrql);
return(STATUS_INVALID_HANDLE);
}
- ObjectBody = OB_ENTRY_TO_POINTER(HandleRep->ObjectBody);
+ ObjectBody = HandleRep->ObjectBody;
DPRINT("ObjectBody %p\n",ObjectBody);
ObjectHeader = BODY_TO_HEADER(ObjectBody);
DPRINT("ObjectHeader->RefCount %lu\n",ObjectHeader->RefCount);
@@ -832,7 +949,7 @@
0,
NULL,
UserMode);
- Attributes = (ULONG_PTR)HandleRep->ObjectBody & OB_HANDLE_FLAG_MASK;
+ Attributes = HandleRep->Attributes.Attributes;
GrantedAccess = HandleRep->GrantedAccess;
KeReleaseSpinLock(&PsGetCurrentProcess()->HandleTable.ListLock,
oldIrql);
@@ -970,7 +1087,7 @@
for (i = 0; i < HANDLE_BLOCK_ENTRIES; i++)
{
- ObjectBody = OB_ENTRY_TO_POINTER(blk->handles[i].ObjectBody);
+ ObjectBody = blk->handles[i].ObjectBody;
if (ObjectBody != NULL)
{
Header = BODY_TO_HEADER(ObjectBody);
More information about the Ros-kernel
mailing list