- 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.

svn path=/trunk/; revision=22696
This commit is contained in:
Alex Ionescu 2006-06-29 19:03:24 +00:00
parent 3dd2bff814
commit 4c630fdc31
2 changed files with 63 additions and 9 deletions

View file

@ -237,6 +237,8 @@ ObpCloseHandleTableEntry(IN PHANDLE_TABLE HandleTable,
ObpDecrementHandleCount(Body, PsGetCurrentProcess(), GrantedAccess);
/* Dereference the object as well */
ASSERT(ObjectHeader->Type);
ASSERT(ObjectHeader->PointerCount != 0xCCCCCCCC);
if (!wcscmp(ObjectHeader->Type->Name.Buffer, L"Key"))
{
//

View file

@ -73,7 +73,7 @@ ObpDeallocateObject(IN PVOID Object)
}
/* 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 @@ ObCreateObjectType(IN PUNICODE_STRING TypeName,
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 @@ ObCreateObjectType(IN PUNICODE_STRING TypeName,
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);
}