mirror of
https://github.com/reactos/reactos.git
synced 2025-02-25 01:39:30 +00:00
support kernel handles, creating them is however not yet supported
svn path=/trunk/; revision=14593
This commit is contained in:
parent
e70a05cabf
commit
9a3b51ea9a
3 changed files with 158 additions and 108 deletions
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -286,6 +286,7 @@ PspPostInitSystemProcess(VOID)
|
|||
PsInitClientIDManagment();
|
||||
|
||||
ObCreateHandleTable(NULL, FALSE, PsInitialSystemProcess);
|
||||
ObpKernelHandleTable = PsInitialSystemProcess->ObjectTable;
|
||||
|
||||
Status = PsCreateCidHandle(PsInitialSystemProcess,
|
||||
PsProcessType,
|
||||
|
|
Loading…
Reference in a new issue