[ros-diffs] [ion] 26669: - Refactor the registry initialization code to be somewhat closer to the Cm rewrite branch. - No actual code/implementation changes per-se, simply moved code into new routines, deleted old routines, renamed some routines and added more error-checking. - Also performed registry initialization in an order more analogous to Windows. - Added cmsysini.c from the branch, but it's not used at the moment.

ion at svn.reactos.org ion at svn.reactos.org
Thu May 10 02:02:05 CEST 2007


Author: ion
Date: Thu May 10 04:02:04 2007
New Revision: 26669

URL: http://svn.reactos.org/svn/reactos?rev=26669&view=rev
Log:
- Refactor the registry initialization code to be somewhat closer to the Cm rewrite branch.
- No actual code/implementation changes per-se, simply moved code into new routines, deleted old routines, renamed some routines and added more error-checking.
- Also performed registry initialization in an order more analogous to Windows.
- Added cmsysini.c from the branch, but it's not used at the moment.

Added:
    trunk/reactos/ntoskrnl/config/cmsysini.c
Modified:
    trunk/reactos/ntoskrnl/cm/import.c
    trunk/reactos/ntoskrnl/cm/registry.c
    trunk/reactos/ntoskrnl/include/internal/ntoskrnl.h
    trunk/reactos/ntoskrnl/ntoskrnl.rbuild

Modified: trunk/reactos/ntoskrnl/cm/import.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/cm/import.c?rev=26669&r1=26668&r2=26669&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/cm/import.c (original)
+++ trunk/reactos/ntoskrnl/cm/import.c Thu May 10 04:02:04 2007
@@ -22,8 +22,6 @@
 
 /* GLOBALS ******************************************************************/
 
-static BOOLEAN CmiHardwareHiveImported = FALSE;
-
 /* FUNCTIONS ****************************************************************/
 
 static BOOLEAN
@@ -85,75 +83,56 @@
 }
 
 
-BOOLEAN INIT_FUNCTION
+BOOLEAN
+INIT_FUNCTION
 CmImportSystemHive(PCHAR ChunkBase,
-		   ULONG ChunkSize)
+                   ULONG ChunkSize,
+                   OUT PEREGISTRY_HIVE *RegistryHive)
+{
+  *RegistryHive = NULL;
+
+  DPRINT ("CmImportSystemHive() called\n");
+
+  if (strncmp (ChunkBase, "regf", 4))
+    {
+      DPRINT1 ("Found invalid '%.*s' magic\n", 4, ChunkBase);
+      return FALSE;
+    }
+
+  DPRINT ("Found '%.*s' magic\n", 4, ChunkBase);
+
+  /* Import the binary system hive (non-volatile, offset-based, permanent) */
+  if (!CmImportBinaryHive (ChunkBase, ChunkSize, 0, RegistryHive))
+    {
+      DPRINT1 ("CmiImportBinaryHive() failed\n");
+      return FALSE;
+    }
+
+  /* Set the hive filename */
+  RtlCreateUnicodeString (&(*RegistryHive)->HiveFileName,
+                          SYSTEM_REG_FILE);
+
+  /* Set the log filename */
+  RtlCreateUnicodeString (&(*RegistryHive)->LogFileName,
+                          SYSTEM_LOG_FILE);
+
+  return TRUE;
+}
+
+BOOLEAN
+INIT_FUNCTION
+CmImportHardwareHive(PCHAR ChunkBase,
+                     ULONG ChunkSize,
+                     OUT PEREGISTRY_HIVE *RegistryHive)
 {
   OBJECT_ATTRIBUTES ObjectAttributes;
-  PEREGISTRY_HIVE RegistryHive;
-  UNICODE_STRING KeyName;
-  NTSTATUS Status;
-
-  DPRINT ("CmImportSystemHive() called\n");
-
-  if (strncmp (ChunkBase, "regf", 4))
-    {
-      DPRINT1 ("Found invalid '%.*s' magic\n", 4, ChunkBase);
-      return FALSE;
-    }
-
-  DPRINT ("Found '%.*s' magic\n", 4, ChunkBase);
-
-  /* Import the binary system hive (non-volatile, offset-based, permanent) */
-  if (!CmImportBinaryHive (ChunkBase, ChunkSize, 0, &RegistryHive))
-    {
-      DPRINT1 ("CmiImportBinaryHive() failed\n");
-      return FALSE;
-    }
-
-  /* Attach it to the machine key */
-  RtlInitUnicodeString (&KeyName,
-			REG_SYSTEM_KEY_NAME);
-  InitializeObjectAttributes (&ObjectAttributes,
-			      &KeyName,
-			      OBJ_CASE_INSENSITIVE,
-			      NULL,
-			      NULL);
-  Status = CmiConnectHive (&ObjectAttributes,
-			   RegistryHive);
-  if (!NT_SUCCESS(Status))
-    {
-      DPRINT1 ("CmiConnectHive(%wZ) failed (Status %lx)\n", &KeyName, Status);
-      return FALSE;
-    }
-
-  /* Set the hive filename */
-  RtlCreateUnicodeString (&RegistryHive->HiveFileName,
-                          SYSTEM_REG_FILE);
-
-  /* Set the log filename */
-  RtlCreateUnicodeString (&RegistryHive->LogFileName,
-                          SYSTEM_LOG_FILE);
-
-  return TRUE;
-}
-
-
-BOOLEAN INIT_FUNCTION
-CmImportHardwareHive(PCHAR ChunkBase,
-		     ULONG ChunkSize)
-{
-  OBJECT_ATTRIBUTES ObjectAttributes;
-  PEREGISTRY_HIVE RegistryHive;
   UNICODE_STRING KeyName;
   HANDLE HardwareKey;
   ULONG Disposition;
   NTSTATUS Status;
+  *RegistryHive = NULL;
 
   DPRINT ("CmImportHardwareHive() called\n");
-
-  if (CmiHardwareHiveImported == TRUE)
-    return TRUE;
 
   if (ChunkBase == NULL &&
       ChunkSize == 0)
@@ -260,38 +239,19 @@
   DPRINT ("ChunkBase %lx  ChunkSize %lu\n", ChunkBase, ChunkSize);
 
   /* Import the binary system hive (volatile, offset-based, permanent) */
-  if (!CmImportBinaryHive (ChunkBase, ChunkSize, HIVE_NO_FILE, &RegistryHive))
+  if (!CmImportBinaryHive (ChunkBase, ChunkSize, HIVE_NO_FILE, RegistryHive))
     {
       DPRINT1 ("CmiImportBinaryHive() failed\n");
       return FALSE;
     }
 
-  /* Attach it to the machine key */
-  RtlInitUnicodeString (&KeyName,
-			REG_HARDWARE_KEY_NAME);
-  InitializeObjectAttributes (&ObjectAttributes,
-			      &KeyName,
-			      OBJ_CASE_INSENSITIVE,
-			      NULL,
-			      NULL);
-  Status = CmiConnectHive (&ObjectAttributes,
-			   RegistryHive);
-  if (!NT_SUCCESS(Status))
-    {
-      DPRINT1 ("CmiConnectHive(%wZ) failed (Status %lx)\n", &KeyName, Status);
-//      CmiRemoveRegistryHive(RegistryHive);
-      return FALSE;
-    }
-
   /* Set the hive filename */
-  RtlInitUnicodeString (&RegistryHive->HiveFileName,
+  RtlInitUnicodeString (&(*RegistryHive)->HiveFileName,
 			NULL);
 
   /* Set the log filename */
-  RtlInitUnicodeString (&RegistryHive->LogFileName,
+  RtlInitUnicodeString (&(*RegistryHive)->LogFileName,
 			NULL);
-
-  CmiHardwareHiveImported = TRUE;
 
   return TRUE;
 }

Modified: trunk/reactos/ntoskrnl/cm/registry.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/cm/registry.c?rev=26669&r1=26668&r2=26669&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/cm/registry.c (original)
+++ trunk/reactos/ntoskrnl/cm/registry.c Thu May 10 04:02:04 2007
@@ -54,6 +54,18 @@
 CmiCheckKey(BOOLEAN Verbose,
   HANDLE Key);
 
+BOOLEAN
+INIT_FUNCTION
+CmImportSystemHive(PCHAR ChunkBase,
+                   ULONG ChunkSize,
+                   OUT PEREGISTRY_HIVE *RegistryHive);
+
+BOOLEAN
+INIT_FUNCTION
+CmImportHardwareHive(PCHAR ChunkBase,
+                     ULONG ChunkSize,
+                     OUT PEREGISTRY_HIVE *RegistryHive);
+
 static NTSTATUS
 CmiCreateCurrentControlSetLink(VOID);
 
@@ -66,6 +78,8 @@
 extern LIST_ENTRY CmiCallbackHead;
 extern FAST_MUTEX CmiCallbackLock;
 
+UNICODE_STRING CmpSystemStartOptions;
+UNICODE_STRING CmpLoadOptions;
 /* FUNCTIONS ****************************************************************/
 
 VOID STDCALL
@@ -129,98 +143,12 @@
   }
 }
 
-VOID INIT_FUNCTION
-CmInit2(PCHAR CommandLine)
-{
-  ULONG PiceStart = 4;
-  BOOLEAN MiniNT = FALSE;
-  NTSTATUS Status;
-  UNICODE_STRING TempString;
-
-  /* Create the 'CurrentControlSet' link. */
-  Status = CmiCreateCurrentControlSetLink();
-  if (!NT_SUCCESS(Status))
-    KEBUGCHECK(CONFIG_INITIALIZATION_FAILED);
-
-  /*
-   * Write the system boot device to registry.
-   */
-  RtlCreateUnicodeStringFromAsciiz(&TempString, KeLoaderBlock->ArcBootDeviceName);
-  Status = RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE,
-				 L"\\Registry\\Machine\\System\\CurrentControlSet\\Control",
-				 L"SystemBootDevice",
-				 REG_SZ,
-				 TempString.Buffer,
-				 TempString.MaximumLength);
-  RtlFreeUnicodeString(&TempString);
-  if (!NT_SUCCESS(Status))
-  {
-    KEBUGCHECK(CONFIG_INITIALIZATION_FAILED);
-  }
-
-  /*
-   * Parse the system start options.
-   */
-  if (strstr(KeLoaderBlock->LoadOptions, "DEBUGPORT=PICE") != NULL)
-	PiceStart = 1;
-  MiniNT = strstr(KeLoaderBlock->LoadOptions, "MININT") != NULL;
-
-  /*
-   * Write the system start options to registry.
-   */
-  RtlCreateUnicodeStringFromAsciiz(&TempString, KeLoaderBlock->LoadOptions);
-  Status = RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE,
-				 L"\\Registry\\Machine\\System\\CurrentControlSet\\Control",
-				 L"SystemStartOptions",
-				 REG_SZ,
-				 TempString.Buffer,
-				 TempString.MaximumLength);
-  RtlFreeUnicodeString(&TempString);
-  if (!NT_SUCCESS(Status))
-  {
-    KEBUGCHECK(CONFIG_INITIALIZATION_FAILED);
-  }
-
-  /*
-   * Create a CurrentControlSet\Control\MiniNT key that is used
-   * to detect WinPE/MiniNT systems.
-   */
-  if (MiniNT)
-    {
-      Status = RtlCreateRegistryKey(RTL_REGISTRY_CONTROL, L"MiniNT");
-      if (!NT_SUCCESS(Status))
-        KEBUGCHECK(CONFIG_INITIALIZATION_FAILED);
-    }
-
-  /* Set PICE 'Start' value to 1, if PICE debugging is enabled */
-  Status = RtlWriteRegistryValue(
-    RTL_REGISTRY_SERVICES,
-    L"\\Pice",
-    L"Start",
-    REG_DWORD,
-    &PiceStart,
-    sizeof(ULONG));
-  if (!NT_SUCCESS(Status))
-    KEBUGCHECK(CONFIG_INITIALIZATION_FAILED);
-}
-
-
-VOID
-INIT_FUNCTION
-STDCALL
-CmInitHives(BOOLEAN SetupBoot)
-{
-    PCHAR BaseAddress;
+PVOID
+NTAPI
+CmpRosGetHardwareHive(OUT PULONG Length)
+{
     PLIST_ENTRY ListHead, NextEntry;
     PMEMORY_ALLOCATION_DESCRIPTOR MdBlock = NULL;
-
-    /* Load Registry Hives. This one can be missing. */
-    BaseAddress = KeLoaderBlock->RegistryBase;
-    if (BaseAddress)
-    {
-        CmImportSystemHive(BaseAddress,
-                           KeLoaderBlock->RegistryLength);
-    }
 
     /* Loop the memory descriptors */
     ListHead = &KeLoaderBlock->MemoryDescriptorListHead;
@@ -236,7 +164,8 @@
         if (MdBlock->MemoryType == LoaderRegistryData)
         {
             /* Check if it's not the SYSTEM hive that we already initialized */
-            if ((MdBlock->BasePage) != ((ULONG_PTR)BaseAddress >> PAGE_SHIFT))
+            if ((MdBlock->BasePage) !=
+                ((ULONG_PTR)KeLoaderBlock->RegistryBase >> PAGE_SHIFT))
             {
                 /* Hardware hive break out */
                 break;
@@ -249,16 +178,239 @@
 
     /* We need a hardware hive */
     ASSERT(MdBlock);
-
-    BaseAddress = (PCHAR)(MdBlock->BasePage << PAGE_SHIFT);
-    CmImportHardwareHive(BaseAddress,
-                         MdBlock->PageCount << PAGE_SHIFT);
-
-    /* Create dummy keys if no hardware hive was found */
-    CmImportHardwareHive (NULL, 0);
-
-    /* Initialize volatile registry settings */
-    if (SetupBoot == FALSE) CmInit2(KeLoaderBlock->LoadOptions);
+    *Length = MdBlock->PageCount << PAGE_SHIFT;
+    return (PVOID)(MdBlock->BasePage << PAGE_SHIFT);
+}
+
+NTSTATUS
+NTAPI
+CmpLinkHiveToMaster(IN PUNICODE_STRING LinkName,
+                    IN HANDLE RootDirectory,
+                    IN PEREGISTRY_HIVE RegistryHive,
+                    IN BOOLEAN Allocate,
+                    IN PSECURITY_DESCRIPTOR SecurityDescriptor)
+{
+    OBJECT_ATTRIBUTES ObjectAttributes;
+
+    /* Don't do anything if we don't actually have a hive */
+    if (Allocate) return STATUS_SUCCESS;
+
+    /* Setup the object attributes */
+    InitializeObjectAttributes(&ObjectAttributes,
+                               LinkName,
+                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+                               RootDirectory,
+                               SecurityDescriptor);
+
+    /* Connect the hive */
+    return CmiConnectHive(&ObjectAttributes, RegistryHive);
+}
+
+NTSTATUS
+NTAPI
+CmpSetSystemValues(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
+{
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    UNICODE_STRING KeyName, ValueName;
+    HANDLE KeyHandle;
+    NTSTATUS Status;
+    ASSERT(LoaderBlock != NULL);
+    if (ExpInTextModeSetup) return STATUS_SUCCESS;
+
+    /* Setup attributes for loader options */
+    RtlInitUnicodeString(&KeyName,
+                         L"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\"
+                         L"Control");
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &KeyName,
+                               OBJ_CASE_INSENSITIVE,
+                               NULL,
+                               NULL);
+    Status = NtOpenKey(&KeyHandle, KEY_WRITE, &ObjectAttributes);
+    if (!NT_SUCCESS(Status)) goto Quickie;
+
+    /* Key opened, now write to the key */
+    RtlInitUnicodeString(&KeyName, L"SystemStartOptions");
+    Status = NtSetValueKey(KeyHandle,
+                           &KeyName,
+                           0,
+                           REG_SZ,
+                           CmpSystemStartOptions.Buffer,
+                           CmpSystemStartOptions.Length);
+    if (!NT_SUCCESS(Status)) goto Quickie;
+
+    /* Free the options now */
+    ExFreePool(CmpSystemStartOptions.Buffer);
+
+    /* Setup value name for system boot device */
+    RtlInitUnicodeString(&KeyName, L"SystemBootDevice");
+    RtlCreateUnicodeStringFromAsciiz(&ValueName, LoaderBlock->NtBootPathName);
+    Status = NtSetValueKey(KeyHandle,
+                           &KeyName,
+                           0,
+                           REG_SZ,
+                           ValueName.Buffer,
+                           ValueName.Length);
+
+Quickie:
+    /* Free the buffers */
+    RtlFreeUnicodeString(&ValueName);
+
+    /* Close the key and return */
+    NtClose(KeyHandle);
+
+    /* Return the status */
+    return Status;
+}
+
+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;
+    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 */
+        Status = CmImportSystemHive(HiveBase,
+                                    LoaderBlock->RegistryLength,
+                                    &SystemHive);
+        if (!NT_SUCCESS(Status)) return FALSE;
+
+        /* We imported, no need to create a new hive */
+        Allocate = FALSE;
+    }
+    else
+    {
+        /* FIXME: Create an empty hive */
+        Allocate = TRUE;
+    }
+
+    /* Attach it to the system key */
+    RtlInitUnicodeString(&KeyName, REG_SYSTEM_KEY_NAME);
+    Status = CmpLinkHiveToMaster(&KeyName, NULL, SystemHive, Allocate, NULL);
+    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
+CmpCreateRegistryRoot(VOID)
+{
+    UNICODE_STRING KeyName;
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    PKEY_OBJECT RootKey;
+    HANDLE RootKeyHandle;
+    NTSTATUS Status;
+
+    /* Create '\Registry' key. */
+    RtlInitUnicodeString(&KeyName, REG_ROOT_KEY_NAME);
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &KeyName,
+                               OBJ_CASE_INSENSITIVE,
+                               NULL,
+                               NULL);
+    Status = ObCreateObject(KernelMode,
+                            CmiKeyType,
+                            &ObjectAttributes,
+                            KernelMode,
+                            NULL,
+                            sizeof(KEY_OBJECT),
+                            0,
+                            0,
+                            (PVOID*)&RootKey);
+    if (!NT_SUCCESS(Status)) return FALSE;
+
+    /* Setup the root key */
+    RootKey->RegistryHive = CmiVolatileHive;
+    RootKey->KeyCellOffset = CmiVolatileHive->Hive.HiveHeader->RootCell;
+    RootKey->KeyCell = HvGetCell(&CmiVolatileHive->Hive, RootKey->KeyCellOffset);
+    RootKey->ParentKey = RootKey;
+    RootKey->Flags = 0;
+    RootKey->SubKeyCounts = 0;
+    RootKey->SubKeys = NULL;
+    RootKey->SizeOfSubKeys = 0;
+    InsertTailList(&CmiKeyObjectListHead, &RootKey->ListEntry);
+    Status = RtlpCreateUnicodeString(&RootKey->Name, L"Registry", NonPagedPool);
+
+    /* Insert the key into the namespace */
+    Status = ObInsertObject(RootKey,
+                            NULL,
+                            KEY_ALL_ACCESS,
+                            0,
+                            NULL,
+                            &RootKeyHandle);
+    if (!NT_SUCCESS(Status)) return FALSE;
+
+    /* Reference the key again so that we never lose it */
+    Status = ObReferenceObjectByHandle(RootKeyHandle,
+                                       KEY_READ,
+                                       NULL,
+                                       KernelMode,
+                                       (PVOID*)&RootKey,
+                                       NULL);
+    if (!NT_SUCCESS(Status)) return FALSE;
+
+    /* Completely sucessful */
+    return TRUE;
 }
 
 BOOLEAN
@@ -266,158 +418,171 @@
 NTAPI
 CmInitSystem1(VOID)
 {
-  OBJECT_ATTRIBUTES ObjectAttributes;
-  UNICODE_STRING KeyName;
-  PKEY_OBJECT RootKey;
-#if 0
-  PCM_KEY_SECURITY RootSecurityCell;
-#endif
-  HANDLE RootKeyHandle;
-  HANDLE KeyHandle;
-  NTSTATUS Status;
-  LARGE_INTEGER DueTime;
-  HANDLE ThreadHandle;
-  CLIENT_ID ThreadId;
-  OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
-  UNICODE_STRING Name;
-
-  DPRINT("Creating Registry Object Type\n");
-  
-  /*  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;
-
-  ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &CmiKeyType);
-
-  /* Initialize the hive list */
-  InitializeListHead(&CmiHiveListHead);
-
-  /* Initialize registry lock */
-  ExInitializeResourceLite(&CmiRegistryLock);
-
-  /* Initialize the key object list */
-  InitializeListHead(&CmiKeyObjectListHead);
-  InitializeListHead(&CmiConnectedHiveList);
-
-  /* Initialize the worker timer */
-  KeInitializeTimerEx(&CmiWorkerTimer, SynchronizationTimer);
-
-  /* Initialize the worker thread */
-  Status = PsCreateSystemThread(&ThreadHandle,
-				THREAD_ALL_ACCESS,
-				NULL,
-				NULL,
-				&ThreadId,
-				CmiWorkerThread,
-				NULL);
-  if (!NT_SUCCESS(Status)) return FALSE;
-
-  /* Start the timer */
-  DueTime.QuadPart = -1;
-  KeSetTimerEx(&CmiWorkerTimer, DueTime, 5000, NULL); /* 5sec */
-
-  /*  Build volatile registry store  */
-  Status = CmiCreateVolatileHive (&CmiVolatileHive);
-  ASSERT(NT_SUCCESS(Status));
-
-  InitializeListHead(&CmiCallbackHead);
-  ExInitializeFastMutex(&CmiCallbackLock);
-
-  /* Create '\Registry' key. */
-  RtlInitUnicodeString(&KeyName, REG_ROOT_KEY_NAME);
-  InitializeObjectAttributes(&ObjectAttributes, &KeyName, 0, NULL, NULL);
-  Status = ObCreateObject(KernelMode,
-			  CmiKeyType,
-			  &ObjectAttributes,
-			  KernelMode,
-			  NULL,
-			  sizeof(KEY_OBJECT),
-			  0,
-			  0,
-			  (PVOID *) &RootKey);
-  ASSERT(NT_SUCCESS(Status));
-  Status = ObInsertObject(RootKey,
-			  NULL,
-			  KEY_ALL_ACCESS,
-			  0,
-			  NULL,
-			  &RootKeyHandle);
-  ASSERT(NT_SUCCESS(Status));
-  RootKey->RegistryHive = CmiVolatileHive;
-  RootKey->KeyCellOffset = CmiVolatileHive->Hive.HiveHeader->RootCell;
-  RootKey->KeyCell = HvGetCell (&CmiVolatileHive->Hive, RootKey->KeyCellOffset);
-  RootKey->ParentKey = RootKey;
-  RootKey->Flags = 0;
-  RootKey->SubKeyCounts = 0;
-  RootKey->SubKeys = NULL;
-  RootKey->SizeOfSubKeys = 0;
-  InsertTailList(&CmiKeyObjectListHead, &RootKey->ListEntry);
-  Status = RtlpCreateUnicodeString(&RootKey->Name, L"Registry", NonPagedPool);
-  ASSERT(NT_SUCCESS(Status));
-
-#if 0
-  Status = CmiAllocateCell(CmiVolatileHive,
-			   0x10, //LONG CellSize,
-			   (PVOID *)&RootSecurityCell,
-			   &RootKey->KeyCell->SecurityKeyOffset);
-  ASSERT(NT_SUCCESS(Status));
-
-  /* Copy the security descriptor */
-
-  CmiVolatileHive->RootSecurityCell = RootSecurityCell;
-#endif
-
-
-  /* Create '\Registry\Machine' key. */
-  RtlInitUnicodeString(&KeyName,
-		       L"Machine");
-  InitializeObjectAttributes(&ObjectAttributes,
-			     &KeyName,
-			     0,
-			     RootKeyHandle,
-			     NULL);
-  Status = ZwCreateKey(&KeyHandle,
-		       KEY_ALL_ACCESS,
-		       &ObjectAttributes,
-		       0,
-		       NULL,
-		       REG_OPTION_VOLATILE,
-		       NULL);
-  ASSERT(NT_SUCCESS(Status));
-
-  /* Create '\Registry\User' key. */
-  RtlInitUnicodeString(&KeyName,
-		       L"User");
-  InitializeObjectAttributes(&ObjectAttributes,
-			     &KeyName,
-			     0,
-			     RootKeyHandle,
-			     NULL);
-  Status = ZwCreateKey(&KeyHandle,
-		       KEY_ALL_ACCESS,
-		       &ObjectAttributes,
-		       0,
-		       NULL,
-		       REG_OPTION_VOLATILE,
-		       NULL);
-  ASSERT(NT_SUCCESS(Status));
-
-  /* Import and Load Registry Hives */
-  CmInitHives(ExpInTextModeSetup);
-  return TRUE;
-}
-
-
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    UNICODE_STRING KeyName;
+    HANDLE KeyHandle;
+    NTSTATUS Status;
+    LARGE_INTEGER DueTime;
+    HANDLE ThreadHandle;
+    CLIENT_ID ThreadId;
+    PEREGISTRY_HIVE HardwareHive;
+    BOOLEAN Allocate = FALSE;
+    PVOID BaseAddress;
+    ULONG Length;
+    PAGED_CODE();
+
+    /* Initialize the hive list */
+    InitializeListHead(&CmiHiveListHead);
+
+    /* Initialize registry lock */
+    ExInitializeResourceLite(&CmiRegistryLock);
+
+    /* Initialize the key object list */
+    InitializeListHead(&CmiKeyObjectListHead);
+    InitializeListHead(&CmiConnectedHiveList);
+
+    /* Initialize the worker timer */
+    KeInitializeTimerEx(&CmiWorkerTimer, SynchronizationTimer);
+
+    /* Initialize the worker thread */
+    Status = PsCreateSystemThread(&ThreadHandle,
+                                  THREAD_ALL_ACCESS,
+                                  NULL,
+                                  NULL,
+                                  &ThreadId,
+                                  CmiWorkerThread,
+                                  NULL);
+    if (!NT_SUCCESS(Status)) return FALSE;
+
+    /* Start the timer */
+    DueTime.QuadPart = -1;
+    KeSetTimerEx(&CmiWorkerTimer, DueTime, 5000, NULL); /* 5sec */
+
+    InitializeListHead(&CmiCallbackHead);
+    ExInitializeFastMutex(&CmiCallbackLock);
+
+    /* Create the key object types */
+    Status = CmpCreateObjectTypes();
+    if (!NT_SUCCESS(Status))
+    {
+        /* Bugcheck */
+        KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED, 1, 1, Status, 0);
+    }
+
+    /* Build volatile registry store */
+    Status = CmiCreateVolatileHive(&CmiVolatileHive);
+    if (!NT_SUCCESS(Status))
+    {
+        /* Bugcheck */
+        KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED, 1, 2, Status, 0);
+    }
+
+    /* Create the \REGISTRY key node */
+    if (!CmpCreateRegistryRoot())
+    {
+        /* Bugcheck */
+        KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED, 1, 4, 0, 0);
+    }
+
+    /* Create '\Registry\Machine' key. */
+    RtlInitUnicodeString(&KeyName, L"\\REGISTRY\\MACHINE");
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &KeyName,
+                               OBJ_CASE_INSENSITIVE,
+                               NULL,
+                               NULL);
+    Status = NtCreateKey(&KeyHandle,
+                         KEY_READ | KEY_WRITE,
+                         &ObjectAttributes,
+                         0,
+                         NULL,
+                         0,
+                         NULL);
+    if (!NT_SUCCESS(Status))
+    {
+        /* Bugcheck */
+        KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED, 1, 5, Status, 0);
+    }
+
+    /* Close the handle */
+    NtClose(KeyHandle);
+
+    /* Create '\Registry\User' key. */
+    RtlInitUnicodeString(&KeyName, L"\\REGISTRY\\USER");
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &KeyName,
+                               OBJ_CASE_INSENSITIVE,
+                               NULL,
+                               NULL);
+    Status = NtCreateKey(&KeyHandle,
+                         KEY_READ | KEY_WRITE,
+                         &ObjectAttributes,
+                         0,
+                         NULL,
+                         0,
+                         NULL);
+    if (!NT_SUCCESS(Status))
+    {
+        /* Bugcheck */
+        KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED, 1, 6, Status, 0);
+    }
+
+    /* Close the handle */
+    NtClose(KeyHandle);
+
+    /* Initialize the system hive */
+    if (!CmpInitializeSystemHive(KeLoaderBlock))
+    {
+        /* Bugcheck */
+        KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED, 1, 7, 0, 0);
+    }
+
+    /* Create the 'CurrentControlSet' link. */
+    Status = CmiCreateCurrentControlSetLink();
+    if (!NT_SUCCESS(Status))
+    {
+        /* Bugcheck */
+        KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED, 1, 8, Status, 0);
+    }
+
+    /* Initialize the hardware hive */
+    BaseAddress = CmpRosGetHardwareHive(&Length);
+    if (!CmImportHardwareHive(BaseAddress, Length, &HardwareHive))
+    {
+        /* Create dummy keys if no hardware hive was found */
+        if (!CmImportHardwareHive (NULL, 0, &HardwareHive))
+        {
+            /* Bugcheck */
+            KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED, 1, 11, Status, 0);
+        }
+
+        /* Don't actually link anything below */
+        Allocate = TRUE;
+    }
+
+    /* Attach it to the machine key */
+    RtlInitUnicodeString(&KeyName, REG_HARDWARE_KEY_NAME);
+    Status = CmpLinkHiveToMaster(&KeyName, NULL, HardwareHive, FALSE, NULL);
+    if (!NT_SUCCESS(Status))
+    {
+        /* Bugcheck */
+        KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED, 1, 12, Status, 0);
+    }
+
+    /* Initialize volatile registry settings */
+    Status = CmpSetSystemValues(KeLoaderBlock);
+    if (!NT_SUCCESS(Status))
+    {
+        /* Bugcheck */
+        KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED, 1, 15, Status, 0);
+    }
+
+    /* Free the load options */
+    ExFreePool(CmpLoadOptions.Buffer);
+
+    /* If we got here, all went well */
+    return TRUE;
+}
 
 static NTSTATUS
 CmiCreateCurrentControlSetLink(VOID)
@@ -435,6 +600,7 @@
   NTSTATUS Status;
   OBJECT_ATTRIBUTES ObjectAttributes;
   HANDLE KeyHandle;
+  if (ExpInTextModeSetup) return STATUS_SUCCESS;
 
   DPRINT("CmiCreateCurrentControlSetLink() called\n");
 

Added: trunk/reactos/ntoskrnl/config/cmsysini.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cmsysini.c?rev=26669&view=auto
==============================================================================
--- trunk/reactos/ntoskrnl/config/cmsysini.c (added)
+++ trunk/reactos/ntoskrnl/config/cmsysini.c Thu May 10 04:02:04 2007
@@ -1,0 +1,646 @@
+/*
+ * PROJECT:         ReactOS Kernel
+ * LICENSE:         GPL - See COPYING in the top level directory
+ * FILE:            ntoskrnl/config/cmsysini.c
+ * PURPOSE:         Configuration Manager - System Initialization Code
+ * PROGRAMMERS:     Alex Ionescu (alex.ionescu at reactos.org)
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include "ntoskrnl.h"
+#include "cm.h"
+#define NDEBUG
+#include "debug.h"
+
+#if 0
+/* GLOBALS *******************************************************************/
+
+UNICODE_STRING CmSymbolicLinkValueName =
+    RTL_CONSTANT_STRING(L"SymbolicLinkValue");
+
+UNICODE_STRING CmpSystemStartOptions;
+UNICODE_STRING CmpLoadOptions;
+
+/* FUNCTIONS *****************************************************************/
+
+NTSTATUS
+NTAPI
+CmpSetSystemValues(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
+{
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    UNICODE_STRING KeyName, ValueName;
+    HANDLE KeyHandle;
+    NTSTATUS Status;
+    ASSERT(LoaderBlock != NULL);
+
+    /* Setup attributes for loader options */
+    RtlInitUnicodeString(&KeyName,
+                         L"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\"
+                         L"Control");
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &KeyName,
+                               OBJ_CASE_INSENSITIVE,
+                               NULL,
+                               NULL);
+    Status = NtOpenKey(&KeyHandle, KEY_WRITE, &ObjectAttributes);
+    if (!NT_SUCCESS(Status)) goto Quickie;
+
+    /* Key opened, now write to the key */
+    RtlInitUnicodeString(&KeyName, L"SystemStartOptions");
+    Status = NtSetValueKey(KeyHandle,
+                           &KeyName,
+                           0,
+                           REG_SZ,
+                           CmpSystemStartOptions.Buffer,
+                           CmpSystemStartOptions.Length);
+    if (!NT_SUCCESS(Status)) goto Quickie;
+
+    /* Free the options now */
+    ExFreePool(CmpSystemStartOptions.Buffer);
+
+    /* Setup value name for system boot device */
+    RtlInitUnicodeString(&KeyName, L"SystemBootDevice");
+    RtlCreateUnicodeStringFromAsciiz(&ValueName, LoaderBlock->NtBootPathName);
+    Status = NtSetValueKey(KeyHandle,
+                           &KeyName,
+                           0,
+                           REG_SZ,
+                           ValueName.Buffer,
+                           ValueName.Length);
+
+Quickie:
+    /* Free the buffers */
+    RtlFreeUnicodeString(&ValueName);
+
+    /* Close the key and return */
+    NtClose(KeyHandle);
+
+    /* Return the status */
+    return Status;
+}
+
+NTSTATUS
+NTAPI
+CmpHwProfileDefaultSelect(IN PVOID ProfileList,
+                          OUT PULONG ProfileIndexToUse,
+                          IN PVOID Context)
+{
+    /* Clear the index and return success */
+    *ProfileIndexToUse = 0;
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+CmpAddDockingInfo(IN HANDLE Key,
+                  IN PPROFILE_PARAMETER_BLOCK ProfileBlock)
+{
+    NTSTATUS Status = STATUS_SUCCESS;
+    UNICODE_STRING KeyName;
+    ULONG Value;
+    PAGED_CODE ();
+
+    /* Get the Value from the profile block, create a Name for it and set it */
+    Value = ProfileBlock->DockingState;
+    RtlInitUnicodeString(&KeyName, L"DockingState");
+    Status = NtSetValueKey(Key,
+                           &KeyName,
+                           0,
+                           REG_DWORD,
+                           &Value,
+                           sizeof(Value));
+    if (!NT_SUCCESS(Status)) return Status;
+
+    /* Get the Value from the profile block, create a Name for it and set it */
+    Value = ProfileBlock->Capabilities;
+    RtlInitUnicodeString(&KeyName, L"Capabilities");
+    Status = NtSetValueKey(Key,
+                           &KeyName,
+                           0,
+                           REG_DWORD,
+                           &Value,
+                           sizeof(Value));
+    if (!NT_SUCCESS(Status)) return Status;
+
+    /* Get the Value from the profile block, create a Name for it and set it */
+    Value = ProfileBlock->DockID;
+    RtlInitUnicodeString(&KeyName, L"DockID");
+    Status = NtSetValueKey(Key,
+                           &KeyName,
+                           0,
+                           REG_DWORD,
+                           &Value,
+                           sizeof(Value));
+    if (!NT_SUCCESS(Status)) return Status;
+
+    /* Get the Value from the profile block, create a Name for it and set it */
+    Value = ProfileBlock->SerialNumber;
+    RtlInitUnicodeString(&KeyName, L"SerialNumber");
+    Status = NtSetValueKey(Key,
+                           &KeyName,
+                           0,
+                           REG_DWORD,
+                           &Value,
+                           sizeof(Value));
+
+    /* Return Status */
+    return Status;
+}
+
+NTSTATUS
+NTAPI
+CmpAddAliasEntry(IN HANDLE IDConfigDB,
+                 IN PPROFILE_PARAMETER_BLOCK ProfileBlock,
+                 IN ULONG ProfileNumber)
+{
+    UNICODE_STRING KeyName;
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    NTSTATUS Status = STATUS_SUCCESS;
+    CHAR Buffer[128];
+    WCHAR UnicodeBuffer[128];
+    ANSI_STRING TempString;
+    HANDLE AliasHandle = NULL, AliasIdHandle = NULL;
+    ULONG Value;
+    ULONG Disposition;
+    ULONG AliasId = 0;
+    PAGED_CODE ();
+
+    /* Open the alias key */
+    RtlInitUnicodeString(&KeyName, L"Alias");
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &KeyName,
+                               OBJ_CASE_INSENSITIVE,
+                               IDConfigDB,
+                               NULL);
+    Status = NtOpenKey(&AliasHandle, KEY_READ | KEY_WRITE, &ObjectAttributes);
+
+    /* Check if we failed to open it */
+    if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
+    {
+        /* Create it instead */
+        Status = NtCreateKey(&AliasHandle,
+                             KEY_READ | KEY_WRITE,
+                             &ObjectAttributes,
+                             0,
+                             NULL,
+                             0,
+                             &Disposition);
+    }
+
+    /* Check if we failed */
+    if (!NT_SUCCESS (Status))
+    {
+        /* Cleanup and exit */
+        AliasHandle = NULL;
+        goto Exit;
+    }
+
+    /* Loop every alias ID */
+    while (AliasId++ < 200)
+    {
+        /* Build the KeyName */
+        sprintf(Buffer, "%04ld", AliasId);
+        RtlInitAnsiString(&TempString, Buffer);
+
+        /* Convert it to Unicode */
+        KeyName.MaximumLength = sizeof(UnicodeBuffer);
+        KeyName.Buffer = UnicodeBuffer;
+        Status = RtlAnsiStringToUnicodeString(&KeyName,
+                                              &TempString,
+                                              FALSE);
+        ASSERT (STATUS_SUCCESS == Status);
+
+        /* Open the key */
+        InitializeObjectAttributes(&ObjectAttributes,
+                                   &KeyName,
+                                   OBJ_CASE_INSENSITIVE,
+                                   AliasHandle,
+                                   NULL);
+        Status = NtOpenKey(&AliasIdHandle,
+                           KEY_READ | KEY_WRITE,
+                           &ObjectAttributes);
+        if (NT_SUCCESS (Status))
+        {
+            /* We opened it, close and keep looping */
+            NtClose(AliasIdHandle);
+        }
+        else if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
+        {
+            /* We couldn't find it, change Status and break out */
+            Status = STATUS_SUCCESS;
+            break;
+        }
+        else
+        {
+            /* Any other error, break out */
+            break;
+        }
+    }
+
+    /* Check if we failed in the alias loop */
+    if (!NT_SUCCESS(Status))
+    {
+        /* Cleanup and exit */
+        AliasIdHandle = 0;
+        goto Exit;
+    }
+
+    /* Otherwise, create the alias key */
+    Status = NtCreateKey(&AliasIdHandle,
+                         KEY_READ | KEY_WRITE,
+                         &ObjectAttributes,
+                         0,
+                         NULL,
+                         0,
+                         &Disposition);
+    if (!NT_SUCCESS(Status))
+    {
+        /* Cleanup and exit */
+        AliasIdHandle = 0;
+        goto Exit;
+    }
+
+    /* Add docking information */
+    CmpAddDockingInfo(AliasIdHandle, ProfileBlock);
+
+    /* Set the profile number */
+    Value = ProfileNumber;
+    RtlInitUnicodeString(&KeyName, L"ProfileNumber");
+    Status = NtSetValueKey(AliasIdHandle,
+                           &KeyName,
+                           0,
+                           REG_DWORD,
+                           &Value,
+                           sizeof(Value));
+
+Exit:
+    /* Close every opened key */
+    if (AliasHandle) NtClose(AliasHandle);
+    if (AliasIdHandle) NtClose(AliasIdHandle);
+
+    /* Return Status */
+    return Status;
+}
+
+NTSTATUS
+NTAPI
+CmSetAcpiHwProfile(IN PPROFILE_ACPI_DOCKING_STATE NewDockState,
+                   IN PVOID Select,
+                   IN PVOID Context,
+                   OUT PHANDLE NewProfile,
+                   OUT PBOOLEAN ProfileChanged)
+{
+    /* FIXME: TODO */
+    *ProfileChanged = FALSE;
+    *NewProfile = NULL;
+    ASSERT(FALSE);
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+CmpCloneHwProfile(IN HANDLE ConfigHandle,
+                  IN HANDLE Parent,
+                  IN HANDLE OldProfile,
+                  IN ULONG OldProfileNumber,
+                  IN USHORT DockingState,
+                  OUT PHANDLE NewProfile,
+                  OUT PULONG NewProfileNumber)
+{
+    /* FIXME: TODO */
+    *NewProfileNumber = FALSE;
+    *NewProfile = NULL;
+    ASSERT(FALSE);
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+CmpCreateCurrentControlSetLink(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
+{
+    UNICODE_STRING ConfigName = RTL_CONSTANT_STRING(L"Control\\ConfigHandle");
+    UNICODE_STRING SelectName =
+        RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\Select");
+    UNICODE_STRING KeyName;
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    CHAR ValueInfoBuffer[128];
+    PKEY_VALUE_FULL_INFORMATION ValueInfo;
+    CHAR Buffer[128];
+    WCHAR UnicodeBuffer[128];
+    HANDLE SelectHandle, KeyHandle, ConfigHandle = NULL, ProfileHandle = NULL;
+    HANDLE ParentHandle = NULL, AcpiHandle;
+    ULONG ControlSet, HwProfile;
+    ANSI_STRING TempString;
+    NTSTATUS Status;
+    ULONG ResultLength, Disposition;
+    BOOLEAN AcpiProfile = FALSE;
+    PLOADER_PARAMETER_EXTENSION LoaderExtension;
+    PROFILE_ACPI_DOCKING_STATE AcpiDockState;
+    BOOLEAN Active;
+    PAGED_CODE();
+
+    /* Open the select key */
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &SelectName,
+                               OBJ_CASE_INSENSITIVE,
+                               NULL,
+                               NULL);
+    Status = NtOpenKey(&SelectHandle, KEY_READ, &ObjectAttributes);
+    if (!NT_SUCCESS(Status))return(Status);
+
+    /* Open the current value */
+    RtlInitUnicodeString(&KeyName, L"Current");
+    Status = NtQueryValueKey(SelectHandle,
+                             &KeyName,
+                             KeyValueFullInformation,
+                             ValueInfoBuffer,
+                             sizeof(ValueInfoBuffer),
+                             &ResultLength);
+    NtClose(SelectHandle);
+    if (!NT_SUCCESS(Status)) return Status;
+
+    /* Get the actual value pointer, and get the control set ID */
+    ValueInfo = (PKEY_VALUE_FULL_INFORMATION)ValueInfoBuffer;
+    ControlSet = *(PULONG)((PUCHAR)ValueInfo + ValueInfo->DataOffset);
+
+    /* Create the current control set key */
+    RtlInitUnicodeString(&KeyName,
+                         L"\\Registry\\Machine\\System\\CurrentControlSet");
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &KeyName,
+                               OBJ_CASE_INSENSITIVE,
+                               NULL,
+                               NULL);
+    Status = NtCreateKey(&KeyHandle,
+                         KEY_CREATE_LINK,
+                         &ObjectAttributes,
+                         0,
+                         NULL,
+                         REG_OPTION_VOLATILE | REG_OPTION_CREATE_LINK,
+                         &Disposition);
+    if (!NT_SUCCESS(Status)) return Status;
+
+    /* Sanity check */
+    ASSERT(Disposition == REG_CREATED_NEW_KEY);
+
+    /* Initialize the symbolic link name */
+    sprintf(Buffer,
+            "\\Registry\\Machine\\System\\ControlSet%03ld",
+            ControlSet);
+    RtlInitAnsiString(&TempString, Buffer);
+
+    /* Create a Unicode string out of it */
+    KeyName.MaximumLength = sizeof(UnicodeBuffer);
+    KeyName.Buffer = UnicodeBuffer;
+    Status = RtlAnsiStringToUnicodeString(&KeyName, &TempString, FALSE);
+
+    /* Set the value */
+    Status = NtSetValueKey(KeyHandle,
+                           &CmSymbolicLinkValueName,
+                           0,
+                           REG_LINK,
+                           KeyName.Buffer,
+                           KeyName.Length);
+    if (!NT_SUCCESS(Status)) return Status;
+
+    /* Get the configuration database key */
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &ConfigName,
+                               OBJ_CASE_INSENSITIVE,
+                               KeyHandle,
+                               NULL);
+    Status = NtOpenKey(&ConfigHandle, KEY_READ, &ObjectAttributes);
+    NtClose(KeyHandle);
+
+    /* Check if we don't have one */
+    if (!NT_SUCCESS(Status))
+    {
+        /* Cleanup and exit */
+        ConfigHandle = 0;
+        goto Cleanup;
+    }
+
+    /* Now get the current config */
+    RtlInitUnicodeString(&KeyName, L"CurrentConfig");
+    Status = NtQueryValueKey(ConfigHandle,
+                             &KeyName,
+                             KeyValueFullInformation,
+                             ValueInfoBuffer,
+                             sizeof(ValueInfoBuffer),
+                             &ResultLength);
+
+    /* Set pointer to buffer */
+    ValueInfo = (PKEY_VALUE_FULL_INFORMATION)ValueInfoBuffer;
+
+    /* Check if we failed or got a non DWORD-value */
+    if (!(NT_SUCCESS(Status)) || (ValueInfo->Type != REG_DWORD)) goto Cleanup;
+
+    /* Get the hadware profile */
+    HwProfile = *(PULONG)((PUCHAR)ValueInfo + ValueInfo->DataOffset);
+
+    /* Open the hardware profile key */
+    RtlInitUnicodeString(&KeyName,
+                         L"\\Registry\\Machine\\System\\CurrentControlSet"
+                         L"\\Hardware Profiles");
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &KeyName,
+                               OBJ_CASE_INSENSITIVE,
+                               NULL,
+                               NULL);
+    Status = NtOpenKey(&ParentHandle, KEY_READ, &ObjectAttributes);
+
+    /* Check if there is no hardware profile key */
+    if (!NT_SUCCESS (Status))
+    {
+        /* Exit and clean up */
+        ParentHandle = 0;
+        goto Cleanup;
+    }
+
+    /* Build the profile name */
+    sprintf(Buffer, "%04ld",HwProfile);
+    RtlInitAnsiString(&TempString, Buffer);
+
+    /* Convert it to Unicode */
+    KeyName.MaximumLength = sizeof(UnicodeBuffer);
+    KeyName.Buffer = UnicodeBuffer;
+    Status = RtlAnsiStringToUnicodeString(&KeyName,
+                                          &TempString,
+                                          FALSE);
+    ASSERT(Status == STATUS_SUCCESS);
+
+    /* Open the associated key */
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &KeyName,
+                               OBJ_CASE_INSENSITIVE,
+                               ParentHandle,
+                               NULL);
+    Status = NtOpenKey(&ProfileHandle,
+                       KEY_READ | KEY_WRITE,
+                       &ObjectAttributes);
+
+    /* Check if there's no such key */
+    if (!NT_SUCCESS (Status))
+    {
+        /* Cleanup and exit */
+        ProfileHandle = 0;
+        goto Cleanup;
+    }
+
+    /* Check if we have a loader block extension */
+    LoaderExtension = LoaderBlock->Extension;
+    if (LoaderExtension)
+    {
+        /* Check the hardware profile status */
+        switch (LoaderExtension->Profile.Status)
+        {
+            /* Cloned status */
+            case 3:
+
+                /* Clone it */
+                Status = CmpCloneHwProfile(ConfigHandle,
+                                           ParentHandle,
+                                           ProfileHandle,
+                                           HwProfile,
+                                           LoaderExtension->
+                                           Profile.DockingState,
+                                           &ProfileHandle,
+                                           &HwProfile);
+                if (!NT_SUCCESS(Status))
+                {
+                    /* Cloning failed, cleanup and exit */
+                    ProfileHandle = 0;
+                    goto Cleanup;
+                }
+
+                /* Set the current config key */
+                RtlInitUnicodeString(&KeyName, L"CurrentConfig");
+                Status = NtSetValueKey(ConfigHandle,
+                                       &KeyName,
+                                       0,
+                                       REG_DWORD,
+                                       &HwProfile,
+                                       sizeof (HwProfile));
+                if (!NT_SUCCESS (Status)) goto Cleanup;
+
+            /* Alias status */
+            case 1:
+
+                /* Create an alias entry */
+                Status = CmpAddAliasEntry(ConfigHandle,
+                                          &LoaderExtension->Profile,
+                                          HwProfile);
+
+            /* Docking status */
+            case 2:
+
+                /* Create the current dock info key */
+                RtlInitUnicodeString(&KeyName,
+                                     L"CurrentDockInfo");
+                InitializeObjectAttributes(&ObjectAttributes,
+                                           &KeyName,
+                                           OBJ_CASE_INSENSITIVE,
+                                           ConfigHandle,
+                                           NULL);
+                Status = NtCreateKey(&KeyHandle,
+                                     KEY_READ | KEY_WRITE,
+                                     &ObjectAttributes,
+                                     0,
+                                     NULL,
+                                     REG_OPTION_VOLATILE,
+                                     &Disposition);
+                ASSERT (STATUS_SUCCESS == Status);
+
+                /* Add the docking information */
+                Status = CmpAddDockingInfo(KeyHandle,
+                                           &LoaderExtension->Profile);
+                break;
+
+            /* Other cases */
+            case 0:
+            case 0xC001:
+                break;
+
+            /* Unknown status */
+            default:
+                ASSERT(FALSE);
+        }
+    }
+
+    /* Create the current hardware profile key */
+    RtlInitUnicodeString(&KeyName,
+                         L"\\Registry\\Machine\\System\\CurrentControlSet\\"
+                         L"Hardware Profiles\\Current");
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &KeyName,
+                               OBJ_CASE_INSENSITIVE,
+                               NULL,
+                               NULL);
+    Status = NtCreateKey(&KeyHandle,
+                         KEY_CREATE_LINK,
+                         &ObjectAttributes,
+                         0,
+                         NULL,
+                         REG_OPTION_VOLATILE | REG_OPTION_CREATE_LINK,
+                         &Disposition);
+    if (NT_SUCCESS(Status))
+    {
+        /* Sanity check */
+        ASSERT(Disposition == REG_CREATED_NEW_KEY);
+
+        /* Create the profile name */
+        sprintf(Buffer,
+                "\\Registry\\Machine\\System\\CurrentControlSet\\"
+                "Hardware Profiles\\%04ld",
+                HwProfile);
+        RtlInitAnsiString(&TempString, Buffer);
+
+        /* Convert it to Unicode */
+        KeyName.MaximumLength = sizeof(UnicodeBuffer);
+        KeyName.Buffer = UnicodeBuffer;
+        Status = RtlAnsiStringToUnicodeString(&KeyName,
+                                              &TempString,
+                                              FALSE);
+        ASSERT (STATUS_SUCCESS == Status);
+
+        /* Set it */
+        Status = NtSetValueKey(KeyHandle,
+                               &CmSymbolicLinkValueName,
+                               0,
+                               REG_LINK,
+                               KeyName.Buffer,
+                               KeyName.Length);
+        NtClose(KeyHandle);
+    }
+
+    /* Check if we have to set the ACPI Profile */
+    if (AcpiProfile)
+    {
+        /* Setup the docking state to undocked */
+        AcpiDockState.DockingState = 1;
+        AcpiDockState.SerialLength = 2;
+        AcpiDockState.SerialNumber[0] = L'\0';
+
+        /* Set the ACPI profile */
+        Status = CmSetAcpiHwProfile(&AcpiDockState,
+                                    CmpHwProfileDefaultSelect,
+                                    NULL,
+                                    &AcpiHandle,
+                                    &Active);
+        ASSERT(NT_SUCCESS(Status));
+
+        /* Close the key */
+        NtClose(AcpiHandle);
+    }
+
+    /* Close every opened handle */
+Cleanup:
+    if (ConfigHandle) NtClose(ConfigHandle);
+    if (ProfileHandle) NtClose(ProfileHandle);
+    if (ParentHandle) NtClose(ParentHandle);
+
+    /* Return success */
+    return STATUS_SUCCESS;
+}
+#endif

Modified: trunk/reactos/ntoskrnl/include/internal/ntoskrnl.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/ntoskrnl.h?rev=26669&r1=26668&r2=26669&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/ntoskrnl.h (original)
+++ trunk/reactos/ntoskrnl/include/internal/ntoskrnl.h Thu May 10 04:02:04 2007
@@ -73,8 +73,8 @@
 BOOLEAN NTAPI ObInit(VOID);
 BOOLEAN NTAPI CmInitSystem1(VOID);
 VOID CmShutdownRegistry(VOID);
-BOOLEAN CmImportSystemHive(PCHAR ChunkBase, ULONG ChunkSize);
-BOOLEAN CmImportHardwareHive(PCHAR ChunkBase, ULONG ChunkSize);
+//BOOLEAN CmImportSystemHive(PCHAR ChunkBase, ULONG ChunkSize);
+//BOOLEAN CmImportHardwareHive(PCHAR ChunkBase, ULONG ChunkSize);
 BOOLEAN NTAPI KdInitSystem(ULONG Reserved, PLOADER_PARAMETER_BLOCK LoaderBlock);
 
 /* FIXME - RtlpCreateUnicodeString is obsolete and should be removed ASAP! */

Modified: trunk/reactos/ntoskrnl/ntoskrnl.rbuild
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ntoskrnl.rbuild?rev=26669&r1=26668&r2=26669&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/ntoskrnl.rbuild (original)
+++ trunk/reactos/ntoskrnl/ntoskrnl.rbuild Thu May 10 04:02:04 2007
@@ -92,6 +92,7 @@
             <file>cmname.c</file>
             <file>cmparse.c</file>
             <file>cmsecach.c</file>
+            <file>cmsysini.c</file>
             <file>cmvalue.c</file>
     </directory>
     <directory name="cm">




More information about the Ros-diffs mailing list