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