Added 24/32 bit sample size and 4/6 channel support.
[wine] / programs / regedit / regedit.c
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include <ctype.h>
22 #include <stdio.h>
23 #include <windows.h>
24 #include "regproc.h"
25
26 static char *usage =
27     "Usage:\n"
28     "    regedit filename\n"
29     "    regedit /E filename [regpath]\n"
30     "    regedit /D regpath\n"
31     "\n"
32     "filename - registry file name\n"
33     "regpath - name of the registry key\n"
34     "\n"
35     "When is called without any switches adds contents of the specified\n"
36     "registry file to the registry\n"
37     "\n"
38     "Switches:\n"
39     "    /E - exports contents of the specified registry key to the specified\n"
40     "   file. Exports the whole registry if no key is specified.\n"
41     "    /D - deletes specified registry key\n"
42     "    /S - silent execution, can be used with any other switch.\n"
43     "   The only existing mode, exists for compatibility with Windows regedit.\n"
44     "    /V - advanced mode, can be used with any other switch.\n"
45     "   Ignored, exists for compatibility with Windows regedit.\n"
46     "    /L - location of system.dat file. Can be used with any other switch.\n"
47     "   Ignored. Exists for compatibility with Windows regedit.\n"
48     "    /R - location of user.dat file. Can be used with any other switch.\n"
49     "   Ignored. Exists for compatibility with Windows regedit.\n"
50     "    /? - print this help. Any other switches are ignored.\n"
51     "    /C - create registry from. Not implemented.\n"
52     "\n"
53     "The switches are case-insensitive, can be prefixed either by '-' or '/'.\n"
54     "This program is command-line compatible with Microsoft Windows\n"
55     "regedit. The difference with Windows regedit - this application has\n"
56     "command-line interface only.\n";
57
58 typedef enum {
59     ACTION_UNDEF, ACTION_ADD, ACTION_EXPORT, ACTION_DELETE
60 } REGEDIT_ACTION;
61
62 BOOL PerformRegAction(REGEDIT_ACTION action, LPSTR s);
63
64 /**
65  * Process unknown switch.
66  *
67  * Params:
68  *   chu - the switch character in upper-case.
69  *   s - the command line string where s points to the switch character.
70  */
71 void error_unknown_switch(char chu, char *s)
72 {
73     if (isalpha(chu)) {
74         fprintf(stderr,"%s: Undefined switch /%c!\n", getAppName(), chu);
75     } else {
76         fprintf(stderr,"%s: Alphabetic character is expected after '%c' "
77                 "in swit ch specification\n", getAppName(), *(s - 1));
78     }
79     exit(1);
80 }
81
82 BOOL ProcessCmdLine(LPSTR lpCmdLine)
83 {
84     REGEDIT_ACTION action = ACTION_UNDEF;
85     LPSTR s = lpCmdLine;        /* command line pointer */
86     CHAR ch = *s;               /* current character */
87
88     setAppName("regedit");
89     while (ch && ((ch == '-') || (ch == '/'))) {
90         char chu;
91         char ch2;
92
93         s++;
94         ch = *s;
95         ch2 = *(s+1);
96         chu = toupper(ch);
97         if (!ch2 || isspace(ch2)) {
98             if (chu == 'S' || chu == 'V') {
99                 /* ignore these switches */
100             } else {
101                 switch (chu) {
102                 case 'D':
103                     action = ACTION_DELETE;
104                     break;
105                 case 'E':
106                     action = ACTION_EXPORT;
107                     break;
108                 case '?':
109                     fprintf(stderr,usage);
110                     exit(0);
111                     break;
112                 default:
113                     error_unknown_switch(chu, s);
114                     break;
115                 }
116             }
117             s++;
118         } else {
119             if (ch2 == ':') {
120                 switch (chu) {
121                 case 'L':
122                     /* fall through */
123                 case 'R':
124                     s += 2;
125                     while (*s && !isspace(*s)) {
126                         s++;
127                     }
128                     break;
129                 default:
130                     error_unknown_switch(chu, s);
131                     break;
132                 }
133             } else {
134                 /* this is a file name, starting from '/' */
135                 s--;
136                 break;
137             }
138         }
139         /* skip spaces to the next parameter */
140         ch = *s;
141         while (ch && isspace(ch)) {
142             s++;
143             ch = *s;
144         }
145     }
146
147     if (*s && action == ACTION_UNDEF)
148         action = ACTION_ADD;
149
150     if (action == ACTION_UNDEF)
151         return FALSE;
152
153     return PerformRegAction(action, s);
154 }
155
156 BOOL PerformRegAction(REGEDIT_ACTION action, LPSTR s)
157 {
158     switch (action) {
159     case ACTION_ADD: {
160             CHAR filename[MAX_PATH];
161             FILE *reg_file;
162
163             get_file_name(&s, filename);
164             if (!filename[0]) {
165                 fprintf(stderr,"%s: No file name is specified\n", getAppName());
166                 fprintf(stderr,usage);
167                 exit(1);
168             }
169
170             while(filename[0]) {
171                 char* realname = NULL;
172                 int size;
173                 size=SearchPath(NULL,filename,NULL,0,NULL,NULL);
174                 if (size>0)
175                 {
176                     realname=HeapAlloc(GetProcessHeap(),0,size);
177                     size=SearchPath(NULL,filename,NULL,size,realname,NULL);
178                 }
179                 if (size==0)
180                 {
181                     fprintf(stderr,"%s: File not found \"%s\" (%ld)\n",
182                             getAppName(),filename,GetLastError());
183                     exit(1);
184                 }
185                 reg_file = fopen(realname, "r");
186                 if (reg_file==NULL)
187                 {
188                     perror("");
189                     fprintf(stderr,"%s: Can't open file \"%s\"\n", getAppName(), filename);
190                     exit(1);
191                 }
192                 processRegLines(reg_file, doSetValue);
193                 if (realname)
194                 {
195                     HeapFree(GetProcessHeap(),0,realname);
196                     fclose(reg_file);
197                 }
198                 get_file_name(&s, filename);
199             }
200             break;
201         }
202     case ACTION_DELETE: {
203             CHAR reg_key_name[KEY_MAX_LEN];
204
205             get_file_name(&s, reg_key_name);
206             if (!reg_key_name[0]) {
207                 fprintf(stderr,"%s: No registry key is specified for removal\n",
208                         getAppName());
209                 fprintf(stderr,usage);
210                 exit(1);
211             }
212             delete_registry_key(reg_key_name);
213             break;
214         }
215     case ACTION_EXPORT: {
216             CHAR filename[MAX_PATH];
217
218             filename[0] = '\0';
219             get_file_name(&s, filename);
220             if (!filename[0]) {
221                 fprintf(stderr,"%s: No file name is specified\n", getAppName());
222                 fprintf(stderr,usage);
223                 exit(1);
224             }
225
226             if (s[0]) {
227                 CHAR reg_key_name[KEY_MAX_LEN];
228
229                 get_file_name(&s, reg_key_name);
230                 export_registry_key(filename, reg_key_name);
231             } else {
232                 export_registry_key(filename, NULL);
233             }
234             break;
235         }
236     default:
237         fprintf(stderr,"%s: Unhandled action!\n", getAppName());
238         exit(1);
239         break;
240     }
241     return TRUE;
242 }