xref: /reactos/sdk/tools/mkhive/mkhive.c (revision 98e8827a)
1 /*
2  *  ReactOS kernel
3  *  Copyright (C) 2003, 2006 ReactOS Team
4  *
5  *  This program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License along
16  *  with this program; if not, write to the Free Software Foundation, Inc.,
17  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 /*
20  * COPYRIGHT:       See COPYING in the top level directory
21  * PROJECT:         ReactOS hive maker
22  * FILE:            tools/mkhive/mkhive.c
23  * PURPOSE:         Hive maker
24  * PROGRAMMERS:     Eric Kohl
25  *                  Hervé Poussineau
26  *                  Hermès Bélusca-Maïto
27  */
28 
29 /* INCLUDES *****************************************************************/
30 
31 #include <limits.h>
32 #include <string.h>
33 #include <stdio.h>
34 
35 #include "mkhive.h"
36 
37 #ifdef _MSC_VER
38 #include <stdlib.h>
39 #define PATH_MAX _MAX_PATH
40 #endif // _MSC_VER
41 
42 #ifndef _WIN32
43 #ifndef PATH_MAX
44 #define PATH_MAX 260
45 #endif
46 #define DIR_SEPARATOR_CHAR '/'
47 #define DIR_SEPARATOR_STRING "/"
48 #else
49 #define DIR_SEPARATOR_CHAR '\\'
50 #define DIR_SEPARATOR_STRING "\\"
51 #endif
52 
53 /* FUNCTIONS ****************************************************************/
54 
55 void usage(void)
56 {
57     printf("Usage: mkhive [-?] -h:hive1[,hiveN...] [-u] -d:<dstdir> <inffiles>\n\n"
58            "  -h:hiveN  - Comma-separated list of hives to create. Possible values are:\n"
59            "              SETUPREG, SYSTEM, SOFTWARE, DEFAULT, SAM, SECURITY, BCD.\n"
60            "  -u        - Generate file names in uppercase (default: lowercase) (TEMPORARY FLAG!).\n"
61            "  -d:dstdir - The binary hive files are created in this directory.\n"
62            "  inffiles  - List of INF files with full path.\n"
63            "  -?        - Displays this help screen.\n");
64 }
65 
66 void convert_path(char *dst, char *src)
67 {
68     int i;
69 
70     i = 0;
71     while (src[i] != 0)
72     {
73 #ifdef _WIN32
74         if (src[i] == '/')
75         {
76             dst[i] = '\\';
77         }
78 #else
79         if (src[i] == '\\')
80         {
81             dst[i] = '/';
82         }
83 #endif
84         else
85         {
86             dst[i] = src[i];
87         }
88 
89         i++;
90     }
91     dst[i] = 0;
92 }
93 
94 int main(int argc, char *argv[])
95 {
96     INT ret;
97     INT i;
98     PSTR ptr;
99     BOOL UpperCaseFileName = FALSE;
100     PCSTR HiveList = NULL;
101     CHAR DestPath[PATH_MAX] = "";
102     CHAR FileName[PATH_MAX];
103 
104     if (argc < 4)
105     {
106         usage();
107         return -1;
108     }
109 
110     printf("Binary hive maker\n");
111 
112     /* Read the options */
113     for (i = 1; i < argc && *argv[i] == '-'; i++)
114     {
115         if (argv[i][1] == '?' && argv[i][2] == 0)
116         {
117             usage();
118             return 0;
119         }
120 
121         if (argv[i][1] == 'u' && argv[i][2] == 0)
122         {
123             UpperCaseFileName = TRUE;
124         }
125         else
126         if (argv[i][1] == 'h' && (argv[i][2] == ':' || argv[i][2] == '='))
127         {
128             HiveList = argv[i] + 3;
129         }
130         else if (argv[i][1] == 'd' && (argv[i][2] == ':' || argv[i][2] == '='))
131         {
132             convert_path(DestPath, argv[i] + 3);
133         }
134         else
135         {
136             fprintf(stderr, "Unrecognized option: %s\n", argv[i]);
137             return -1;
138         }
139     }
140 
141     /* Check whether we have all the parameters needed */
142     if (!HiveList || !*HiveList)
143     {
144         fprintf(stderr, "The mandatory list of hives is missing.\n");
145         return -1;
146     }
147     if (!*DestPath)
148     {
149         fprintf(stderr, "The mandatory output directory is missing.\n");
150         return -1;
151     }
152     if (i >= argc)
153     {
154         fprintf(stderr, "Not enough parameters, or the list of INF files is missing.\n");
155         return -1;
156     }
157 
158     /* Initialize the registry */
159     RegInitializeRegistry(HiveList);
160 
161     /* Default to failure */
162     ret = -1;
163 
164     /* Now we should have the list of INF files: parse it */
165     for (; i < argc; ++i)
166     {
167         convert_path(FileName, argv[i]);
168         if (!ImportRegistryFile(FileName))
169             goto Quit;
170     }
171 
172     for (i = 0; i < MAX_NUMBER_OF_REGISTRY_HIVES; ++i)
173     {
174         /* Skip this registry hive if it's not in the list */
175         if (!strstr(HiveList, RegistryHives[i].HiveName))
176             continue;
177 
178         strcpy(FileName, DestPath);
179         strcat(FileName, DIR_SEPARATOR_STRING);
180 
181         ptr = FileName + strlen(FileName);
182 
183         strcat(FileName, RegistryHives[i].HiveName);
184 
185         /* Exception for the special setup registry hive */
186         // if (strcmp(RegistryHives[i].HiveName, "SETUPREG") == 0)
187         if (i == 0)
188             strcat(FileName, ".HIV");
189 
190         /* Adjust file name case if needed */
191         if (UpperCaseFileName)
192         {
193             for (; *ptr; ++ptr)
194                 *ptr = toupper(*ptr);
195         }
196         else
197         {
198             for (; *ptr; ++ptr)
199                 *ptr = tolower(*ptr);
200         }
201 
202         if (!ExportBinaryHive(FileName, RegistryHives[i].CmHive))
203             goto Quit;
204 
205         /* If we happen to deal with the special setup registry hive, stop there */
206         // if (strcmp(RegistryHives[i].HiveName, "SETUPREG") == 0)
207         if (i == 0)
208             break;
209     }
210 
211     /* Success */
212     ret = 0;
213 
214 Quit:
215     /* Shut down the registry */
216     RegShutdownRegistry();
217 
218     if (ret == 0)
219         printf("  Done.\n");
220 
221     return ret;
222 }
223 
224 /* EOF */
225