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 PDIRECTORY_OBJECT NameSpaceRoot;
extern POBJECT_TYPE ObSymbolicLinkType; 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, VOID ObpAddEntryDirectory(PDIRECTORY_OBJECT Parent,
POBJECT_HEADER Header, POBJECT_HEADER Header,
@ -266,10 +274,6 @@ NTSTATUS ObFindObject(POBJECT_ATTRIBUTES ObjectAttributes,
POBJECT_TYPE ObjectType); POBJECT_TYPE ObjectType);
VOID ObDeleteHandleTable(struct _EPROCESS* Process); VOID ObDeleteHandleTable(struct _EPROCESS* Process);
NTSTATUS
ObDeleteHandle(PEPROCESS Process,
HANDLE Handle);
NTSTATUS NTSTATUS
ObpQueryHandleAttributes(HANDLE Handle, ObpQueryHandleAttributes(HANDLE Handle,
POBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo); POBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo);

View file

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

View file

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