Author: ion
Date: Fri Oct 6 10:27:52 2006
New Revision: 24420
URL:
http://svn.reactos.org/svn/reactos?rev=24420&view=rev
Log:
- Define HIVE_LIST_ENTRY, CM_PARSE_CONTEXT.
- Stub CmpReportNotify.
- Implement CmpHiveRootSecurityDescriptor, CmpLinkHiveToMaster, CmpInitializeSystemHive.
- Rename CmInitializeRegistry to CmInitSystem1 and detect PE boot (/MININT).
Modified:
branches/alex-cm-branch/reactos/ntoskrnl/cm/cm.h
branches/alex-cm-branch/reactos/ntoskrnl/cm/cmapi.c
branches/alex-cm-branch/reactos/ntoskrnl/cm/cmhive.c
branches/alex-cm-branch/reactos/ntoskrnl/cm/cminit.c
Modified: branches/alex-cm-branch/reactos/ntoskrnl/cm/cm.h
URL:
http://svn.reactos.org/svn/reactos/branches/alex-cm-branch/reactos/ntoskrnl…
==============================================================================
--- branches/alex-cm-branch/reactos/ntoskrnl/cm/cm.h (original)
+++ branches/alex-cm-branch/reactos/ntoskrnl/cm/cm.h Fri Oct 6 10:27:52 2006
@@ -560,6 +560,40 @@
} CM_CACHED_VALUE, *PCM_CACHED_VALUE;
//
+// Hive List Entry
+//
+typedef struct _HIVE_LIST_ENTRY
+{
+ PWCHAR FileName;
+ PWCHAR BaseName;
+ PWCHAR RegRootName;
+ PCMHIVE CmHive;
+ ULONG HHiveFlags;
+ ULONG CmHiveFlags;
+ PCMHIVE CmHive2;
+ BOOLEAN ThreadFinished;
+ BOOLEAN ThreadStarted;
+ BOOLEAN Allocate;
+ BOOLEAN WinPERequired;
+} HIVE_LIST_ENTRY, *PHIVE_LIST_ENTRY;
+
+//
+// Parse context for Key Object
+//
+typedef struct _CM_PARSE_CONTEXT
+{
+ ULONG TitleIndex;
+ UNICODE_STRING Class;
+ ULONG CreateOptions;
+ ULONG Disposition;
+ CM_KEY_REFERENCE ChildHive;
+ BOOLEAN CreateLink;
+ BOOLEAN Flag2;
+ HANDLE PredefinedHandle;
+ ULONG PostActions;
+} CM_PARSE_CONTEXT, *PCM_PARSE_CONTEXT;
+
+//
// Registry Validation Functions
//
BOOLEAN
@@ -567,6 +601,17 @@
CmCheckRegistry(
IN PCMHIVE Hive,
IN BOOLEAN CleanFlag
+);
+
+//
+// Notification Routines
+//
+VOID
+CmpReportNotify(
+ IN PCM_KEY_CONTROL_BLOCK Kcb,
+ IN PHHIVE Hive,
+ IN HCELL_INDEX Cell,
+ IN ULONG Filter
);
//
@@ -666,6 +711,22 @@
IN PUNICODE_STRING FileName
);
+PSECURITY_DESCRIPTOR
+NTAPI
+CmpHiveRootSecurityDescriptor(
+ VOID
+);
+
+NTSTATUS
+NTAPI
+CmpLinkHiveToMaster(
+ IN PUNICODE_STRING LinkName,
+ IN HANDLE RootDirectory,
+ IN PCMHIVE CmHive,
+ IN BOOLEAN Allocate,
+ IN PSECURITY_DESCRIPTOR SecurityDescriptor
+);
+
//
// Registry Utility Functions
//
Modified: branches/alex-cm-branch/reactos/ntoskrnl/cm/cmapi.c
URL:
http://svn.reactos.org/svn/reactos/branches/alex-cm-branch/reactos/ntoskrnl…
==============================================================================
--- branches/alex-cm-branch/reactos/ntoskrnl/cm/cmapi.c (original)
+++ branches/alex-cm-branch/reactos/ntoskrnl/cm/cmapi.c Fri Oct 6 10:27:52 2006
@@ -43,3 +43,13 @@
ExReleasePushLock(&CmpHiveListHeadLock);
return Flushed;
}
+
+VOID
+CmpReportNotify(IN PCM_KEY_CONTROL_BLOCK Kcb,
+ IN PHHIVE Hive,
+ IN HCELL_INDEX Cell,
+ IN ULONG Filter)
+{
+ /* FIXME: TODO */
+ ASSERT(FALSE);
+}
Modified: branches/alex-cm-branch/reactos/ntoskrnl/cm/cmhive.c
URL:
http://svn.reactos.org/svn/reactos/branches/alex-cm-branch/reactos/ntoskrnl…
==============================================================================
--- branches/alex-cm-branch/reactos/ntoskrnl/cm/cmhive.c (original)
+++ branches/alex-cm-branch/reactos/ntoskrnl/cm/cmhive.c Fri Oct 6 10:27:52 2006
@@ -323,3 +323,243 @@
return STATUS_SUCCESS;
}
+PSECURITY_DESCRIPTOR
+NTAPI
+CmpHiveRootSecurityDescriptor(VOID)
+{
+ SID_IDENTIFIER_AUTHORITY WorldAuthority = SECURITY_WORLD_SID_AUTHORITY;
+ SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
+ PSID WorldSid;
+ PSID RestrictedSid;
+ PSID SystemSid;
+ PSID AdminSid;
+ NTSTATUS Status;
+ ULONG AceSize, AclSize;
+ PACL Acl, SdAcl;
+ PACE_HEADER AceHeader;
+ PSECURITY_DESCRIPTOR HiveSd;
+ PAGED_CODE();
+
+ /* Allocate all the SIDs */
+ WorldSid = ExAllocatePoolWithTag(PagedPool,
+ RtlLengthRequiredSid(1),
+ TAG_CM);
+ RestrictedSid = ExAllocatePoolWithTag(PagedPool,
+ RtlLengthRequiredSid(1),
+ TAG_CM);
+ SystemSid = ExAllocatePoolWithTag(PagedPool,
+ RtlLengthRequiredSid(1),
+ TAG_CM);
+ AdminSid = ExAllocatePoolWithTag(PagedPool,
+ RtlLengthRequiredSid(2),
+ TAG_CM);
+
+ /* Make sure that all were allocated */
+ if (!(WorldSid) || !(RestrictedSid) || !(SystemSid) || !(AdminSid))
+ {
+ /* Fail */
+ KeBugCheckEx(REGISTRY_ERROR, 10, 0, 0, 0);
+ }
+
+ /* Now initialize all the SIDs */
+ Status = RtlInitializeSid(WorldSid, &WorldAuthority, 1);
+ if (NT_SUCCESS(Status))
+ {
+ Status = RtlInitializeSid(RestrictedSid, &NtAuthority, 1);
+ }
+ if (NT_SUCCESS(Status))
+ {
+ Status = RtlInitializeSid(SystemSid, &NtAuthority, 1);
+ }
+ if (NT_SUCCESS(Status))
+ {
+ Status = RtlInitializeSid(AdminSid, &NtAuthority, 2);
+ }
+ if (NT_SUCCESS(Status)) KeBugCheckEx(REGISTRY_ERROR, 10, 1, 0, 0);
+
+ /* Setup the sub-authority SIDs */
+ *(RtlSubAuthoritySid(WorldSid, 0)) = SECURITY_WORLD_RID;
+ *(RtlSubAuthoritySid(RestrictedSid, 0)) = SECURITY_RESTRICTED_CODE_RID;
+ *(RtlSubAuthoritySid(SystemSid, 0)) = SECURITY_LOCAL_SYSTEM_RID;
+ *(RtlSubAuthoritySid(AdminSid, 0)) = SECURITY_BUILTIN_DOMAIN_RID;
+ *(RtlSubAuthoritySid(AdminSid, 1)) = DOMAIN_ALIAS_RID_ADMINS;
+
+ /* Sanity checks */
+ ASSERT(RtlValidSid(WorldSid));
+ ASSERT(RtlValidSid(RestrictedSid));
+ ASSERT(RtlValidSid(SystemSid));
+ ASSERT(RtlValidSid(AdminSid));
+
+ /* Calculate length of the ACE */
+ AceSize = (SeLengthSid(WorldSid) -
+ sizeof(ULONG) + sizeof(ACCESS_ALLOWED_ACE)) +
+ (SeLengthSid(RestrictedSid) -
+ sizeof(ULONG) + sizeof(ACCESS_ALLOWED_ACE))+
+ (SeLengthSid(SystemSid) -
+ sizeof(ULONG) + sizeof(ACCESS_ALLOWED_ACE)) +
+ (SeLengthSid(AdminSid) -
+ sizeof(ULONG) + sizeof(ACCESS_ALLOWED_ACE));
+
+ /* Calculate the ACL length and allocate it */
+ AclSize = AceSize + sizeof(ACL);
+ Acl = ExAllocatePoolWithTag(PagedPool, AclSize, TAG_CM);
+ if (!Acl) KeBugCheckEx(REGISTRY_ERROR, 10, 2, 0, 0);
+
+ /* Create it */
+ Status = RtlCreateAcl(Acl, AclSize, ACL_REVISION);
+ if (!NT_SUCCESS(Status)) KeBugCheckEx(REGISTRY_ERROR, 10, 3, 0, 0);
+
+ /* Add our ACEs */
+ Status = RtlAddAccessAllowedAce(Acl,
+ ACL_REVISION,
+ KEY_ALL_ACCESS,
+ SystemSid);
+ if (NT_SUCCESS(Status))
+ {
+ Status = RtlAddAccessAllowedAce(Acl,
+ ACL_REVISION,
+ KEY_ALL_ACCESS,
+ AdminSid);
+ }
+ if (NT_SUCCESS(Status))
+ {
+ Status = RtlAddAccessAllowedAce(Acl,
+ ACL_REVISION,
+ KEY_READ,
+ WorldSid);
+ }
+ if (NT_SUCCESS(Status))
+ {
+ Status = RtlAddAccessAllowedAce(Acl,
+ ACL_REVISION,
+ KEY_READ,
+ RestrictedSid);
+ }
+ if (!NT_SUCCESS(Status)) KeBugCheckEx(REGISTRY_ERROR, 10, 4, 0, 0);
+
+ /* Get every ACE and turn on the inherit flag */
+ Status = RtlGetAce(Acl,0,&AceHeader);
+ ASSERT(NT_SUCCESS(Status));
+ AceHeader->AceFlags |= CONTAINER_INHERIT_ACE;
+ Status = RtlGetAce(Acl,1,&AceHeader);
+ ASSERT(NT_SUCCESS(Status));
+ AceHeader->AceFlags |= CONTAINER_INHERIT_ACE;
+ Status = RtlGetAce(Acl,2,&AceHeader);
+ ASSERT(NT_SUCCESS(Status));
+ AceHeader->AceFlags |= CONTAINER_INHERIT_ACE;
+ Status = RtlGetAce(Acl,3,&AceHeader);
+ ASSERT(NT_SUCCESS(Status));
+ AceHeader->AceFlags |= CONTAINER_INHERIT_ACE;
+
+ /* Allocate the SD */
+ HiveSd = ExAllocatePoolWithTag(PagedPool,
+ AclSize + sizeof(SECURITY_DESCRIPTOR),
+ TAG_CM);
+ if (!HiveSd) KeBugCheckEx(REGISTRY_ERROR, 10, 5, 0, 0);
+
+ /* Copy the ACL into it */
+ SdAcl = (PACL)((PISECURITY_DESCRIPTOR)HiveSd + 1);
+ RtlMoveMemory(SdAcl, Acl, AclSize);
+
+ /* Create the SD */
+ Status = RtlCreateSecurityDescriptor(HiveSd, SECURITY_DESCRIPTOR_REVISION);
+ if (!NT_SUCCESS(Status))
+ {
+ /* Failed, free the descriptor and bugcheck */
+ ExFreePool(HiveSd);
+ KeBugCheckEx(REGISTRY_ERROR, 10, 6, 0, 0);
+ }
+
+ /* Set the DACL */
+ Status = RtlSetDaclSecurityDescriptor(HiveSd, TRUE, SdAcl, FALSE);
+ if (!NT_SUCCESS(Status))
+ {
+ /* Failed, free the descriptor and bugcheck */
+ ExFreePool(HiveSd);
+ KeBugCheckEx(REGISTRY_ERROR, 10, 7, 0, 0);
+ }
+
+ /* Free all allocations */
+ ExFreePool(WorldSid);
+ ExFreePool(RestrictedSid);
+ ExFreePool(SystemSid);
+ ExFreePool(AdminSid);
+ ExFreePool(Acl);
+
+ /* Return the SD */
+ return HiveSd;
+}
+
+NTSTATUS
+NTAPI
+CmpLinkHiveToMaster(IN PUNICODE_STRING LinkName,
+ IN HANDLE RootDirectory,
+ IN PCMHIVE CmHive,
+ IN BOOLEAN Allocate,
+ IN PSECURITY_DESCRIPTOR SecurityDescriptor)
+{
+ CM_PARSE_CONTEXT ParseContext;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ HANDLE KeyHandle;
+ NTSTATUS Status;
+ PCM_KEY_BODY KeyBody;
+ PAGED_CODE();
+
+ /* Fill out the parse context */
+ ParseContext.TitleIndex = 0;
+ ParseContext.Class.Length = 0;
+ ParseContext.Class.MaximumLength = 0;
+ ParseContext.Class.Buffer = NULL;
+ ParseContext.CreateOptions = 0;
+ ParseContext.CreateLink = TRUE;
+ ParseContext.Flag2 = TRUE;
+ ParseContext.PostActions = 0;
+ ParseContext.ChildHive.KeyHive = &CmHive->Hive;
+
+ /* Check if we're allocating */
+ if (Allocate)
+ {
+ /* Set no child */
+ ParseContext.ChildHive.KeyCell = HCELL_NIL;
+ }
+ else
+ {
+ /* Otherwise, set the root cell */
+ ParseContext.ChildHive.KeyCell = CmHive->Hive.HiveHeader->RootCell;
+ }
+
+ /* Open the key */
+ InitializeObjectAttributes(&ObjectAttributes,
+ LinkName,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+ RootDirectory,
+ SecurityDescriptor);
+ Status = ObOpenObjectByName(&ObjectAttributes,
+ CmpKeyObjectType,
+ KernelMode,
+ NULL,
+ KEY_READ | KEY_WRITE,
+ &ParseContext,
+ &KeyHandle);
+ if (!NT_SUCCESS(Status)) return Status;
+
+ /* Reference the key body */
+ Status = ObReferenceObjectByHandle(KeyHandle,
+ 0,
+ CmpKeyObjectType,
+ KernelMode,
+ &KeyBody,
+ NULL);
+ ASSERT(NT_SUCCESS(Status));
+
+ /* Send a notification */
+ CmpReportNotify(KeyBody->KeyControlBlock,
+ KeyBody->KeyControlBlock->KeyHive,
+ KeyBody->KeyControlBlock->KeyCell,
+ REG_NOTIFY_CHANGE_NAME);
+
+ /* Dereference the key and close the handle */
+ ObDereferenceObject((PVOID)KeyBody);
+ ZwClose(KeyHandle);
+ return STATUS_SUCCESS;
+}
Modified: branches/alex-cm-branch/reactos/ntoskrnl/cm/cminit.c
URL:
http://svn.reactos.org/svn/reactos/branches/alex-cm-branch/reactos/ntoskrnl…
==============================================================================
--- branches/alex-cm-branch/reactos/ntoskrnl/cm/cminit.c (original)
+++ branches/alex-cm-branch/reactos/ntoskrnl/cm/cminit.c Fri Oct 6 10:27:52 2006
@@ -12,16 +12,29 @@
#define NDEBUG
#include <debug.h>
+UNICODE_STRING CmRegistryMachineSystemName =
+ RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\SYSTEM");
+UNICODE_STRING CmpSystemFileName =
+ RTL_CONSTANT_STRING(L"SYSTEM");
+
+BOOLEAN CmpMiniNTBoot;
+BOOLEAN CmpShareSystemHives;
+ULONG CmpBootType;
+
PEPROCESS CmpSystemProcess;
PCMHIVE CmpMasterHive;
HANDLE CmpRegistryRootHandle;
+BOOLEAN CmSelfHeal, CmpSelfHeal;
KGUARDED_MUTEX CmpSelfHealQueueLock;
LIST_ENTRY CmpSelfHealQueueListHead;
+HIVE_LIST_ENTRY CmpMachineHiveList[];
+
EX_PUSH_LOCK CmpLoadHiveLock;
UNICODE_STRING CmpSystemStartOptions;
+UNICODE_STRING CmpLoadOptions;
ULONG CmpCallBackCount;
@@ -237,9 +250,113 @@
NtClose(KeyHandle);
}
+BOOLEAN
+NTAPI
+CmpInitializeSystemHive(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
+{
+ PCMHIVE SystemHive;
+ PVOID HiveImageBase;
+ BOOLEAN Allocate = FALSE;
+ PSECURITY_DESCRIPTOR SecurityDescriptor;
+ NTSTATUS Status;
+ STRING TempString;
+ PAGED_CODE();
+
+ /* Create ANSI_STRING from the loader options */
+ RtlInitAnsiString(&TempString, LoaderBlock->LoadOptions);
+
+ /* Setup UNICODE_STRING */
+ CmpLoadOptions.Length = 0;
+ CmpLoadOptions.MaximumLength = TempString.Length * sizeof(WCHAR) +
+ sizeof(UNICODE_NULL);
+ CmpLoadOptions.Buffer = ExAllocatePoolWithTag(PagedPool,
+ CmpLoadOptions.MaximumLength,
+ TAG_CM);
+ if (!CmpLoadOptions.Buffer)
+ {
+ /* Fail */
+ KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 5, 6, 0, 0);
+ }
+
+ /* Convert it to Unicode and nul-terminate it */
+ RtlAnsiStringToUnicodeString(&CmpLoadOptions, &TempString, FALSE);
+ CmpLoadOptions.Buffer[TempString.Length] = UNICODE_NULL;
+ CmpLoadOptions.Length += sizeof(WCHAR);
+
+ /* Get the image base */
+ HiveImageBase = LoaderBlock->RegistryBase;
+ if (!HiveImageBase)
+ {
+ /* Don't have a system hive, create it */
+ Status = CmpInitializeHive(&SystemHive,
+ HINIT_CREATE,
+ 0,
+ HFILE_TYPE_ALTERNATE,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ &CmpSystemFileName);
+ if (!NT_SUCCESS(Status)) return FALSE;
+ Allocate = TRUE;
+ }
+ else
+ {
+ /* Make a copy of the loaded hive */
+ Status = CmpInitializeHive(&SystemHive,
+ HINIT_MEMORY,
+ 0,
+ HFILE_TYPE_ALTERNATE,
+ HiveImageBase,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ &CmpSystemFileName);
+ if (!NT_SUCCESS(Status)) return FALSE;
+
+ /* Check if we loaded with shared hives */
+ if (CmpShareSystemHives) SystemHive->Hive.HvBinHeadersUse = 0;
+
+ /* Set the boot type */
+ CmpBootType = SystemHive->Hive.HiveHeader->BootType;
+
+ /* Check if we loaded in self-healing mode */
+ if (!CmSelfHeal)
+ {
+ /* We didn't, check the boot type */
+ if (CmpBootType & 4)
+ {
+ /* Invalid boot type */
+ CmpSelfHeal = FALSE;
+ KeBugCheckEx(REGISTRY_ERROR, 3, 3, (ULONG_PTR)SystemHive, 0);
+ }
+ }
+ }
+
+ /* Create security descriptor */
+ SecurityDescriptor = CmpHiveRootSecurityDescriptor();
+
+ /* Link the hive to the master */
+ Status = CmpLinkHiveToMaster(&CmRegistryMachineSystemName,
+ NULL,
+ SystemHive,
+ Allocate,
+ SecurityDescriptor);
+
+ /* Free the descriptor and check for success */
+ ExFreePool(SecurityDescriptor);
+ if (!NT_SUCCESS(Status)) return FALSE;
+
+ /* Save the hive */
+ CmpMachineHiveList[3].CmHive = SystemHive;
+ return TRUE;
+}
+
VOID
NTAPI
-CmInitializeRegistry(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
+CmInitSystem1(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING KeyName;
@@ -248,6 +365,14 @@
HANDLE KeyHandle;
NTSTATUS Status;
PAGED_CODE();
+
+ /* Check if this is PE-boot */
+ if (ExpIsWinPEMode)
+ {
+ /* Set registry to PE mode */
+ CmpMiniNTBoot = TRUE;
+ CmpShareSystemHives = TRUE;
+ }
/* Initialize the hive list and lock */
InitializeListHead(&CmpHiveListHead);