[PATCH 06/13] reg: Prompt the user to overwrite the export file if it already exists
Hugh McMaster
hugh.mcmaster at outlook.com
Sun Dec 3 00:50:15 CST 2017
Signed-off-by: Hugh McMaster <hugh.mcmaster at outlook.com>
---
programs/reg/export.c | 45 ++++++++++++++++++++++++++++++++++++++++++++-
programs/reg/reg.c | 4 ++--
programs/reg/reg.h | 2 ++
programs/reg/reg.rc | 1 +
programs/reg/resource.h | 1 +
programs/reg/tests/reg.c | 18 +++++++++---------
6 files changed, 59 insertions(+), 12 deletions(-)
diff --git a/programs/reg/export.c b/programs/reg/export.c
index 9d0d33274e..81ffd220a3 100644
--- a/programs/reg/export.c
+++ b/programs/reg/export.c
@@ -17,6 +17,7 @@
*/
#include <windows.h>
+#include <stdlib.h>
#include <wine/unicode.h>
#include <wine/debug.h>
@@ -25,6 +26,44 @@
WINE_DEFAULT_DEBUG_CHANNEL(reg);
+static HANDLE create_file(const WCHAR *filename, DWORD action)
+{
+ return CreateFileW(filename, GENERIC_WRITE, 0, NULL, action, FILE_ATTRIBUTE_NORMAL, NULL);
+}
+
+static HANDLE get_file_handle(WCHAR *filename, BOOL overwrite_file)
+{
+ HANDLE hFile = create_file(filename, overwrite_file ? CREATE_ALWAYS : CREATE_NEW);
+
+ if (hFile == INVALID_HANDLE_VALUE)
+ {
+ DWORD error = GetLastError();
+
+ if (error == ERROR_FILE_EXISTS)
+ {
+ if (!ask_confirm(STRING_OVERWRITE_FILE, filename))
+ {
+ output_message(STRING_CANCELLED);
+ exit(0);
+ }
+
+ hFile = create_file(filename, CREATE_ALWAYS);
+ }
+ else
+ {
+ WCHAR *str;
+
+ FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS, NULL, error, 0, (WCHAR *)&str, 0, NULL);
+ output_writeconsole(str, lstrlenW(str));
+ LocalFree(str);
+ exit(1);
+ }
+ }
+
+ return hFile;
+}
+
static BOOL is_overwrite_switch(const WCHAR *s)
{
if (strlenW(s) > 2)
@@ -40,6 +79,8 @@ int reg_export(int argc, WCHAR *argv[])
{
HKEY root, hkey;
WCHAR *path, *long_key;
+ BOOL overwrite_file = FALSE;
+ HANDLE hFile;
if (argc == 3 || argc > 5)
goto error;
@@ -47,7 +88,7 @@ int reg_export(int argc, WCHAR *argv[])
if (!parse_registry_key(argv[2], &root, &path, &long_key))
return 1;
- if (argc == 5 && !is_overwrite_switch(argv[4]))
+ if (argc == 5 && !(overwrite_file = is_overwrite_switch(argv[4])))
goto error;
if (RegOpenKeyExW(root, path, 0, KEY_READ, &hkey))
@@ -56,7 +97,9 @@ int reg_export(int argc, WCHAR *argv[])
return 1;
}
+ hFile = get_file_handle(argv[3], overwrite_file);
FIXME(": operation not yet implemented\n");
+ CloseHandle(hFile);
RegCloseKey(hkey);
diff --git a/programs/reg/reg.c b/programs/reg/reg.c
index e26928470e..a3e2cf730a 100644
--- a/programs/reg/reg.c
+++ b/programs/reg/reg.c
@@ -111,7 +111,7 @@ BOOL heap_free(void *buf)
return HeapFree(GetProcessHeap(), 0, buf);
}
-static void output_writeconsole(const WCHAR *str, DWORD wlen)
+void output_writeconsole(const WCHAR *str, DWORD wlen)
{
DWORD count, ret;
@@ -176,7 +176,7 @@ static void WINAPIV output_string(const WCHAR *fmt, ...)
}
/* ask_confirm() adapted from programs/cmd/builtins.c */
-static BOOL ask_confirm(unsigned int msgid, WCHAR *reg_info)
+BOOL ask_confirm(unsigned int msgid, WCHAR *reg_info)
{
HMODULE hmod;
WCHAR Ybuffer[4];
diff --git a/programs/reg/reg.h b/programs/reg/reg.h
index 3b5ab86ff9..35f22a5db6 100644
--- a/programs/reg/reg.h
+++ b/programs/reg/reg.h
@@ -27,7 +27,9 @@
void *heap_xalloc(size_t size);
void *heap_xrealloc(void *buf, size_t size);
BOOL heap_free(void *buf);
+void output_writeconsole(const WCHAR *str, DWORD wlen);
void WINAPIV output_message(unsigned int id, ...);
+BOOL ask_confirm(unsigned int msgid, WCHAR *reg_info);
HKEY path_get_rootkey(const WCHAR *path);
BOOL parse_registry_key(const WCHAR *key, HKEY *root, WCHAR **path, WCHAR **long_key);
diff --git a/programs/reg/reg.rc b/programs/reg/reg.rc
index 2ac0b22809..9d8cb882c7 100644
--- a/programs/reg/reg.rc
+++ b/programs/reg/reg.rc
@@ -68,4 +68,5 @@ STRINGTABLE
STRING_ESCAPE_SEQUENCE, "reg: Unrecognized escape sequence [\\%1!c!]\n"
STRING_EXPORT_USAGE, "REG EXPORT key_name file.reg [/y]\n"
STRING_INVALID_SYSTEM_KEY, "reg: Invalid system key [%1]\n"
+ STRING_OVERWRITE_FILE, "The file '%1' already exists. Do you want to overwrite it?"
}
diff --git a/programs/reg/resource.h b/programs/reg/resource.h
index aef2ca9738..518f92ceac 100644
--- a/programs/reg/resource.h
+++ b/programs/reg/resource.h
@@ -58,3 +58,4 @@
#define STRING_ESCAPE_SEQUENCE 135
#define STRING_EXPORT_USAGE 136
#define STRING_INVALID_SYSTEM_KEY 137
+#define STRING_OVERWRITE_FILE 138
diff --git a/programs/reg/tests/reg.c b/programs/reg/tests/reg.c
index 9e4a8145a6..62299aa268 100644
--- a/programs/reg/tests/reg.c
+++ b/programs/reg/tests/reg.c
@@ -4289,7 +4289,7 @@ static BOOL compare_export_(unsigned line, const char *filename, const char *exp
lok(!lstrcmpW(fbuf, wstr), "export data does not match expected data\n");
ret = DeleteFileA(filename);
- todo_wine lok(ret, "DeleteFile failed: %u\n", GetLastError());
+ lok(ret, "DeleteFile failed: %u\n", GetLastError());
exit:
HeapFree(GetProcessHeap(), 0, fbuf);
@@ -4442,7 +4442,7 @@ static void test_export(void)
else /* Windows XP (32-bit) and older */
win_skip("File overwrite flag [/y] not supported; skipping position tests\n");
- todo_wine ok(compare_export("file.reg", empty_key_test, 0), "compare_export() failed\n");
+ ok(compare_export("file.reg", empty_key_test, TODO_REG_COMPARE), "compare_export() failed\n");
/* Test registry export with a simple data structure */
dword = 0x100;
@@ -4451,7 +4451,7 @@ static void test_export(void)
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);
- todo_wine ok(compare_export("file.reg", simple_test, 0), "compare_export() failed\n");
+ ok(compare_export("file.reg", simple_test, TODO_REG_COMPARE), "compare_export() failed\n");
/* Test registry export with a complex data structure */
add_key(hkey, "Subkey1", &subkey);
@@ -4489,7 +4489,7 @@ static void test_export(void)
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);
- todo_wine ok(compare_export("file.reg", complex_test, 0), "compare_export() failed\n");
+ ok(compare_export("file.reg", complex_test, TODO_REG_COMPARE), "compare_export() failed\n");
err = delete_tree(HKEY_CURRENT_USER, KEY_BASE);
ok(err == ERROR_SUCCESS, "delete_tree() failed: %d\n", err);
@@ -4503,7 +4503,7 @@ static void test_export(void)
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);
- todo_wine ok(compare_export("file.reg", key_order_test, 0), "compare_export() failed\n");
+ ok(compare_export("file.reg", key_order_test, TODO_REG_COMPARE), "compare_export() failed\n");
delete_key(hkey, "Subkey1");
delete_key(hkey, "Subkey2");
@@ -4518,7 +4518,7 @@ static void test_export(void)
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);
- todo_wine ok(compare_export("file.reg", value_order_test, 0), "compare_export() failed\n");
+ ok(compare_export("file.reg", value_order_test, TODO_REG_COMPARE), "compare_export() failed\n");
delete_key(HKEY_CURRENT_USER, KEY_BASE);
@@ -4536,7 +4536,7 @@ static void test_export(void)
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);
- todo_wine ok(compare_export("file.reg", empty_hex_test, 0), "compare_export() failed\n");
+ ok(compare_export("file.reg", empty_hex_test, TODO_REG_COMPARE), "compare_export() failed\n");
delete_key(HKEY_CURRENT_USER, KEY_BASE);
@@ -4554,7 +4554,7 @@ static void test_export(void)
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);
- todo_wine ok(compare_export("file.reg", empty_hex_test2, 0), "compare_export() failed\n");
+ ok(compare_export("file.reg", empty_hex_test2, TODO_REG_COMPARE), "compare_export() failed\n");
delete_key(HKEY_CURRENT_USER, KEY_BASE);
@@ -4573,7 +4573,7 @@ static void test_export(void)
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);
- todo_wine ok(compare_export("file.reg", hex_types_test, 0), "compare_export() failed\n");
+ ok(compare_export("file.reg", hex_types_test, TODO_REG_COMPARE), "compare_export() failed\n");
delete_key(HKEY_CURRENT_USER, KEY_BASE);
}
--
2.15.0
More information about the wine-devel
mailing list