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(&reg_key_name_buf, &reg_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,
-                        &reg_key_name_buf, &reg_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,
-                        &reg_key_name_buf, &reg_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],
-                            &reg_key_name_buf, &reg_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, &reg_key_name_buf, &reg_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