Hugh McMaster : regedit: Re-implement some parts of the export operation.
Alexandre Julliard
julliard at winehq.org
Wed Jul 19 16:05:32 CDT 2017
Module: wine
Branch: master
Commit: efe3bc87e77d9723bd4a8ce1d6afc6982ed965a0
URL: http://source.winehq.org/git/wine.git/?a=commit;h=efe3bc87e77d9723bd4a8ce1d6afc6982ed965a0
Author: Hugh McMaster <hugh.mcmaster at outlook.com>
Date: Wed Jul 19 05:28:21 2017 +0000
regedit: Re-implement some parts of the export operation.
Signed-off-by: Hugh McMaster <hugh.mcmaster at outlook.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
programs/regedit/regproc.c | 274 +++++++++++++++++++++++----------------------
1 file changed, 143 insertions(+), 131 deletions(-)
diff --git a/programs/regedit/regproc.c b/programs/regedit/regproc.c
index 4c52a19..5a0d222 100644
--- a/programs/regedit/regproc.c
+++ b/programs/regedit/regproc.c
@@ -1403,137 +1403,6 @@ static void export_hkey(FILE *file, HKEY key,
}
/******************************************************************************
- * Open file in binary mode for export.
- */
-static FILE *REGPROC_open_export_file(WCHAR *file_name, BOOL unicode)
-{
- FILE *file;
- WCHAR dash = '-';
-
- if (strncmpW(file_name,&dash,1)==0) {
- file=stdout;
- _setmode(_fileno(file), _O_BINARY);
- } else
- {
- WCHAR wb_mode[] = {'w','b',0};
- WCHAR regedit[] = {'r','e','g','e','d','i','t',0};
-
- file = _wfopen(file_name, wb_mode);
- if (!file) {
- _wperror(regedit);
- error_exit(STRING_CANNOT_OPEN_FILE, file_name);
- }
- }
- if(unicode)
- {
- const BYTE unicode_seq[] = {0xff,0xfe};
- const WCHAR header[] = {'W','i','n','d','o','w','s',' ','R','e','g','i','s','t','r','y',' ','E','d','i','t','o','r',' ','V','e','r','s','i','o','n',' ','5','.','0','0','\r','\n'};
- fwrite(unicode_seq, sizeof(BYTE), sizeof(unicode_seq)/sizeof(unicode_seq[0]), file);
- fwrite(header, sizeof(WCHAR), sizeof(header)/sizeof(header[0]), file);
- } else
- {
- fputs("REGEDIT4\r\n", file);
- }
-
- return file;
-}
-
-/******************************************************************************
- * Writes contents of the registry key to the specified file stream.
- *
- * Parameters:
- * file_name - name of a file to export registry branch to.
- * reg_key_name - registry branch to export. The whole registry is exported if
- * reg_key_name is NULL or contains an empty string.
- */
-BOOL export_registry_key(WCHAR *file_name, WCHAR *reg_key_name, DWORD format)
-{
- WCHAR *reg_key_name_buf;
- WCHAR *val_name_buf;
- BYTE *val_buf;
- WCHAR *line_buf;
- DWORD reg_key_name_size = KEY_MAX_LEN;
- DWORD val_name_size = KEY_MAX_LEN;
- DWORD val_size = REG_VAL_BUF_SIZE;
- DWORD line_buf_size = KEY_MAX_LEN + REG_VAL_BUF_SIZE;
- FILE *file = NULL;
- BOOL unicode = (format == REG_FORMAT_5);
-
- reg_key_name_buf = HeapAlloc(GetProcessHeap(), 0,
- reg_key_name_size * sizeof(*reg_key_name_buf));
- val_name_buf = HeapAlloc(GetProcessHeap(), 0,
- val_name_size * sizeof(*val_name_buf));
- val_buf = HeapAlloc(GetProcessHeap(), 0, val_size);
- line_buf = HeapAlloc(GetProcessHeap(), 0, line_buf_size * sizeof(*line_buf));
- CHECK_ENOUGH_MEMORY(reg_key_name_buf && val_name_buf && val_buf && line_buf);
-
- if (reg_key_name && reg_key_name[0]) {
- HKEY reg_key_class;
- WCHAR *branch_name = NULL;
- HKEY key;
-
- REGPROC_resize_char_buffer(®_key_name_buf, ®_key_name_size,
- lstrlenW(reg_key_name));
- lstrcpyW(reg_key_name_buf, reg_key_name);
-
- /* open the specified key */
- if (!(reg_key_class = parse_key_name(reg_key_name, &branch_name)))
- {
- if (branch_name) *(branch_name - 1) = 0;
- error_exit(STRING_INVALID_SYSTEM_KEY, reg_key_name);
- }
-
- if (!branch_name || !*branch_name) {
- /* no branch - registry class is specified */
- file = REGPROC_open_export_file(file_name, unicode);
- export_hkey(file, reg_key_class,
- ®_key_name_buf, ®_key_name_size,
- &val_name_buf, &val_name_size,
- &val_buf, &val_size, &line_buf,
- &line_buf_size, unicode);
- } else if (RegOpenKeyW(reg_key_class, branch_name, &key) == ERROR_SUCCESS) {
- file = REGPROC_open_export_file(file_name, unicode);
- export_hkey(file, key,
- ®_key_name_buf, ®_key_name_size,
- &val_name_buf, &val_name_size,
- &val_buf, &val_size, &line_buf,
- &line_buf_size, unicode);
- RegCloseKey(key);
- } else {
- output_message(STRING_REG_KEY_NOT_FOUND, reg_key_name);
- }
- } else {
- unsigned int i;
-
- /* export all registry classes */
- file = REGPROC_open_export_file(file_name, unicode);
- for (i = 0; i < ARRAY_SIZE(reg_class_keys); i++) {
- /* do not export HKEY_CLASSES_ROOT */
- if (reg_class_keys[i] != HKEY_CLASSES_ROOT &&
- reg_class_keys[i] != HKEY_CURRENT_USER &&
- reg_class_keys[i] != HKEY_CURRENT_CONFIG &&
- reg_class_keys[i] != HKEY_DYN_DATA) {
- lstrcpyW(reg_key_name_buf, reg_class_namesW[i]);
- export_hkey(file, reg_class_keys[i],
- ®_key_name_buf, ®_key_name_size,
- &val_name_buf, &val_name_size,
- &val_buf, &val_size, &line_buf,
- &line_buf_size, unicode);
- }
- }
- }
-
- if (file) {
- fclose(file);
- }
- HeapFree(GetProcessHeap(), 0, reg_key_name);
- HeapFree(GetProcessHeap(), 0, val_name_buf);
- HeapFree(GetProcessHeap(), 0, val_buf);
- HeapFree(GetProcessHeap(), 0, line_buf);
- return TRUE;
-}
-
-/******************************************************************************
* Reads contents of the specified file into the registry.
*/
BOOL import_registry_file(FILE *reg_file)
@@ -1603,3 +1472,146 @@ void delete_registry_key(WCHAR *reg_key_name)
RegDeleteTreeW(key_class, key_name);
}
+
+static int export_registry_data(FILE *fp, HKEY key, WCHAR *path, BOOL unicode)
+{
+ WCHAR *reg_key_name_buf, *val_name_buf, *line_buf;
+ BYTE *val_buf;
+ DWORD reg_key_name_size = KEY_MAX_LEN;
+ DWORD val_name_size = KEY_MAX_LEN;
+ DWORD val_size = REG_VAL_BUF_SIZE;
+ DWORD line_buf_size = KEY_MAX_LEN + REG_VAL_BUF_SIZE;
+
+ reg_key_name_buf = HeapAlloc(GetProcessHeap(), 0, reg_key_name_size * sizeof(WCHAR));
+ val_name_buf = HeapAlloc(GetProcessHeap(), 0, val_name_size * sizeof(WCHAR));
+ val_buf = HeapAlloc(GetProcessHeap(), 0, val_size);
+ line_buf = HeapAlloc(GetProcessHeap(), 0, line_buf_size * sizeof(WCHAR));
+ CHECK_ENOUGH_MEMORY(reg_key_name_buf && val_name_buf && val_buf && line_buf);
+
+ lstrcpyW(reg_key_name_buf, path);
+
+ export_hkey(fp, key, ®_key_name_buf, ®_key_name_size, &val_name_buf, &val_name_size,
+ &val_buf, &val_size, &line_buf, &line_buf_size, unicode);
+
+ HeapFree(GetProcessHeap(), 0, reg_key_name_buf);
+ HeapFree(GetProcessHeap(), 0, val_name_buf);
+ HeapFree(GetProcessHeap(), 0, val_buf);
+ HeapFree(GetProcessHeap(), 0, line_buf);
+
+ return 0;
+}
+
+static FILE *REGPROC_open_export_file(WCHAR *file_name, BOOL unicode)
+{
+ FILE *file;
+ static const WCHAR hyphen[] = {'-',0};
+
+ if (!strcmpW(file_name, hyphen))
+ {
+ file = stdout;
+ _setmode(_fileno(file), _O_BINARY);
+ }
+ else
+ {
+ static const WCHAR wb_mode[] = {'w','b',0};
+
+ file = _wfopen(file_name, wb_mode);
+ if (!file)
+ {
+ static const WCHAR regedit[] = {'r','e','g','e','d','i','t',0};
+ _wperror(regedit);
+ error_exit(STRING_CANNOT_OPEN_FILE, file_name);
+ }
+ }
+
+ if (unicode)
+ {
+ static const BYTE bom[] = {0xff,0xfe};
+ static const WCHAR header[] = {'W','i','n','d','o','w','s',' ',
+ 'R','e','g','i','s','t','r','y',' ','E','d','i','t','o','r',' ',
+ 'V','e','r','s','i','o','n',' ','5','.','0','0','\r','\n'};
+
+ fwrite(bom, sizeof(BYTE), ARRAY_SIZE(bom), file);
+ fwrite(header, sizeof(WCHAR), ARRAY_SIZE(header), file);
+ }
+ else
+ fputs("REGEDIT4\r\n", file);
+
+ return file;
+}
+
+static HKEY open_export_key(HKEY key_class, WCHAR *subkey, WCHAR *path)
+{
+ HKEY key;
+
+ if (!RegOpenKeyExW(key_class, subkey, 0, KEY_READ, &key))
+ return key;
+
+ output_message(STRING_OPEN_KEY_FAILED, path);
+ return NULL;
+}
+
+static BOOL export_key(WCHAR *file_name, WCHAR *path, BOOL unicode)
+{
+ HKEY key_class, key;
+ WCHAR *subkey;
+ FILE *fp;
+ BOOL ret;
+
+ if (!(key_class = parse_key_name(path, &subkey)))
+ {
+ if (subkey) *(subkey - 1) = 0;
+ output_message(STRING_INVALID_SYSTEM_KEY, path);
+ return FALSE;
+ }
+
+ if (!(key = open_export_key(key_class, subkey, path)))
+ return FALSE;
+
+ fp = REGPROC_open_export_file(file_name, unicode);
+ ret = export_registry_data(fp, key, path, unicode);
+ fclose(fp);
+
+ RegCloseKey(key);
+ return ret;
+}
+
+static BOOL export_all(WCHAR *file_name, WCHAR *path, BOOL unicode)
+{
+ FILE *fp;
+ int i;
+ HKEY classes[] = {HKEY_LOCAL_MACHINE, HKEY_USERS}, key;
+ WCHAR *class_name;
+
+ fp = REGPROC_open_export_file(file_name, unicode);
+
+ for (i = 0; i < ARRAY_SIZE(classes); i++)
+ {
+ if (!(key = open_export_key(classes[i], NULL, path)))
+ {
+ fclose(fp);
+ return FALSE;
+ }
+
+ class_name = resize_buffer(NULL, (lstrlenW(reg_class_namesW[i]) + 1) * sizeof(WCHAR));
+ lstrcpyW(class_name, reg_class_namesW[i]);
+
+ export_registry_data(fp, classes[i], class_name, unicode);
+
+ HeapFree(GetProcessHeap(), 0, class_name);
+ RegCloseKey(key);
+ }
+
+ fclose(fp);
+ return TRUE;
+}
+
+BOOL export_registry_key(WCHAR *file_name, WCHAR *path, DWORD format)
+{
+ BOOL unicode = (format == REG_FORMAT_5);
+
+ if (path && *path)
+ return export_key(file_name, path, unicode);
+ else
+ return export_all(file_name, path, unicode);
+}
More information about the wine-cvs
mailing list