support kernel handles, creating them is however not yet supported Modified: trunk/reactos/ntoskrnl/include/internal/ob.h Modified: trunk/reactos/ntoskrnl/ob/handle.c Modified: trunk/reactos/ntoskrnl/ps/process.c _____
Modified: trunk/reactos/ntoskrnl/include/internal/ob.h --- trunk/reactos/ntoskrnl/include/internal/ob.h 2005-04-11 20:27:20 UTC (rev 14592) +++ trunk/reactos/ntoskrnl/include/internal/ob.h 2005-04-11 21:50:15 UTC (rev 14593) @@ -242,7 +242,15 @@
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, PWSTR Name); @@ -267,10 +275,6 @@ VOID ObDeleteHandleTable(struct _EPROCESS* Process);
NTSTATUS -ObDeleteHandle(PEPROCESS Process, - HANDLE Handle); - -NTSTATUS ObpQueryHandleAttributes(HANDLE Handle, POBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo);
_____
Modified: trunk/reactos/ntoskrnl/ob/handle.c --- trunk/reactos/ntoskrnl/ob/handle.c 2005-04-11 20:27:20 UTC (rev 14592) +++ trunk/reactos/ntoskrnl/ob/handle.c 2005-04-11 21:50:15 UTC (rev 14593) @@ -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 @@ ObDeleteHandleTable(Process); }
-VOID +static VOID ObpDecrementHandleCount(PVOID ObjectBody) { POBJECT_HEADER ObjectHeader = BODY_TO_HEADER(ObjectBody); @@ -76,19 +80,28 @@ 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 @@ 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 @@ 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 @@
/* FIXME: Do we need to set anything in the object header??? */
- ExUnlockHandleTableEntry(Process->ObjectTable, + ExUnlockHandleTableEntry(HandleTable, HandleTableEntry);
KeLeaveCriticalRegion(); @@ -153,6 +175,54 @@ }
+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 @@ 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 @@ NewHandleCount = InterlockedIncrement(&ObjectHeader->HandleCount); ASSERT(NewHandleCount >= 2);
- ExUnlockHandleTableEntry(SourceProcess->ObjectTable, + ExUnlockHandleTableEntry(SourceHandleTable, SourceHandleEntry);
KeLeaveCriticalRegion(); @@ -231,8 +314,8 @@ { if (Options & DUPLICATE_CLOSE_SOURCE) { - ObDeleteHandle(SourceProcess, - SourceHandle); + ObpDeleteHandle(SourceHandleTable, + SourceHandle); }
ObDereferenceObject(ObjectBody); @@ -384,8 +467,8 @@
if (Options & DUPLICATE_CLOSE_SOURCE) { - ObDeleteHandle(SourceProcess, - SourceHandle); + ObpDeleteHandle(SourceProcess->ObjectTable, + SourceHandle); } } } @@ -464,10 +547,7 @@ ObjectHeader = EX_HTE_TO_HDR(HandleTableEntry); if(InterlockedIncrement(&ObjectHeader->HandleCount) == 1) { - ObReferenceObjectByPointer(HEADER_TO_BODY(ObjectHeader), - 0, - NULL, - UserMode); + ObReferenceObject(HEADER_TO_BODY(ObjectHeader)); } }
@@ -504,54 +584,6 @@
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, ACCESS_MASK GrantedAccess, @@ -685,11 +717,11 @@ { 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 @@ 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 @@ 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 @@ 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 @@ HandleInformation->GrantedAccess = THREAD_ALL_ACCESS; }
- *Object = PsGetCurrentThread(); + *Object = CurrentThread; CHECKPOINT; return STATUS_SUCCESS; } @@ -763,9 +785,20 @@ 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 @@ 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 @@ rights than the handle can grant */ if(AccessMode != KernelMode && (~GrantedAccess & DesiredAccess)) { - ExUnlockHandleTableEntry(PsGetCurrentProcess()->ObjectTable, + ExUnlockHandleTableEntry(HandleTable, HandleEntry);
KeLeaveCriticalRegion(); @@ -814,15 +847,13 @@ 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 @@ 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; }
_____
Modified: trunk/reactos/ntoskrnl/ps/process.c --- trunk/reactos/ntoskrnl/ps/process.c 2005-04-11 20:27:20 UTC (rev 14592) +++ trunk/reactos/ntoskrnl/ps/process.c 2005-04-11 21:50:15 UTC (rev 14593) @@ -286,6 +286,7 @@
PsInitClientIDManagment();
ObCreateHandleTable(NULL, FALSE, PsInitialSystemProcess); + ObpKernelHandleTable = PsInitialSystemProcess->ObjectTable;
Status = PsCreateCidHandle(PsInitialSystemProcess, PsProcessType,