[ros-diffs] [ion] 22228: - Fix ExChangeHandle not to send NULL but the actual context to the callback function (fix by Thomas Weidenmueller <w3seek at 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.

ion at svn.reactos.org ion at svn.reactos.org
Mon Jun 5 02:04:37 CEST 2006


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 at 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=22228&r1=22227&r2=22228&view=diff
==============================================================================
--- 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.h?rev=22228&r1=22227&r2=22228&view=diff
==============================================================================
--- 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=22228&r1=22227&r2=22228&view=diff
==============================================================================
--- 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=22228&r1=22227&r2=22228&view=diff
==============================================================================
--- 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 */




More information about the Ros-diffs mailing list