ReactOS  0.4.15-dev-1377-ga59cecd
regedit.c
Go to the documentation of this file.
1 /*
2  * Windows regedit.exe registry editor implementation.
3  *
4  * Copyright (C) 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 static const LPCWSTR usage =
24  L"Usage:\n"
25  L" regedit filenames\n"
26  L" regedit /E filename [regpath]\n"
27  L" regedit /D regpath\n"
28  L"\n"
29  L"filenames - List of registry files names\n"
30  L"filename - Registry file name\n"
31  L"regpath - Name of the registry key\n"
32  L"\n"
33  L"When is called without any switches adds contents of the specified\n"
34  L"registry files to the registry.\n"
35  L"\n"
36  L"Switches:\n"
37  L" /E - Exports contents of the specified registry key to the specified\n"
38  L" file. Exports the whole registry if no key is specified.\n"
39  L" /D - Deletes specified registry key\n"
40  L" /S - Silent execution, can be used with any other switch.\n"
41  L" The only existing mode, exists for compatibility with Windows regedit.\n"
42  L" /V - Advanced mode, can be used with any other switch.\n"
43  L" Ignored, exists for compatibility with Windows regedit.\n"
44  L" /L - Location of system.dat file. Can be used with any other switch.\n"
45  L" Ignored. Exists for compatibility with Windows regedit.\n"
46  L" /R - Location of user.dat file. Can be used with any other switch.\n"
47  L" Ignored. Exists for compatibility with Windows regedit.\n"
48  L" /? - Print this help. Any other switches are ignored.\n"
49  L" /C - Create registry from. Not implemented.\n"
50  L"\n"
51  L"The switches are case-insensitive, can be prefixed either by '-' or '/'.\n"
52  L"This program is command-line compatible with Microsoft Windows\n"
53  L"regedit.\n";
54 
55 typedef enum
56 {
59 
60 
62 {
63  return L"regedit";
64 }
65 
66 /******************************************************************************
67  * Copies file name from command line string to the buffer.
68  * Rewinds the command line string pointer to the next non-space character
69  * after the file name.
70  * Buffer contains an empty string if no filename was found;
71  *
72  * params:
73  * command_line - command line current position pointer
74  * where *s[0] is the first symbol of the file name.
75  * file_name - buffer to write the file name to.
76  */
77 void get_file_name(LPWSTR *command_line, LPWSTR file_name)
78 {
79  WCHAR *s = *command_line;
80  size_t pos = 0; /* position of pointer "s" in *command_line */
81  file_name[0] = 0;
82 
83  if (!s[0])
84  {
85  return;
86  }
87 
88  if (s[0] == L'"')
89  {
90  s++;
91  (*command_line)++;
92  while(s[0] != L'"')
93  {
94  if (!s[0])
95  {
96  fwprintf(stderr, L"%s: Unexpected end of file name!\n", getAppName());
97  exit(1);
98  }
99  s++;
100  pos++;
101  }
102  }
103  else
104  {
105  while(s[0] && !iswspace(s[0]))
106  {
107  s++;
108  pos++;
109  }
110  }
111  memcpy(file_name, *command_line, pos * sizeof(WCHAR));
112  /* remove the last backslash */
113  if (file_name[pos - 1] == L'\\')
114  {
115  file_name[pos - 1] = L'\0';
116  }
117  else
118  {
119  file_name[pos] = L'\0';
120  }
121 
122  if (s[0])
123  {
124  s++;
125  pos++;
126  }
127  while(s[0] && iswspace(s[0]))
128  {
129  s++;
130  pos++;
131  }
132  (*command_line) += pos;
133 }
134 
136 {
137  switch (action)
138  {
139  case ACTION_ADD:
140  {
141  WCHAR szText[512];
143  LPWSTR command_line = s;
144  UINT count = 0, mbType = MB_YESNO;
145  FILE *fp;
146 
147  get_file_name(&command_line, filename);
148  while (filename[0])
149  {
150  count++;
151  get_file_name(&command_line, filename);
152  }
153 
154  if (count == 0)
155  {
156  InfoMessageBox(NULL, MB_OK | MB_ICONINFORMATION, NULL, L"No file name is specified.");
158  exit(4);
159  }
160 
161  if (count > 1)
162  {
163  /* Enable three buttons if we have more than one file */
164  mbType = MB_YESNOCANCEL;
165  }
166 
168  while (filename[0])
169  {
170  /* Request import confirmation */
171  if (!silent)
172  {
173  int choice;
174 
176 
177  choice = InfoMessageBox(NULL, mbType | MB_ICONQUESTION, szTitle, szText, filename);
178 
179  switch (choice)
180  {
181  case IDNO:
182  goto cont;
183  case IDCANCEL:
184  /* The cancel case is useful if the user is importing more than one registry file
185  at a time, and wants to back out anytime during the import process. This way, the
186  user doesn't have to resort to ending the regedit process abruptly just to cancel
187  the operation. */
188  return TRUE;
189  default:
190  break;
191  }
192  }
193 
194  /* Open the file */
195  fp = _wfopen(filename, L"r");
196 
197  /* Import it */
198  if (fp == NULL || !import_registry_file(fp))
199  {
200  /* Error opening the file */
201  if (!silent)
202  {
205  }
206  }
207  else
208  {
209  /* Show successful import */
210  if (!silent)
211  {
214  }
215  }
216 
217  /* Close the file */
218  if (fp) fclose(fp);
219 
220 cont:
222  }
223  break;
224  }
225 
226  case ACTION_DELETE:
227  {
228  WCHAR reg_key_name[KEY_MAX_LEN];
229  get_file_name(&s, reg_key_name);
230  if (!reg_key_name[0])
231  {
232  InfoMessageBox(NULL, MB_OK | MB_ICONINFORMATION, NULL, L"No registry key is specified for removal.");
234  exit(6);
235  }
236  delete_registry_key(reg_key_name);
237  break;
238  }
239 
240  case ACTION_EXPORT:
241  {
243 
244  filename[0] = L'\0';
246  if (!filename[0])
247  {
248  InfoMessageBox(NULL, MB_OK | MB_ICONINFORMATION, NULL, L"No file name is specified.");
250  exit(7);
251  }
252 
253  if (s[0])
254  {
255  WCHAR reg_key_name[KEY_MAX_LEN];
256  get_file_name(&s, reg_key_name);
257  export_registry_key(filename, reg_key_name, REG_FORMAT_4);
258  }
259  else
260  {
262  }
263  break;
264  }
265 
266  default:
267  fwprintf(stderr, L"%s: Unhandled action!\n", getAppName());
268  exit(8);
269  break;
270  }
271 
272  return TRUE;
273 }
274 
283 {
284  if (iswalpha(chu))
285  {
286  fwprintf(stderr, L"%s: Undefined switch /%c!\n", getAppName(), chu);
287  }
288  else
289  {
290  fwprintf(stderr, L"%s: Alphabetic character is expected after '%c' "
291  L"in switch specification\n", getAppName(), *(s - 1));
292  }
293  exit(1);
294 }
295 
297 {
298  BOOL silent = FALSE;
300  LPWSTR s = lpCmdLine; /* command line pointer */
301  WCHAR ch = *s; /* current character */
302 
303  while (ch && ((ch == L'-') || (ch == L'/')))
304  {
305  WCHAR chu;
306  WCHAR ch2;
307 
308  s++;
309  ch = *s;
310  ch2 = *(s + 1);
311  chu = towupper(ch);
312  if (!ch2 || iswspace(ch2))
313  {
314  if (chu == L'S')
315  {
316  /* Silence dialogs */
317  silent = TRUE;
318  }
319  else if (chu == L'V')
320  {
321  /* Ignore this switch */
322  }
323  else
324  {
325  switch (chu)
326  {
327  case L'D':
329  break;
330  case L'E':
332  break;
333  case L'?':
335  exit(3);
336  break;
337  default:
338  error_unknown_switch(chu, s);
339  break;
340  }
341  }
342  s++;
343  }
344  else
345  {
346  if (ch2 == L':')
347  {
348  switch (chu)
349  {
350  case L'L':
351  /* fall through */
352  case L'R':
353  s += 2;
354  while (*s && !iswspace(*s))
355  {
356  s++;
357  }
358  break;
359  default:
360  error_unknown_switch(chu, s);
361  break;
362  }
363  }
364  else
365  {
366  /* this is a file name, starting from '/' */
367  s--;
368  break;
369  }
370  }
371  /* skip spaces to the next parameter */
372  ch = *s;
373  while (ch && iswspace(ch))
374  {
375  s++;
376  ch = *s;
377  }
378  }
379 
380  if (*s && action == ACTION_UNDEF)
381  action = ACTION_ADD;
382 
383  if (action != ACTION_UNDEF)
384  return PerformRegAction(action, s, silent);
385  else
386  return FALSE;
387 }
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
_Check_return_ _CRTIMP FILE *__cdecl _wfopen(_In_z_ const wchar_t *_Filename, _In_z_ const wchar_t *_Mode)
#define TRUE
Definition: types.h:120
GLuint GLuint GLsizei count
Definition: gl.h:1545
#define iswalpha(_c)
Definition: ctype.h:664
int InfoMessageBox(HWND hWnd, UINT uType, LPCWSTR lpTitle, LPCWSTR lpMessage,...)
Definition: error.c:51
const char * filename
Definition: ioapi.h:135
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)
#define KEY_MAX_LEN
Definition: regproc.h:22
#define FALSE
Definition: types.h:117
#define MB_YESNO
Definition: winuser.h:811
static const WCHAR szText[]
Definition: dialog.c:139
void get_file_name(LPWSTR *command_line, LPWSTR file_name)
Definition: regedit.c:77
unsigned int BOOL
Definition: ntddk_ex.h:94
_Check_return_opt_ _CRTIMP int __cdecl fwprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const wchar_t *_Format,...)
#define MB_ICONQUESTION
Definition: winuser.h:783
#define MB_YESNOCANCEL
Definition: winuser.h:812
#define IDS_IMPORT_PROMPT
Definition: resource.h:196
#define COUNT_OF(a)
Definition: main.h:33
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define MAX_PATH
Definition: compat.h:34
TCHAR szTitle[MAX_LOADSTRING]
Definition: magnifier.c:35
#define iswspace(_c)
Definition: ctype.h:669
#define MB_ICONINFORMATION
Definition: winuser.h:796
BOOL PerformRegAction(REGEDIT_ACTION action, LPWSTR s, BOOL silent)
Definition: regedit.c:135
static const WCHAR L[]
Definition: oid.c:1250
#define MB_ICONERROR
Definition: winuser.h:781
GLsizeiptr const GLvoid GLenum usage
Definition: glext.h:5919
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLdouble s
Definition: gl.h:2039
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
#define IDS_IMPORT_ERROR
Definition: resource.h:198
REGEDIT_ACTION
Definition: regedit.c:55
BOOL ProcessCmdLine(LPWSTR lpCmdLine)
Definition: regedit.c:296
HINSTANCE hInst
Definition: dxdiag.c:13
const WCHAR * action
Definition: action.c:7783
#define REG_FORMAT_4
Definition: regproc.h:25
#define IDS_IMPORT_OK
Definition: resource.h:197
LPCWSTR getAppName(void)
Definition: regedit.c:61
unsigned int UINT
Definition: ndis.h:50
#define NULL
Definition: types.h:112
#define MB_OK
Definition: winuser.h:784
BOOL export_registry_key(WCHAR *file_name, WCHAR *reg_key_name, DWORD format)
Definition: regproc.c:1310
static LPCWSTR file_name
Definition: protocol.c:147
static void error_unknown_switch(WCHAR chu, LPWSTR s)
Definition: regedit.c:282
FILE * stderr
BOOL import_registry_file(FILE *reg_file)
Definition: regproc.c:1405
#define towupper(c)
Definition: wctype.h:99
#define IDNO
Definition: winuser.h:830
void exit(int exitcode)
Definition: _exit.c:33
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define IDCANCEL
Definition: winuser.h:825
void delete_registry_key(WCHAR *reg_key_name)
Definition: regproc.c:1432