- support for kernel handles
- attach to owning process before accessing the handle table if necessary
Modified: trunk/reactos/ntoskrnl/cm/ntfunc.c
Modified: trunk/reactos/ntoskrnl/ex/init.c
Modified: trunk/reactos/ntoskrnl/include/internal/ob.h
Modified: trunk/reactos/ntoskrnl/ob/handle.c
Modified: trunk/reactos/ntoskrnl/ob/namespc.c
Modified: trunk/reactos/ntoskrnl/ob/object.c
Modified: trunk/reactos/ntoskrnl/ps/security.c
Modified: trunk/reactos/ntoskrnl/se/priv.c

Modified: trunk/reactos/ntoskrnl/cm/ntfunc.c
--- trunk/reactos/ntoskrnl/cm/ntfunc.c	2005-12-10 15:53:27 UTC (rev 20037)
+++ trunk/reactos/ntoskrnl/cm/ntfunc.c	2005-12-10 16:38:04 UTC (rev 20038)
@@ -247,7 +247,7 @@
   if (!NT_SUCCESS(Status))
     {
       DPRINT1("ObpCaptureObjectAttributes() failed (Status %lx)\n", Status);
-      goto Cleanup;
+      return Status;
     }
 
   PostCreateKeyInfo.CompleteName = &ObjectName;
@@ -255,7 +255,6 @@
   Status = CmiCallRegisteredCallbacks(RegNtPreCreateKey, &PreCreateKeyInfo);
   if (!NT_SUCCESS(Status))
     {
-      ObpReleaseCapturedAttributes(&ObjectCreateInfo);
       goto Cleanup;
     }
     
@@ -264,7 +263,6 @@
                         (PVOID*)&Object,
                         &RemainingPath,
                         CmiKeyType);
-  ObpReleaseCapturedAttributes(&ObjectCreateInfo);
   if (!NT_SUCCESS(Status))
     {
       PostCreateKeyInfo.Object = NULL;
@@ -291,11 +289,10 @@
 	  goto Cleanup;
 	}
 
-      Status = ObpCreateHandle(PsGetCurrentProcess(),
-			      Object,
-			      DesiredAccess,
-			      TRUE,
-			      &hKey);
+      Status = ObpCreateHandle(Object,
+			       DesiredAccess,
+			       ObjectCreateInfo.Attributes,
+			       &hKey);
 
       if (!NT_SUCCESS(Status))
         DPRINT1("ObpCreateHandle failed Status 0x%x\n", Status);
@@ -466,6 +463,7 @@
   _SEH_END;
 
 Cleanup:
+  ObpReleaseCapturedAttributes(&ObjectCreateInfo);
   if (Class != NULL)
   {
     ReleaseCapturedUnicodeString(&CapturedClass,
@@ -1332,7 +1330,6 @@
 	                (PVOID*)&Object,
                         &RemainingPath,
                         CmiKeyType);
-  ObpReleaseCapturedAttributes(&ObjectCreateInfo);
   if (!NT_SUCCESS(Status))
     {
       DPRINT("CmpFindObject() returned 0x%08lx\n", Status);
@@ -1363,17 +1360,17 @@
       goto openkey_cleanup;
     }
 
-  Status = ObpCreateHandle(PsGetCurrentProcess(),
-			  Object,
-			  DesiredAccess,
-			  TRUE,
-			  &hKey);
+  Status = ObpCreateHandle(Object,
+			   DesiredAccess,
+			   ObjectCreateInfo.Attributes,
+			   &hKey);
 
   if (!NT_SUCCESS(Status))
      hKey = NULL;
 
 openkey_cleanup:
 
+  ObpReleaseCapturedAttributes(&ObjectCreateInfo);
   PostOpenKeyInfo.Object = NT_SUCCESS(Status) ? (PVOID)Object : NULL;
   PostOpenKeyInfo.Status = Status;
   CmiCallRegisteredCallbacks (RegNtPostOpenKey, &PostOpenKeyInfo);

Modified: trunk/reactos/ntoskrnl/ex/init.c
--- trunk/reactos/ntoskrnl/ex/init.c	2005-12-10 15:53:27 UTC (rev 20037)
+++ trunk/reactos/ntoskrnl/ex/init.c	2005-12-10 16:38:04 UTC (rev 20038)
@@ -429,10 +429,9 @@
     RTL_USER_PROCESS_INFORMATION Info;
 
     /* Create a handle to the process */
-    Status = ObpCreateHandle(PsGetCurrentProcess(),
-                             PsInitialSystemProcess,
+    Status = ObpCreateHandle(PsInitialSystemProcess,
                              PROCESS_CREATE_PROCESS | PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION,
-                             FALSE,
+                             OBJ_KERNEL_HANDLE,
                              &SystemProcessHandle);
     if(!NT_SUCCESS(Status))
     {

Modified: trunk/reactos/ntoskrnl/include/internal/ob.h
--- trunk/reactos/ntoskrnl/include/internal/ob.h	2005-12-10 15:53:27 UTC (rev 20037)
+++ trunk/reactos/ntoskrnl/include/internal/ob.h	2005-12-10 16:38:04 UTC (rev 20038)
@@ -51,6 +51,8 @@
    ((ProcessorMode) == KernelMode))
 #define ObKernelHandleToHandle(Handle)                                         \
   (HANDLE)((ULONG_PTR)(Handle) & ~KERNEL_HANDLE_FLAG)
+#define ObMarkHandleAsKernelHandle(Handle)                                     \
+  (HANDLE)((ULONG_PTR)(Handle) | KERNEL_HANDLE_FLAG)
 
 extern PDIRECTORY_OBJECT NameSpaceRoot;
 extern POBJECT_TYPE ObSymbolicLinkType;
@@ -75,10 +77,9 @@
 NTSTATUS
 NTAPI
 ObpCreateHandle(
-    struct _EPROCESS* Process,
     PVOID ObjectBody,
     ACCESS_MASK GrantedAccess,
-    BOOLEAN Inherit,
+    ULONG HandleAttributes,
     PHANDLE Handle
 );
 
@@ -134,7 +135,7 @@
     HANDLE SourceHandle,
     PHANDLE TargetHandle,
     ACCESS_MASK DesiredAccess,
-    BOOLEAN InheritHandle,
+    ULONG HandleAttributes,
     ULONG Options
 );
 

Modified: trunk/reactos/ntoskrnl/ob/handle.c
--- trunk/reactos/ntoskrnl/ob/handle.c	2005-12-10 15:53:27 UTC (rev 20037)
+++ trunk/reactos/ntoskrnl/ob/handle.c	2005-12-10 16:38:04 UTC (rev 20038)
@@ -89,42 +89,57 @@
 ObpQueryHandleAttributes(HANDLE Handle,
 			 POBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo)
 {
-  PHANDLE_TABLE HandleTable;
   PHANDLE_TABLE_ENTRY HandleTableEntry;
+  PEPROCESS Process, CurrentProcess;
+  KAPC_STATE ApcState;
+  BOOLEAN AttachedToProcess = FALSE;
+  NTSTATUS Status = STATUS_SUCCESS;
 
   PAGED_CODE();
 
-  DPRINT("ObpQueryHandleAttributes(Handle %x)\n", Handle);
+  DPRINT("ObpQueryHandleAttributes(Handle %p)\n", Handle);
+  CurrentProcess = PsGetCurrentProcess();
 
+  KeEnterCriticalRegion();
+
   if(ObIsKernelHandle(Handle, ExGetPreviousMode()))
   {
-    HandleTable = ObpKernelHandleTable;
+    Process = PsInitialSystemProcess;
     Handle = ObKernelHandleToHandle(Handle);
+
+    if (Process != CurrentProcess)
+    {
+      KeStackAttachProcess(&Process->Pcb,
+                           &ApcState);
+      AttachedToProcess = TRUE;
+    }
   }
   else
   {
-    HandleTable = PsGetCurrentProcess()->ObjectTable;
+    Process = CurrentProcess;
   }
 
-  KeEnterCriticalRegion();
-
-  HandleTableEntry = ExMapHandleToPointer(HandleTable,
+  HandleTableEntry = ExMapHandleToPointer(Process->ObjectTable,
                                           Handle);
-  if (HandleTableEntry == NULL)
-    {
-      KeLeaveCriticalRegion();
-      return STATUS_INVALID_HANDLE;
-    }
+  if (HandleTableEntry != NULL)
+  {
+    HandleInfo->Inherit = (HandleTableEntry->u1.ObAttributes & EX_HANDLE_ENTRY_INHERITABLE) != 0;
+    HandleInfo->ProtectFromClose = (HandleTableEntry->u1.ObAttributes & EX_HANDLE_ENTRY_PROTECTFROMCLOSE) != 0;
 
-  HandleInfo->Inherit = (HandleTableEntry->u1.ObAttributes & EX_HANDLE_ENTRY_INHERITABLE) != 0;
-  HandleInfo->ProtectFromClose = (HandleTableEntry->u1.ObAttributes & EX_HANDLE_ENTRY_PROTECTFROMCLOSE) != 0;
+    ExUnlockHandleTableEntry(Process->ObjectTable,
+                             HandleTableEntry);
+  }
+  else
+    Status = STATUS_INVALID_HANDLE;
 
-  ExUnlockHandleTableEntry(HandleTable,
-                           HandleTableEntry);
+  if (AttachedToProcess)
+  {
+    KeUnstackDetachProcess(&ApcState);
+  }
 
   KeLeaveCriticalRegion();
 
-  return STATUS_SUCCESS;
+  return Status;
 }
 
 
@@ -133,75 +148,92 @@
 ObpSetHandleAttributes(HANDLE Handle,
 		       POBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo)
 {
-  PHANDLE_TABLE HandleTable;
   PHANDLE_TABLE_ENTRY HandleTableEntry;
+  PEPROCESS Process, CurrentProcess;
+  KAPC_STATE ApcState;
+  BOOLEAN AttachedToProcess = FALSE;
+  NTSTATUS Status = STATUS_SUCCESS;
 
   PAGED_CODE();
 
-  DPRINT("ObpSetHandleAttributes(Handle %x)\n", Handle);
+  DPRINT("ObpSetHandleAttributes(Handle %p)\n", Handle);
+  CurrentProcess = PsGetCurrentProcess();
 
+  KeEnterCriticalRegion();
+
   if(ObIsKernelHandle(Handle, ExGetPreviousMode()))
   {
-    HandleTable = ObpKernelHandleTable;
+    Process = PsInitialSystemProcess;
     Handle = ObKernelHandleToHandle(Handle);
+
+    if (Process != CurrentProcess)
+    {
+      KeStackAttachProcess(&Process->Pcb,
+                           &ApcState);
+      AttachedToProcess = TRUE;
+    }
   }
   else
   {
-    HandleTable = PsGetCurrentProcess()->ObjectTable;
+    Process = CurrentProcess;
   }
 
-  KeEnterCriticalRegion();
-
-  HandleTableEntry = ExMapHandleToPointer(HandleTable,
+  HandleTableEntry = ExMapHandleToPointer(Process->ObjectTable,
                                           Handle);
-  if (HandleTableEntry == NULL)
-    {
-      KeLeaveCriticalRegion();
-      return STATUS_INVALID_HANDLE;
-    }
+  if (HandleTableEntry != NULL)
+  {
+    if (HandleInfo->Inherit)
+      HandleTableEntry->u1.ObAttributes |= EX_HANDLE_ENTRY_INHERITABLE;
+    else
+      HandleTableEntry->u1.ObAttributes &= ~EX_HANDLE_ENTRY_INHERITABLE;
 
-  if (HandleInfo->Inherit)
-    HandleTableEntry->u1.ObAttributes |= EX_HANDLE_ENTRY_INHERITABLE;
-  else
-    HandleTableEntry->u1.ObAttributes &= ~EX_HANDLE_ENTRY_INHERITABLE;
+    if (HandleInfo->ProtectFromClose)
+      HandleTableEntry->u1.ObAttributes |= EX_HANDLE_ENTRY_PROTECTFROMCLOSE;
+    else
+      HandleTableEntry->u1.ObAttributes &= ~EX_HANDLE_ENTRY_PROTECTFROMCLOSE;
 
-  if (HandleInfo->ProtectFromClose)
-    HandleTableEntry->u1.ObAttributes |= EX_HANDLE_ENTRY_PROTECTFROMCLOSE;
+    /* FIXME: Do we need to set anything in the object header??? */
+
+    ExUnlockHandleTableEntry(Process->ObjectTable,
+                             HandleTableEntry);
+  }
   else
-    HandleTableEntry->u1.ObAttributes &= ~EX_HANDLE_ENTRY_PROTECTFROMCLOSE;
+    Status = STATUS_INVALID_HANDLE;
 
-  /* FIXME: Do we need to set anything in the object header??? */
+  if (AttachedToProcess)
+  {
+    KeUnstackDetachProcess(&ApcState);
+  }
 
-  ExUnlockHandleTableEntry(HandleTable,
-                           HandleTableEntry);
-
   KeLeaveCriticalRegion();
 
-  return STATUS_SUCCESS;
+  return Status;
 }
 
 
 static NTSTATUS
-ObpDeleteHandle(PHANDLE_TABLE HandleTable,
-	        HANDLE Handle)
+ObpDeleteHandle(HANDLE Handle)
 {
    PHANDLE_TABLE_ENTRY HandleEntry;
    PVOID Body;
    POBJECT_HEADER ObjectHeader;
+   PHANDLE_TABLE ObjectTable;
 
    PAGED_CODE();
 
-   DPRINT("ObpDeleteHandle(Handle %x)\n",Handle);
+   DPRINT("ObpDeleteHandle(Handle %p)\n",Handle);
 
+   ObjectTable = PsGetCurrentProcess()->ObjectTable;
+
    KeEnterCriticalRegion();
 
-   HandleEntry = ExMapHandleToPointer(HandleTable,
+   HandleEntry = ExMapHandleToPointer(ObjectTable,
                                       Handle);
    if(HandleEntry != NULL)
    {
      if(HandleEntry->u1.ObAttributes & EX_HANDLE_ENTRY_PROTECTFROMCLOSE)
      {
-       ExUnlockHandleTableEntry(HandleTable,
+       ExUnlockHandleTableEntry(ObjectTable,
                                 HandleEntry);
 
        KeLeaveCriticalRegion();
@@ -212,13 +244,13 @@
      ObjectHeader = EX_HTE_TO_HDR(HandleEntry);
      Body = &ObjectHeader->Body;
 
-     ObpDecrementHandleCount(Body);
-
-     /* destroy and unlock the handle entry */
-     ExDestroyHandleByEntry(HandleTable,
+    /* destroy and unlock the handle entry */
+     ExDestroyHandleByEntry(ObjectTable,
                             HandleEntry,
                             Handle);
 
+     ObpDecrementHandleCount(Body);
+
      KeLeaveCriticalRegion();
 
      return STATUS_SUCCESS;
@@ -235,35 +267,48 @@
 		  HANDLE SourceHandle,
 		  PHANDLE TargetHandle,
 		  ACCESS_MASK DesiredAccess,
-		  BOOLEAN InheritHandle,
+		  ULONG HandleAttributes,
 		  ULONG Options)
 {
-  PHANDLE_TABLE SourceHandleTable;
   PHANDLE_TABLE_ENTRY SourceHandleEntry;
   HANDLE_TABLE_ENTRY NewHandleEntry;
+  BOOLEAN AttachedToProcess = FALSE;
   PVOID ObjectBody;
   POBJECT_HEADER ObjectHeader;
   ULONG NewHandleCount;
   HANDLE NewTargetHandle;
+  PEPROCESS CurrentProcess;
+  KAPC_STATE ApcState;
+  NTSTATUS Status = STATUS_SUCCESS;
 
   PAGED_CODE();
 
-  if(ObIsKernelHandle(SourceHandle, ExGetPreviousMode()))
+  if(SourceProcess == NULL ||
+     ObIsKernelHandle(SourceHandle, ExGetPreviousMode()))
   {
-    SourceHandleTable = ObpKernelHandleTable;
+    SourceProcess = PsInitialSystemProcess;
     SourceHandle = ObKernelHandleToHandle(SourceHandle);
   }
-  else
-  {
-    SourceHandleTable = SourceProcess->ObjectTable;
-  }
 
+  CurrentProcess = PsGetCurrentProcess();
+
   KeEnterCriticalRegion();
 
-  SourceHandleEntry = ExMapHandleToPointer(SourceHandleTable,
+  if (SourceProcess != CurrentProcess)
+  {
+    KeStackAttachProcess(&SourceProcess->Pcb,
+                         &ApcState);
+    AttachedToProcess = TRUE;
+  }
+  SourceHandleEntry = ExMapHandleToPointer(SourceProcess->ObjectTable,
                                            SourceHandle);
   if (SourceHandleEntry == NULL)
     {
+      if (AttachedToProcess)
+      {
+        KeUnstackDetachProcess(&ApcState);
+      }
+
       KeLeaveCriticalRegion();
       return STATUS_INVALID_HANDLE;
     }
@@ -272,7 +317,7 @@
   ObjectBody = &ObjectHeader->Body;
 
   NewHandleEntry.u1.Object = SourceHandleEntry->u1.Object;
-  if(InheritHandle)
+  if(HandleAttributes & OBJ_INHERIT)
     NewHandleEntry.u1.ObAttributes |= EX_HANDLE_ENTRY_INHERITABLE;
   else
     NewHandleEntry.u1.ObAttributes &= ~EX_HANDLE_ENTRY_INHERITABLE;
@@ -305,27 +350,54 @@
   NewHandleCount = InterlockedIncrement(&ObjectHeader->HandleCount);
   ASSERT(NewHandleCount >= 2);
 
-  ExUnlockHandleTableEntry(SourceHandleTable,
+  ExUnlockHandleTableEntry(SourceProcess->ObjectTable,
                            SourceHandleEntry);
 
-  KeLeaveCriticalRegion();
+  if (AttachedToProcess)
+  {
+    KeUnstackDetachProcess(&ApcState);
+    AttachedToProcess = FALSE;
+  }
 
+  if (TargetProcess != CurrentProcess)
+  {
+    KeStackAttachProcess(&TargetProcess->Pcb,
+                         &ApcState);
+    AttachedToProcess = TRUE;
+  }
+
   /* attempt to create the new handle */
   NewTargetHandle = ExCreateHandle(TargetProcess->ObjectTable,
                                    &NewHandleEntry);
+  if (AttachedToProcess)
+  {
+    KeUnstackDetachProcess(&ApcState);
+    AttachedToProcess = FALSE;
+  }
+
   if (NewTargetHandle != NULL)
   {
     if (Options & DUPLICATE_CLOSE_SOURCE)
     {
-      ObpDeleteHandle(SourceHandleTable,
-                      SourceHandle);
+      if (SourceProcess != CurrentProcess)
+      {
+        KeStackAttachProcess(&SourceProcess->Pcb,
+                             &ApcState);
+        AttachedToProcess = TRUE;
+      }
+
+      /* delete the source handle */
+      ObpDeleteHandle(SourceHandle);
+
+      if (AttachedToProcess)
+      {
+        KeUnstackDetachProcess(&ApcState);
+      }
     }
 
     ObDereferenceObject(ObjectBody);
 
     *TargetHandle = NewTargetHandle;
-
-    return STATUS_SUCCESS;
   }
   else
   {
@@ -337,8 +409,12 @@
     }
 
     ObDereferenceObject(ObjectBody);
-    return STATUS_UNSUCCESSFUL;
+    Status = STATUS_UNSUCCESSFUL;
   }
+
+  KeLeaveCriticalRegion();
+
+  return Status;
 }
 
 /*
@@ -350,7 +426,7 @@
 		   IN	HANDLE		TargetProcessHandle,
 		   OUT	PHANDLE		TargetHandle  OPTIONAL,
 		   IN	ACCESS_MASK	DesiredAccess,
-		   IN	ULONG		InheritHandle,
+		   IN	ULONG		HandleAttributes,
 		   IN   ULONG		Options)
 /*
  * FUNCTION: Copies a handle from one process space to another
@@ -364,8 +440,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 = The desired handle attributes.
  *	   Options = Specifies special actions upon duplicating the handle.
  *                   Can be one of the values DUPLICATE_CLOSE_SOURCE |
  *                   DUPLICATE_SAME_ACCESS. DUPLICATE_CLOSE_SOURCE specifies
@@ -379,8 +454,11 @@
 {
    PEPROCESS SourceProcess;
    PEPROCESS TargetProcess;
+   PEPROCESS CurrentProcess;
    HANDLE hTarget;
+   BOOLEAN AttachedToProcess = FALSE;
    KPROCESSOR_MODE PreviousMode;
+   KAPC_STATE ApcState;
    NTSTATUS Status = STATUS_SUCCESS;
 
    PAGED_CODE();
@@ -428,6 +506,8 @@
        return(Status);
      }
 
+   CurrentProcess = PsGetCurrentProcess();
+
    /* Check for magic handle first */
    if (SourceHandle == NtCurrentThread() ||
        SourceHandle == NtCurrentProcess())
@@ -458,18 +538,42 @@
                                &ObjectType->TypeInfo.GenericMapping);
            }
          }
-         Status = ObpCreateHandle(TargetProcess,
-                                  ObjectBody,
+
+         if (TargetProcess != CurrentProcess)
+         {
+           KeStackAttachProcess(&TargetProcess->Pcb,
+                                &ApcState);
+           AttachedToProcess = TRUE;
+         }
+
+         Status = ObpCreateHandle(ObjectBody,
                                   DesiredAccess,
-                                  InheritHandle,
+                                  HandleAttributes,
                                   &hTarget);
 
+         if (AttachedToProcess)
+         {
+           KeUnstackDetachProcess(&ApcState);
+           AttachedToProcess = FALSE;
+         }
+
          ObDereferenceObject(ObjectBody);
 
          if (Options & DUPLICATE_CLOSE_SOURCE)
          {
-           ObpDeleteHandle(SourceProcess->ObjectTable,
-                           SourceHandle);
+           if (SourceProcess != CurrentProcess)
+           {
+             KeStackAttachProcess(&SourceProcess->Pcb,
+                                  &ApcState);
+             AttachedToProcess = TRUE;
+           }
+
+           ObpDeleteHandle(SourceHandle);
+
+           if (AttachedToProcess)
+           {
+             KeUnstackDetachProcess(&ApcState);
+           }
          }
        }
      }
@@ -480,7 +584,7 @@
                                   SourceHandle,
                                   &hTarget,
                                   DesiredAccess,
-                                  InheritHandle,
+                                  HandleAttributes,
                                   Options);
      }
 
@@ -591,11 +695,10 @@
 
 NTSTATUS
 NTAPI
-ObpCreateHandle(PEPROCESS Process,
-	       PVOID ObjectBody,
-	       ACCESS_MASK GrantedAccess,
-	       BOOLEAN Inherit,
-	       PHANDLE HandleReturn)
+ObpCreateHandle(PVOID ObjectBody,
+	        ACCESS_MASK GrantedAccess,
+	        ULONG HandleAttributes,
+	        PHANDLE HandleReturn)
 /*
  * FUNCTION: Add a handle referencing an object
  * ARGUMENTS:
@@ -605,18 +708,23 @@
  */
 {
    HANDLE_TABLE_ENTRY NewEntry;
+   PEPROCESS Process, CurrentProcess;
    POBJECT_HEADER ObjectHeader;
    HANDLE Handle;
+   KAPC_STATE ApcState;
+   BOOLEAN AttachedToProcess = FALSE;
 
    PAGED_CODE();
 
-   DPRINT("ObpCreateHandle(Process %x, obj %x)\n",Process,ObjectBody);
+   DPRINT("ObpCreateHandle(obj %p)\n",ObjectBody);
 
-   ASSERT(Process);
    ASSERT(ObjectBody);
 
+   CurrentProcess = PsGetCurrentProcess();
+
    ObjectHeader = BODY_TO_HEADER(ObjectBody);
 
+   /* check that this is a valid kernel pointer */
    ASSERT((ULONG_PTR)ObjectHeader & EX_HANDLE_ENTRY_LOCKED);
 
    if (GrantedAccess & MAXIMUM_ALLOWED)
@@ -632,23 +740,49 @@
      }
 
    NewEntry.u1.Object = ObjectHeader;
-   if(Inherit)
+   if(HandleAttributes & OBJ_INHERIT)
      NewEntry.u1.ObAttributes |= EX_HANDLE_ENTRY_INHERITABLE;
    else
      NewEntry.u1.ObAttributes &= ~EX_HANDLE_ENTRY_INHERITABLE;
    NewEntry.u2.GrantedAccess = GrantedAccess;
 
+   if ((HandleAttributes & OBJ_KERNEL_HANDLE) &&
+       ExGetPreviousMode == KernelMode)
+   {
+       Process = PsInitialSystemProcess;
+       if (Process != CurrentProcess)
+       {
+           KeStackAttachProcess(&Process->Pcb,
+                                &ApcState);
+           AttachedToProcess = TRUE;
+       }
+   }
+   else
+   {
+       Process = CurrentProcess;
+       /* mask out the OBJ_KERNEL_HANDLE attribute */
+       HandleAttributes &= ~OBJ_KERNEL_HANDLE;
+   }
+
    Handle = ExCreateHandle(Process->ObjectTable,
                            &NewEntry);
-   DPRINT("ObCreateHandle(0x%x)==0x%x [HT:0x%x]\n", ObjectHeader, Handle, Process->ObjectTable);
+
+   if (AttachedToProcess)
+   {
+       KeUnstackDetachProcess(&ApcState);
+   }
+
    if(Handle != NULL)
    {
+     if (HandleAttributes & OBJ_KERNEL_HANDLE)
+     {
+       /* mark the handle value */
+       Handle = ObMarkHandleAsKernelHandle(Handle);
+     }
+
      if(InterlockedIncrement(&ObjectHeader->HandleCount) == 1)
      {
-      ObReferenceObjectByPointer(ObjectBody,
-			         0,
-			         NULL,
-			         UserMode);
+       ObReferenceObject(ObjectBody);
      }
 
      *HandleReturn = Handle;
@@ -668,16 +802,34 @@
 			      OUT PBOOLEAN GenerateOnClose)
 {
   PHANDLE_TABLE_ENTRY HandleEntry;
-  PEPROCESS Process;
+  PEPROCESS Process, CurrentProcess;
+  KAPC_STATE ApcState;
+  BOOLEAN AttachedToProcess = FALSE;
+  NTSTATUS Status = STATUS_SUCCESS;
 
   PAGED_CODE();
 
-  DPRINT("ObQueryObjectAuditingByHandle(Handle %x)\n", Handle);
+  DPRINT("ObQueryObjectAuditingByHandle(Handle %p)\n", Handle);
 
-  Process = PsGetCurrentProcess();
+  CurrentProcess = PsGetCurrentProcess();
 
   KeEnterCriticalRegion();
 
+  if(ObIsKernelHandle(Handle, ExGetPreviousMode()))
+  {
+    Process = PsInitialSystemProcess;
+    Handle = ObKernelHandleToHandle(Handle);
+
+    if (Process != CurrentProcess)
+    {
+      KeStackAttachProcess(&Process->Pcb,
+                           &ApcState);
+      AttachedToProcess = TRUE;
+    }
+  }
+  else
+     Process = CurrentProcess;
+
   HandleEntry = ExMapHandleToPointer(Process->ObjectTable,
                                      Handle);
   if(HandleEntry != NULL)
@@ -686,15 +838,18 @@
 
     ExUnlockHandleTableEntry(Process->ObjectTable,
                              HandleEntry);
+  }
+  else
+    Status = STATUS_INVALID_HANDLE;
 
-    KeLeaveCriticalRegion();
-
-    return STATUS_SUCCESS;
+  if (AttachedToProcess)
+  {
+    KeUnstackDetachProcess(&ApcState);
   }
 
   KeLeaveCriticalRegion();
 
-  return STATUS_INVALID_HANDLE;
+  return Status;
 }
 
 
@@ -723,29 +878,32 @@
 {
    PHANDLE_TABLE_ENTRY HandleEntry;
    POBJECT_HEADER ObjectHeader;
-   PHANDLE_TABLE HandleTable;
    PVOID ObjectBody;
    ACCESS_MASK GrantedAccess;
    ULONG Attributes;
+   PEPROCESS CurrentProcess, Process;
+   BOOLEAN AttachedToProcess = FALSE;
+   KAPC_STATE ApcState;
 
    PAGED_CODE();
 
-   DPRINT("ObReferenceObjectByHandle(Handle %x, DesiredAccess %x, "
-	   "ObjectType %x, AccessMode %d, Object %x)\n",Handle,DesiredAccess,
+   DPRINT("ObReferenceObjectByHandle(Handle %p, DesiredAccess %x, "
+	   "ObjectType %p, AccessMode %d, Object %p)\n",Handle,DesiredAccess,
 	   ObjectType,AccessMode,Object);
 
    if (Handle == NULL)
      {
        return STATUS_INVALID_HANDLE;
      }
+
+   CurrentProcess = PsGetCurrentProcess();
+
    /*
     * Handle special handle names
     */
    if (Handle == NtCurrentProcess() &&
        (ObjectType == PsProcessType || ObjectType == NULL))
      {
-        PEPROCESS CurrentProcess = PsGetCurrentProcess();
-
         ObReferenceObject(CurrentProcess);
 
 	if (HandleInformation != NULL)
@@ -755,7 +913,7 @@
 	  }
 
 	*Object = CurrentProcess;
-	DPRINT("Referencing current process %x\n", CurrentProcess);
+	DPRINT("Referencing current process %p\n", CurrentProcess);
 	return STATUS_SUCCESS;
      }
    else if (Handle == NtCurrentProcess())
@@ -796,37 +954,53 @@
 
    if(ObIsKernelHandle(Handle, AccessMode))
    {
-      HandleTable = ObpKernelHandleTable;
+      Process = PsInitialSystemProcess;
       Handle = ObKernelHandleToHandle(Handle);
    }
    else
    {
-      HandleTable = PsGetCurrentProcess()->ObjectTable;
+      Process = CurrentProcess;
    }
 
    KeEnterCriticalRegion();
 
-   HandleEntry = ExMapHandleToPointer(HandleTable,
+   if (Process != CurrentProcess)
+   {
+     KeStackAttachProcess(&Process->Pcb,
+                          &ApcState);
+     AttachedToProcess = TRUE;
+   }
+
+   HandleEntry = ExMapHandleToPointer(Process->ObjectTable,
 				      Handle);
    if (HandleEntry == NULL)
      {
+        if (AttachedToProcess)
+        {
+            KeUnstackDetachProcess(&ApcState);
+        }
         KeLeaveCriticalRegion();
-        DPRINT("ExMapHandleToPointer() failed for handle 0x%x\n", Handle);
+        DPRINT("ExMapHandleToPointer() failed for handle 0x%p\n", Handle);
         return(STATUS_INVALID_HANDLE);
      }
 
    ObjectHeader = EX_HTE_TO_HDR(HandleEntry);
    ObjectBody = &ObjectHeader->Body;
 
-   DPRINT("locked1: ObjectHeader: 0x%x [HT:0x%x]\n", ObjectHeader, HandleTable);
+   DPRINT("locked1: ObjectHeader: 0x%p [HT:0x%p]\n", ObjectHeader, Process->ObjectTable);
 
    if (ObjectType != NULL && ObjectType != ObjectHeader->Type)
      {
-        DPRINT("ObjectType mismatch: %wZ vs %wZ (handle 0x%x)\n", &ObjectType->Name, ObjectHeader->Type ? &ObjectHeader->Type->Name : NULL, Handle);
+        DPRINT("ObjectType mismatch: %wZ vs %wZ (handle 0x%p)\n", &ObjectType->Name, ObjectHeader->Type ? &ObjectHeader->Type->Name : NULL, Handle);
 
-        ExUnlockHandleTableEntry(HandleTable,
+        ExUnlockHandleTableEntry(Process->ObjectTable,
                                  HandleEntry);
 
+        if (AttachedToProcess)
+        {
+            KeUnstackDetachProcess(&ApcState);
+        }
+
         KeLeaveCriticalRegion();
 
         return(STATUS_OBJECT_TYPE_MISMATCH);
@@ -845,9 +1019,14 @@
       rights than the handle can grant */
    if(AccessMode != KernelMode && (~GrantedAccess & DesiredAccess))
      {
-        ExUnlockHandleTableEntry(HandleTable,
+        ExUnlockHandleTableEntry(Process->ObjectTable,
                                  HandleEntry);
 
+        if (AttachedToProcess)
+        {
+            KeUnstackDetachProcess(&ApcState);
+        }
+
         KeLeaveCriticalRegion();
 
         DPRINT1("GrantedAccess: 0x%x, ~GrantedAccess: 0x%x, DesiredAccess: 0x%x, denied: 0x%x\n", GrantedAccess, ~GrantedAccess, DesiredAccess, ~GrantedAccess & DesiredAccess);
@@ -861,9 +1040,14 @@
                                                 EX_HANDLE_ENTRY_INHERITABLE |
                                                 EX_HANDLE_ENTRY_AUDITONCLOSE);
 
-   ExUnlockHandleTableEntry(HandleTable,
+   ExUnlockHandleTableEntry(Process->ObjectTable,
                             HandleEntry);
 
+   if (AttachedToProcess)
+   {
+       KeUnstackDetachProcess(&ApcState);
+   }
+
    KeLeaveCriticalRegion();
 
    if (HandleInformation != NULL)
@@ -897,27 +1081,43 @@
 NTSTATUS STDCALL
 NtClose(IN HANDLE Handle)
 {
-   PHANDLE_TABLE HandleTable;
+   PEPROCESS Process, CurrentProcess;
+   BOOLEAN AttachedToProcess = FALSE;
+   KAPC_STATE ApcState;
    NTSTATUS Status;
+   KPROCESSOR_MODE PreviousMode;
 
    PAGED_CODE();
 
-   if(ObIsKernelHandle(Handle, ExGetPreviousMode()))
+   PreviousMode = ExGetPreviousMode();
+   CurrentProcess = PsGetCurrentProcess();
+
+   if(ObIsKernelHandle(Handle, PreviousMode))
    {
-      HandleTable = ObpKernelHandleTable;
+      Process = PsInitialSystemProcess;
       Handle = ObKernelHandleToHandle(Handle);
+
+      if (Process != CurrentProcess)
+      {
+        KeStackAttachProcess(&Process->Pcb,
+                             &ApcState);
+        AttachedToProcess = TRUE;
+      }
    }
    else
+      Process = CurrentProcess;
+
+   Status = ObpDeleteHandle(Handle);
+
+   if (AttachedToProcess)
    {
-      HandleTable = PsGetCurrentProcess()->ObjectTable;
+     KeUnstackDetachProcess(&ApcState);
    }
 
-   Status = ObpDeleteHandle(HandleTable,
-			    Handle);
    if (!NT_SUCCESS(Status))
      {
-        if((ExGetPreviousMode() != KernelMode) &&
-           (PsGetCurrentProcess()->ExceptionPort))
+        if((PreviousMode != KernelMode) &&
+           (CurrentProcess->ExceptionPort))
         {
            KeRaiseUserException(Status);
         }
@@ -1128,10 +1328,9 @@
     DPRINT("Creating handle\n");
     if (Handle != NULL)
     {
-        Status = ObpCreateHandle(PsGetCurrentProcess(),
-                                 &Header->Body,
+        Status = ObpCreateHandle(&Header->Body,
                                  DesiredAccess,
-                                 ObjectCreateInfo->Attributes & OBJ_INHERIT,
+                                 ObjectCreateInfo->Attributes,
                                  Handle);
         DPRINT("handle Created: %d. refcount. handlecount %d %d\n",
                  *Handle, Header->PointerCount, Header->HandleCount);

Modified: trunk/reactos/ntoskrnl/ob/namespc.c
--- trunk/reactos/ntoskrnl/ob/namespc.c	2005-12-10 15:53:27 UTC (rev 20037)
+++ trunk/reactos/ntoskrnl/ob/namespc.c	2005-12-10 16:38:04 UTC (rev 20038)
@@ -183,19 +183,18 @@
 			 &Object,
 			 &RemainingPath,
 			 ObjectType);
-   ObpReleaseCapturedAttributes(&ObjectCreateInfo);
    if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
    if (!NT_SUCCESS(Status))
      {
 	DPRINT("ObFindObject() failed (Status %lx)\n", Status);
-	return Status;
+	goto Cleanup;
      }
 
-   DPRINT("OBject: %x, Remaining Path: %wZ\n", Object, &RemainingPath);
+   DPRINT("OBject: %p, Remaining Path: %wZ\n", Object, &RemainingPath);
    if (Object == NULL)
      {
-       RtlFreeUnicodeString(&RemainingPath);
-       return STATUS_UNSUCCESSFUL;
+       Status = STATUS_UNSUCCESSFUL;
+       goto Cleanup;
      }
    if (RemainingPath.Buffer != NULL)
    {
@@ -203,19 +202,21 @@
          Status = STATUS_OBJECT_NAME_NOT_FOUND;
       else
          Status =STATUS_OBJECT_PATH_NOT_FOUND;
-      RtlFreeUnicodeString(&RemainingPath);
-      ObDereferenceObject(Object);
-      return Status;
+      goto Cleanup;
    }
    
-   Status = ObpCreateHandle(PsGetCurrentProcess(),
-			   Object,
-			   DesiredAccess,
-			   FALSE,
-			   Handle);
[truncated at 1000 lines; 107 more skipped]