Author: ion Date: Mon May 29 04:18:36 2006 New Revision: 22099
URL: http://svn.reactos.ru/svn/reactos?rev=22099&view=rev Log: - 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.
Modified: trunk/reactos/ntoskrnl/ob/obinit.c trunk/reactos/ntoskrnl/ob/oblife.c
Modified: trunk/reactos/ntoskrnl/ob/obinit.c URL: http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/ob/obinit.c?rev=220... ============================================================================== --- trunk/reactos/ntoskrnl/ob/obinit.c (original) +++ trunk/reactos/ntoskrnl/ob/obinit.c Mon May 29 04:18:36 2006 @@ -56,6 +56,9 @@
/* 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");
Modified: trunk/reactos/ntoskrnl/ob/oblife.c URL: http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/ob/oblife.c?rev=220... ============================================================================== --- trunk/reactos/ntoskrnl/ob/oblife.c (original) +++ trunk/reactos/ntoskrnl/ob/oblife.c Mon May 29 04:18:36 2006 @@ -398,7 +398,6 @@ return Status; }
- VOID STDCALL ObpReleaseCapturedAttributes(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo) @@ -414,12 +413,13 @@ }
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 @@ 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 @@ Tag = ObjectType->Key; }
- DPRINT("Checking ObjectName: %x\n", ObjectName); /* Check if the Object has a name */ if (ObjectName->Buffer) { @@ -456,7 +455,6 @@ 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 @@ }
/* 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 @@ 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 @@ 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; } - - /* Link stuff to Object Header */ - Header->ObjectCreateInfo = ObjectCreateInfo; + if (PreviousMode == KernelMode) + { + /* Set the kernel flag */ + Header->Flags |= OB_FLAG_KERNEL_MODE; + } + + /* Increase the number of objects of this type */ + if (ObjectType) ObjectType->TotalNumberOfObjects++;
/* Return Header */ *ObjectHeader = Header; @@ -560,41 +560,34 @@ 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 @@ /* Insert it into the Object Directory */ if (ObpTypeDirectoryObject) { - OBP_LOOKUP_CONTEXT Context; Context.Directory = ObpTypeDirectoryObject; Context.DirectoryLocked = TRUE; ObpLookupEntryDirectory(ObpTypeDirectoryObject, @@ -701,46 +693,68 @@ 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)) { - /* Allocate the Object */ - DPRINT("Allocating: %wZ\n", &ObjectName); - Status = ObpAllocateObject(ObjectCreateInfo, - &ObjectName, - Type, - ObjectSize + sizeof(OBJECT_HEADER), - &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 */ - return 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 */ + 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 */ - 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; }