Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenreg.cGo 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,®_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
1.6.3
|