ReactOS 0.4.15-dev-5669-g09dde2c
export.c
Go to the documentation of this file.
1/*
2 * Copyright 2017 Hugh McMaster
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17 */
18
19#include <stdio.h>
20#include "reg.h"
21
22static void write_file(HANDLE hFile, const WCHAR *str)
23{
24 DWORD written;
25
26 WriteFile(hFile, str, lstrlenW(str) * sizeof(WCHAR), &written, NULL);
27}
28
29static WCHAR *escape_string(WCHAR *str, size_t str_len, size_t *line_len)
30{
31 size_t i, escape_count, pos;
32 WCHAR *buf;
33
34 for (i = 0, escape_count = 0; i < str_len; i++)
35 {
36 WCHAR c = str[i];
37
38 if (!c) break;
39
40 if (c == '\r' || c == '\n' || c == '\\' || c == '"')
41 escape_count++;
42 }
43
44 buf = malloc((str_len + escape_count + 1) * sizeof(WCHAR));
45
46 for (i = 0, pos = 0; i < str_len; i++, pos++)
47 {
48 WCHAR c = str[i];
49
50 if (!c) break;
51
52 switch (c)
53 {
54 case '\r':
55 buf[pos++] = '\\';
56 buf[pos] = 'r';
57 break;
58 case '\n':
59 buf[pos++] = '\\';
60 buf[pos] = 'n';
61 break;
62 case '\\':
63 buf[pos++] = '\\';
64 buf[pos] = '\\';
65 break;
66 case '"':
67 buf[pos++] = '\\';
68 buf[pos] = '"';
69 break;
70 default:
71 buf[pos] = c;
72 }
73 }
74
75 buf[pos] = 0;
76 *line_len = pos;
77 return buf;
78}
79
80static size_t export_value_name(HANDLE hFile, WCHAR *name, size_t len)
81{
82 static const WCHAR *default_name = L"@=";
83 size_t line_len;
84
85 if (name && *name)
86 {
87 WCHAR *str = escape_string(name, len, &line_len);
88 WCHAR *buf = malloc((line_len + 4) * sizeof(WCHAR));
89 line_len = swprintf(buf, L"\"%s\"=", str);
91 free(buf);
92 free(str);
93 }
94 else
95 {
96 line_len = lstrlenW(default_name);
97 write_file(hFile, default_name);
98 }
99
100 return line_len;
101}
102
103static void export_string_data(WCHAR **buf, WCHAR *data, size_t size)
104{
105 size_t len = 0, line_len;
106 WCHAR *str;
107
108 if (size)
109 len = size / sizeof(WCHAR) - 1;
110 str = escape_string(data, len, &line_len);
111 *buf = malloc((line_len + 3) * sizeof(WCHAR));
112 swprintf(*buf, L"\"%s\"", str);
113 free(str);
114}
115
117{
118 *buf = malloc(15 * sizeof(WCHAR));
119 swprintf(*buf, L"dword:%08x", *data);
120}
121
123{
124 static const WCHAR *hex = L"hex:";
125 size_t line_len;
126
127 if (type == REG_BINARY)
128 {
129 line_len = lstrlenW(hex);
131 }
132 else
133 {
134 WCHAR *buf = malloc(15 * sizeof(WCHAR));
135 line_len = swprintf(buf, L"hex(%x):", type);
137 free(buf);
138 }
139
140 return line_len;
141}
142
143#define MAX_HEX_CHARS 77
144
146 DWORD line_len, void *data, DWORD size)
147{
148 size_t num_commas, i, pos;
149
150 line_len += export_hex_data_type(hFile, type);
151
152 if (!size) return;
153
154 num_commas = size - 1;
155 *buf = malloc(size * 3 * sizeof(WCHAR));
156
157 for (i = 0, pos = 0; i < size; i++)
158 {
159 pos += swprintf(*buf + pos, L"%02x", ((BYTE *)data)[i]);
160 if (i == num_commas) break;
161 (*buf)[pos++] = ',';
162 (*buf)[pos] = 0;
163 line_len += 3;
164
165 if (line_len >= MAX_HEX_CHARS)
166 {
168 write_file(hFile, L"\\\r\n ");
169 line_len = 2;
170 pos = 0;
171 }
172 }
173}
174
176{
177 static const WCHAR *newline = L"\r\n";
178
179 write_file(hFile, newline);
180}
181
182static void export_data(HANDLE hFile, WCHAR *value_name, DWORD value_len,
183 DWORD type, void *data, size_t size)
184{
185 WCHAR *buf = NULL;
186 size_t line_len = export_value_name(hFile, value_name, value_len);
187
188 switch (type)
189 {
190 case REG_SZ:
192 break;
193 case REG_DWORD:
194 if (size)
195 {
197 break;
198 }
199 /* fall through */
200 case REG_NONE:
201 case REG_EXPAND_SZ:
202 case REG_BINARY:
203 case REG_MULTI_SZ:
204 default:
205 export_hex_data(hFile, &buf, type, line_len, data, size);
206 break;
207 }
208
209 if (size || type == REG_SZ)
210 {
212 free(buf);
213 }
214
216}
217
219{
220 WCHAR *buf;
221
222 buf = malloc((lstrlenW(name) + 7) * sizeof(WCHAR));
223 swprintf(buf, L"\r\n[%s]\r\n", name);
225 free(buf);
226}
227
229{
230 LONG rc;
231 DWORD max_value_len = 256, value_len;
232 DWORD max_data_bytes = 2048, data_size;
233 DWORD subkey_len;
235 WCHAR *value_name, *subkey_name, *subkey_path;
236 BYTE *data;
237 HKEY subkey;
238
240
241 value_name = malloc(max_value_len * sizeof(WCHAR));
242 data = malloc(max_data_bytes);
243
244 i = 0;
245 for (;;)
246 {
247 value_len = max_value_len;
248 data_size = max_data_bytes;
249 rc = RegEnumValueW(hkey, i, value_name, &value_len, NULL, &type, data, &data_size);
250
251 if (rc == ERROR_SUCCESS)
252 {
253 export_data(hFile, value_name, value_len, type, data, data_size);
254 i++;
255 }
256 else if (rc == ERROR_MORE_DATA)
257 {
258 if (data_size > max_data_bytes)
259 {
260 max_data_bytes = data_size;
261 data = realloc(data, max_data_bytes);
262 }
263 else
264 {
265 max_value_len *= 2;
266 value_name = realloc(value_name, max_value_len * sizeof(WCHAR));
267 }
268 }
269 else break;
270 }
271
272 free(data);
273 free(value_name);
274
275 subkey_name = malloc(MAX_SUBKEY_LEN * sizeof(WCHAR));
276
278
279 i = 0;
280 for (;;)
281 {
282 subkey_len = MAX_SUBKEY_LEN;
283 rc = RegEnumKeyExW(hkey, i, subkey_name, &subkey_len, NULL, NULL, NULL, NULL);
284 if (rc == ERROR_SUCCESS)
285 {
286 subkey_path = build_subkey_path(path, path_len, subkey_name, subkey_len);
287 if (!RegOpenKeyExW(hkey, subkey_name, 0, KEY_READ|sam, &subkey))
288 {
289 export_registry_data(hFile, subkey, subkey_path, sam);
290 RegCloseKey(subkey);
291 }
292 free(subkey_path);
293 i++;
294 }
295 else break;
296 }
297
298 free(subkey_name);
299 return 0;
300}
301
303{
304 static const WCHAR header[] = L"\xFEFFWindows Registry Editor Version 5.00\r\n";
305
307}
308
310{
312}
313
314static HANDLE get_file_handle(WCHAR *filename, BOOL overwrite_file)
315{
317
319 {
321
323 {
325 {
327 exit(0);
328 }
329
331 }
332 else
333 {
334 WCHAR *str;
335
339 LocalFree(str);
340 exit(1);
341 }
342 }
343
344 return hFile;
345}
346
347int reg_export(int argc, WCHAR *argvW[])
348{
349 HKEY root, hkey;
351 BOOL overwrite_file = FALSE;
352 REGSAM sam = 0;
354 int i, ret;
355
356 if (argc < 4) goto invalid;
357
358 if (!parse_registry_key(argvW[2], &root, &path))
359 return 1;
360
361 for (i = 4; i < argc; i++)
362 {
363 WCHAR *str;
364
365 if (argvW[i][0] != '/' && argvW[i][0] != '-')
366 goto invalid;
367
368 str = &argvW[i][1];
369
370 if (is_char(*str, 'y') && !str[1])
371 overwrite_file = TRUE;
372 else if (!lstrcmpiW(str, L"reg:32"))
373 {
374 if (sam & KEY_WOW64_32KEY) goto invalid;
376 continue;
377 }
378 else if (!lstrcmpiW(str, L"reg:64"))
379 {
380 if (sam & KEY_WOW64_64KEY) goto invalid;
382 continue;
383 }
384 else
385 goto invalid;
386 }
387
389 goto invalid;
390
391 if (RegOpenKeyExW(root, path, 0, KEY_READ|sam, &hkey))
392 {
394 return 1;
395 }
396
398
399 hFile = get_file_handle(argvW[3], overwrite_file);
404
405 RegCloseKey(hkey);
406
407 return ret;
408
409invalid:
412 return 1;
413}
static int argc
Definition: ServiceArgs.c:12
static WCHAR * escape_string(WCHAR *str, size_t str_len, size_t *line_len)
Definition: export.c:29
static HANDLE get_file_handle(WCHAR *filename, BOOL overwrite_file)
Definition: export.c:314
static void export_key_name(HANDLE hFile, WCHAR *name)
Definition: export.c:218
static void export_dword_data(WCHAR **buf, DWORD *data)
Definition: export.c:116
static void export_hex_data(HANDLE hFile, WCHAR **buf, DWORD type, DWORD line_len, void *data, DWORD size)
Definition: export.c:145
#define MAX_HEX_CHARS
Definition: export.c:143
static void export_newline(HANDLE hFile)
Definition: export.c:175
static void export_file_header(HANDLE hFile)
Definition: export.c:302
int reg_export(int argc, WCHAR *argvW[])
Definition: export.c:347
static void export_string_data(WCHAR **buf, WCHAR *data, size_t size)
Definition: export.c:103
static int export_registry_data(HANDLE hFile, HKEY hkey, WCHAR *path, REGSAM sam)
Definition: export.c:228
static size_t export_value_name(HANDLE hFile, WCHAR *name, size_t len)
Definition: export.c:80
static void write_file(HANDLE hFile, const WCHAR *str)
Definition: export.c:22
static size_t export_hex_data_type(HANDLE hFile, DWORD type)
Definition: export.c:122
static void export_data(HANDLE hFile, WCHAR *value_name, DWORD value_len, DWORD type, void *data, size_t size)
Definition: export.c:182
static REGSAM sam
Definition: query.c:143
void output_writeconsole(const WCHAR *str, DWORD wlen)
Definition: reg.c:53
WCHAR * get_long_key(HKEY root, WCHAR *path)
Definition: reg.c:208
BOOL is_char(const WCHAR s, const WCHAR c)
Definition: reg.c:267
WCHAR * build_subkey_path(WCHAR *path, DWORD path_len, WCHAR *subkey_name, DWORD subkey_len)
Definition: reg.c:198
BOOL ask_confirm(unsigned int msgid, WCHAR *reg_info)
Definition: reg.c:127
void WINAPIV output_message(unsigned int id,...)
Definition: reg.c:92
BOOL parse_registry_key(const WCHAR *key, HKEY *root, WCHAR **path)
Definition: reg.c:234
#define MAX_SUBKEY_LEN
Definition: reg.h:26
#define STRING_CANCELLED
Definition: resource.h:37
#define STRING_INVALID_SYNTAX
Definition: resource.h:33
#define STRING_FUNC_HELP
Definition: resource.h:34
#define STRING_KEY_NONEXIST
Definition: resource.h:38
#define STRING_OVERWRITE_FILE
Definition: resource.h:77
#define RegCloseKey(hKey)
Definition: registry.h:47
struct _root root
#define ERROR_MORE_DATA
Definition: dderror.h:13
#define realloc
Definition: debug_ros.c:6
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3356
LONG WINAPI RegEnumKeyExW(_In_ HKEY hKey, _In_ DWORD dwIndex, _Out_ LPWSTR lpName, _Inout_ LPDWORD lpcbName, _Reserved_ LPDWORD lpReserved, _Out_opt_ LPWSTR lpClass, _Inout_opt_ LPDWORD lpcbClass, _Out_opt_ PFILETIME lpftLastWriteTime)
Definition: reg.c:2527
LONG WINAPI RegEnumValueW(_In_ HKEY hKey, _In_ DWORD index, _Out_ LPWSTR value, _Inout_ PDWORD val_count, _Reserved_ PDWORD reserved, _Out_opt_ PDWORD type, _Out_opt_ LPBYTE data, _Inout_opt_ PDWORD count)
Definition: reg.c:2853
#define CloseHandle
Definition: compat.h:739
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define CreateFileW
Definition: compat.h:741
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define lstrlenW
Definition: compat.h:750
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
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
#define swprintf
Definition: precomp.h:40
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLsizeiptr size
Definition: glext.h:5919
const GLubyte * c
Definition: glext.h:8905
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
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:1577
int hex(char ch)
const char * filename
Definition: ioapi.h:137
#define c
Definition: ke_i.h:80
#define REG_SZ
Definition: layer.c:22
int WINAPI lstrcmpiW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:194
#define error(str)
Definition: mkdosfs.c:1605
#define CREATE_ALWAYS
Definition: disk.h:72
#define CREATE_NEW
Definition: disk.h:69
static DWORD path_len
Definition: batch.c:31
#define create_file(name, size)
Definition: asmcache.c:813
static const WCHAR invalid[]
Definition: assoc.c:39
_In_ HANDLE hFile
Definition: mswsock.h:90
#define REG_BINARY
Definition: nt_native.h:1496
#define KEY_READ
Definition: nt_native.h:1023
#define REG_MULTI_SZ
Definition: nt_native.h:1501
#define REG_NONE
Definition: nt_native.h:1492
#define GENERIC_WRITE
Definition: nt_native.h:90
#define REG_EXPAND_SZ
Definition: nt_native.h:1494
#define L(x)
Definition: ntvdm.h:50
long LONG
Definition: pedump.c:60
const WCHAR * str
#define REG_DWORD
Definition: sdbapi.c:596
_CRTIMP wchar_t *__cdecl _wcsupr(_Inout_z_ wchar_t *_String)
#define exit(n)
Definition: config.h:202
Definition: name.c:39
#define str_len
Definition: treelist.c:89
int ret
DWORD WINAPI GetLastError(void)
Definition: except.c:1040
#define FORMAT_MESSAGE_IGNORE_INSERTS
Definition: winbase.h:420
#define FORMAT_MESSAGE_FROM_SYSTEM
Definition: winbase.h:423
#define FORMAT_MESSAGE_ALLOCATE_BUFFER
Definition: winbase.h:419
#define ERROR_FILE_EXISTS
Definition: winerror.h:165
ACCESS_MASK REGSAM
Definition: winreg.h:69
#define KEY_WOW64_32KEY
Definition: cmtypes.h:45
#define KEY_WOW64_64KEY
Definition: cmtypes.h:46
__wchar_t WCHAR
Definition: xmlstorage.h:180
unsigned char BYTE
Definition: xxhash.c:193