- 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
This commit is contained in:
Alex Ionescu 2007-05-11 18:58:34 +00:00
parent 010910bc34
commit 703c503a4f
7 changed files with 242 additions and 161 deletions

View file

@ -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)
{

View file

@ -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);

View file

@ -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,

View file

@ -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;
}

View file

@ -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
//

View file

@ -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]);

View file

@ -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);
}