[ros-diffs] [ion] 22696: - Fixes in ObCreateObjectType to pass Fireball's (and some of my own local) ob tests: - Fix a check in ObpFreeObject which was causing a bugcheck if the object had a handle database (fixes another kmtest failure/crash). - Verify parameters passed to ObCreateObjectType based on behaviour seen on Windows 2003 (I might've missed some, these are the ones I tested for). This fixes 2 of the kmtest failures. - Also make sure the object type's name doesn't have a slash in the name. - Also make sure we don't allow creating two object types with the same name. - Also use our own local copy of the object name and copy it.

ion at svn.reactos.org ion at svn.reactos.org
Thu Jun 29 21:03:24 CEST 2006


Author: ion
Date: Thu Jun 29 23:03:24 2006
New Revision: 22696

URL: http://svn.reactos.org/svn/reactos?rev=22696&view=rev
Log:
- Fixes in ObCreateObjectType to pass Fireball's (and some of my own local) ob tests:
  - Fix a check in ObpFreeObject which was causing a bugcheck if the object had a handle database (fixes another kmtest failure/crash).
  - Verify parameters passed to ObCreateObjectType based on behaviour seen on Windows 2003 (I might've missed some, these are the ones I tested for). This fixes 2 of the kmtest failures.
  - Also make sure the object type's name doesn't have a slash in the name.
  - Also make sure we don't allow creating two object types with the same name.
  - Also use our own local copy of the object name and copy it.

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

Modified: trunk/reactos/ntoskrnl/ob/obhandle.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ob/obhandle.c?rev=22696&r1=22695&r2=22696&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/ob/obhandle.c (original)
+++ trunk/reactos/ntoskrnl/ob/obhandle.c Thu Jun 29 23:03:24 2006
@@ -237,6 +237,8 @@
     ObpDecrementHandleCount(Body, PsGetCurrentProcess(), GrantedAccess);
 
     /* Dereference the object as well */
+    ASSERT(ObjectHeader->Type);
+    ASSERT(ObjectHeader->PointerCount != 0xCCCCCCCC);
     if (!wcscmp(ObjectHeader->Type->Name.Buffer, L"Key"))
     {
         //

Modified: trunk/reactos/ntoskrnl/ob/oblife.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ob/oblife.c?rev=22696&r1=22695&r2=22696&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/ob/oblife.c (original)
+++ trunk/reactos/ntoskrnl/ob/oblife.c Thu Jun 29 23:03:24 2006
@@ -73,7 +73,7 @@
     }
 
     /* Check if a handle database was active */
-    if ((HandleInfo) && (Header->Flags & OB_FLAG_SINGLE_PROCESS))
+    if ((HandleInfo) && !(Header->Flags & OB_FLAG_SINGLE_PROCESS))
     {
         /* Free it */
         ExFreePool(HandleInfo->HandleCountDatabase);
@@ -690,10 +690,69 @@
     NTSTATUS Status;
     CHAR Tag[4];
     OBP_LOOKUP_CONTEXT Context;
+    PWCHAR p;
+    ULONG i;
+    UNICODE_STRING ObjectName;
+
+    /* Verify parameters */
+    if (!(TypeName) ||
+        !(TypeName->Length) ||
+        !(ObjectTypeInitializer) ||
+        (ObjectTypeInitializer->Length != sizeof(*ObjectTypeInitializer)) ||
+        (ObjectTypeInitializer->InvalidAttributes & ~OBJ_VALID_ATTRIBUTES) ||
+        (ObjectTypeInitializer->MaintainHandleCount &&
+         (!(ObjectTypeInitializer->OpenProcedure) &&
+          !ObjectTypeInitializer->CloseProcedure)) ||
+        ((!ObjectTypeInitializer->UseDefaultObject) &&
+         (ObjectTypeInitializer->PoolType != NonPagedPool)))
+    {
+        /* Fail */
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    /* Make sure the name doesn't have a separator */
+    p = TypeName->Buffer;
+    i = TypeName->Length / sizeof(WCHAR);
+    while (i--)
+    {
+        /* Check for one and fail */
+        if (*p++ == OBJ_NAME_PATH_SEPARATOR) return STATUS_OBJECT_NAME_INVALID;
+    }
+
+    /* Check if we've already created the directory of types */
+    if (ObpTypeDirectoryObject)
+    {
+        /* Then scan it to figure out if we've already created this type */
+        Context.Directory = ObpTypeDirectoryObject;
+        Context.DirectoryLocked = TRUE;
+        if (ObpLookupEntryDirectory(ObpTypeDirectoryObject,
+                                    TypeName,
+                                    OBJ_CASE_INSENSITIVE,
+                                    FALSE,
+                                    &Context))
+        {
+            /* We have already created it, so fail */
+            return STATUS_OBJECT_NAME_COLLISION;
+        }
+    }
+
+    /* Now make a copy of the object name */
+    ObjectName.Buffer = ExAllocatePoolWithTag(PagedPool,
+                                              TypeName->MaximumLength,
+                                              OB_NAME_TAG);
+    if (!ObjectName.Buffer)
+    {
+        /* Out of memory, fail */
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    /* Set the length and copy the name */
+    ObjectName.MaximumLength = TypeName->MaximumLength;
+    RtlCopyUnicodeString(&ObjectName, TypeName);
 
     /* Allocate the Object */
     Status = ObpAllocateObject(NULL,
-                               TypeName,
+                               &ObjectName,
                                ObTypeObjectType,
                                sizeof(OBJECT_TYPE) + sizeof(OBJECT_HEADER),
                                KernelMode,
@@ -788,13 +847,6 @@
     if (ObpTypeDirectoryObject)
     {
         /* Insert it into the Object Directory */
-        Context.Directory = ObpTypeDirectoryObject;
-        Context.DirectoryLocked = TRUE;
-        ObpLookupEntryDirectory(ObpTypeDirectoryObject,
-                                TypeName,
-                                OBJ_CASE_INSENSITIVE,
-                                FALSE,
-                                &Context);
         ObpInsertEntryDirectory(ObpTypeDirectoryObject, &Context, Header);
         ObReferenceObject(ObpTypeDirectoryObject);
     }




More information about the Ros-diffs mailing list