- 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 PEREGISTRY_HIVE CmiVolatileHive;
extern POBJECT_TYPE CmiKeyType; extern POBJECT_TYPE CmpKeyObjectType;
extern KSPIN_LOCK CmiKeyListLock; extern KSPIN_LOCK CmiKeyListLock;
extern LIST_ENTRY CmiHiveListHead; extern LIST_ENTRY CmiHiveListHead;
@ -148,7 +148,7 @@ NTSTATUS STDCALL
CmUnRegisterCallback(IN LARGE_INTEGER Cookie); CmUnRegisterCallback(IN LARGE_INTEGER Cookie);
NTSTATUS STDCALL NTSTATUS STDCALL
CmiObjectParse(IN PVOID ParsedObject, CmpParseKey(IN PVOID ParsedObject,
IN PVOID ObjectType, IN PVOID ObjectType,
IN OUT PACCESS_STATE AccessState, IN OUT PACCESS_STATE AccessState,
IN KPROCESSOR_MODE AccessMode, IN KPROCESSOR_MODE AccessMode,
@ -160,10 +160,10 @@ CmiObjectParse(IN PVOID ParsedObject,
OUT PVOID *NextObject); OUT PVOID *NextObject);
VOID STDCALL VOID STDCALL
CmiObjectDelete(PVOID DeletedObject); CmpDeleteKeyObject(PVOID DeletedObject);
NTSTATUS STDCALL NTSTATUS STDCALL
CmiObjectSecurity(PVOID ObjectBody, CmpSecurityMethod(PVOID ObjectBody,
SECURITY_OPERATION_CODE OperationCode, SECURITY_OPERATION_CODE OperationCode,
PSECURITY_INFORMATION SecurityInformation, PSECURITY_INFORMATION SecurityInformation,
PSECURITY_DESCRIPTOR SecurityDescriptor, PSECURITY_DESCRIPTOR SecurityDescriptor,
@ -173,7 +173,7 @@ CmiObjectSecurity(PVOID ObjectBody,
PGENERIC_MAPPING GenericMapping); PGENERIC_MAPPING GenericMapping);
NTSTATUS STDCALL NTSTATUS STDCALL
CmiObjectQueryName (PVOID ObjectBody, CmpQueryKeyName (PVOID ObjectBody,
IN BOOLEAN HasObjectName, IN BOOLEAN HasObjectName,
POBJECT_NAME_INFORMATION ObjectNameInfo, POBJECT_NAME_INFORMATION ObjectNameInfo,
ULONG Length, ULONG Length,
@ -478,6 +478,14 @@ PSECURITY_DESCRIPTOR
NTAPI NTAPI
CmpHiveRootSecurityDescriptor(VOID); CmpHiveRootSecurityDescriptor(VOID);
BOOLEAN
NTAPI
CmpInitializeSystemHive(IN PLOADER_PARAMETER_BLOCK LoaderBlock);
NTSTATUS
NTAPI
CmpCreateObjectTypes(VOID);
#if 0 #if 0
static __inline PVOID xHvGetCell(char *file, int line, PHHIVE Hive, HCELL_INDEX Cell) static __inline PVOID xHvGetCell(char *file, int line, PHHIVE Hive, HCELL_INDEX Cell)
{ {

View file

@ -24,7 +24,7 @@
/* GLOBALS ******************************************************************/ /* GLOBALS ******************************************************************/
extern POBJECT_TYPE CmiKeyType; extern POBJECT_TYPE CmpKeyObjectType;
extern LIST_ENTRY CmiKeyObjectListHead; extern LIST_ENTRY CmiKeyObjectListHead;
static BOOLEAN CmiRegistryInitialized = FALSE; static BOOLEAN CmiRegistryInitialized = FALSE;
@ -218,7 +218,7 @@ NtCreateKey(OUT PHANDLE KeyHandle,
&ObjectName, &ObjectName,
(PVOID*)&Object, (PVOID*)&Object,
&RemainingPath, &RemainingPath,
CmiKeyType, CmpKeyObjectType,
NULL, NULL,
NULL); NULL);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
@ -300,7 +300,7 @@ NtCreateKey(OUT PHANDLE KeyHandle,
DPRINT("RemainingPath %S ParentObject 0x%p\n", RemainingPath.Buffer, Object); DPRINT("RemainingPath %S ParentObject 0x%p\n", RemainingPath.Buffer, Object);
Status = ObCreateObject(PreviousMode, Status = ObCreateObject(PreviousMode,
CmiKeyType, CmpKeyObjectType,
NULL, NULL,
PreviousMode, PreviousMode,
NULL, NULL,
@ -452,7 +452,7 @@ NtDeleteKey(IN HANDLE KeyHandle)
/* Verify that the handle is valid and is a registry key */ /* Verify that the handle is valid and is a registry key */
Status = ObReferenceObjectByHandle(KeyHandle, Status = ObReferenceObjectByHandle(KeyHandle,
DELETE, DELETE,
CmiKeyType, CmpKeyObjectType,
PreviousMode, PreviousMode,
(PVOID *)&KeyObject, (PVOID *)&KeyObject,
NULL); NULL);
@ -516,7 +516,7 @@ NtDeleteKey(IN HANDLE KeyHandle)
/* /*
* Note: * Note:
* Hive-Synchronization will not be triggered here. This is done in * 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. * have been released.
*/ */
@ -563,7 +563,7 @@ NtEnumerateKey(IN HANDLE KeyHandle,
/* Verify that the handle is valid and is a registry key */ /* Verify that the handle is valid and is a registry key */
Status = ObReferenceObjectByHandle(KeyHandle, Status = ObReferenceObjectByHandle(KeyHandle,
KEY_ENUMERATE_SUB_KEYS, KEY_ENUMERATE_SUB_KEYS,
CmiKeyType, CmpKeyObjectType,
PreviousMode, PreviousMode,
(PVOID *) &KeyObject, (PVOID *) &KeyObject,
NULL); NULL);
@ -863,7 +863,7 @@ NtEnumerateValueKey(IN HANDLE KeyHandle,
/* Verify that the handle is valid and is a registry key */ /* Verify that the handle is valid and is a registry key */
Status = ObReferenceObjectByHandle(KeyHandle, Status = ObReferenceObjectByHandle(KeyHandle,
KEY_QUERY_VALUE, KEY_QUERY_VALUE,
CmiKeyType, CmpKeyObjectType,
ExGetPreviousMode(), ExGetPreviousMode(),
(PVOID *) &KeyObject, (PVOID *) &KeyObject,
NULL); NULL);
@ -1116,7 +1116,7 @@ NtFlushKey(IN HANDLE KeyHandle)
/* Verify that the handle is valid and is a registry key */ /* Verify that the handle is valid and is a registry key */
Status = ObReferenceObjectByHandle(KeyHandle, Status = ObReferenceObjectByHandle(KeyHandle,
0, 0,
CmiKeyType, CmpKeyObjectType,
PreviousMode, PreviousMode,
(PVOID *)&KeyObject, (PVOID *)&KeyObject,
NULL); NULL);
@ -1244,7 +1244,7 @@ NtOpenKey(OUT PHANDLE KeyHandle,
&ObjectName, &ObjectName,
(PVOID*)&Object, (PVOID*)&Object,
&RemainingPath, &RemainingPath,
CmiKeyType, CmpKeyObjectType,
NULL, NULL,
NULL); NULL);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
@ -1340,7 +1340,7 @@ NtQueryKey(IN HANDLE KeyHandle,
/* Verify that the handle is valid and is a registry key */ /* Verify that the handle is valid and is a registry key */
Status = ObReferenceObjectByHandle(KeyHandle, Status = ObReferenceObjectByHandle(KeyHandle,
(KeyInformationClass != KeyNameInformation ? KEY_QUERY_VALUE : 0), (KeyInformationClass != KeyNameInformation ? KEY_QUERY_VALUE : 0),
CmiKeyType, CmpKeyObjectType,
ExGetPreviousMode(), ExGetPreviousMode(),
(PVOID *) &KeyObject, (PVOID *) &KeyObject,
NULL); NULL);
@ -1566,7 +1566,7 @@ NtQueryValueKey(IN HANDLE KeyHandle,
/* Verify that the handle is valid and is a registry key */ /* Verify that the handle is valid and is a registry key */
Status = ObReferenceObjectByHandle(KeyHandle, Status = ObReferenceObjectByHandle(KeyHandle,
KEY_QUERY_VALUE, KEY_QUERY_VALUE,
CmiKeyType, CmpKeyObjectType,
ExGetPreviousMode(), ExGetPreviousMode(),
(PVOID *)&KeyObject, (PVOID *)&KeyObject,
NULL); NULL);
@ -1830,7 +1830,7 @@ NtSetValueKey(IN HANDLE KeyHandle,
/* Verify that the handle is valid and is a registry key */ /* Verify that the handle is valid and is a registry key */
Status = ObReferenceObjectByHandle(KeyHandle, Status = ObReferenceObjectByHandle(KeyHandle,
DesiredAccess, DesiredAccess,
CmiKeyType, CmpKeyObjectType,
ExGetPreviousMode(), ExGetPreviousMode(),
(PVOID *)&KeyObject, (PVOID *)&KeyObject,
NULL); NULL);
@ -2005,7 +2005,7 @@ NtDeleteValueKey (IN HANDLE KeyHandle,
/* Verify that the handle is valid and is a registry key */ /* Verify that the handle is valid and is a registry key */
Status = ObReferenceObjectByHandle(KeyHandle, Status = ObReferenceObjectByHandle(KeyHandle,
KEY_SET_VALUE, KEY_SET_VALUE,
CmiKeyType, CmpKeyObjectType,
PreviousMode, PreviousMode,
(PVOID *)&KeyObject, (PVOID *)&KeyObject,
NULL); NULL);
@ -2218,7 +2218,7 @@ NtQueryMultipleValueKey (IN HANDLE KeyHandle,
/* Verify that the handle is valid and is a registry key */ /* Verify that the handle is valid and is a registry key */
Status = ObReferenceObjectByHandle(KeyHandle, Status = ObReferenceObjectByHandle(KeyHandle,
KEY_QUERY_VALUE, KEY_QUERY_VALUE,
CmiKeyType, CmpKeyObjectType,
ExGetPreviousMode(), ExGetPreviousMode(),
(PVOID *) &KeyObject, (PVOID *) &KeyObject,
NULL); NULL);

View file

@ -29,7 +29,7 @@
extern BOOLEAN ExpInTextModeSetup; extern BOOLEAN ExpInTextModeSetup;
POBJECT_TYPE CmiKeyType = NULL; POBJECT_TYPE CmpKeyObjectType = NULL;
PEREGISTRY_HIVE CmiVolatileHive = NULL; PEREGISTRY_HIVE CmiVolatileHive = NULL;
LIST_ENTRY CmiHiveListHead; LIST_ENTRY CmiHiveListHead;
@ -46,9 +46,6 @@ volatile BOOLEAN CmiHiveSyncPending = FALSE;
KDPC CmiHiveSyncDpc; KDPC CmiHiveSyncDpc;
KTIMER CmiHiveSyncTimer; KTIMER CmiHiveSyncTimer;
static GENERIC_MAPPING CmiKeyMapping =
{KEY_READ, KEY_WRITE, KEY_EXECUTE, KEY_ALL_ACCESS};
static VOID STDCALL static VOID STDCALL
CmiHiveSyncDpcRoutine(PKDPC Dpc, CmiHiveSyncDpcRoutine(PKDPC Dpc,
PVOID DeferredContext, PVOID DeferredContext,
@ -186,118 +183,6 @@ CmpLinkHiveToMaster(IN PUNICODE_STRING LinkName,
return CmiConnectHive(&ObjectAttributes, RegistryHive); 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 BOOLEAN
NTAPI NTAPI
CmpCreateRootNode(IN PHHIVE Hive, CmpCreateRootNode(IN PHHIVE Hive,
@ -381,7 +266,7 @@ CmpCreateRegistryRoot(VOID)
NULL, NULL,
NULL); NULL);
Status = ObCreateObject(KernelMode, Status = ObCreateObject(KernelMode,
CmiKeyType, CmpKeyObjectType,
&ObjectAttributes, &ObjectAttributes,
KernelMode, KernelMode,
NULL, NULL,
@ -675,7 +560,7 @@ CmiConnectHive(IN POBJECT_ATTRIBUTES KeyObjectAttributes,
&ObjectName, &ObjectName,
(PVOID*)&ParentKey, (PVOID*)&ParentKey,
&RemainingPath, &RemainingPath,
CmiKeyType, CmpKeyObjectType,
NULL, NULL,
NULL); NULL);
/* Yields a new reference */ /* Yields a new reference */
@ -714,7 +599,7 @@ CmiConnectHive(IN POBJECT_ATTRIBUTES KeyObjectAttributes,
&RemainingPath, ParentKey); &RemainingPath, ParentKey);
Status = ObCreateObject(KernelMode, Status = ObCreateObject(KernelMode,
CmiKeyType, CmpKeyObjectType,
NULL, NULL,
KernelMode, KernelMode,
NULL, NULL,

View file

@ -174,7 +174,7 @@ CmFindObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo,
{ {
ObReferenceObjectByPointer(ObpRootDirectoryObject, ObReferenceObjectByPointer(ObpRootDirectoryObject,
DIRECTORY_TRAVERSE, DIRECTORY_TRAVERSE,
CmiKeyType, CmpKeyObjectType,
ObjectCreateInfo->ProbeMode); ObjectCreateInfo->ProbeMode);
CurrentObject = ObpRootDirectoryObject; CurrentObject = ObpRootDirectoryObject;
} }
@ -267,7 +267,7 @@ CmFindObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo,
ObReferenceObjectByPointer(FoundObject, ObReferenceObjectByPointer(FoundObject,
STANDARD_RIGHTS_REQUIRED, STANDARD_RIGHTS_REQUIRED,
CmiKeyType, CmpKeyObjectType,
KernelMode); KernelMode);
if (End != NULL) if (End != NULL)
{ {
@ -317,7 +317,7 @@ Next:
ObReferenceObjectByPointer(NextObject, ObReferenceObjectByPointer(NextObject,
DIRECTORY_TRAVERSE, DIRECTORY_TRAVERSE,
CmiKeyType, CmpKeyObjectType,
ObjectCreateInfo->ProbeMode); ObjectCreateInfo->ProbeMode);
} }
@ -342,7 +342,7 @@ Next:
} }
NTSTATUS STDCALL NTSTATUS STDCALL
CmiObjectParse(IN PVOID ParsedObject, CmpParseKey(IN PVOID ParsedObject,
IN PVOID ObjectType, IN PVOID ObjectType,
IN OUT PACCESS_STATE AccessState, IN OUT PACCESS_STATE AccessState,
IN KPROCESSOR_MODE AccessMode, IN KPROCESSOR_MODE AccessMode,
@ -481,9 +481,9 @@ CmiObjectParse(IN PVOID ParsedObject,
} }
/* Create new key object and put into linked list */ /* Create new key object and put into linked list */
DPRINT("CmiObjectParse: %S\n", *Path); DPRINT("CmpParseKey: %S\n", *Path);
Status = ObCreateObject(KernelMode, Status = ObCreateObject(KernelMode,
CmiKeyType, CmpKeyObjectType,
NULL, NULL,
KernelMode, KernelMode,
NULL, NULL,
@ -586,7 +586,7 @@ OBJECT_TO_OBJECT_HEADER(FoundObject)->ObjectCreateInfo = NULL;
ExReleaseResourceLite(&CmiRegistryLock); ExReleaseResourceLite(&CmiRegistryLock);
KeLeaveCriticalRegion(); KeLeaveCriticalRegion();
DPRINT("CmiObjectParse: %wZ\n", &FoundObject->Name); DPRINT("CmpParseKey: %wZ\n", &FoundObject->Name);
*Path = EndPtr; *Path = EndPtr;
@ -600,7 +600,7 @@ OBJECT_TO_OBJECT_HEADER(FoundObject)->ObjectCreateInfo = NULL;
} }
VOID STDCALL VOID STDCALL
CmiObjectDelete(PVOID DeletedObject) CmpDeleteKeyObject(PVOID DeletedObject)
{ {
PKEY_OBJECT ParentKeyObject; PKEY_OBJECT ParentKeyObject;
PKEY_OBJECT KeyObject; PKEY_OBJECT KeyObject;
@ -789,7 +789,7 @@ CmiAssignSecurityDescriptor(PKEY_OBJECT KeyObject,
NTSTATUS STDCALL NTSTATUS STDCALL
CmiObjectSecurity(PVOID ObjectBody, CmpSecurityMethod(PVOID ObjectBody,
SECURITY_OPERATION_CODE OperationCode, SECURITY_OPERATION_CODE OperationCode,
PSECURITY_INFORMATION SecurityInformation, PSECURITY_INFORMATION SecurityInformation,
PSECURITY_DESCRIPTOR SecurityDescriptor, PSECURITY_DESCRIPTOR SecurityDescriptor,
@ -798,7 +798,7 @@ CmiObjectSecurity(PVOID ObjectBody,
POOL_TYPE PoolType, POOL_TYPE PoolType,
PGENERIC_MAPPING GenericMapping) PGENERIC_MAPPING GenericMapping)
{ {
DPRINT("CmiObjectSecurity() called\n"); DPRINT("CmpSecurityMethod() called\n");
switch (OperationCode) switch (OperationCode)
{ {
@ -828,7 +828,7 @@ CmiObjectSecurity(PVOID ObjectBody,
NTSTATUS STDCALL NTSTATUS STDCALL
CmiObjectQueryName (PVOID ObjectBody, CmpQueryKeyName (PVOID ObjectBody,
IN BOOLEAN HasName, IN BOOLEAN HasName,
POBJECT_NAME_INFORMATION ObjectNameInfo, POBJECT_NAME_INFORMATION ObjectNameInfo,
ULONG Length, ULONG Length,
@ -838,7 +838,7 @@ CmiObjectQueryName (PVOID ObjectBody,
PKEY_OBJECT KeyObject; PKEY_OBJECT KeyObject;
NTSTATUS Status; NTSTATUS Status;
DPRINT ("CmiObjectQueryName() called\n"); DPRINT ("CmpQueryKeyName() called\n");
KeyObject = (PKEY_OBJECT)ObjectBody; KeyObject = (PKEY_OBJECT)ObjectBody;
@ -931,7 +931,7 @@ CmiAddKeyToList(PKEY_OBJECT ParentKey,
ObReferenceObjectByPointer(ParentKey, ObReferenceObjectByPointer(ParentKey,
STANDARD_RIGHTS_REQUIRED, STANDARD_RIGHTS_REQUIRED,
CmiKeyType, CmpKeyObjectType,
KernelMode); KernelMode);
NewKey->ParentKey = ParentKey; NewKey->ParentKey = ParentKey;
} }

View file

@ -767,10 +767,10 @@ CmpInitializeHive(
IN ULONG FileType, IN ULONG FileType,
IN PVOID HiveData, IN PVOID HiveData,
IN HANDLE Primary, IN HANDLE Primary,
IN HANDLE Alternate,
IN HANDLE Log, IN HANDLE Log,
IN HANDLE External, IN HANDLE External,
IN PUNICODE_STRING FileName IN PUNICODE_STRING FileName,
IN ULONG CheckFlags
); );
PSECURITY_DESCRIPTOR PSECURITY_DESCRIPTOR
@ -982,6 +982,24 @@ extern PCM_FULL_RESOURCE_DESCRIPTOR CmpConfigurationData;
extern UNICODE_STRING CmTypeName[]; extern UNICODE_STRING CmTypeName[];
extern BOOLEAN ExpInTextModeSetup; 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 // Inlined functions
// //

View file

@ -44,7 +44,7 @@ CmpHiveRootSecurityDescriptor(VOID)
if (!(Sid[0]) || !(Sid[1]) || !(Sid[2]) || !(Sid[3])) if (!(Sid[0]) || !(Sid[1]) || !(Sid[2]) || !(Sid[3]))
{ {
/* Bugcheck */ /* Bugcheck */
KEBUGCHECKEX(REGISTRY_ERROR, 2, 1, 0, 0); KEBUGCHECKEX(REGISTRY_ERROR, 11, 1, 0, 0);
} }
/* Phase 2: Initialize all SIDs */ /* Phase 2: Initialize all SIDs */
@ -52,7 +52,7 @@ CmpHiveRootSecurityDescriptor(VOID)
Status |= RtlInitializeSid(Sid[1], &NtAuthority, 1); Status |= RtlInitializeSid(Sid[1], &NtAuthority, 1);
Status |= RtlInitializeSid(Sid[2], &NtAuthority, 1); Status |= RtlInitializeSid(Sid[2], &NtAuthority, 1);
Status |= RtlInitializeSid(Sid[3], &NtAuthority, 2); 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 */ /* Phase 2: Setup SID Sub Authorities */
*RtlSubAuthoritySid(Sid[0], 0) = SECURITY_WORLD_RID; *RtlSubAuthoritySid(Sid[0], 0) = SECURITY_WORLD_RID;
@ -79,18 +79,18 @@ CmpHiveRootSecurityDescriptor(VOID)
/* Phase 3: Allocate the ACL */ /* Phase 3: Allocate the ACL */
Acl = ExAllocatePoolWithTag(PagedPool, AclLength, TAG_CM); 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 */ /* Phase 4: Create the ACL */
Status = RtlCreateAcl(Acl, AclLength, ACL_REVISION); 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 */ /* Phase 5: Build the ACL */
Status = RtlAddAccessAllowedAce(Acl, ACL_REVISION, KEY_ALL_ACCESS, Sid[0]); 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_ALL_ACCESS, Sid[1]);
Status |= RtlAddAccessAllowedAce(Acl, ACL_REVISION, KEY_READ, Sid[2]); Status |= RtlAddAccessAllowedAce(Acl, ACL_REVISION, KEY_READ, Sid[2]);
Status |= RtlAddAccessAllowedAce(Acl, ACL_REVISION, KEY_READ, Sid[3]); 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 */ /* Phase 5: Make the ACEs inheritable */
Status = RtlGetAce(Acl, 0,( PVOID*)&AceHeader); Status = RtlGetAce(Acl, 0,( PVOID*)&AceHeader);
@ -111,7 +111,7 @@ CmpHiveRootSecurityDescriptor(VOID)
sizeof(SECURITY_DESCRIPTOR) + sizeof(SECURITY_DESCRIPTOR) +
AclLength, AclLength,
TAG_CM); 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 */ /* Phase 6: Make a copy of the ACL */
AclCopy = (PACL)((PISECURITY_DESCRIPTOR)SecurityDescriptor + 1); AclCopy = (PACL)((PISECURITY_DESCRIPTOR)SecurityDescriptor + 1);
@ -120,14 +120,14 @@ CmpHiveRootSecurityDescriptor(VOID)
/* Phase 7: Create the security descriptor */ /* Phase 7: Create the security descriptor */
Status = RtlCreateSecurityDescriptor(SecurityDescriptor, Status = RtlCreateSecurityDescriptor(SecurityDescriptor,
SECURITY_DESCRIPTOR_REVISION); 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 */ /* Phase 8: Set the ACL as a DACL */
Status = RtlSetDaclSecurityDescriptor(SecurityDescriptor, Status = RtlSetDaclSecurityDescriptor(SecurityDescriptor,
TRUE, TRUE,
AclCopy, AclCopy,
FALSE); 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 */ /* Free the SIDs and original ACL */
for (i = 0; i < 4; i++) ExFreePool(Sid[i]); for (i = 0; i < 4; i++) ExFreePool(Sid[i]);

View file

@ -15,11 +15,19 @@
/* GLOBALS *******************************************************************/ /* GLOBALS *******************************************************************/
HIVE_LIST_ENTRY CmpMachineHiveList[5];
UNICODE_STRING CmSymbolicLinkValueName = UNICODE_STRING CmSymbolicLinkValueName =
RTL_CONSTANT_STRING(L"SymbolicLinkValue"); RTL_CONSTANT_STRING(L"SymbolicLinkValue");
UNICODE_STRING CmpSystemStartOptions; UNICODE_STRING CmpSystemStartOptions;
UNICODE_STRING CmpLoadOptions; UNICODE_STRING CmpLoadOptions;
BOOLEAN CmpShareSystemHives;
BOOLEAN CmSelfHeal = TRUE;
BOOLEAN CmpSelfHeal = TRUE;
ULONG CmpBootType;
extern BOOLEAN ExpInTextModeSetup; extern BOOLEAN ExpInTextModeSetup;
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
@ -310,3 +318,165 @@ Cleanup:
/* Return success */ /* Return success */
return STATUS_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);
}