[PATCH 2/3] regedit: Use WINAPI functions for better internationalization
Hugh McMaster
hugh.mcmaster at outlook.com
Tue Jul 5 00:15:35 CDT 2016
Signed-off-by: Hugh McMaster <hugh.mcmaster at outlook.com>
---
programs/regedit/regedit.c | 106 ++++++++++++++++++++++++++++----------------
programs/regedit/regedit.rc | 37 ++++++++++++++++
programs/regedit/resource.h | 10 +++++
3 files changed, 114 insertions(+), 39 deletions(-)
diff --git a/programs/regedit/regedit.c b/programs/regedit/regedit.c
index ae268b6..04dd317 100644
--- a/programs/regedit/regedit.c
+++ b/programs/regedit/regedit.c
@@ -23,38 +23,66 @@
#include <windows.h>
#include <shellapi.h>
#include "wine/unicode.h"
+#include "wine/debug.h"
#include "regproc.h"
+#include "resource.h"
-static const char *usage =
- "Usage:\n"
- " regedit filename\n"
- " regedit /E filename [regpath]\n"
- " regedit /D regpath\n"
- "\n"
- "filename - registry file name\n"
- "regpath - name of the registry key\n"
- "\n"
- "When called without any switches, adds the content of the specified\n"
- "file to the registry\n"
- "\n"
- "Switches:\n"
- " /E - exports contents of the specified registry key to the specified\n"
- " file. Exports the whole registry if no key is specified.\n"
- " /D - deletes specified registry key\n"
- " /S - silent execution, can be used with any other switch.\n"
- " Default. The only existing mode, exists for compatibility with Windows regedit.\n"
- " /V - advanced mode, can be used with any other switch.\n"
- " Ignored, exists for compatibility with Windows regedit.\n"
- " /L - location of system.dat file. Can be used with any other switch.\n"
- " Ignored. Exists for compatibility with Windows regedit.\n"
- " /R - location of user.dat file. Can be used with any other switch.\n"
- " Ignored. Exists for compatibility with Windows regedit.\n"
- " /? - print this help. Any other switches are ignored.\n"
- " /C - create registry from file. Not implemented.\n"
- "\n"
- "The switches are case-insensitive, can be prefixed either by '-' or '/'.\n"
- "This program is command-line compatible with Microsoft Windows\n"
- "regedit.\n";
+WINE_DEFAULT_DEBUG_CHANNEL(regedit);
+
+static void output_writeconsole(const WCHAR *str, DWORD wlen)
+{
+ DWORD count, ret;
+
+ ret = WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), str, wlen, &count, NULL);
+ if (!ret)
+ {
+ DWORD len;
+ char *msgA;
+
+ /* WriteConsole() fails on Windows if its output is redirected. If this occurs,
+ * we should call WriteFile() and assume the console encoding is still correct.
+ */
+ len = WideCharToMultiByte(GetConsoleOutputCP(), 0, str, wlen, NULL, 0, NULL, NULL);
+ msgA = HeapAlloc(GetProcessHeap(), 0, len);
+ if (!msgA) return;
+
+ WideCharToMultiByte(GetConsoleOutputCP(), 0, str, wlen, msgA, len, NULL, NULL);
+ WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), msgA, len, &count, FALSE);
+ HeapFree(GetProcessHeap(), 0, msgA);
+ }
+}
+
+static void output_formatstring(const WCHAR *fmt, __ms_va_list va_args)
+{
+ WCHAR *str;
+ DWORD len;
+
+ SetLastError(NO_ERROR);
+ len = FormatMessageW(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ALLOCATE_BUFFER,
+ fmt, 0, 0, (WCHAR *)&str, 0, &va_args);
+ if (len == 0 && GetLastError() != NO_ERROR)
+ {
+ WINE_FIXME("Could not format string: le=%u, fmt=%s\n", GetLastError(), wine_dbgstr_w(fmt));
+ return;
+ }
+ output_writeconsole(str, len);
+ LocalFree(str);
+}
+
+static void __cdecl output_message(unsigned int id, ...)
+{
+ WCHAR fmt[1536];
+ __ms_va_list va_args;
+
+ if (!LoadStringW(GetModuleHandleW(NULL), id, fmt, sizeof(fmt)/sizeof(*fmt)))
+ {
+ WINE_FIXME("LoadString failed with %d\n", GetLastError());
+ return;
+ }
+ __ms_va_start(va_args, id);
+ output_formatstring(fmt, va_args);
+ __ms_va_end(va_args);
+}
typedef enum {
ACTION_ADD, ACTION_EXPORT, ACTION_DELETE
@@ -84,8 +112,7 @@ static BOOL PerformRegAction(REGEDIT_ACTION action, WCHAR **argv, int *i)
}
if (size == 0)
{
- fprintf(stderr, "regedit: File not found \"%ls\" (%d)\n",
- filename, GetLastError());
+ output_message(STRING_FILE_NOT_FOUND, filename);
exit(1);
}
reg_file = _wfopen(realname, rb_mode);
@@ -93,7 +120,7 @@ static BOOL PerformRegAction(REGEDIT_ACTION action, WCHAR **argv, int *i)
{
WCHAR regedit[] = {'r','e','g','e','d','i','t',0};
_wperror(regedit);
- fprintf(stderr, "regedit: Can't open file \"%ls\"\n", filename);
+ output_message(STRING_CANNOT_OPEN_FILE, filename);
exit(1);
}
import_registry_file(reg_file);
@@ -119,7 +146,7 @@ static BOOL PerformRegAction(REGEDIT_ACTION action, WCHAR **argv, int *i)
break;
}
default:
- fprintf(stderr, "regedit: Unhandled action!\n");
+ output_message(STRING_UNHANDLED_ACTION);
exit(1);
break;
}
@@ -157,7 +184,7 @@ BOOL ProcessCmdLine(WCHAR *cmdline)
switch (toupperW(argv[i][1]))
{
case '?':
- fprintf(stderr, usage);
+ output_message(STRING_USAGE);
exit(0);
break;
case 'D':
@@ -176,7 +203,8 @@ BOOL ProcessCmdLine(WCHAR *cmdline)
/* ignored */;
break;
default:
- fprintf(stderr, "regedit: Invalid switch [%ls]\n", argv[i]);
+ output_message(STRING_INVALID_SWITCH, argv[i]);
+ output_message(STRING_HELP);
exit(1);
}
}
@@ -187,13 +215,13 @@ BOOL ProcessCmdLine(WCHAR *cmdline)
{
case ACTION_ADD:
case ACTION_EXPORT:
- fprintf(stderr, "regedit: No file name was specified\n\n");
+ output_message(STRING_NO_FILENAME);
break;
case ACTION_DELETE:
- fprintf(stderr,"regedit: No registry key was specified for removal\n\n");
+ output_message(STRING_NO_REG_KEY);
break;
}
- fprintf(stderr, usage);
+ output_message(STRING_HELP);
exit(1);
}
diff --git a/programs/regedit/regedit.rc b/programs/regedit/regedit.rc
index 2a331c9..18d19b5 100644
--- a/programs/regedit/regedit.rc
+++ b/programs/regedit/regedit.rc
@@ -328,6 +328,43 @@ IDC_REGEDIT ACCELERATORS
VK_F5, ID_VIEW_REFRESH, VIRTKEY
}
+/* Command-line strings */
+STRINGTABLE
+{
+ STRING_USAGE, "Usage:\n\
+\ regedit [options] [filename] [reg_key]\n\
+\n\
+\Options:\n\
+\ [no option] Launch the graphical version of this program.\n\
+\ /L:system.dat The location of the system.dat file to be modified.\n\
+\ Compatible with any other switch. Ignored.\n\
+\ /R:user.dat The location of the user.dat file to be modified.\n\
+\ Compatible with any other switch. Ignored.\n\
+\ /C Import the contents of a registry file.\n\
+\ /D Delete a specified registry key.\n\
+\ /E Export the contents of a specified registry key to a file.\n\
+\ If no key is specified, the entire registry is exported.\n\
+\ /S Silent mode. No messages will be displayed.\n\
+\ /V Launch the GUI in advanced mode. Ignored.\n\
+\ /? Display this information and exit.\n\
+\ [filename] The location of the file containing registry information to\n\
+\ be imported. When used with [/E], this option specifies the\n\
+\ file location where registry information will be exported.\n\
+\ [reg_key] The registry key to be modified.\n\
+\n\
+\Usage examples:\n\
+\ regedit \"import.reg\"\n\
+\ regedit /E \"export.reg\" \"HKEY_CURRENT_USER\\Console\"\n\
+\ regedit /D \"HKEY_LOCAL_MACHINE\\Error\\Path\"\n"
+ STRING_INVALID_SWITCH, "regedit: Invalid or unrecognized switch [%1]\n"
+ STRING_HELP, "Type \"regedit /?\" for help.\n"
+ STRING_NO_FILENAME, "regedit: No filename was specified.\n"
+ STRING_NO_REG_KEY, "regedit: No registry key was specified for removal.\n"
+ STRING_FILE_NOT_FOUND, "regedit: The file '%1' was not found.\n"
+ STRING_CANNOT_OPEN_FILE, "regedit: Unable to open the file '%1'.\n"
+ STRING_UNHANDLED_ACTION, "regedit: Unhandled action.\n"
+}
+
/* define language neutral resources */
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
diff --git a/programs/regedit/resource.h b/programs/regedit/resource.h
index 020765e..37051d8 100644
--- a/programs/regedit/resource.h
+++ b/programs/regedit/resource.h
@@ -157,3 +157,13 @@
#define IDC_EXPORT_PATH 103
#define IDC_STATIC -1
+
+/* Command-line strings */
+#define STRING_USAGE 3001
+#define STRING_INVALID_SWITCH 3002
+#define STRING_HELP 3003
+#define STRING_NO_FILENAME 3004
+#define STRING_NO_REG_KEY 3005
+#define STRING_FILE_NOT_FOUND 3006
+#define STRING_CANNOT_OPEN_FILE 3007
+#define STRING_UNHANDLED_ACTION 3008
--
2.7.4
More information about the wine-patches
mailing list