forked from Mirrors/wine-wine
reg: Export registry value names.
Signed-off-by: Hugh McMaster <hugh.mcmaster@outlook.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>oldstable
parent
ab3ee817c3
commit
879282ec14
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue