support kernel handles, creating them is however not yet supported

svn path=/trunk/; revision=14593
This commit is contained in:
Thomas Bluemel 2005-04-11 21:50:15 +00:00
parent e70a05cabf
commit 9a3b51ea9a
3 changed files with 158 additions and 108 deletions

View file

@ -242,6 +242,14 @@ enum
extern PDIRECTORY_OBJECT NameSpaceRoot;
extern POBJECT_TYPE ObSymbolicLinkType;
extern PHANDLE_TABLE ObpKernelHandleTable;
#define KERNEL_HANDLE_FLAG (1 << ((sizeof(HANDLE) * 8) - 1))
#define ObIsKernelHandle(Handle, ProcessorMode) \
(((ULONG_PTR)(Handle) & KERNEL_HANDLE_FLAG) && \
((ProcessorMode) == KernelMode))
#define ObKernelHandleToHandle(Handle) \
(HANDLE)((ULONG_PTR)(Handle) & ~KERNEL_HANDLE_FLAG)
VOID ObpAddEntryDirectory(PDIRECTORY_OBJECT Parent,
POBJECT_HEADER Header,
@ -266,10 +274,6 @@ NTSTATUS ObFindObject(POBJECT_ATTRIBUTES ObjectAttributes,
POBJECT_TYPE ObjectType);
VOID ObDeleteHandleTable(struct _EPROCESS* Process);
NTSTATUS
ObDeleteHandle(PEPROCESS Process,
HANDLE Handle);
NTSTATUS
ObpQueryHandleAttributes(HANDLE Handle,
POBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo);

View file

@ -42,6 +42,10 @@
#define GENERIC_ANY (GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL)
/* GLOBALS *****************************************************************/
PHANDLE_TABLE ObpKernelHandleTable = NULL;
/* FUNCTIONS ***************************************************************/
VOID
@ -51,7 +55,7 @@ ObKillProcess(PEPROCESS Process)
ObDeleteHandleTable(Process);
}
VOID
static VOID
ObpDecrementHandleCount(PVOID ObjectBody)
{
POBJECT_HEADER ObjectHeader = BODY_TO_HEADER(ObjectBody);
@ -76,19 +80,28 @@ NTSTATUS
ObpQueryHandleAttributes(HANDLE Handle,
POBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo)
{
PEPROCESS Process;
PHANDLE_TABLE HandleTable;
PHANDLE_TABLE_ENTRY HandleTableEntry;
LONG ExHandle = HANDLE_TO_EX_HANDLE(Handle);
LONG ExHandle;
PAGED_CODE();
DPRINT("ObpQueryHandleAttributes(Handle %x)\n", Handle);
if(ObIsKernelHandle(Handle, ExGetPreviousMode()))
{
HandleTable = ObpKernelHandleTable;
ExHandle = HANDLE_TO_EX_HANDLE(ObKernelHandleToHandle(Handle));
}
else
{
HandleTable = PsGetCurrentProcess()->ObjectTable;
ExHandle = HANDLE_TO_EX_HANDLE(Handle);
}
KeEnterCriticalRegion();
Process = PsGetCurrentProcess();
HandleTableEntry = ExMapHandleToPointer(Process->ObjectTable,
HandleTableEntry = ExMapHandleToPointer(HandleTable,
ExHandle);
if (HandleTableEntry == NULL)
{
@ -99,7 +112,7 @@ ObpQueryHandleAttributes(HANDLE Handle,
HandleInfo->Inherit = (HandleTableEntry->u1.ObAttributes & EX_HANDLE_ENTRY_INHERITABLE) != 0;
HandleInfo->ProtectFromClose = (HandleTableEntry->u1.ObAttributes & EX_HANDLE_ENTRY_PROTECTFROMCLOSE) != 0;
ExUnlockHandleTableEntry(Process->ObjectTable,
ExUnlockHandleTableEntry(HandleTable,
HandleTableEntry);
KeLeaveCriticalRegion();
@ -112,19 +125,28 @@ NTSTATUS
ObpSetHandleAttributes(HANDLE Handle,
POBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo)
{
PEPROCESS Process;
PHANDLE_TABLE HandleTable;
PHANDLE_TABLE_ENTRY HandleTableEntry;
LONG ExHandle = HANDLE_TO_EX_HANDLE(Handle);
LONG ExHandle;
PAGED_CODE();
DPRINT("ObpSetHandleAttributes(Handle %x)\n", Handle);
Process = PsGetCurrentProcess();
if(ObIsKernelHandle(Handle, ExGetPreviousMode()))
{
HandleTable = ObpKernelHandleTable;
ExHandle = HANDLE_TO_EX_HANDLE(ObKernelHandleToHandle(Handle));
}
else
{
HandleTable = PsGetCurrentProcess()->ObjectTable;
ExHandle = HANDLE_TO_EX_HANDLE(Handle);
}
KeEnterCriticalRegion();
HandleTableEntry = ExMapHandleToPointer(Process->ObjectTable,
HandleTableEntry = ExMapHandleToPointer(HandleTable,
ExHandle);
if (HandleTableEntry == NULL)
{
@ -144,7 +166,7 @@ ObpSetHandleAttributes(HANDLE Handle,
/* FIXME: Do we need to set anything in the object header??? */
ExUnlockHandleTableEntry(Process->ObjectTable,
ExUnlockHandleTableEntry(HandleTable,
HandleTableEntry);
KeLeaveCriticalRegion();
@ -153,6 +175,54 @@ ObpSetHandleAttributes(HANDLE Handle,
}
static NTSTATUS
ObpDeleteHandle(PHANDLE_TABLE HandleTable,
HANDLE Handle)
{
PHANDLE_TABLE_ENTRY HandleEntry;
PVOID Body;
POBJECT_HEADER ObjectHeader;
LONG ExHandle = HANDLE_TO_EX_HANDLE(Handle);
PAGED_CODE();
DPRINT("ObpDeleteHandle(Handle %x)\n",Handle);
KeEnterCriticalRegion();
HandleEntry = ExMapHandleToPointer(HandleTable,
ExHandle);
if(HandleEntry != NULL)
{
if(HandleEntry->u1.ObAttributes & EX_HANDLE_ENTRY_PROTECTFROMCLOSE)
{
ExUnlockHandleTableEntry(HandleTable,
HandleEntry);
KeLeaveCriticalRegion();
return STATUS_HANDLE_NOT_CLOSABLE;
}
ObjectHeader = EX_HTE_TO_HDR(HandleEntry);
Body = HEADER_TO_BODY(ObjectHeader);
ObpDecrementHandleCount(Body);
/* destroy and unlock the handle entry */
ExDestroyHandleByEntry(HandleTable,
HandleEntry,
ExHandle);
KeLeaveCriticalRegion();
return STATUS_SUCCESS;
}
KeLeaveCriticalRegion();
return STATUS_INVALID_HANDLE;
}
NTSTATUS
ObDuplicateObject(PEPROCESS SourceProcess,
PEPROCESS TargetProcess,
@ -162,19 +232,32 @@ ObDuplicateObject(PEPROCESS SourceProcess,
BOOLEAN InheritHandle,
ULONG Options)
{
PHANDLE_TABLE SourceHandleTable;
PHANDLE_TABLE_ENTRY SourceHandleEntry;
HANDLE_TABLE_ENTRY NewHandleEntry;
PVOID ObjectBody;
POBJECT_HEADER ObjectHeader;
LONG ExTargetHandle;
LONG ExSourceHandle = HANDLE_TO_EX_HANDLE(SourceHandle);
LONG ExSourceHandle;
ULONG NewHandleCount;
PAGED_CODE();
if(ObIsKernelHandle(SourceHandle, ExGetPreviousMode()))
{
SourceHandleTable = ObpKernelHandleTable;
SourceHandle = ObKernelHandleToHandle(SourceHandle);
}
else
{
SourceHandleTable = SourceProcess->ObjectTable;
}
ExSourceHandle = HANDLE_TO_EX_HANDLE(SourceHandle);
KeEnterCriticalRegion();
SourceHandleEntry = ExMapHandleToPointer(SourceProcess->ObjectTable,
SourceHandleEntry = ExMapHandleToPointer(SourceHandleTable,
ExSourceHandle);
if (SourceHandleEntry == NULL)
{
@ -219,7 +302,7 @@ ObDuplicateObject(PEPROCESS SourceProcess,
NewHandleCount = InterlockedIncrement(&ObjectHeader->HandleCount);
ASSERT(NewHandleCount >= 2);
ExUnlockHandleTableEntry(SourceProcess->ObjectTable,
ExUnlockHandleTableEntry(SourceHandleTable,
SourceHandleEntry);
KeLeaveCriticalRegion();
@ -231,8 +314,8 @@ ObDuplicateObject(PEPROCESS SourceProcess,
{
if (Options & DUPLICATE_CLOSE_SOURCE)
{
ObDeleteHandle(SourceProcess,
SourceHandle);
ObpDeleteHandle(SourceHandleTable,
SourceHandle);
}
ObDereferenceObject(ObjectBody);
@ -384,8 +467,8 @@ NtDuplicateObject (IN HANDLE SourceProcessHandle,
if (Options & DUPLICATE_CLOSE_SOURCE)
{
ObDeleteHandle(SourceProcess,
SourceHandle);
ObpDeleteHandle(SourceProcess->ObjectTable,
SourceHandle);
}
}
}
@ -464,10 +547,7 @@ DuplicateHandleCallback(PHANDLE_TABLE HandleTable,
ObjectHeader = EX_HTE_TO_HDR(HandleTableEntry);
if(InterlockedIncrement(&ObjectHeader->HandleCount) == 1)
{
ObReferenceObjectByPointer(HEADER_TO_BODY(ObjectHeader),
0,
NULL,
UserMode);
ObReferenceObject(HEADER_TO_BODY(ObjectHeader));
}
}
@ -503,54 +583,6 @@ VOID ObCreateHandleTable(PEPROCESS Parent,
}
NTSTATUS
ObDeleteHandle(PEPROCESS Process,
HANDLE Handle)
{
PHANDLE_TABLE_ENTRY HandleEntry;
PVOID Body;
POBJECT_HEADER ObjectHeader;
LONG ExHandle = HANDLE_TO_EX_HANDLE(Handle);
PAGED_CODE();
DPRINT("ObDeleteHandle(Handle %x)\n",Handle);
KeEnterCriticalRegion();
HandleEntry = ExMapHandleToPointer(Process->ObjectTable,
ExHandle);
if(HandleEntry != NULL)
{
if(HandleEntry->u1.ObAttributes & EX_HANDLE_ENTRY_PROTECTFROMCLOSE)
{
ExUnlockHandleTableEntry(Process->ObjectTable,
HandleEntry);
KeLeaveCriticalRegion();
return STATUS_HANDLE_NOT_CLOSABLE;
}
ObjectHeader = EX_HTE_TO_HDR(HandleEntry);
Body = HEADER_TO_BODY(ObjectHeader);
ObpDecrementHandleCount(Body);
/* destroy and unlock the handle entry */
ExDestroyHandleByEntry(Process->ObjectTable,
HandleEntry,
ExHandle);
KeLeaveCriticalRegion();
return STATUS_SUCCESS;
}
KeLeaveCriticalRegion();
return STATUS_INVALID_HANDLE;
}
NTSTATUS
ObCreateHandle(PEPROCESS Process,
PVOID ObjectBody,
@ -685,11 +717,11 @@ ObReferenceObjectByHandle(HANDLE Handle,
{
PHANDLE_TABLE_ENTRY HandleEntry;
POBJECT_HEADER ObjectHeader;
PHANDLE_TABLE HandleTable;
PVOID ObjectBody;
ACCESS_MASK GrantedAccess;
ULONG Attributes;
NTSTATUS Status;
LONG ExHandle = HANDLE_TO_EX_HANDLE(Handle);
LONG ExHandle;
PAGED_CODE();
@ -703,14 +735,9 @@ ObReferenceObjectByHandle(HANDLE Handle,
if (Handle == NtCurrentProcess() &&
(ObjectType == PsProcessType || ObjectType == NULL))
{
Status = ObReferenceObjectByPointer(PsGetCurrentProcess(),
PROCESS_ALL_ACCESS,
PsProcessType,
UserMode);
if (! NT_SUCCESS(Status))
{
return Status;
}
PEPROCESS CurrentProcess = PsGetCurrentProcess();
ObReferenceObject(CurrentProcess);
if (HandleInformation != NULL)
{
@ -718,8 +745,8 @@ ObReferenceObjectByHandle(HANDLE Handle,
HandleInformation->GrantedAccess = PROCESS_ALL_ACCESS;
}
*Object = PsGetCurrentProcess();
DPRINT("Referencing current process %x\n", PsGetCurrentProcess());
*Object = CurrentProcess;
DPRINT("Referencing current process %x\n", CurrentProcess);
return STATUS_SUCCESS;
}
else if (Handle == NtCurrentProcess())
@ -731,14 +758,9 @@ ObReferenceObjectByHandle(HANDLE Handle,
if (Handle == NtCurrentThread() &&
(ObjectType == PsThreadType || ObjectType == NULL))
{
Status = ObReferenceObjectByPointer(PsGetCurrentThread(),
THREAD_ALL_ACCESS,
PsThreadType,
UserMode);
if (! NT_SUCCESS(Status))
{
return Status;
}
PETHREAD CurrentThread = PsGetCurrentThread();
ObReferenceObject(CurrentThread);
if (HandleInformation != NULL)
{
@ -746,7 +768,7 @@ ObReferenceObjectByHandle(HANDLE Handle,
HandleInformation->GrantedAccess = THREAD_ALL_ACCESS;
}
*Object = PsGetCurrentThread();
*Object = CurrentThread;
CHECKPOINT;
return STATUS_SUCCESS;
}
@ -763,9 +785,20 @@ ObReferenceObjectByHandle(HANDLE Handle,
DesiredAccess |= GENERIC_ALL;
}
if(ObIsKernelHandle(Handle, AccessMode))
{
HandleTable = ObpKernelHandleTable;
ExHandle = HANDLE_TO_EX_HANDLE(ObKernelHandleToHandle(Handle));
}
else
{
HandleTable = PsGetCurrentProcess()->ObjectTable;
ExHandle = HANDLE_TO_EX_HANDLE(Handle);
}
KeEnterCriticalRegion();
HandleEntry = ExMapHandleToPointer(PsGetCurrentProcess()->ObjectTable,
HandleEntry = ExMapHandleToPointer(HandleTable,
ExHandle);
if (HandleEntry == NULL)
{
@ -777,13 +810,13 @@ ObReferenceObjectByHandle(HANDLE Handle,
ObjectHeader = EX_HTE_TO_HDR(HandleEntry);
ObjectBody = HEADER_TO_BODY(ObjectHeader);
DPRINT("locked1: ObjectHeader: 0x%x [HT:0x%x]\n", ObjectHeader, PsGetCurrentProcess()->ObjectTable);
DPRINT("locked1: ObjectHeader: 0x%x [HT:0x%x]\n", ObjectHeader, HandleTable);
if (ObjectType != NULL && ObjectType != ObjectHeader->ObjectType)
{
DPRINT("ObjectType mismatch: %wZ vs %wZ (handle 0x%x)\n", &ObjectType->TypeName, ObjectHeader->ObjectType ? &ObjectHeader->ObjectType->TypeName : NULL, Handle);
ExUnlockHandleTableEntry(PsGetCurrentProcess()->ObjectTable,
ExUnlockHandleTableEntry(HandleTable,
HandleEntry);
KeLeaveCriticalRegion();
@ -804,7 +837,7 @@ ObReferenceObjectByHandle(HANDLE Handle,
rights than the handle can grant */
if(AccessMode != KernelMode && (~GrantedAccess & DesiredAccess))
{
ExUnlockHandleTableEntry(PsGetCurrentProcess()->ObjectTable,
ExUnlockHandleTableEntry(HandleTable,
HandleEntry);
KeLeaveCriticalRegion();
@ -814,15 +847,13 @@ ObReferenceObjectByHandle(HANDLE Handle,
return(STATUS_ACCESS_DENIED);
}
ObReferenceObjectByPointer(ObjectBody,
0,
NULL,
UserMode);
ObReferenceObject(ObjectBody);
Attributes = HandleEntry->u1.ObAttributes & (EX_HANDLE_ENTRY_PROTECTFROMCLOSE |
EX_HANDLE_ENTRY_INHERITABLE |
EX_HANDLE_ENTRY_AUDITONCLOSE);
ExUnlockHandleTableEntry(PsGetCurrentProcess()->ObjectTable,
ExUnlockHandleTableEntry(HandleTable,
HandleEntry);
KeLeaveCriticalRegion();
@ -858,16 +889,30 @@ ObReferenceObjectByHandle(HANDLE Handle,
NTSTATUS STDCALL
NtClose(IN HANDLE Handle)
{
PHANDLE_TABLE HandleTable;
NTSTATUS Status;
PAGED_CODE();
Status = ObDeleteHandle(PsGetCurrentProcess(),
Handle);
if(ObIsKernelHandle(Handle, ExGetPreviousMode()))
{
HandleTable = ObpKernelHandleTable;
Handle = ObKernelHandleToHandle(Handle);
}
else
{
HandleTable = PsGetCurrentProcess()->ObjectTable;
}
Status = ObpDeleteHandle(HandleTable,
Handle);
if (!NT_SUCCESS(Status))
{
if(((PEPROCESS)(KeGetCurrentThread()->ApcState.Process))->ExceptionPort)
if((ExGetPreviousMode() != KernelMode) &&
(PsGetCurrentProcess()->ExceptionPort))
{
KeRaiseUserException(Status);
}
return Status;
}

View file

@ -286,6 +286,7 @@ PspPostInitSystemProcess(VOID)
PsInitClientIDManagment();
ObCreateHandleTable(NULL, FALSE, PsInitialSystemProcess);
ObpKernelHandleTable = PsInitialSystemProcess->ObjectTable;
Status = PsCreateCidHandle(PsInitialSystemProcess,
PsProcessType,