- Formatting/name/comment/declaration/calling convention changes.

- Make ObpCreateHandleTable return NTSTATUS instead of VOID, so that it can return STATUS_INSUFFIENT_RESOURCES if the handle table couldn't be allocated.

svn path=/trunk/; revision=22249
This commit is contained in:
Alex Ionescu 2006-06-06 21:02:55 +00:00
parent 7fff40f524
commit a25a59160d
4 changed files with 220 additions and 216 deletions

View file

@ -42,25 +42,33 @@ extern NPAGED_LOOKASIDE_LIST ObpNmLookasideList, ObpCiLookasideList;
BOOLEAN BOOLEAN
NTAPI NTAPI
ObpDeleteEntryDirectory(POBP_LOOKUP_CONTEXT Context); ObpDeleteEntryDirectory(
IN POBP_LOOKUP_CONTEXT Context
);
BOOLEAN BOOLEAN
NTAPI NTAPI
ObpInsertEntryDirectory(IN POBJECT_DIRECTORY Parent, ObpInsertEntryDirectory(
IN POBP_LOOKUP_CONTEXT Context, IN POBJECT_DIRECTORY Parent,
IN POBJECT_HEADER ObjectHeader); IN POBP_LOOKUP_CONTEXT Context,
IN POBJECT_HEADER ObjectHeader
);
PVOID PVOID
NTAPI NTAPI
ObpLookupEntryDirectory(IN POBJECT_DIRECTORY Directory, ObpLookupEntryDirectory(
IN PUNICODE_STRING Name, IN POBJECT_DIRECTORY Directory,
IN ULONG Attributes, IN PUNICODE_STRING Name,
IN UCHAR SearchShadow, IN ULONG Attributes,
IN POBP_LOOKUP_CONTEXT Context); IN UCHAR SearchShadow,
IN POBP_LOOKUP_CONTEXT Context
);
VOID VOID
NTAPI NTAPI
ObInitSymbolicLinkImplementation(VOID); ObInitSymbolicLinkImplementation(
VOID
);
NTSTATUS NTSTATUS
NTAPI NTAPI
@ -73,21 +81,15 @@ ObpCreateHandle(
NTSTATUS NTSTATUS
NTAPI NTAPI
ObpParseDirectory( ObpCreateHandleTable(
PVOID Object, IN PEPROCESS Parent,
PVOID * NextObject, IN PEPROCESS Process
PUNICODE_STRING FullPath,
PWSTR * Path,
ULONG Attributes,
POBP_LOOKUP_CONTEXT Context
); );
VOID VOID
NTAPI NTAPI
ObCreateHandleTable( ObKillProcess(
struct _EPROCESS* Parent, IN PEPROCESS Process
BOOLEAN Inherit,
struct _EPROCESS* Process
); );
NTSTATUS NTSTATUS
@ -137,10 +139,10 @@ NTAPI
ObpGetHandleCountByHandleTable(PHANDLE_TABLE HandleTable); ObpGetHandleCountByHandleTable(PHANDLE_TABLE HandleTable);
VOID VOID
STDCALL NTAPI
ObQueryDeviceMapInformation( ObQueryDeviceMapInformation(
PEPROCESS Process, IN PEPROCESS Process,
PPROCESS_DEVICEMAP_INFORMATION DeviceMapInfo OUT PPROCESS_DEVICEMAP_INFORMATION DeviceMapInfo
); );
VOID VOID
@ -150,10 +152,6 @@ ObpSetPermanentObject(
IN BOOLEAN Permanent IN BOOLEAN Permanent
); );
VOID
STDCALL
ObKillProcess(PEPROCESS Process);
VOID VOID
FASTCALL FASTCALL
ObpDeleteObject( ObpDeleteObject(

View file

@ -323,6 +323,106 @@ ObpDeleteHandle(HANDLE Handle)
return Status; return Status;
} }
NTSTATUS
NTAPI
ObpCreateHandle(PVOID ObjectBody,
ACCESS_MASK GrantedAccess,
ULONG HandleAttributes,
PHANDLE HandleReturn)
/*
* FUNCTION: Add a handle referencing an object
* ARGUMENTS:
* obj = Object body that the handle should refer to
* RETURNS: The created handle
* NOTE: The handle is valid only in the context of the current process
*/
{
HANDLE_TABLE_ENTRY NewEntry;
PEPROCESS Process, CurrentProcess;
POBJECT_HEADER ObjectHeader;
HANDLE Handle;
KAPC_STATE ApcState;
BOOLEAN AttachedToProcess = FALSE;
PAGED_CODE();
DPRINT("ObpCreateHandle(obj %p)\n",ObjectBody);
ASSERT(ObjectBody);
CurrentProcess = PsGetCurrentProcess();
ObjectHeader = OBJECT_TO_OBJECT_HEADER(ObjectBody);
/* check that this is a valid kernel pointer */
ASSERT((ULONG_PTR)ObjectHeader & EX_HANDLE_ENTRY_LOCKED);
if (GrantedAccess & MAXIMUM_ALLOWED)
{
GrantedAccess &= ~MAXIMUM_ALLOWED;
GrantedAccess |= GENERIC_ALL;
}
if (GrantedAccess & GENERIC_ACCESS)
{
RtlMapGenericMask(&GrantedAccess,
&ObjectHeader->Type->TypeInfo.GenericMapping);
}
NewEntry.Object = ObjectHeader;
if(HandleAttributes & OBJ_INHERIT)
NewEntry.ObAttributes |= EX_HANDLE_ENTRY_INHERITABLE;
else
NewEntry.ObAttributes &= ~EX_HANDLE_ENTRY_INHERITABLE;
NewEntry.GrantedAccess = GrantedAccess;
if ((HandleAttributes & OBJ_KERNEL_HANDLE) &&
ExGetPreviousMode == KernelMode)
{
Process = PsInitialSystemProcess;
if (Process != CurrentProcess)
{
KeStackAttachProcess(&Process->Pcb,
&ApcState);
AttachedToProcess = TRUE;
}
}
else
{
Process = CurrentProcess;
/* mask out the OBJ_KERNEL_HANDLE attribute */
HandleAttributes &= ~OBJ_KERNEL_HANDLE;
}
Handle = ExCreateHandle(Process->ObjectTable,
&NewEntry);
if (AttachedToProcess)
{
KeUnstackDetachProcess(&ApcState);
}
if(Handle != NULL)
{
if (HandleAttributes & OBJ_KERNEL_HANDLE)
{
/* mark the handle value */
Handle = ObMarkHandleAsKernelHandle(Handle);
}
if(InterlockedIncrement(&ObjectHeader->HandleCount) == 1)
{
ObReferenceObject(ObjectBody);
}
*HandleReturn = Handle;
return STATUS_SUCCESS;
}
return STATUS_UNSUCCESSFUL;
}
/*++ /*++
* @name ObpSetHandleAttributes * @name ObpSetHandleAttributes
* *
@ -389,6 +489,98 @@ ObpSetHandleAttributes(IN PHANDLE_TABLE HandleTable,
return TRUE; return TRUE;
} }
VOID
NTAPI
ObpCloseHandleCallback(IN PHANDLE_TABLE HandleTable,
IN PVOID Object,
IN ULONG GrantedAccess,
IN PVOID Context)
{
PAGED_CODE();
/* Simply decrement the handle count */
ObpDecrementHandleCount(&EX_OBJ_TO_HDR(Object)->Body,
PsGetCurrentProcess(),
GrantedAccess);
}
BOOLEAN
NTAPI
ObpDuplicateHandleCallback(IN PHANDLE_TABLE HandleTable,
IN PHANDLE_TABLE_ENTRY HandleTableEntry,
IN PVOID Context)
{
POBJECT_HEADER ObjectHeader;
BOOLEAN Ret = FALSE;
PAGED_CODE();
/* Make sure that the handle is inheritable */
Ret = (HandleTableEntry->ObAttributes & EX_HANDLE_ENTRY_INHERITABLE) != 0;
if(Ret)
{
/* Get the object header and increment the handle and pointer counts */
ObjectHeader = EX_HTE_TO_HDR(HandleTableEntry);
InterlockedIncrement(&ObjectHeader->HandleCount);
InterlockedIncrement(&ObjectHeader->PointerCount);
}
/* Return duplication result */
return Ret;
}
NTSTATUS
NTAPI
ObpCreateHandleTable(IN PEPROCESS Parent,
IN PEPROCESS Process)
{
PHANDLE_TABLE HandleTable;
PAGED_CODE();
/* Check if we have a parent */
if (Parent)
{
/* Duplicate the parent's */
HandleTable = ExDupHandleTable(Process,
ObpDuplicateHandleCallback,
NULL,
Parent->ObjectTable);
}
else
{
/* Create a new one */
HandleTable = ExCreateHandleTable(Process);
}
/* Now write it and make sure we got one */
Process->ObjectTable = HandleTable;
if (!HandleTable) return STATUS_INSUFFICIENT_RESOURCES;
/* If we got here then the table was created OK */
return STATUS_SUCCESS;
}
VOID
NTAPI
ObKillProcess(IN PEPROCESS Process)
{
PAGED_CODE();
/* Enter a critical region */
KeEnterCriticalRegion();
/* Sweep the handle table to close all handles */
ExSweepHandleTable(Process->ObjectTable,
ObpCloseHandleCallback,
Process);
/* Destroy the table and leave the critical region */
ExDestroyHandleTable(Process->ObjectTable);
KeLeaveCriticalRegion();
/* Clear the object table */
Process->ObjectTable = NULL;
}
NTSTATUS NTSTATUS
NTAPI NTAPI
ObDuplicateObject(PEPROCESS SourceProcess, ObDuplicateObject(PEPROCESS SourceProcess,
@ -546,192 +738,6 @@ ObDuplicateObject(PEPROCESS SourceProcess,
return Status; return Status;
} }
static VOID STDCALL
SweepHandleCallback(PHANDLE_TABLE HandleTable,
PVOID Object,
ULONG GrantedAccess,
PVOID Context)
{
POBJECT_HEADER ObjectHeader;
PVOID ObjectBody;
PAGED_CODE();
ObjectHeader = EX_OBJ_TO_HDR(Object);
ObjectBody = &ObjectHeader->Body;
ObpDecrementHandleCount(ObjectBody, PsGetCurrentProcess(), GrantedAccess);
}
static BOOLEAN STDCALL
DuplicateHandleCallback(PHANDLE_TABLE HandleTable,
PHANDLE_TABLE_ENTRY HandleTableEntry,
PVOID Context)
{
POBJECT_HEADER ObjectHeader;
BOOLEAN Ret = FALSE;
PAGED_CODE();
Ret = (HandleTableEntry->ObAttributes & EX_HANDLE_ENTRY_INHERITABLE) != 0;
if(Ret)
{
ObjectHeader = EX_HTE_TO_HDR(HandleTableEntry);
if(InterlockedIncrement(&ObjectHeader->HandleCount) == 1)
{
ObReferenceObject(&ObjectHeader->Body);
}
}
return Ret;
}
VOID
NTAPI
ObCreateHandleTable(PEPROCESS Parent,
BOOLEAN Inherit,
PEPROCESS Process)
/*
* FUNCTION: Creates a handle table for a process
* ARGUMENTS:
* Parent = Parent process (or NULL if this is the first process)
* Inherit = True if the process should inherit its parent's handles
* Process = Process whose handle table is to be created
*/
{
PAGED_CODE();
DPRINT("ObCreateHandleTable(Parent %x, Inherit %d, Process %x)\n",
Parent,Inherit,Process);
if(Parent != NULL)
{
Process->ObjectTable = ExDupHandleTable(Process,
DuplicateHandleCallback,
NULL,
Parent->ObjectTable);
}
else
{
Process->ObjectTable = ExCreateHandleTable(Process);
}
}
VOID
STDCALL
ObKillProcess(PEPROCESS Process)
{
PAGED_CODE();
/* FIXME - Temporary hack: sweep and destroy here, needs to be fixed!!! */
ExSweepHandleTable(Process->ObjectTable,
SweepHandleCallback,
Process);
ExDestroyHandleTable(Process->ObjectTable);
Process->ObjectTable = NULL;
}
NTSTATUS
NTAPI
ObpCreateHandle(PVOID ObjectBody,
ACCESS_MASK GrantedAccess,
ULONG HandleAttributes,
PHANDLE HandleReturn)
/*
* FUNCTION: Add a handle referencing an object
* ARGUMENTS:
* obj = Object body that the handle should refer to
* RETURNS: The created handle
* NOTE: The handle is valid only in the context of the current process
*/
{
HANDLE_TABLE_ENTRY NewEntry;
PEPROCESS Process, CurrentProcess;
POBJECT_HEADER ObjectHeader;
HANDLE Handle;
KAPC_STATE ApcState;
BOOLEAN AttachedToProcess = FALSE;
PAGED_CODE();
DPRINT("ObpCreateHandle(obj %p)\n",ObjectBody);
ASSERT(ObjectBody);
CurrentProcess = PsGetCurrentProcess();
ObjectHeader = OBJECT_TO_OBJECT_HEADER(ObjectBody);
/* check that this is a valid kernel pointer */
ASSERT((ULONG_PTR)ObjectHeader & EX_HANDLE_ENTRY_LOCKED);
if (GrantedAccess & MAXIMUM_ALLOWED)
{
GrantedAccess &= ~MAXIMUM_ALLOWED;
GrantedAccess |= GENERIC_ALL;
}
if (GrantedAccess & GENERIC_ACCESS)
{
RtlMapGenericMask(&GrantedAccess,
&ObjectHeader->Type->TypeInfo.GenericMapping);
}
NewEntry.Object = ObjectHeader;
if(HandleAttributes & OBJ_INHERIT)
NewEntry.ObAttributes |= EX_HANDLE_ENTRY_INHERITABLE;
else
NewEntry.ObAttributes &= ~EX_HANDLE_ENTRY_INHERITABLE;
NewEntry.GrantedAccess = GrantedAccess;
if ((HandleAttributes & OBJ_KERNEL_HANDLE) &&
ExGetPreviousMode == KernelMode)
{
Process = PsInitialSystemProcess;
if (Process != CurrentProcess)
{
KeStackAttachProcess(&Process->Pcb,
&ApcState);
AttachedToProcess = TRUE;
}
}
else
{
Process = CurrentProcess;
/* mask out the OBJ_KERNEL_HANDLE attribute */
HandleAttributes &= ~OBJ_KERNEL_HANDLE;
}
Handle = ExCreateHandle(Process->ObjectTable,
&NewEntry);
if (AttachedToProcess)
{
KeUnstackDetachProcess(&ApcState);
}
if(Handle != NULL)
{
if (HandleAttributes & OBJ_KERNEL_HANDLE)
{
/* mark the handle value */
Handle = ObMarkHandleAsKernelHandle(Handle);
}
if(InterlockedIncrement(&ObjectHeader->HandleCount) == 1)
{
ObReferenceObject(ObjectBody);
}
*HandleReturn = Handle;
return STATUS_SUCCESS;
}
return STATUS_UNSUCCESSFUL;
}
/* PUBLIC FUNCTIONS *********************************************************/ /* PUBLIC FUNCTIONS *********************************************************/
NTSTATUS NTSTATUS

View file

@ -340,7 +340,7 @@ PspCreateProcess(OUT PHANDLE ProcessHandle,
/* Create or Clone the Handle Table */ /* Create or Clone the Handle Table */
DPRINT("Initialzing Process Handle Table\n"); DPRINT("Initialzing Process Handle Table\n");
ObCreateHandleTable(pParentProcess, InheritObjectTable, Process); ObpCreateHandleTable(pParentProcess, Process);
DPRINT("Handle Table: %x\n", Process->ObjectTable); DPRINT("Handle Table: %x\n", Process->ObjectTable);
/* Set Process's Directory Base */ /* Set Process's Directory Base */

View file

@ -303,7 +303,7 @@ PspPostInitSystemProcess(VOID)
process a PID */ process a PID */
PsInitClientIDManagment(); PsInitClientIDManagment();
ObCreateHandleTable(NULL, FALSE, PsInitialSystemProcess); ObpCreateHandleTable(NULL, PsInitialSystemProcess);
ObpKernelHandleTable = PsInitialSystemProcess->ObjectTable; ObpKernelHandleTable = PsInitialSystemProcess->ObjectTable;
CidEntry.Object = PsInitialSystemProcess; CidEntry.Object = PsInitialSystemProcess;