ReactOS 0.4.15-dev-7659-ga55345b
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. */
41#else
43
45 {
46 DWORD len;
47 char *msgA;
48
49 /* WriteConsole() fails on Windows if its output is redirected. If this occurs,
50 * we should call WriteFile() with OEM code page.
51 */
52 len = WideCharToMultiByte(GetOEMCP(), 0, str, wlen, NULL, 0, NULL, NULL);
53 msgA = malloc(len);
54 if (!msgA) return;
55
56 WideCharToMultiByte(GetOEMCP(), 0, str, wlen, msgA, len, NULL, NULL);
58 free(msgA);
59 }
60#endif
61}
62
63static void output_formatstring(const WCHAR *fmt, va_list va_args)
64{
65 WCHAR *str;
66 DWORD len;
67
68#ifdef __REACTOS__
70#endif
72 fmt, 0, 0, (WCHAR *)&str, 0, &va_args);
73#ifdef __REACTOS__
74 if (len == 0 && GetLastError() != NO_ERROR)
75#else
76 if (len == 0 && GetLastError() != ERROR_NO_WORK_DONE)
77#endif
78 {
79 WINE_FIXME("Could not format string: le=%lu, fmt=%s\n", GetLastError(), wine_dbgstr_w(fmt));
80 return;
81 }
84}
85
86void WINAPIV output_message(unsigned int id, ...)
87{
88 WCHAR fmt[1536];
89 va_list va_args;
90
92 {
93 WINE_FIXME("LoadString failed with %ld\n", GetLastError());
94 return;
95 }
96 va_start(va_args, id);
97 output_formatstring(fmt, va_args);
98 va_end(va_args);
99}
100
101void WINAPIV error_exit(unsigned int id, ...)
102{
103 WCHAR fmt[1536];
104 va_list va_args;
105
107 {
108#ifndef __REACTOS__
109 WINE_FIXME("LoadString failed with %lu\n", GetLastError());
110#endif
111 return;
112 }
113 va_start(va_args, id);
114 output_formatstring(fmt, va_args);
115 va_end(va_args);
116
117 exit(0); /* regedit.exe always terminates with error code zero */
118}
119
120typedef enum {
123
124#ifdef __REACTOS__
125static void PerformRegAction(REGEDIT_ACTION action, WCHAR **argv, int *i, BOOL silent)
126#else
128#endif
129{
130 switch (action) {
131 case ACTION_ADD: {
132 WCHAR *filename = argv[*i];
133 WCHAR *realname = NULL;
134 FILE *reg_file;
135
136#ifdef __REACTOS__
137 /* Request import confirmation */
138 if (!silent)
139 {
140 WCHAR szText[512];
141 int choice;
142 UINT mbType = MB_YESNO;
143
145
146 if (argv[*i + 1] != NULL)
147 {
148 /* Enable three buttons if there's another file coming */
149 mbType = MB_YESNOCANCEL;
150 }
151
152 choice = InfoMessageBox(NULL, mbType | MB_ICONQUESTION, szTitle, szText, filename);
153 switch (choice)
154 {
155 case IDNO:
156 return;
157 case IDCANCEL:
158 /* The cancel case is useful if the user is importing more than one registry file
159 * at a time, and wants to back out anytime during the import process. This way, the
160 * user doesn't have to resort to ending the regedit process abruptly just to cancel
161 * the operation.
162 * To achieve this, we skip all further command line arguments.
163 */
164 *i = INT_MAX - 1;
165 return;
166 default:
167 break;
168 }
169 }
170#endif
171 if (!lstrcmpW(filename, L"-"))
172 reg_file = stdin;
173 else
174 {
175 int size;
176
178 if (size > 0)
179 {
180 realname = malloc(size * sizeof(WCHAR));
181 size = SearchPathW(NULL, filename, NULL, size, realname, NULL);
182 }
183 if (size == 0)
184 {
186 free(realname);
187 return;
188 }
189 reg_file = _wfopen(realname, L"rb");
190 if (reg_file == NULL)
191 {
192 _wperror(L"regedit");
194 free(realname);
195 return;
196 }
197 }
198 import_registry_file(reg_file);
199 if (realname)
200 {
201 free(realname);
202 fclose(reg_file);
203 }
204 break;
205 }
206 case ACTION_DELETE:
208 break;
209 case ACTION_EXPORT: {
210 WCHAR *filename = argv[*i];
211 WCHAR *key_name = argv[++(*i)];
212
213 if (key_name && *key_name)
215 else
217 break;
218 }
219 default:
220#ifdef __REACTOS__
222#else
224#endif
225 break;
226 }
227}
228
230{
231 WCHAR **argv;
232 int argc, i;
234#ifdef __REACTOS__
235 BOOL silent = FALSE;
236#endif
237
239
240 if (!argv)
241 return FALSE;
242
243 if (argc == 1)
244 {
246 return FALSE;
247 }
248
249 for (i = 1; i < argc; i++)
250 {
251 if (argv[i][0] != '/' && argv[i][0] != '-')
252 break; /* No flags specified. */
253
254 if (!argv[i][1] && argv[i][0] == '-')
255 break; /* '-' is a filename. It indicates we should use stdin. */
256
257 if (argv[i][1] && argv[i][2] && argv[i][2] != ':')
258 break; /* This is a file path beginning with '/'. */
259
260 switch (towupper(argv[i][1]))
261 {
262 case '?':
264 break;
265 case 'D':
267 break;
268 case 'E':
270 break;
271 case 'C':
272 case 'L':
273 case 'M':
274 case 'R':
275 /* unhandled */;
276 break;
277 case 'S':
278#ifdef __REACTOS__
279 silent = TRUE;
280 break;
281#endif
282 case 'V':
283 /* ignored */;
284 break;
285 default:
288 }
289 }
290
291 if (i == argc)
292 {
293 switch (action)
294 {
295 case ACTION_ADD:
296 case ACTION_EXPORT:
298 break;
299 case ACTION_DELETE:
301 break;
302 }
304 }
305
306 for (; i < argc; i++)
307#ifdef __REACTOS__
308 PerformRegAction(action, argv, &i, silent);
309#else
311#endif
312
314
315 return TRUE;
316}
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
int InfoMessageBox(HWND hWnd, UINT uType, LPCWSTR lpTitle, LPCWSTR lpMessage,...)
Definition: error.c:51
BOOL import_registry_file(FILE *reg_file)
Definition: regproc.c:1054
#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:1579
void delete_registry_key(WCHAR *reg_key_name)
Definition: regproc.c:1102
static void output_formatstring(const WCHAR *fmt, va_list va_args)
Definition: regedit.c:63
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:127
BOOL ProcessCmdLine(WCHAR *cmdline)
Definition: regedit.c:229
void WINAPIV output_message(unsigned int id,...)
Definition: regedit.c:86
void WINAPIV error_exit(unsigned int id,...)
Definition: regedit.c:101
REGEDIT_ACTION
Definition: regedit.c:120
@ ACTION_ADD
Definition: regedit.c:121
@ ACTION_EXPORT
Definition: regedit.c:121
@ ACTION_DELETE
Definition: regedit.c:121
#define STRING_INVALID_SWITCH
Definition: resource.h:373
#define STRING_CANNOT_OPEN_FILE
Definition: resource.h:378
#define STRING_NO_FILENAME
Definition: resource.h:375
#define IDS_IMPORT_PROMPT
Definition: resource.h:196
#define STRING_NO_REG_KEY
Definition: resource.h:376
#define STRING_UNHANDLED_ACTION
Definition: resource.h:379
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:1042
#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:830
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:816
int WINAPI MessageBoxW(_In_opt_ HWND hWnd, _In_opt_ LPCWSTR lpText, _In_opt_ LPCWSTR lpCaption, _In_ UINT uType)
#define MB_ICONERROR
Definition: winuser.h:786
#define IDNO
Definition: winuser.h:835
#define MB_ICONQUESTION
Definition: winuser.h:788
#define MB_YESNOCANCEL
Definition: winuser.h:817
#define STRING_HELP
Definition: xcopy.h:74
__wchar_t WCHAR
Definition: xmlstorage.h:180