Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438/* * PROJECT: ReactOS Kernel * LICENSE: GPL - See COPYING in the top level directory * FILE: ntoskrnl/ob/obinit.c * PURPOSE: Handles Object Manager Initialization and Shutdown * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) * Eric Kohl * Thomas Weidenmueller (w3seek@reactos.org) */
/* INCLUDES ******************************************************************/
#include <ntoskrnl.h>#define NDEBUG#include <debug.h>
/* GLOBALS *******************************************************************/
GENERIC_MAPPING ObpTypeMapping ={ STANDARD_RIGHTS_READ, STANDARD_RIGHTS_WRITE, STANDARD_RIGHTS_EXECUTE, 0x000F0001};
GENERIC_MAPPING ObpDirectoryMapping ={ STANDARD_RIGHTS_READ | DIRECTORY_QUERY | DIRECTORY_TRAVERSE, STANDARD_RIGHTS_WRITE | DIRECTORY_CREATE_SUBDIRECTORY | DIRECTORY_CREATE_OBJECT, STANDARD_RIGHTS_EXECUTE | DIRECTORY_QUERY | DIRECTORY_TRAVERSE, 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 = 0;
CODE_SEG("INIT")VOIDNTAPIPsInitializeQuotaSystem(VOID);
ULONG ObpInitializationPhase;
ULONG ObpObjectSecurityMode = 0;ULONG ObpProtectionMode = 0;
/* PRIVATE FUNCTIONS *********************************************************/
staticCODE_SEG("INIT")NTSTATUSNTAPIObpCreateKernelObjectsSD(OUT PSECURITY_DESCRIPTOR *SecurityDescriptor){ PSECURITY_DESCRIPTOR Sd = NULL; PACL Dacl; ULONG AclSize, SdSize; NTSTATUS Status;
AclSize = sizeof(ACL) + sizeof(ACE) + RtlLengthSid(SeWorldSid) + sizeof(ACE) + RtlLengthSid(SeAliasAdminsSid) + sizeof(ACE) + RtlLengthSid(SeLocalSystemSid);
SdSize = sizeof(SECURITY_DESCRIPTOR) + AclSize;
/* Allocate the SD and ACL */ Sd = ExAllocatePoolWithTag(PagedPool, SdSize, TAG_SD); if (Sd == NULL) { return STATUS_INSUFFICIENT_RESOURCES; }
/* Initialize the SD */ Status = RtlCreateSecurityDescriptor(Sd, SECURITY_DESCRIPTOR_REVISION); if (!NT_SUCCESS(Status)) goto done;
Dacl = (PACL)((INT_PTR)Sd + sizeof(SECURITY_DESCRIPTOR));
/* Initialize the DACL */ RtlCreateAcl(Dacl, AclSize, ACL_REVISION);
/* Add the ACEs */ RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_READ, SeWorldSid);
RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, SeAliasAdminsSid);
RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, SeLocalSystemSid);
/* Attach the DACL to the SD */ Status = RtlSetDaclSecurityDescriptor(Sd, TRUE, Dacl, FALSE); if (!NT_SUCCESS(Status)) goto done;
*SecurityDescriptor = Sd;
done: if (!NT_SUCCESS(Status)) { if (Sd != NULL) ExFreePoolWithTag(Sd, TAG_SD); }
return Status;}
CODE_SEG("INIT")BOOLEANNTAPIObInit2(VOID){ CCHAR i; PKPRCB Prcb; PGENERAL_LOOKASIDE CurrentList = NULL;
/* Now allocate the per-processor lists */ for (i = 0; i < KeNumberProcessors; i++) { /* Get the PRCB for this CPU */ Prcb = KiProcessorBlock[(int)i];
/* Set the OBJECT_CREATE_INFORMATION List */ Prcb->PPLookasideList[LookasideCreateInfoList].L = &ObpCreateInfoLookasideList; CurrentList = ExAllocatePoolWithTag(NonPagedPool, sizeof(GENERAL_LOOKASIDE), 'ICbO'); if (CurrentList) { /* Initialize it */ ExInitializeSystemLookasideList(CurrentList, NonPagedPool, sizeof(OBJECT_CREATE_INFORMATION), 'ICbO', 32, &ExSystemLookasideListHead); } else { /* No list, use the static buffer */ CurrentList = &ObpCreateInfoLookasideList; }
/* Link it */ Prcb->PPLookasideList[LookasideCreateInfoList].P = CurrentList;
/* Set the captured UNICODE_STRING Object Name List */ Prcb->PPLookasideList[LookasideNameBufferList].L = &ObpNameBufferLookasideList; CurrentList = ExAllocatePoolWithTag(NonPagedPool, sizeof(GENERAL_LOOKASIDE), 'MNbO'); if (CurrentList) { /* Initialize it */ ExInitializeSystemLookasideList(CurrentList, PagedPool, 248, 'MNbO', 16, &ExSystemLookasideListHead); } else { /* No list, use the static buffer */ CurrentList = &ObpNameBufferLookasideList; }
/* Link it */ Prcb->PPLookasideList[LookasideNameBufferList].P = CurrentList; }
return TRUE;}
CODE_SEG("INIT")BOOLEANNTAPIObInitSystem(VOID){ OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING Name; OBJECT_TYPE_INITIALIZER ObjectTypeInitializer; OBP_LOOKUP_CONTEXT Context; HANDLE Handle; PKPRCB Prcb = KeGetCurrentPrcb(); PLIST_ENTRY ListHead, NextEntry; POBJECT_HEADER Header; POBJECT_HEADER_CREATOR_INFO CreatorInfo; POBJECT_HEADER_NAME_INFO NameInfo; PSECURITY_DESCRIPTOR KernelObjectsSD = NULL; NTSTATUS Status;
/* Check if this is actually Phase 1 initialization */ if (ObpInitializationPhase != 0) goto ObPostPhase0;
/* Initialize the OBJECT_CREATE_INFORMATION List */ ExInitializeSystemLookasideList(&ObpCreateInfoLookasideList, NonPagedPool, sizeof(OBJECT_CREATE_INFORMATION), 'ICbO', 32, &ExSystemLookasideListHead);
/* Set the captured UNICODE_STRING Object Name List */ ExInitializeSystemLookasideList(&ObpNameBufferLookasideList, PagedPool, 248, 'MNbO', 16, &ExSystemLookasideListHead);
/* Temporarily setup both pointers to the shared list */ Prcb->PPLookasideList[LookasideCreateInfoList].L = &ObpCreateInfoLookasideList; Prcb->PPLookasideList[LookasideCreateInfoList].P = &ObpCreateInfoLookasideList; Prcb->PPLookasideList[LookasideNameBufferList].L = &ObpNameBufferLookasideList; Prcb->PPLookasideList[LookasideNameBufferList].P = &ObpNameBufferLookasideList;
/* Initialize the security descriptor cache */ ObpInitSdCache();
/* Initialize the Default Event */ KeInitializeEvent(&ObpDefaultObject, NotificationEvent, TRUE);
/* Initialize the Dos Device Map mutex */ KeInitializeGuardedMutex(&ObpDeviceMapLock);
/* Setup default access for the system process */ PsGetCurrentProcess()->GrantedAccess = PROCESS_ALL_ACCESS; PsGetCurrentThread()->GrantedAccess = THREAD_ALL_ACCESS;
/* Setup the Object Reaper */ ExInitializeWorkItem(&ObpReaperWorkItem, ObpReapObject, NULL);
/* Initialize default Quota block */ PsInitializeQuotaSystem();
/* Create kernel handle table */ PsGetCurrentProcess()->ObjectTable = ExCreateHandleTable(NULL); ObpKernelHandleTable = PsGetCurrentProcess()->ObjectTable;
/* Create the Type Type */ RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer)); RtlInitUnicodeString(&Name, L"Type"); ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer); ObjectTypeInitializer.ValidAccessMask = OBJECT_TYPE_ALL_ACCESS; ObjectTypeInitializer.UseDefaultObject = TRUE; ObjectTypeInitializer.MaintainTypeList = TRUE; ObjectTypeInitializer.PoolType = NonPagedPool; ObjectTypeInitializer.GenericMapping = ObpTypeMapping; ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(OBJECT_TYPE); ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK; ObjectTypeInitializer.DeleteProcedure = ObpDeleteObjectType; ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &ObpTypeObjectType);
/* Create the Directory Type */ RtlInitUnicodeString(&Name, L"Directory"); ObjectTypeInitializer.PoolType = PagedPool; ObjectTypeInitializer.ValidAccessMask = DIRECTORY_ALL_ACCESS; ObjectTypeInitializer.CaseInsensitive = TRUE; ObjectTypeInitializer.MaintainTypeList = FALSE; ObjectTypeInitializer.GenericMapping = ObpDirectoryMapping; ObjectTypeInitializer.DeleteProcedure = NULL; ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(OBJECT_DIRECTORY); ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &ObpDirectoryObjectType); ObpDirectoryObjectType->TypeInfo.ValidAccessMask &= ~SYNCHRONIZE;
/* 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, &ObpSymbolicLinkObjectType); ObpSymbolicLinkObjectType->TypeInfo.ValidAccessMask &= ~SYNCHRONIZE;
/* Phase 0 initialization complete */ ObpInitializationPhase++; return TRUE;
ObPostPhase0:
/* Re-initialize lookaside lists */ ObInit2();
/* Initialize Object Types directory attributes */ RtlInitUnicodeString(&Name, L"\\"); InitializeObjectAttributes(&ObjectAttributes, &Name, OBJ_CASE_INSENSITIVE | OBJ_PERMANENT, NULL, SePublicDefaultUnrestrictedSd);
/* 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, ObpDirectoryObjectType, KernelMode, (PVOID*)&ObpRootDirectoryObject, NULL); if (!NT_SUCCESS(Status)) return FALSE;
/* Close the extra handle */ Status = NtClose(Handle); if (!NT_SUCCESS(Status)) return FALSE;
/* Create a custom security descriptor for the KernelObjects directory */ Status = ObpCreateKernelObjectsSD(&KernelObjectsSD); if (!NT_SUCCESS(Status)) return FALSE;
/* Initialize the KernelObjects directory attributes */ RtlInitUnicodeString(&Name, L"\\KernelObjects"); InitializeObjectAttributes(&ObjectAttributes, &Name, OBJ_CASE_INSENSITIVE | OBJ_PERMANENT, NULL, KernelObjectsSD);
/* Create the directory */ Status = NtCreateDirectoryObject(&Handle, DIRECTORY_ALL_ACCESS, &ObjectAttributes); ExFreePoolWithTag(KernelObjectsSD, TAG_SD); if (!NT_SUCCESS(Status)) return FALSE;
/* Close the extra handle */ Status = NtClose(Handle); if (!NT_SUCCESS(Status)) return FALSE;
/* Initialize ObjectTypes directory attributes */ RtlInitUnicodeString(&Name, L"\\ObjectTypes"); InitializeObjectAttributes(&ObjectAttributes, &Name, OBJ_CASE_INSENSITIVE | OBJ_PERMANENT, NULL, NULL);
/* 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, ObpDirectoryObjectType, KernelMode, (PVOID*)&ObpTypeDirectoryObject, NULL); if (!NT_SUCCESS(Status)) return FALSE;
/* Close the extra handle */ Status = NtClose(Handle); if (!NT_SUCCESS(Status)) return FALSE;
/* Initialize the lookup context and lock it */ ObpInitializeLookupContext(&Context); ObpAcquireLookupContextLock(&Context, ObpTypeDirectoryObject);
/* Loop the object types */ ListHead = &ObpTypeObjectType->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)) { /* 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; }
/* Cleanup after lookup */ ObpReleaseLookupContext(&Context);
/* Initialize DOS Devices Directory and related Symbolic Links */ Status = ObpCreateDosDevicesDirectory(); if (!NT_SUCCESS(Status)) return FALSE; return TRUE;}
/* EOF */