support kernel handles, creating them is however not yet supported
Modified: trunk/reactos/ntoskrnl/include/internal/ob.h
Modified: trunk/reactos/ntoskrnl/ob/handle.c
Modified: trunk/reactos/ntoskrnl/ps/process.c

Modified: trunk/reactos/ntoskrnl/include/internal/ob.h
--- trunk/reactos/ntoskrnl/include/internal/ob.h	2005-04-11 20:27:20 UTC (rev 14592)
+++ trunk/reactos/ntoskrnl/include/internal/ob.h	2005-04-11 21:50:15 UTC (rev 14593)
@@ -242,7 +242,15 @@
 
 extern PDIRECTORY_OBJECT NameSpaceRoot;
 extern POBJECT_TYPE ObSymbolicLinkType;
+extern PHANDLE_TABLE ObpKernelHandleTable;
 
+#define KERNEL_HANDLE_FLAG (1 << ((sizeof(HANDLE) * 8) - 1))
+#define ObIsKernelHandle(Handle, ProcessorMode)                                \
+  (((ULONG_PTR)(Handle) & KERNEL_HANDLE_FLAG) &&                               \
+   ((ProcessorMode) == KernelMode))
+#define ObKernelHandleToHandle(Handle)                                         \
+  (HANDLE)((ULONG_PTR)(Handle) & ~KERNEL_HANDLE_FLAG)
+
 VOID ObpAddEntryDirectory(PDIRECTORY_OBJECT Parent,
 			  POBJECT_HEADER Header,
 			  PWSTR Name);
@@ -267,10 +275,6 @@
 VOID ObDeleteHandleTable(struct _EPROCESS* Process);
 
 NTSTATUS
-ObDeleteHandle(PEPROCESS Process,
-	       HANDLE Handle);
-
-NTSTATUS
 ObpQueryHandleAttributes(HANDLE Handle,
 			 POBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo);
 

Modified: trunk/reactos/ntoskrnl/ob/handle.c
--- trunk/reactos/ntoskrnl/ob/handle.c	2005-04-11 20:27:20 UTC (rev 14592)
+++ trunk/reactos/ntoskrnl/ob/handle.c	2005-04-11 21:50:15 UTC (rev 14593)
@@ -42,6 +42,10 @@
 
 #define GENERIC_ANY (GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL)
 
+/* GLOBALS *****************************************************************/
+
+PHANDLE_TABLE ObpKernelHandleTable = NULL;
+
 /* FUNCTIONS ***************************************************************/
 
 VOID
@@ -51,7 +55,7 @@
     ObDeleteHandleTable(Process);
 }
 
-VOID
+static VOID
 ObpDecrementHandleCount(PVOID ObjectBody)
 {
   POBJECT_HEADER ObjectHeader = BODY_TO_HEADER(ObjectBody);
@@ -76,19 +80,28 @@
 ObpQueryHandleAttributes(HANDLE Handle,
 			 POBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo)
 {
-  PEPROCESS Process;
+  PHANDLE_TABLE HandleTable;
   PHANDLE_TABLE_ENTRY HandleTableEntry;
-  LONG ExHandle = HANDLE_TO_EX_HANDLE(Handle);
+  LONG ExHandle;
   
   PAGED_CODE();
 
   DPRINT("ObpQueryHandleAttributes(Handle %x)\n", Handle);
+  
+  if(ObIsKernelHandle(Handle, ExGetPreviousMode()))
+  {
+    HandleTable = ObpKernelHandleTable;
+    ExHandle = HANDLE_TO_EX_HANDLE(ObKernelHandleToHandle(Handle));
+  }
+  else
+  {
+    HandleTable = PsGetCurrentProcess()->ObjectTable;
+    ExHandle = HANDLE_TO_EX_HANDLE(Handle);
+  }
 
   KeEnterCriticalRegion();
 
-  Process = PsGetCurrentProcess();
-
-  HandleTableEntry = ExMapHandleToPointer(Process->ObjectTable,
+  HandleTableEntry = ExMapHandleToPointer(HandleTable,
                                           ExHandle);
   if (HandleTableEntry == NULL)
     {
@@ -99,7 +112,7 @@
   HandleInfo->Inherit = (HandleTableEntry->u1.ObAttributes & EX_HANDLE_ENTRY_INHERITABLE) != 0;
   HandleInfo->ProtectFromClose = (HandleTableEntry->u1.ObAttributes & EX_HANDLE_ENTRY_PROTECTFROMCLOSE) != 0;
 
-  ExUnlockHandleTableEntry(Process->ObjectTable,
+  ExUnlockHandleTableEntry(HandleTable,
                            HandleTableEntry);
 
   KeLeaveCriticalRegion();
@@ -112,19 +125,28 @@
 ObpSetHandleAttributes(HANDLE Handle,
 		       POBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo)
 {
-  PEPROCESS Process;
+  PHANDLE_TABLE HandleTable;
   PHANDLE_TABLE_ENTRY HandleTableEntry;
-  LONG ExHandle = HANDLE_TO_EX_HANDLE(Handle);
+  LONG ExHandle;
   
   PAGED_CODE();
 
   DPRINT("ObpSetHandleAttributes(Handle %x)\n", Handle);
 
-  Process = PsGetCurrentProcess();
+  if(ObIsKernelHandle(Handle, ExGetPreviousMode()))
+  {
+    HandleTable = ObpKernelHandleTable;
+    ExHandle = HANDLE_TO_EX_HANDLE(ObKernelHandleToHandle(Handle));
+  }
+  else
+  {
+    HandleTable = PsGetCurrentProcess()->ObjectTable;
+    ExHandle = HANDLE_TO_EX_HANDLE(Handle);
+  }
   
   KeEnterCriticalRegion();
 
-  HandleTableEntry = ExMapHandleToPointer(Process->ObjectTable,
+  HandleTableEntry = ExMapHandleToPointer(HandleTable,
                                           ExHandle);
   if (HandleTableEntry == NULL)
     {
@@ -144,7 +166,7 @@
 
   /* FIXME: Do we need to set anything in the object header??? */
 
-  ExUnlockHandleTableEntry(Process->ObjectTable,
+  ExUnlockHandleTableEntry(HandleTable,
                            HandleTableEntry);
 
   KeLeaveCriticalRegion();
@@ -153,6 +175,54 @@
 }
 
 
+static NTSTATUS
+ObpDeleteHandle(PHANDLE_TABLE HandleTable,
+	        HANDLE Handle)
+{
+   PHANDLE_TABLE_ENTRY HandleEntry;
+   PVOID Body;
+   POBJECT_HEADER ObjectHeader;
+   LONG ExHandle = HANDLE_TO_EX_HANDLE(Handle);
+
+   PAGED_CODE();
+
+   DPRINT("ObpDeleteHandle(Handle %x)\n",Handle);
+
+   KeEnterCriticalRegion();
+
+   HandleEntry = ExMapHandleToPointer(HandleTable,
+                                      ExHandle);
+   if(HandleEntry != NULL)
+   {
+     if(HandleEntry->u1.ObAttributes & EX_HANDLE_ENTRY_PROTECTFROMCLOSE)
+     {
+       ExUnlockHandleTableEntry(HandleTable,
+                                HandleEntry);
+
+       KeLeaveCriticalRegion();
+
+       return STATUS_HANDLE_NOT_CLOSABLE;
+     }
+
+     ObjectHeader = EX_HTE_TO_HDR(HandleEntry);
+     Body = HEADER_TO_BODY(ObjectHeader);
+
+     ObpDecrementHandleCount(Body);
+
+     /* destroy and unlock the handle entry */
+     ExDestroyHandleByEntry(HandleTable,
+                            HandleEntry,
+                            ExHandle);
+
+     KeLeaveCriticalRegion();
+
+     return STATUS_SUCCESS;
+   }
+   KeLeaveCriticalRegion();
+   return STATUS_INVALID_HANDLE;
+}
+
+
 NTSTATUS
 ObDuplicateObject(PEPROCESS SourceProcess,
 		  PEPROCESS TargetProcess,
@@ -162,19 +232,32 @@
 		  BOOLEAN InheritHandle,
 		  ULONG Options)
 {
+  PHANDLE_TABLE SourceHandleTable;
   PHANDLE_TABLE_ENTRY SourceHandleEntry;
   HANDLE_TABLE_ENTRY NewHandleEntry;
   PVOID ObjectBody;
   POBJECT_HEADER ObjectHeader;
   LONG ExTargetHandle;
-  LONG ExSourceHandle = HANDLE_TO_EX_HANDLE(SourceHandle);
+  LONG ExSourceHandle;
   ULONG NewHandleCount;
   
   PAGED_CODE();
   
+  if(ObIsKernelHandle(SourceHandle, ExGetPreviousMode()))
+  {
+    SourceHandleTable = ObpKernelHandleTable;
+    SourceHandle = ObKernelHandleToHandle(SourceHandle);
+  }
+  else
+  {
+    SourceHandleTable = SourceProcess->ObjectTable;
+  }
+  
+  ExSourceHandle = HANDLE_TO_EX_HANDLE(SourceHandle);
+  
   KeEnterCriticalRegion();
   
-  SourceHandleEntry = ExMapHandleToPointer(SourceProcess->ObjectTable,
+  SourceHandleEntry = ExMapHandleToPointer(SourceHandleTable,
                                            ExSourceHandle);
   if (SourceHandleEntry == NULL)
     {
@@ -219,7 +302,7 @@
   NewHandleCount = InterlockedIncrement(&ObjectHeader->HandleCount);
   ASSERT(NewHandleCount >= 2);
   
-  ExUnlockHandleTableEntry(SourceProcess->ObjectTable,
+  ExUnlockHandleTableEntry(SourceHandleTable,
                            SourceHandleEntry);
 
   KeLeaveCriticalRegion();
@@ -231,8 +314,8 @@
   {
     if (Options & DUPLICATE_CLOSE_SOURCE)
     {
-      ObDeleteHandle(SourceProcess,
-                     SourceHandle);
+      ObpDeleteHandle(SourceHandleTable,
+                      SourceHandle);
     }
     
     ObDereferenceObject(ObjectBody);
@@ -384,8 +467,8 @@
 
          if (Options & DUPLICATE_CLOSE_SOURCE)
          {
-           ObDeleteHandle(SourceProcess,
-                          SourceHandle);
+           ObpDeleteHandle(SourceProcess->ObjectTable,
+                           SourceHandle);
          }
        }
      }
@@ -464,10 +547,7 @@
     ObjectHeader = EX_HTE_TO_HDR(HandleTableEntry);
     if(InterlockedIncrement(&ObjectHeader->HandleCount) == 1)
     {
-      ObReferenceObjectByPointer(HEADER_TO_BODY(ObjectHeader),
-			         0,
-			         NULL,
-			         UserMode);
+      ObReferenceObject(HEADER_TO_BODY(ObjectHeader));
     }
   }
   
@@ -504,54 +584,6 @@
 
 
 NTSTATUS
-ObDeleteHandle(PEPROCESS Process,
-	       HANDLE Handle)
-{
-   PHANDLE_TABLE_ENTRY HandleEntry;
-   PVOID Body;
-   POBJECT_HEADER ObjectHeader;
-   LONG ExHandle = HANDLE_TO_EX_HANDLE(Handle);
-   
-   PAGED_CODE();
-
-   DPRINT("ObDeleteHandle(Handle %x)\n",Handle);
-   
-   KeEnterCriticalRegion();
-   
-   HandleEntry = ExMapHandleToPointer(Process->ObjectTable,
-                                      ExHandle);
-   if(HandleEntry != NULL)
-   {
-     if(HandleEntry->u1.ObAttributes & EX_HANDLE_ENTRY_PROTECTFROMCLOSE)
-     {
-       ExUnlockHandleTableEntry(Process->ObjectTable,
-                                HandleEntry);
-
-       KeLeaveCriticalRegion();
-
-       return STATUS_HANDLE_NOT_CLOSABLE;
-     }
-
-     ObjectHeader = EX_HTE_TO_HDR(HandleEntry);
-     Body = HEADER_TO_BODY(ObjectHeader);
-     
-     ObpDecrementHandleCount(Body);
-     
-     /* destroy and unlock the handle entry */
-     ExDestroyHandleByEntry(Process->ObjectTable,
-                            HandleEntry,
-                            ExHandle);
-     
-     KeLeaveCriticalRegion();
-     
-     return STATUS_SUCCESS;
-   }
-   KeLeaveCriticalRegion();
-   return STATUS_INVALID_HANDLE;
-}
-
-
-NTSTATUS
 ObCreateHandle(PEPROCESS Process,
 	       PVOID ObjectBody,
 	       ACCESS_MASK GrantedAccess,
@@ -685,11 +717,11 @@
 {
    PHANDLE_TABLE_ENTRY HandleEntry;
    POBJECT_HEADER ObjectHeader;
+   PHANDLE_TABLE HandleTable;
    PVOID ObjectBody;
    ACCESS_MASK GrantedAccess;
    ULONG Attributes;
-   NTSTATUS Status;
-   LONG ExHandle = HANDLE_TO_EX_HANDLE(Handle);
+   LONG ExHandle;
    
    PAGED_CODE();
    
@@ -703,14 +735,9 @@
    if (Handle == NtCurrentProcess() && 
        (ObjectType == PsProcessType || ObjectType == NULL))
      {
-	Status = ObReferenceObjectByPointer(PsGetCurrentProcess(),
-	                                    PROCESS_ALL_ACCESS,
-	                                    PsProcessType,
-	                                    UserMode);
-	if (! NT_SUCCESS(Status))
-	  {
-	    return Status;
-	  }
+        PEPROCESS CurrentProcess = PsGetCurrentProcess();
+        
+        ObReferenceObject(CurrentProcess);
 
 	if (HandleInformation != NULL)
 	  {
@@ -718,8 +745,8 @@
 	    HandleInformation->GrantedAccess = PROCESS_ALL_ACCESS;
 	  }
 
-	*Object = PsGetCurrentProcess();
-	DPRINT("Referencing current process %x\n", PsGetCurrentProcess());
+	*Object = CurrentProcess;
+	DPRINT("Referencing current process %x\n", CurrentProcess);
 	return STATUS_SUCCESS;
      }
    else if (Handle == NtCurrentProcess())
@@ -731,14 +758,9 @@
    if (Handle == NtCurrentThread() && 
        (ObjectType == PsThreadType || ObjectType == NULL))
      {
-	Status = ObReferenceObjectByPointer(PsGetCurrentThread(),
-	                                    THREAD_ALL_ACCESS,
-	                                    PsThreadType,
-	                                    UserMode);
-	if (! NT_SUCCESS(Status))
-	  {
-	    return Status;
-	  }
+        PETHREAD CurrentThread = PsGetCurrentThread();
+        
+        ObReferenceObject(CurrentThread);
 
 	if (HandleInformation != NULL)
 	  {
@@ -746,7 +768,7 @@
 	    HandleInformation->GrantedAccess = THREAD_ALL_ACCESS;
 	  }
 
-	*Object = PsGetCurrentThread();
+	*Object = CurrentThread;
 	CHECKPOINT;
 	return STATUS_SUCCESS;
      }
@@ -763,9 +785,20 @@
         DesiredAccess |= GENERIC_ALL;
      }
    
+   if(ObIsKernelHandle(Handle, AccessMode))
+   {
+      HandleTable = ObpKernelHandleTable;
+      ExHandle = HANDLE_TO_EX_HANDLE(ObKernelHandleToHandle(Handle));
+   }
+   else
+   {
+      HandleTable = PsGetCurrentProcess()->ObjectTable;
+      ExHandle = HANDLE_TO_EX_HANDLE(Handle);
+   }
+
    KeEnterCriticalRegion();
    
-   HandleEntry = ExMapHandleToPointer(PsGetCurrentProcess()->ObjectTable,
+   HandleEntry = ExMapHandleToPointer(HandleTable,
 				      ExHandle);
    if (HandleEntry == NULL)
      {
@@ -777,13 +810,13 @@
    ObjectHeader = EX_HTE_TO_HDR(HandleEntry);
    ObjectBody = HEADER_TO_BODY(ObjectHeader);
    
-   DPRINT("locked1: ObjectHeader: 0x%x [HT:0x%x]\n", ObjectHeader, PsGetCurrentProcess()->ObjectTable);
+   DPRINT("locked1: ObjectHeader: 0x%x [HT:0x%x]\n", ObjectHeader, HandleTable);
    
    if (ObjectType != NULL && ObjectType != ObjectHeader->ObjectType)
      {
         DPRINT("ObjectType mismatch: %wZ vs %wZ (handle 0x%x)\n", &ObjectType->TypeName, ObjectHeader->ObjectType ? &ObjectHeader->ObjectType->TypeName : NULL, Handle);
 
-        ExUnlockHandleTableEntry(PsGetCurrentProcess()->ObjectTable,
+        ExUnlockHandleTableEntry(HandleTable,
                                  HandleEntry);
 
         KeLeaveCriticalRegion();
@@ -804,7 +837,7 @@
       rights than the handle can grant */
    if(AccessMode != KernelMode && (~GrantedAccess & DesiredAccess))
      {
-        ExUnlockHandleTableEntry(PsGetCurrentProcess()->ObjectTable,
+        ExUnlockHandleTableEntry(HandleTable,
                                  HandleEntry);
 
         KeLeaveCriticalRegion();
@@ -814,15 +847,13 @@
         return(STATUS_ACCESS_DENIED);
      }
 
-   ObReferenceObjectByPointer(ObjectBody,
-			      0,
-			      NULL,
-			      UserMode);
+   ObReferenceObject(ObjectBody);
+   
    Attributes = HandleEntry->u1.ObAttributes & (EX_HANDLE_ENTRY_PROTECTFROMCLOSE |
                                                 EX_HANDLE_ENTRY_INHERITABLE |
                                                 EX_HANDLE_ENTRY_AUDITONCLOSE);
 
-   ExUnlockHandleTableEntry(PsGetCurrentProcess()->ObjectTable,
+   ExUnlockHandleTableEntry(HandleTable,
                             HandleEntry);
    
    KeLeaveCriticalRegion();
@@ -858,16 +889,30 @@
 NTSTATUS STDCALL
 NtClose(IN HANDLE Handle)
 {
+   PHANDLE_TABLE HandleTable;
    NTSTATUS Status;
    
    PAGED_CODE();
    
-   Status = ObDeleteHandle(PsGetCurrentProcess(),
-			   Handle);
+   if(ObIsKernelHandle(Handle, ExGetPreviousMode()))
+   {
+      HandleTable = ObpKernelHandleTable;
+      Handle = ObKernelHandleToHandle(Handle);
+   }
+   else
+   {
+      HandleTable = PsGetCurrentProcess()->ObjectTable;
+   }
+   
+   Status = ObpDeleteHandle(HandleTable,
+			    Handle);
    if (!NT_SUCCESS(Status))
      {
-        if(((PEPROCESS)(KeGetCurrentThread()->ApcState.Process))->ExceptionPort)
+        if((ExGetPreviousMode() != KernelMode) &&
+           (PsGetCurrentProcess()->ExceptionPort))
+        {
            KeRaiseUserException(Status);
+        }
 	return Status;
      }
    

Modified: trunk/reactos/ntoskrnl/ps/process.c
--- trunk/reactos/ntoskrnl/ps/process.c	2005-04-11 20:27:20 UTC (rev 14592)
+++ trunk/reactos/ntoskrnl/ps/process.c	2005-04-11 21:50:15 UTC (rev 14593)
@@ -286,6 +286,7 @@
   PsInitClientIDManagment();
   
   ObCreateHandleTable(NULL, FALSE, PsInitialSystemProcess);
+  ObpKernelHandleTable = PsInitialSystemProcess->ObjectTable;
   
   Status = PsCreateCidHandle(PsInitialSystemProcess,
                              PsProcessType,