mirror of
https://github.com/reactos/reactos.git
synced 2025-08-02 13:16:07 +00:00
- 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:
parent
0817ba9198
commit
453c3d0af0
2 changed files with 81 additions and 64 deletions
|
@ -57,6 +57,9 @@ ObInit(VOID)
|
||||||
/* Initialize the Default Event */
|
/* Initialize the Default Event */
|
||||||
KeInitializeEvent(&ObpDefaultObject, NotificationEvent, TRUE );
|
KeInitializeEvent(&ObpDefaultObject, NotificationEvent, TRUE );
|
||||||
|
|
||||||
|
/* Setup the Object Reaper */
|
||||||
|
ExInitializeWorkItem(&ObpReaperWorkItem, ObpReapObject, NULL);
|
||||||
|
|
||||||
/* Create the Type Type */
|
/* Create the Type Type */
|
||||||
DPRINT("Creating Type Type\n");
|
DPRINT("Creating Type Type\n");
|
||||||
RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
|
RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
|
||||||
|
|
|
@ -398,7 +398,6 @@ ObpCaptureObjectAttributes(IN POBJECT_ATTRIBUTES ObjectAttributes,
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
STDCALL
|
STDCALL
|
||||||
ObpReleaseCapturedAttributes(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo)
|
ObpReleaseCapturedAttributes(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo)
|
||||||
|
@ -414,12 +413,13 @@ ObpReleaseCapturedAttributes(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
STDCALL
|
NTAPI
|
||||||
ObpAllocateObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo,
|
ObpAllocateObject(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo,
|
||||||
PUNICODE_STRING ObjectName,
|
IN PUNICODE_STRING ObjectName,
|
||||||
POBJECT_TYPE ObjectType,
|
IN POBJECT_TYPE ObjectType,
|
||||||
ULONG ObjectSize,
|
IN ULONG ObjectSize,
|
||||||
POBJECT_HEADER *ObjectHeader)
|
IN KPROCESSOR_MODE PreviousMode,
|
||||||
|
IN POBJECT_HEADER *ObjectHeader)
|
||||||
{
|
{
|
||||||
POBJECT_HEADER Header;
|
POBJECT_HEADER Header;
|
||||||
BOOLEAN HasHandleInfo = FALSE;
|
BOOLEAN HasHandleInfo = FALSE;
|
||||||
|
@ -431,9 +431,9 @@ ObpAllocateObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo,
|
||||||
POOL_TYPE PoolType;
|
POOL_TYPE PoolType;
|
||||||
ULONG FinalSize = ObjectSize;
|
ULONG FinalSize = ObjectSize;
|
||||||
ULONG Tag;
|
ULONG Tag;
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
/* If we don't have an Object Type yet, force NonPaged */
|
/* If we don't have an Object Type yet, force NonPaged */
|
||||||
DPRINT("ObpAllocateObject\n");
|
|
||||||
if (!ObjectType)
|
if (!ObjectType)
|
||||||
{
|
{
|
||||||
PoolType = NonPagedPool;
|
PoolType = NonPagedPool;
|
||||||
|
@ -445,7 +445,6 @@ ObpAllocateObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo,
|
||||||
Tag = ObjectType->Key;
|
Tag = ObjectType->Key;
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINT("Checking ObjectName: %x\n", ObjectName);
|
|
||||||
/* Check if the Object has a name */
|
/* Check if the Object has a name */
|
||||||
if (ObjectName->Buffer)
|
if (ObjectName->Buffer)
|
||||||
{
|
{
|
||||||
|
@ -456,7 +455,6 @@ ObpAllocateObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo,
|
||||||
if (ObjectType)
|
if (ObjectType)
|
||||||
{
|
{
|
||||||
/* Check if the Object maintains handle counts */
|
/* Check if the Object maintains handle counts */
|
||||||
DPRINT("Checking ObjectType->TypeInfo: %x\n", &ObjectType->TypeInfo);
|
|
||||||
if (ObjectType->TypeInfo.MaintainHandleCount)
|
if (ObjectType->TypeInfo.MaintainHandleCount)
|
||||||
{
|
{
|
||||||
FinalSize += sizeof(OBJECT_HEADER_HANDLE_INFO);
|
FinalSize += sizeof(OBJECT_HEADER_HANDLE_INFO);
|
||||||
|
@ -472,18 +470,13 @@ ObpAllocateObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate memory for the Object and Header */
|
/* Allocate memory for the Object and Header */
|
||||||
DPRINT("Allocating: %x %x\n", FinalSize, Tag);
|
|
||||||
Header = ExAllocatePoolWithTag(PoolType, FinalSize, Tag);
|
Header = ExAllocatePoolWithTag(PoolType, FinalSize, Tag);
|
||||||
if (!Header) {
|
if (!Header) return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
DPRINT1("Not enough memory!\n");
|
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize Handle Info */
|
/* Initialize Handle Info */
|
||||||
if (HasHandleInfo)
|
if (HasHandleInfo)
|
||||||
{
|
{
|
||||||
HandleInfo = (POBJECT_HEADER_HANDLE_INFO)Header;
|
HandleInfo = (POBJECT_HEADER_HANDLE_INFO)Header;
|
||||||
DPRINT("Info: %x\n", HandleInfo);
|
|
||||||
HandleInfo->SingleEntry.HandleCount = 0;
|
HandleInfo->SingleEntry.HandleCount = 0;
|
||||||
Header = (POBJECT_HEADER)(HandleInfo + 1);
|
Header = (POBJECT_HEADER)(HandleInfo + 1);
|
||||||
}
|
}
|
||||||
|
@ -492,7 +485,6 @@ ObpAllocateObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo,
|
||||||
if (HasNameInfo)
|
if (HasNameInfo)
|
||||||
{
|
{
|
||||||
NameInfo = (POBJECT_HEADER_NAME_INFO)Header;
|
NameInfo = (POBJECT_HEADER_NAME_INFO)Header;
|
||||||
DPRINT("Info: %x %wZ\n", NameInfo, ObjectName);
|
|
||||||
NameInfo->Name = *ObjectName;
|
NameInfo->Name = *ObjectName;
|
||||||
NameInfo->Directory = NULL;
|
NameInfo->Directory = NULL;
|
||||||
Header = (POBJECT_HEADER)(NameInfo + 1);
|
Header = (POBJECT_HEADER)(NameInfo + 1);
|
||||||
|
@ -502,48 +494,56 @@ ObpAllocateObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo,
|
||||||
if (HasCreatorInfo)
|
if (HasCreatorInfo)
|
||||||
{
|
{
|
||||||
CreatorInfo = (POBJECT_HEADER_CREATOR_INFO)Header;
|
CreatorInfo = (POBJECT_HEADER_CREATOR_INFO)Header;
|
||||||
DPRINT("Info: %x\n", CreatorInfo);
|
CreatorInfo->CreatorUniqueProcess = PsGetCurrentProcess() ?
|
||||||
/* FIXME: Needs Alex's Init patch
|
PsGetCurrentProcessId() : 0;
|
||||||
* CreatorInfo->CreatorUniqueProcess = PsGetCurrentProcessId();
|
|
||||||
*/
|
|
||||||
InitializeListHead(&CreatorInfo->TypeList);
|
InitializeListHead(&CreatorInfo->TypeList);
|
||||||
Header = (POBJECT_HEADER)(CreatorInfo + 1);
|
Header = (POBJECT_HEADER)(CreatorInfo + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize the object header */
|
/* Initialize the object header */
|
||||||
RtlZeroMemory(Header, ObjectSize);
|
RtlZeroMemory(Header, ObjectSize);
|
||||||
DPRINT("Initalized header %p\n", Header);
|
|
||||||
Header->HandleCount = 0;
|
|
||||||
Header->PointerCount = 1;
|
Header->PointerCount = 1;
|
||||||
Header->Type = ObjectType;
|
Header->Type = ObjectType;
|
||||||
Header->Flags = OB_FLAG_CREATE_INFO;
|
Header->Flags = OB_FLAG_CREATE_INFO;
|
||||||
|
Header->ObjectCreateInfo = ObjectCreateInfo;
|
||||||
|
|
||||||
/* Set the Offsets for the Info */
|
/* Set the Offsets for the Info */
|
||||||
if (HasHandleInfo)
|
if (HasHandleInfo)
|
||||||
{
|
{
|
||||||
Header->HandleInfoOffset = HasNameInfo * sizeof(OBJECT_HEADER_NAME_INFO) +
|
Header->HandleInfoOffset = HasNameInfo *
|
||||||
|
sizeof(OBJECT_HEADER_NAME_INFO) +
|
||||||
sizeof(OBJECT_HEADER_HANDLE_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;
|
Header->Flags |= OB_FLAG_SINGLE_PROCESS;
|
||||||
}
|
}
|
||||||
if (HasNameInfo)
|
if (HasNameInfo)
|
||||||
{
|
{
|
||||||
Header->NameInfoOffset = sizeof(OBJECT_HEADER_NAME_INFO) +
|
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 (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;
|
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;
|
Header->Flags |= OB_FLAG_EXCLUSIVE;
|
||||||
}
|
}
|
||||||
|
if (PreviousMode == KernelMode)
|
||||||
|
{
|
||||||
|
/* Set the kernel flag */
|
||||||
|
Header->Flags |= OB_FLAG_KERNEL_MODE;
|
||||||
|
}
|
||||||
|
|
||||||
/* Link stuff to Object Header */
|
/* Increase the number of objects of this type */
|
||||||
Header->ObjectCreateInfo = ObjectCreateInfo;
|
if (ObjectType) ObjectType->TotalNumberOfObjects++;
|
||||||
|
|
||||||
/* Return Header */
|
/* Return Header */
|
||||||
*ObjectHeader = Header;
|
*ObjectHeader = Header;
|
||||||
|
@ -560,41 +560,34 @@ ObpCreateTypeObject(POBJECT_TYPE_INITIALIZER ObjectTypeInitializer,
|
||||||
POBJECT_TYPE LocalObjectType;
|
POBJECT_TYPE LocalObjectType;
|
||||||
ULONG HeaderSize;
|
ULONG HeaderSize;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
CHAR Tag[4];
|
||||||
|
OBP_LOOKUP_CONTEXT Context;
|
||||||
|
|
||||||
DPRINT("ObpCreateTypeObject(ObjectType: %wZ)\n", TypeName);
|
|
||||||
|
|
||||||
/* Allocate the Object */
|
/* Allocate the Object */
|
||||||
Status = ObpAllocateObject(NULL,
|
Status = ObpAllocateObject(NULL,
|
||||||
TypeName,
|
TypeName,
|
||||||
ObTypeObjectType,
|
ObTypeObjectType,
|
||||||
sizeof(OBJECT_TYPE) + sizeof(OBJECT_HEADER),
|
sizeof(OBJECT_TYPE) + sizeof(OBJECT_HEADER),
|
||||||
|
KernelMode,
|
||||||
(POBJECT_HEADER*)&Header);
|
(POBJECT_HEADER*)&Header);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status)) return Status;
|
||||||
{
|
|
||||||
DPRINT1("ObpAllocateObject failed!\n");
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
LocalObjectType = (POBJECT_TYPE)&Header->Body;
|
LocalObjectType = (POBJECT_TYPE)&Header->Body;
|
||||||
DPRINT("Local ObjectType: %p Header: %p \n", LocalObjectType, Header);
|
|
||||||
|
|
||||||
/* Check if this is the first Object Type */
|
/* Check if this is the first Object Type */
|
||||||
if (!ObTypeObjectType)
|
if (!ObTypeObjectType)
|
||||||
{
|
{
|
||||||
ObTypeObjectType = LocalObjectType;
|
ObTypeObjectType = LocalObjectType;
|
||||||
Header->Type = ObTypeObjectType;
|
Header->Type = ObTypeObjectType;
|
||||||
|
LocalObjectType->TotalNumberOfObjects = 1;
|
||||||
LocalObjectType->Key = TAG('O', 'b', 'j', 'T');
|
LocalObjectType->Key = TAG('O', 'b', 'j', 'T');
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CHAR Tag[4];
|
/* Set Tag */
|
||||||
Tag[0] = TypeName->Buffer[0];
|
Tag[0] = TypeName->Buffer[0];
|
||||||
Tag[1] = TypeName->Buffer[1];
|
Tag[1] = TypeName->Buffer[1];
|
||||||
Tag[2] = TypeName->Buffer[2];
|
Tag[2] = TypeName->Buffer[2];
|
||||||
Tag[3] = TypeName->Buffer[3];
|
Tag[3] = TypeName->Buffer[3];
|
||||||
|
|
||||||
/* Set Tag */
|
|
||||||
DPRINT("Convert: %s \n", Tag);
|
|
||||||
LocalObjectType->Key = *(PULONG)Tag;
|
LocalObjectType->Key = *(PULONG)Tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -662,7 +655,6 @@ ObpCreateTypeObject(POBJECT_TYPE_INITIALIZER ObjectTypeInitializer,
|
||||||
/* Insert it into the Object Directory */
|
/* Insert it into the Object Directory */
|
||||||
if (ObpTypeDirectoryObject)
|
if (ObpTypeDirectoryObject)
|
||||||
{
|
{
|
||||||
OBP_LOOKUP_CONTEXT Context;
|
|
||||||
Context.Directory = ObpTypeDirectoryObject;
|
Context.Directory = ObpTypeDirectoryObject;
|
||||||
Context.DirectoryLocked = TRUE;
|
Context.DirectoryLocked = TRUE;
|
||||||
ObpLookupEntryDirectory(ObpTypeDirectoryObject,
|
ObpLookupEntryDirectory(ObpTypeDirectoryObject,
|
||||||
|
@ -701,46 +693,68 @@ ObCreateObject(IN KPROCESSOR_MODE ObjectAttributesAccessMode OPTIONAL,
|
||||||
Type, ObjectAttributes, Object);
|
Type, ObjectAttributes, Object);
|
||||||
|
|
||||||
/* Allocate a Buffer for the Object Create Info */
|
/* Allocate a Buffer for the Object Create Info */
|
||||||
DPRINT("Allocating Create Buffer\n");
|
|
||||||
ObjectCreateInfo = ExAllocatePoolWithTag(NonPagedPool,
|
ObjectCreateInfo = ExAllocatePoolWithTag(NonPagedPool,
|
||||||
sizeof(*ObjectCreateInfo),
|
sizeof(*ObjectCreateInfo),
|
||||||
TAG('O','b','C', 'I'));
|
TAG('O','b','C', 'I'));
|
||||||
|
if (!ObjectCreateInfo) return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
/* Capture all the info */
|
/* Capture all the info */
|
||||||
DPRINT("Capturing Create Info\n");
|
|
||||||
Status = ObpCaptureObjectAttributes(ObjectAttributes,
|
Status = ObpCaptureObjectAttributes(ObjectAttributes,
|
||||||
ObjectAttributesAccessMode,
|
ObjectAttributesAccessMode,
|
||||||
Type,
|
Type,
|
||||||
ObjectCreateInfo,
|
ObjectCreateInfo,
|
||||||
&ObjectName);
|
&ObjectName);
|
||||||
|
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
/* Allocate the Object */
|
/* Validate attributes */
|
||||||
DPRINT("Allocating: %wZ\n", &ObjectName);
|
if (Type->TypeInfo.InvalidAttributes &
|
||||||
Status = ObpAllocateObject(ObjectCreateInfo,
|
ObjectCreateInfo->Attributes)
|
||||||
&ObjectName,
|
|
||||||
Type,
|
|
||||||
ObjectSize + sizeof(OBJECT_HEADER),
|
|
||||||
&Header);
|
|
||||||
if (NT_SUCCESS(Status))
|
|
||||||
{
|
{
|
||||||
/* Return the Object */
|
/* Fail */
|
||||||
DPRINT("Returning Object\n");
|
Status = STATUS_INVALID_PARAMETER;
|
||||||
*Object = &Header->Body;
|
}
|
||||||
|
else
|
||||||
/* Return to caller, leave the Capture Info Alive for ObInsert */
|
{
|
||||||
return Status;
|
/* 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 */
|
/* Release the Capture Info, we don't need it */
|
||||||
DPRINT1("Allocation failed\n");
|
|
||||||
ObpReleaseCapturedAttributes(ObjectCreateInfo);
|
ObpReleaseCapturedAttributes(ObjectCreateInfo);
|
||||||
if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
|
if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We failed, so release the Buffer */
|
/* We failed, so release the Buffer */
|
||||||
DPRINT1("Capture failed\n");
|
|
||||||
ExFreePool(ObjectCreateInfo);
|
ExFreePool(ObjectCreateInfo);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue