[ros-diffs] [ion] 22099: - Object Manager Fixes (2 of 3): * Remove superflous debug prints used a long time ago while debugging * Set the CreatorUniqueProcess * Align code to 80 chars * Do a privilege check of OB_FLAG_PERMANENT is being used, and de-allocate the object if this failed. * Send the PreviousMode to ObpAllocateObject so that it can honor it and set the OB_FLAG_KERNEL_MODE flag. * Use OBJECT_TYPE accounting to increase TotalNumberOfObjects. * Fail ObCreateObject in low-memory situations instead of ignoring it. * Respect OBJECT_TYPE.TypeInfo.InvalidAttributes if an attempt is to create an object with invalid attributes is detected. * Respect PagedPoolCharge and NonPagedPoolCharge parameters and save them in the OBJECT_CREATE_INFORMATION strucutre.

ion at svn.reactos.org ion at svn.reactos.org
Mon May 29 02:18:36 CEST 2006


Author: ion
Date: Mon May 29 04:18:36 2006
New Revision: 22099

URL: http://svn.reactos.ru/svn/reactos?rev=22099&view=rev
Log:
- Object Manager Fixes (2 of 3):
  * Remove superflous debug prints used a long time ago while debugging
  * Set the CreatorUniqueProcess 
  * Align code to 80 chars
  * Do a privilege check of OB_FLAG_PERMANENT is being used, and de-allocate the object if this failed.
  * Send the PreviousMode to ObpAllocateObject so that it can honor it and set the OB_FLAG_KERNEL_MODE flag.
  * Use OBJECT_TYPE accounting to increase TotalNumberOfObjects.
  * Fail ObCreateObject in low-memory situations instead of ignoring it.
  * Respect OBJECT_TYPE.TypeInfo.InvalidAttributes if an attempt is to create an object with invalid attributes is detected.
  * Respect PagedPoolCharge and NonPagedPoolCharge parameters and save them in the OBJECT_CREATE_INFORMATION strucutre.

Modified:
    trunk/reactos/ntoskrnl/ob/obinit.c
    trunk/reactos/ntoskrnl/ob/oblife.c

Modified: trunk/reactos/ntoskrnl/ob/obinit.c
URL: http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/ob/obinit.c?rev=22099&r1=22098&r2=22099&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/ob/obinit.c (original)
+++ trunk/reactos/ntoskrnl/ob/obinit.c Mon May 29 04:18:36 2006
@@ -56,6 +56,9 @@
 
     /* Initialize the Default Event */
     KeInitializeEvent(&ObpDefaultObject, NotificationEvent, TRUE );
+
+    /* Setup the Object Reaper */
+    ExInitializeWorkItem(&ObpReaperWorkItem, ObpReapObject, NULL);
 
     /* Create the Type Type */
     DPRINT("Creating Type Type\n");

Modified: trunk/reactos/ntoskrnl/ob/oblife.c
URL: http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/ob/oblife.c?rev=22099&r1=22098&r2=22099&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/ob/oblife.c (original)
+++ trunk/reactos/ntoskrnl/ob/oblife.c Mon May 29 04:18:36 2006
@@ -398,7 +398,6 @@
     return Status;
 }
 
-
 VOID
 STDCALL
 ObpReleaseCapturedAttributes(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo)
@@ -414,12 +413,13 @@
 }
 
 NTSTATUS
-STDCALL
-ObpAllocateObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo,
-                  PUNICODE_STRING ObjectName,
-                  POBJECT_TYPE ObjectType,
-                  ULONG ObjectSize,
-                  POBJECT_HEADER *ObjectHeader)
+NTAPI
+ObpAllocateObject(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo,
+                  IN PUNICODE_STRING ObjectName,
+                  IN POBJECT_TYPE ObjectType,
+                  IN ULONG ObjectSize,
+                  IN KPROCESSOR_MODE PreviousMode,
+                  IN POBJECT_HEADER *ObjectHeader)
 {
     POBJECT_HEADER Header;
     BOOLEAN HasHandleInfo = FALSE;
@@ -431,9 +431,9 @@
     POOL_TYPE PoolType;
     ULONG FinalSize = ObjectSize;
     ULONG Tag;
+    PAGED_CODE();
         
     /* If we don't have an Object Type yet, force NonPaged */
-    DPRINT("ObpAllocateObject\n");
     if (!ObjectType) 
     {
         PoolType = NonPagedPool;
@@ -445,7 +445,6 @@
         Tag = ObjectType->Key;
     }
     
-    DPRINT("Checking ObjectName: %x\n", ObjectName);
     /* Check if the Object has a name */
     if (ObjectName->Buffer) 
     {
@@ -456,7 +455,6 @@
     if (ObjectType)
     {
         /* Check if the Object maintains handle counts */
-        DPRINT("Checking ObjectType->TypeInfo: %x\n", &ObjectType->TypeInfo);
         if (ObjectType->TypeInfo.MaintainHandleCount)
         {
             FinalSize += sizeof(OBJECT_HEADER_HANDLE_INFO);
@@ -472,18 +470,13 @@
     }
 
     /* Allocate memory for the Object and Header */
-    DPRINT("Allocating: %x %x\n", FinalSize, Tag);
     Header = ExAllocatePoolWithTag(PoolType, FinalSize, Tag);
-    if (!Header) {
-        DPRINT1("Not enough memory!\n");
-        return STATUS_INSUFFICIENT_RESOURCES;
-    }
+    if (!Header) return STATUS_INSUFFICIENT_RESOURCES;
            
     /* Initialize Handle Info */
     if (HasHandleInfo)
     {
         HandleInfo = (POBJECT_HEADER_HANDLE_INFO)Header;
-        DPRINT("Info: %x\n", HandleInfo);
         HandleInfo->SingleEntry.HandleCount = 0;
         Header = (POBJECT_HEADER)(HandleInfo + 1);
     }
@@ -492,7 +485,6 @@
     if (HasNameInfo) 
     {
         NameInfo = (POBJECT_HEADER_NAME_INFO)Header;
-        DPRINT("Info: %x %wZ\n", NameInfo, ObjectName);
         NameInfo->Name = *ObjectName;
         NameInfo->Directory = NULL;
         Header = (POBJECT_HEADER)(NameInfo + 1);
@@ -502,48 +494,56 @@
     if (HasCreatorInfo)
     {
         CreatorInfo = (POBJECT_HEADER_CREATOR_INFO)Header;
-        DPRINT("Info: %x\n", CreatorInfo);
-        /* FIXME: Needs Alex's Init patch
-         * CreatorInfo->CreatorUniqueProcess = PsGetCurrentProcessId();
-         */
+        CreatorInfo->CreatorUniqueProcess = PsGetCurrentProcess() ?
+                                            PsGetCurrentProcessId() : 0;
         InitializeListHead(&CreatorInfo->TypeList);
         Header = (POBJECT_HEADER)(CreatorInfo + 1);
     }
     
     /* Initialize the object header */
     RtlZeroMemory(Header, ObjectSize);
-    DPRINT("Initalized header %p\n", Header);
-    Header->HandleCount = 0;
     Header->PointerCount = 1;
     Header->Type = ObjectType;
     Header->Flags = OB_FLAG_CREATE_INFO;
+    Header->ObjectCreateInfo = ObjectCreateInfo;
     
     /* Set the Offsets for the Info */
     if (HasHandleInfo)
     {
-        Header->HandleInfoOffset = HasNameInfo * sizeof(OBJECT_HEADER_NAME_INFO) + 
+        Header->HandleInfoOffset = HasNameInfo *
+                                   sizeof(OBJECT_HEADER_NAME_INFO) +
                                    sizeof(OBJECT_HEADER_HANDLE_INFO) +
-                                   HasCreatorInfo * sizeof(OBJECT_HEADER_CREATOR_INFO);
+                                   HasCreatorInfo *
+                                   sizeof(OBJECT_HEADER_CREATOR_INFO);
+
+        /* Set the flag so we know when freeing */
         Header->Flags |= OB_FLAG_SINGLE_PROCESS;
     }
     if (HasNameInfo)
     {
         Header->NameInfoOffset = sizeof(OBJECT_HEADER_NAME_INFO) + 
-                                 HasCreatorInfo * sizeof(OBJECT_HEADER_CREATOR_INFO);
+                                 HasCreatorInfo *
+                                 sizeof(OBJECT_HEADER_CREATOR_INFO);
     }
     if (HasCreatorInfo) Header->Flags |= OB_FLAG_CREATOR_INFO;
-    
-    if (ObjectCreateInfo && ObjectCreateInfo->Attributes & OBJ_PERMANENT)
-    {
+    if ((ObjectCreateInfo) && (ObjectCreateInfo->Attributes & OBJ_PERMANENT))
+    {
+        /* Set the needed flag so we can check */
         Header->Flags |= OB_FLAG_PERMANENT;
     }
-    if (ObjectCreateInfo && ObjectCreateInfo->Attributes & OBJ_EXCLUSIVE)
-    {
+    if ((ObjectCreateInfo) && (ObjectCreateInfo->Attributes & OBJ_EXCLUSIVE))
+    {
+        /* Set the needed flag so we can check */
         Header->Flags |= OB_FLAG_EXCLUSIVE;
     }
-    
-    /* Link stuff to Object Header */
-    Header->ObjectCreateInfo = ObjectCreateInfo;
+    if (PreviousMode == KernelMode)
+    {
+        /* Set the kernel flag */
+        Header->Flags |= OB_FLAG_KERNEL_MODE;
+    }
+    
+    /* Increase the number of objects of this type */
+    if (ObjectType) ObjectType->TotalNumberOfObjects++;
     
     /* Return Header */
     *ObjectHeader = Header;
@@ -560,41 +560,34 @@
     POBJECT_TYPE LocalObjectType;
     ULONG HeaderSize;
     NTSTATUS Status;
-
-    DPRINT("ObpCreateTypeObject(ObjectType: %wZ)\n", TypeName);
-    
+    CHAR Tag[4];
+    OBP_LOOKUP_CONTEXT Context;
+
     /* Allocate the Object */
     Status = ObpAllocateObject(NULL, 
                                TypeName,
                                ObTypeObjectType, 
                                sizeof(OBJECT_TYPE) + sizeof(OBJECT_HEADER),
+                               KernelMode,
                                (POBJECT_HEADER*)&Header);
-    if (!NT_SUCCESS(Status))
-    {
-        DPRINT1("ObpAllocateObject failed!\n");
-        return Status;
-    }
-    
+    if (!NT_SUCCESS(Status)) return Status;
     LocalObjectType = (POBJECT_TYPE)&Header->Body;
-    DPRINT("Local ObjectType: %p Header: %p \n", LocalObjectType, Header);
     
     /* Check if this is the first Object Type */
     if (!ObTypeObjectType)
     {
         ObTypeObjectType = LocalObjectType;
         Header->Type = ObTypeObjectType;
+        LocalObjectType->TotalNumberOfObjects = 1;
         LocalObjectType->Key = TAG('O', 'b', 'j', 'T');
     }
     else
     {   
-        CHAR Tag[4];
+        /* Set Tag */
         Tag[0] = TypeName->Buffer[0];
         Tag[1] = TypeName->Buffer[1];
         Tag[2] = TypeName->Buffer[2];
         Tag[3] = TypeName->Buffer[3];
-        
-        /* Set Tag */
-        DPRINT("Convert: %s \n", Tag);
         LocalObjectType->Key = *(PULONG)Tag;
     }
     
@@ -662,7 +655,6 @@
     /* Insert it into the Object Directory */
     if (ObpTypeDirectoryObject)
     {
-        OBP_LOOKUP_CONTEXT Context;
         Context.Directory = ObpTypeDirectoryObject;
         Context.DirectoryLocked = TRUE;
         ObpLookupEntryDirectory(ObpTypeDirectoryObject,
@@ -701,46 +693,68 @@
             Type, ObjectAttributes, Object);
 
     /* Allocate a Buffer for the Object Create Info */
-    DPRINT("Allocating Create Buffer\n");
     ObjectCreateInfo = ExAllocatePoolWithTag(NonPagedPool, 
                                              sizeof(*ObjectCreateInfo),
                                              TAG('O','b','C', 'I'));
+    if (!ObjectCreateInfo) return STATUS_INSUFFICIENT_RESOURCES;
 
     /* Capture all the info */
-    DPRINT("Capturing Create Info\n");
     Status = ObpCaptureObjectAttributes(ObjectAttributes,
                                         ObjectAttributesAccessMode,
                                         Type,
                                         ObjectCreateInfo,
                                         &ObjectName);
-
     if (NT_SUCCESS(Status))
     {
-        /* Allocate the Object */
-        DPRINT("Allocating: %wZ\n", &ObjectName);
-        Status = ObpAllocateObject(ObjectCreateInfo,
-                                   &ObjectName,
-                                   Type,
-                                   ObjectSize + sizeof(OBJECT_HEADER),
-                                   &Header);
-        if (NT_SUCCESS(Status))
-        {
-            /* Return the Object */
-            DPRINT("Returning Object\n");
-            *Object = &Header->Body;
-            
-            /* Return to caller, leave the Capture Info Alive for ObInsert */
-            return Status;
+        /* Validate attributes */
+        if (Type->TypeInfo.InvalidAttributes &
+            ObjectCreateInfo->Attributes)
+        {
+            /* Fail */
+            Status = STATUS_INVALID_PARAMETER;
+        }
+        else
+        {
+            /* Save the pool charges */
+            ObjectCreateInfo->PagedPoolCharge = PagedPoolCharge;
+            ObjectCreateInfo->NonPagedPoolCharge = NonPagedPoolCharge;
+
+            /* Allocate the Object */
+            Status = ObpAllocateObject(ObjectCreateInfo,
+                                       &ObjectName,
+                                       Type,
+                                       ObjectSize + sizeof(OBJECT_HEADER),
+                                       AccessMode,
+                                       &Header);
+            if (NT_SUCCESS(Status))
+            {
+                /* Return the Object */
+                *Object = &Header->Body;
+                
+                    /* Check if this is a permanent object */
+                    if (Header->Flags & OB_FLAG_PERMANENT)
+                    {
+                        /* Do the privilege check */
+                        if (!SeSinglePrivilegeCheck(SeCreatePermanentPrivilege,
+                                                    ObjectAttributesAccessMode))
+                        {
+                            /* Fail */
+                            ObpDeallocateObject(*Object);
+                            Status = STATUS_PRIVILEGE_NOT_HELD;
+                        }
+                    }
+
+                    /* Return status */
+                return Status;
+            }
         }
 
         /* Release the Capture Info, we don't need it */
-        DPRINT1("Allocation failed\n");
         ObpReleaseCapturedAttributes(ObjectCreateInfo);
         if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
     }
 
     /* We failed, so release the Buffer */
-    DPRINT1("Capture failed\n");
     ExFreePool(ObjectCreateInfo);
     return Status;
 }




More information about the Ros-diffs mailing list