update for HEAD-2003091401
[reactos.git] / ntoskrnl / cm / import.c
index 1221d19..2d3cd13 100644 (file)
@@ -3,10 +3,12 @@
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/cm/import.c
- * PURPOSE:         Registry functions
- * PROGRAMMERS:     Rex Jolliff
+ * PURPOSE:         Registry-Hive import functions
+ * PROGRAMMERS:     Eric Kohl
  */
 
+/* INCLUDES *****************************************************************/
+
 #include <ctype.h>
 
 #include <ddk/ntddk.h>
 #include <string.h>
 #include <internal/pool.h>
 #include <internal/registry.h>
+#include <internal/ntoskrnl.h>
 
 #define NDEBUG
 #include <internal/debug.h>
 
 #include "cm.h"
 
-static PCHAR 
-checkAndSkipMagic (PCHAR  regChunk)
-{
-  if (strncmp (regChunk, 
-               REGISTRY_FILE_MAGIC, 
-               strlen (REGISTRY_FILE_MAGIC)) != 0)
-  {
-    CPRINT ("incorrect magic number in registry chunk. expected: %s got:%.*s\n",
-            REGISTRY_FILE_MAGIC,
-            strlen (REGISTRY_FILE_MAGIC),
-            regChunk);
-    return  0;
-  }
-  regChunk += strlen (REGISTRY_FILE_MAGIC);
-  DPRINT ("Found regsitry chunk magic value\n");
-
-  return  regChunk;
-}
-
-static PCHAR
-skipWhitespaceInChunk (PCHAR regChunk)
-{
-  while (*regChunk && isspace (*regChunk))
-    regChunk++;
-
-  return *regChunk ? regChunk : 0;
-}
+/* GLOBALS ******************************************************************/
 
-static int
-computeKeyNameSize (PCHAR  regChunk)
-{
-  int  copyCount = 0;
+static BOOLEAN CmiHardwareHiveImported = FALSE;
 
-  while (*regChunk != 0 && *regChunk != ']')
-  {
-    copyCount++;
-    regChunk++;
-  }
 
-  return  copyCount;
-}
+/* FUNCTIONS ****************************************************************/
 
 static BOOLEAN
-allocateKeyName (PUNICODE_STRING  newKeyName, int  newKeySize)
+CmImportBinaryHive (PCHAR ChunkBase,
+                   ULONG ChunkSize,
+                   ULONG Flags,
+                   PREGISTRY_HIVE *RegistryHive)
 {
-  if (newKeyName->MaximumLength < (newKeySize + 1) * sizeof (WCHAR))
-  {
-    if (newKeyName->Buffer != 0)
-      ExFreePool (newKeyName->Buffer);
-    newKeyName->Length = 0;
-    newKeyName->MaximumLength = (newKeySize + 1) * sizeof (WCHAR);
-    newKeyName->Buffer = ExAllocatePool (NonPagedPool, newKeyName->MaximumLength);
-    if (newKeyName->Buffer == 0)
+  PREGISTRY_HIVE Hive;
+  NTSTATUS Status;
+
+  *RegistryHive = NULL;
+
+  if (strncmp (ChunkBase, "regf", 4))
     {
-      CPRINT ("Could not allocate space for key name\n");
-      return  FALSE;
+      DPRINT1 ("Found invalid '%*s' magic\n", 4, ChunkBase);
+      return FALSE;
     }
-    newKeyName->Buffer [0] = 0;
-  }
-  else
-  {
-    newKeyName->Length = 0;
-    newKeyName->Buffer [0] = 0;
-  }
-
-  return  TRUE;
-}
 
-static PCHAR
-skipToNextKeyInChunk (PCHAR  regChunk)
-{
-  while (*regChunk != 0 && *regChunk != '[')
-  {
-    while (*regChunk != 0 && *regChunk != '\n')
+  /* Create a new hive */
+  Hive = ExAllocatePool (NonPagedPool,
+                        sizeof(REGISTRY_HIVE));
+  if (Hive == NULL)
     {
-      regChunk++;
+      return FALSE;
     }
-    regChunk++;
-  }
+  RtlZeroMemory (Hive,
+                sizeof(REGISTRY_HIVE));
 
-  return  *regChunk ? regChunk : 0;
-}
+  /* Set hive flags */
+  Hive->Flags = Flags;
 
-static PCHAR
-getKeyNameFromChunk (PCHAR  regChunk, PUNICODE_STRING  newKeyName)
-{
-  int index = 0;
-
-  while (*regChunk != 0 && *regChunk != ']')
-  {
-    newKeyName->Buffer [index++] = *regChunk++;
-  }
-  newKeyName->Buffer [index] = '\0';
-  newKeyName->Length = index * sizeof (WCHAR);
-
-  return  *regChunk ? regChunk : 0;
-}
+  /* Allocate hive header */
+  Hive->HiveHeader = (PHIVE_HEADER)ExAllocatePool (NonPagedPool,
+                                                  sizeof(HIVE_HEADER));
+  if (Hive->HiveHeader == NULL)
+    {
+      DPRINT1 ("Allocating hive header failed\n");
+      ExFreePool (Hive);
+      return FALSE;
+    }
 
-static HANDLE
-createNewKey (PUNICODE_STRING  newKeyName)
-{
-  NTSTATUS  status;
-  OBJECT_ATTRIBUTES  attributes;
-  HANDLE  handleToReturn;
-
-  DPRINT ("Creating key (%wZ)\n", newKeyName);
-  InitializeObjectAttributes (&attributes,
-                              newKeyName,
-                              0,
-                              0,
-                              NULL);
-  status = NtCreateKey (&handleToReturn,
-                        KEY_ALL_ACCESS,
-                        &attributes,
-                        0,
-                        NULL,
-                        REG_OPTION_VOLATILE,
-                        NULL);
-  if (!NT_SUCCESS(status))
-  {
-    CPRINT ("Could not crete key (%wZ)\n", newKeyName);
-    return  INVALID_HANDLE_VALUE;
-  }
-
-  return  handleToReturn;
-}
+  /* Import the hive header */
+  RtlCopyMemory (Hive->HiveHeader,
+                ChunkBase,
+                sizeof(HIVE_HEADER));
 
-static PCHAR
-skipToNextKeyValueInChunk (PCHAR  regChunk)
-{
-  while (*regChunk != 0 && *regChunk != '\n')
-    regChunk++;
-  regChunk = skipWhitespaceInChunk (regChunk);
-  
-  return  regChunk;
-}
+  /* Read update counter */
+  Hive->UpdateCounter = Hive->HiveHeader->UpdateCounter1;
 
-static int
-computeKeyValueNameSize (PCHAR  regChunk)
-{
-  int size = 0;
-
-  if (*regChunk != '\"')
-    return  0;
-  regChunk++;
-  while (*regChunk != 0 && *regChunk != '\"')
-  {
-    size++;
-    regChunk++;
-  }
-
-  return  regChunk ? size : 0;
-}
+  /* Set the hive's size */
+  Hive->FileSize = ChunkSize;
 
-static PCHAR
-getKeyValueNameFromChunk (PCHAR  regChunk, PUNICODE_STRING  newKeyName)
-{
-  int  index = 0;
-
-  regChunk++;
-  while (*regChunk != 0 && *regChunk != '\"')
-  {
-    newKeyName->Buffer [index++] = *regChunk++;
-  }
-  newKeyName->Buffer [index] = '\0';
-  newKeyName->Length = index * sizeof (WCHAR);
-  regChunk++;
-
-  return  *regChunk ? regChunk : 0;
-}
+  /* Set the size of the block list */
+  Hive->BlockListSize = (Hive->FileSize / 4096) - 1;
 
-static PCHAR 
-getKeyValueTypeFromChunk (PCHAR  regChunk, PCHAR  dataFormat, int *keyValueType)
-{
-  if (*regChunk == '\"')
-  {
-    strcpy (dataFormat, "string");
-    *keyValueType = REG_SZ;
-  }
-  else if (strncmp (regChunk, "hex", 3) == 0)
-  {
-    strcpy (dataFormat, "hex");
-    regChunk += 3;
-    if (*regChunk == '(')
+  /* Allocate block list */
+  DPRINT("Space needed for block list describing hive: 0x%x\n",
+        Hive->BlockListSize * sizeof(PHBIN *));
+  Hive->BlockList = ExAllocatePool (NonPagedPool,
+                                   Hive->BlockListSize * sizeof(PHBIN *));
+  if (Hive->BlockList == NULL)
     {
-      regChunk++;
-      *keyValueType = atoi (regChunk);
-      while (*regChunk != 0 && *regChunk != ')')
-        regChunk++;
-      regChunk++;
+      DPRINT1 ("Allocating block list failed\n");
+      ExFreePool (Hive->HiveHeader);
+      ExFreePool (Hive);
+      return FALSE;
     }
-    else
-      *keyValueType = REG_BINARY;
-    if (*regChunk == ':')
-      regChunk++;
-  }
-  else if (strncmp (regChunk, "dword", 5) == 0)
-  {
-    strcpy (dataFormat, "dword");
-    *keyValueType = REG_DWORD;
-    regChunk += 5;
-    if (*regChunk == ':')
-      regChunk++;
-  }
-  else if (strncmp (regChunk, "multi", 5) == 0)
-  {
-    strcpy (dataFormat, "multi");
-    *keyValueType = REG_MULTI_SZ;
-    regChunk += 5;
-    if (*regChunk == ':')
-      regChunk++;
-  }
-  else if (strncmp (regChunk, "expand", 6) == 0)
-  {
-    strcpy (dataFormat, "expand");
-    *keyValueType = REG_EXPAND_SZ;
-    regChunk += 6;
-    if (*regChunk == ':')
-      regChunk++;
-  }
-  else
-  {
-    UNIMPLEMENTED;
-  }
-
-  return  *regChunk ? regChunk : 0;
-}
-
-static int 
-computeKeyValueDataSize (PCHAR  regChunk, PCHAR  dataFormat)
-{
-  int  dataSize = 0;
+  RtlZeroMemory (Hive->BlockList,
+                Hive->BlockListSize * sizeof(PHBIN *));
 
-  if (strcmp (dataFormat, "string") == 0)
-  {
-    regChunk++;
-    while (*regChunk != 0 && *regChunk != '\"')
-    {
-      dataSize++;
-      dataSize++;
-      regChunk++;
-    }
-    dataSize++;
-    dataSize++;
-  }
-  else if (strcmp (dataFormat, "hex") == 0)
-  {
-    while (*regChunk != 0 && isxdigit(*regChunk))
+  /* Import the bins */
+  Status = CmiImportHiveBins(Hive,
+                            (PUCHAR)((ULONG_PTR)ChunkBase + 4096));
+  if (!NT_SUCCESS(Status))
     {
-      regChunk++;
-      regChunk++;
-      dataSize++;
-      if (*regChunk == ',')
-      {
-        regChunk++;
-        if (*regChunk == '\\')
-        {
-          regChunk++;
-          regChunk = skipWhitespaceInChunk (regChunk);
-        }
-      }
+      DPRINT1 ("CmiImportHiveBins() failed (Status %lx)\n", Status);
+      CmiFreeHiveBins (Hive);
+      ExFreePool (Hive->BlockList);
+      ExFreePool (Hive->HiveHeader);
+      ExFreePool (Hive);
+      return Status;
     }
-  }
-  else if (strcmp (dataFormat, "dword") == 0)
-  {
-    dataSize = sizeof(DWORD);
-    while (*regChunk != 0 && isxdigit(*regChunk))
-    {
-      regChunk++;
-    }
-  }
-  else if (strcmp (dataFormat, "multi") == 0)
-  {
-    while (*regChunk == '\"')
+
+  /* Initialize the free cell list */
+  Status = CmiCreateHiveFreeCellList (Hive);
+  if (!NT_SUCCESS(Status))
     {
-      regChunk++;
-      while (*regChunk != 0 && *regChunk != '\"')
-      {
-        dataSize++;
-        dataSize++;
-        regChunk++;
-      }
-      regChunk++;
-      dataSize++;
-      dataSize++;
-      if (*regChunk == ',')
-      {
-        regChunk++;
-        regChunk = skipWhitespaceInChunk (regChunk);
-        if (*regChunk == '\\')
-        {
-          regChunk++;
-          regChunk = skipWhitespaceInChunk (regChunk);
-        }
-      }
-      else
-        break;
+      DPRINT1 ("CmiCreateHiveFreeCellList() failed (Status %lx)\n", Status);
+      CmiFreeHiveBins (Hive);
+      ExFreePool (Hive->BlockList);
+      ExFreePool (Hive->HiveHeader);
+      ExFreePool (Hive);
+
+      return Status;
     }
-    dataSize++;
-    dataSize++;
-  }
-  else if (strcmp (dataFormat, "expand") == 0)
-  {
-    regChunk++;
-    while (*regChunk != 0 && *regChunk != '\"')
+
+  if (!(Hive->Flags & HIVE_NO_FILE))
     {
-      dataSize++;
-      dataSize++;
-      regChunk++;
+      /* Create the block bitmap */
+      Status = CmiCreateHiveBitmap (Hive);
+      if (!NT_SUCCESS(Status))
+       {
+         DPRINT1 ("CmiCreateHiveBitmap() failed (Status %lx)\n", Status);
+         CmiFreeHiveFreeCellList (Hive);
+         CmiFreeHiveBins (Hive);
+         ExFreePool (Hive->BlockList);
+         ExFreePool (Hive->HiveHeader);
+         ExFreePool (Hive);
+
+         return Status;
+       }
     }
-    dataSize++;
-    dataSize++;
-  }
-  else
-  {
-    UNIMPLEMENTED;
-  }
-
-  return  dataSize;
-}
 
-static BOOLEAN
-allocateDataBuffer (PVOID * data, int * dataBufferSize, int dataSize)
-{
-  if (*dataBufferSize < dataSize)
-  {
-    if (*dataBufferSize > 0)
-      ExFreePool (*data);
-    *data = ExAllocatePool (NonPagedPool, dataSize);
-    *dataBufferSize = dataSize;
-  }
-
-  return  TRUE;
+  /* Initialize the hive's executive resource */
+  ExInitializeResourceLite(&Hive->HiveResource);
+
+  /* Acquire hive list lock exclusively */
+  ExAcquireResourceExclusiveLite(&CmiHiveListLock, TRUE);
+
+  /* Add the new hive to the hive list */
+  InsertTailList(&CmiHiveListHead, &Hive->HiveList);
+
+  /* Release hive list lock */
+  ExReleaseResourceLite(&CmiHiveListLock);
+
+  *RegistryHive = Hive;
+
+  return TRUE;
 }
 
-static PCHAR
-getKeyValueDataFromChunk (PCHAR  regChunk, PCHAR  dataFormat, PCHAR data)
+
+BOOLEAN
+CmImportSystemHive(PCHAR ChunkBase,
+                  ULONG ChunkSize)
 {
-  char  dataValue;
-  ULONG ulValue;
-  PWCHAR ptr;
-  
-  if (strcmp (dataFormat, "string") == 0)
-  {
-    /* convert quoted string to zero-terminated Unicode string */
-    ptr = (PWCHAR)data;
-    regChunk++;
-    while (*regChunk != 0 && *regChunk != '\"')
+  OBJECT_ATTRIBUTES ObjectAttributes;
+  PREGISTRY_HIVE RegistryHive;
+  UNICODE_STRING KeyName;
+  NTSTATUS Status;
+
+  DPRINT ("CmImportSystemHive() called\n");
+
+  if (strncmp (ChunkBase, "regf", 4))
     {
-      *ptr++ = (WCHAR)*regChunk++;
+      DPRINT1 ("Found invalid '%.*s' magic\n", 4, ChunkBase);
+      return FALSE;
     }
-    *ptr = 0;
-    regChunk++;
-  }
-  else if (strcmp (dataFormat, "hex") == 0)
-  {
-    while (*regChunk != 0 && isxdigit (*regChunk))
+
+  DPRINT ("Found '%.*s' magic\n", 4, ChunkBase);
+
+  /* Import the binary system hive (non-volatile, offset-based, permanent) */
+  if (!CmImportBinaryHive (ChunkBase, ChunkSize, 0, &RegistryHive))
     {
-      dataValue = (isdigit (*regChunk) ? *regChunk - '0' : 
-        tolower(*regChunk) - 'a' + 10) << 4;
-      regChunk++;
-      dataValue += (isdigit (*regChunk) ? *regChunk - '0' : 
-        tolower(*regChunk) - 'a' + 10);
-      regChunk++;
-      *data++ = dataValue;
-      if (*regChunk == ',')
-      {
-        regChunk++;
-        if (*regChunk == '\\')
-        {
-          regChunk++;
-          regChunk = skipWhitespaceInChunk (regChunk);
-        }
-      }
+      DPRINT1 ("CmiImportBinaryHive() failed\n", Status);
+      return FALSE;
     }
-  }
-  else if (strcmp (dataFormat, "dword") == 0)
-  {
-    ulValue = 0;
-    while (*regChunk != 0 && isxdigit(*regChunk))
+
+  /* Attach it to the machine key */
+  RtlInitUnicodeString (&KeyName,
+                       L"\\Registry\\Machine\\System");
+  InitializeObjectAttributes (&ObjectAttributes,
+                             &KeyName,
+                             OBJ_CASE_INSENSITIVE,
+                             NULL,
+                             NULL);
+  Status = CmiConnectHive (&ObjectAttributes,
+                          RegistryHive);
+  if (!NT_SUCCESS(Status))
     {
-      dataValue = (isdigit (*regChunk) ? *regChunk - '0' : 
-        tolower(*regChunk) - 'a' + 10);
-      ulValue = (ulValue << 4) + dataValue;
-      regChunk++;
+      DPRINT1 ("CmiConnectHive() failed (Status %lx)\n", Status);
+//      CmiRemoveRegistryHive(RegistryHive);
+      return FALSE;
     }
-    memcpy(data, &ulValue, sizeof(ULONG));
-  }
-  else if (strcmp (dataFormat, "multi") == 0)
-  {
-    ptr = (PWCHAR)data;
-    while (*regChunk == '\"')
+
+  /* Set the hive filename */
+  RtlCreateUnicodeString (&RegistryHive->HiveFileName,
+                         SYSTEM_REG_FILE);
+
+  /* Set the log filename */
+  RtlCreateUnicodeString (&RegistryHive->LogFileName,
+                         SYSTEM_LOG_FILE);
+
+  return TRUE;
+}
+
+
+BOOLEAN
+CmImportHardwareHive(PCHAR ChunkBase,
+                    ULONG ChunkSize)
+{
+  OBJECT_ATTRIBUTES ObjectAttributes;
+  PREGISTRY_HIVE RegistryHive;
+  UNICODE_STRING KeyName;
+  HANDLE HardwareKey;
+  ULONG Disposition;
+  NTSTATUS Status;
+
+  DPRINT ("CmImportHardwareHive() called\n");
+
+  if (CmiHardwareHiveImported == TRUE)
+    return TRUE;
+
+  if (ChunkBase == NULL &&
+      ChunkSize == 0)
     {
-      regChunk++;
-      while (*regChunk != 0 && *regChunk != '\"')
-      {
-        *ptr++ = (WCHAR)*regChunk++;
-      }
-      regChunk++;
-      *ptr++ = 0;
-      if (*regChunk == ',')
-      {
-        regChunk++;
-        regChunk = skipWhitespaceInChunk (regChunk);
-        if (*regChunk == '\\')
-        {
-          regChunk++;
-          regChunk = skipWhitespaceInChunk (regChunk);
-        }
-      }
-      else
-        break;
+      /* Create '\Registry\Machine\HARDWARE' key. */
+      RtlInitUnicodeString (&KeyName,
+                           L"\\Registry\\Machine\\HARDWARE");
+      InitializeObjectAttributes (&ObjectAttributes,
+                                 &KeyName,
+                                 OBJ_CASE_INSENSITIVE,
+                                 NULL,
+                                 NULL);
+      Status = NtCreateKey (&HardwareKey,
+                           KEY_ALL_ACCESS,
+                           &ObjectAttributes,
+                           0,
+                           NULL,
+                           REG_OPTION_VOLATILE,
+                           &Disposition);
+      if (!NT_SUCCESS(Status))
+       {
+         return FALSE;
+       }
+      NtClose (HardwareKey);
+
+      /* Create '\Registry\Machine\HARDWARE\DESCRIPTION' key. */
+      RtlInitUnicodeString(&KeyName,
+                          L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION");
+      InitializeObjectAttributes (&ObjectAttributes,
+                                 &KeyName,
+                                 OBJ_CASE_INSENSITIVE,
+                                 NULL,
+                                 NULL);
+      Status = NtCreateKey (&HardwareKey,
+                           KEY_ALL_ACCESS,
+                           &ObjectAttributes,
+                           0,
+                           NULL,
+                           REG_OPTION_VOLATILE,
+                           &Disposition);
+      if (!NT_SUCCESS(Status))
+       {
+         return FALSE;
+       }
+      NtClose (HardwareKey);
+
+      /* Create '\Registry\Machine\HARDWARE\DEVICEMAP' key. */
+      RtlInitUnicodeString (&KeyName,
+                           L"\\Registry\\Machine\\HARDWARE\\DEVICEMAP");
+      InitializeObjectAttributes (&ObjectAttributes,
+                                 &KeyName,
+                                 OBJ_CASE_INSENSITIVE,
+                                 NULL,
+                                 NULL);
+      Status = NtCreateKey (&HardwareKey,
+                           KEY_ALL_ACCESS,
+                           &ObjectAttributes,
+                           0,
+                           NULL,
+                           REG_OPTION_VOLATILE,
+                           &Disposition);
+      if (!NT_SUCCESS(Status))
+       {
+         return FALSE;
+       }
+      NtClose (HardwareKey);
+
+      /* Create '\Registry\Machine\HARDWARE\RESOURCEMAP' key. */
+      RtlInitUnicodeString(&KeyName,
+                          L"\\Registry\\Machine\\HARDWARE\\RESOURCEMAP");
+      InitializeObjectAttributes (&ObjectAttributes,
+                                 &KeyName,
+                                 OBJ_CASE_INSENSITIVE,
+                                 NULL,
+                                 NULL);
+      Status = NtCreateKey (&HardwareKey,
+                           KEY_ALL_ACCESS,
+                           &ObjectAttributes,
+                           0,
+                           NULL,
+                           REG_OPTION_VOLATILE,
+                           &Disposition);
+      if (!NT_SUCCESS(Status))
+       {
+         return FALSE;
+       }
+      NtClose (HardwareKey);
+
+      return TRUE;
     }
-    *ptr = 0;
-  }
-  else if (strcmp (dataFormat, "expand") == 0)
-  {
-    /* convert quoted string to zero-terminated Unicode string */
-    ptr = (PWCHAR)data;
-    regChunk++;
-    while (*regChunk != 0 && *regChunk != '\"')
+
+  /* Check the hive magic */
+  if (strncmp (ChunkBase, "regf", 4))
     {
-      *ptr++ = (WCHAR)*regChunk++;
+      DPRINT1 ("Found invalid '%.*s' magic\n", 4, ChunkBase);
+      return FALSE;
     }
-    *ptr = 0;
-    regChunk++;
-  }
-  else
-  {
-    UNIMPLEMENTED;
-  }
-
-  return  *regChunk ? regChunk : 0;
-}
 
-static BOOLEAN
-setKeyValue (HANDLE  currentKey,
-             PUNICODE_STRING  newValueName,
-             ULONG  keyValueType,
-             PVOID  data,
-             ULONG  dataSize)
-{
-  NTSTATUS  status;
-
-  DPRINT ("Adding value (%wZ) to current key, with data type %d size %d\n",
-          newValueName,
-          keyValueType,
-          dataSize);
-  status = NtSetValueKey (currentKey,
-                          newValueName,
-                          0,
-                          keyValueType,
-                          data,
-                          dataSize);
-  if (!NT_SUCCESS(status))
-  {
-    CPRINT ("could not set key value, rc:%08x\n", status);
-    return  FALSE;
-  }
-
-  return  TRUE;
-}
+  DPRINT ("Found '%.*s' magic\n", 4, ChunkBase);
+  DPRINT ("ChunkBase %lx  ChunkSize %lu\n", ChunkBase, ChunkSize);
 
-VOID
-CmImportHive(PCHAR  ChunkBase,
-            ULONG  ChunkSize)
-{
-  HANDLE  currentKey = INVALID_HANDLE_VALUE;
-  int  newKeySize;
-  UNICODE_STRING  newKeyName = {0, 0, 0};
-  char  dataFormat [10];
-  int  keyValueType;
-  int  dataSize = 0;
-  int  dataBufferSize = 0;
-  PVOID  data = 0;
-  PCHAR regChunk;
-
-  DPRINT("ChunkBase %p  ChunkSize %lx\n", ChunkBase, ChunkSize);
-
-  regChunk = checkAndSkipMagic (ChunkBase);
-  if (regChunk == 0)
-    return;
-
-  while (regChunk != 0 && *regChunk != 0 && (((ULONG)regChunk-(ULONG)ChunkBase) < ChunkSize))
-  {
-    regChunk = skipWhitespaceInChunk (regChunk);
-    if (regChunk == 0)
-      continue;
-
-    if (*regChunk == '[')
+  /* Import the binary system hive (volatile, offset-based, permanent) */
+  if (!CmImportBinaryHive (ChunkBase, ChunkSize, HIVE_NO_FILE, &RegistryHive))
     {
-      if (currentKey != INVALID_HANDLE_VALUE)
-      {
-        DPRINT("Closing current key: 0x%lx\n", currentKey);
-        NtClose (currentKey);
-        currentKey = INVALID_HANDLE_VALUE;
-      }
-
-      regChunk++;
-
-      newKeySize = computeKeyNameSize (regChunk);
-      if (!allocateKeyName (&newKeyName, newKeySize))
-      {
-        regChunk = 0;
-        continue;
-      }
-
-      regChunk = getKeyNameFromChunk (regChunk, &newKeyName);
-      if (regChunk == 0)
-        continue;
-
-      currentKey = createNewKey (&newKeyName);
-      if (currentKey == INVALID_HANDLE_VALUE)
-      {
-        regChunk = skipToNextKeyInChunk (regChunk);
-        continue;
-      }
-
-      regChunk++;
+      DPRINT1 ("CmiImportBinaryHive() failed\n", Status);
+      return FALSE;
     }
-    else
+
+  /* Attach it to the machine key */
+  RtlInitUnicodeString (&KeyName,
+                       L"\\Registry\\Machine\\HARDWARE");
+  InitializeObjectAttributes (&ObjectAttributes,
+                             &KeyName,
+                             OBJ_CASE_INSENSITIVE,
+                             NULL,
+                             NULL);
+  Status = CmiConnectHive (&ObjectAttributes,
+                          RegistryHive);
+  if (!NT_SUCCESS(Status))
     {
-      if (currentKey == INVALID_HANDLE_VALUE)
-      {
-        regChunk = skipToNextKeyInChunk (regChunk);
-        continue;
-      }
-
-      newKeySize = computeKeyValueNameSize (regChunk);
-      if (!allocateKeyName (&newKeyName, newKeySize))
-      {
-        regChunk = 0;
-        continue;
-      }
-
-      regChunk = getKeyValueNameFromChunk (regChunk, &newKeyName);
-      if (regChunk == 0)
-        continue;
-
-      if (*regChunk != '=')
-      {
-        regChunk = skipToNextKeyValueInChunk (regChunk);
-        continue;
-      }
-      regChunk++;
-
-      regChunk = getKeyValueTypeFromChunk (regChunk, dataFormat, &keyValueType);
-      if (regChunk == 0)
-        continue;
-
-      dataSize = computeKeyValueDataSize (regChunk, dataFormat);
-      if (!allocateDataBuffer (&data, &dataBufferSize, dataSize))
-      {
-        regChunk = 0;
-        continue;
-      }
-      
-      regChunk = getKeyValueDataFromChunk (regChunk, dataFormat, data);
-      if (regChunk == 0)
-        continue;
-
-      if (!setKeyValue (currentKey, &newKeyName, keyValueType, data, dataSize))
-      {
-        regChunk = 0;
-        continue;
-      }
+      DPRINT1 ("CmiConnectHive() failed (Status %lx)\n", Status);
+//      CmiRemoveRegistryHive(RegistryHive);
+      return FALSE;
     }
-  }
-
-  if (currentKey != INVALID_HANDLE_VALUE)
-  {
-    NtClose (currentKey);
-  }
-  if (newKeyName.Buffer != 0)
-  {
-    ExFreePool (newKeyName.Buffer);
-  }
-  if (data != 0)
-  {
-    ExFreePool (data);
-  }
-
-  return;
-}
 
+  /* Set the hive filename */
+  RtlInitUnicodeString (&RegistryHive->HiveFileName,
+                       NULL);
+
+  /* Set the log filename */
+  RtlInitUnicodeString (&RegistryHive->LogFileName,
+                       NULL);
+
+  CmiHardwareHiveImported = TRUE;
+
+  return TRUE;
+}
 
+/* EOF */