ReactOS 0.4.15-dev-7788-g1ad9096
reg.c
Go to the documentation of this file.
1/*
2 * Copyright 2008 Andrew Riedi
3 * Copyright 2016-2017, 2021 Hugh McMaster
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18 */
19
20#include <stdio.h>
21#include "reg.h"
22#include <wine/debug.h>
23
25
26static const struct
27{
31}
32root_rels[] =
33{
34 {HKEY_LOCAL_MACHINE, L"HKLM", L"HKEY_LOCAL_MACHINE"},
35 {HKEY_CURRENT_USER, L"HKCU", L"HKEY_CURRENT_USER"},
36 {HKEY_CLASSES_ROOT, L"HKCR", L"HKEY_CLASSES_ROOT"},
37 {HKEY_USERS, L"HKU", L"HKEY_USERS"},
38 {HKEY_CURRENT_CONFIG, L"HKCC", L"HKEY_CURRENT_CONFIG"},
39};
40
41const struct reg_type_rels type_rels[] =
42{
43 {REG_NONE, L"REG_NONE"},
44 {REG_SZ, L"REG_SZ"},
45 {REG_EXPAND_SZ, L"REG_EXPAND_SZ"},
46 {REG_BINARY, L"REG_BINARY"},
47 {REG_DWORD, L"REG_DWORD"},
48 {REG_DWORD_LITTLE_ENDIAN, L"REG_DWORD_LITTLE_ENDIAN"},
49 {REG_DWORD_BIG_ENDIAN, L"REG_DWORD_BIG_ENDIAN"},
50 {REG_MULTI_SZ, L"REG_MULTI_SZ"},
51};
52
54{
56
58 if (!ret)
59 {
60 DWORD len;
61 char *msgA;
62
63 /* On Windows WriteConsoleW() fails if the output is redirected. So fall
64 * back to WriteFile(), assuming the console encoding is still the right
65 * one in that case.
66 */
68 msgA = malloc(len);
69
72 free(msgA);
73 }
74}
75
76static void output_formatstring(const WCHAR *fmt, va_list va_args)
77{
78 WCHAR *str;
79 DWORD len;
80
82 fmt, 0, 0, (WCHAR *)&str, 0, &va_args);
83 if (len == 0 && GetLastError() != NO_ERROR)
84 {
85 WINE_FIXME("Could not format string: le=%u, fmt=%s\n", GetLastError(), wine_dbgstr_w(fmt));
86 return;
87 }
90}
91
92void WINAPIV output_message(unsigned int id, ...)
93{
94 WCHAR *fmt = NULL;
95 int len;
96 va_list va_args;
97
98 if (!(len = LoadStringW(GetModuleHandleW(NULL), id, (WCHAR *)&fmt, 0)))
99 {
100 WINE_FIXME("LoadString failed with %d\n", GetLastError());
101 return;
102 }
103
104 len++;
105 fmt = malloc(len * sizeof(WCHAR));
106 if (!fmt) return;
107
109
110 va_start(va_args, id);
111 output_formatstring(fmt, va_args);
112 va_end(va_args);
113
114 free(fmt);
115}
116
118{
119 va_list va_args;
120
121 va_start(va_args, fmt);
122 output_formatstring(fmt, va_args);
123 va_end(va_args);
124}
125
126/* ask_confirm() adapted from programs/cmd/builtins.c */
127BOOL ask_confirm(unsigned int msgid, WCHAR *reg_info)
128{
130 WCHAR Ybuffer[4];
131 WCHAR Nbuffer[4];
132 WCHAR defval[32];
133 WCHAR answer[MAX_PATH];
134 WCHAR *str;
135 DWORD count;
136
138 LoadStringW(hmod, STRING_YES, Ybuffer, ARRAY_SIZE(Ybuffer));
139 LoadStringW(hmod, STRING_NO, Nbuffer, ARRAY_SIZE(Nbuffer));
141
142 str = (reg_info && *reg_info) ? reg_info : defval;
143
144 while (1)
145 {
146 output_message(msgid, str);
149 answer[0] = towupper(answer[0]);
150 if (answer[0] == Ybuffer[0])
151 return TRUE;
152 if (answer[0] == Nbuffer[0])
153 return FALSE;
154 }
155}
156
157static inline BOOL path_rootname_cmp(const WCHAR *input_path, const WCHAR *rootkey_name)
158{
159 DWORD length = lstrlenW(rootkey_name);
160
161 return (!_wcsnicmp(input_path, rootkey_name, length) &&
162 (input_path[length] == 0 || input_path[length] == '\\'));
163}
164
166{
167 DWORD i;
168
169 for (i = 0; i < ARRAY_SIZE(root_rels); i++)
170 {
173 return root_rels[i].key;
174 }
175
176 return NULL;
177}
178
179static BOOL sane_path(const WCHAR *key)
180{
181 unsigned int i = lstrlenW(key);
182
183 if (i < 3 || (key[i - 1] == '\\' && key[i - 2] == '\\'))
184 {
186 return FALSE;
187 }
188
189 if (key[0] == '\\' && key[1] == '\\' && key[2] != '\\')
190 {
192 return FALSE;
193 }
194
195 return TRUE;
196}
197
199{
200 WCHAR *subkey_path;
201
202 subkey_path = malloc((path_len + subkey_len + 2) * sizeof(WCHAR));
203 swprintf(subkey_path, L"%s\\%s", path, subkey_name);
204
205 return subkey_path;
206}
207
209{
210 int i, len;
211 WCHAR *long_key;
212
213 for (i = 0; i < ARRAY_SIZE(root_rels); i++)
214 {
215 if (root == root_rels[i].key)
216 break;
217 }
218
220
221 if (!path)
222 {
223 long_key = malloc((len + 1) * sizeof(WCHAR));
224 lstrcpyW(long_key, root_rels[i].long_name);
225 return long_key;
226 }
227
228 len += lstrlenW(path) + 1; /* add one for the concatenating backslash */
229 long_key = malloc((len + 1) * sizeof(WCHAR));
230 swprintf(long_key, L"%s\\%s", root_rels[i].long_name, path);
231 return long_key;
232}
233
235{
236 WCHAR *p;
237
238 if (!sane_path(key))
239 return FALSE;
240
242 if (!*root)
243 {
245 return FALSE;
246 }
247
248 *path = wcschr(key, '\\');
249
250 if (!*path)
251 return TRUE;
252
253 (*path)++;
254
255 if (!**path)
256 {
258 return FALSE;
259 }
260
261 p = *path + lstrlenW(*path) - 1;
262 if (*p == '\\') *p = 0;
263
264 return TRUE;
265}
266
267BOOL is_char(const WCHAR s, const WCHAR c)
268{
269 return (s == c || s == towupper(c));
270}
271
272BOOL is_switch(const WCHAR *s, const WCHAR c)
273{
274 if (lstrlenW(s) > 2)
275 return FALSE;
276
277 return ((s[0] == '/' || s[0] == '-') && is_char(s[1], c));
278}
279
281{
282 return (is_switch(s, '?') || is_switch(s, 'h'));
283}
284
294
295static enum operations get_operation(const WCHAR *str, int *op_help)
296{
297 struct op_info { const WCHAR *op; int id; int help_id; };
298
299 static const struct op_info op_array[] =
300 {
301 { L"add", REG_ADD, STRING_ADD_USAGE },
302 { L"copy", REG_COPY, STRING_COPY_USAGE },
303 { L"delete", REG_DELETE, STRING_DELETE_USAGE },
304 { L"export", REG_EXPORT, STRING_EXPORT_USAGE },
305 { L"import", REG_IMPORT, STRING_IMPORT_USAGE },
306 { L"query", REG_QUERY, STRING_QUERY_USAGE },
307 { NULL, -1, 0 }
308 };
309
310 const struct op_info *ptr;
311
312 for (ptr = op_array; ptr->op; ptr++)
313 {
314 if (!lstrcmpiW(str, ptr->op))
315 {
316 *op_help = ptr->help_id;
317 return ptr->id;
318 }
319 }
320
321 return REG_INVALID;
322}
323
324int __cdecl wmain(int argc, WCHAR *argvW[])
325{
326 int op, op_help;
327
328 if (argc == 1)
329 {
332 return 1;
333 }
334
335 if (is_help_switch(argvW[1]))
336 {
338 return 0;
339 }
340
341 op = get_operation(argvW[1], &op_help);
342
343 if (op == REG_INVALID)
344 {
347 return 1;
348 }
349 else if (argc == 2) /* Valid operation, no arguments supplied */
350 goto invalid;
351
352 if (is_help_switch(argvW[2]))
353 {
354 if (argc > 3) goto invalid;
355
356 output_message(op_help);
358 return 0;
359 }
360
361 if (op == REG_ADD)
362 return reg_add(argc, argvW);
363
364 if (op == REG_COPY)
365 return reg_copy(argc, argvW);
366
367 if (op == REG_DELETE)
368 return reg_delete(argc, argvW);
369
370 if (op == REG_EXPORT)
371 return reg_export(argc, argvW);
372
373 if (op == REG_IMPORT)
374 return reg_import(argc, argvW);
375
376 return reg_query(argc, argvW);
377
378invalid:
381 return 1;
382}
static int argc
Definition: ServiceArgs.c:12
#define __cdecl
Definition: accygwin.h:79
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
int reg_add(int argc, WCHAR *argvW[])
Definition: add.c:227
int reg_copy(int argc, WCHAR *argvW[])
Definition: copy.c:193
int reg_delete(int argc, WCHAR *argvW[])
Definition: delete.c:134
int reg_export(int argc, WCHAR *argvW[])
Definition: export.c:347
int reg_import(int argc, WCHAR *argvW[])
Definition: import.c:980
int reg_query(int argc, WCHAR *argvW[])
Definition: query.c:339
void output_writeconsole(const WCHAR *str, DWORD wlen)
Definition: reg.c:53
static enum operations get_operation(const WCHAR *str, int *op_help)
Definition: reg.c:295
static BOOL is_help_switch(const WCHAR *s)
Definition: reg.c:280
static const struct @2 root_rels[]
const WCHAR * short_name
Definition: reg.c:29
WCHAR * get_long_key(HKEY root, WCHAR *path)
Definition: reg.c:208
const WCHAR * long_name
Definition: reg.c:30
static void output_formatstring(const WCHAR *fmt, va_list va_args)
Definition: reg.c:76
BOOL is_char(const WCHAR s, const WCHAR c)
Definition: reg.c:267
BOOL is_switch(const WCHAR *s, const WCHAR c)
Definition: reg.c:272
HKEY path_get_rootkey(const WCHAR *path)
Definition: reg.c:165
static BOOL sane_path(const WCHAR *key)
Definition: reg.c:179
WCHAR * build_subkey_path(WCHAR *path, DWORD path_len, WCHAR *subkey_name, DWORD subkey_len)
Definition: reg.c:198
void WINAPIV output_string(const WCHAR *fmt,...)
Definition: reg.c:117
static BOOL path_rootname_cmp(const WCHAR *input_path, const WCHAR *rootkey_name)
Definition: reg.c:157
HKEY key
Definition: reg.c:28
BOOL ask_confirm(unsigned int msgid, WCHAR *reg_info)
Definition: reg.c:127
void WINAPIV output_message(unsigned int id,...)
Definition: reg.c:92
const struct reg_type_rels type_rels[]
Definition: reg.c:41
operations
Definition: reg.c:285
@ REG_EXPORT
Definition: reg.c:289
@ REG_IMPORT
Definition: reg.c:290
@ REG_COPY
Definition: reg.c:287
@ REG_ADD
Definition: reg.c:286
@ REG_QUERY
Definition: reg.c:291
@ REG_DELETE
Definition: reg.c:288
@ REG_INVALID
Definition: reg.c:292
BOOL parse_registry_key(const WCHAR *key, HKEY *root, WCHAR **path)
Definition: reg.c:234
#define STRING_IMPORT_USAGE
Definition: resource.h:49
#define STRING_NO
Definition: resource.h:29
#define STRING_USAGE
Definition: resource.h:44
#define STRING_INVALID_KEY
Definition: resource.h:52
#define STRING_INVALID_SYNTAX
Definition: resource.h:33
#define STRING_DEFAULT_VALUE
Definition: resource.h:40
#define STRING_NO_REMOTE
Definition: resource.h:53
#define STRING_DELETE_USAGE
Definition: resource.h:47
#define STRING_INVALID_OPTION
Definition: resource.h:55
#define STRING_INVALID_SYSTEM_KEY
Definition: resource.h:54
#define STRING_FUNC_HELP
Definition: resource.h:34
#define STRING_YESNO
Definition: resource.h:31
#define STRING_QUERY_USAGE
Definition: resource.h:50
#define STRING_ADD_USAGE
Definition: resource.h:45
#define STRING_COPY_USAGE
Definition: resource.h:46
#define STRING_REG_VIEW_USAGE
Definition: resource.h:51
#define STRING_REG_HELP
Definition: resource.h:43
#define STRING_EXPORT_USAGE
Definition: resource.h:48
#define STRING_YES
Definition: resource.h:28
#define ARRAY_SIZE(A)
Definition: main.h:33
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
UINT op
Definition: effect.c:236
#define wcschr
Definition: compat.h:17
#define MAX_PATH
Definition: compat.h:34
#define lstrcpyW
Definition: compat.h:749
#define WideCharToMultiByte
Definition: compat.h:111
#define lstrlenW
Definition: compat.h:750
UINT WINAPI DECLSPEC_HOTPATCH GetConsoleOutputCP(VOID)
Definition: console.c:2451
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 DECLSPEC_HOTPATCH ReadConsoleW(IN HANDLE hConsoleInput, OUT LPVOID lpBuffer, IN DWORD nNumberOfCharsToRead, OUT LPDWORD lpNumberOfCharsRead, IN PCONSOLE_READCONSOLE_CONTROL pInputControl OPTIONAL)
Definition: readwrite.c:1174
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 FormatMessageW(DWORD dwFlags, LPCVOID lpSource, DWORD dwMessageId, DWORD dwLanguageId, LPWSTR lpBuffer, DWORD nSize, __ms_va_list *args)
Definition: format_msg.c:583
#define swprintf
Definition: precomp.h:40
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLdouble s
Definition: gl.h:2039
GLuint GLuint GLsizei count
Definition: gl.h:1545
const GLubyte * c
Definition: glext.h:8905
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLuint id
Definition: glext.h:5910
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
static int reg
Definition: i386-dis.c:1290
#define wine_dbgstr_w
Definition: kernel32.h:34
#define REG_SZ
Definition: layer.c:22
int WINAPI lstrcmpiW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:194
static PVOID ptr
Definition: dispmode.c:27
static DWORD path_len
Definition: batch.c:31
static PEXPLICIT_ACCESSW *static HMODULE hmod
Definition: security.c:143
static const WCHAR invalid[]
Definition: assoc.c:39
#define REG_BINARY
Definition: nt_native.h:1496
#define REG_DWORD_LITTLE_ENDIAN
Definition: nt_native.h:1498
#define REG_DWORD_BIG_ENDIAN
Definition: nt_native.h:1499
#define REG_MULTI_SZ
Definition: nt_native.h:1501
#define REG_NONE
Definition: nt_native.h:1492
#define REG_EXPAND_SZ
Definition: nt_native.h:1494
#define L(x)
Definition: ntvdm.h:50
int wmain()
const WCHAR * str
#define REG_DWORD
Definition: sdbapi.c:596
#define WINAPIV
Definition: sdbpapi.h:64
_CRTIMP wchar_t *__cdecl _wcsupr(_Inout_z_ wchar_t *_String)
_Check_return_ _CRTIMP int __cdecl _wcsnicmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)
#define WINE_FIXME
Definition: debug.h:366
Definition: dsound.c:943
Definition: copy.c:22
#define towupper(c)
Definition: wctype.h:99
int ret
#define STD_OUTPUT_HANDLE
Definition: winbase.h:268
#define STD_INPUT_HANDLE
Definition: winbase.h:267
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 HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define HKEY_CURRENT_CONFIG
Definition: winreg.h:15
#define HKEY_CURRENT_USER
Definition: winreg.h:11
#define HKEY_CLASSES_ROOT
Definition: winreg.h:10
#define HKEY_USERS
Definition: winreg.h:13
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)
__wchar_t WCHAR
Definition: xmlstorage.h:180