KIRQL CalloutIrql;
KPROCESSOR_MODE ProbeMode;
ULONG Total;
+ POBJECT_HEADER_NAME_INFO NameInfo;
PAGED_CODE();
/* Get the object header and type */
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
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",
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)
Status = STATUS_INSUFFICIENT_RESOURCES;
}
+ /* Mark it as a kernel handle if requested */
+ if (KernelHandle)
+ {
+ NewHandle = ObMarkHandleAsKernelHandle(NewHandle);
+ }
+
/* Return the handle */
if (TargetHandle) *TargetHandle = NewHandle;
AccessMode,
NULL,
Handle);
- if (!NT_SUCCESS(Status))
+ if (!NT_SUCCESS(Status2))
{
ObDereferenceObject(Object);
Status = Status2;