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

  1. Home
  2. Community
  3. Development
  4. myReactOS

  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

reg.c

Go to the documentation of this file.
00001 /*
00002  * Copyright 2008 Andrew Riedi
00003  *
00004  * This library is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Lesser General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2.1 of the License, or (at your option) any later version.
00008  *
00009  * This library is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * Lesser General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Lesser General Public
00015  * License along with this library; if not, write to the Free Software
00016  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00017  */
00018 
00019 #include <windows.h>
00020 #include <wine/unicode.h>
00021 #include "reg.h"
00022 
00023 static int reg_printfW(const WCHAR *msg, ...)
00024 {
00025     va_list va_args;
00026     int wlen;
00027     DWORD count, ret;
00028     WCHAR msg_buffer[8192];
00029 
00030     va_start(va_args, msg);
00031     vsprintfW(msg_buffer, msg, va_args);
00032     va_end(va_args);
00033 
00034     wlen = lstrlenW(msg_buffer);
00035     ret = WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), msg_buffer, wlen, &count, NULL);
00036     if (!ret)
00037     {
00038         DWORD len;
00039         char  *msgA;
00040 
00041         len = WideCharToMultiByte(GetConsoleOutputCP(), 0, msg_buffer, wlen,
00042             NULL, 0, NULL, NULL);
00043         msgA = HeapAlloc(GetProcessHeap(), 0, len * sizeof(char));
00044         if (!msgA)
00045             return 0;
00046 
00047         WideCharToMultiByte(GetConsoleOutputCP(), 0, msg_buffer, wlen, msgA, len,
00048             NULL, NULL);
00049         WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), msgA, len, &count, FALSE);
00050         HeapFree(GetProcessHeap(), 0, msgA);
00051     }
00052 
00053     return count;
00054 }
00055 
00056 static int reg_message(int msg)
00057 {
00058     static const WCHAR formatW[] = {'%','s',0};
00059     WCHAR msg_buffer[8192];
00060 
00061     LoadStringW(GetModuleHandleW(NULL), msg, msg_buffer,
00062         sizeof(msg_buffer)/sizeof(WCHAR));
00063     return reg_printfW(formatW, msg_buffer);
00064 }
00065 
00066 static HKEY get_rootkey(LPWSTR key)
00067 {
00068     static const WCHAR szHKLM[] = {'H','K','L','M',0};
00069     static const WCHAR szHKCU[] = {'H','K','C','U',0};
00070     static const WCHAR szHKCR[] = {'H','K','C','R',0};
00071     static const WCHAR szHKU[] = {'H','K','U',0};
00072     static const WCHAR szHKCC[] = {'H','K','C','C',0};
00073 
00074     if (CompareStringW(CP_ACP,NORM_IGNORECASE,key,4,szHKLM,4)==2)
00075         return HKEY_LOCAL_MACHINE;
00076     else if (CompareStringW(CP_ACP,NORM_IGNORECASE,key,4,szHKCU,4)==2)
00077         return HKEY_CURRENT_USER;
00078     else if (CompareStringW(CP_ACP,NORM_IGNORECASE,key,4,szHKCR,4)==2)
00079         return HKEY_CLASSES_ROOT;
00080     else if (CompareStringW(CP_ACP,NORM_IGNORECASE,key,3,szHKU,3)==2)
00081         return HKEY_USERS;
00082     else if (CompareStringW(CP_ACP,NORM_IGNORECASE,key,4,szHKCC,4)==2)
00083         return HKEY_CURRENT_CONFIG;
00084     else return NULL;
00085 }
00086 
00087 static DWORD get_regtype(LPWSTR type)
00088 {
00089     static const WCHAR szREG_SZ[] = {'R','E','G','_','S','Z',0};
00090     static const WCHAR szREG_MULTI_SZ[] = {'R','E','G','_','M','U','L','T','I','_','S','Z',0};
00091     static const WCHAR szREG_DWORD_BIG_ENDIAN[] = {'R','E','G','_','D','W','O','R','D','_','B','I','G','_','E','N','D','I','A','N',0};
00092     static const WCHAR szREG_DWORD[] = {'R','E','G','_','D','W','O','R','D',0};
00093     static const WCHAR szREG_BINARY[] = {'R','E','G','_','B','I','N','A','R','Y',0};
00094     static const WCHAR szREG_DWORD_LITTLE_ENDIAN[] = {'R','E','G','_','D','W','O','R','D','_','L','I','T','T','L','E','_','E','N','D','I','A','N',0};
00095     static const WCHAR szREG_NONE[] = {'R','E','G','_','N','O','N','E',0};
00096     static const WCHAR szREG_EXPAND_SZ[] = {'R','E','G','_','E','X','P','A','N','D','_','S','Z',0};
00097 
00098     if (!type)
00099         return REG_SZ;
00100 
00101     if (lstrcmpiW(type,szREG_SZ)==0) return REG_SZ;
00102     if (lstrcmpiW(type,szREG_DWORD)==0) return REG_DWORD;
00103     if (lstrcmpiW(type,szREG_MULTI_SZ)==0) return REG_MULTI_SZ;
00104     if (lstrcmpiW(type,szREG_EXPAND_SZ)==0) return REG_EXPAND_SZ;
00105     if (lstrcmpiW(type,szREG_DWORD_BIG_ENDIAN)==0) return REG_DWORD_BIG_ENDIAN;
00106     if (lstrcmpiW(type,szREG_DWORD_LITTLE_ENDIAN)==0) return REG_DWORD_LITTLE_ENDIAN;
00107     if (lstrcmpiW(type,szREG_BINARY)==0) return REG_BINARY;
00108     if (lstrcmpiW(type,szREG_NONE)==0) return REG_NONE;
00109 
00110     return -1;
00111 }
00112 
00113 static LPBYTE get_regdata(LPWSTR data, DWORD reg_type, WCHAR separator, DWORD *reg_count)
00114 {
00115     LPBYTE out_data = NULL;
00116     *reg_count = 0;
00117 
00118     switch (reg_type)
00119     {
00120         case REG_SZ:
00121         {
00122             *reg_count = (lstrlenW(data) + 1) * sizeof(WCHAR);
00123             out_data = HeapAlloc(GetProcessHeap(),0,*reg_count);
00124             lstrcpyW((LPWSTR)out_data,data);
00125             break;
00126         }
00127         case REG_DWORD:
00128         {
00129             LPWSTR rest;
00130             DWORD val;
00131             val = strtolW(data, &rest, 0);
00132             if (rest == data) {
00133                 static const WCHAR nonnumber[] = {'E','r','r','o','r',':',' ','/','d',' ','r','e','q','u','i','r','e','s',' ','n','u','m','b','e','r','.','\n',0};
00134                 reg_printfW(nonnumber);
00135                 break;
00136             }
00137             *reg_count = sizeof(DWORD);
00138             out_data = HeapAlloc(GetProcessHeap(),0,*reg_count);
00139             ((LPDWORD)out_data)[0] = val;
00140             break;
00141         }
00142         default:
00143         {
00144             static const WCHAR unhandled[] = {'U','n','h','a','n','d','l','e','d',' ','T','y','p','e',' ','0','x','%','x',' ',' ','d','a','t','a',' ','%','s','\n',0};
00145             reg_printfW(unhandled, reg_type,data);
00146         }
00147     }
00148 
00149     return out_data;
00150 }
00151 
00152 static int reg_add(WCHAR *key_name, WCHAR *value_name, BOOL value_empty,
00153     WCHAR *type, WCHAR separator, WCHAR *data, BOOL force)
00154 {
00155     static const WCHAR stubW[] = {'A','D','D',' ','-',' ','%','s',
00156         ' ','%','s',' ','%','d',' ','%','s',' ','%','s',' ','%','d','\n',0};
00157     LPWSTR p;
00158     HKEY root,subkey;
00159 
00160     reg_printfW(stubW, key_name, value_name, value_empty, type, data, force);
00161 
00162     if (key_name[0]=='\\' && key_name[1]=='\\')
00163     {
00164         reg_message(STRING_NO_REMOTE);
00165         return 1;
00166     }
00167 
00168     p = strchrW(key_name,'\\');
00169     if (!p)
00170     {
00171         reg_message(STRING_INVALID_KEY);
00172         return 1;
00173     }
00174     p++;
00175 
00176     root = get_rootkey(key_name);
00177     if (!root)
00178     {
00179         reg_message(STRING_INVALID_KEY);
00180         return 1;
00181     }
00182 
00183     if(RegCreateKeyW(root,p,&subkey)!=ERROR_SUCCESS)
00184     {
00185         reg_message(STRING_INVALID_KEY);
00186         return 1;
00187     }
00188 
00189     if (value_name || data)
00190     {
00191         DWORD reg_type;
00192         DWORD reg_count = 0;
00193         BYTE* reg_data = NULL;
00194 
00195         if (!force)
00196         {
00197             if (RegQueryValueW(subkey,value_name,NULL,NULL)==ERROR_SUCCESS)
00198             {
00199                 /* FIXME:  Prompt for overwrite */
00200             }
00201         }
00202 
00203         reg_type = get_regtype(type);
00204         if (reg_type == -1)
00205         {
00206             RegCloseKey(subkey);
00207             reg_message(STRING_INVALID_CMDLINE);
00208             return 1;
00209         }
00210 
00211         if (data)
00212             reg_data = get_regdata(data,reg_type,separator,&reg_count);
00213 
00214         RegSetValueExW(subkey,value_name,0,reg_type,reg_data,reg_count);
00215         HeapFree(GetProcessHeap(),0,reg_data);
00216     }
00217 
00218     RegCloseKey(subkey);
00219     reg_message(STRING_SUCCESS);
00220 
00221     return 0;
00222 }
00223 
00224 static int reg_delete(WCHAR *key_name, WCHAR *value_name, BOOL value_empty,
00225     BOOL value_all, BOOL force)
00226 {
00227     LPWSTR p;
00228     HKEY root,subkey;
00229 
00230     static const WCHAR stubW[] = {'D','E','L','E','T','E',
00231         ' ','-',' ','%','s',' ','%','s',' ','%','d',' ','%','d',' ','%','d','\n'
00232         ,0};
00233     reg_printfW(stubW, key_name, value_name, value_empty, value_all, force);
00234 
00235     if (key_name[0]=='\\' && key_name[1]=='\\')
00236     {
00237         reg_message(STRING_NO_REMOTE);
00238         return 1;
00239     }
00240 
00241     p = strchrW(key_name,'\\');
00242     if (!p)
00243     {
00244         reg_message(STRING_INVALID_KEY);
00245         return 1;
00246     }
00247     p++;
00248 
00249     root = get_rootkey(key_name);
00250     if (!root)
00251     {
00252         reg_message(STRING_INVALID_KEY);
00253         return 1;
00254     }
00255 
00256     if (value_name && value_empty)
00257     {
00258         reg_message(STRING_INVALID_CMDLINE);
00259         return 1;
00260     }
00261 
00262     if (value_empty && value_all)
00263     {
00264         reg_message(STRING_INVALID_CMDLINE);
00265         return 1;
00266     }
00267 
00268     if (!force)
00269     {
00270         /* FIXME:  Prompt for delete */
00271     }
00272 
00273     /* Delete subtree only if no /v* option is given */
00274     if (!value_name && !value_empty && !value_all)
00275     {
00276         if (RegDeleteTreeW(root,p)!=ERROR_SUCCESS)
00277         {
00278             reg_message(STRING_CANNOT_FIND);
00279             return 1;
00280         }
00281         reg_message(STRING_SUCCESS);
00282         return 0;
00283     }
00284 
00285     if(RegOpenKeyW(root,p,&subkey)!=ERROR_SUCCESS)
00286     {
00287         reg_message(STRING_CANNOT_FIND);
00288         return 1;
00289     }
00290 
00291     if (value_all)
00292     {
00293         LPWSTR szValue;
00294         DWORD maxValue;
00295         DWORD count;
00296         LONG rc;
00297 
00298         rc = RegQueryInfoKeyW(subkey, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
00299             &maxValue, NULL, NULL, NULL);
00300         if (rc != ERROR_SUCCESS)
00301         {
00302             /* FIXME: failure */
00303             RegCloseKey(subkey);
00304             return 1;
00305         }
00306         maxValue++;
00307         szValue = HeapAlloc(GetProcessHeap(),0,maxValue*sizeof(WCHAR));
00308 
00309         while (1)
00310         {
00311             count = maxValue;
00312             rc = RegEnumValueW(subkey, 0, szValue, &count, NULL, NULL, NULL, NULL);
00313             if (rc == ERROR_SUCCESS)
00314             {
00315                 rc = RegDeleteValueW(subkey, szValue);
00316                 if (rc != ERROR_SUCCESS)
00317                     break;
00318             }
00319             else break;
00320         }
00321         if (rc != ERROR_SUCCESS)
00322         {
00323             /* FIXME  delete failed */
00324         }
00325     }
00326     else if (value_name)
00327     {
00328         if (RegDeleteValueW(subkey,value_name) != ERROR_SUCCESS)
00329         {
00330             RegCloseKey(subkey);
00331             reg_message(STRING_CANNOT_FIND);
00332             return 1;
00333         }
00334     }
00335     else if (value_empty)
00336     {
00337         RegSetValueExW(subkey,NULL,0,REG_SZ,NULL,0);
00338     }
00339 
00340     RegCloseKey(subkey);
00341     reg_message(STRING_SUCCESS);
00342     return 0;
00343 }
00344 
00345 static int reg_query(WCHAR *key_name, WCHAR *value_name, BOOL value_empty,
00346     BOOL subkey)
00347 {
00348     static const WCHAR stubW[] = {'S','T','U','B',' ','Q','U','E','R','Y',' ',
00349         '-',' ','%','s',' ','%','s',' ','%','d',' ','%','d','\n',0};
00350     reg_printfW(stubW, key_name, value_name, value_empty, subkey);
00351 
00352     return 1;
00353 }
00354 
00355 int wmain(int argc, WCHAR *argvW[])
00356 {
00357     int i;
00358 
00359     static const WCHAR addW[] = {'a','d','d',0};
00360     static const WCHAR deleteW[] = {'d','e','l','e','t','e',0};
00361     static const WCHAR queryW[] = {'q','u','e','r','y',0};
00362     static const WCHAR slashDW[] = {'/','d',0};
00363     static const WCHAR slashFW[] = {'/','f',0};
00364     static const WCHAR slashHW[] = {'/','h',0};
00365     static const WCHAR slashSW[] = {'/','s',0};
00366     static const WCHAR slashTW[] = {'/','t',0};
00367     static const WCHAR slashVW[] = {'/','v',0};
00368     static const WCHAR slashVAW[] = {'/','v','a',0};
00369     static const WCHAR slashVEW[] = {'/','v','e',0};
00370     static const WCHAR slashHelpW[] = {'/','?',0};
00371 
00372     if (argc < 2 || !lstrcmpW(argvW[1], slashHelpW)
00373                  || !lstrcmpiW(argvW[1], slashHW))
00374     {
00375         reg_message(STRING_USAGE);
00376         return 0;
00377     }
00378 
00379     if (!lstrcmpiW(argvW[1], addW))
00380     {
00381         WCHAR *key_name, *value_name = NULL, *type = NULL, separator = '\0', *data = NULL;
00382         BOOL value_empty = FALSE, force = FALSE;
00383 
00384         if (argc < 3)
00385         {
00386             reg_message(STRING_INVALID_CMDLINE);
00387             return 1;
00388         }
00389         else if (argc == 3 && (!lstrcmpW(argvW[2], slashHelpW) ||
00390                                !lstrcmpiW(argvW[2], slashHW)))
00391         {
00392             reg_message(STRING_ADD_USAGE);
00393             return 0;
00394         }
00395 
00396         key_name = argvW[2];
00397         for (i = 1; i < argc; i++)
00398         {
00399             if (!lstrcmpiW(argvW[i], slashVW))
00400                 value_name = argvW[++i];
00401             else if (!lstrcmpiW(argvW[i], slashVEW))
00402                 value_empty = TRUE;
00403             else if (!lstrcmpiW(argvW[i], slashTW))
00404                 type = argvW[++i];
00405             else if (!lstrcmpiW(argvW[i], slashSW))
00406                 separator = argvW[++i][0];
00407             else if (!lstrcmpiW(argvW[i], slashDW))
00408                 data = argvW[++i];
00409             else if (!lstrcmpiW(argvW[i], slashFW))
00410                 force = TRUE;
00411         }
00412         return reg_add(key_name, value_name, value_empty, type, separator,
00413             data, force);
00414     }
00415     else if (!lstrcmpiW(argvW[1], deleteW))
00416     {
00417         WCHAR *key_name, *value_name = NULL;
00418         BOOL value_empty = FALSE, value_all = FALSE, force = FALSE;
00419 
00420         if (argc < 3)
00421         {
00422             reg_message(STRING_INVALID_CMDLINE);
00423             return 1;
00424         }
00425         else if (argc == 3 && (!lstrcmpW(argvW[2], slashHelpW) ||
00426                                !lstrcmpiW(argvW[2], slashHW)))
00427         {
00428             reg_message(STRING_DELETE_USAGE);
00429             return 0;
00430         }
00431 
00432         key_name = argvW[2];
00433         for (i = 1; i < argc; i++)
00434         {
00435             if (!lstrcmpiW(argvW[i], slashVW))
00436                 value_name = argvW[++i];
00437             else if (!lstrcmpiW(argvW[i], slashVEW))
00438                 value_empty = TRUE;
00439             else if (!lstrcmpiW(argvW[i], slashVAW))
00440                 value_all = TRUE;
00441             else if (!lstrcmpiW(argvW[i], slashFW))
00442                 force = TRUE;
00443         }
00444         return reg_delete(key_name, value_name, value_empty, value_all, force);
00445     }
00446     else if (!lstrcmpiW(argvW[1], queryW))
00447     {
00448         WCHAR *key_name, *value_name = NULL;
00449         BOOL value_empty = FALSE, subkey = FALSE;
00450 
00451         if (argc < 3)
00452         {
00453             reg_message(STRING_INVALID_CMDLINE);
00454             return 1;
00455         }
00456         else if (argc == 3 && (!lstrcmpW(argvW[2], slashHelpW) ||
00457                                !lstrcmpiW(argvW[2], slashHW)))
00458         {
00459             reg_message(STRING_QUERY_USAGE);
00460             return 0;
00461         }
00462 
00463         key_name = argvW[2];
00464         for (i = 1; i < argc; i++)
00465         {
00466             if (!lstrcmpiW(argvW[i], slashVW))
00467                 value_name = argvW[++i];
00468             else if (!lstrcmpiW(argvW[i], slashVEW))
00469                 value_empty = TRUE;
00470             else if (!lstrcmpiW(argvW[i], slashSW))
00471                 subkey = TRUE;
00472         }
00473         return reg_query(key_name, value_name, value_empty, subkey);
00474     }
00475     else
00476     {
00477         reg_message(STRING_INVALID_CMDLINE);
00478         return 1;
00479     }
00480 }

Generated on Thu Feb 9 04:39:01 2012 for ReactOS by doxygen 1.6.3

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