[MKHIVE][CMAKE] Make mkhive a bit more flexible, so that it can generate only specifi...
authorHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Fri, 2 Jun 2017 00:34:10 +0000 (00:34 +0000)
committerHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Mon, 8 Oct 2018 19:23:38 +0000 (21:23 +0200)
This commit is needed for building a single bootcd registry hive. It will also enable 1-st stage setup to have a proper registry present as done on Windows.
CORE-13347

[CMAKE]
Note that the mkhive commands should really depend on the generated UTF16 INF files since the latter are those that are actually used as input for mkhive.
Otherwise, the mkhive calls & the UTF16 INF file conversion is not serialized and we can generate "corrupted" hives due to the fact that mkhive is using
INF files that are in the process of being (and therefore, only partially) generated.

svn path=/branches/setup_improvements/; revision=74741
svn path=/branches/setup_improvements/; revision=74749

sdk/cmake/CMakeMacros.cmake
sdk/tools/mkhive/mkhive.c
sdk/tools/mkhive/mkhive.h
sdk/tools/mkhive/registry.c
sdk/tools/mkhive/registry.h

index d321415..e86b639 100644 (file)
@@ -808,43 +808,66 @@ function(create_registry_hives)
                 NO_CAB
                 FOR bootcd regtest)
 
-    # livecd hives
+    # BootCD setup system hive
+    add_custom_command(
+        OUTPUT ${CMAKE_BINARY_DIR}/boot/bootdata/SETUPREG.HIV
+        COMMAND native-mkhive -h:SETUPREG -d:${CMAKE_BINARY_DIR}/boot/bootdata ${CMAKE_BINARY_DIR}/boot/bootdata/hivesys_utf16.inf
+        DEPENDS native-mkhive ${CMAKE_BINARY_DIR}/boot/bootdata/hivesys_utf16.inf)
+
+    add_custom_target(bootcd_hives
+        DEPENDS ${CMAKE_BINARY_DIR}/boot/bootdata/SETUPREG.HIV)
+
+    add_cd_file(
+        FILE ${CMAKE_BINARY_DIR}/boot/bootdata/SETUPREG.HIV
+        TARGET bootcd_hives
+        DESTINATION reactos
+        NO_CAB
+        FOR bootcd regtest)
+
+    # LiveCD hives
     list(APPEND _livecd_inf_files
         ${_registry_inf}
         ${CMAKE_SOURCE_DIR}/boot/bootdata/livecd.inf
         ${CMAKE_SOURCE_DIR}/boot/bootdata/hiveinst.inf)
 
     add_custom_command(
-        OUTPUT ${CMAKE_BINARY_DIR}/boot/bootdata/sam
-            ${CMAKE_BINARY_DIR}/boot/bootdata/default
-            ${CMAKE_BINARY_DIR}/boot/bootdata/security
-            ${CMAKE_BINARY_DIR}/boot/bootdata/software
-            ${CMAKE_BINARY_DIR}/boot/bootdata/system
-            ${CMAKE_BINARY_DIR}/boot/bootdata/BCD
-        COMMAND native-mkhive ${CMAKE_BINARY_DIR}/boot/bootdata ${_livecd_inf_files}
+        OUTPUT ${CMAKE_BINARY_DIR}/boot/bootdata/system
+               ${CMAKE_BINARY_DIR}/boot/bootdata/software
+               ${CMAKE_BINARY_DIR}/boot/bootdata/default
+               ${CMAKE_BINARY_DIR}/boot/bootdata/sam
+               ${CMAKE_BINARY_DIR}/boot/bootdata/security
+        COMMAND native-mkhive -h:SYSTEM,SOFTWARE,DEFAULT,SAM,SECURITY -d:${CMAKE_BINARY_DIR}/boot/bootdata ${_livecd_inf_files}
         DEPENDS native-mkhive ${_livecd_inf_files})
 
     add_custom_target(livecd_hives
-        DEPENDS ${CMAKE_BINARY_DIR}/boot/bootdata/sam
-            ${CMAKE_BINARY_DIR}/boot/bootdata/default
-            ${CMAKE_BINARY_DIR}/boot/bootdata/security
-            ${CMAKE_BINARY_DIR}/boot/bootdata/software
-            ${CMAKE_BINARY_DIR}/boot/bootdata/system
-            ${CMAKE_BINARY_DIR}/boot/bootdata/BCD)
+        DEPENDS ${CMAKE_BINARY_DIR}/boot/bootdata/system
+                ${CMAKE_BINARY_DIR}/boot/bootdata/software
+                ${CMAKE_BINARY_DIR}/boot/bootdata/default
+                ${CMAKE_BINARY_DIR}/boot/bootdata/sam
+                ${CMAKE_BINARY_DIR}/boot/bootdata/security)
 
     add_cd_file(
-        FILE ${CMAKE_BINARY_DIR}/boot/bootdata/sam
-            ${CMAKE_BINARY_DIR}/boot/bootdata/default
-            ${CMAKE_BINARY_DIR}/boot/bootdata/security
-            ${CMAKE_BINARY_DIR}/boot/bootdata/software
-            ${CMAKE_BINARY_DIR}/boot/bootdata/system
+        FILE ${CMAKE_BINARY_DIR}/boot/bootdata/system
+             ${CMAKE_BINARY_DIR}/boot/bootdata/software
+             ${CMAKE_BINARY_DIR}/boot/bootdata/default
+             ${CMAKE_BINARY_DIR}/boot/bootdata/sam
+             ${CMAKE_BINARY_DIR}/boot/bootdata/security
         TARGET livecd_hives
         DESTINATION reactos/system32/config
         FOR livecd)
 
+    # BCD Hive
+    add_custom_command(
+        OUTPUT ${CMAKE_BINARY_DIR}/boot/bootdata/BCD
+        COMMAND native-mkhive -h:BCD -d:${CMAKE_BINARY_DIR}/boot/bootdata ${CMAKE_BINARY_DIR}/boot/bootdata/hivebcd_utf16.inf
+        DEPENDS native-mkhive ${CMAKE_BINARY_DIR}/boot/bootdata/hivebcd_utf16.inf)
+
+    add_custom_target(bcd_hive
+        DEPENDS ${CMAKE_BINARY_DIR}/boot/bootdata/BCD)
+
     add_cd_file(
         FILE ${CMAKE_BINARY_DIR}/boot/bootdata/BCD
-        TARGET livecd_hives
+        TARGET bcd_hive
         DESTINATION efi/boot
         NO_CAB
         FOR bootcd regtest livecd)
index a1d6ef4..39a443b 100644 (file)
@@ -21,8 +21,9 @@
  * PROJECT:         ReactOS hive maker
  * FILE:            tools/mkhive/mkhive.c
  * PURPOSE:         Hive maker
- * PROGRAMMER:      Eric Kohl
- *                  Hervé Poussineau
+ * PROGRAMMERS:     Eric Kohl
+ *                  Hervé Poussineau
+ *                  Hermès Bélusca-Maïto
  */
 
 #include <limits.h>
 #endif
 
 
-void usage (void)
+void usage(void)
 {
-    printf ("Usage: mkhive <dstdir> <inffiles>\n\n");
-    printf ("  dstdir   - binary hive files are created in this directory\n");
-    printf ("  inffiles - inf files with full path\n");
+    printf("Usage: mkhive -h:hive1[,hiveN...] -d:<dstdir> <inffiles>\n\n"
+           "  -h:hiveN  - Comma-separated list of hives to create. Possible values are:\n"
+           "              SETUPREG, SYSTEM, SOFTWARE, DEFAULT, SAM, SECURITY, BCD.\n"
+           "  -d:dstdir - The binary hive files are created in this directory.\n"
+           "  inffiles  - List of INF files with full path.\n");
 }
 
 void convert_path(char *dst, char *src)
@@ -83,83 +86,106 @@ void convert_path(char *dst, char *src)
     dst[i] = 0;
 }
 
-int main (int argc, char *argv[])
+int main(int argc, char *argv[])
 {
-    char FileName[PATH_MAX];
-    int i;
+    INT ret;
+    UINT i;
+    PCSTR HiveList = NULL;
+    CHAR DestPath[PATH_MAX] = "";
+    CHAR FileName[PATH_MAX];
 
-    if (argc < 3)
+    if (argc < 4)
     {
-        usage ();
-        return 1;
+        usage();
+        return -1;
     }
 
-    printf ("Binary hive maker\n");
-
-    RegInitializeRegistry ();
+    printf("Binary hive maker\n");
 
-    for (i = 2; i < argc; i++)
+    /* Read the options */
+    for (i = 1; i < argc && *argv[i] == '-'; i++)
     {
-        convert_path (FileName, argv[i]);
-        if (!ImportRegistryFile (FileName))
+        if (argv[i][1] == 'h' && (argv[i][2] == ':' || argv[i][2] == '='))
+        {
+            HiveList = argv[i] + 3;
+        }
+        else if (argv[i][1] == 'd' && (argv[i][2] == ':' || argv[i][2] == '='))
+        {
+            convert_path(DestPath, argv[i] + 3);
+        }
+        else
         {
-            return 1;
+            fprintf(stderr, "Unrecognized option: %s\n", argv[i]);
+            return -1;
         }
     }
 
-    convert_path (FileName, argv[1]);
-    strcat (FileName, DIR_SEPARATOR_STRING);
-    strcat (FileName, "default");
-    if (!ExportBinaryHive (FileName, &DefaultHive))
+    /* Check whether we have all the parameters needed */
+    if (!HiveList || !*HiveList)
     {
-        return 1;
+        fprintf(stderr, "The mandatory list of hives is missing.\n");
+        return -1;
     }
-
-    convert_path (FileName, argv[1]);
-    strcat (FileName, DIR_SEPARATOR_STRING);
-    strcat (FileName, "sam");
-    if (!ExportBinaryHive (FileName, &SamHive))
+    if (!*DestPath)
     {
-        return 1;
+        fprintf(stderr, "The mandatory output directory is missing.\n");
+        return -1;
     }
-
-    convert_path (FileName, argv[1]);
-    strcat (FileName, DIR_SEPARATOR_STRING);
-    strcat (FileName, "security");
-    if (!ExportBinaryHive (FileName, &SecurityHive))
+    if (i >= argc)
     {
-        return 1;
+        fprintf(stderr, "Not enough parameters, or the list of INF files is missing.\n");
+        return -1;
     }
 
-    convert_path (FileName, argv[1]);
-    strcat (FileName, DIR_SEPARATOR_STRING);
-    strcat (FileName, "software");
-    if (!ExportBinaryHive (FileName, &SoftwareHive))
-    {
-        return 1;
-    }
+    /* Initialize the registry */
+    RegInitializeRegistry(HiveList);
+
+    /* Default to failure */
+    ret = -1;
 
-    convert_path (FileName, argv[1]);
-    strcat (FileName, DIR_SEPARATOR_STRING);
-    strcat (FileName, "system");
-    if (!ExportBinaryHive (FileName, &SystemHive))
+    /* Now we should have the list of INF files: parse it */
+    for (; i < argc; ++i)
     {
-        return 1;
+        convert_path(FileName, argv[i]);
+        if (!ImportRegistryFile(FileName))
+            goto Quit;
     }
 
-    convert_path (FileName, argv[1]);
-    strcat (FileName, DIR_SEPARATOR_STRING);
-    strcat (FileName, "BCD");
-    if (!ExportBinaryHive (FileName, &BcdHive))
+    for (i = 0; i < MAX_NUMBER_OF_REGISTRY_HIVES; ++i)
     {
-        return 1;
+        /* Skip this registry hive if it's not in the list */
+        if (!strstr(HiveList, RegistryHives[i].HiveName))
+            continue;
+
+        strcpy(FileName, DestPath);
+        strcat(FileName, DIR_SEPARATOR_STRING);
+        strcat(FileName, RegistryHives[i].HiveName);
+
+        /* Exception for the special setup registry hive */
+        // if (strcmp(RegistryHives[i].HiveName, "SETUPREG") == 0)
+        if (i == 0)
+            strcat(FileName, ".HIV");
+
+        if (!ExportBinaryHive(FileName, RegistryHives[i].CmHive))
+            goto Quit;
+
+        /* If we happen to deal with the special setup registry hive, stop there */
+        // if (strcmp(RegistryHives[i].HiveName, "SETUPREG") == 0)
+        if (i == 0)
+            break;
     }
 
-    RegShutdownRegistry ();
+    /* Success */
+    ret = 0;
+
+Quit:
+    /* Shut down the registry */
+    RegShutdownRegistry();
 
-    printf ("  Done.\n");
+    if (ret == 0)
+        printf("  Done.\n");
 
-    return 0;
+    return ret;
 }
 
 /* EOF */
index 519ee91..517925a 100644 (file)
@@ -21,7 +21,7 @@
  * PROJECT:         ReactOS hive maker
  * FILE:            tools/mkhive/mkhive.h
  * PURPOSE:         Hive maker
- * PROGRAMMER     Eric Kohl
+ * PROGRAMMERS:     Eric Kohl
  *                  Hervé Poussineau
  */
 
 
 #include <typedefs.h>
 
+#ifndef _MSC_VER
+#ifndef _countof
+#define _countof(_Array) (sizeof(_Array) / sizeof(_Array[0]))
+#endif
+#endif
+
 // Definitions copied from <ntstatus.h>
 // We only want to include host headers, so we define them manually
 #define STATUS_SUCCESS                   ((NTSTATUS)0x00000000)
index e7a8cc9..17030bb 100644 (file)
@@ -21,7 +21,8 @@
  * PROJECT:         ReactOS hive maker
  * FILE:            tools/mkhive/registry.c
  * PURPOSE:         Registry code
- * PROGRAMMER:      Hervé Poussineau
+ * PROGRAMMERS:     Hervé Poussineau
+ *                  Hermès Bélusca-Maïto
  */
 
 /*
 
 static CMHIVE RootHive;
 static PMEMKEY RootKey;
-CMHIVE DefaultHive;  /* \Registry\User\.DEFAULT */
-CMHIVE SamHive;      /* \Registry\Machine\SAM */
-CMHIVE SecurityHive; /* \Registry\Machine\SECURITY */
-CMHIVE SoftwareHive; /* \Registry\Machine\SOFTWARE */
-CMHIVE SystemHive;   /* \Registry\Machine\SYSTEM */
-CMHIVE BcdHive;      /* \Registry\Machine\BCD00000000 */
+
+static CMHIVE SystemHive;   /* \Registry\Machine\SYSTEM */
+static CMHIVE SoftwareHive; /* \Registry\Machine\SOFTWARE */
+static CMHIVE DefaultHive;  /* \Registry\User\.DEFAULT */
+static CMHIVE SamHive;      /* \Registry\Machine\SAM */
+static CMHIVE SecurityHive; /* \Registry\Machine\SECURITY */
+static CMHIVE BcdHive;      /* \Registry\Machine\BCD00000000 */
 
 //
 // TODO: Write these values in a more human-readable form.
@@ -56,7 +58,7 @@ CMHIVE BcdHive;      /* \Registry\Machine\BCD00000000 */
 // A cross-check was subsequently done with the system hives to verify that
 // the security descriptors were the same.
 //
-UCHAR BcdSecurity[] =
+static UCHAR BcdSecurity[] =
 {
     // SECURITY_DESCRIPTOR_RELATIVE
     0x01,                   // Revision
@@ -118,7 +120,7 @@ UCHAR BcdSecurity[] =
     0x01, 0x02, 0x00, 0x00
 };
 
-UCHAR SoftwareSecurity[] =
+static UCHAR SoftwareSecurity[] =
 {
     // SECURITY_DESCRIPTOR_RELATIVE
     0x01,                   // Revision
@@ -234,7 +236,7 @@ UCHAR SoftwareSecurity[] =
 };
 
 // Same security for SYSTEM, SAM and .DEFAULT
-UCHAR SystemSecurity[] =
+static UCHAR SystemSecurity[] =
 {
     // SECURITY_DESCRIPTOR_RELATIVE
     0x01,                   // Revision
@@ -330,6 +332,24 @@ UCHAR SystemSecurity[] =
     0x01, 0x02, 0x00, 0x00
 };
 
+
+HIVE_LIST_ENTRY RegistryHives[/*MAX_NUMBER_OF_REGISTRY_HIVES*/] =
+{
+    /* Special Setup system registry hive */
+    // WARNING: Please *keep* it in first position!
+    { "SETUPREG", L"Registry\\Machine\\SYSTEM"     , &SystemHive  , SystemSecurity  , sizeof(SystemSecurity)   },
+
+    /* Regular registry hives */
+    { "SYSTEM"  , L"Registry\\Machine\\SYSTEM"     , &SystemHive  , SystemSecurity  , sizeof(SystemSecurity)   },
+    { "SOFTWARE", L"Registry\\Machine\\SOFTWARE"   , &SoftwareHive, SoftwareSecurity, sizeof(SoftwareSecurity) },
+    { "DEFAULT" , L"Registry\\User\\.DEFAULT"      , &DefaultHive , SystemSecurity  , sizeof(SystemSecurity)   },
+    { "SAM"     , L"Registry\\Machine\\SAM"        , &SamHive     , SystemSecurity  , sizeof(SystemSecurity)   },
+    { "SECURITY", L"Registry\\Machine\\SECURITY"   , &SecurityHive, NULL            , 0                        },
+    { "BCD"     , L"Registry\\Machine\\BCD00000000", &BcdHive     , BcdSecurity     , sizeof(BcdSecurity)      },
+};
+C_ASSERT(_countof(RegistryHives) == MAX_NUMBER_OF_REGISTRY_HIVES);
+
+
 static PMEMKEY
 CreateInMemoryStructure(
     IN PCMHIVE RegistryHive,
@@ -346,6 +366,7 @@ CreateInMemoryStructure(
     return Key;
 }
 
+LIST_ENTRY CmiHiveListHead;
 LIST_ENTRY CmiReparsePointsHead;
 
 static LONG
@@ -671,9 +692,9 @@ VOID
 RepGetValueData(
     IN PHHIVE Hive,
     IN PCM_KEY_VALUE ValueCell,
-    OUT ULONG* Type OPTIONAL,
+    OUT PULONG Type OPTIONAL,
     OUT PUCHAR Data OPTIONAL,
-    IN OUT ULONG* DataSize OPTIONAL)
+    IN OUT PULONG DataSize OPTIONAL)
 {
     ULONG DataLength;
     PVOID DataCell;
@@ -759,16 +780,16 @@ static BOOL
 ConnectRegistry(
     IN HKEY RootKey,
     IN PCMHIVE HiveToConnect,
-    IN PUCHAR Descriptor,
-    IN ULONG DescriptorLength,
-    IN LPCWSTR Path)
+    IN PUCHAR SecurityDescriptor,
+    IN ULONG SecurityDescriptorLength,
+    IN PCWSTR Path)
 {
     NTSTATUS Status;
     PREPARSE_POINT ReparsePoint;
     PMEMKEY NewKey;
     LONG rc;
 
-    ReparsePoint = (PREPARSE_POINT)malloc(sizeof(REPARSE_POINT));
+    ReparsePoint = (PREPARSE_POINT)malloc(sizeof(*ReparsePoint));
     if (!ReparsePoint)
         return FALSE;
 
@@ -794,7 +815,7 @@ ConnectRegistry(
      */
     Status = CmiCreateSecurityKey(&HiveToConnect->Hive,
                                   HiveToConnect->Hive.BaseBlock->RootCell,
-                                  Descriptor, DescriptorLength);
+                                  SecurityDescriptor, SecurityDescriptorLength);
     if (!NT_SUCCESS(Status))
         DPRINT1("Failed to add security for root key '%S'\n", Path);
 
@@ -821,18 +842,64 @@ ConnectRegistry(
     ReparsePoint->DestinationHive = NewKey->RegistryHive;
     ReparsePoint->DestinationKeyCellOffset = NewKey->KeyCellOffset;
     InsertTailList(&CmiReparsePointsHead, &ReparsePoint->ListEntry);
+
     return TRUE;
 }
 
-LIST_ENTRY CmiHiveListHead;
+static BOOL
+CreateSymLink(
+    IN PCWSTR LinkKeyPath OPTIONAL,
+    IN OUT PHKEY LinkKeyHandle OPTIONAL,
+    // IN PCWSTR TargetKeyPath OPTIONAL,
+    IN HKEY TargetKeyHandle)
+{
+    PMEMKEY LinkKey, TargetKey;
+    PREPARSE_POINT ReparsePoint;
+
+    ReparsePoint = (PREPARSE_POINT)malloc(sizeof(*ReparsePoint));
+    if (!ReparsePoint)
+        return FALSE;
+
+    if (LinkKeyPath && !(LinkKeyHandle && *LinkKeyHandle))
+    {
+        /* Create the link key */
+        RegCreateKeyExW(NULL,
+                        LinkKeyPath,
+                        0,
+                        NULL,
+                        REG_OPTION_VOLATILE,
+                        0,
+                        NULL,
+                        (HKEY*)&LinkKey,
+                        NULL);
+    }
+    else if (LinkKeyHandle)
+    {
+        /* Use the user-provided link key handle */
+        LinkKey = HKEY_TO_MEMKEY(*LinkKeyHandle);
+    }
+
+    if (LinkKeyHandle)
+        *LinkKeyHandle = MEMKEY_TO_HKEY(LinkKey);
+
+    TargetKey = HKEY_TO_MEMKEY(TargetKeyHandle);
+
+    ReparsePoint->SourceHive = LinkKey->RegistryHive;
+    ReparsePoint->SourceKeyCellOffset = LinkKey->KeyCellOffset;
+    ReparsePoint->DestinationHive = TargetKey->RegistryHive;
+    ReparsePoint->DestinationKeyCellOffset = TargetKey->KeyCellOffset;
+    InsertTailList(&CmiReparsePointsHead, &ReparsePoint->ListEntry);
+
+    return TRUE;
+}
 
 VOID
-RegInitializeRegistry(VOID)
+RegInitializeRegistry(
+    IN PCSTR HiveList)
 {
-    UNICODE_STRING RootKeyName = RTL_CONSTANT_STRING(L"\\");
     NTSTATUS Status;
-    PMEMKEY ControlSetKey, CurrentControlSetKey;
-    PREPARSE_POINT ReparsePoint;
+    UINT i;
+    HKEY ControlSetKey;
 
     InitializeListHead(&CmiHiveListHead);
     InitializeListHead(&CmiReparsePointsHead);
@@ -847,70 +914,56 @@ RegInitializeRegistry(VOID)
     RootKey = CreateInMemoryStructure(&RootHive,
                                       RootHive.Hive.BaseBlock->RootCell);
 
-    /* Create DEFAULT key */
-    ConnectRegistry(NULL,
-                    &DefaultHive,
-                    SystemSecurity, sizeof(SystemSecurity),
-                    L"Registry\\User\\.DEFAULT");
-
-    /* Create SAM key */
-    ConnectRegistry(NULL,
-                    &SamHive,
-                    SystemSecurity, sizeof(SystemSecurity),
-                    L"Registry\\Machine\\SAM");
-
-    /* Create SECURITY key */
-    ConnectRegistry(NULL,
-                    &SecurityHive,
-                    NULL, 0,
-                    L"Registry\\Machine\\SECURITY");
-
-    /* Create SOFTWARE key */
-    ConnectRegistry(NULL,
-                    &SoftwareHive,
-                    SoftwareSecurity, sizeof(SoftwareSecurity),
-                    L"Registry\\Machine\\SOFTWARE");
-
-    /* Create BCD key */
-    ConnectRegistry(NULL,
-                    &BcdHive,
-                    BcdSecurity, sizeof(BcdSecurity),
-                    L"Registry\\Machine\\BCD00000000");
-
-    /* Create SYSTEM key */
-    ConnectRegistry(NULL,
-                    &SystemHive,
-                    SystemSecurity, sizeof(SystemSecurity),
-                    L"Registry\\Machine\\SYSTEM");
-
-    /* Create 'ControlSet001' key */
+    for (i = 0; i < _countof(RegistryHives); ++i)
+    {
+        /* Skip this registry hive if it's not in the list */
+        if (!strstr(HiveList, RegistryHives[i].HiveName))
+            continue;
+
+        /* Create the registry key */
+        ConnectRegistry(NULL,
+                        RegistryHives[i].CmHive,
+                        RegistryHives[i].SecurityDescriptor,
+                        RegistryHives[i].SecurityDescriptorLength,
+                        RegistryHives[i].HiveRegistryPath);
+
+        /* If we happen to deal with the special setup registry hive, stop there */
+        // if (strcmp(RegistryHives[i].HiveName, "SETUPREG") == 0)
+        if (i == 0)
+            break;
+    }
+
+    /* Create the 'ControlSet001' key */
     RegCreateKeyW(NULL,
                   L"Registry\\Machine\\SYSTEM\\ControlSet001",
-                  (HKEY*)&ControlSetKey);
-
-    /* Create 'CurrentControlSet' key */
-    RegCreateKeyExW(NULL,
-                    L"Registry\\Machine\\SYSTEM\\CurrentControlSet",
-                    0,
-                    NULL,
-                    REG_OPTION_VOLATILE,
-                    0,
-                    NULL,
-                    (HKEY*)&CurrentControlSetKey,
-                    NULL);
-
-    /* Connect 'CurrentControlSet' to 'ControlSet001' */
-    ReparsePoint = (PREPARSE_POINT)malloc(sizeof(REPARSE_POINT));
-    ReparsePoint->SourceHive = CurrentControlSetKey->RegistryHive;
-    ReparsePoint->SourceKeyCellOffset = CurrentControlSetKey->KeyCellOffset;
-    ReparsePoint->DestinationHive = ControlSetKey->RegistryHive;
-    ReparsePoint->DestinationKeyCellOffset = ControlSetKey->KeyCellOffset;
-    InsertTailList(&CmiReparsePointsHead, &ReparsePoint->ListEntry);
+                  &ControlSetKey);
+
+    /* Create the 'CurrentControlSet' key as a symlink to 'ControlSet001' */
+    CreateSymLink(L"Registry\\Machine\\SYSTEM\\CurrentControlSet",
+                  NULL, ControlSetKey);
+
+#if 0
+    /* Link SECURITY to SAM */
+    CmpLinkKeyToHive(L"\\Registry\\Machine\\Security\\SAM", L"\\Registry\\Machine\\SAM\\SAM");
+    /* Link S-1-5-18 to .Default */
+    CmpLinkKeyToHive(L"\\Registry\\User\\S-1-5-18", L"\\Registry\\User\\.Default");
+#endif
 }
 
 VOID
 RegShutdownRegistry(VOID)
 {
+    PLIST_ENTRY Entry;
+    PREPARSE_POINT ReparsePoint;
+
+    /* Clean up the reparse points list */
+    while (!IsListEmpty(&CmiReparsePointsHead))
+    {
+        Entry = RemoveHeadList(&CmiReparsePointsHead);
+        ReparsePoint = CONTAINING_RECORD(Entry, REPARSE_POINT, ListEntry);
+        free(ReparsePoint);
+    }
+
     /* FIXME: clean up the complete hive */
 
     free(RootKey);
index 0215a31..7712de9 100644 (file)
@@ -26,12 +26,17 @@ typedef struct _MEMKEY
 #define HKEY_TO_MEMKEY(hKey) ((PMEMKEY)(hKey))
 #define MEMKEY_TO_HKEY(memKey) ((HKEY)(memKey))
 
-extern CMHIVE DefaultHive;  /* \Registry\User\.DEFAULT */
-extern CMHIVE SamHive;      /* \Registry\Machine\SAM */
-extern CMHIVE SecurityHive; /* \Registry\Machine\SECURITY */
-extern CMHIVE SoftwareHive; /* \Registry\Machine\SOFTWARE */
-extern CMHIVE SystemHive;   /* \Registry\Machine\SYSTEM */
-extern CMHIVE BcdHive;      /* \Registry\Machine\BCD00000000 */
+typedef struct _HIVE_LIST_ENTRY
+{
+    PCSTR   HiveName;
+    PCWSTR  HiveRegistryPath;
+    PCMHIVE CmHive;
+    PUCHAR  SecurityDescriptor;
+    ULONG   SecurityDescriptorLength;
+} HIVE_LIST_ENTRY, *PHIVE_LIST_ENTRY;
+
+#define MAX_NUMBER_OF_REGISTRY_HIVES    7
+extern HIVE_LIST_ENTRY RegistryHives[];
 
 #define ERROR_SUCCESS                    0L
 #define ERROR_UNSUCCESSFUL               1L
@@ -57,7 +62,8 @@ extern CMHIVE BcdHive;      /* \Registry\Machine\BCD00000000 */
 #define REG_QWORD_LITTLE_ENDIAN            11
 
 VOID
-RegInitializeRegistry(VOID);
+RegInitializeRegistry(
+    IN PCSTR HiveList);
 
 VOID
 RegShutdownRegistry(VOID);