diff --git a/reactos/ntoskrnl/ex/init.c b/reactos/ntoskrnl/ex/init.c index 1feb2e8e07e..1866d407df2 100644 --- a/reactos/ntoskrnl/ex/init.c +++ b/reactos/ntoskrnl/ex/init.c @@ -425,7 +425,7 @@ ExpLoadInitialProcess(IN PHANDLE ProcessHandle, /* Create the environment string */ RtlInitEmptyUnicodeString(&Environment, ProcessParameters->Environment, - Size); + (USHORT)Size); /* Append the DLL path to it */ RtlAppendUnicodeToString(&Environment, L"Path=" ); diff --git a/reactos/ntoskrnl/include/internal/ob.h b/reactos/ntoskrnl/include/internal/ob.h index 2c09fd287a3..0052e69d8cd 100644 --- a/reactos/ntoskrnl/include/internal/ob.h +++ b/reactos/ntoskrnl/include/internal/ob.h @@ -112,8 +112,8 @@ ObpLookupEntryDirectory( // VOID NTAPI -ObInitSymbolicLinkImplementation( - VOID +ObpDeleteSymbolicLink( + IN PVOID ObjectBody ); NTSTATUS @@ -219,17 +219,6 @@ ObpReapObject( IN PVOID Unused ); -VOID -NTAPI -ObDereferenceDeviceMap(IN PEPROCESS Process); - -VOID -NTAPI -ObInheritDeviceMap( - IN PEPROCESS Parent, - IN PEPROCESS Process -); - VOID FASTCALL ObpSetPermanentObject( @@ -245,10 +234,35 @@ ObpDeleteNameCheck( VOID NTAPI -ObClearProcessHandleTable(IN PEPROCESS Process); +ObClearProcessHandleTable( + IN PEPROCESS Process +); -/* Security descriptor cache functions */ +// +// DOS Devices Functions +// +VOID +NTAPI +ObDereferenceDeviceMap( + IN PEPROCESS Process +); +VOID +NTAPI +ObInheritDeviceMap( + IN PEPROCESS Parent, + IN PEPROCESS Process +); + +NTSTATUS +NTAPI +ObpCreateDosDevicesDirectory( + VOID +); + +// +// Security descriptor cache functions +// NTSTATUS NTAPI ObpInitSdCache( diff --git a/reactos/ntoskrnl/ob/obinit.c b/reactos/ntoskrnl/ob/obinit.c index 718ad309192..395b867fbbe 100644 --- a/reactos/ntoskrnl/ob/obinit.c +++ b/reactos/ntoskrnl/ob/obinit.c @@ -37,6 +37,14 @@ GENERIC_MAPPING ObpDirectoryMapping = DIRECTORY_ALL_ACCESS }; +GENERIC_MAPPING ObpSymbolicLinkMapping = +{ + STANDARD_RIGHTS_READ | SYMBOLIC_LINK_QUERY, + STANDARD_RIGHTS_WRITE, + STANDARD_RIGHTS_EXECUTE | SYMBOLIC_LINK_QUERY, + SYMBOLIC_LINK_ALL_ACCESS +}; + PDEVICE_MAP ObSystemDeviceMap = NULL; ULONG ObpTraceLevel = OB_HANDLE_DEBUG | OB_REFERENCE_DEBUG; @@ -124,12 +132,15 @@ ObInit(VOID) { OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING Name; - SECURITY_DESCRIPTOR SecurityDescriptor; OBJECT_TYPE_INITIALIZER ObjectTypeInitializer; OBP_LOOKUP_CONTEXT Context; - UNICODE_STRING LinkName = RTL_CONSTANT_STRING(L"\\DosDevices"); HANDLE Handle; PKPRCB Prcb = KeGetCurrentPrcb(); + PLIST_ENTRY ListHead, NextEntry; + POBJECT_HEADER Header; + POBJECT_HEADER_CREATOR_INFO CreatorInfo; + POBJECT_HEADER_NAME_INFO NameInfo; + NTSTATUS Status; /* Check if this is actually Phase 1 initialization */ if (ObpInitializationPhase != 0) goto ObPostPhase0; @@ -184,12 +195,11 @@ ObInit(VOID) ObjectTypeInitializer.PoolType = NonPagedPool; ObjectTypeInitializer.GenericMapping = ObpTypeMapping; ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(OBJECT_TYPE); + ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK; ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &ObTypeObjectType); /* Create the Directory Type */ - RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer)); RtlInitUnicodeString(&Name, L"Directory"); - ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer); ObjectTypeInitializer.ValidAccessMask = DIRECTORY_ALL_ACCESS; ObjectTypeInitializer.UseDefaultObject = FALSE; ObjectTypeInitializer.MaintainTypeList = FALSE; @@ -197,6 +207,16 @@ ObInit(VOID) ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(OBJECT_DIRECTORY); ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &ObDirectoryType); + /* Create 'symbolic link' object type */ + RtlInitUnicodeString(&Name, L"SymbolicLink"); + ObjectTypeInitializer.DefaultNonPagedPoolCharge = + sizeof(OBJECT_SYMBOLIC_LINK); + ObjectTypeInitializer.GenericMapping = ObpSymbolicLinkMapping; + ObjectTypeInitializer.ValidAccessMask = SYMBOLIC_LINK_ALL_ACCESS; + ObjectTypeInitializer.ParseProcedure = ObpParseSymbolicLink; + ObjectTypeInitializer.DeleteProcedure = ObpDeleteSymbolicLink; + ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &ObSymbolicLinkType); + /* Phase 0 initialization complete */ ObpInitializationPhase++; return TRUE; @@ -206,105 +226,102 @@ ObPostPhase0: /* Re-initialize lookaside lists */ ObInit2(); - /* Create security descriptor */ - RtlCreateSecurityDescriptor(&SecurityDescriptor, - SECURITY_DESCRIPTOR_REVISION1); - RtlSetOwnerSecurityDescriptor(&SecurityDescriptor, - SeAliasAdminsSid, - FALSE); - RtlSetGroupSecurityDescriptor(&SecurityDescriptor, - SeLocalSystemSid, - FALSE); - RtlSetDaclSecurityDescriptor(&SecurityDescriptor, - TRUE, - SePublicDefaultDacl, - FALSE); - - /* Create root directory */ + /* Initialize Object Types directory attributes */ + RtlInitUnicodeString(&Name, L"\\"); InitializeObjectAttributes(&ObjectAttributes, + &Name, + OBJ_CASE_INSENSITIVE | OBJ_PERMANENT, NULL, - OBJ_PERMANENT, - NULL, - &SecurityDescriptor); - ObCreateObject(KernelMode, - ObDirectoryType, - &ObjectAttributes, - KernelMode, - NULL, - sizeof(OBJECT_DIRECTORY), - 0, - 0, - (PVOID*)&NameSpaceRoot); - ObInsertObject((PVOID)NameSpaceRoot, - NULL, - DIRECTORY_ALL_ACCESS, - 0, - NULL, - NULL); + SePublicDefaultUnrestrictedSd); - /* Create '\ObjectTypes' directory */ + /* Create the directory */ + Status = NtCreateDirectoryObject(&Handle, + DIRECTORY_ALL_ACCESS, + &ObjectAttributes); + if (!NT_SUCCESS(Status)) return FALSE; + + /* Get a handle to it */ + Status = ObReferenceObjectByHandle(Handle, + 0, + ObDirectoryType, + KernelMode, + (PVOID*)&NameSpaceRoot, + NULL); + if (!NT_SUCCESS(Status)) return FALSE; + + /* Close the extra handle */ + Status = NtClose(Handle); + if (!NT_SUCCESS(Status)) return FALSE; + + /* Initialize Object Types directory attributes */ RtlInitUnicodeString(&Name, L"\\ObjectTypes"); InitializeObjectAttributes(&ObjectAttributes, &Name, - OBJ_PERMANENT, - NULL, - &SecurityDescriptor); - ObCreateObject(KernelMode, - ObDirectoryType, - &ObjectAttributes, - KernelMode, - NULL, - sizeof(OBJECT_DIRECTORY), - 0, - 0, - (PVOID*)&ObpTypeDirectoryObject); - ObInsertObject((PVOID)ObpTypeDirectoryObject, - NULL, - DIRECTORY_ALL_ACCESS, - 0, - NULL, - NULL); - - /* Insert the two objects we already created but couldn't add */ - /* NOTE: Uses TypeList & Creator Info in OB 2.0 */ - Context.Directory = ObpTypeDirectoryObject; - Context.DirectoryLocked = TRUE; - if (!ObpLookupEntryDirectory(ObpTypeDirectoryObject, - &OBJECT_HEADER_TO_NAME_INFO(OBJECT_TO_OBJECT_HEADER(ObTypeObjectType))->Name, - OBJ_CASE_INSENSITIVE, - FALSE, - &Context)) - { - ObpInsertEntryDirectory(ObpTypeDirectoryObject, &Context, OBJECT_TO_OBJECT_HEADER(ObTypeObjectType)); - } - if (!ObpLookupEntryDirectory(ObpTypeDirectoryObject, - &OBJECT_HEADER_TO_NAME_INFO(OBJECT_TO_OBJECT_HEADER(ObDirectoryType))->Name, - OBJ_CASE_INSENSITIVE, - FALSE, - &Context)) - { - ObpInsertEntryDirectory(ObpTypeDirectoryObject, &Context, OBJECT_TO_OBJECT_HEADER(ObDirectoryType)); - } - - /* Create 'symbolic link' object type */ - ObInitSymbolicLinkImplementation(); - - /* Create the '\??' directory */ - RtlInitUnicodeString(&Name, L"\\??"); - InitializeObjectAttributes(&ObjectAttributes, - &Name, - 0, + OBJ_CASE_INSENSITIVE | OBJ_PERMANENT, NULL, NULL); - ZwCreateDirectoryObject(&Handle, 0, &ObjectAttributes); - /* Create link from '\DosDevices' to '\??' directory */ - RtlInitUnicodeString(&Name, L"\\??"); - IoCreateSymbolicLink(&LinkName, &Name); + /* Create the directory */ + Status = NtCreateDirectoryObject(&Handle, + DIRECTORY_ALL_ACCESS, + &ObjectAttributes); + if (!NT_SUCCESS(Status)) return FALSE; - /* FIXME: Hack Hack! */ - ObSystemDeviceMap = ExAllocatePoolWithTag(NonPagedPool, sizeof(*ObSystemDeviceMap), TAG('O', 'b', 'D', 'm')); - RtlZeroMemory(ObSystemDeviceMap, sizeof(*ObSystemDeviceMap)); + /* Get a handle to it */ + Status = ObReferenceObjectByHandle(Handle, + 0, + ObDirectoryType, + KernelMode, + (PVOID*)&ObpTypeDirectoryObject, + NULL); + if (!NT_SUCCESS(Status)) return FALSE; + + /* Close the extra handle */ + Status = NtClose(Handle); + if (!NT_SUCCESS(Status)) return FALSE; + + /* Loop the object types */ + ListHead = &ObTypeObjectType->TypeList; + NextEntry = ListHead->Flink; + while (ListHead != NextEntry) + { + /* Get the creator info from the list */ + CreatorInfo = CONTAINING_RECORD(NextEntry, + OBJECT_HEADER_CREATOR_INFO, + TypeList); + + /* Recover the header and the name header from the creator info */ + Header = (POBJECT_HEADER)(CreatorInfo + 1); + NameInfo = OBJECT_HEADER_TO_NAME_INFO(Header); + + /* Make sure we have a name, and aren't inserted yet */ + if ((NameInfo) && !(NameInfo->Directory)) + { + /* Set up the context for the insert */ + Context.Directory = ObpTypeDirectoryObject; + Context.DirectoryLocked = TRUE; + + /* Do the initial lookup to setup the context */ + if (!ObpLookupEntryDirectory(ObpTypeDirectoryObject, + &NameInfo->Name, + OBJ_CASE_INSENSITIVE, + FALSE, + &Context)) + { + /* Insert this object type */ + ObpInsertEntryDirectory(ObpTypeDirectoryObject, + &Context, + Header); + } + } + + /* Move to the next entry */ + NextEntry = NextEntry->Flink; + } + + /* Initialize DOS Devices Directory and related Symbolic Links */ + Status = ObpCreateDosDevicesDirectory(); + if (!NT_SUCCESS(Status)) return FALSE; return TRUE; } diff --git a/reactos/ntoskrnl/ob/oblife.c b/reactos/ntoskrnl/ob/oblife.c index a6b06e026cb..acb86664f30 100644 --- a/reactos/ntoskrnl/ob/oblife.c +++ b/reactos/ntoskrnl/ob/oblife.c @@ -27,6 +27,10 @@ NPAGED_LOOKASIDE_LIST ObpNmLookasideList, ObpCiLookasideList; WORK_QUEUE_ITEM ObpReaperWorkItem; volatile PVOID ObpReaperList; +ULONG ObpObjectsCreated, ObpObjectsWithName, ObpObjectsWithPoolQuota; +ULONG ObpObjectsWithHandleDB, ObpObjectsWithCreatorInfo; +POBJECT_TYPE ObpObjectTypes[32]; + /* PRIVATE FUNCTIONS *********************************************************/ VOID @@ -39,6 +43,8 @@ ObpDeallocateObject(IN PVOID Object) POBJECT_HEADER_HANDLE_INFO HandleInfo; POBJECT_HEADER_NAME_INFO NameInfo; POBJECT_HEADER_CREATOR_INFO CreatorInfo; + POBJECT_HEADER_QUOTA_INFO QuotaInfo; + ULONG PagedPoolCharge, NonPagedPoolCharge; PAGED_CODE(); /* Get the header and assume this is what we'll free */ @@ -59,6 +65,13 @@ ObpDeallocateObject(IN PVOID Object) { HeaderLocation = HandleInfo; } + if ((QuotaInfo = OBJECT_HEADER_TO_QUOTA_INFO(Header))) + { + HeaderLocation = QuotaInfo; + } + + /* Decrease the total */ + InterlockedDecrement(&ObjectType->TotalNumberOfObjects); /* Check if we have create info */ if (Header->Flags & OB_FLAG_CREATE_INFO) @@ -71,6 +84,34 @@ ObpDeallocateObject(IN PVOID Object) Header->ObjectCreateInfo = NULL; } } + else + { + /* Check if it has a quota block */ + if (Header->QuotaBlockCharged) + { + /* Check if we have quota information */ + if (QuotaInfo) + { + /* Get charges from quota information */ + PagedPoolCharge = QuotaInfo->PagedPoolCharge + + QuotaInfo->SecurityDescriptorCharge; + NonPagedPoolCharge = QuotaInfo->NonPagedPoolCharge; + } + else + { + /* Get charges from object type */ + PagedPoolCharge = ObjectType->TypeInfo.DefaultPagedPoolCharge; + NonPagedPoolCharge = ObjectType-> + TypeInfo.DefaultNonPagedPoolCharge; + + /* Add the SD charge too */ + if (Header->Flags & OB_FLAG_SECURITY) PagedPoolCharge += 2000; + } + + /* FIXME: Should be returning quota */ + DPRINT("Quotas: %lx %lx\n", PagedPoolCharge, NonPagedPoolCharge); + } + } /* Check if a handle database was active */ if ((HandleInfo) && !(Header->Flags & OB_FLAG_SINGLE_PROCESS)) @@ -89,11 +130,7 @@ ObpDeallocateObject(IN PVOID Object) } /* Free the object using the same allocation tag */ - ExFreePoolWithTag(HeaderLocation, - ObjectType ? TAG('T', 'j', 'b', 'O') : ObjectType->Key); - - /* Decrease the total */ - ObjectType->TotalNumberOfObjects--; + ExFreePoolWithTag(HeaderLocation, ObjectType->Key); } VOID @@ -134,6 +171,7 @@ ObpDeleteObject(IN PVOID Object) /* Check if we have a security descriptor */ if (Header->SecurityDescriptor) { + /* Call the security procedure to delete it */ ObjectType->TypeInfo.SecurityProcedure(Object, DeleteSecurityDescriptor, 0, @@ -247,9 +285,7 @@ ObpCaptureObjectName(IN OUT PUNICODE_STRING CapturedName, /* First Probe the String */ ProbeForReadUnicodeString(ObjectName); LocalName = *ObjectName; - ProbeForRead(LocalName.Buffer, - LocalName.Length, - sizeof(WCHAR)); + ProbeForRead(LocalName.Buffer, LocalName.Length, sizeof(WCHAR)); } else { @@ -311,6 +347,7 @@ ObpCaptureObjectName(IN OUT PUNICODE_STRING CapturedName, } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) { + /* Handle exception and free the string buffer */ Status = _SEH_GetExceptionCode(); if (StringBuffer) ExFreePool(StringBuffer); } @@ -461,59 +498,125 @@ ObpAllocateObject(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo, IN POBJECT_HEADER *ObjectHeader) { POBJECT_HEADER Header; - BOOLEAN HasHandleInfo = FALSE; - BOOLEAN HasNameInfo = FALSE; - BOOLEAN HasCreatorInfo = FALSE; + ULONG QuotaSize, HandleSize, NameSize, CreatorSize; POBJECT_HEADER_HANDLE_INFO HandleInfo; POBJECT_HEADER_NAME_INFO NameInfo; POBJECT_HEADER_CREATOR_INFO CreatorInfo; + POBJECT_HEADER_QUOTA_INFO QuotaInfo; POOL_TYPE PoolType; - ULONG FinalSize = ObjectSize; + ULONG FinalSize; ULONG Tag; PAGED_CODE(); - /* If we don't have an Object Type yet, force NonPaged */ - if (!ObjectType) + /* Accounting */ + ObpObjectsCreated++; + + /* Check if we don't have an Object Type yet */ + if (!ObjectType) { + /* Use default tag and non-paged pool */ PoolType = NonPagedPool; Tag = TAG('O', 'b', 'j', 'T'); } else { + /* Use the pool and tag given */ PoolType = ObjectType->TypeInfo.PoolType; Tag = ObjectType->Key; } - /* Check if the Object has a name */ - if (ObjectName->Buffer) + /* Check if we have no create information (ie: we're an object type) */ + if (!ObjectCreateInfo) { - FinalSize += sizeof(OBJECT_HEADER_NAME_INFO); - HasNameInfo = TRUE; + /* Use defaults */ + QuotaSize = HandleSize = 0; + NameSize = sizeof(OBJECT_HEADER_NAME_INFO); + CreatorSize = sizeof(OBJECT_HEADER_CREATOR_INFO); } - - if (ObjectType) + else { - /* Check if the Object maintains handle counts */ + /* Check if we have quota */ + if ((ObjectCreateInfo->PagedPoolCharge != + ObjectType->TypeInfo.DefaultPagedPoolCharge) || + (ObjectCreateInfo->NonPagedPoolCharge != + ObjectType->TypeInfo.DefaultNonPagedPoolCharge) || + (ObjectCreateInfo->SecurityDescriptorCharge > 2000) || + (ObjectCreateInfo->Attributes & OBJ_EXCLUSIVE)) + { + /* Set quota size */ + QuotaSize = sizeof(OBJECT_HEADER_QUOTA_INFO); + ObpObjectsWithPoolQuota++; + } + else + { + /* No Quota */ + QuotaSize = 0; + } + + /* Check if we have a handle database */ if (ObjectType->TypeInfo.MaintainHandleCount) { - FinalSize += sizeof(OBJECT_HEADER_HANDLE_INFO); - HasHandleInfo = TRUE; + /* Set handle database size */ + HandleSize = sizeof(OBJECT_HEADER_HANDLE_INFO); + ObpObjectsWithHandleDB++; } - - /* Check if the Object maintains type lists */ - if (ObjectType->TypeInfo.MaintainTypeList) + else { - FinalSize += sizeof(OBJECT_HEADER_CREATOR_INFO); - HasCreatorInfo = TRUE; + /* None */ + HandleSize = 0; + } + + /* Check if the Object has a name */ + if (ObjectName->Buffer) + { + /* Set name size */ + NameSize = sizeof(OBJECT_HEADER_NAME_INFO); + ObpObjectsWithName++; + } + else + { + /* No name */ + NameSize = 0; + } + + /* Check if the Object maintains type lists */ + if (ObjectType->TypeInfo.MaintainTypeList) + { + /* Set owner/creator size */ + CreatorSize = sizeof(OBJECT_HEADER_CREATOR_INFO); + ObpObjectsWithCreatorInfo++; + } + else + { + /* No info */ + CreatorSize = 0; } } + /* Set final header size */ + FinalSize = QuotaSize + + HandleSize + + NameSize + + CreatorSize + + FIELD_OFFSET(OBJECT_HEADER, Body); + /* Allocate memory for the Object and Header */ - Header = ExAllocatePoolWithTag(PoolType, FinalSize, Tag); + Header = ExAllocatePoolWithTag(PoolType, FinalSize + ObjectSize, Tag); if (!Header) return STATUS_INSUFFICIENT_RESOURCES; + /* Initialize quota info */ + if (QuotaSize) + { + QuotaInfo = (POBJECT_HEADER_QUOTA_INFO)Header; + QuotaInfo->PagedPoolCharge = ObjectCreateInfo->PagedPoolCharge; + QuotaInfo->NonPagedPoolCharge = ObjectCreateInfo->NonPagedPoolCharge; + QuotaInfo->SecurityDescriptorCharge = ObjectCreateInfo->SecurityDescriptorCharge; + QuotaInfo->ExclusiveProcess = NULL; + Header = (POBJECT_HEADER)(QuotaInfo + 1); + } + /* Initialize Handle Info */ - if (HasHandleInfo) + if (HandleSize) { HandleInfo = (POBJECT_HEADER_HANDLE_INFO)Header; HandleInfo->SingleEntry.HandleCount = 0; @@ -521,7 +624,7 @@ ObpAllocateObject(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo, } /* Initialize the Object Name Info */ - if (HasNameInfo) + if (NameSize) { NameInfo = (POBJECT_HEADER_NAME_INFO)Header; NameInfo->Name = *ObjectName; @@ -530,59 +633,104 @@ ObpAllocateObject(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo, } /* Initialize Creator Info */ - if (HasCreatorInfo) + if (CreatorSize) { CreatorInfo = (POBJECT_HEADER_CREATOR_INFO)Header; - CreatorInfo->CreatorUniqueProcess = PsGetCurrentProcess() ? - PsGetCurrentProcessId() : 0; + CreatorInfo->CreatorBackTraceIndex = 0; + CreatorInfo->CreatorUniqueProcess = PsGetCurrentProcessId(); InitializeListHead(&CreatorInfo->TypeList); Header = (POBJECT_HEADER)(CreatorInfo + 1); } - /* Initialize the object header */ - RtlZeroMemory(Header, ObjectSize); - Header->PointerCount = 1; - Header->Type = ObjectType; + /* Check for quota information */ + if (QuotaSize) + { + /* Set the offset */ + Header->QuotaInfoOffset = (UCHAR)(QuotaSize + + HandleSize + + NameSize + + CreatorSize); + } + else + { + /* No offset */ + Header->QuotaInfoOffset = 0; + } + + /* Check for handle information */ + if (HandleSize) + { + /* Set the offset */ + Header->HandleInfoOffset = (UCHAR)(HandleSize + + NameSize + + CreatorSize); + } + else + { + /* No offset */ + Header->HandleInfoOffset = 0; + } + + /* Check for name information */ + if (NameSize) + { + /* Set the offset */ + Header->NameInfoOffset = (UCHAR)(NameSize + CreatorSize); + } + else + { + /* No Name */ + Header->NameInfoOffset = 0; + } + + /* Set the new object flag */ Header->Flags = OB_FLAG_CREATE_INFO; + + /* Remember if we have creator info */ + if (CreatorSize) Header->Flags |= OB_FLAG_CREATOR_INFO; + + /* Remember if we have handle info */ + if (HandleSize) Header->Flags |= OB_FLAG_SINGLE_PROCESS; + + /* Initialize the object header */ + Header->PointerCount = 1; + Header->HandleCount = 0; + Header->Type = ObjectType; Header->ObjectCreateInfo = ObjectCreateInfo; + Header->SecurityDescriptor = NULL; - /* Set the Offsets for the Info */ - if (HasHandleInfo) - { - Header->HandleInfoOffset = HasNameInfo * - sizeof(OBJECT_HEADER_NAME_INFO) + - sizeof(OBJECT_HEADER_HANDLE_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); - } - if (HasCreatorInfo) Header->Flags |= OB_FLAG_CREATOR_INFO; + /* Check if this is a permanent object */ if ((ObjectCreateInfo) && (ObjectCreateInfo->Attributes & OBJ_PERMANENT)) { /* Set the needed flag so we can check */ Header->Flags |= OB_FLAG_PERMANENT; } + + /* Check if this is an exclusive object */ if ((ObjectCreateInfo) && (ObjectCreateInfo->Attributes & OBJ_EXCLUSIVE)) { /* Set the needed flag so we can check */ Header->Flags |= OB_FLAG_EXCLUSIVE; } - if (PreviousMode == KernelMode) + + /* Set kernel-mode flag */ + if (PreviousMode == KernelMode) Header->Flags |= OB_FLAG_KERNEL_MODE; + + /* Check if we have a type */ + if (ObjectType) { - /* Set the kernel flag */ - Header->Flags |= OB_FLAG_KERNEL_MODE; + /* Increase the number of objects of this type */ + ObjectType->TotalNumberOfObjects++; + + /* Update the high water */ + ObjectType->HighWaterNumberOfObjects = max(ObjectType-> + TotalNumberOfObjects, + ObjectType-> + HighWaterNumberOfObjects); } - /* Increase the number of objects of this type */ - if (ObjectType) ObjectType->TotalNumberOfObjects++; + /* OMG-Hack-Of-Doom */ + RtlZeroMemory(&Header->Body, ObjectSize); /* Return Header */ *ObjectHeader = Header; @@ -593,7 +741,7 @@ ObpAllocateObject(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo, NTSTATUS NTAPI -ObCreateObject(IN KPROCESSOR_MODE ObjectAttributesAccessMode OPTIONAL, +ObCreateObject(IN KPROCESSOR_MODE ProbeMode OPTIONAL, IN POBJECT_TYPE Type, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN KPROCESSOR_MODE AccessMode, @@ -616,22 +764,36 @@ ObCreateObject(IN KPROCESSOR_MODE ObjectAttributesAccessMode OPTIONAL, /* Capture all the info */ Status = ObpCaptureObjectAttributes(ObjectAttributes, - ObjectAttributesAccessMode, + ProbeMode, FALSE, ObjectCreateInfo, &ObjectName); if (NT_SUCCESS(Status)) { /* Validate attributes */ - if (Type->TypeInfo.InvalidAttributes & - ObjectCreateInfo->Attributes) + if (Type->TypeInfo.InvalidAttributes & ObjectCreateInfo->Attributes) { /* Fail */ Status = STATUS_INVALID_PARAMETER; } else { - /* Save the pool charges */ + /* Check if we have a paged charge */ + if (!PagedPoolCharge) + { + /* Save it */ + PagedPoolCharge = ObjectType->TypeInfo.DefaultPagedPoolCharge; + } + + /* Check for nonpaged charge */ + if (!NonPagedPoolCharge) + { + /* Save it */ + NonPagedPoolCharge = ObjectType-> + TypeInfo.DefaultNonPagedPoolCharge; + } + + /* Write the pool charges */ ObjectCreateInfo->PagedPoolCharge = PagedPoolCharge; ObjectCreateInfo->NonPagedPoolCharge = NonPagedPoolCharge; @@ -639,7 +801,7 @@ ObCreateObject(IN KPROCESSOR_MODE ObjectAttributesAccessMode OPTIONAL, Status = ObpAllocateObject(ObjectCreateInfo, &ObjectName, Type, - ObjectSize + sizeof(OBJECT_HEADER), + ObjectSize, AccessMode, &Header); if (NT_SUCCESS(Status)) @@ -652,7 +814,7 @@ ObCreateObject(IN KPROCESSOR_MODE ObjectAttributesAccessMode OPTIONAL, { /* Do the privilege check */ if (!SeSinglePrivilegeCheck(SeCreatePermanentPrivilege, - ObjectAttributesAccessMode)) + ProbeMode)) { /* Fail */ ObpDeallocateObject(*Object); @@ -691,6 +853,7 @@ ObCreateObjectType(IN PUNICODE_STRING TypeName, PWCHAR p; ULONG i; UNICODE_STRING ObjectName; + POBJECT_HEADER_CREATOR_INFO CreatorInfo; /* Verify parameters */ if (!(TypeName) || @@ -752,7 +915,7 @@ ObCreateObjectType(IN PUNICODE_STRING TypeName, Status = ObpAllocateObject(NULL, &ObjectName, ObTypeObjectType, - sizeof(OBJECT_TYPE) + sizeof(OBJECT_HEADER), + sizeof(OBJECT_TYPE), KernelMode, (POBJECT_HEADER*)&Header); if (!NT_SUCCESS(Status)) @@ -767,21 +930,30 @@ ObCreateObjectType(IN PUNICODE_STRING TypeName, LocalObjectType->Name = ObjectName; Header->Flags |= OB_FLAG_KERNEL_MODE | OB_FLAG_PERMANENT; + /* Clear accounting data */ + LocalObjectType->TotalNumberOfObjects = + LocalObjectType->TotalNumberOfHandles = + LocalObjectType->HighWaterNumberOfObjects = + LocalObjectType->HighWaterNumberOfHandles = 0; + /* Check if this is the first Object Type */ if (!ObTypeObjectType) { + /* It is, so set this as the type object */ ObTypeObjectType = LocalObjectType; Header->Type = ObTypeObjectType; + + /* Set the hard-coded key and object count */ LocalObjectType->TotalNumberOfObjects = 1; LocalObjectType->Key = TAG('O', 'b', 'j', 'T'); } else { /* Set Tag */ - Tag[0] = TypeName->Buffer[0]; - Tag[1] = TypeName->Buffer[1]; - Tag[2] = TypeName->Buffer[2]; - Tag[3] = TypeName->Buffer[3]; + Tag[0] = (CHAR)TypeName->Buffer[0]; + Tag[1] = (CHAR)TypeName->Buffer[1]; + Tag[2] = (CHAR)TypeName->Buffer[2]; + Tag[3] = (CHAR)TypeName->Buffer[3]; LocalObjectType->Key = *(PULONG)Tag; } @@ -797,9 +969,10 @@ ObCreateObjectType(IN PUNICODE_STRING TypeName, } /* Calculate how much space our header'll take up */ - HeaderSize = sizeof(OBJECT_HEADER) + sizeof(OBJECT_HEADER_NAME_INFO) + + HeaderSize = sizeof(OBJECT_HEADER) + + sizeof(OBJECT_HEADER_NAME_INFO) + (ObjectTypeInitializer->MaintainHandleCount ? - sizeof(OBJECT_HEADER_HANDLE_INFO) : 0); + sizeof(OBJECT_HEADER_HANDLE_INFO) : 0); /* Check the pool type */ if (ObjectTypeInitializer->PoolType == NonPagedPool) @@ -846,17 +1019,37 @@ ObCreateObjectType(IN PUNICODE_STRING TypeName, ExInitializeResourceLite(&LocalObjectType->Mutex); InitializeListHead(&LocalObjectType->TypeList); - /* Check if we're actually creating the directory object itself */ - if (ObpTypeDirectoryObject) + /* Get creator info and insert it into the type list */ + CreatorInfo = OBJECT_HEADER_TO_CREATOR_INFO(Header); + if (CreatorInfo) InsertTailList(&ObTypeObjectType->TypeList, + &CreatorInfo->TypeList); + + /* Set the index and the entry into the object type array */ + LocalObjectType->Index = ObTypeObjectType->TotalNumberOfObjects; + if (LocalObjectType->Index < 32) { - /* Insert it into the Object Directory */ - ObpInsertEntryDirectory(ObpTypeDirectoryObject, &Context, Header); - ObReferenceObject(ObpTypeDirectoryObject); + /* It fits, insert it */ + ObpObjectTypes[LocalObjectType->Index - 1] = LocalObjectType; } - /* Return the object type and creations tatus */ - *ObjectType = LocalObjectType; - return Status; + /* Check if we're actually creating the directory object itself */ + if (!(ObpTypeDirectoryObject) || + (ObpInsertEntryDirectory(ObpTypeDirectoryObject, &Context, Header))) + { + /* Check if the type directory exists */ + if (ObpTypeDirectoryObject) + { + /* Reference it */ + ObReferenceObject(ObpTypeDirectoryObject); + } + + /* Return the object type and success */ + *ObjectType = LocalObjectType; + return STATUS_SUCCESS; + } + + /* If we got here, then we failed */ + return STATUS_INSUFFICIENT_RESOURCES; } /*++ @@ -878,7 +1071,7 @@ NTAPI ObMakeTemporaryObject(IN PVOID ObjectBody) { /* Call the internal API */ - ObpSetPermanentObject (ObjectBody, FALSE); + ObpSetPermanentObject(ObjectBody, FALSE); } /*++ diff --git a/reactos/ntoskrnl/ob/obname.c b/reactos/ntoskrnl/ob/obname.c index fe15162fc0b..88cf9e16dd2 100644 --- a/reactos/ntoskrnl/ob/obname.c +++ b/reactos/ntoskrnl/ob/obname.c @@ -21,6 +21,82 @@ POBJECT_DIRECTORY ObpTypeDirectoryObject = NULL; /* PRIVATE FUNCTIONS *********************************************************/ +NTSTATUS +NTAPI +ObpCreateDosDevicesDirectory(VOID) +{ + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING Name, LinkName; + HANDLE Handle, SymHandle; + NTSTATUS Status; + + /* Create the '\??' directory */ + RtlInitUnicodeString(&Name, L"\\??"); + InitializeObjectAttributes(&ObjectAttributes, + &Name, + OBJ_PERMANENT, + NULL, + NULL); + Status = NtCreateDirectoryObject(&Handle, + DIRECTORY_ALL_ACCESS, + &ObjectAttributes); + if (!NT_SUCCESS(Status)) return FALSE; + + /* Initialize the GLOBALROOT path */ + RtlInitUnicodeString(&LinkName, L"GLOBALROOT"); + RtlInitUnicodeString(&Name, L""); + InitializeObjectAttributes(&ObjectAttributes, + &LinkName, + OBJ_PERMANENT, + Handle, + NULL); + Status = NtCreateSymbolicLinkObject(&SymHandle, + SYMBOLIC_LINK_ALL_ACCESS, + &ObjectAttributes, + &Name); + if (NT_SUCCESS(Status)) NtClose(SymHandle); + + /* Link \??\Global to \?? */ + RtlInitUnicodeString(&LinkName, L"Global"); + RtlInitUnicodeString(&Name, L"\\??"); + InitializeObjectAttributes(&ObjectAttributes, + &LinkName, + OBJ_PERMANENT, + Handle, + NULL); + Status = NtCreateSymbolicLinkObject(&SymHandle, + SYMBOLIC_LINK_ALL_ACCESS, + &ObjectAttributes, + &Name); + if (NT_SUCCESS(Status)) NtClose(SymHandle); + + /* Close the directory handle */ + NtClose(Handle); + if (!NT_SUCCESS(Status)) return Status; + + /* Create link from '\DosDevices' to '\??' directory */ + RtlCreateUnicodeString(&LinkName, L"\\DosDevices"); + InitializeObjectAttributes(&ObjectAttributes, + &LinkName, + OBJ_PERMANENT, + NULL, + NULL); + Status = NtCreateSymbolicLinkObject(&SymHandle, + SYMBOLIC_LINK_ALL_ACCESS, + &ObjectAttributes, + &Name); + if (NT_SUCCESS(Status)) NtClose(SymHandle); + + /* FIXME: Hack Hack! */ + ObSystemDeviceMap = ExAllocatePoolWithTag(NonPagedPool, + sizeof(*ObSystemDeviceMap), + TAG('O', 'b', 'D', 'm')); + RtlZeroMemory(ObSystemDeviceMap, sizeof(*ObSystemDeviceMap)); + + /* Return status */ + return Status; +} + VOID NTAPI ObDereferenceDeviceMap(IN PEPROCESS Process) diff --git a/reactos/ntoskrnl/ob/symlink.c b/reactos/ntoskrnl/ob/symlink.c index 1b2d48d555a..37479e6ca6b 100644 --- a/reactos/ntoskrnl/ob/symlink.c +++ b/reactos/ntoskrnl/ob/symlink.c @@ -21,14 +21,6 @@ POBJECT_TYPE ObSymbolicLinkType = NULL; -static GENERIC_MAPPING ObpSymbolicLinkMapping = -{ - STANDARD_RIGHTS_READ | SYMBOLIC_LINK_QUERY, - STANDARD_RIGHTS_WRITE, - STANDARD_RIGHTS_EXECUTE | SYMBOLIC_LINK_QUERY, - SYMBOLIC_LINK_ALL_ACCESS -}; - /* PRIVATE FUNCTIONS *********************************************************/ /*++ @@ -181,40 +173,6 @@ ObpParseSymbolicLink(IN PVOID ParsedObject, return STATUS_REPARSE; } -/*++ -* @name ObInitSymbolicLinkImplementation -* -* The ObInitSymbolicLinkImplementation routine -* -* @param None. -* -* @return None. -* -* @remarks None. -* -*--*/ -VOID -INIT_FUNCTION -NTAPI -ObInitSymbolicLinkImplementation(VOID) -{ - UNICODE_STRING Name; - OBJECT_TYPE_INITIALIZER ObjectTypeInitializer; - - /* Initialize the Directory type */ - RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer)); - RtlInitUnicodeString(&Name, L"SymbolicLink"); - ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer); - ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(OBJECT_SYMBOLIC_LINK); - ObjectTypeInitializer.GenericMapping = ObpSymbolicLinkMapping; - ObjectTypeInitializer.PoolType = NonPagedPool; - ObjectTypeInitializer.ValidAccessMask = SYMBOLIC_LINK_ALL_ACCESS; - ObjectTypeInitializer.UseDefaultObject = TRUE; - ObjectTypeInitializer.ParseProcedure = ObpParseSymbolicLink; - ObjectTypeInitializer.DeleteProcedure = ObpDeleteSymbolicLink; - ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &ObSymbolicLinkType); -} - /* PUBLIC FUNCTIONS **********************************************************/ /*++