3 * Copyright (C) 2003, 2006 ReactOS Team
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.
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.
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.
19 /* COPYRIGHT: See COPYING in the top level directory
20 * PROJECT: ReactOS hive maker
21 * FILE: tools/mkhive/reginf.h
22 * PURPOSE: Inf file import code
23 * PROGRAMMER: Eric Kohl
27 /* INCLUDES *****************************************************************/
36 #define FLG_ADDREG_BINVALUETYPE 0x00000001
37 #define FLG_ADDREG_NOCLOBBER 0x00000002
38 #define FLG_ADDREG_DELVAL 0x00000004
39 #define FLG_ADDREG_APPEND 0x00000008
40 #define FLG_ADDREG_KEYONLY 0x00000010
41 #define FLG_ADDREG_OVERWRITEONLY 0x00000020
42 #define FLG_ADDREG_TYPE_SZ 0x00000000
43 #define FLG_ADDREG_TYPE_MULTI_SZ 0x00010000
44 #define FLG_ADDREG_TYPE_EXPAND_SZ 0x00020000
45 #define FLG_ADDREG_TYPE_BINARY (0x00000000 | FLG_ADDREG_BINVALUETYPE)
46 #define FLG_ADDREG_TYPE_DWORD (0x00010000 | FLG_ADDREG_BINVALUETYPE)
47 #define FLG_ADDREG_TYPE_NONE (0x00020000 | FLG_ADDREG_BINVALUETYPE)
48 #define FLG_ADDREG_TYPE_MASK (0xFFFF0000 | FLG_ADDREG_BINVALUETYPE)
51 /* FUNCTIONS ****************************************************************/
54 GetRootKey (PWCHAR Name
)
56 if (!wcsicmp (Name
, L
"HKCR"))
58 wcscpy (Name
, L
"\\Registry\\Machine\\SOFTWARE\\Classes\\");
62 if (!wcsicmp (Name
, L
"HKCU"))
64 wcscpy (Name
, L
"\\Registry\\User\\.DEFAULT\\");
68 if (!wcsicmp (Name
, L
"HKLM"))
70 wcscpy (Name
, L
"\\Registry\\Machine\\");
74 if (!wcsicmp (Name
, L
"HKU"))
76 wcscpy (Name
, L
"\\Registry\\User\\");
81 if (!wcsicmp (Name
, L
"HKR"))
89 /***********************************************************************
92 * Append a multisz string to a multisz registry value.
109 Error
= RegQueryValueExW (
116 if ((Error
!= ERROR_SUCCESS
) ||
117 (Type
!= REG_MULTI_SZ
))
120 Buffer
= malloc (Size
+ (StringSize
* sizeof(WCHAR
)));
124 Error
= RegQueryValueExW (
131 if (Error
!= ERROR_SUCCESS
)
134 /* compare each string against all the existing ones */
136 while (*Strings
!= 0)
138 len
= wcslen (Strings
) + 1;
140 for (p
= Buffer
; *p
!= 0; p
+= wcslen (p
) + 1)
141 if (!wcsicmp (p
, Strings
))
144 if (*p
== 0) /* not found, need to append it */
146 memcpy (p
, Strings
, len
* sizeof(WCHAR
));
148 Total
+= len
* sizeof(WCHAR
);
155 DPRINT ("setting value %S to %S\n", ValueName
, Buffer
);
170 /***********************************************************************
173 * Perform an add/delete registry operation depending on the flags.
179 IN PINFCONTEXT Context
,
182 WCHAR EmptyStr
= (WCHAR
)0;
187 if (Flags
& FLG_ADDREG_DELVAL
) /* deletion */
191 RegDeleteValueW (KeyHandle
, ValueName
);
195 RegDeleteKeyW (KeyHandle
, NULL
);
201 if (Flags
& FLG_ADDREG_KEYONLY
)
204 if (Flags
& (FLG_ADDREG_NOCLOBBER
| FLG_ADDREG_OVERWRITEONLY
))
206 Error
= RegQueryValueExW (
213 if ((Error
== ERROR_SUCCESS
) &&
214 (Flags
& FLG_ADDREG_NOCLOBBER
))
217 if ((Error
!= ERROR_SUCCESS
) &&
218 (Flags
& FLG_ADDREG_OVERWRITEONLY
))
222 switch (Flags
& FLG_ADDREG_TYPE_MASK
)
224 case FLG_ADDREG_TYPE_SZ
:
228 case FLG_ADDREG_TYPE_MULTI_SZ
:
232 case FLG_ADDREG_TYPE_EXPAND_SZ
:
233 Type
= REG_EXPAND_SZ
;
236 case FLG_ADDREG_TYPE_BINARY
:
240 case FLG_ADDREG_TYPE_DWORD
:
244 case FLG_ADDREG_TYPE_NONE
:
253 if (!(Flags
& FLG_ADDREG_BINVALUETYPE
) ||
254 (Type
== REG_DWORD
&& InfHostGetFieldCount (Context
) == 5))
258 if (Type
== REG_MULTI_SZ
)
260 if (InfHostGetMultiSzField (Context
, 5, NULL
, 0, &Size
) != 0)
265 Str
= malloc (Size
* sizeof(WCHAR
));
269 InfHostGetMultiSzField (Context
, 5, Str
, (ULONG
)Size
, NULL
);
272 if (Flags
& FLG_ADDREG_APPEND
)
286 /* else fall through to normal string handling */
290 if (InfHostGetStringField (Context
, 5, NULL
, 0, &Size
) != 0)
295 Str
= malloc (Size
* sizeof(WCHAR
));
299 InfHostGetStringField (Context
, 5, Str
, (ULONG
)Size
, NULL
);
303 if (Type
== REG_DWORD
)
305 ULONG dw
= Str
? wcstoul (Str
, NULL
, 0) : 0;
307 DPRINT("setting dword %S to %x\n", ValueName
, dw
);
319 DPRINT("setting value %S to %S\n", ValueName
, Str
);
329 (ULONG
)Size
* sizeof(WCHAR
));
339 (ULONG
)sizeof(WCHAR
));
344 else /* get the binary data */
348 if (InfHostGetBinaryField (Context
, 5, NULL
, 0, &Size
) != 0)
353 Data
= malloc (Size
);
357 DPRINT("setting binary data %s len %d\n", ValueName
, Size
);
358 InfHostGetBinaryField (Context
, 5, Data
, Size
, NULL
);
375 /***********************************************************************
378 * Called once for each AddReg and DelReg entry in a given section.
381 registry_callback (HINF hInf
, PWCHAR Section
, BOOL Delete
)
383 WCHAR Buffer
[MAX_INF_STRING_LENGTH
];
388 PINFCONTEXT Context
= NULL
;
393 Ok
= InfHostFindFirstLine (hInf
, Section
, NULL
, &Context
) == 0;
395 return TRUE
; /* Don't fail if the section isn't present */
397 for (;Ok
; Ok
= (InfHostFindNextLine (Context
, Context
) == 0))
400 if (InfHostGetStringField (Context
, 1, Buffer
, MAX_INF_STRING_LENGTH
, NULL
) != 0)
402 if (!GetRootKey (Buffer
))
406 Length
= wcslen (Buffer
);
407 if (InfHostGetStringField (Context
, 2, Buffer
+ Length
, MAX_INF_STRING_LENGTH
- (ULONG
)Length
, NULL
) != 0)
410 DPRINT("KeyName: <%S>\n", Buffer
);
414 Flags
= FLG_ADDREG_DELVAL
;
419 if (InfHostGetIntField (Context
, 4, &Flags
) != 0)
423 DPRINT("Flags: 0x%x\n", Flags
);
425 if (Delete
|| (Flags
& FLG_ADDREG_OVERWRITEONLY
))
427 if (RegOpenKeyW (NULL
, Buffer
, &KeyHandle
) != ERROR_SUCCESS
)
429 DPRINT("RegOpenKey(%S) failed\n", Buffer
);
430 continue; /* ignore if it doesn't exist */
435 if (RegCreateKeyW (NULL
, Buffer
, &KeyHandle
) != ERROR_SUCCESS
)
437 DPRINT("RegCreateKey(%S) failed\n", Buffer
);
443 if (InfHostGetStringField (Context
, 3, Buffer
, MAX_INF_STRING_LENGTH
, NULL
) == 0)
453 if (!do_reg_operation (KeyHandle
, ValuePtr
, Context
, Flags
))
459 InfHostFreeContext(Context
);
466 ImportRegistryFile(PCHAR FileName
)
471 /* Load inf file from install media. */
472 if (InfHostOpenFile(&hInf
, FileName
, 0, &ErrorLine
) != 0)
474 DPRINT1 ("InfHostOpenFile(%s) failed\n", FileName
);
478 if (!registry_callback (hInf
, L
"DelReg", TRUE
))
480 DPRINT1 ("registry_callback() for DelReg failed\n");
483 if (!registry_callback (hInf
, L
"AddReg", FALSE
))
485 DPRINT1 ("registry_callback() for AddReg failed\n");
488 InfHostCloseFile (hInf
);