ReactOS 0.4.16-dev-340-g0540c21
reginf.c
Go to the documentation of this file.
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/reginf.c
23 * PURPOSE: Inf file import code
24 * PROGRAMMERS: Eric Kohl
25 * Hervé Poussineau
26 */
27
28/* INCLUDES *****************************************************************/
29
30#include <string.h>
31#include <stdlib.h>
32#include <stdio.h>
33
34#define NDEBUG
35#include "mkhive.h"
36
37#define FLG_ADDREG_BINVALUETYPE 0x00000001
38#define FLG_ADDREG_NOCLOBBER 0x00000002
39#define FLG_ADDREG_DELVAL 0x00000004
40#define FLG_ADDREG_APPEND 0x00000008
41#define FLG_ADDREG_KEYONLY 0x00000010
42#define FLG_ADDREG_OVERWRITEONLY 0x00000020
43#define FLG_ADDREG_KEYONLY_COMMON 0x00002000
44#define FLG_DELREG_KEYONLY_COMMON FLG_ADDREG_KEYONLY_COMMON
45#define FLG_ADDREG_DELREG_BIT 0x00008000
46
47#define FLG_ADDREG_TYPE_SZ 0x00000000
48#define FLG_ADDREG_TYPE_MULTI_SZ 0x00010000
49#define FLG_ADDREG_TYPE_EXPAND_SZ 0x00020000
50#define FLG_ADDREG_TYPE_BINARY (0x00000000 | FLG_ADDREG_BINVALUETYPE)
51#define FLG_ADDREG_TYPE_DWORD (0x00010000 | FLG_ADDREG_BINVALUETYPE)
52#define FLG_ADDREG_TYPE_NONE (0x00020000 | FLG_ADDREG_BINVALUETYPE)
53#define FLG_ADDREG_TYPE_MASK (0xFFFF0000 | FLG_ADDREG_BINVALUETYPE)
54
55
56static const WCHAR HKCR[] = {'H','K','C','R',0};
57static const WCHAR HKCU[] = {'H','K','C','U',0};
58static const WCHAR HKLM[] = {'H','K','L','M',0};
59static const WCHAR HKU[] = {'H','K','U',0};
60static const WCHAR HKR[] = {'H','K','R',0};
61static const WCHAR BCD[] = {'B','C','D',0};
62
63static const WCHAR HKCRPath[] = {'\\','R','e','g','i','s','t','r','y','\\','M','a','c','h','i','n','e','\\','S','O','F','T','W','A','R','E','\\','C','l','a','s','s','e','s','\\',0};
64static const WCHAR HKCUPath[] = {'\\','R','e','g','i','s','t','r','y','\\','U','s','e','r','\\','.','D','E','F','A','U','L','T','\\',0};
65static const WCHAR HKLMPath[] = {'\\','R','e','g','i','s','t','r','y','\\','M','a','c','h','i','n','e','\\',0};
66static const WCHAR HKUPath[] = {'\\','R','e','g','i','s','t','r','y','\\','U','s','e','r','\\',0};
67static const WCHAR BCDPath[] = {'\\','R','e','g','i','s','t','r','y','\\','M','a','c','h','i','n','e','\\',0};
68
69static const WCHAR AddReg[] = {'A','d','d','R','e','g',0};
70static const WCHAR DelReg[] = {'D','e','l','R','e','g',0};
71
72/* FUNCTIONS ****************************************************************/
73
74static BOOL
76{
77 if (!strcmpiW(Name, HKCR))
78 {
80 return TRUE;
81 }
82
83 if (!strcmpiW(Name, HKCU))
84 {
86 return TRUE;
87 }
88
89 if (!strcmpiW(Name, HKLM))
90 {
92 return TRUE;
93 }
94
95 if (!strcmpiW(Name, HKU))
96 {
98 return TRUE;
99 }
100
101 if (!strcmpiW(Name, BCD))
102 {
104 return TRUE;
105 }
106
107#if 0
108 if (!strcmpiW(Name, HKR))
109 return FALSE;
110#endif
111
112 return FALSE;
113}
114
115
116/***********************************************************************
117 * append_multi_sz_value
118 *
119 * Append a multisz string to a multisz registry value.
120 */
121// NOTE: Synced with setupapi/install.c ; see also usetup/registry.c
122static VOID
127 IN ULONG StringSize) // In characters
128{
129 ULONG Size, Total; // In bytes
130 ULONG Type;
132 PWCHAR p;
133 size_t len;
134 LONG Error;
135
137 ValueName,
138 NULL,
139 &Type,
140 NULL,
141 &Size);
142 if ((Error != ERROR_SUCCESS) || (Type != REG_MULTI_SZ))
143 return;
144
145 Buffer = malloc(Size + StringSize * sizeof(WCHAR));
146 if (Buffer == NULL)
147 return;
148
150 ValueName,
151 NULL,
152 NULL,
153 (PUCHAR)Buffer,
154 &Size);
155 if (Error != ERROR_SUCCESS)
156 goto done;
157
158 /* compare each string against all the existing ones */
159 Total = Size;
160 while (*Strings != 0)
161 {
162 len = strlenW(Strings) + 1;
163
164 for (p = Buffer; *p != 0; p += strlenW(p) + 1)
165 if (!strcmpiW(p, Strings))
166 break;
167
168 if (*p == 0) /* not found, need to append it */
169 {
170 memcpy(p, Strings, len * sizeof(WCHAR));
171 p[len] = 0;
172 Total += len * sizeof(WCHAR);
173 }
174 Strings += len;
175 }
176
177 if (Total != Size)
178 {
179 DPRINT("setting value '%S' to '%S'\n", ValueName, Buffer);
181 ValueName,
182 0,
184 (PUCHAR)Buffer,
185 Total + sizeof(WCHAR));
186 }
187
188done:
189 free(Buffer);
190}
191
192
193/***********************************************************************
194 * do_reg_operation
195 *
196 * Perform an add/delete registry operation depending on the flags.
197 */
198static BOOL
203 IN ULONG Flags)
204{
205 WCHAR EmptyStr = 0;
206 ULONG Type;
207 ULONG Size;
208 LONG Error;
209
210 if (Flags & (FLG_ADDREG_DELREG_BIT | FLG_ADDREG_DELVAL)) /* deletion */
211 {
213 {
214 // NOTE: We don't currently handle deleting sub-values inside multi-strings.
216 }
217 else
218 {
220 }
221 return TRUE;
222 }
223
225 return TRUE;
226
228 {
230 ValueName,
231 NULL,
232 NULL,
233 NULL,
234 NULL);
235
237 return TRUE;
238
240 return TRUE;
241 }
242
243 switch (Flags & FLG_ADDREG_TYPE_MASK)
244 {
246 Type = REG_SZ;
247 break;
248
251 break;
252
255 break;
256
259 break;
260
262 Type = REG_DWORD;
263 break;
264
266 Type = REG_NONE;
267 break;
268
269 default:
270 Type = Flags >> 16;
271 break;
272 }
273
276 {
277 PWCHAR Str = NULL;
278
279 if (Type == REG_MULTI_SZ)
280 {
281 if (InfHostGetMultiSzField(Context, 5, NULL, 0, &Size) != 0)
282 Size = 0;
283
284 if (Size)
285 {
286 Str = malloc(Size * sizeof(WCHAR));
287 if (Str == NULL)
288 return FALSE;
289
291 }
292
294 {
295 if (Str == NULL)
296 return TRUE;
297
298 DPRINT("append_multi_sz_value(ValueName = '%S')\n", ValueName);
300 ValueName,
301 Str,
302 Size);
303
304 free(Str);
305 return TRUE;
306 }
307 /* else fall through to normal string handling */
308 }
309 else
310 {
311 if (InfHostGetStringField(Context, 5, NULL, 0, &Size) != 0)
312 Size = 0;
313
314 if (Size)
315 {
316 Str = malloc(Size * sizeof(WCHAR));
317 if (Str == NULL)
318 return FALSE;
319
321 }
322 }
323
324 if (Type == REG_DWORD)
325 {
326 ULONG dw = Str ? strtoulW(Str, NULL, 0) : 0;
327
328 DPRINT("setting dword '%S' to %x\n", ValueName, dw);
329
331 ValueName,
332 0,
333 Type,
334 (const PUCHAR)&dw,
335 sizeof(ULONG));
336 }
337 else
338 {
339 DPRINT("setting value '%S' to '%S'\n", ValueName, Str);
340
341 if (Str)
342 {
344 ValueName,
345 0,
346 Type,
347 (PVOID)Str,
348 (ULONG)(Size * sizeof(WCHAR)));
349 }
350 else
351 {
353 ValueName,
354 0,
355 Type,
356 (PVOID)&EmptyStr,
357 sizeof(WCHAR));
358 }
359 }
360 free(Str);
361 }
362 else /* get the binary data */
363 {
364 PUCHAR Data = NULL;
365
366 if (InfHostGetBinaryField(Context, 5, NULL, 0, &Size) != 0)
367 Size = 0;
368
369 if (Size)
370 {
371 Data = malloc(Size);
372 if (Data == NULL)
373 return FALSE;
374
375 DPRINT("setting binary data '%S' len %d\n", ValueName, (ULONG)Size);
377 }
378
380 ValueName,
381 0,
382 Type,
383 (PVOID)Data,
384 (ULONG)Size);
385
386 free(Data);
387 }
388
389 return TRUE;
390}
391
392/***********************************************************************
393 * registry_callback
394 *
395 * Called once for each AddReg and DelReg entry in a given section.
396 */
397static BOOL
399{
401 PWCHAR ValuePtr;
402 ULONG Flags;
403 size_t Length;
404
407 BOOL Ok;
408
409 Ok = InfHostFindFirstLine(hInf, Section, NULL, &Context) == 0;
410 if (!Ok)
411 return TRUE; /* Don't fail if the section isn't present */
412
413 for (Ok = TRUE; Ok; Ok = (InfHostFindNextLine(Context, Context) == 0))
414 {
415 /* Get root */
416 if (InfHostGetStringField(Context, 1, Buffer, sizeof(Buffer)/sizeof(WCHAR), NULL) != 0)
417 continue;
418 if (!get_root_key(Buffer))
419 continue;
420
421 /* Get key */
423 if (InfHostGetStringField(Context, 2, Buffer + Length, sizeof(Buffer)/sizeof(WCHAR) - (ULONG)Length, NULL) != 0)
424 *Buffer = 0;
425
426 DPRINT("KeyName: <%S>\n", Buffer);
427
428 /* Get flags */
429 if (InfHostGetIntField(Context, 4, (INT*)&Flags) != 0)
430 Flags = 0;
431
432 if (Delete)
433 {
434 if (!Flags)
436 else if (!(Flags & FLG_ADDREG_DELREG_BIT))
437 continue; /* ignore this entry */
438 }
439 else
440 {
442 continue; /* ignore this entry */
443 }
444
445 DPRINT("Flags: 0x%x\n", Flags);
446
448 {
450 {
451 DPRINT("RegOpenKey(%S) failed\n", Buffer);
452 continue; /* ignore if it doesn't exist */
453 }
454 }
455 else
456 {
458 {
459 DPRINT("RegCreateKey(%S) failed\n", Buffer);
460 continue;
461 }
462 }
463
464 /* Get value name */
465 if (InfHostGetStringField(Context, 3, Buffer, sizeof(Buffer)/sizeof(WCHAR), NULL) == 0)
466 {
467 ValuePtr = Buffer;
468 }
469 else
470 {
471 ValuePtr = NULL;
472 }
473
474 /* And now do it */
475 if (!do_reg_operation(KeyHandle, ValuePtr, Context, Flags))
476 {
478 return FALSE;
479 }
480
482 }
483
485
486 return TRUE;
487}
488
489
490BOOL
492{
493 HINF hInf;
494 ULONG ErrorLine;
495
496 /* Load inf file from install media. */
497 if (InfHostOpenFile(&hInf, FileName, 0, &ErrorLine) != 0)
498 {
499 DPRINT1("InfHostOpenFile(%s) failed\n", FileName);
500 return FALSE;
501 }
502
503 if (!registry_callback(hInf, (PWCHAR)DelReg, TRUE))
504 {
505 DPRINT1("registry_callback() for DelReg failed\n");
506 InfHostCloseFile(hInf);
507 return FALSE;
508 }
509
510 if (!registry_callback(hInf, (PWCHAR)AddReg, FALSE))
511 {
512 DPRINT1("registry_callback() for AddReg failed\n");
513 InfHostCloseFile(hInf);
514 return FALSE;
515 }
516
517 InfHostCloseFile(hInf);
518 return TRUE;
519}
520
521/* EOF */
Type
Definition: Type.h:7
#define DPRINT1
Definition: precomp.h:8
BOOL Delete(LPCTSTR ServiceName)
Definition: delete.c:12
BOOL Error
Definition: chkdsk.c:66
#define RegCloseKey(hKey)
Definition: registry.h:49
Definition: bufpool.h:45
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
LONG WINAPI RegOpenKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3268
LONG WINAPI RegSetValueExW(_In_ HKEY hKey, _In_ LPCWSTR lpValueName, _In_ DWORD Reserved, _In_ DWORD dwType, _In_ CONST BYTE *lpData, _In_ DWORD cbData)
Definition: reg.c:4882
LONG WINAPI RegDeleteKeyW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey)
Definition: reg.c:1239
LONG WINAPI RegDeleteValueW(HKEY hKey, LPCWSTR lpValueName)
Definition: reg.c:2330
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4103
LONG WINAPI RegCreateKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:1201
static const WCHAR Strings[]
Definition: reg.c:35
unsigned int BOOL
Definition: ntddk_ex.h:94
@ Ok
Definition: gdiplustypes.h:26
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
REFIID LPVOID DWORD_PTR dw
Definition: atlbase.h:40
int InfHostOpenFile(PHINF InfHandle, const CHAR *FileName, LANGID LanguageId, ULONG *ErrorLine)
Definition: infhostgen.c:128
int InfHostFindNextLine(PINFCONTEXT ContextIn, PINFCONTEXT ContextOut)
Definition: infhostget.c:39
int InfHostFindFirstLine(HINF InfHandle, const WCHAR *Section, const WCHAR *Key, PINFCONTEXT *Context)
Definition: infhostget.c:18
int InfHostGetIntField(PINFCONTEXT Context, ULONG FieldIndex, INT *IntegerValue)
Definition: infhostget.c:139
int InfHostGetMultiSzField(PINFCONTEXT Context, ULONG FieldIndex, WCHAR *ReturnBuffer, ULONG ReturnBufferSize, ULONG *RequiredSize)
Definition: infhostget.c:159
int InfHostGetBinaryField(PINFCONTEXT Context, ULONG FieldIndex, UCHAR *ReturnBuffer, ULONG ReturnBufferSize, ULONG *RequiredSize)
Definition: infhostget.c:116
int InfHostGetStringField(PINFCONTEXT Context, ULONG FieldIndex, WCHAR *ReturnBuffer, ULONG ReturnBufferSize, ULONG *RequiredSize)
Definition: infhostget.c:182
LONG InfHostGetFieldCount(PINFCONTEXT Context)
Definition: infhostget.c:109
void InfHostCloseFile(HINF InfHandle)
Definition: infhostgen.c:283
void InfHostFreeContext(PINFCONTEXT Context)
Definition: infhostget.c:244
#define MAX_INF_STRING_LENGTH
Definition: infsupp.h:36
#define REG_SZ
Definition: layer.c:22
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4715
#define REG_BINARY
Definition: nt_native.h:1496
#define REG_MULTI_SZ
Definition: nt_native.h:1501
#define REG_NONE
Definition: nt_native.h:1492
#define REG_EXPAND_SZ
Definition: nt_native.h:1494
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
long LONG
Definition: pedump.c:60
#define strcmpiW(s1, s2)
Definition: unicode.h:45
#define strlenW(s)
Definition: unicode.h:34
#define strtoulW(s1, s2, b)
Definition: unicode.h:47
#define strcpyW(d, s)
Definition: unicode.h:35
static const WCHAR HKUPath[]
Definition: reginf.c:66
#define FLG_ADDREG_DELREG_BIT
Definition: reginf.c:45
#define FLG_ADDREG_OVERWRITEONLY
Definition: reginf.c:42
static BOOL do_reg_operation(IN HKEY KeyHandle, IN PCWSTR ValueName, IN PINFCONTEXT Context, IN ULONG Flags)
Definition: reginf.c:199
static BOOL registry_callback(HINF hInf, PCWSTR Section, BOOL Delete)
Definition: reginf.c:398
static const WCHAR HKLM[]
Definition: reginf.c:58
#define FLG_ADDREG_TYPE_MASK
Definition: reginf.c:53
BOOL ImportRegistryFile(PCHAR FileName)
Definition: reginf.c:491
#define FLG_ADDREG_TYPE_BINARY
Definition: reginf.c:50
static const WCHAR HKCR[]
Definition: reginf.c:56
#define FLG_ADDREG_TYPE_SZ
Definition: reginf.c:47
#define FLG_ADDREG_BINVALUETYPE
Definition: reginf.c:37
#define FLG_ADDREG_APPEND
Definition: reginf.c:40
#define FLG_ADDREG_TYPE_EXPAND_SZ
Definition: reginf.c:49
#define FLG_DELREG_KEYONLY_COMMON
Definition: reginf.c:44
#define FLG_ADDREG_DELVAL
Definition: reginf.c:39
static BOOL get_root_key(PWCHAR Name)
Definition: reginf.c:75
static VOID append_multi_sz_value(IN HKEY KeyHandle, IN PCWSTR ValueName, IN PCWSTR Strings, IN ULONG StringSize)
Definition: reginf.c:123
static const WCHAR HKLMPath[]
Definition: reginf.c:65
#define FLG_ADDREG_TYPE_MULTI_SZ
Definition: reginf.c:48
static const WCHAR HKCRPath[]
Definition: reginf.c:63
static const WCHAR HKCUPath[]
Definition: reginf.c:64
#define FLG_ADDREG_TYPE_NONE
Definition: reginf.c:52
#define FLG_ADDREG_KEYONLY
Definition: reginf.c:41
#define FLG_ADDREG_NOCLOBBER
Definition: reginf.c:38
#define FLG_ADDREG_TYPE_DWORD
Definition: reginf.c:51
static const WCHAR AddReg[]
Definition: reginf.c:69
#define FLG_ADDREG_KEYONLY_COMMON
Definition: reginf.c:43
static const WCHAR BCD[]
Definition: reginf.c:61
static const WCHAR BCDPath[]
Definition: reginf.c:67
static const WCHAR HKU[]
Definition: reginf.c:59
static const WCHAR HKR[]
Definition: reginf.c:60
static const WCHAR DelReg[]
Definition: reginf.c:70
static const WCHAR HKCU[]
Definition: reginf.c:57
#define REG_DWORD
Definition: sdbapi.c:596
#define DPRINT
Definition: sndvol32.h:73
const uint16_t * PCWSTR
Definition: typedefs.h:57
int32_t INT
Definition: typedefs.h:58
#define IN
Definition: typedefs.h:39
uint16_t * PWCHAR
Definition: typedefs.h:56
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
char * PCHAR
Definition: typedefs.h:51
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:243
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
__wchar_t WCHAR
Definition: xmlstorage.h:180