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

svn path=/trunk/; revision=22099
This commit is contained in:
Alex Ionescu 2006-05-29 00:18:36 +00:00
parent 0817ba9198
commit 453c3d0af0
2 changed files with 81 additions and 64 deletions

View file

@ -57,6 +57,9 @@ ObInit(VOID)
/* 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");
RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));

View file

@ -398,7 +398,6 @@ ObpCaptureObjectAttributes(IN POBJECT_ATTRIBUTES ObjectAttributes,
return Status;
}
VOID
STDCALL
ObpReleaseCapturedAttributes(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo)
@ -414,12 +413,13 @@ ObpReleaseCapturedAttributes(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo)
}
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 @@ ObpAllocateObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo,
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 @@ ObpAllocateObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo,
Tag = ObjectType->Key;
}
DPRINT("Checking ObjectName: %x\n", ObjectName);
/* Check if the Object has a name */
if (ObjectName->Buffer)
{
@ -456,7 +455,6 @@ ObpAllocateObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo,
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 @@ ObpAllocateObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo,
}
/* 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 @@ ObpAllocateObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo,
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 @@ ObpAllocateObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo,
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;
}
if (PreviousMode == KernelMode)
{
/* Set the kernel flag */
Header->Flags |= OB_FLAG_KERNEL_MODE;
}
/* Link stuff to Object Header */
Header->ObjectCreateInfo = ObjectCreateInfo;
/* Increase the number of objects of this type */
if (ObjectType) ObjectType->TotalNumberOfObjects++;
/* Return Header */
*ObjectHeader = Header;
@ -560,41 +560,34 @@ ObpCreateTypeObject(POBJECT_TYPE_INITIALIZER ObjectTypeInitializer,
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 @@ ObpCreateTypeObject(POBJECT_TYPE_INITIALIZER ObjectTypeInitializer,
/* Insert it into the Object Directory */
if (ObpTypeDirectoryObject)
{
OBP_LOOKUP_CONTEXT Context;
Context.Directory = ObpTypeDirectoryObject;
Context.DirectoryLocked = TRUE;
ObpLookupEntryDirectory(ObpTypeDirectoryObject,
@ -701,46 +693,68 @@ ObCreateObject(IN KPROCESSOR_MODE ObjectAttributesAccessMode OPTIONAL,
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))
{
/* 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 */
DPRINT("Allocating: %wZ\n", &ObjectName);
Status = ObpAllocateObject(ObjectCreateInfo,
&ObjectName,
Type,
ObjectSize + sizeof(OBJECT_HEADER),
AccessMode,
&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 */
/* 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;
}