3 * Copyright (C) 2003 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
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 * COPYRIGHT: See COPYING in the top level directory
21 * PROJECT: ReactOS hive maker
22 * FILE: tools/mkhive/reginf.h
23 * PURPOSE: Inf file import code
24 * PROGRAMMER: Eric Kohl
27 /* INCLUDES *****************************************************************/
39 #define FLG_ADDREG_BINVALUETYPE 0x00000001
40 #define FLG_ADDREG_NOCLOBBER 0x00000002
41 #define FLG_ADDREG_DELVAL 0x00000004
42 #define FLG_ADDREG_APPEND 0x00000008
43 #define FLG_ADDREG_KEYONLY 0x00000010
44 #define FLG_ADDREG_OVERWRITEONLY 0x00000020
45 #define FLG_ADDREG_TYPE_SZ 0x00000000
46 #define FLG_ADDREG_TYPE_MULTI_SZ 0x00010000
47 #define FLG_ADDREG_TYPE_EXPAND_SZ 0x00020000
48 #define FLG_ADDREG_TYPE_BINARY (0x00000000 | FLG_ADDREG_BINVALUETYPE)
49 #define FLG_ADDREG_TYPE_DWORD (0x00010000 | FLG_ADDREG_BINVALUETYPE)
50 #define FLG_ADDREG_TYPE_NONE (0x00020000 | FLG_ADDREG_BINVALUETYPE)
51 #define FLG_ADDREG_TYPE_MASK (0xFFFF0000 | FLG_ADDREG_BINVALUETYPE)
54 /* FUNCTIONS ****************************************************************/
57 GetRootKey (PCHAR Name
)
59 if (!strcasecmp (Name
, "HKCR"))
61 strcpy (Name
, "\\Registry\\Machine\\SOFTWARE\\Classes\\");
65 if (!strcasecmp (Name
, "HKCU"))
67 strcpy (Name
, "\\Registry\\User\\.DEFAULT\\");
71 if (!strcasecmp (Name
, "HKLM"))
73 strcpy (Name
, "\\Registry\\Machine\\");
77 if (!strcasecmp (Name
, "HKU"))
79 strcpy (Name
, "\\Registry\\User\\");
84 if (!strcasecmp (Name
, "HKR"))
92 /***********************************************************************
95 * Append a multisz string to a multisz registry value.
98 AppendMultiSzValue (HKEY KeyHandle
,
111 Error
= RegQueryValue (KeyHandle
,
116 if ((Error
!= ERROR_SUCCESS
) ||
117 (Type
!= REG_MULTI_SZ
))
120 Buffer
= malloc (Size
+ StringSize
);
124 Error
= RegQueryValue (KeyHandle
,
129 if (Error
!= ERROR_SUCCESS
)
132 /* compare each string against all the existing ones */
134 while (*Strings
!= 0)
136 len
= strlen (Strings
) + 1;
138 for (p
= Buffer
; *p
!= 0; p
+= strlen (p
) + 1)
139 if (!strcasecmp (p
, Strings
))
142 if (*p
== 0) /* not found, need to append it */
144 memcpy (p
, Strings
, len
);
153 DPRINT ("setting value %s to %s\n", ValueName
, Buffer
);
154 RegSetValue (KeyHandle
,
166 /***********************************************************************
169 * Perform an add/delete registry operation depending on the flags.
172 do_reg_operation(HKEY KeyHandle
,
177 CHAR EmptyStr
= (CHAR
)0;
182 if (Flags
& FLG_ADDREG_DELVAL
) /* deletion */
186 RegDeleteValue (KeyHandle
,
191 RegDeleteKey (KeyHandle
,
198 if (Flags
& FLG_ADDREG_KEYONLY
)
201 if (Flags
& (FLG_ADDREG_NOCLOBBER
| FLG_ADDREG_OVERWRITEONLY
))
203 Error
= RegQueryValue (KeyHandle
,
208 if ((Error
== ERROR_SUCCESS
) &&
209 (Flags
& FLG_ADDREG_NOCLOBBER
))
212 if ((Error
!= ERROR_SUCCESS
) &&
213 (Flags
& FLG_ADDREG_OVERWRITEONLY
))
217 switch (Flags
& FLG_ADDREG_TYPE_MASK
)
219 case FLG_ADDREG_TYPE_SZ
:
223 case FLG_ADDREG_TYPE_MULTI_SZ
:
227 case FLG_ADDREG_TYPE_EXPAND_SZ
:
228 Type
= REG_EXPAND_SZ
;
231 case FLG_ADDREG_TYPE_BINARY
:
235 case FLG_ADDREG_TYPE_DWORD
:
239 case FLG_ADDREG_TYPE_NONE
:
248 if (!(Flags
& FLG_ADDREG_BINVALUETYPE
) ||
249 (Type
== REG_DWORD
&& InfGetFieldCount (Context
) == 5))
253 if (Type
== REG_MULTI_SZ
)
255 if (!InfGetMultiSzField (Context
, 5, NULL
, 0, &Size
))
264 InfGetMultiSzField (Context
, 5, Str
, Size
, NULL
);
267 if (Flags
& FLG_ADDREG_APPEND
)
272 AppendMultiSzValue (KeyHandle
,
280 /* else fall through to normal string handling */
284 if (!InfGetStringField (Context
, 5, NULL
, 0, &Size
))
293 InfGetStringField (Context
, 5, Str
, Size
, NULL
);
297 if (Type
== REG_DWORD
)
299 ULONG dw
= Str
? strtoul (Str
, NULL
, 0) : 0;
301 DPRINT("setting dword %s to %lx\n", ValueName
, dw
);
303 RegSetValue (KeyHandle
,
311 DPRINT("setting value %s to %s\n", ValueName
, Str
);
315 RegSetValue (KeyHandle
,
323 RegSetValue (KeyHandle
,
332 else /* get the binary data */
336 if (!InfGetBinaryField (Context
, 5, NULL
, 0, &Size
))
341 Data
= malloc (Size
);
345 DPRINT("setting binary data %s len %lu\n", ValueName
, Size
);
346 InfGetBinaryField (Context
, 5, Data
, Size
, NULL
);
349 RegSetValue (KeyHandle
,
362 /***********************************************************************
365 * Called once for each AddReg and DelReg entry in a given section.
368 registry_callback (HINF hInf
, PCHAR Section
, BOOL Delete
)
370 CHAR Buffer
[MAX_INF_STRING_LENGTH
];
380 Ok
= InfFindFirstLine (hInf
, Section
, NULL
, &Context
);
382 return TRUE
; /* Don't fail if the section isn't present */
384 for (;Ok
; Ok
= InfFindNextLine (&Context
, &Context
))
387 if (!InfGetStringField (&Context
, 1, Buffer
, MAX_INF_STRING_LENGTH
, NULL
))
389 if (!GetRootKey (Buffer
))
393 Length
= strlen (Buffer
);
394 if (!InfGetStringField (&Context
, 2, Buffer
+ Length
, MAX_INF_STRING_LENGTH
- Length
, NULL
))
397 DPRINT("KeyName: <%s>\n", Buffer
);
401 Flags
= FLG_ADDREG_DELVAL
;
406 if (!InfGetIntField (&Context
, 4, (PLONG
)&Flags
))
410 DPRINT("Flags: %lx\n", Flags
);
412 if (Delete
|| (Flags
& FLG_ADDREG_OVERWRITEONLY
))
414 if (RegOpenKey (NULL
, Buffer
, &KeyHandle
) != ERROR_SUCCESS
)
416 DPRINT("RegOpenKey(%s) failed\n", Buffer
);
417 continue; /* ignore if it doesn't exist */
422 if (RegCreateKey (NULL
, Buffer
, &KeyHandle
) != ERROR_SUCCESS
)
424 DPRINT("RegCreateKey(%s) failed\n", Buffer
);
430 if (InfGetStringField (&Context
, 3, Buffer
, MAX_INF_STRING_LENGTH
, NULL
))
440 if (!do_reg_operation (KeyHandle
, ValuePtr
, &Context
, Flags
))
451 ImportRegistryFile(PCHAR FileName
,
458 /* Load inf file from install media. */
459 if (!InfOpenFile(&hInf
, FileName
, &ErrorLine
))
461 DPRINT1 ("InfOpenFile() failed\n");
465 if (!registry_callback (hInf
, "DelReg", TRUE
))
467 DPRINT1 ("registry_callback() failed\n");
470 if (!registry_callback (hInf
, "AddReg", FALSE
))
472 DPRINT1 ("registry_callback() failed\n");