update for HEAD-2003091401
[reactos.git] / ntoskrnl / ob / handle.c
index 8d3b679..35afe76 100644 (file)
@@ -29,7 +29,8 @@
 
 /* INCLUDES ****************************************************************/
 
-#include <ddk/ntddk.h>
+#define NTOS_MODE_KERNEL
+#include <ntos.h>
 #include <internal/ob.h>
 #include <internal/ps.h>
 #include <internal/pool.h>
@@ -153,6 +154,9 @@ ObDuplicateObject(PEPROCESS SourceProcess,
   return(STATUS_SUCCESS);
 }
 
+/*
+ * @implemented
+ */
 NTSTATUS STDCALL 
 NtDuplicateObject (IN  HANDLE          SourceProcessHandle,
                   IN   HANDLE          SourceHandle,
@@ -217,40 +221,60 @@ NtDuplicateObject (IN     HANDLE          SourceProcessHandle,
        ObDereferenceObject(SourceProcess);
        return(Status);
      }
-   KeAcquireSpinLock(&SourceProcess->HandleTable.ListLock, &oldIrql);
-   SourceHandleRep = ObpGetObjectByHandle(&SourceProcess->HandleTable,
-                                         SourceHandle);
-   if (SourceHandleRep == NULL)
-     {
-       KeReleaseSpinLock(&SourceProcess->HandleTable.ListLock, oldIrql);
-       ObDereferenceObject(SourceProcess);
-       ObDereferenceObject(TargetProcess);
-       return(STATUS_INVALID_HANDLE);
-     }
-   ObjectBody = SourceHandleRep->ObjectBody;
-   ObReferenceObjectByPointer(ObjectBody,
-                             0,
-                             NULL,
-                             UserMode);
-   
-   if (Options & DUPLICATE_SAME_ACCESS)
+
+   /* Check for magic handle first */
+   if (SourceHandle == NtCurrentThread())
      {
-       DesiredAccess = SourceHandleRep->GrantedAccess;
+       ObReferenceObjectByHandle(SourceHandle,
+                                 PROCESS_DUP_HANDLE,
+                                 NULL,
+                                 UserMode,
+                                 &ObjectBody,
+                                 NULL);
+
+       ObCreateHandle(TargetProcess,
+                      ObjectBody,
+                      THREAD_ALL_ACCESS,
+                      InheritHandle,
+                      &TargetHandle);
      }
-   
-   KeReleaseSpinLock(&SourceProcess->HandleTable.ListLock, oldIrql);
-   if (!SourceHandleRep->Inherit)
+   else
      {
-       ObDereferenceObject(TargetProcess);
-       ObDereferenceObject(SourceProcess);
-       ObDereferenceObject(ObjectBody);
-       return STATUS_INVALID_HANDLE;
+       KeAcquireSpinLock(&SourceProcess->HandleTable.ListLock, &oldIrql);
+       SourceHandleRep = ObpGetObjectByHandle(&SourceProcess->HandleTable,
+                                             SourceHandle);
+       if (SourceHandleRep == NULL)
+        {
+          KeReleaseSpinLock(&SourceProcess->HandleTable.ListLock, oldIrql);
+          ObDereferenceObject(SourceProcess);
+          ObDereferenceObject(TargetProcess);
+          return(STATUS_INVALID_HANDLE);
+        }
+       ObjectBody = SourceHandleRep->ObjectBody;
+       ObReferenceObjectByPointer(ObjectBody,
+                                 0,
+                                 NULL,
+                                 UserMode);
+   
+       if (Options & DUPLICATE_SAME_ACCESS)
+        {
+          DesiredAccess = SourceHandleRep->GrantedAccess;
+        }
+   
+       KeReleaseSpinLock(&SourceProcess->HandleTable.ListLock, oldIrql);
+       if (!SourceHandleRep->Inherit)
+         {
+          ObDereferenceObject(TargetProcess);
+          ObDereferenceObject(SourceProcess);
+          ObDereferenceObject(ObjectBody);
+          return STATUS_INVALID_HANDLE;
+        }
+       ObCreateHandle(TargetProcess,
+                     ObjectBody,
+                     DesiredAccess,
+                     InheritHandle,
+                     &TargetHandle);
      }
-   ObCreateHandle(TargetProcess,
-                 ObjectBody,
-                 DesiredAccess,
-                 InheritHandle,
-                 &TargetHandle);
    
    if (Options & DUPLICATE_CLOSE_SOURCE)
      {
@@ -313,8 +337,6 @@ VOID ObCloseAllHandles(PEPROCESS Process)
                  current->handles[i].ObjectBody = NULL;
                  
                  KeReleaseSpinLock(&HandleTable->ListLock, oldIrql);
-                 KeDetachProcess();
-                 
                  if ((Header->ObjectType != NULL) &&
                      (Header->ObjectType->Close != NULL))
                    {
@@ -323,7 +345,6 @@ VOID ObCloseAllHandles(PEPROCESS Process)
                    }
                  
                  ObDereferenceObject(ObjectBody);
-                 KeAttachProcess(Process);
                  KeAcquireSpinLock(&HandleTable->ListLock, &oldIrql);
                  current_entry = &HandleTable->ListHead;
                  break;
@@ -460,11 +481,11 @@ PVOID ObDeleteHandle(PEPROCESS Process, HANDLE Handle)
    if (ObjectBody != NULL)
      {
        Header = BODY_TO_HEADER(ObjectBody);
-       InterlockedDecrement(&(BODY_TO_HEADER(ObjectBody)->HandleCount));
        ObReferenceObjectByPointer(ObjectBody,
                                   0,
                                   NULL,
                                   UserMode);
+       InterlockedDecrement(&(BODY_TO_HEADER(ObjectBody)->HandleCount));
        Rep->ObjectBody = NULL;
    
        KeReleaseSpinLock(&HandleTable->ListLock, oldIrql);
@@ -567,6 +588,9 @@ NTSTATUS ObCreateHandle(PEPROCESS Process,
 }
 
 
+/*
+ * @implemented
+ */
 NTSTATUS STDCALL
 ObReferenceObjectByHandle(HANDLE Handle,
                          ACCESS_MASK DesiredAccess,
@@ -593,6 +617,7 @@ ObReferenceObjectByHandle(HANDLE Handle,
    KIRQL oldIrql;
    PVOID ObjectBody;
    ACCESS_MASK GrantedAccess;
+   NTSTATUS Status;
    
    ASSERT_IRQL(PASSIVE_LEVEL);
    
@@ -609,13 +634,18 @@ ObReferenceObjectByHandle(HANDLE Handle,
      {
        DPRINT("Reference from %x\n", ((PULONG)&Handle)[-1]);
        
-       ObReferenceObjectByPointer(PsGetCurrentProcess(),
-                                  PROCESS_ALL_ACCESS,
-                                  PsProcessType,
-                                  UserMode);
+       Status = ObReferenceObjectByPointer(PsGetCurrentProcess(),
+                                           PROCESS_ALL_ACCESS,
+                                           PsProcessType,
+                                           UserMode);
+       if (! NT_SUCCESS(Status))
+         {
+           return Status;
+         }
+
        *Object = PsGetCurrentProcess();
        DPRINT("Referencing current process %x\n", PsGetCurrentProcess());
-       return(STATUS_SUCCESS);
+       return STATUS_SUCCESS;
      }
    else if (Handle == NtCurrentProcess())
      {
@@ -625,13 +655,18 @@ ObReferenceObjectByHandle(HANDLE Handle,
    if (Handle == NtCurrentThread() && 
        (ObjectType == PsThreadType || ObjectType == NULL))
      {
-       ObReferenceObjectByPointer(PsGetCurrentThread(),
-                                  THREAD_ALL_ACCESS,
-                                  PsThreadType,
-                                  UserMode);
+       Status = ObReferenceObjectByPointer(PsGetCurrentThread(),
+                                           THREAD_ALL_ACCESS,
+                                           PsThreadType,
+                                           UserMode);
+       if (! NT_SUCCESS(Status))
+         {
+           return Status;
+         }
+
        *Object = PsGetCurrentThread();
        CHECKPOINT;
-       return(STATUS_SUCCESS);
+       return STATUS_SUCCESS;
      }
    else if (Handle == NtCurrentThread())
      {
@@ -675,7 +710,7 @@ ObReferenceObjectByHandle(HANDLE Handle,
        DPRINT("Reference from %x\n", ((PULONG)&Handle)[-1]);
      }
    
-   if (AccessMode == UserMode)
+   if (DesiredAccess && AccessMode == UserMode)
      {
        RtlMapGenericMask(&DesiredAccess, ObjectHeader->ObjectType->Mapping);
 
@@ -707,6 +742,8 @@ ObReferenceObjectByHandle(HANDLE Handle,
  *             
  * RETURN VALUE
  *     Status.
+ *
+ * @implemented
  */
 NTSTATUS STDCALL NtClose(HANDLE Handle)
 {
@@ -720,6 +757,8 @@ NTSTATUS STDCALL NtClose(HANDLE Handle)
    ObjectBody = ObDeleteHandle(PsGetCurrentProcess(), Handle);
    if (ObjectBody == NULL)
      {
+        if(((PEPROCESS)(KeGetCurrentThread()->ApcState.Process))->ExceptionPort)
+           KeRaiseUserException(STATUS_INVALID_HANDLE);
        return(STATUS_INVALID_HANDLE);
      }
    
@@ -731,6 +770,9 @@ NTSTATUS STDCALL NtClose(HANDLE Handle)
    return(STATUS_SUCCESS);
 }
 
+/*
+ * @implemented
+ */
 NTSTATUS STDCALL
 ObInsertObject(PVOID Object,
               PACCESS_STATE PassedAccessState,