Hugh McMaster : reg: Export registry value names.

Alexandre Julliard julliard at winehq.org
Mon Dec 4 14:58:20 CST 2017


Module: wine
Branch: master
Commit: 879282ec1481f80f6f93fa7d4624107cc8c0b6fb
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=879282ec1481f80f6f93fa7d4624107cc8c0b6fb

Author: Hugh McMaster <hugh.mcmaster at outlook.com>
Date:   Sun Dec  3 06:50:19 2017 +0000

reg: Export registry value names.

Signed-off-by: Hugh McMaster <hugh.mcmaster at outlook.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 programs/reg/export.c    | 124 +++++++++++++++++++++++++++++++++++++++++++++--
 programs/reg/tests/reg.c |  20 ++++----
 2 files changed, 131 insertions(+), 13 deletions(-)

diff --git a/programs/reg/export.c b/programs/reg/export.c
index f98ca1f..b94d79f 100644
--- a/programs/reg/export.c
+++ b/programs/reg/export.c
@@ -33,6 +33,87 @@ static void write_file(HANDLE hFile, const WCHAR *str)
     WriteFile(hFile, str, lstrlenW(str) * sizeof(WCHAR), &written, NULL);
 }
 
+static WCHAR *escape_string(WCHAR *str, size_t str_len, size_t *line_len)
+{
+    size_t i, escape_count, pos;
+    WCHAR *buf;
+
+    for (i = 0, escape_count = 0; i < str_len; i++)
+    {
+        WCHAR c = str[i];
+        if (c == '\r' || c == '\n' || c == '\\' || c == '"' || c == '\0')
+            escape_count++;
+    }
+
+    buf = heap_xalloc((str_len + escape_count + 1) * sizeof(WCHAR));
+
+    for (i = 0, pos = 0; i < str_len; i++, pos++)
+    {
+        WCHAR c = str[i];
+
+        switch (c)
+        {
+        case '\r':
+            buf[pos++] = '\\';
+            buf[pos] = 'r';
+            break;
+        case '\n':
+            buf[pos++] = '\\';
+            buf[pos] = 'n';
+            break;
+        case '\\':
+            buf[pos++] = '\\';
+            buf[pos] = '\\';
+            break;
+        case '"':
+            buf[pos++] = '\\';
+            buf[pos] = '"';
+            break;
+        case '\0':
+            buf[pos++] = '\\';
+            buf[pos] = '0';
+            break;
+        default:
+            buf[pos] = c;
+        }
+    }
+
+    buf[pos] = 0;
+    *line_len = pos;
+    return buf;
+}
+
+static size_t export_value_name(HANDLE hFile, WCHAR *name, size_t len)
+{
+    static const WCHAR quoted_fmt[] = {'"','%','s','"','=',0};
+    static const WCHAR default_name[] = {'@','=',0};
+    size_t line_len;
+
+    if (name && *name)
+    {
+        WCHAR *str = escape_string(name, len, &line_len);
+        WCHAR *buf = heap_xalloc((line_len + 4) * sizeof(WCHAR));
+        line_len = sprintfW(buf, quoted_fmt, str);
+        write_file(hFile, buf);
+        heap_free(buf);
+        heap_free(str);
+    }
+    else
+    {
+        line_len = lstrlenW(default_name);
+        write_file(hFile, default_name);
+    }
+
+    return line_len;
+}
+
+static void export_newline(HANDLE hFile)
+{
+    static const WCHAR newline[] = {'\r','\n',0};
+
+    write_file(hFile, newline);
+}
+
 static void export_key_name(HANDLE hFile, WCHAR *name)
 {
     static const WCHAR fmt[] = {'\r','\n','[','%','s',']','\r','\n',0};
@@ -44,6 +125,42 @@ static void export_key_name(HANDLE hFile, WCHAR *name)
     heap_free(buf);
 }
 
+static int export_registry_data(HANDLE hFile, HKEY key, WCHAR *path)
+{
+    LONG rc;
+    DWORD max_value_len = 256, value_len;
+    DWORD i;
+    WCHAR *value_name;
+
+    export_key_name(hFile, path);
+
+    value_name = heap_xalloc(max_value_len * sizeof(WCHAR));
+
+    i = 0;
+    for (;;)
+    {
+        value_len = max_value_len;
+        rc = RegEnumValueW(key, i, value_name, &value_len, NULL, NULL, NULL, NULL);
+
+        if (rc == ERROR_SUCCESS)
+        {
+            export_value_name(hFile, value_name, value_len);
+            FIXME(": export of data types not yet implemented\n");
+            export_newline(hFile);
+            i++;
+        }
+        else if (rc == ERROR_MORE_DATA)
+        {
+            max_value_len *= 2;
+            value_name = heap_xrealloc(value_name, max_value_len * sizeof(WCHAR));
+        }
+        else break;
+    }
+
+    heap_free(value_name);
+    return 0;
+}
+
 static void export_file_header(HANDLE hFile)
 {
     static const WCHAR header[] = { 0xfeff,'W','i','n','d','o','w','s',' ',
@@ -108,6 +225,7 @@ int reg_export(int argc, WCHAR *argv[])
     WCHAR *path, *long_key;
     BOOL overwrite_file = FALSE;
     HANDLE hFile;
+    int ret;
 
     if (argc == 3 || argc > 5)
         goto error;
@@ -126,13 +244,13 @@ int reg_export(int argc, WCHAR *argv[])
 
     hFile = get_file_handle(argv[3], overwrite_file);
     export_file_header(hFile);
-    export_key_name(hFile, long_key);
-    FIXME(": operation not yet implemented\n");
+    ret = export_registry_data(hFile, hkey, long_key);
+    export_newline(hFile);
     CloseHandle(hFile);
 
     RegCloseKey(hkey);
 
-    return 1;
+    return ret;
 
 error:
     output_message(STRING_INVALID_SYNTAX);
diff --git a/programs/reg/tests/reg.c b/programs/reg/tests/reg.c
index 62299aa..f1fa8e6 100644
--- a/programs/reg/tests/reg.c
+++ b/programs/reg/tests/reg.c
@@ -4422,7 +4422,7 @@ static void test_export(void)
     add_key(HKEY_CURRENT_USER, KEY_BASE, &hkey);
 
     run_reg_exe("reg export HKEY_CURRENT_USER\\" KEY_BASE " file.reg", &r);
-    todo_wine ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
+    ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
 
     os_version = GetVersion();
     major_version = LOBYTE(LOWORD(os_version));
@@ -4437,12 +4437,12 @@ static void test_export(void)
         ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
 
         run_reg_exe("reg export HKEY_CURRENT_USER\\" KEY_BASE " file.reg /y", &r);
-        todo_wine ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
+        ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
     }
     else /* Windows XP (32-bit) and older */
         win_skip("File overwrite flag [/y] not supported; skipping position tests\n");
 
-    ok(compare_export("file.reg", empty_key_test, TODO_REG_COMPARE), "compare_export() failed\n");
+    ok(compare_export("file.reg", empty_key_test, 0), "compare_export() failed\n");
 
     /* Test registry export with a simple data structure */
     dword = 0x100;
@@ -4450,7 +4450,7 @@ static void test_export(void)
     add_value(hkey, "String", REG_SZ, "Your text here...", 18);
 
     run_reg_exe("reg export HKEY_CURRENT_USER\\" KEY_BASE " file.reg", &r);
-    todo_wine ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
+    ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
     ok(compare_export("file.reg", simple_test, TODO_REG_COMPARE), "compare_export() failed\n");
 
     /* Test registry export with a complex data structure */
@@ -4488,7 +4488,7 @@ static void test_export(void)
     RegCloseKey(hkey);
 
     run_reg_exe("reg export HKEY_CURRENT_USER\\" KEY_BASE " file.reg", &r);
-    todo_wine ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
+    ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
     ok(compare_export("file.reg", complex_test, TODO_REG_COMPARE), "compare_export() failed\n");
 
     err = delete_tree(HKEY_CURRENT_USER, KEY_BASE);
@@ -4502,7 +4502,7 @@ static void test_export(void)
     RegCloseKey(subkey);
 
     run_reg_exe("reg export HKEY_CURRENT_USER\\" KEY_BASE " file.reg", &r);
-    todo_wine ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
+    ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
     ok(compare_export("file.reg", key_order_test, TODO_REG_COMPARE), "compare_export() failed\n");
 
     delete_key(hkey, "Subkey1");
@@ -4517,7 +4517,7 @@ static void test_export(void)
     RegCloseKey(hkey);
 
     run_reg_exe("reg export HKEY_CURRENT_USER\\" KEY_BASE " file.reg", &r);
-    todo_wine ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
+    ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
     ok(compare_export("file.reg", value_order_test, TODO_REG_COMPARE), "compare_export() failed\n");
 
     delete_key(HKEY_CURRENT_USER, KEY_BASE);
@@ -4535,7 +4535,7 @@ static void test_export(void)
     RegCloseKey(hkey);
 
     run_reg_exe("reg export HKEY_CURRENT_USER\\" KEY_BASE " file.reg", &r);
-    todo_wine ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
+    ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
     ok(compare_export("file.reg", empty_hex_test, TODO_REG_COMPARE), "compare_export() failed\n");
 
     delete_key(HKEY_CURRENT_USER, KEY_BASE);
@@ -4553,7 +4553,7 @@ static void test_export(void)
     RegCloseKey(hkey);
 
     run_reg_exe("reg export HKEY_CURRENT_USER\\" KEY_BASE " file.reg", &r);
-    todo_wine ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
+    ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
     ok(compare_export("file.reg", empty_hex_test2, TODO_REG_COMPARE), "compare_export() failed\n");
 
     delete_key(HKEY_CURRENT_USER, KEY_BASE);
@@ -4572,7 +4572,7 @@ static void test_export(void)
     RegCloseKey(hkey);
 
     run_reg_exe("reg export HKEY_CURRENT_USER\\" KEY_BASE " file.reg", &r);
-    todo_wine ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
+    ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
     ok(compare_export("file.reg", hex_types_test, TODO_REG_COMPARE), "compare_export() failed\n");
 
     delete_key(HKEY_CURRENT_USER, KEY_BASE);




More information about the wine-cvs mailing list