Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenreginf.c
Go to the documentation of this file.
00001 /* 00002 * ReactOS kernel 00003 * Copyright (C) 2003, 2006 ReactOS Team 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License as published by 00007 * the Free Software Foundation; either version 2 of the License, or 00008 * (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License along 00016 * with this program; if not, write to the Free Software Foundation, Inc., 00017 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00018 */ 00019 /* COPYRIGHT: See COPYING in the top level directory 00020 * PROJECT: ReactOS hive maker 00021 * FILE: tools/mkhive/reginf.h 00022 * PURPOSE: Inf file import code 00023 * PROGRAMMER: Eric Kohl 00024 * Hervé Poussineau 00025 */ 00026 00027 /* INCLUDES *****************************************************************/ 00028 00029 #include <string.h> 00030 #include <stdlib.h> 00031 #include <stdio.h> 00032 00033 #define NDEBUG 00034 #include "mkhive.h" 00035 00036 #define FLG_ADDREG_BINVALUETYPE 0x00000001 00037 #define FLG_ADDREG_NOCLOBBER 0x00000002 00038 #define FLG_ADDREG_DELVAL 0x00000004 00039 #define FLG_ADDREG_APPEND 0x00000008 00040 #define FLG_ADDREG_KEYONLY 0x00000010 00041 #define FLG_ADDREG_OVERWRITEONLY 0x00000020 00042 #define FLG_ADDREG_TYPE_SZ 0x00000000 00043 #define FLG_ADDREG_TYPE_MULTI_SZ 0x00010000 00044 #define FLG_ADDREG_TYPE_EXPAND_SZ 0x00020000 00045 #define FLG_ADDREG_TYPE_BINARY (0x00000000 | FLG_ADDREG_BINVALUETYPE) 00046 #define FLG_ADDREG_TYPE_DWORD (0x00010000 | FLG_ADDREG_BINVALUETYPE) 00047 #define FLG_ADDREG_TYPE_NONE (0x00020000 | FLG_ADDREG_BINVALUETYPE) 00048 #define FLG_ADDREG_TYPE_MASK (0xFFFF0000 | FLG_ADDREG_BINVALUETYPE) 00049 00050 00051 static const WCHAR HKCR[] = {'H','K','C','R',0}; 00052 static const WCHAR HKCU[] = {'H','K','C','U',0}; 00053 static const WCHAR HKLM[] = {'H','K','L','M',0}; 00054 static const WCHAR HKU[] = {'H','K','U',0}; 00055 static const WCHAR HKR[] = {'H','K','R',0}; 00056 00057 static 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}; 00058 static const WCHAR HKCUPath[] = {'\\','R','e','g','i','s','t','r','y','\\','U','s','e','r','\\','.','D','E','F','A','U','L','T','\\',0}; 00059 static const WCHAR HKLMPath[] = {'\\','R','e','g','i','s','t','r','y','\\','M','a','c','h','i','n','e','\\',0}; 00060 static const WCHAR HKUPath[] = {'\\','R','e','g','i','s','t','r','y','\\','U','s','e','r','\\',0}; 00061 00062 static const WCHAR AddReg[] = {'A','d','d','R','e','g',0}; 00063 static const WCHAR DelReg[] = {'D','e','l','R','e','g',0}; 00064 00065 /* FUNCTIONS ****************************************************************/ 00066 00067 static BOOL 00068 GetRootKey (PWCHAR Name) 00069 { 00070 if (!strcmpiW (Name, HKCR)) 00071 { 00072 strcpyW (Name, HKCRPath); 00073 return TRUE; 00074 } 00075 00076 if (!strcmpiW (Name, HKCU)) 00077 { 00078 strcpyW (Name, HKCUPath); 00079 return TRUE; 00080 } 00081 00082 if (!strcmpiW (Name, HKLM)) 00083 { 00084 strcpyW (Name, HKLMPath); 00085 return TRUE; 00086 } 00087 00088 if (!strcmpiW (Name, HKU)) 00089 { 00090 strcpyW (Name, HKUPath); 00091 return TRUE; 00092 } 00093 00094 #if 0 00095 if (!strcmpiW (Name, HKR)) 00096 return FALSE; 00097 #endif 00098 00099 return FALSE; 00100 } 00101 00102 00103 /*********************************************************************** 00104 * AppendMultiSzValue 00105 * 00106 * Append a multisz string to a multisz registry value. 00107 */ 00108 static VOID 00109 AppendMultiSzValue ( 00110 IN HKEY KeyHandle, 00111 IN PWCHAR ValueName, 00112 IN PWCHAR Strings, 00113 IN SIZE_T StringSize) 00114 { 00115 SIZE_T Size; 00116 ULONG Type; 00117 size_t Total; 00118 PWCHAR Buffer; 00119 PWCHAR p; 00120 size_t len; 00121 LONG Error; 00122 00123 Error = RegQueryValueExW ( 00124 KeyHandle, 00125 ValueName, 00126 NULL, 00127 &Type, 00128 NULL, 00129 &Size); 00130 if ((Error != ERROR_SUCCESS) || 00131 (Type != REG_MULTI_SZ)) 00132 return; 00133 00134 Buffer = malloc ((Size + StringSize) * sizeof(WCHAR)); 00135 if (Buffer == NULL) 00136 return; 00137 00138 Error = RegQueryValueExW ( 00139 KeyHandle, 00140 ValueName, 00141 NULL, 00142 NULL, 00143 (PUCHAR)Buffer, 00144 &Size); 00145 if (Error != ERROR_SUCCESS) 00146 goto done; 00147 00148 /* compare each string against all the existing ones */ 00149 Total = Size; 00150 while (*Strings != 0) 00151 { 00152 len = strlenW(Strings) + 1; 00153 00154 for (p = Buffer; *p != 0; p += strlenW(p) + 1) 00155 if (!strcmpiW(p, Strings)) 00156 break; 00157 00158 if (*p == 0) /* not found, need to append it */ 00159 { 00160 memcpy (p, Strings, len); 00161 p[len] = 0; 00162 Total += len; 00163 } 00164 Strings += len; 00165 } 00166 00167 if (Total != Size) 00168 { 00169 DPRINT ("setting value %S to %S\n", ValueName, Buffer); 00170 RegSetValueExW ( 00171 KeyHandle, 00172 ValueName, 00173 0, 00174 REG_MULTI_SZ, 00175 (PUCHAR)Buffer, 00176 (ULONG)Total * sizeof(WCHAR)); 00177 } 00178 00179 done: 00180 free (Buffer); 00181 } 00182 00183 00184 /*********************************************************************** 00185 * do_reg_operation 00186 * 00187 * Perform an add/delete registry operation depending on the flags. 00188 */ 00189 static BOOL 00190 do_reg_operation( 00191 IN HKEY KeyHandle, 00192 IN PWCHAR ValueName, 00193 IN PINFCONTEXT Context, 00194 IN ULONG Flags) 00195 { 00196 WCHAR EmptyStr = (CHAR)0; 00197 ULONG Type; 00198 ULONG Size; 00199 LONG Error; 00200 00201 if (Flags & FLG_ADDREG_DELVAL) /* deletion */ 00202 { 00203 if (ValueName) 00204 { 00205 RegDeleteValueW (KeyHandle, ValueName); 00206 } 00207 else 00208 { 00209 RegDeleteKeyW (KeyHandle, NULL); 00210 } 00211 00212 return TRUE; 00213 } 00214 00215 if (Flags & FLG_ADDREG_KEYONLY) 00216 return TRUE; 00217 00218 if (Flags & (FLG_ADDREG_NOCLOBBER | FLG_ADDREG_OVERWRITEONLY)) 00219 { 00220 Error = RegQueryValueExW ( 00221 KeyHandle, 00222 ValueName, 00223 NULL, 00224 NULL, 00225 NULL, 00226 NULL); 00227 if ((Error == ERROR_SUCCESS) && 00228 (Flags & FLG_ADDREG_NOCLOBBER)) 00229 return TRUE; 00230 00231 if ((Error != ERROR_SUCCESS) && 00232 (Flags & FLG_ADDREG_OVERWRITEONLY)) 00233 return TRUE; 00234 } 00235 00236 switch (Flags & FLG_ADDREG_TYPE_MASK) 00237 { 00238 case FLG_ADDREG_TYPE_SZ: 00239 Type = REG_SZ; 00240 break; 00241 00242 case FLG_ADDREG_TYPE_MULTI_SZ: 00243 Type = REG_MULTI_SZ; 00244 break; 00245 00246 case FLG_ADDREG_TYPE_EXPAND_SZ: 00247 Type = REG_EXPAND_SZ; 00248 break; 00249 00250 case FLG_ADDREG_TYPE_BINARY: 00251 Type = REG_BINARY; 00252 break; 00253 00254 case FLG_ADDREG_TYPE_DWORD: 00255 Type = REG_DWORD; 00256 break; 00257 00258 case FLG_ADDREG_TYPE_NONE: 00259 Type = REG_NONE; 00260 break; 00261 00262 default: 00263 Type = Flags >> 16; 00264 break; 00265 } 00266 00267 if (!(Flags & FLG_ADDREG_BINVALUETYPE) || 00268 (Type == REG_DWORD && InfHostGetFieldCount (Context) == 5)) 00269 { 00270 PWCHAR Str = NULL; 00271 00272 if (Type == REG_MULTI_SZ) 00273 { 00274 if (InfHostGetMultiSzField (Context, 5, NULL, 0, &Size) != 0) 00275 Size = 0; 00276 00277 if (Size) 00278 { 00279 Str = malloc (Size * sizeof(WCHAR)); 00280 if (Str == NULL) 00281 return FALSE; 00282 00283 InfHostGetMultiSzField (Context, 5, Str, (ULONG)Size, NULL); 00284 } 00285 00286 if (Flags & FLG_ADDREG_APPEND) 00287 { 00288 if (Str == NULL) 00289 return TRUE; 00290 00291 AppendMultiSzValue ( 00292 KeyHandle, 00293 ValueName, 00294 Str, 00295 Size); 00296 00297 free (Str); 00298 return TRUE; 00299 } 00300 /* else fall through to normal string handling */ 00301 } 00302 else 00303 { 00304 if (InfHostGetStringField (Context, 5, NULL, 0, &Size) != 0) 00305 Size = 0; 00306 00307 if (Size) 00308 { 00309 Str = malloc (Size * sizeof(WCHAR)); 00310 if (Str == NULL) 00311 return FALSE; 00312 00313 InfHostGetStringField (Context, 5, Str, (ULONG)Size, NULL); 00314 } 00315 } 00316 00317 if (Type == REG_DWORD) 00318 { 00319 ULONG dw = Str ? strtoulW (Str, NULL, 0) : 0; 00320 00321 DPRINT("setting dword %S to %x\n", ValueName, dw); 00322 00323 RegSetValueExW ( 00324 KeyHandle, 00325 ValueName, 00326 0, 00327 Type, 00328 (const PUCHAR)&dw, 00329 sizeof(ULONG)); 00330 } 00331 else 00332 { 00333 DPRINT("setting value %S to %S\n", ValueName, Str); 00334 00335 if (Str) 00336 { 00337 RegSetValueExW ( 00338 KeyHandle, 00339 ValueName, 00340 0, 00341 Type, 00342 (PVOID)Str, 00343 (ULONG)Size * sizeof(WCHAR)); 00344 } 00345 else 00346 { 00347 RegSetValueExW ( 00348 KeyHandle, 00349 ValueName, 00350 0, 00351 Type, 00352 (PVOID)&EmptyStr, 00353 (ULONG)sizeof(WCHAR)); 00354 } 00355 } 00356 free (Str); 00357 } 00358 else /* get the binary data */ 00359 { 00360 PUCHAR Data = NULL; 00361 00362 if (InfHostGetBinaryField (Context, 5, NULL, 0, &Size) != 0) 00363 Size = 0; 00364 00365 if (Size) 00366 { 00367 Data = malloc (Size); 00368 if (Data == NULL) 00369 return FALSE; 00370 00371 DPRINT("setting binary data %S len %d\n", ValueName, Size); 00372 InfHostGetBinaryField (Context, 5, Data, Size, NULL); 00373 } 00374 00375 RegSetValueExW ( 00376 KeyHandle, 00377 ValueName, 00378 0, 00379 Type, 00380 (PVOID)Data, 00381 (ULONG)Size); 00382 00383 free (Data); 00384 } 00385 00386 return TRUE; 00387 } 00388 00389 /*********************************************************************** 00390 * registry_callback 00391 * 00392 * Called once for each AddReg and DelReg entry in a given section. 00393 */ 00394 static BOOL 00395 registry_callback (HINF hInf, PWCHAR Section, BOOL Delete) 00396 { 00397 WCHAR Buffer[MAX_INF_STRING_LENGTH]; 00398 PWCHAR ValuePtr; 00399 ULONG Flags; 00400 size_t Length; 00401 00402 PINFCONTEXT Context = NULL; 00403 HKEY KeyHandle; 00404 BOOL Ok; 00405 00406 00407 Ok = InfHostFindFirstLine (hInf, Section, NULL, &Context) == 0; 00408 if (!Ok) 00409 return TRUE; /* Don't fail if the section isn't present */ 00410 00411 for (;Ok; Ok = (InfHostFindNextLine (Context, Context) == 0)) 00412 { 00413 /* get root */ 00414 if (InfHostGetStringField (Context, 1, Buffer, MAX_INF_STRING_LENGTH, NULL) != 0) 00415 continue; 00416 if (!GetRootKey (Buffer)) 00417 continue; 00418 00419 /* get key */ 00420 Length = strlenW (Buffer); 00421 if (InfHostGetStringField (Context, 2, Buffer + Length, MAX_INF_STRING_LENGTH - (ULONG)Length, NULL) != 0) 00422 *Buffer = 0; 00423 00424 DPRINT("KeyName: <%S>\n", Buffer); 00425 00426 if (Delete) 00427 { 00428 Flags = FLG_ADDREG_DELVAL; 00429 } 00430 else 00431 { 00432 /* get flags */ 00433 if (InfHostGetIntField (Context, 4, &Flags) != 0) 00434 Flags = 0; 00435 } 00436 00437 DPRINT("Flags: 0x%x\n", Flags); 00438 00439 if (Delete || (Flags & FLG_ADDREG_OVERWRITEONLY)) 00440 { 00441 if (RegOpenKeyW (NULL, Buffer, &KeyHandle) != ERROR_SUCCESS) 00442 { 00443 DPRINT("RegOpenKey(%S) failed\n", Buffer); 00444 continue; /* ignore if it doesn't exist */ 00445 } 00446 } 00447 else 00448 { 00449 if (RegCreateKeyW (NULL, Buffer, &KeyHandle) != ERROR_SUCCESS) 00450 { 00451 DPRINT("RegCreateKey(%S) failed\n", Buffer); 00452 continue; 00453 } 00454 } 00455 00456 /* get value name */ 00457 if (InfHostGetStringField (Context, 3, Buffer, MAX_INF_STRING_LENGTH, NULL) == 0) 00458 { 00459 ValuePtr = Buffer; 00460 } 00461 else 00462 { 00463 ValuePtr = NULL; 00464 } 00465 00466 /* and now do it */ 00467 if (!do_reg_operation (KeyHandle, ValuePtr, Context, Flags)) 00468 { 00469 return FALSE; 00470 } 00471 } 00472 00473 InfHostFreeContext(Context); 00474 00475 return TRUE; 00476 } 00477 00478 00479 BOOL 00480 ImportRegistryFile(PCHAR FileName) 00481 { 00482 HINF hInf; 00483 ULONG ErrorLine; 00484 00485 /* Load inf file from install media. */ 00486 if (InfHostOpenFile(&hInf, FileName, 0, &ErrorLine) != 0) 00487 { 00488 DPRINT1 ("InfHostOpenFile(%s) failed\n", FileName); 00489 return FALSE; 00490 } 00491 00492 if (!registry_callback (hInf, (PWCHAR)DelReg, TRUE)) 00493 { 00494 DPRINT1 ("registry_callback() for DelReg failed\n"); 00495 } 00496 00497 if (!registry_callback (hInf, (PWCHAR)AddReg, FALSE)) 00498 { 00499 DPRINT1 ("registry_callback() for AddReg failed\n"); 00500 } 00501 00502 InfHostCloseFile (hInf); 00503 00504 return TRUE; 00505 } 00506 00507 /* EOF */ Generated on Sun May 27 2012 04:37:46 for ReactOS by
1.7.6.1
|