Author: ion Date: Mon Jun 5 04:04:36 2006 New Revision: 22228
URL: http://svn.reactos.ru/svn/reactos?rev=22228&view=rev Log: - Fix ExChangeHandle not to send NULL but the actual context to the callback function (fix by Thomas Weidenmueller w3seek@reactos.org) - Re-implement NtSetInformationObject based on ExChangeHandle and using ObpSetHandleAttributes as a callback. - Re-implement NtQueryObject's ObjectHandleInformation case to simply return the information that's already in HandleAttributes; there is no point in querying for it all over again. - Fix NtSetInformationObject not to allow a user-mode call to modify kernel-mdoe handle attributes. Add FIXME for Inheritance permissions check. - Fix NtQueryObject to properly return OBJ_PERMANENT and OBJ_EXCLUSIVE; these flags are not stored in Handle Attributes. - Fix NtQueryObject not to attempt referencing the handle if the caller specified AllTypesInformation, because then a handle is not needed.
Modified: trunk/reactos/ntoskrnl/ex/handle.c trunk/reactos/ntoskrnl/include/internal/ob.h trunk/reactos/ntoskrnl/ob/obhandle.c trunk/reactos/ntoskrnl/ob/oblife.c
Modified: trunk/reactos/ntoskrnl/ex/handle.c URL: http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/ex/handle.c?rev=222... ============================================================================== --- trunk/reactos/ntoskrnl/ex/handle.c (original) +++ trunk/reactos/ntoskrnl/ex/handle.c Mon Jun 5 04:04:36 2006 @@ -916,7 +916,7 @@ { Ret = ChangeHandleCallback(HandleTable, HandleTableEntry, - NULL); + Context);
ExUnlockHandleTableEntry(HandleTable, HandleTableEntry);
Modified: trunk/reactos/ntoskrnl/include/internal/ob.h URL: http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/include/internal/ob... ============================================================================== --- trunk/reactos/ntoskrnl/include/internal/ob.h (original) +++ trunk/reactos/ntoskrnl/include/internal/ob.h Mon Jun 5 04:04:36 2006 @@ -8,6 +8,12 @@
#ifndef __INCLUDE_INTERNAL_OBJMGR_H #define __INCLUDE_INTERNAL_OBJMGR_H + +typedef struct _OBP_SET_HANDLE_ATTRIBUTES_CONTEXT +{ + KPROCESSOR_MODE PreviousMode; + OBJECT_HANDLE_ATTRIBUTE_INFORMATION Information; +} OBP_SET_HANDLE_ATTRIBUTES_CONTEXT, *POBP_SET_HANDLE_ATTRIBUTES_CONTEXT;
#define GENERIC_ACCESS (GENERIC_READ | \ GENERIC_WRITE | \ @@ -100,18 +106,12 @@ IN PVOID Insert );
-NTSTATUS -NTAPI -ObpQueryHandleAttributes( - HANDLE Handle, - POBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo -); - -NTSTATUS +BOOLEAN NTAPI ObpSetHandleAttributes( - HANDLE Handle, - POBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo + IN PHANDLE_TABLE HandleTable, + IN OUT PHANDLE_TABLE_ENTRY HandleTableEntry, + IN PVOID Context );
NTSTATUS
Modified: trunk/reactos/ntoskrnl/ob/obhandle.c URL: http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/ob/obhandle.c?rev=2... ============================================================================== --- trunk/reactos/ntoskrnl/ob/obhandle.c (original) +++ trunk/reactos/ntoskrnl/ob/obhandle.c Mon Jun 5 04:04:36 2006 @@ -154,129 +154,51 @@ } }
-NTSTATUS +BOOLEAN NTAPI -ObpQueryHandleAttributes(HANDLE Handle, - POBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo) -{ - PHANDLE_TABLE_ENTRY HandleTableEntry; - PEPROCESS Process, CurrentProcess; - KAPC_STATE ApcState; - BOOLEAN AttachedToProcess = FALSE; - NTSTATUS Status = STATUS_SUCCESS; - - PAGED_CODE(); - - DPRINT("ObpQueryHandleAttributes(Handle %p)\n", Handle); - CurrentProcess = PsGetCurrentProcess(); - - KeEnterCriticalRegion(); - - if(ObIsKernelHandle(Handle, ExGetPreviousMode())) - { - Process = PsInitialSystemProcess; - Handle = ObKernelHandleToHandle(Handle); - - if (Process != CurrentProcess) - { - KeStackAttachProcess(&Process->Pcb, - &ApcState); - AttachedToProcess = TRUE; - } - } - else - { - Process = CurrentProcess; - } - - HandleTableEntry = ExMapHandleToPointer(Process->ObjectTable, - Handle); - if (HandleTableEntry != NULL) - { - HandleInfo->Inherit = (HandleTableEntry->ObAttributes & EX_HANDLE_ENTRY_INHERITABLE) != 0; - HandleInfo->ProtectFromClose = (HandleTableEntry->ObAttributes & EX_HANDLE_ENTRY_PROTECTFROMCLOSE) != 0; - - ExUnlockHandleTableEntry(Process->ObjectTable, - HandleTableEntry); - } - else - Status = STATUS_INVALID_HANDLE; - - if (AttachedToProcess) - { - KeUnstackDetachProcess(&ApcState); - } - - KeLeaveCriticalRegion(); - - return Status; -} - -NTSTATUS -NTAPI -ObpSetHandleAttributes(HANDLE Handle, - POBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo) -{ - PHANDLE_TABLE_ENTRY HandleTableEntry; - PEPROCESS Process, CurrentProcess; - KAPC_STATE ApcState; - BOOLEAN AttachedToProcess = FALSE; - NTSTATUS Status = STATUS_SUCCESS; - - PAGED_CODE(); - - DPRINT("ObpSetHandleAttributes(Handle %p)\n", Handle); - CurrentProcess = PsGetCurrentProcess(); - - KeEnterCriticalRegion(); - - if(ObIsKernelHandle(Handle, ExGetPreviousMode())) - { - Process = PsInitialSystemProcess; - Handle = ObKernelHandleToHandle(Handle); - - if (Process != CurrentProcess) - { - KeStackAttachProcess(&Process->Pcb, - &ApcState); - AttachedToProcess = TRUE; - } - } - else - { - Process = CurrentProcess; - } - - HandleTableEntry = ExMapHandleToPointer(Process->ObjectTable, - Handle); - if (HandleTableEntry != NULL) - { - if (HandleInfo->Inherit) - HandleTableEntry->ObAttributes |= EX_HANDLE_ENTRY_INHERITABLE; - else - HandleTableEntry->ObAttributes &= ~EX_HANDLE_ENTRY_INHERITABLE; - - if (HandleInfo->ProtectFromClose) - HandleTableEntry->ObAttributes |= EX_HANDLE_ENTRY_PROTECTFROMCLOSE; - else - HandleTableEntry->ObAttributes &= ~EX_HANDLE_ENTRY_PROTECTFROMCLOSE; - - /* FIXME: Do we need to set anything in the object header??? */ - - ExUnlockHandleTableEntry(Process->ObjectTable, - HandleTableEntry); - } - else - Status = STATUS_INVALID_HANDLE; - - if (AttachedToProcess) - { - KeUnstackDetachProcess(&ApcState); - } - - KeLeaveCriticalRegion(); - - return Status; +ObpSetHandleAttributes(IN PHANDLE_TABLE HandleTable, + IN OUT PHANDLE_TABLE_ENTRY HandleTableEntry, + IN PVOID Context) +{ + POBP_SET_HANDLE_ATTRIBUTES_CONTEXT SetHandleInfo = + (POBP_SET_HANDLE_ATTRIBUTES_CONTEXT)Context; + POBJECT_HEADER ObjectHeader = EX_HTE_TO_HDR(HandleTableEntry); + PAGED_CODE(); + + /* Don't allow operations on kernel objects */ + if ((ObjectHeader->Flags & OB_FLAG_KERNEL_MODE) && + (SetHandleInfo->PreviousMode != KernelMode)) + { + /* Fail */ + return FALSE; + } + + /* Check if making the handle inheritable */ + if (SetHandleInfo->Information.Inherit) + { + /* Set the flag. FIXME: Need to check if this is allowed */ + HandleTableEntry->ObAttributes |= EX_HANDLE_ENTRY_INHERITABLE; + } + else + { + /* Otherwise this implies we're removing the flag */ + HandleTableEntry->ObAttributes &= ~EX_HANDLE_ENTRY_INHERITABLE; + } + + /* Check if making the handle protected */ + if (SetHandleInfo->Information.ProtectFromClose) + { + /* Set the flag */ + HandleTableEntry->ObAttributes |= EX_HANDLE_ENTRY_PROTECTFROMCLOSE; + } + else + { + /* Otherwise, remove it */ + HandleTableEntry->ObAttributes &= ~EX_HANDLE_ENTRY_PROTECTFROMCLOSE; + } + + /* Return success */ + return TRUE; }
static NTSTATUS
Modified: trunk/reactos/ntoskrnl/ob/oblife.c URL: http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/ob/oblife.c?rev=222... ============================================================================== --- trunk/reactos/ntoskrnl/ob/oblife.c (original) +++ trunk/reactos/ntoskrnl/ob/oblife.c Mon Jun 5 04:04:36 2006 @@ -790,95 +790,157 @@ OUT PULONG ResultLength OPTIONAL) { OBJECT_HANDLE_INFORMATION HandleInfo; - POBJECT_HEADER ObjectHeader; + POBJECT_HEADER ObjectHeader = NULL; + POBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleFlags; + POBJECT_BASIC_INFORMATION BasicInfo; ULONG InfoLength; - PVOID Object; + PVOID Object = NULL; NTSTATUS Status; PAGED_CODE();
- Status = ObReferenceObjectByHandle(ObjectHandle, - 0, - NULL, - KeGetPreviousMode(), - &Object, - &HandleInfo); - if (!NT_SUCCESS (Status)) return Status; - - ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object); - + /* FIXME: Needs SEH */ + + /* + * Make sure this isn't a generic type query, since the caller doesn't + * have to give a handle for it + */ + if (ObjectInformationClass != ObjectAllTypesInformation) + { + /* Reference the object */ + Status = ObReferenceObjectByHandle(ObjectHandle, + 0, + NULL, + KeGetPreviousMode(), + &Object, + &HandleInfo); + if (!NT_SUCCESS (Status)) return Status; + + /* Get the object header */ + ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object); + } + + /* Check the information class */ switch (ObjectInformationClass) { - case ObjectBasicInformation: - InfoLength = sizeof(OBJECT_BASIC_INFORMATION); - if (Length != sizeof(OBJECT_BASIC_INFORMATION)) - { - Status = STATUS_INFO_LENGTH_MISMATCH; - } - else - { - POBJECT_BASIC_INFORMATION BasicInfo; - + /* Basic info */ + case ObjectBasicInformation: + + /* Validate length */ + InfoLength = sizeof(OBJECT_BASIC_INFORMATION); + if (Length != sizeof(OBJECT_BASIC_INFORMATION)) + { + /* Fail */ + Status = STATUS_INFO_LENGTH_MISMATCH; + break; + } + + /* Fill out the basic information */ BasicInfo = (POBJECT_BASIC_INFORMATION)ObjectInformation; BasicInfo->Attributes = HandleInfo.HandleAttributes; BasicInfo->GrantedAccess = HandleInfo.GrantedAccess; BasicInfo->HandleCount = ObjectHeader->HandleCount; BasicInfo->PointerCount = ObjectHeader->PointerCount; + + /* Permanent/Exclusive Flags are NOT in Handle attributes! */ + if (ObjectHeader->Flags & OB_FLAG_EXCLUSIVE) + { + /* Set the flag */ + BasicInfo->Attributes |= OBJ_EXCLUSIVE; + } + if (ObjectHeader->Flags & OB_FLAG_PERMANENT) + { + /* Set the flag */ + BasicInfo->Attributes |= OBJ_PERMANENT; + } + + /* Copy quota information */ BasicInfo->PagedPoolUsage = 0; /* FIXME*/ BasicInfo->NonPagedPoolUsage = 0; /* FIXME*/ + + /* Copy name information */ BasicInfo->NameInformationLength = 0; /* FIXME*/ BasicInfo->TypeInformationLength = 0; /* FIXME*/ + + /* Copy security information */ BasicInfo->SecurityDescriptorLength = 0; /* FIXME*/ + + /* Check if this is a symlink */ if (ObjectHeader->Type == ObSymbolicLinkType) { + /* Return the creation time */ BasicInfo->CreateTime.QuadPart = ((POBJECT_SYMBOLIC_LINK)Object)->CreationTime.QuadPart; } else { + /* Otherwise return 0 */ BasicInfo->CreateTime.QuadPart = (ULONGLONG)0; } + + /* Break out with success */ Status = STATUS_SUCCESS; - } - break; - - case ObjectNameInformation: - Status = ObQueryNameString(Object, - (POBJECT_NAME_INFORMATION)ObjectInformation, - Length, - &InfoLength); - break; - - case ObjectTypeInformation: - Status = STATUS_NOT_IMPLEMENTED; - break; - - case ObjectAllTypesInformation: - Status = STATUS_NOT_IMPLEMENTED; - break; - - case ObjectHandleInformation: - InfoLength = sizeof (OBJECT_HANDLE_ATTRIBUTE_INFORMATION); - if (Length != sizeof (OBJECT_HANDLE_ATTRIBUTE_INFORMATION)) - { - Status = STATUS_INFO_LENGTH_MISMATCH; - } - else - { - Status = ObpQueryHandleAttributes( - ObjectHandle, - (POBJECT_HANDLE_ATTRIBUTE_INFORMATION)ObjectInformation); - } - break; - - default: - Status = STATUS_INVALID_INFO_CLASS; - break; - } - - ObDereferenceObject (Object); - - if (ResultLength != NULL) *ResultLength = InfoLength; - + break; + + /* Name information */ + case ObjectNameInformation: + + /* Call the helper and break out */ + Status = ObQueryNameString(Object, + (POBJECT_NAME_INFORMATION) + ObjectInformation, + Length, + &InfoLength); + break; + + /* Information about this type */ + case ObjectTypeInformation: + DPRINT1("NOT IMPLEMENTED!\n"); + Status = STATUS_NOT_IMPLEMENTED; + break; + + /* Information about all types */ + case ObjectAllTypesInformation: + DPRINT1("NOT IMPLEMENTED!\n"); + Status = STATUS_NOT_IMPLEMENTED; + break; + + /* Information about the handle flags */ + case ObjectHandleInformation: + + /* Validate length */ + InfoLength = sizeof (OBJECT_HANDLE_ATTRIBUTE_INFORMATION); + if (Length != sizeof (OBJECT_HANDLE_ATTRIBUTE_INFORMATION)) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + break; + } + + /* Get the structure */ + HandleFlags = (POBJECT_HANDLE_ATTRIBUTE_INFORMATION) + ObjectInformation; + + /* Set the flags */ + HandleFlags->Inherit = (HandleInfo.HandleAttributes & + EX_HANDLE_ENTRY_INHERITABLE) != 0; + HandleFlags->ProtectFromClose = (HandleInfo.HandleAttributes & + EX_HANDLE_ENTRY_PROTECTFROMCLOSE) != 0; + + /* Break out with success */ + Status = STATUS_SUCCESS; + break; + + /* Anything else */ + default: + /* Fail it */ + Status = STATUS_INVALID_INFO_CLASS; + break; + } + + /* Derefernece the object if we had referenced it */ + if (Object) ObDereferenceObject (Object); + + /* Return the length and status */ + if (ResultLength) *ResultLength = InfoLength; return Status; }
@@ -912,29 +974,66 @@ IN PVOID ObjectInformation, IN ULONG Length) { - PVOID Object; - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; + OBP_SET_HANDLE_ATTRIBUTES_CONTEXT Context; + PVOID ObjectTable; + KAPC_STATE ApcState; + BOOLEAN AttachedToProcess = FALSE; PAGED_CODE();
+ /* Validate the information class */ if (ObjectInformationClass != ObjectHandleInformation) + { + /* Invalid class */ return STATUS_INVALID_INFO_CLASS; - + } + + /* Validate the length */ if (Length != sizeof (OBJECT_HANDLE_ATTRIBUTE_INFORMATION)) + { + /* Invalid length */ return STATUS_INFO_LENGTH_MISMATCH; - - Status = ObReferenceObjectByHandle(ObjectHandle, - 0, - NULL, - KeGetPreviousMode(), - &Object, - NULL); - if (!NT_SUCCESS (Status)) return Status; - - Status = ObpSetHandleAttributes(ObjectHandle, - (POBJECT_HANDLE_ATTRIBUTE_INFORMATION) - ObjectInformation); - - ObDereferenceObject (Object); + } + + /* Save the previous mode and actual information */ + Context.PreviousMode = ExGetPreviousMode(); + Context.Information = *(POBJECT_HANDLE_ATTRIBUTE_INFORMATION) + ObjectInformation; + + /* Check if this is a kernel handle */ + if (ObIsKernelHandle(ObjectHandle, Context.PreviousMode)) + { + /* Get the actual handle */ + ObjectHandle = ObKernelHandleToHandle(ObjectHandle); + ObjectTable = ObpKernelHandleTable; + + /* Check if we're not in the system process */ + if (PsGetCurrentProcess() != PsInitialSystemProcess) + { + /* Attach to it */ + KeStackAttachProcess(&PsInitialSystemProcess->Pcb, &ApcState); + AttachedToProcess = TRUE; + } + } + else + { + /* Use the current table */ + ObjectTable = PsGetCurrentProcess()->ObjectTable; + } + + /* Change the handle attributes */ + if (!ExChangeHandle(ObjectTable, + ObjectHandle, + ObpSetHandleAttributes, + &Context)) + { + /* Some failure */ + Status = STATUS_ACCESS_DENIED; + } + + /* De-attach if we were attached, and return status */ + if (AttachedToProcess) KeUnstackDetachProcess(&ApcState); return Status; } + /* EOF */