ReactOS 0.4.15-dev-5865-g640e228
regedit.c
Go to the documentation of this file.
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 St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21#ifndef __REACTOS__
22#include <stdlib.h>
23#include <windows.h>
24#include <commctrl.h>
25#include <shellapi.h>
26
27#include "wine/debug.h"
28#include "main.h"
29#else
30#include "regedit.h"
31#endif
32
34
35static void output_writeconsole(const WCHAR *str, DWORD wlen)
36{
37#ifdef __REACTOS__
38 /* This is win32gui application, don't ever try writing to console.
39 * For the console version we have a separate reg.exe application. */
40 WCHAR AppStr[255];
41 LoadStringW(hInst, IDS_APP_TITLE, AppStr, ARRAY_SIZE(AppStr));
43#else
45
47 {
48 DWORD len;
49 char *msgA;
50
51 /* WriteConsole() fails on Windows if its output is redirected. If this occurs,
52 * we should call WriteFile() with OEM code page.
53 */
54 len = WideCharToMultiByte(GetOEMCP(), 0, str, wlen, NULL, 0, NULL, NULL);
55 msgA = malloc(len);
56 if (!msgA) return;
57
58 WideCharToMultiByte(GetOEMCP(), 0, str, wlen, msgA, len, NULL, NULL);
60 free(msgA);
61 }
62#endif
63}
64
65static void output_formatstring(const WCHAR *fmt, va_list va_args)
66{
67 WCHAR *str;
68 DWORD len;
69
70#ifdef __REACTOS__
72#endif
74 fmt, 0, 0, (WCHAR *)&str, 0, &va_args);
75#ifdef __REACTOS__
76 if (len == 0 && GetLastError() != NO_ERROR)
77#else
78 if (len == 0 && GetLastError() != ERROR_NO_WORK_DONE)
79#endif
80 {
81 WINE_FIXME("Could not format string: le=%lu, fmt=%s\n", GetLastError(), wine_dbgstr_w(fmt));
82 return;
83 }
86}
87
88void WINAPIV output_message(unsigned int id, ...)
89{
90 WCHAR fmt[1536];
91 va_list va_args;
92
94 {
95 WINE_FIXME("LoadString failed with %ld\n", GetLastError());
96 return;
97 }
98 va_start(va_args, id);
99 output_formatstring(fmt, va_args);
100 va_end(va_args);
101}
102
103void WINAPIV error_exit(unsigned int id, ...)
104{
105 WCHAR fmt[1536];
106 va_list va_args;
107
109 {
110#ifndef __REACTOS__
111 WINE_FIXME("LoadString failed with %lu\n", GetLastError());
112#endif
113 return;
114 }
115 va_start(va_args, id);
116 output_formatstring(fmt, va_args);
117 va_end(va_args);
118
119 exit(0); /* regedit.exe always terminates with error code zero */
120}
121
122typedef enum {
125
126#ifdef __REACTOS__
127static void PerformRegAction(REGEDIT_ACTION action, WCHAR **argv, int *i, BOOL silent)
128#else
130#endif
131{
132 switch (action) {
133 case ACTION_ADD: {
134 WCHAR *filename = argv[*i];
135 WCHAR *realname = NULL;
136 FILE *reg_file;
137
138#ifdef __REACTOS__
139 /* Request import confirmation */
140 if (!silent)
141 {
142 WCHAR szText[512];
143 int choice;
144 UINT mbType = MB_YESNO;
145
147
148 if (argv[*i + 1] != NULL)
149 {
150 /* Enable three buttons if there's another file coming */
151 mbType = MB_YESNOCANCEL;
152 }
153
154 choice = InfoMessageBox(NULL, mbType | MB_ICONQUESTION, szTitle, szText, filename);
155 switch (choice)
156 {
157 case IDNO:
158 return;
159 case IDCANCEL:
160 /* The cancel case is useful if the user is importing more than one registry file
161 * at a time, and wants to back out anytime during the import process. This way, the
162 * user doesn't have to resort to ending the regedit process abruptly just to cancel
163 * the operation.
164 * To achieve this, we skip all further command line arguments.
165 */
166 *i = INT_MAX - 1;
167 return;
168 default:
169 break;
170 }
171 }
172#endif
173 if (!lstrcmpW(filename, L"-"))
174 reg_file = stdin;
175 else
176 {
177 int size;
178
180 if (size > 0)
181 {
182 realname = malloc(size * sizeof(WCHAR));
183 size = SearchPathW(NULL, filename, NULL, size, realname, NULL);
184 }
185 if (size == 0)
186 {
188 free(realname);
189 return;
190 }
191 reg_file = _wfopen(realname, L"rb");
192 if (reg_file == NULL)
193 {
194 _wperror(L"regedit");
196 free(realname);
197 return;
198 }
199 }
200 import_registry_file(reg_file);
201 if (realname)
202 {
203 free(realname);
204 fclose(reg_file);
205 }
206 break;
207 }
208 case ACTION_DELETE:
210 break;
211 case ACTION_EXPORT: {
212 WCHAR *filename = argv[*i];
213 WCHAR *key_name = argv[++(*i)];
214
215 if (key_name && *key_name)
217 else
219 break;
220 }
221 default:
223 break;
224 }
225}
226
228{
229 WCHAR **argv;
230 int argc, i;
232#ifdef __REACTOS__
233 BOOL silent = FALSE;
234#endif
235
237
238 if (!argv)
239 return FALSE;
240
241 if (argc == 1)
242 {
244 return FALSE;
245 }
246
247 for (i = 1; i < argc; i++)
248 {
249 if (argv[i][0] != '/' && argv[i][0] != '-')
250 break; /* No flags specified. */
251
252 if (!argv[i][1] && argv[i][0] == '-')
253 break; /* '-' is a filename. It indicates we should use stdin. */
254
255 if (argv[i][1] && argv[i][2] && argv[i][2] != ':')
256 break; /* This is a file path beginning with '/'. */
257
258 switch (towupper(argv[i][1]))
259 {
260 case '?':
262 break;
263 case 'D':
265 break;
266 case 'E':
268 break;
269 case 'C':
270 case 'L':
271 case 'M':
272 case 'R':
273 /* unhandled */;
274 break;
275 case 'S':
276#ifdef __REACTOS__
277 silent = TRUE;
278 break;
279#endif
280 case 'V':
281 /* ignored */;
282 break;
283 default:
286 }
287 }
288
289 if (i == argc)
290 {
291 switch (action)
292 {
293 case ACTION_ADD:
294 case ACTION_EXPORT:
296 break;
297 case ACTION_DELETE:
299 break;
300 }
302 }
303
304 for (; i < argc; i++)
305#ifdef __REACTOS__
306 PerformRegAction(action, argv, &i, silent);
307#else
309#endif
310
312
313 return TRUE;
314}
static int argc
Definition: ServiceArgs.c:12
char * va_list
Definition: acmsvcex.h:78
#define va_end(ap)
Definition: acmsvcex.h:90
#define va_start(ap, A)
Definition: acmsvcex.h:91
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define STRING_FILE_NOT_FOUND
Definition: resource.h:8
#define STRING_USAGE
Definition: resource.h:44
#define IDS_APP_TITLE
Definition: resource.h:10
int InfoMessageBox(HWND hWnd, UINT uType, LPCWSTR lpTitle, LPCWSTR lpMessage,...)
Definition: error.c:51
BOOL import_registry_file(FILE *reg_file)
Definition: regproc.c:1049
#define ARRAY_SIZE(A)
Definition: main.h:33
#define REG_FORMAT_5
Definition: main.h:44
BOOL export_registry_key(WCHAR *file_name, WCHAR *path, DWORD format)
Definition: regproc.c:1546
void delete_registry_key(WCHAR *reg_key_name)
Definition: regproc.c:1097
static void output_formatstring(const WCHAR *fmt, va_list va_args)
Definition: regedit.c:65
static void output_writeconsole(const WCHAR *str, DWORD wlen)
Definition: regedit.c:35
static void PerformRegAction(REGEDIT_ACTION action, WCHAR **argv, int *i)
Definition: regedit.c:129
BOOL ProcessCmdLine(WCHAR *cmdline)
Definition: regedit.c:227
void WINAPIV output_message(unsigned int id,...)
Definition: regedit.c:88
void WINAPIV error_exit(unsigned int id,...)
Definition: regedit.c:103
REGEDIT_ACTION
Definition: regedit.c:122
@ ACTION_ADD
Definition: regedit.c:123
@ ACTION_EXPORT
Definition: regedit.c:123
@ ACTION_DELETE
Definition: regedit.c:123
#define STRING_INVALID_SWITCH
Definition: resource.h:303
#define STRING_CANNOT_OPEN_FILE
Definition: resource.h:308
#define STRING_NO_FILENAME
Definition: resource.h:305
#define IDS_IMPORT_PROMPT
Definition: resource.h:194
#define STRING_NO_REG_KEY
Definition: resource.h:306
#define STRING_UNHANDLED_ACTION
Definition: resource.h:309
HANDLE WINAPI GetStdHandle(IN DWORD nStdHandle)
Definition: console.c:203
#define NO_ERROR
Definition: dderror.h:5
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define SetLastError(x)
Definition: compat.h:752
#define WideCharToMultiByte
Definition: compat.h:111
BOOL WINAPI DECLSPEC_HOTPATCH WriteConsoleW(IN HANDLE hConsoleOutput, IN CONST VOID *lpBuffer, IN DWORD nNumberOfCharsToWrite, OUT LPDWORD lpNumberOfCharsWritten, LPVOID lpReserved)
Definition: readwrite.c:1447
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
HMODULE WINAPI GetModuleHandleW(LPCWSTR lpModuleName)
Definition: loader.c:838
DWORD WINAPI SearchPathW(IN LPCWSTR lpPath OPTIONAL, IN LPCWSTR lpFileName, IN LPCWSTR lpExtension OPTIONAL, IN DWORD nBufferLength, OUT LPWSTR lpBuffer, OUT LPWSTR *lpFilePart OPTIONAL)
Definition: path.c:1298
DWORD WINAPI FormatMessageW(DWORD dwFlags, LPCVOID lpSource, DWORD dwMessageId, DWORD dwLanguageId, LPWSTR lpBuffer, DWORD nSize, __ms_va_list *args)
Definition: format_msg.c:583
const WCHAR * action
Definition: action.c:7479
HINSTANCE hInst
Definition: dxdiag.c:13
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLsizeiptr size
Definition: glext.h:5919
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1594
#define INT_MAX
Definition: limits.h:40
_Check_return_ _CRTIMP FILE *__cdecl _wfopen(_In_z_ const wchar_t *_Filename, _In_z_ const wchar_t *_Mode)
_CRTIMP void __cdecl _wperror(_In_opt_z_ const wchar_t *_ErrMsg)
#define stdin
Definition: stdio.h:98
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
const char * filename
Definition: ioapi.h:137
#define wine_dbgstr_w
Definition: kernel32.h:34
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:170
TCHAR szTitle[MAX_LOADSTRING]
Definition: magnifier.c:35
#define argv
Definition: mplay32.c:18
unsigned int UINT
Definition: ndis.h:50
#define L(x)
Definition: ntvdm.h:50
const WCHAR * str
#define WINAPIV
Definition: sdbpapi.h:64
#define WINE_FIXME
Definition: debug.h:366
#define exit(n)
Definition: config.h:202
LPWSTR *WINAPI CommandLineToArgvW(LPCWSTR lpCmdline, int *numargs)
Definition: shell32_main.c:80
TCHAR * cmdline
Definition: stretchblt.cpp:32
Definition: dsound.c:943
#define towupper(c)
Definition: wctype.h:99
#define STD_OUTPUT_HANDLE
Definition: winbase.h:268
DWORD WINAPI GetLastError(void)
Definition: except.c:1040
#define FORMAT_MESSAGE_FROM_STRING
Definition: winbase.h:421
#define FORMAT_MESSAGE_ALLOCATE_BUFFER
Definition: winbase.h:419
UINT WINAPI GetOEMCP(void)
Definition: nls.c:2322
#define IDCANCEL
Definition: winuser.h:825
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)
#define MB_YESNO
Definition: winuser.h:811
int WINAPI MessageBoxW(_In_opt_ HWND hWnd, _In_opt_ LPCWSTR lpText, _In_opt_ LPCWSTR lpCaption, _In_ UINT uType)
#define IDNO
Definition: winuser.h:830
#define MB_OK
Definition: winuser.h:784
#define MB_ICONQUESTION
Definition: winuser.h:783
#define MB_ICONINFORMATION
Definition: winuser.h:796
#define MB_YESNOCANCEL
Definition: winuser.h:812
#define STRING_HELP
Definition: xcopy.h:74
__wchar_t WCHAR
Definition: xmlstorage.h:180