mirror of
https://github.com/reactos/reactos.git
synced 2025-04-26 16:40:27 +00:00
- 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:
parent
010910bc34
commit
703c503a4f
7 changed files with 242 additions and 161 deletions
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
//
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue