ReactOS 0.4.16-dev-336-gb667d82
txtproc.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Registry Editor
3 * LICENSE: LGPL-2.0-or-later (https://spdx.org/licenses/LGPL-2.0-or-later)
4 * PURPOSE: Exporting registry data to a text file
5 * COPYRIGHT: Copyright 2023 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
6 */
7
8#include "regedit.h"
9
11{
14};
15
17{
18 /* Use rotation buffer */
19 static WCHAR s_asz[3][MAX_PATH];
20 static INT s_index = 0;
21 LPWSTR psz;
22 LoadStringW(hInst, id, s_asz[s_index], MAX_PATH);
23 psz = s_asz[s_index];
24 s_index = (s_index + 1) % _countof(s_asz);
25 return psz;
26}
27
28static void txt_fputs(FILE *fp, LPCWSTR str)
29{
30 fwrite(str, lstrlenW(str) * sizeof(WCHAR), 1, fp);
31}
32
33static void txt_newline(FILE *fp)
34{
35 txt_fputs(fp, L"\r\n");
36}
37
38static void txt_fprintf(FILE *fp, LPCWSTR format, ...)
39{
40 WCHAR line[1024];
41 va_list va;
42 va_start(va, format);
44 txt_fputs(fp, line);
45 va_end(va);
46}
47
49{
50 unsigned int i;
51
52 if (!key_name) return 0;
53
54 *key_path = wcschr(key_name, '\\');
55 if (*key_path)
56 (*key_path)++;
57
58 for (i = 0; i < _countof(reg_class_keys); i++)
59 {
62 (key_name[len] == 0 || key_name[len] == '\\'))
63 {
64 return reg_class_keys[i];
65 }
66 }
67
68 return 0;
69}
70
71static void txt_export_binary(FILE *fp, const void *data, size_t size)
72{
73 const BYTE *pb = data;
74 for (DWORD addr = 0; addr < size; addr += 0x10)
75 {
76 txt_fprintf(fp, L"%08X ", addr);
77 for (size_t column = 0; column < 16; ++column)
78 {
79 if (addr + column >= size)
80 {
81 if (column == 8)
82 txt_fputs(fp, L" ");
83 txt_fputs(fp, L" ");
84 }
85 else
86 {
87 if (column == 8)
88 txt_fputs(fp, L" -");
89 txt_fprintf(fp, L" %02x", (pb[addr + column] & 0xFF));
90 }
91 }
92 txt_fputs(fp, L" ");
93 for (size_t column = 0; column < 16; ++column)
94 {
95 if (addr + column >= size)
96 {
97 break;
98 }
99 else
100 {
101 BYTE b = pb[addr + column];
103 txt_fprintf(fp, L"%c", b);
104 else
105 txt_fputs(fp, L".");
106 }
107 }
108 txt_newline(fp);
109 }
110}
111
113{
114 txt_fprintf(fp, L"%-19s%s\r\n", label, value);
115}
116
117static void txt_export_multi_sz(FILE *fp, const void *data, size_t size)
118{
119 LPCWSTR pch;
120 for (pch = data; *pch; pch += lstrlenW(pch) + 1)
121 {
122 if (pch == data)
124 else
125 txt_export_field(fp, L"", pch);
126 }
127}
128
130{
132}
133
135{
137}
138
139static void
140txt_export_data(FILE *fp, INT i, LPCWSTR value_name, DWORD value_len, DWORD type,
141 const void *data, size_t size)
142{
143 LPCWSTR pszType;
144
146 txt_newline(fp);
147 txt_export_name(fp, value_name);
148
149 switch (type)
150 {
151 case REG_SZ:
152 txt_export_type(fp, L"REG_SZ");
154 break;
155
156 case REG_DWORD:
157 txt_export_type(fp, L"REG_DWORD");
158 txt_fprintf(fp, L"%-19s0x%lx\r\n", load_str(IDS_FIELD_DATA), *(DWORD*)data);
159 break;
160
161 case REG_EXPAND_SZ:
162 txt_export_type(fp, L"REG_EXPAND_SZ");
164 break;
165
166 case REG_MULTI_SZ:
167 txt_export_type(fp, L"REG_MULTI_SZ");
169 break;
170
171 case REG_BINARY:
172 case REG_QWORD:
173 case REG_NONE:
174 default:
175 if (type == REG_BINARY)
176 pszType = L"REG_BINARY";
177 else if (type == REG_QWORD)
178 pszType = L"REG_QWORD";
179 else if (type == REG_NONE)
180 pszType = L"REG_NONE";
181 else
182 pszType = load_str(IDS_UNKNOWN);
183
184 txt_export_type(fp, pszType);
187 break;
188 }
189
190 txt_newline(fp);
191}
192
193static WCHAR *
195{
196 WCHAR *subkey_path;
197 SIZE_T cb_subkey_path = (path_len + subkey_len + 2) * sizeof(WCHAR);
198 subkey_path = malloc(cb_subkey_path);
199 StringCbPrintfW(subkey_path, cb_subkey_path, L"%s\\%s", path, subkey_name);
200 return subkey_path;
201}
202
204{
206}
207
209{
211 DWORD cchClassName = _countof(szClassName);
212 FILETIME ftLastWrite, ftLocal, ftNull = { 0 };
213 SYSTEMTIME stLastWrite;
214 WCHAR sz1[64], sz2[64];
215 LONG error;
216
218 NULL, NULL, &ftLastWrite);
219 if (error != ERROR_SUCCESS)
220 {
221 cchClassName = 0;
222 ftLastWrite = ftNull;
223 }
224
226
227 if (cchClassName > 0)
229 else
231
232 if (memcmp(&ftLastWrite, &ftNull, sizeof(ftNull)) == 0)
233 {
235 return;
236 }
237
238 FileTimeToLocalFileTime(&ftLastWrite, &ftLocal);
239 FileTimeToSystemTime(&ftLocal, &stLastWrite);
242 txt_fprintf(fp, L"%-19s%s - %s\r\n", load_str(IDS_FIELD_LASTWRITE), sz1, sz2);
243}
244
246{
247 LONG rc;
248 DWORD max_value_len = MAX_PATH, value_len;
249 DWORD max_data_bytes = 2048, data_size;
250 DWORD subkey_len;
252 WCHAR *value_name, *subkey_name, *subkey_path;
253 BYTE *data;
254 HKEY subkey;
255
258
259 value_name = malloc(max_value_len * sizeof(WCHAR));
260 data = malloc(max_data_bytes);
261
262 i = 0;
263 for (;;)
264 {
265 value_len = max_value_len;
266 data_size = max_data_bytes;
267 rc = RegEnumValueW(key, i, value_name, &value_len, NULL, &type, data, &data_size);
268 if (rc == ERROR_SUCCESS)
269 {
270 txt_export_data(fp, i, value_name, value_len, type, data, data_size);
271 i++;
272 }
273 else if (rc == ERROR_MORE_DATA)
274 {
275 if (data_size > max_data_bytes)
276 {
277 max_data_bytes = data_size;
278 data = realloc(data, max_data_bytes);
279 }
280 else
281 {
282 max_value_len *= 2;
283 value_name = realloc(value_name, max_value_len * sizeof(WCHAR));
284 }
285 }
286 else break;
287 }
288
289 free(data);
290 free(value_name);
291
292 subkey_name = malloc(MAX_PATH * sizeof(WCHAR));
293
295
296 i = 0;
297 for (;;)
298 {
299 subkey_len = MAX_PATH;
300 rc = RegEnumKeyExW(key, i, subkey_name, &subkey_len, NULL, NULL, NULL, NULL);
301 if (rc == ERROR_SUCCESS)
302 {
303 if (i == 0)
304 txt_newline(fp);
305
306 subkey_path = txt_build_subkey_path(path, path_len, subkey_name, subkey_len);
307 if (!RegOpenKeyExW(key, subkey_name, 0, KEY_READ, &subkey))
308 {
309 txt_newline(fp);
310 txt_export_registry_data(fp, subkey, subkey_path);
311 RegCloseKey(subkey);
312 }
313 free(subkey_path);
314 i++;
315 }
316 else break;
317 }
318
319 free(subkey_name);
320}
321
323{
324 FILE *file = _wfopen(file_name, L"wb");
325 if (file)
326 fwrite("\xFF\xFE", 2, 1, file);
327 return file;
328}
329
331{
332 HKEY key;
333
334 if (RegOpenKeyExW(key_class, subkey, 0, KEY_READ, &key) != ERROR_SUCCESS)
335 return NULL;
336
337 return key;
338}
339
341{
342 HKEY key_class, key;
343 WCHAR *subkey;
344 FILE *fp;
345
346 if (!(key_class = txt_parse_key_name(path, &subkey)))
347 {
348 if (subkey) *(subkey - 1) = 0;
349 return FALSE;
350 }
351
352 if (!(key = txt_open_export_key(key_class, subkey, path)))
353 return FALSE;
354
356 if (fp)
357 {
359 txt_newline(fp);
360 fclose(fp);
361 }
362
364 return fp != NULL;
365}
366
368{
369 FILE *fp;
370 int i;
371 HKEY classes[] = {HKEY_LOCAL_MACHINE, HKEY_USERS}, key;
372 WCHAR *class_name;
373
375 if (!fp)
376 return FALSE;
377
378 for (i = 0; i < _countof(classes); i++)
379 {
380 if (!(key = txt_open_export_key(classes[i], NULL, path)))
381 {
382 fclose(fp);
383 return FALSE;
384 }
385
386 class_name = malloc((lstrlenW(reg_class_namesW[i]) + 1) * sizeof(WCHAR));
387 lstrcpyW(class_name, reg_class_namesW[i]);
388
389 txt_export_registry_data(fp, classes[i], class_name);
390
391 free(class_name);
393 }
394
395 txt_newline(fp);
396 fclose(fp);
397
398 return TRUE;
399}
400
402{
403 if (path && *path)
405 else
407}
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#define isprint(c)
Definition: acclib.h:73
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 IDS_UNKNOWN
Definition: resource.h:7
const WCHAR * reg_class_namesW[]
Definition: main.c:12
#define IDS_FIELD_TYPE
Definition: resource.h:207
#define IDS_NULL_TIMESTAMP
Definition: resource.h:205
#define IDS_FIELD_KEY_NAME
Definition: resource.h:202
#define IDS_FIELD_LASTWRITE
Definition: resource.h:209
#define IDS_FIELD_CLASS_NAME
Definition: resource.h:203
#define IDS_FIELD_NAME
Definition: resource.h:206
#define IDS_VALUE_INDEX
Definition: resource.h:211
#define IDS_NO_CLASS_NAME
Definition: resource.h:204
#define IDS_FIELD_DATA
Definition: resource.h:208
#define RegCloseKey(hKey)
Definition: registry.h:49
static const WCHAR szClassName[]
Definition: clipbrd.c:11
#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:3333
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:2504
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:2830
LONG WINAPI RegQueryInfoKeyW(HKEY hKey, LPWSTR lpClass, LPDWORD lpcClass, LPDWORD lpReserved, LPDWORD lpcSubKeys, LPDWORD lpcMaxSubKeyLen, LPDWORD lpcMaxClassLen, LPDWORD lpcValues, LPDWORD lpcMaxValueNameLen, LPDWORD lpcMaxValueLen, LPDWORD lpcbSecurityDescriptor, PFILETIME lpftLastWriteTime)
Definition: reg.c:3662
#define wcschr
Definition: compat.h:17
#define MAX_PATH
Definition: compat.h:34
#define lstrcpyW
Definition: compat.h:749
#define lstrlenW
Definition: compat.h:750
BOOL WINAPI FileTimeToSystemTime(IN CONST FILETIME *lpFileTime, OUT LPSYSTEMTIME lpSystemTime)
Definition: time.c:188
BOOL WINAPI FileTimeToLocalFileTime(IN CONST FILETIME *lpFileTime, OUT LPFILETIME lpLocalFileTime)
Definition: time.c:221
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 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
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLenum const GLvoid * addr
Definition: glext.h:9621
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
_Check_return_ _CRTIMP FILE *__cdecl _wfopen(_In_z_ const wchar_t *_Filename, _In_z_ const wchar_t *_Mode)
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
_Check_return_opt_ _CRTIMP size_t __cdecl fwrite(_In_reads_bytes_(_Size *_Count) const void *_Str, _In_ size_t _Size, _In_ size_t _Count, _Inout_ FILE *_File)
#define REG_SZ
Definition: layer.c:22
INT WINAPI GetTimeFormatW(LCID lcid, DWORD dwFlags, const SYSTEMTIME *lpTime, LPCWSTR lpFormat, LPWSTR lpTimeStr, INT cchOut)
Definition: lcformat.c:1093
INT WINAPI GetDateFormatW(LCID lcid, DWORD dwFlags, const SYSTEMTIME *lpTime, LPCWSTR lpFormat, LPWSTR lpDateStr, INT cchOut)
Definition: lcformat.c:993
#define error(str)
Definition: mkdosfs.c:1605
#define pch(ap)
Definition: match.c:418
static DWORD path_len
Definition: batch.c:31
static const WCHAR label[]
Definition: itemdlg.c:1546
static LPCWSTR file_name
Definition: protocol.c:147
#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 REG_EXPAND_SZ
Definition: nt_native.h:1494
#define LOCALE_USER_DEFAULT
#define UNICODE_NULL
#define L(x)
Definition: ntvdm.h:50
long LONG
Definition: pedump.c:60
const WCHAR * str
#define REG_QWORD
Definition: sdbapi.c:597
#define REG_DWORD
Definition: sdbapi.c:596
_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 _countof(array)
Definition: sndvol32.h:70
STRSAFEAPI StringCchVPrintfW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszFormat, va_list argList)
Definition: strsafe.h:490
STRSAFEAPI StringCbPrintfW(STRSAFE_LPWSTR pszDest, size_t cbDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:557
Definition: fci.c:127
Definition: format.c:58
Definition: copy.c:22
Definition: parser.c:49
Definition: name.c:39
static void txt_export_binary(FILE *fp, const void *data, size_t size)
Definition: txtproc.c:71
static BOOL txt_export_key(LPCWSTR file_name, LPCWSTR path)
Definition: txtproc.c:340
static void txt_newline(FILE *fp)
Definition: txtproc.c:33
static void txt_export_name(FILE *fp, LPCWSTR name)
Definition: txtproc.c:134
static void txt_export_multi_sz(FILE *fp, const void *data, size_t size)
Definition: txtproc.c:117
static void txt_fputs(FILE *fp, LPCWSTR str)
Definition: txtproc.c:28
static void txt_fprintf(FILE *fp, LPCWSTR format,...)
Definition: txtproc.c:38
static void txt_export_registry_data(FILE *fp, HKEY key, LPCWSTR path)
Definition: txtproc.c:245
static void txt_export_field(FILE *fp, LPCWSTR label, LPCWSTR value)
Definition: txtproc.c:112
static WCHAR * txt_build_subkey_path(LPCWSTR path, DWORD path_len, LPCWSTR subkey_name, DWORD subkey_len)
Definition: txtproc.c:194
static HKEY reg_class_keys[]
Definition: txtproc.c:10
static void txt_export_type(FILE *fp, LPCWSTR type)
Definition: txtproc.c:129
static HKEY txt_parse_key_name(LPCWSTR key_name, WCHAR **key_path)
Definition: txtproc.c:48
static void txt_export_class_and_last_write(FILE *fp, HKEY key)
Definition: txtproc.c:208
static void txt_export_data(FILE *fp, INT i, LPCWSTR value_name, DWORD value_len, DWORD type, const void *data, size_t size)
Definition: txtproc.c:140
static HKEY txt_open_export_key(HKEY key_class, LPCWSTR subkey, LPCWSTR path)
Definition: txtproc.c:330
static void txt_export_key_name(FILE *fp, LPCWSTR name)
Definition: txtproc.c:203
static BOOL txt_export_all(LPCWSTR file_name, LPCWSTR path)
Definition: txtproc.c:367
static FILE * txt_open_export_file(LPCWSTR file_name)
Definition: txtproc.c:322
static LPWSTR load_str(INT id)
Definition: txtproc.c:16
BOOL txt_export_registry_key(LPCWSTR file_name, LPCWSTR path)
Definition: txtproc.c:401
ULONG_PTR SIZE_T
Definition: typedefs.h:80
int32_t INT
Definition: typedefs.h:58
Definition: pdh_main.c:94
#define TIME_NOSECONDS
Definition: winnls.h:280
#define DATE_SHORTDATE
Definition: winnls.h:198
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define HKEY_CURRENT_CONFIG
Definition: winreg.h:15
#define HKEY_DYN_DATA
Definition: winreg.h:16
#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)
BOOL WINAPI IsCharAlphaNumericW(_In_ WCHAR)
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
unsigned char BYTE
Definition: xxhash.c:193