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=... ============================================================================== --- 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=22... ============================================================================== --- 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); }