[STORPORT] Fix x64 build
[reactos.git] / ntoskrnl / ob / obhandle.c
index a2b2f9c..58e7ba3 100644 (file)
@@ -484,7 +484,22 @@ NTSTATUS
 NTAPI
 ObpValidateAccessMask(IN PACCESS_STATE AccessState)
 {
-    /* TODO */
+    PISECURITY_DESCRIPTOR SecurityDescriptor;
+
+    /* We're only interested if the object for this access state has an SD */
+    SecurityDescriptor = AccessState->SecurityDescriptor;
+    if (SecurityDescriptor)
+    {
+        /* Check if the SD has a system ACL but hasn't been granted access to get/set it */
+        if ((SecurityDescriptor->Control & SE_SACL_PRESENT) &&
+            !(AccessState->PreviouslyGrantedAccess & ACCESS_SYSTEM_SECURITY))
+        {
+            /* We're gonna need access */
+            AccessState->RemainingDesiredAccess |= ACCESS_SYSTEM_SECURITY;
+        }
+    }
+
+    /* This can't fail */
     return STATUS_SUCCESS;
 }
 
@@ -807,6 +822,7 @@ ObpIncrementHandleCount(IN PVOID Object,
     KIRQL CalloutIrql;
     KPROCESSOR_MODE ProbeMode;
     ULONG Total;
+    POBJECT_HEADER_NAME_INFO NameInfo;
     PAGED_CODE();
 
     /* Get the object header and type */
@@ -872,6 +888,16 @@ ObpIncrementHandleCount(IN PVOID Object,
         goto Quickie;
     }
 
+    /* Check for exclusive kernel object */
+    NameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
+    if ((NameInfo) && (NameInfo->QueryReferences & OB_FLAG_KERNEL_EXCLUSIVE) &&
+        (ProbeMode != KernelMode))
+    {
+        /* Caller is not kernel, but the object is kernel exclusive */
+        Status = STATUS_ACCESS_DENIED;
+        goto Quickie;
+    }
+
     /*
      * Check if this is an object that went from 0 handles back to existence,
      * but doesn't have an open procedure, only a close procedure. This means
@@ -1978,25 +2004,79 @@ ObpDuplicateHandleCallback(IN PEPROCESS Process,
     return Ret;
 }
 
+/*++
+* @name ObClearProcessHandleTable
+*
+*     The ObClearProcessHandleTable routine clears the handle table
+*     of the given process.
+*
+* @param Process
+*        The process of which the handle table should be cleared.
+*
+* @return None.
+*
+* @remarks None.
+*
+*--*/
 VOID
 NTAPI
 ObClearProcessHandleTable(IN PEPROCESS Process)
 {
-    /* FIXME */
+    PHANDLE_TABLE HandleTable;
+    OBP_CLOSE_HANDLE_CONTEXT Context;
+    KAPC_STATE ApcState;
+    BOOLEAN AttachedToProcess = FALSE;
+
+    ASSERT(Process);
+
+    /* Ensure the handle table doesn't go away while we use it */
+    HandleTable = ObReferenceProcessHandleTable(Process);
+    if (!HandleTable) return;
+
+    /* Attach to the current process if needed */
+    if (PsGetCurrentProcess() != Process)
+    {
+        KeStackAttachProcess(&Process->Pcb, &ApcState);
+        AttachedToProcess = TRUE;
+    }
+
+    /* Enter a critical region */
+    KeEnterCriticalRegion();
+
+    /* Fill out the context */
+    Context.AccessMode = UserMode;
+    Context.HandleTable = HandleTable;
+
+    /* Sweep the handle table to close all handles */
+    ExSweepHandleTable(HandleTable,
+                       ObpCloseHandleCallback,
+                       &Context);
+
+    /* Leave the critical region */
+    KeLeaveCriticalRegion();
+
+    /* Detach if needed */
+    if (AttachedToProcess)
+        KeUnstackDetachProcess(&ApcState);
+
+    /* Let the handle table go */
+    ObDereferenceProcessHandleTable(Process);
 }
 
 /*++
-* @name ObpCreateHandleTable
+* @name ObInitProcess
 *
-*     The ObpCreateHandleTable routine <FILLMEIN>
+*     The ObInitProcess routine initializes the handle table for the process
+*     to be initialized, by either creating a new one or duplicating it from
+*     the parent process.
 *
 * @param Parent
-*        <FILLMEIN>.
+*        A parent process (optional).
 *
 * @param Process
-*        <FILLMEIN>.
+*        The process to initialize.
 *
-* @return <FILLMEIN>.
+* @return Success or failure.
 *
 * @remarks None.
 *
@@ -2059,14 +2139,16 @@ ObInitProcess(IN PEPROCESS Parent OPTIONAL,
 /*++
 * @name ObKillProcess
 *
-*     The ObKillProcess routine <FILLMEIN>
+*     The ObKillProcess routine performs rundown operations on the process,
+*     then clears and destroys its handle table.
 *
 * @param Process
-*        <FILLMEIN>.
+*        The process to be killed.
 *
 * @return None.
 *
-* @remarks None.
+* @remarks Called by the Object Manager cleanup code (kernel)
+*          when a process is to be destroyed.
 *
 *--*/
 VOID
@@ -2139,6 +2221,8 @@ ObDuplicateObject(IN PEPROCESS SourceProcess,
     PHANDLE_TABLE HandleTable;
     OBJECT_HANDLE_INFORMATION HandleInformation;
     ULONG AuditMask;
+    BOOLEAN KernelHandle = FALSE;
+
     PAGED_CODE();
     OBTRACE(OB_HANDLE_DEBUG,
             "%s - Duplicating handle: %p for %p into %p\n",
@@ -2211,6 +2295,14 @@ ObDuplicateObject(IN PEPROCESS SourceProcess,
         return Status;
     }
 
+    /* Create a kernel handle if asked, but only in the system process */
+    if (PreviousMode == KernelMode &&
+        HandleAttributes & OBJ_KERNEL_HANDLE &&
+        TargetProcess == PsInitialSystemProcess)
+    {
+        KernelHandle = TRUE;
+    }
+
     /* Get the target handle table */
     HandleTable = ObReferenceProcessHandleTable(TargetProcess);
     if (!HandleTable)
@@ -2365,6 +2457,12 @@ ObDuplicateObject(IN PEPROCESS SourceProcess,
         Status = STATUS_INSUFFICIENT_RESOURCES;
     }
 
+    /* Mark it as a kernel handle if requested */
+    if (KernelHandle)
+    {
+        NewHandle = ObMarkHandleAsKernelHandle(NewHandle);
+    }
+
     /* Return the handle */
     if (TargetHandle) *TargetHandle = NewHandle;
 
@@ -2567,7 +2665,7 @@ ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes,
                                   AccessMode,
                                   NULL,
                                   Handle);
-        if (!NT_SUCCESS(Status))
+        if (!NT_SUCCESS(Status2))
         {
             ObDereferenceObject(Object);
             Status = Status2;