/* Reference ourselves */
ObjectHeader = OBJECT_TO_OBJECT_HEADER(Process);
- InterlockedIncrement(&ObjectHeader->PointerCount);
+ InterlockedIncrementSizeT(&ObjectHeader->PointerCount);
/* Return the pointer */
*Object = Process;
/* Reference ourselves */
ObjectHeader = OBJECT_TO_OBJECT_HEADER(Thread);
- InterlockedExchangeAdd(&ObjectHeader->PointerCount, 1);
+ InterlockedIncrementSizeT(&ObjectHeader->PointerCount);
/* No audit mask */
*AuditMask = 0;
*Object = &ObjectHeader->Body;
/* Add a reference */
- InterlockedExchangeAdd(&ObjectHeader->PointerCount, 1);
+ InterlockedIncrementSizeT(&ObjectHeader->PointerCount);
/* Unlock the handle */
ExUnlockHandleTableEntry(HandleTable, HandleEntry);
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;
}
ProcessHandleCount = 0;
/* Decrement the handle count */
- NewCount = InterlockedDecrement(&ObjectHeader->HandleCount);
+ NewCount = InterlockedDecrementSizeT(&ObjectHeader->HandleCount);
/* Check if we're out of handles and this was an exclusive object */
if (!(NewCount) && (ObjectHeader->Flags & OB_FLAG_EXCLUSIVE))
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
}
/* Increase the handle count */
- InterlockedIncrement(&ObjectHeader->HandleCount);
+ InterlockedIncrementSizeT(&ObjectHeader->HandleCount);
ProcessHandleCount = 0;
/* Check if we have a handle database */
}
/* Increase the handle count */
- InterlockedIncrement(&ObjectHeader->HandleCount);
+ InterlockedIncrementSizeT(&ObjectHeader->HandleCount);
ProcessHandleCount = 0;
/* Check if we have a handle database */
if (AdditionalReferences)
{
/* Add them to the header */
- InterlockedExchangeAdd(&ObjectHeader->PointerCount,
- AdditionalReferences);
+ InterlockedExchangeAddSizeT(&ObjectHeader->PointerCount,
+ AdditionalReferences);
}
/* Save the access mask */
if (AdditionalReferences)
{
/* Dereference it as many times as required */
- InterlockedExchangeAdd(&ObjectHeader->PointerCount,
- -(LONG)AdditionalReferences);
+ InterlockedExchangeAddSizeT(&ObjectHeader->PointerCount,
+ -(LONG)AdditionalReferences);
}
/* Decrement the handle count and detach */
if (AdditionalReferences)
{
/* Add them to the header */
- InterlockedExchangeAdd(&ObjectHeader->PointerCount, AdditionalReferences);
+ InterlockedExchangeAddSizeT(&ObjectHeader->PointerCount,
+ AdditionalReferences);
}
/* Now we can release the object */
if (AdditionalReferences > 1)
{
/* Dereference it many times */
- InterlockedExchangeAdd(&ObjectHeader->PointerCount,
- -(LONG)(AdditionalReferences - 1));
+ InterlockedExchangeAddSizeT(&ObjectHeader->PointerCount,
+ -(LONG)(AdditionalReferences - 1));
}
/* Dereference the object one last time */
ObjectHeader = ObpGetHandleObject(HandleTableEntry);
/* Increment the pointer count */
- InterlockedIncrement(&ObjectHeader->PointerCount);
+ InterlockedIncrementSizeT(&ObjectHeader->PointerCount);
/* Release the handle lock */
ExUnlockHandleTableEntry(HandleTable, OldEntry);
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.
*
/*++
* @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
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;
{
/* Check if this was a symbolic link */
if (OBJECT_TO_OBJECT_HEADER(InsertObject)->Type ==
- ObSymbolicLinkType)
+ ObpSymbolicLinkObjectType)
{
/* Dereference it */
ObDereferenceObject(InsertObject);
else
{
/* Check if this is a symbolic link */
- if (ObjectType == ObSymbolicLinkType)
+ if (ObjectType == ObpSymbolicLinkObjectType)
{
/* Create the internal name */
ObpCreateSymbolicLinkName(Object);