[NTOS:OB]
[reactos.git] / reactos / ntoskrnl / ob / obhandle.c
index a2b2f9c..e97c69d 100644 (file)
@@ -807,6 +807,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 +873,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
@@ -2139,6 +2150,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 +2224,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 +2386,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 +2594,7 @@ ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes,
                                   AccessMode,
                                   NULL,
                                   Handle);
-        if (!NT_SUCCESS(Status))
+        if (!NT_SUCCESS(Status2))
         {
             ObDereferenceObject(Object);
             Status = Status2;