1 /* 2 * Windows regedit.exe registry editor implementation. 3 * 4 * Copyright 2002 Andriy Palamarchuk 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 */ 20 21 #include <regedit.h> 22 23 24 static const char *usage = 25 "Usage:\n" 26 " regedit filename\n" 27 " regedit /E filename [regpath]\n" 28 " regedit /D regpath\n" 29 "\n" 30 "filename - registry file name\n" 31 "regpath - name of the registry key\n" 32 "\n" 33 "When is called without any switches adds contents of the specified\n" 34 "registry file to the registry\n" 35 "\n" 36 "Switches:\n" 37 " /E - exports contents of the specified registry key to the specified\n" 38 " file. Exports the whole registry if no key is specified.\n" 39 " /D - deletes specified registry key\n" 40 " /S - silent execution, can be used with any other switch.\n" 41 " The only existing mode, exists for compatibility with Windows regedit.\n" 42 " /V - advanced mode, can be used with any other switch.\n" 43 " Ignored, exists for compatibility with Windows regedit.\n" 44 " /L - location of system.dat file. Can be used with any other switch.\n" 45 " Ignored. Exists for compatibility with Windows regedit.\n" 46 " /R - location of user.dat file. Can be used with any other switch.\n" 47 " Ignored. Exists for compatibility with Windows regedit.\n" 48 " /? - print this help. Any other switches are ignored.\n" 49 " /C - create registry from. Not implemented.\n" 50 "\n" 51 "The switches are case-insensitive, can be prefixed either by '-' or '/'.\n" 52 "This program is command-line compatible with Microsoft Windows\n" 53 "regedit.\n"; 54 55 typedef enum { 56 ACTION_UNDEF, ACTION_ADD, ACTION_EXPORT, ACTION_DELETE 57 } REGEDIT_ACTION; 58 59 BOOL PerformRegAction(REGEDIT_ACTION action, LPSTR s); 60 61 /** 62 * Process unknown switch. 63 * 64 * Params: 65 * chu - the switch character in upper-case. 66 * s - the command line string where s points to the switch character. 67 */ 68 static void error_unknown_switch(char chu, char *s) 69 { 70 if (isalpha(chu)) { 71 fprintf(stderr,"%s: Undefined switch /%c!\n", getAppName(), chu); 72 } else { 73 fprintf(stderr,"%s: Alphabetic character is expected after '%c' " 74 "in swit ch specification\n", getAppName(), *(s - 1)); 75 } 76 exit(1); 77 } 78 79 BOOL ProcessCmdLine(LPSTR lpCmdLine) 80 { 81 REGEDIT_ACTION action = ACTION_UNDEF; 82 LPSTR s = lpCmdLine; /* command line pointer */ 83 CHAR ch = *s; /* current character */ 84 85 setAppName("regedit"); 86 while (ch && ((ch == '-') || (ch == '/'))) { 87 char chu; 88 char ch2; 89 90 s++; 91 ch = *s; 92 ch2 = *(s+1); 93 chu = (CHAR) toupper(ch); 94 if (!ch2 || isspace(ch2)) { 95 if (chu == 'S' || chu == 'V') { 96 /* ignore these switches */ 97 } else { 98 switch (chu) { 99 case 'D': 100 action = ACTION_DELETE; 101 break; 102 case 'E': 103 action = ACTION_EXPORT; 104 break; 105 case '?': 106 fprintf(stderr,usage); 107 exit(0); 108 break; 109 default: 110 error_unknown_switch(chu, s); 111 break; 112 } 113 } 114 s++; 115 } else { 116 if (ch2 == ':') { 117 switch (chu) { 118 case 'L': 119 /* fall through */ 120 case 'R': 121 s += 2; 122 while (*s && !isspace(*s)) { 123 s++; 124 } 125 break; 126 default: 127 error_unknown_switch(chu, s); 128 break; 129 } 130 } else { 131 /* this is a file name, starting from '/' */ 132 s--; 133 break; 134 } 135 } 136 /* skip spaces to the next parameter */ 137 ch = *s; 138 while (ch && isspace(ch)) { 139 s++; 140 ch = *s; 141 } 142 } 143 144 if (*s && action == ACTION_UNDEF) 145 action = ACTION_ADD; 146 147 if (action == ACTION_UNDEF) 148 return FALSE; 149 150 return PerformRegAction(action, s); 151 } 152 153 BOOL PerformRegAction(REGEDIT_ACTION action, LPSTR s) 154 { 155 switch (action) { 156 case ACTION_ADD: { 157 CHAR filename[MAX_PATH]; 158 FILE *reg_file; 159 160 get_file_name(&s, filename); 161 if (!filename[0]) { 162 fprintf(stderr,"%s: No file name is specified\n", getAppName()); 163 fprintf(stderr,usage); 164 exit(1); 165 } 166 167 while(filename[0]) { 168 reg_file = fopen(filename, "r"); 169 if (reg_file) { 170 processRegLines(reg_file, doSetValue); 171 fclose(reg_file); 172 } else { 173 perror(""); 174 fprintf(stderr,"%s: Can't open file \"%s\"\n", getAppName(), filename); 175 exit(1); 176 } 177 get_file_name(&s, filename); 178 } 179 break; 180 } 181 case ACTION_DELETE: { 182 CHAR reg_key_name[KEY_MAX_LEN]; 183 184 get_file_name(&s, reg_key_name); 185 if (!reg_key_name[0]) { 186 fprintf(stderr,"%s: No registry key is specified for removal\n", 187 getAppName()); 188 fprintf(stderr,usage); 189 exit(1); 190 } 191 delete_registry_key(reg_key_name); 192 break; 193 } 194 case ACTION_EXPORT: { 195 CHAR filename[MAX_PATH]; 196 LPCTSTR pszFilename; 197 #ifdef UNICODE 198 WCHAR filename_wide[MAX_PATH]; 199 #endif 200 201 filename[0] = '\0'; 202 get_file_name(&s, filename); 203 if (!filename[0]) { 204 fprintf(stderr,"%s: No file name is specified\n", getAppName()); 205 fprintf(stderr,usage); 206 exit(1); 207 } 208 209 #ifdef UNICODE 210 MultiByteToWideChar(CP_ACP, 0, filename, -1, filename_wide, 211 sizeof(filename_wide) / sizeof(filename_wide[0])); 212 pszFilename = filename_wide; 213 #else 214 pszFilename = filename; 215 #endif 216 217 if (s[0]) { 218 CHAR reg_key_name[KEY_MAX_LEN]; 219 220 get_file_name(&s, reg_key_name); 221 export_registry_key(pszFilename, reg_key_name); 222 } else { 223 export_registry_key(pszFilename, NULL); 224 } 225 break; 226 } 227 default: 228 fprintf(stderr,"%s: Unhandled action!\n", getAppName()); 229 exit(1); 230 break; 231 } 232 return TRUE; 233 } 234