ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

reginf.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.