From 703c503a4f0c5ba8143b92e20f3ac9d48bdbe0ad Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Fri, 11 May 2007 18:58:34 +0000 Subject: [PATCH] - Move CmpInitializeSystemHive and CmpCreateObjectTypes to cmsysini.c since they're almost identical to the Cm rewrite and compatible, so they're considered "new" code (although they still use EREGISTRY_HIVE). - Add code missing in CmpInitializeSystemHive from Cm Rewrite (mainly detecting boot type and self-healing settings). - Free a memory leak. - Enable security for key objects. - Rename CmiKeyType to CmpKeyObjectType. svn path=/trunk/; revision=26702 --- reactos/ntoskrnl/cm/cm.h | 18 ++- reactos/ntoskrnl/cm/ntfunc.c | 28 ++--- reactos/ntoskrnl/cm/registry.c | 123 +-------------------- reactos/ntoskrnl/cm/regobj.c | 26 ++--- reactos/ntoskrnl/config/cm.h | 22 +++- reactos/ntoskrnl/config/cmse.c | 16 +-- reactos/ntoskrnl/config/cmsysini.c | 170 +++++++++++++++++++++++++++++ 7 files changed, 242 insertions(+), 161 deletions(-) diff --git a/reactos/ntoskrnl/cm/cm.h b/reactos/ntoskrnl/cm/cm.h index a81d563ed56..e0cfd32d01f 100644 --- a/reactos/ntoskrnl/cm/cm.h +++ b/reactos/ntoskrnl/cm/cm.h @@ -107,7 +107,7 @@ typedef struct _KEY_OBJECT extern PEREGISTRY_HIVE CmiVolatileHive; -extern POBJECT_TYPE CmiKeyType; +extern POBJECT_TYPE CmpKeyObjectType; extern KSPIN_LOCK CmiKeyListLock; extern LIST_ENTRY CmiHiveListHead; @@ -148,7 +148,7 @@ NTSTATUS STDCALL CmUnRegisterCallback(IN LARGE_INTEGER Cookie); NTSTATUS STDCALL -CmiObjectParse(IN PVOID ParsedObject, +CmpParseKey(IN PVOID ParsedObject, IN PVOID ObjectType, IN OUT PACCESS_STATE AccessState, IN KPROCESSOR_MODE AccessMode, @@ -160,10 +160,10 @@ CmiObjectParse(IN PVOID ParsedObject, OUT PVOID *NextObject); VOID STDCALL -CmiObjectDelete(PVOID DeletedObject); +CmpDeleteKeyObject(PVOID DeletedObject); NTSTATUS STDCALL -CmiObjectSecurity(PVOID ObjectBody, +CmpSecurityMethod(PVOID ObjectBody, SECURITY_OPERATION_CODE OperationCode, PSECURITY_INFORMATION SecurityInformation, PSECURITY_DESCRIPTOR SecurityDescriptor, @@ -173,7 +173,7 @@ CmiObjectSecurity(PVOID ObjectBody, PGENERIC_MAPPING GenericMapping); NTSTATUS STDCALL -CmiObjectQueryName (PVOID ObjectBody, +CmpQueryKeyName (PVOID ObjectBody, IN BOOLEAN HasObjectName, POBJECT_NAME_INFORMATION ObjectNameInfo, ULONG Length, @@ -478,6 +478,14 @@ PSECURITY_DESCRIPTOR NTAPI CmpHiveRootSecurityDescriptor(VOID); +BOOLEAN +NTAPI +CmpInitializeSystemHive(IN PLOADER_PARAMETER_BLOCK LoaderBlock); + +NTSTATUS +NTAPI +CmpCreateObjectTypes(VOID); + #if 0 static __inline PVOID xHvGetCell(char *file, int line, PHHIVE Hive, HCELL_INDEX Cell) { diff --git a/reactos/ntoskrnl/cm/ntfunc.c b/reactos/ntoskrnl/cm/ntfunc.c index dd3b5051b09..3443e7d9b29 100644 --- a/reactos/ntoskrnl/cm/ntfunc.c +++ b/reactos/ntoskrnl/cm/ntfunc.c @@ -24,7 +24,7 @@ /* GLOBALS ******************************************************************/ -extern POBJECT_TYPE CmiKeyType; +extern POBJECT_TYPE CmpKeyObjectType; extern LIST_ENTRY CmiKeyObjectListHead; static BOOLEAN CmiRegistryInitialized = FALSE; @@ -218,7 +218,7 @@ NtCreateKey(OUT PHANDLE KeyHandle, &ObjectName, (PVOID*)&Object, &RemainingPath, - CmiKeyType, + CmpKeyObjectType, NULL, NULL); if (!NT_SUCCESS(Status)) @@ -300,7 +300,7 @@ NtCreateKey(OUT PHANDLE KeyHandle, DPRINT("RemainingPath %S ParentObject 0x%p\n", RemainingPath.Buffer, Object); Status = ObCreateObject(PreviousMode, - CmiKeyType, + CmpKeyObjectType, NULL, PreviousMode, NULL, @@ -452,7 +452,7 @@ NtDeleteKey(IN HANDLE KeyHandle) /* Verify that the handle is valid and is a registry key */ Status = ObReferenceObjectByHandle(KeyHandle, DELETE, - CmiKeyType, + CmpKeyObjectType, PreviousMode, (PVOID *)&KeyObject, NULL); @@ -516,7 +516,7 @@ NtDeleteKey(IN HANDLE KeyHandle) /* * Note: * Hive-Synchronization will not be triggered here. This is done in - * CmiObjectDelete() (in regobj.c) after all key-related structures + * CmpDeleteKeyObject() (in regobj.c) after all key-related structures * have been released. */ @@ -563,7 +563,7 @@ NtEnumerateKey(IN HANDLE KeyHandle, /* Verify that the handle is valid and is a registry key */ Status = ObReferenceObjectByHandle(KeyHandle, KEY_ENUMERATE_SUB_KEYS, - CmiKeyType, + CmpKeyObjectType, PreviousMode, (PVOID *) &KeyObject, NULL); @@ -863,7 +863,7 @@ NtEnumerateValueKey(IN HANDLE KeyHandle, /* Verify that the handle is valid and is a registry key */ Status = ObReferenceObjectByHandle(KeyHandle, KEY_QUERY_VALUE, - CmiKeyType, + CmpKeyObjectType, ExGetPreviousMode(), (PVOID *) &KeyObject, NULL); @@ -1116,7 +1116,7 @@ NtFlushKey(IN HANDLE KeyHandle) /* Verify that the handle is valid and is a registry key */ Status = ObReferenceObjectByHandle(KeyHandle, 0, - CmiKeyType, + CmpKeyObjectType, PreviousMode, (PVOID *)&KeyObject, NULL); @@ -1244,7 +1244,7 @@ NtOpenKey(OUT PHANDLE KeyHandle, &ObjectName, (PVOID*)&Object, &RemainingPath, - CmiKeyType, + CmpKeyObjectType, NULL, NULL); if (!NT_SUCCESS(Status)) @@ -1340,7 +1340,7 @@ NtQueryKey(IN HANDLE KeyHandle, /* Verify that the handle is valid and is a registry key */ Status = ObReferenceObjectByHandle(KeyHandle, (KeyInformationClass != KeyNameInformation ? KEY_QUERY_VALUE : 0), - CmiKeyType, + CmpKeyObjectType, ExGetPreviousMode(), (PVOID *) &KeyObject, NULL); @@ -1566,7 +1566,7 @@ NtQueryValueKey(IN HANDLE KeyHandle, /* Verify that the handle is valid and is a registry key */ Status = ObReferenceObjectByHandle(KeyHandle, KEY_QUERY_VALUE, - CmiKeyType, + CmpKeyObjectType, ExGetPreviousMode(), (PVOID *)&KeyObject, NULL); @@ -1830,7 +1830,7 @@ NtSetValueKey(IN HANDLE KeyHandle, /* Verify that the handle is valid and is a registry key */ Status = ObReferenceObjectByHandle(KeyHandle, DesiredAccess, - CmiKeyType, + CmpKeyObjectType, ExGetPreviousMode(), (PVOID *)&KeyObject, NULL); @@ -2005,7 +2005,7 @@ NtDeleteValueKey (IN HANDLE KeyHandle, /* Verify that the handle is valid and is a registry key */ Status = ObReferenceObjectByHandle(KeyHandle, KEY_SET_VALUE, - CmiKeyType, + CmpKeyObjectType, PreviousMode, (PVOID *)&KeyObject, NULL); @@ -2218,7 +2218,7 @@ NtQueryMultipleValueKey (IN HANDLE KeyHandle, /* Verify that the handle is valid and is a registry key */ Status = ObReferenceObjectByHandle(KeyHandle, KEY_QUERY_VALUE, - CmiKeyType, + CmpKeyObjectType, ExGetPreviousMode(), (PVOID *) &KeyObject, NULL); diff --git a/reactos/ntoskrnl/cm/registry.c b/reactos/ntoskrnl/cm/registry.c index c35689b0fed..dfc9e06952d 100644 --- a/reactos/ntoskrnl/cm/registry.c +++ b/reactos/ntoskrnl/cm/registry.c @@ -29,7 +29,7 @@ extern BOOLEAN ExpInTextModeSetup; -POBJECT_TYPE CmiKeyType = NULL; +POBJECT_TYPE CmpKeyObjectType = NULL; PEREGISTRY_HIVE CmiVolatileHive = NULL; LIST_ENTRY CmiHiveListHead; @@ -46,9 +46,6 @@ volatile BOOLEAN CmiHiveSyncPending = FALSE; KDPC CmiHiveSyncDpc; KTIMER CmiHiveSyncTimer; -static GENERIC_MAPPING CmiKeyMapping = - {KEY_READ, KEY_WRITE, KEY_EXECUTE, KEY_ALL_ACCESS}; - static VOID STDCALL CmiHiveSyncDpcRoutine(PKDPC Dpc, PVOID DeferredContext, @@ -186,118 +183,6 @@ CmpLinkHiveToMaster(IN PUNICODE_STRING LinkName, return CmiConnectHive(&ObjectAttributes, RegistryHive); } -BOOLEAN -NTAPI -CmpInitializeSystemHive(IN PLOADER_PARAMETER_BLOCK LoaderBlock) -{ - PVOID HiveBase; - ANSI_STRING LoadString; - PVOID Buffer; - ULONG Length; - NTSTATUS Status; - BOOLEAN Allocate; - UNICODE_STRING KeyName; - PEREGISTRY_HIVE SystemHive; - UNICODE_STRING HiveName = RTL_CONSTANT_STRING(L"SYSTEM"); - PSECURITY_DESCRIPTOR SecurityDescriptor; - PAGED_CODE(); - - /* Setup the ansi string */ - RtlInitAnsiString(&LoadString, LoaderBlock->LoadOptions); - - /* Allocate the unicode buffer */ - Length = LoadString.Length * sizeof(WCHAR) + sizeof(UNICODE_NULL); - Buffer = ExAllocatePoolWithTag(PagedPool, Length, 0); - if (!Buffer) - { - /* Fail */ - KEBUGCHECKEX(BAD_SYSTEM_CONFIG_INFO, 3, 1, (ULONG_PTR)LoaderBlock, 0); - } - - /* Setup the unicode string */ - RtlInitEmptyUnicodeString(&CmpLoadOptions, Buffer, Length); - - /* Add the load options and null-terminate */ - RtlAnsiStringToUnicodeString(&CmpLoadOptions, &LoadString, FALSE); - CmpLoadOptions.Buffer[LoadString.Length] = UNICODE_NULL; - CmpLoadOptions.Length += sizeof(WCHAR); - - /* Get the System Hive base address */ - HiveBase = LoaderBlock->RegistryBase; - if (HiveBase) - { - /* Import it */ - ((PHBASE_BLOCK)HiveBase)->Length = LoaderBlock->RegistryLength; - Status = CmpInitializeHive(&SystemHive, - HINIT_MEMORY, - 0, //HIVE_NOLAZYFLUSH, - HFILE_TYPE_LOG, - HiveBase, - NULL, - NULL, - NULL, - &HiveName, - 2); - if (!NT_SUCCESS(Status)) return FALSE; - CmPrepareHive(&SystemHive->Hive); - - /* Set the hive filename */ - RtlCreateUnicodeString(&SystemHive->HiveFileName, SYSTEM_REG_FILE); - - /* Set the log filename */ - RtlCreateUnicodeString(&SystemHive->LogFileName, SYSTEM_LOG_FILE); - - /* We imported, no need to create a new hive */ - Allocate = FALSE; - } - else - { - /* FIXME: Create an empty hive */ - Allocate = TRUE; - } - - /* Create the default security descriptor */ - SecurityDescriptor = CmpHiveRootSecurityDescriptor(); - - /* Attach it to the system key */ - RtlInitUnicodeString(&KeyName, REG_SYSTEM_KEY_NAME); - Status = CmpLinkHiveToMaster(&KeyName, - NULL, - SystemHive, - Allocate, - SecurityDescriptor); - if (!NT_SUCCESS(Status)) return FALSE; - - /* Success! */ - return TRUE; -} - -NTSTATUS -NTAPI -CmpCreateObjectTypes(VOID) -{ - OBJECT_TYPE_INITIALIZER ObjectTypeInitializer; - UNICODE_STRING Name; - PAGED_CODE(); - - /* Initialize the Key object type */ - RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer)); - RtlInitUnicodeString(&Name, L"Key"); - ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer); - ObjectTypeInitializer.DefaultPagedPoolCharge = sizeof(KEY_OBJECT); - ObjectTypeInitializer.GenericMapping = CmiKeyMapping; - ObjectTypeInitializer.PoolType = PagedPool; - ObjectTypeInitializer.ValidAccessMask = KEY_ALL_ACCESS; - ObjectTypeInitializer.UseDefaultObject = TRUE; - ObjectTypeInitializer.DeleteProcedure = CmiObjectDelete; - ObjectTypeInitializer.ParseProcedure = CmiObjectParse; - ObjectTypeInitializer.SecurityProcedure = CmiObjectSecurity; - ObjectTypeInitializer.QueryNameProcedure = CmiObjectQueryName; - - /* Create it */ - return ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &CmiKeyType); -} - BOOLEAN NTAPI CmpCreateRootNode(IN PHHIVE Hive, @@ -381,7 +266,7 @@ CmpCreateRegistryRoot(VOID) NULL, NULL); Status = ObCreateObject(KernelMode, - CmiKeyType, + CmpKeyObjectType, &ObjectAttributes, KernelMode, NULL, @@ -675,7 +560,7 @@ CmiConnectHive(IN POBJECT_ATTRIBUTES KeyObjectAttributes, &ObjectName, (PVOID*)&ParentKey, &RemainingPath, - CmiKeyType, + CmpKeyObjectType, NULL, NULL); /* Yields a new reference */ @@ -714,7 +599,7 @@ CmiConnectHive(IN POBJECT_ATTRIBUTES KeyObjectAttributes, &RemainingPath, ParentKey); Status = ObCreateObject(KernelMode, - CmiKeyType, + CmpKeyObjectType, NULL, KernelMode, NULL, diff --git a/reactos/ntoskrnl/cm/regobj.c b/reactos/ntoskrnl/cm/regobj.c index a762a279a51..42f5990decb 100644 --- a/reactos/ntoskrnl/cm/regobj.c +++ b/reactos/ntoskrnl/cm/regobj.c @@ -174,7 +174,7 @@ CmFindObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo, { ObReferenceObjectByPointer(ObpRootDirectoryObject, DIRECTORY_TRAVERSE, - CmiKeyType, + CmpKeyObjectType, ObjectCreateInfo->ProbeMode); CurrentObject = ObpRootDirectoryObject; } @@ -267,7 +267,7 @@ CmFindObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo, ObReferenceObjectByPointer(FoundObject, STANDARD_RIGHTS_REQUIRED, - CmiKeyType, + CmpKeyObjectType, KernelMode); if (End != NULL) { @@ -317,7 +317,7 @@ Next: ObReferenceObjectByPointer(NextObject, DIRECTORY_TRAVERSE, - CmiKeyType, + CmpKeyObjectType, ObjectCreateInfo->ProbeMode); } @@ -342,7 +342,7 @@ Next: } NTSTATUS STDCALL -CmiObjectParse(IN PVOID ParsedObject, +CmpParseKey(IN PVOID ParsedObject, IN PVOID ObjectType, IN OUT PACCESS_STATE AccessState, IN KPROCESSOR_MODE AccessMode, @@ -481,9 +481,9 @@ CmiObjectParse(IN PVOID ParsedObject, } /* Create new key object and put into linked list */ - DPRINT("CmiObjectParse: %S\n", *Path); + DPRINT("CmpParseKey: %S\n", *Path); Status = ObCreateObject(KernelMode, - CmiKeyType, + CmpKeyObjectType, NULL, KernelMode, NULL, @@ -586,7 +586,7 @@ OBJECT_TO_OBJECT_HEADER(FoundObject)->ObjectCreateInfo = NULL; ExReleaseResourceLite(&CmiRegistryLock); KeLeaveCriticalRegion(); - DPRINT("CmiObjectParse: %wZ\n", &FoundObject->Name); + DPRINT("CmpParseKey: %wZ\n", &FoundObject->Name); *Path = EndPtr; @@ -600,7 +600,7 @@ OBJECT_TO_OBJECT_HEADER(FoundObject)->ObjectCreateInfo = NULL; } VOID STDCALL -CmiObjectDelete(PVOID DeletedObject) +CmpDeleteKeyObject(PVOID DeletedObject) { PKEY_OBJECT ParentKeyObject; PKEY_OBJECT KeyObject; @@ -789,7 +789,7 @@ CmiAssignSecurityDescriptor(PKEY_OBJECT KeyObject, NTSTATUS STDCALL -CmiObjectSecurity(PVOID ObjectBody, +CmpSecurityMethod(PVOID ObjectBody, SECURITY_OPERATION_CODE OperationCode, PSECURITY_INFORMATION SecurityInformation, PSECURITY_DESCRIPTOR SecurityDescriptor, @@ -798,7 +798,7 @@ CmiObjectSecurity(PVOID ObjectBody, POOL_TYPE PoolType, PGENERIC_MAPPING GenericMapping) { - DPRINT("CmiObjectSecurity() called\n"); + DPRINT("CmpSecurityMethod() called\n"); switch (OperationCode) { @@ -828,7 +828,7 @@ CmiObjectSecurity(PVOID ObjectBody, NTSTATUS STDCALL -CmiObjectQueryName (PVOID ObjectBody, +CmpQueryKeyName (PVOID ObjectBody, IN BOOLEAN HasName, POBJECT_NAME_INFORMATION ObjectNameInfo, ULONG Length, @@ -838,7 +838,7 @@ CmiObjectQueryName (PVOID ObjectBody, PKEY_OBJECT KeyObject; NTSTATUS Status; - DPRINT ("CmiObjectQueryName() called\n"); + DPRINT ("CmpQueryKeyName() called\n"); KeyObject = (PKEY_OBJECT)ObjectBody; @@ -931,7 +931,7 @@ CmiAddKeyToList(PKEY_OBJECT ParentKey, ObReferenceObjectByPointer(ParentKey, STANDARD_RIGHTS_REQUIRED, - CmiKeyType, + CmpKeyObjectType, KernelMode); NewKey->ParentKey = ParentKey; } diff --git a/reactos/ntoskrnl/config/cm.h b/reactos/ntoskrnl/config/cm.h index 5be366caf07..79145309e0c 100644 --- a/reactos/ntoskrnl/config/cm.h +++ b/reactos/ntoskrnl/config/cm.h @@ -767,10 +767,10 @@ CmpInitializeHive( IN ULONG FileType, IN PVOID HiveData, IN HANDLE Primary, - IN HANDLE Alternate, IN HANDLE Log, IN HANDLE External, - IN PUNICODE_STRING FileName + IN PUNICODE_STRING FileName, + IN ULONG CheckFlags ); PSECURITY_DESCRIPTOR @@ -982,6 +982,24 @@ extern PCM_FULL_RESOURCE_DESCRIPTOR CmpConfigurationData; extern UNICODE_STRING CmTypeName[]; extern BOOLEAN ExpInTextModeSetup; +// +// BUGBUG Old Hive Stuff for Temporary Support +// +#define SYSTEM_REG_FILE L"\\SystemRoot\\System32\\Config\\SYSTEM" +#define SYSTEM_LOG_FILE L"\\SystemRoot\\System32\\Config\\SYSTEM.log" +#define REG_SYSTEM_KEY_NAME L"\\Registry\\Machine\\SYSTEM" +typedef struct _EREGISTRY_HIVE +{ + HHIVE Hive; + LIST_ENTRY HiveList; + UNICODE_STRING HiveFileName; + UNICODE_STRING LogFileName; + PCM_KEY_SECURITY RootSecurityCell; + ULONG Flags; + HANDLE HiveHandle; + HANDLE LogHandle; +} EREGISTRY_HIVE, *PEREGISTRY_HIVE; + // // Inlined functions // diff --git a/reactos/ntoskrnl/config/cmse.c b/reactos/ntoskrnl/config/cmse.c index c8299608fc6..a76ddf67632 100644 --- a/reactos/ntoskrnl/config/cmse.c +++ b/reactos/ntoskrnl/config/cmse.c @@ -44,7 +44,7 @@ CmpHiveRootSecurityDescriptor(VOID) if (!(Sid[0]) || !(Sid[1]) || !(Sid[2]) || !(Sid[3])) { /* Bugcheck */ - KEBUGCHECKEX(REGISTRY_ERROR, 2, 1, 0, 0); + KEBUGCHECKEX(REGISTRY_ERROR, 11, 1, 0, 0); } /* Phase 2: Initialize all SIDs */ @@ -52,7 +52,7 @@ CmpHiveRootSecurityDescriptor(VOID) Status |= RtlInitializeSid(Sid[1], &NtAuthority, 1); Status |= RtlInitializeSid(Sid[2], &NtAuthority, 1); Status |= RtlInitializeSid(Sid[3], &NtAuthority, 2); - if (!NT_SUCCESS(Status)) KEBUGCHECKEX(REGISTRY_ERROR, 2, 2, 0, 0); + if (!NT_SUCCESS(Status)) KEBUGCHECKEX(REGISTRY_ERROR, 11, 2, 0, 0); /* Phase 2: Setup SID Sub Authorities */ *RtlSubAuthoritySid(Sid[0], 0) = SECURITY_WORLD_RID; @@ -79,18 +79,18 @@ CmpHiveRootSecurityDescriptor(VOID) /* Phase 3: Allocate the ACL */ Acl = ExAllocatePoolWithTag(PagedPool, AclLength, TAG_CM); - if (!Acl) KEBUGCHECKEX(REGISTRY_ERROR, 2, 3, 0, 0); + if (!Acl) KEBUGCHECKEX(REGISTRY_ERROR, 11, 3, 0, 0); /* Phase 4: Create the ACL */ Status = RtlCreateAcl(Acl, AclLength, ACL_REVISION); - if (!NT_SUCCESS(Status)) KEBUGCHECKEX(REGISTRY_ERROR, 2, 4, Status, 0); + if (!NT_SUCCESS(Status)) KEBUGCHECKEX(REGISTRY_ERROR, 11, 4, Status, 0); /* Phase 5: Build the ACL */ Status = RtlAddAccessAllowedAce(Acl, ACL_REVISION, KEY_ALL_ACCESS, Sid[0]); Status |= RtlAddAccessAllowedAce(Acl, ACL_REVISION, KEY_ALL_ACCESS, Sid[1]); Status |= RtlAddAccessAllowedAce(Acl, ACL_REVISION, KEY_READ, Sid[2]); Status |= RtlAddAccessAllowedAce(Acl, ACL_REVISION, KEY_READ, Sid[3]); - if (!NT_SUCCESS(Status)) KEBUGCHECKEX(REGISTRY_ERROR, 2, 5, Status, 0); + if (!NT_SUCCESS(Status)) KEBUGCHECKEX(REGISTRY_ERROR, 11, 5, Status, 0); /* Phase 5: Make the ACEs inheritable */ Status = RtlGetAce(Acl, 0,( PVOID*)&AceHeader); @@ -111,7 +111,7 @@ CmpHiveRootSecurityDescriptor(VOID) sizeof(SECURITY_DESCRIPTOR) + AclLength, TAG_CM); - if (!SecurityDescriptor) KEBUGCHECKEX(REGISTRY_ERROR, 2, 6, 0, 0); + if (!SecurityDescriptor) KEBUGCHECKEX(REGISTRY_ERROR, 11, 6, 0, 0); /* Phase 6: Make a copy of the ACL */ AclCopy = (PACL)((PISECURITY_DESCRIPTOR)SecurityDescriptor + 1); @@ -120,14 +120,14 @@ CmpHiveRootSecurityDescriptor(VOID) /* Phase 7: Create the security descriptor */ Status = RtlCreateSecurityDescriptor(SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION); - if (!NT_SUCCESS(Status)) KEBUGCHECKEX(REGISTRY_ERROR, 2, 7, Status, 0); + if (!NT_SUCCESS(Status)) KEBUGCHECKEX(REGISTRY_ERROR, 11, 7, Status, 0); /* Phase 8: Set the ACL as a DACL */ Status = RtlSetDaclSecurityDescriptor(SecurityDescriptor, TRUE, AclCopy, FALSE); - if (!NT_SUCCESS(Status)) KEBUGCHECKEX(REGISTRY_ERROR, 2, 8, Status, 0); + if (!NT_SUCCESS(Status)) KEBUGCHECKEX(REGISTRY_ERROR, 11, 8, Status, 0); /* Free the SIDs and original ACL */ for (i = 0; i < 4; i++) ExFreePool(Sid[i]); diff --git a/reactos/ntoskrnl/config/cmsysini.c b/reactos/ntoskrnl/config/cmsysini.c index b71fcb4451e..4c580131b0d 100644 --- a/reactos/ntoskrnl/config/cmsysini.c +++ b/reactos/ntoskrnl/config/cmsysini.c @@ -15,11 +15,19 @@ /* GLOBALS *******************************************************************/ +HIVE_LIST_ENTRY CmpMachineHiveList[5]; + UNICODE_STRING CmSymbolicLinkValueName = RTL_CONSTANT_STRING(L"SymbolicLinkValue"); UNICODE_STRING CmpSystemStartOptions; UNICODE_STRING CmpLoadOptions; + +BOOLEAN CmpShareSystemHives; +BOOLEAN CmSelfHeal = TRUE; +BOOLEAN CmpSelfHeal = TRUE; +ULONG CmpBootType; + extern BOOLEAN ExpInTextModeSetup; /* FUNCTIONS *****************************************************************/ @@ -310,3 +318,165 @@ Cleanup: /* Return success */ return STATUS_SUCCESS; } + +BOOLEAN +NTAPI +CmpInitializeSystemHive(IN PLOADER_PARAMETER_BLOCK LoaderBlock) +{ + PVOID HiveBase; + ANSI_STRING LoadString; + PVOID Buffer; + ULONG Length; + NTSTATUS Status; + BOOLEAN Allocate; + UNICODE_STRING KeyName; + PEREGISTRY_HIVE SystemHive = NULL; + UNICODE_STRING HiveName = RTL_CONSTANT_STRING(L"SYSTEM"); + PSECURITY_DESCRIPTOR SecurityDescriptor; + PAGED_CODE(); + + /* Setup the ansi string */ + RtlInitAnsiString(&LoadString, LoaderBlock->LoadOptions); + + /* Allocate the unicode buffer */ + Length = LoadString.Length * sizeof(WCHAR) + sizeof(UNICODE_NULL); + Buffer = ExAllocatePoolWithTag(PagedPool, Length, 0); + if (!Buffer) + { + /* Fail */ + KEBUGCHECKEX(BAD_SYSTEM_CONFIG_INFO, 3, 1, (ULONG_PTR)LoaderBlock, 0); + } + + /* Setup the unicode string */ + RtlInitEmptyUnicodeString(&CmpLoadOptions, Buffer, Length); + + /* Add the load options and null-terminate */ + RtlAnsiStringToUnicodeString(&CmpLoadOptions, &LoadString, FALSE); + CmpLoadOptions.Buffer[LoadString.Length] = UNICODE_NULL; + CmpLoadOptions.Length += sizeof(WCHAR); + + /* Get the System Hive base address */ + HiveBase = LoaderBlock->RegistryBase; + if (HiveBase) + { + /* Import it */ + ((PHBASE_BLOCK)HiveBase)->Length = LoaderBlock->RegistryLength; + Status = CmpInitializeHive((PCMHIVE*)&SystemHive, + HINIT_MEMORY, + 0, //HIVE_NOLAZYFLUSH, + HFILE_TYPE_LOG, + HiveBase, + NULL, + NULL, + NULL, + &HiveName, + 2); + if (!NT_SUCCESS(Status)) return FALSE; + CmPrepareHive(&SystemHive->Hive); + + /* Set the hive filename */ + RtlCreateUnicodeString(&SystemHive->HiveFileName, SYSTEM_REG_FILE); + + /* Set the log filename */ + RtlCreateUnicodeString(&SystemHive->LogFileName, SYSTEM_LOG_FILE); + + /* We imported, no need to create a new hive */ + Allocate = FALSE; + + /* Manually set the hive as volatile, if in Live CD mode */ + if (CmpShareSystemHives) SystemHive->Hive.HiveFlags = HIVE_VOLATILE; + } + else + { +#if 0 + /* Create it */ + Status = CmpInitializeHive((PCMHIVE*)&SystemHive, + HINIT_CREATE, + HIVE_NOLAZYFLUSH, + HFILE_TYPE_LOG, + NULL, + NULL, + NULL, + NULL, + &HiveName, + 0); + if (!NT_SUCCESS(Status)) return FALSE; +#endif + + /* Tell CmpLinkHiveToMaster to allocate a hive */ + Allocate = TRUE; + } + + /* Save the boot type */ + if (SystemHive) CmpBootType = SystemHive->Hive.HiveHeader->BootType; + + /* Are we in self-healing mode? */ + if (!CmSelfHeal) + { + /* Disable self-healing internally and check if boot type wanted it */ + CmpSelfHeal = FALSE; + if (CmpBootType & 4) + { + /* We're disabled, so bugcheck */ + KEBUGCHECKEX(BAD_SYSTEM_CONFIG_INFO, + 3, + 3, + (ULONG_PTR)SystemHive, + 0); + } + } + + /* Create the default security descriptor */ + SecurityDescriptor = CmpHiveRootSecurityDescriptor(); + + /* Attach it to the system key */ + RtlInitUnicodeString(&KeyName, REG_SYSTEM_KEY_NAME); + Status = CmpLinkHiveToMaster(&KeyName, + NULL, + (PCMHIVE)SystemHive, + Allocate, + SecurityDescriptor); + + /* Free the security descriptor */ + ExFreePool(SecurityDescriptor); + if (!NT_SUCCESS(Status)) return FALSE; + + /* Add the hive to the hive list */ + CmpMachineHiveList[3].CmHive = (PCMHIVE)SystemHive; + + /* Success! */ + return TRUE; +} + +NTSTATUS +NTAPI +CmpCreateObjectTypes(VOID) +{ + OBJECT_TYPE_INITIALIZER ObjectTypeInitializer; + UNICODE_STRING Name; + GENERIC_MAPPING CmpKeyMapping = {KEY_READ, + KEY_WRITE, + KEY_EXECUTE, + KEY_ALL_ACCESS}; + PAGED_CODE(); + + /* Initialize the Key object type */ + RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer)); + RtlInitUnicodeString(&Name, L"Key"); + ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer); + ObjectTypeInitializer.DefaultPagedPoolCharge = sizeof(CM_KEY_BODY); + ObjectTypeInitializer.GenericMapping = CmpKeyMapping; + ObjectTypeInitializer.PoolType = PagedPool; + ObjectTypeInitializer.ValidAccessMask = KEY_ALL_ACCESS; + ObjectTypeInitializer.UseDefaultObject = TRUE; + ObjectTypeInitializer.DeleteProcedure = CmpDeleteKeyObject; + ObjectTypeInitializer.ParseProcedure = CmpParseKey; + ObjectTypeInitializer.SecurityProcedure = CmpSecurityMethod; + ObjectTypeInitializer.QueryNameProcedure = CmpQueryKeyName; + //ObjectTypeInitializer.CloseProcedure = CmpCloseKeyObject; + ObjectTypeInitializer.SecurityRequired = TRUE; + + /* Create it */ + return ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &CmpKeyObjectType); +} +