ReactOS 0.4.16-dev-188-g678aa63
regedit.c
Go to the documentation of this file.
1/*
2 * Windows regedit.exe registry editor implementation.
3 *
4 * Copyright 2002 Andriy Palamarchuk
5 * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
6 */
7
8#ifndef __REACTOS__
9#include <stdlib.h>
10#include <windows.h>
11#include <commctrl.h>
12#include <shellapi.h>
13
14#include "wine/debug.h"
15#include "main.h"
16#else
17#include "regedit.h"
18#endif
19
21
22static void output_writeconsole(const WCHAR *str, DWORD wlen)
23{
24#ifdef __REACTOS__
25 /* This is win32gui application, don't ever try writing to console.
26 * For the console version we have a separate reg.exe application. */
28#else
30
32 {
33 DWORD len;
34 char *msgA;
35
36 /* WriteConsole() fails on Windows if its output is redirected. If this occurs,
37 * we should call WriteFile() with OEM code page.
38 */
39 len = WideCharToMultiByte(GetOEMCP(), 0, str, wlen, NULL, 0, NULL, NULL);
40 msgA = malloc(len);
41 if (!msgA) return;
42
43 WideCharToMultiByte(GetOEMCP(), 0, str, wlen, msgA, len, NULL, NULL);
45 free(msgA);
46 }
47#endif
48}
49
50static void output_formatstring(const WCHAR *fmt, va_list va_args)
51{
52 WCHAR *str;
53 DWORD len;
54
55#ifdef __REACTOS__
57#endif
59 fmt, 0, 0, (WCHAR *)&str, 0, &va_args);
60#ifdef __REACTOS__
61 if (len == 0 && GetLastError() != NO_ERROR)
62#else
63 if (len == 0 && GetLastError() != ERROR_NO_WORK_DONE)
64#endif
65 {
66 WINE_FIXME("Could not format string: le=%lu, fmt=%s\n", GetLastError(), wine_dbgstr_w(fmt));
67 return;
68 }
71}
72
73void WINAPIV output_message(unsigned int id, ...)
74{
75 WCHAR fmt[1536];
76 va_list va_args;
77
79 {
80 WINE_FIXME("LoadString failed with %ld\n", GetLastError());
81 return;
82 }
83 va_start(va_args, id);
84 output_formatstring(fmt, va_args);
85 va_end(va_args);
86}
87
88void WINAPIV error_exit(unsigned int id, ...)
89{
90 WCHAR fmt[1536];
91 va_list va_args;
92
94 {
95#ifndef __REACTOS__
96 WINE_FIXME("LoadString failed with %lu\n", GetLastError());
97#endif
98 return;
99 }
100 va_start(va_args, id);
101 output_formatstring(fmt, va_args);
102 va_end(va_args);
103
104 exit(0); /* regedit.exe always terminates with error code zero */
105}
106
107typedef enum {
110
111#ifdef __REACTOS__
113#else
115#endif
116{
117 switch (action) {
118 case ACTION_ADD: {
119 WCHAR *filename = argv[*i];
120 WCHAR *realname = NULL;
121 FILE *reg_file;
122
123#ifdef __REACTOS__
124 /* Request import confirmation */
125 if (!silent)
126 {
127 WCHAR szText[512];
128 int choice;
129 UINT mbType = MB_YESNO;
130
132
133 if (argv[*i + 1] != NULL)
134 {
135 /* Enable three buttons if there's another file coming */
136 mbType = MB_YESNOCANCEL;
137 }
138
139 choice = InfoMessageBox(NULL, mbType | MB_ICONQUESTION, szTitle, szText, filename);
140 switch (choice)
141 {
142 case IDNO:
143 return;
144 case IDCANCEL:
145 /* The cancel case is useful if the user is importing more than one registry file
146 * at a time, and wants to back out anytime during the import process. This way, the
147 * user doesn't have to resort to ending the regedit process abruptly just to cancel
148 * the operation.
149 * To achieve this, we skip all further command line arguments.
150 */
151 *i = INT_MAX - 1;
152 return;
153 default:
154 break;
155 }
156 }
157#endif
158 if (!lstrcmpW(filename, L"-"))
159 reg_file = stdin;
160 else
161 {
162 int size;
163
165 if (size > 0)
166 {
167 realname = malloc(size * sizeof(WCHAR));
168 size = SearchPathW(NULL, filename, NULL, size, realname, NULL);
169 }
170 if (size == 0)
171 {
173 free(realname);
174 return;
175 }
176 reg_file = _wfopen(realname, L"rb");
177 if (reg_file == NULL)
178 {
179 _wperror(L"regedit");
181 free(realname);
182 return;
183 }
184 }
185 import_registry_file(reg_file);
186 if (realname)
187 {
188 free(realname);
189 fclose(reg_file);
190 }
191 break;
192 }
193 case ACTION_DELETE:
195 break;
196 case ACTION_EXPORT: {
197 WCHAR *filename = argv[*i];
198 WCHAR *key_name = argv[++(*i)];
199
200 if (key_name && *key_name)
202 else
204 break;
205 }
206 default:
207#ifdef __REACTOS__
209#else
211#endif
212 break;
213 }
214}
215
217{
218 WCHAR **argv;
219 int argc, i;
221#ifdef __REACTOS__
222 BOOL silent = FALSE;
223#endif
224
226
227 if (!argv)
228 return FALSE;
229
230 if (argc == 1)
231 {
233 return FALSE;
234 }
235
236 for (i = 1; i < argc; i++)
237 {
238 if (argv[i][0] != '/' && argv[i][0] != '-')
239 break; /* No flags specified. */
240
241 if (!argv[i][1] && argv[i][0] == '-')
242 break; /* '-' is a filename. It indicates we should use stdin. */
243
244 if (argv[i][1] && argv[i][2] && argv[i][2] != ':')
245 break; /* This is a file path beginning with '/'. */
246
247 switch (towupper(argv[i][1]))
248 {
249 case '?':
251 break;
252 case 'D':
254 break;
255 case 'E':
257 break;
258 case 'C':
259 case 'L':
260 case 'M':
261 case 'R':
262 /* unhandled */;
263 break;
264 case 'S':
265#ifdef __REACTOS__
266 silent = TRUE;
267 break;
268#endif
269 case 'V':
270 /* ignored */;
271 break;
272 default:
275 }
276 }
277
278 if (i == argc)
279 {
280 switch (action)
281 {
282 case ACTION_ADD:
283 case ACTION_EXPORT:
285 break;
286 case ACTION_DELETE:
288 break;
289 }
291 }
292
293 for (; i < argc; i++)
294#ifdef __REACTOS__
296#else
298#endif
299
301
302 return TRUE;
303}
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:38
BOOL import_registry_file(FILE *reg_file)
Definition: regproc.c:1041
#define ARRAY_SIZE(A)
Definition: main.h:20
#define REG_FORMAT_5
Definition: main.h:31
BOOL export_registry_key(WCHAR *file_name, WCHAR *path, DWORD format)
Definition: regproc.c:1566
void delete_registry_key(WCHAR *reg_key_name)
Definition: regproc.c:1089
static void output_formatstring(const WCHAR *fmt, va_list va_args)
Definition: regedit.c:50
static void output_writeconsole(const WCHAR *str, DWORD wlen)
Definition: regedit.c:22
static void PerformRegAction(REGEDIT_ACTION action, WCHAR **argv, int *i)
Definition: regedit.c:114
BOOL ProcessCmdLine(WCHAR *cmdline)
Definition: regedit.c:216
void WINAPIV output_message(unsigned int id,...)
Definition: regedit.c:73
void WINAPIV error_exit(unsigned int id,...)
Definition: regedit.c:88
REGEDIT_ACTION
Definition: regedit.c:107
@ ACTION_ADD
Definition: regedit.c:108
@ ACTION_EXPORT
Definition: regedit.c:108
@ ACTION_DELETE
Definition: regedit.c:108
#define STRING_INVALID_SWITCH
Definition: resource.h:325
#define STRING_CANNOT_OPEN_FILE
Definition: resource.h:330
#define STRING_NO_FILENAME
Definition: resource.h:327
#define IDS_IMPORT_PROMPT
Definition: resource.h:149
#define STRING_NO_REG_KEY
Definition: resource.h:328
#define STRING_UNHANDLED_ACTION
Definition: resource.h:331
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
int WINAPI lstrcmpW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4243
UINT WINAPI GetOEMCP(void)
Definition: locale.c:2060
const WCHAR * action
Definition: action.c:7509
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
TCHAR szTitle[MAX_LOADSTRING]
Definition: magnifier.c:35
#define argv
Definition: mplay32.c:18
static BOOL silent
Definition: msiexec.c:42
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:79
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
#define IDCANCEL
Definition: winuser.h:834
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:820
int WINAPI MessageBoxW(_In_opt_ HWND hWnd, _In_opt_ LPCWSTR lpText, _In_opt_ LPCWSTR lpCaption, _In_ UINT uType)
#define MB_ICONERROR
Definition: winuser.h:790
#define IDNO
Definition: winuser.h:839
#define MB_ICONQUESTION
Definition: winuser.h:792
#define MB_YESNOCANCEL
Definition: winuser.h:821
#define STRING_HELP
Definition: xcopy.h:74
__wchar_t WCHAR
Definition: xmlstorage.h:180