Author: hbelusca
Date: Fri Jun  2 00:34:10 2017
New Revision: 74741

URL: http://svn.reactos.org/svn/reactos?rev=74741&view=rev
Log:
[MKHIVE][CMAKE]: Make mkhive a bit more flexible, so that it can generate only 
specific hives on-demand (and not all of them always at once). I need this for 
building a single bootcd registry hive.
I commit these changes in my branch because it's too much über-advanced code 
for our trunk, yet... (and it will uncover deep "setup" hacks in NTOS' iomgr & 
pnpmgr as soon as I'll enable 1-st stage setup to have a proper registry 
present as done on windows).
CORE-13347 #comment Committed in r74741 but just in the setup_improvements 
branch for the moment.

Modified:
    branches/setup_improvements/sdk/cmake/CMakeMacros.cmake
    branches/setup_improvements/sdk/tools/mkhive/binhive.c
    branches/setup_improvements/sdk/tools/mkhive/cmi.c
    branches/setup_improvements/sdk/tools/mkhive/mkhive.c
    branches/setup_improvements/sdk/tools/mkhive/mkhive.h
    branches/setup_improvements/sdk/tools/mkhive/reginf.c
    branches/setup_improvements/sdk/tools/mkhive/registry.c
    branches/setup_improvements/sdk/tools/mkhive/registry.h

Modified: branches/setup_improvements/sdk/cmake/CMakeMacros.cmake
URL: 
http://svn.reactos.org/svn/reactos/branches/setup_improvements/sdk/cmake/CMakeMacros.cmake?rev=74741&r1=74740&r2=74741&view=diff
==============================================================================
--- branches/setup_improvements/sdk/cmake/CMakeMacros.cmake     [iso-8859-1] 
(original)
+++ branches/setup_improvements/sdk/cmake/CMakeMacros.cmake     [iso-8859-1] 
Fri Jun  2 00:34:10 2017
@@ -762,6 +762,22 @@
                 NO_CAB
                 FOR bootcd regtest)
 
+    # 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_SOURCE_DIR}/boot/bootdata/hivesys.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}
@@ -769,27 +785,27 @@
         ${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
-        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)
+        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)
@@ -797,7 +813,7 @@
     # BCD Hive
     add_custom_command(
         OUTPUT ${CMAKE_BINARY_DIR}/boot/bootdata/BCD
-        COMMAND native-mkhive ${CMAKE_BINARY_DIR}/boot/bootdata 
${CMAKE_BINARY_DIR}/boot/bootdata/hivebcd_utf16.inf
+        COMMAND native-mkhive -h:BCD -d:${CMAKE_BINARY_DIR}/boot/bootdata 
${CMAKE_BINARY_DIR}/boot/bootdata/hivebcd_utf16.inf
         DEPENDS native-mkhive ${CMAKE_SOURCE_DIR}/boot/bootdata/hivebcd.inf)
 
     add_custom_target(bcd_hive

Modified: branches/setup_improvements/sdk/tools/mkhive/binhive.c
URL: 
http://svn.reactos.org/svn/reactos/branches/setup_improvements/sdk/tools/mkhive/binhive.c?rev=74741&r1=74740&r2=74741&view=diff
==============================================================================
--- branches/setup_improvements/sdk/tools/mkhive/binhive.c      [iso-8859-1] 
(original)
+++ branches/setup_improvements/sdk/tools/mkhive/binhive.c      [iso-8859-1] 
Fri Jun  2 00:34:10 2017
@@ -33,26 +33,26 @@
 BOOL
 ExportBinaryHive(
     IN PCSTR FileName,
-    IN PCMHIVE Hive)
+    IN PCMHIVE CmHive)
 {
     FILE *File;
     BOOL ret;
 
-    printf ("  Creating binary hive: %s\n", FileName);
+    printf("  Creating binary hive: %s\n", FileName);
 
     /* Create new hive file */
-    File = fopen (FileName, "w+b");
+    File = fopen(FileName, "wb");
     if (File == NULL)
     {
         printf("    Error creating/opening file\n");
         return FALSE;
     }
 
-    fseek (File, 0, SEEK_SET);
+    fseek(File, 0, SEEK_SET);
 
-    Hive->FileHandles[HFILE_TYPE_PRIMARY] = (HANDLE)File;
-    ret = HvWriteHive(&Hive->Hive);
-    fclose (File);
+    CmHive->FileHandles[HFILE_TYPE_PRIMARY] = (HANDLE)File;
+    ret = HvWriteHive(&CmHive->Hive);
+    fclose(File);
     return ret;
 }
 

Modified: branches/setup_improvements/sdk/tools/mkhive/cmi.c
URL: 
http://svn.reactos.org/svn/reactos/branches/setup_improvements/sdk/tools/mkhive/cmi.c?rev=74741&r1=74740&r2=74741&view=diff
==============================================================================
--- branches/setup_improvements/sdk/tools/mkhive/cmi.c  [iso-8859-1] (original)
+++ branches/setup_improvements/sdk/tools/mkhive/cmi.c  [iso-8859-1] Fri Jun  2 
00:34:10 2017
@@ -55,8 +55,12 @@
     OUT PVOID Buffer,
     IN SIZE_T BufferLength)
 {
-    DPRINT1("CmpFileRead() unimplemented\n");
-    return FALSE;
+    PCMHIVE CmHive = (PCMHIVE)RegistryHive;
+    FILE *File = CmHive->FileHandles[HFILE_TYPE_PRIMARY];
+    if (fseek(File, *FileOffset, SEEK_SET) != 0)
+        return FALSE;
+
+    return (fread(Buffer, 1, BufferLength, File) == BufferLength);
 }
 
 static BOOLEAN

Modified: branches/setup_improvements/sdk/tools/mkhive/mkhive.c
URL: 
http://svn.reactos.org/svn/reactos/branches/setup_improvements/sdk/tools/mkhive/mkhive.c?rev=74741&r1=74740&r2=74741&view=diff
==============================================================================
--- branches/setup_improvements/sdk/tools/mkhive/mkhive.c       [iso-8859-1] 
(original)
+++ branches/setup_improvements/sdk/tools/mkhive/mkhive.c       [iso-8859-1] 
Fri Jun  2 00:34:10 2017
@@ -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>
@@ -48,11 +49,13 @@
 #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,80 +86,106 @@
     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");
+    printf("Binary hive maker\n");
 
-    RegInitializeRegistry ();
-
-    for (i = 2; i < argc; i++)
+    /* Read the options */
+    for (i = 1; i < argc && *argv[i] == '-'; i++)
     {
-        convert_path (FileName, argv[i]);
-        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
+        {
+            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;
+    }
+    if (!*DestPath)
+    {
+        fprintf(stderr, "The mandatory output directory is missing.\n");
+        return -1;
+    }
+    if (i >= argc)
+    {
+        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, "sam");
-    if (!ExportBinaryHive (FileName, &SamHive))
+    /* Initialize the registry */
+    RegInitializeRegistry(HiveList);
+
+    /* Default to failure */
+    ret = -1;
+
+    /* 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, "security");
-    if (!ExportBinaryHive (FileName, &SecurityHive))
+    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;
     }
 
-    convert_path (FileName, argv[1]);
-    strcat (FileName, DIR_SEPARATOR_STRING);
-    strcat (FileName, "software");
-    if (!ExportBinaryHive (FileName, &SoftwareHive))
-    {
-        return 1;
-    }
+    /* Success */
+    ret = 0;
 
-    convert_path (FileName, argv[1]);
-    strcat (FileName, DIR_SEPARATOR_STRING);
-    strcat (FileName, "system");
-    if (!ExportBinaryHive (FileName, &SystemHive))
-    {
-        return 1;
-    }
+Quit:
+    /* Shut down the registry */
+    RegShutdownRegistry();
 
-    convert_path (FileName, argv[1]);
-    strcat (FileName, DIR_SEPARATOR_STRING);
-    strcat (FileName, "BCD");
-    if (!ExportBinaryHive (FileName, &BcdHive))
-    {
-        return 1;
-    }
+    if (ret == 0)
+        printf("  Done.\n");
 
-    RegShutdownRegistry ();
-
-    printf ("  Done.\n");
-
-    return 0;
+    return ret;
 }
 
 /* EOF */

Modified: branches/setup_improvements/sdk/tools/mkhive/mkhive.h
URL: 
http://svn.reactos.org/svn/reactos/branches/setup_improvements/sdk/tools/mkhive/mkhive.h?rev=74741&r1=74740&r2=74741&view=diff
==============================================================================
--- branches/setup_improvements/sdk/tools/mkhive/mkhive.h       [iso-8859-1] 
(original)
+++ branches/setup_improvements/sdk/tools/mkhive/mkhive.h       [iso-8859-1] 
Fri Jun  2 00:34:10 2017
@@ -21,7 +21,7 @@
  * PROJECT:         ReactOS hive maker
  * FILE:            tools/mkhive/mkhive.h
  * PURPOSE:         Hive maker
- * PROGRAMMER:      Eric Kohl
+ * PROGRAMMERS:     Eric Kohl
  *                  Hervé Poussineau
  */
 

Modified: branches/setup_improvements/sdk/tools/mkhive/reginf.c
URL: 
http://svn.reactos.org/svn/reactos/branches/setup_improvements/sdk/tools/mkhive/reginf.c?rev=74741&r1=74740&r2=74741&view=diff
==============================================================================
--- branches/setup_improvements/sdk/tools/mkhive/reginf.c       [iso-8859-1] 
(original)
+++ branches/setup_improvements/sdk/tools/mkhive/reginf.c       [iso-8859-1] 
Fri Jun  2 00:34:10 2017
@@ -21,7 +21,7 @@
  * PROJECT:         ReactOS hive maker
  * FILE:            tools/mkhive/reginf.c
  * PURPOSE:         Inf file import code
- * PROGRAMMER:      Eric Kohl
+ * PROGRAMMERS:     Eric Kohl
  *                  Hervé Poussineau
  */
 
@@ -68,40 +68,40 @@
 /* FUNCTIONS ****************************************************************/
 
 static BOOL
-GetRootKey (PWCHAR Name)
+get_root_key(PWCHAR Name)
 {
-    if (!strcmpiW (Name, HKCR))
-    {
-        strcpyW (Name, HKCRPath);
-        return TRUE;
-    }
-
-    if (!strcmpiW (Name, HKCU))
-    {
-        strcpyW (Name, HKCUPath);
-        return TRUE;
-    }
-
-    if (!strcmpiW (Name, HKLM))
-    {
-        strcpyW (Name, HKLMPath);
-        return TRUE;
-    }
-
-    if (!strcmpiW (Name, HKU))
-    {
-        strcpyW (Name, HKUPath);
-        return TRUE;
-    }
-
-    if (!strcmpiW (Name, BCD))
-    {
-        strcpyW (Name, BCDPath);
+    if (!strcmpiW(Name, HKCR))
+    {
+        strcpyW(Name, HKCRPath);
+        return TRUE;
+    }
+
+    if (!strcmpiW(Name, HKCU))
+    {
+        strcpyW(Name, HKCUPath);
+        return TRUE;
+    }
+
+    if (!strcmpiW(Name, HKLM))
+    {
+        strcpyW(Name, HKLMPath);
+        return TRUE;
+    }
+
+    if (!strcmpiW(Name, HKU))
+    {
+        strcpyW(Name, HKUPath);
+        return TRUE;
+    }
+
+    if (!strcmpiW(Name, BCD))
+    {
+        strcpyW(Name, BCDPath);
         return TRUE;
     }
 
 #if 0
-    if (!strcmpiW (Name, HKR))
+    if (!strcmpiW(Name, HKR))
         return FALSE;
 #endif
 
@@ -110,47 +110,44 @@
 
 
 /***********************************************************************
- * AppendMultiSzValue
+ * append_multi_sz_value
  *
  * Append a multisz string to a multisz registry value.
  */
+// NOTE: Synced with setupapi/install.c ; see also usetup/registry.c
 static VOID
-AppendMultiSzValue (
+append_multi_sz_value(
     IN HKEY KeyHandle,
     IN PWCHAR ValueName,
     IN PWCHAR Strings,
-    IN ULONG StringSize)
+    IN ULONG StringSize) // In characters
 {
-    ULONG Size;
+    ULONG Size, Total;   // In bytes
     ULONG Type;
-    ULONG Total;
     PWCHAR Buffer;
     PWCHAR p;
     size_t len;
     LONG Error;
 
-    Error = RegQueryValueExW (
-        KeyHandle,
-        ValueName,
-        NULL,
-        &Type,
-        NULL,
-        &Size);
-    if ((Error != ERROR_SUCCESS) ||
-        (Type != REG_MULTI_SZ))
+    Error = RegQueryValueExW(KeyHandle,
+                             ValueName,
+                             NULL,
+                             &Type,
+                             NULL,
+                             &Size);
+    if ((Error != ERROR_SUCCESS) || (Type != REG_MULTI_SZ))
         return;
 
-    Buffer = malloc ((Size + StringSize) * sizeof(WCHAR));
+    Buffer = malloc(Size + StringSize * sizeof(WCHAR));
     if (Buffer == NULL)
         return;
 
-    Error = RegQueryValueExW (
-        KeyHandle,
-        ValueName,
-        NULL,
-        NULL,
-        (PUCHAR)Buffer,
-        &Size);
+    Error = RegQueryValueExW(KeyHandle,
+                             ValueName,
+                             NULL,
+                             NULL,
+                             (PUCHAR)Buffer,
+                             &Size);
     if (Error != ERROR_SUCCESS)
         goto done;
 
@@ -166,27 +163,26 @@
 
         if (*p == 0)  /* not found, need to append it */
         {
-            memcpy (p, Strings, len);
+            memcpy(p, Strings, len * sizeof(WCHAR));
             p[len] = 0;
-            Total += len;
+            Total += len * sizeof(WCHAR);
         }
         Strings += len;
     }
 
     if (Total != Size)
     {
-        DPRINT ("setting value %S to %S\n", ValueName, Buffer);
-        RegSetValueExW (
-            KeyHandle,
-            ValueName,
-            0,
-            REG_MULTI_SZ,
-            (PUCHAR)Buffer,
-            Total * sizeof(WCHAR));
+        DPRINT("setting value %S to %S\n", ValueName, Buffer);
+        RegSetValueExW(KeyHandle,
+                       ValueName,
+                       0,
+                       REG_MULTI_SZ,
+                       (PUCHAR)Buffer,
+                       Total + sizeof(WCHAR));
     }
 
 done:
-    free (Buffer);
+    free(Buffer);
 }
 
 
@@ -202,7 +198,7 @@
     IN PINFCONTEXT Context,
     IN ULONG Flags)
 {
-    WCHAR EmptyStr = (CHAR)0;
+    WCHAR EmptyStr = 0;
     ULONG Type;
     ULONG Size;
     LONG Error;
@@ -211,11 +207,11 @@
     {
         if (ValueName)
         {
-            RegDeleteValueW (KeyHandle, ValueName);
+            RegDeleteValueW(KeyHandle, ValueName);
         }
         else
         {
-            RegDeleteKeyW (KeyHandle, NULL);
+            RegDeleteKeyW(KeyHandle, NULL);
         }
 
         return TRUE;
@@ -226,19 +222,16 @@
 
     if (Flags & (FLG_ADDREG_NOCLOBBER | FLG_ADDREG_OVERWRITEONLY))
     {
-        Error = RegQueryValueExW (
-            KeyHandle,
-            ValueName,
-            NULL,
-            NULL,
-            NULL,
-            NULL);
-        if ((Error == ERROR_SUCCESS) &&
-            (Flags & FLG_ADDREG_NOCLOBBER))
+        Error = RegQueryValueExW(KeyHandle,
+                                 ValueName,
+                                 NULL,
+                                 NULL,
+                                 NULL,
+                                 NULL);
+        if ((Error == ERROR_SUCCESS) && (Flags & FLG_ADDREG_NOCLOBBER))
             return TRUE;
 
-        if ((Error != ERROR_SUCCESS) &&
-            (Flags & FLG_ADDREG_OVERWRITEONLY))
+        if ((Error != ERROR_SUCCESS) && (Flags & FLG_ADDREG_OVERWRITEONLY))
             return TRUE;
     }
 
@@ -274,22 +267,22 @@
     }
 
     if (!(Flags & FLG_ADDREG_BINVALUETYPE) ||
-        (Type == REG_DWORD && InfHostGetFieldCount (Context) == 5))
+        (Type == REG_DWORD && InfHostGetFieldCount(Context) == 5))
     {
         PWCHAR Str = NULL;
 
         if (Type == REG_MULTI_SZ)
         {
-            if (InfHostGetMultiSzField (Context, 5, NULL, 0, &Size) != 0)
+            if (InfHostGetMultiSzField(Context, 5, NULL, 0, &Size) != 0)
                 Size = 0;
 
             if (Size)
             {
-                Str = malloc (Size * sizeof(WCHAR));
+                Str = malloc(Size * sizeof(WCHAR));
                 if (Str == NULL)
                     return FALSE;
 
-                InfHostGetMultiSzField (Context, 5, Str, Size, NULL);
+                InfHostGetMultiSzField(Context, 5, Str, Size, NULL);
             }
 
             if (Flags & FLG_ADDREG_APPEND)
@@ -297,45 +290,43 @@
                 if (Str == NULL)
                     return TRUE;
 
-                AppendMultiSzValue (
-                    KeyHandle,
-                    ValueName,
-                    Str,
-                    Size);
-
-                free (Str);
+                append_multi_sz_value(KeyHandle,
+                                      ValueName,
+                                      Str,
+                                      Size);
+
+                free(Str);
                 return TRUE;
             }
             /* else fall through to normal string handling */
         }
         else
         {
-            if (InfHostGetStringField (Context, 5, NULL, 0, &Size) != 0)
+            if (InfHostGetStringField(Context, 5, NULL, 0, &Size) != 0)
                 Size = 0;
 
             if (Size)
             {
-                Str = malloc (Size * sizeof(WCHAR));
+                Str = malloc(Size * sizeof(WCHAR));
                 if (Str == NULL)
                     return FALSE;
 
-                InfHostGetStringField (Context, 5, Str, Size, NULL);
+                InfHostGetStringField(Context, 5, Str, Size, NULL);
             }
         }
 
         if (Type == REG_DWORD)
         {
-            ULONG dw = Str ? strtoulW (Str, NULL, 0) : 0;
+            ULONG dw = Str ? strtoulW(Str, NULL, 0) : 0;
 
             DPRINT("setting dword %S to %x\n", ValueName, dw);
 
-            RegSetValueExW (
-                KeyHandle,
-                ValueName,
-                0,
-                Type,
-                (const PUCHAR)&dw,
-                sizeof(ULONG));
+            RegSetValueExW(KeyHandle,
+                           ValueName,
+                           0,
+                           Type,
+                           (const PUCHAR)&dw,
+                           sizeof(ULONG));
         }
         else
         {
@@ -343,53 +334,50 @@
 
             if (Str)
             {
-                RegSetValueExW (
-                    KeyHandle,
-                    ValueName,
-                    0,
-                    Type,
-                    (PVOID)Str,
-                    Size * sizeof(WCHAR));
+                RegSetValueExW(KeyHandle,
+                               ValueName,
+                               0,
+                               Type,
+                               (PVOID)Str,
+                               Size * sizeof(WCHAR));
             }
             else
             {
-                RegSetValueExW (
-                    KeyHandle,
-                    ValueName,
-                    0,
-                    Type,
-                    (PVOID)&EmptyStr,
-                    sizeof(WCHAR));
-            }
-        }
-        free (Str);
+                RegSetValueExW(KeyHandle,
+                               ValueName,
+                               0,
+                               Type,
+                               (PVOID)&EmptyStr,
+                               sizeof(WCHAR));
+            }
+        }
+        free(Str);
     }
     else  /* get the binary data */
     {
         PUCHAR Data = NULL;
 
-        if (InfHostGetBinaryField (Context, 5, NULL, 0, &Size) != 0)
+        if (InfHostGetBinaryField(Context, 5, NULL, 0, &Size) != 0)
             Size = 0;
 
         if (Size)
         {
-            Data = malloc (Size);
+            Data = malloc(Size);
             if (Data == NULL)
                 return FALSE;
 
             DPRINT("setting binary data %S len %d\n", ValueName, Size);
-            InfHostGetBinaryField (Context, 5, Data, Size, NULL);
-        }
-
-        RegSetValueExW (
-            KeyHandle,
-            ValueName,
-            0,
-            Type,
-            (PVOID)Data,
-            Size);
-
-        free (Data);
+            InfHostGetBinaryField(Context, 5, Data, Size, NULL);
+        }
+
+        RegSetValueExW(KeyHandle,
+                       ValueName,
+                       0,
+                       Type,
+                       (PVOID)Data,
+                       Size);
+
+        free(Data);
     }
 
     return TRUE;
@@ -401,7 +389,7 @@
  * Called once for each AddReg and DelReg entry in a given section.
  */
 static BOOL
-registry_callback (HINF hInf, PWCHAR Section, BOOL Delete)
+registry_callback(HINF hInf, PWCHAR Section, BOOL Delete)
 {
     WCHAR Buffer[MAX_INF_STRING_LENGTH];
     PWCHAR ValuePtr;
@@ -413,21 +401,21 @@
     BOOL Ok;
 
 
-    Ok = InfHostFindFirstLine (hInf, Section, NULL, &Context) == 0;
+    Ok = InfHostFindFirstLine(hInf, Section, NULL, &Context) == 0;
     if (!Ok)
         return TRUE; /* Don't fail if the section isn't present */
 
-    for (;Ok; Ok = (InfHostFindNextLine (Context, Context) == 0))
+    for (;Ok; Ok = (InfHostFindNextLine(Context, Context) == 0))
     {
         /* get root */
-        if (InfHostGetStringField (Context, 1, Buffer, MAX_INF_STRING_LENGTH, 
NULL) != 0)
+        if (InfHostGetStringField(Context, 1, Buffer, 
sizeof(Buffer)/sizeof(WCHAR), NULL) != 0)
             continue;
-        if (!GetRootKey (Buffer))
+        if (!get_root_key(Buffer))
             continue;
 
         /* get key */
-        Length = strlenW (Buffer);
-        if (InfHostGetStringField (Context, 2, Buffer + Length, 
MAX_INF_STRING_LENGTH - (ULONG)Length, NULL) != 0)
+        Length = strlenW(Buffer);
+        if (InfHostGetStringField(Context, 2, Buffer + Length, 
sizeof(Buffer)/sizeof(WCHAR) - (ULONG)Length, NULL) != 0)
             *Buffer = 0;
 
         DPRINT("KeyName: <%S>\n", Buffer);
@@ -439,7 +427,7 @@
         else
         {
             /* get flags */
-            if (InfHostGetIntField (Context, 4, (INT *)&Flags) != 0)
+            if (InfHostGetIntField(Context, 4, (INT *)&Flags) != 0)
                 Flags = 0;
         }
 
@@ -447,7 +435,7 @@
 
         if (Delete || (Flags & FLG_ADDREG_OVERWRITEONLY))
         {
-            if (RegOpenKeyW (NULL, Buffer, &KeyHandle) != ERROR_SUCCESS)
+            if (RegOpenKeyW(NULL, Buffer, &KeyHandle) != ERROR_SUCCESS)
             {
                 DPRINT("RegOpenKey(%S) failed\n", Buffer);
                 continue;  /* ignore if it doesn't exist */
@@ -455,7 +443,7 @@
         }
         else
         {
-            if (RegCreateKeyW (NULL, Buffer, &KeyHandle) != ERROR_SUCCESS)
+            if (RegCreateKeyW(NULL, Buffer, &KeyHandle) != ERROR_SUCCESS)
             {
                 DPRINT("RegCreateKey(%S) failed\n", Buffer);
                 continue;
@@ -463,7 +451,7 @@
         }
 
         /* get value name */
-        if (InfHostGetStringField (Context, 3, Buffer, MAX_INF_STRING_LENGTH, 
NULL) == 0)
+        if (InfHostGetStringField(Context, 3, Buffer, 
sizeof(Buffer)/sizeof(WCHAR), NULL) == 0)
         {
             ValuePtr = Buffer;
         }
@@ -473,7 +461,7 @@
         }
 
         /* and now do it */
-        if (!do_reg_operation (KeyHandle, ValuePtr, Context, Flags))
+        if (!do_reg_operation(KeyHandle, ValuePtr, Context, Flags))
         {
             return FALSE;
         }
@@ -494,21 +482,25 @@
     /* Load inf file from install media. */
     if (InfHostOpenFile(&hInf, FileName, 0, &ErrorLine) != 0)
     {
-        DPRINT1 ("InfHostOpenFile(%s) failed\n", FileName);
+        DPRINT1("InfHostOpenFile(%s) failed\n", FileName);
         return FALSE;
     }
 
-    if (!registry_callback (hInf, (PWCHAR)DelReg, TRUE))
-    {
-        DPRINT1 ("registry_callback() for DelReg failed\n");
-    }
-
-    if (!registry_callback (hInf, (PWCHAR)AddReg, FALSE))
-    {
-        DPRINT1 ("registry_callback() for AddReg failed\n");
-    }
-
-    InfHostCloseFile (hInf);
+    if (!registry_callback(hInf, (PWCHAR)DelReg, TRUE))
+    {
+        DPRINT1("registry_callback() for DelReg failed\n");
+        InfHostCloseFile(hInf);
+        return FALSE;
+    }
+
+    if (!registry_callback(hInf, (PWCHAR)AddReg, FALSE))
+    {
+        DPRINT1("registry_callback() for AddReg failed\n");
+        InfHostCloseFile(hInf);
+        return FALSE;
+    }
+
+    InfHostCloseFile(hInf);
 
     return TRUE;
 }

Modified: branches/setup_improvements/sdk/tools/mkhive/registry.c
URL: 
http://svn.reactos.org/svn/reactos/branches/setup_improvements/sdk/tools/mkhive/registry.c?rev=74741&r1=74740&r2=74741&view=diff
==============================================================================
--- branches/setup_improvements/sdk/tools/mkhive/registry.c     [iso-8859-1] 
(original)
+++ branches/setup_improvements/sdk/tools/mkhive/registry.c     [iso-8859-1] 
Fri Jun  2 00:34:10 2017
@@ -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
  */
 
 /*
@@ -38,12 +39,13 @@
 
 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 @@
 // 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 @@
     0x01, 0x02, 0x00, 0x00
 };
 
-UCHAR SoftwareSecurity[] =
+static UCHAR SoftwareSecurity[] =
 {
     // SECURITY_DESCRIPTOR_RELATIVE
     0x01,                   // Revision
@@ -234,7 +236,7 @@
 };
 
 // Same security for SYSTEM, SAM and .DEFAULT
-UCHAR SystemSecurity[] =
+static UCHAR SystemSecurity[] =
 {
     // SECURITY_DESCRIPTOR_RELATIVE
     0x01,                   // Revision
@@ -330,6 +332,24 @@
     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 @@
     return Key;
 }
 
+LIST_ENTRY CmiHiveListHead;
 LIST_ENTRY CmiReparsePointsHead;
 
 static LONG
@@ -671,9 +692,9 @@
 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 @@
 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 @@
      */
     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 @@
     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)
-{
-    UNICODE_STRING RootKeyName = RTL_CONSTANT_STRING(L"\\");
+RegInitializeRegistry(
+    IN PCSTR HiveList)
+{
     NTSTATUS Status;
-    PMEMKEY ControlSetKey, CurrentControlSetKey;
-    PREPARSE_POINT ReparsePoint;
+    UINT i;
+    HKEY ControlSetKey;
 
     InitializeListHead(&CmiHiveListHead);
     InitializeListHead(&CmiReparsePointsHead);
@@ -847,70 +914,56 @@
     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);

Modified: branches/setup_improvements/sdk/tools/mkhive/registry.h
URL: 
http://svn.reactos.org/svn/reactos/branches/setup_improvements/sdk/tools/mkhive/registry.h?rev=74741&r1=74740&r2=74741&view=diff
==============================================================================
--- branches/setup_improvements/sdk/tools/mkhive/registry.h     [iso-8859-1] 
(original)
+++ branches/setup_improvements/sdk/tools/mkhive/registry.h     [iso-8859-1] 
Fri Jun  2 00:34:10 2017
@@ -26,12 +26,17 @@
 #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 @@
 #define REG_QWORD_LITTLE_ENDIAN            11
 
 VOID
-RegInitializeRegistry(VOID);
+RegInitializeRegistry(
+    IN PCSTR HiveList);
 
 VOID
 RegShutdownRegistry(VOID);


Reply via email to