From 256290f74f9d51fce5bdf2b48e93e65f42fc2588 Mon Sep 17 00:00:00 2001 From: Hugh McMaster Date: Tue, 5 Jul 2016 05:15:22 +0000 Subject: [PATCH] regedit: Parse command-line input using Unicode. Signed-off-by: Hugh McMaster Signed-off-by: Alexandre Julliard --- programs/regedit/Makefile.in | 2 +- programs/regedit/main.c | 9 +- programs/regedit/regedit.c | 165 +++++++++++------------------------ 3 files changed, 53 insertions(+), 123 deletions(-) diff --git a/programs/regedit/Makefile.in b/programs/regedit/Makefile.in index acbfbd4f8ee..54f00f71b5b 100644 --- a/programs/regedit/Makefile.in +++ b/programs/regedit/Makefile.in @@ -1,5 +1,5 @@ MODULE = regedit.exe -APPMODE = -mwindows -mno-cygwin +APPMODE = -mwindows -municode -mno-cygwin IMPORTS = advapi32 DELAYIMPORTS = shlwapi shell32 comdlg32 comctl32 user32 gdi32 diff --git a/programs/regedit/main.c b/programs/regedit/main.c index 593ffef01c1..8f825801803 100644 --- a/programs/regedit/main.c +++ b/programs/regedit/main.c @@ -30,7 +30,7 @@ WCHAR g_pszDefaultValueName[64]; -BOOL ProcessCmdLine(LPSTR lpCmdLine); +BOOL ProcessCmdLine(WCHAR *cmdline); static const WCHAR hkey_local_machine[] = {'H','K','E','Y','_','L','O','C','A','L','_','M','A','C','H','I','N','E',0}; static const WCHAR hkey_users[] = {'H','K','E','Y','_','U','S','E','R','S',0}; @@ -134,15 +134,12 @@ static BOOL TranslateChildTabMessage(MSG *msg) return TRUE; } -int APIENTRY WinMain(HINSTANCE hInstance, - HINSTANCE hPrevInstance, - LPSTR lpCmdLine, - int nCmdShow) +int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow) { MSG msg; HACCEL hAccel; - if (ProcessCmdLine(lpCmdLine)) { + if (ProcessCmdLine(GetCommandLineW())) { return 0; } diff --git a/programs/regedit/regedit.c b/programs/regedit/regedit.c index cbe3616b099..ae268b69978 100644 --- a/programs/regedit/regedit.c +++ b/programs/regedit/regedit.c @@ -18,10 +18,11 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include #include #include #include +#include +#include "wine/unicode.h" #include "regproc.h" static const char *usage = @@ -59,43 +60,41 @@ typedef enum { ACTION_ADD, ACTION_EXPORT, ACTION_DELETE } REGEDIT_ACTION; -static BOOL PerformRegAction(REGEDIT_ACTION action, char **argv, int *i) +static BOOL PerformRegAction(REGEDIT_ACTION action, WCHAR **argv, int *i) { switch (action) { case ACTION_ADD: { - char *filename = argv[*i]; + WCHAR *filename = argv[*i]; + WCHAR hyphen[] = {'-',0}; FILE *reg_file; - if (filename[0]) { - char* realname = NULL; + if (!strcmpW(filename, hyphen)) + reg_file = stdin; + else + { + int size; + WCHAR *realname = NULL; + WCHAR rb_mode[] = {'r','b',0}; - if (strcmp(filename, "-") == 0) + size = SearchPathW(NULL, filename, NULL, 0, NULL, NULL); + if (size > 0) { - reg_file = stdin; + realname = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR)); + size = SearchPathW(NULL, filename, NULL, size, realname, NULL); } - else + if (size == 0) { - int size; - - size = SearchPathA(NULL, filename, NULL, 0, NULL, NULL); - if (size > 0) - { - realname = HeapAlloc(GetProcessHeap(), 0, size); - size = SearchPathA(NULL, filename, NULL, size, realname, NULL); - } - if (size == 0) - { - fprintf(stderr, "regedit: File not found \"%s\" (%d)\n", - filename, GetLastError()); - exit(1); - } - reg_file = fopen(realname, "rb"); - if (reg_file == NULL) - { - perror(""); - fprintf(stderr, "regedit: Can't open file \"%s\"\n", filename); - exit(1); - } + fprintf(stderr, "regedit: File not found \"%ls\" (%d)\n", + filename, GetLastError()); + exit(1); + } + reg_file = _wfopen(realname, rb_mode); + if (reg_file == NULL) + { + WCHAR regedit[] = {'r','e','g','e','d','i','t',0}; + _wperror(regedit); + fprintf(stderr, "regedit: Can't open file \"%ls\"\n", filename); + exit(1); } import_registry_file(reg_file); if (realname) @@ -106,29 +105,17 @@ static BOOL PerformRegAction(REGEDIT_ACTION action, char **argv, int *i) } break; } - case ACTION_DELETE: { - WCHAR *reg_key_nameW = GetWideString(argv[*i]); - - delete_registry_key(reg_key_nameW); - HeapFree(GetProcessHeap(), 0, reg_key_nameW); + case ACTION_DELETE: + delete_registry_key(argv[*i]); break; - } case ACTION_EXPORT: { - char *filename = argv[*i]; - WCHAR* filenameW; + WCHAR *filename = argv[*i]; + WCHAR *key_name = argv[++(*i)]; - filenameW = GetWideString(filename); - if (filenameW[0]) { - char *reg_key_name = argv[++(*i)]; - WCHAR* reg_key_nameW; - - reg_key_nameW = GetWideString(reg_key_name); - export_registry_key(filenameW, reg_key_nameW, REG_FORMAT_4); - HeapFree(GetProcessHeap(), 0, reg_key_nameW); - } else { - export_registry_key(filenameW, NULL, REG_FORMAT_4); - } - HeapFree(GetProcessHeap(), 0, filenameW); + if (key_name && *key_name) + export_registry_key(filename, key_name, REG_FORMAT_4); + else + export_registry_key(filename, NULL, REG_FORMAT_4); break; } default: @@ -139,76 +126,24 @@ static BOOL PerformRegAction(REGEDIT_ACTION action, char **argv, int *i) return TRUE; } -static char *get_token(char *input, char **next) +BOOL ProcessCmdLine(WCHAR *cmdline) { - char *ch = input; - char *str; - - while (*ch && isspace(*ch)) - ch++; - - str = ch; - - if (*ch == '"') { - ch++; - str = ch; - for (;;) { - while (*ch && (*ch != '"')) - ch++; - - if (!*ch) - break; - - if (*(ch - 1) == '\\') { - ch++; - continue; - } - break; - } - } - else { - while (*ch && !isspace(*ch)) - ch++; - } - - if (*ch) { - *ch = 0; - ch++; - } - - *next = ch; - return str; -} - -BOOL ProcessCmdLine(LPSTR lpCmdLine) -{ - char *s = lpCmdLine; - char **argv; - char *tok; - int argc = 0, i = 1; + WCHAR **argv; + int argc, i; REGEDIT_ACTION action = ACTION_ADD; - if (!*lpCmdLine) + argv = CommandLineToArgvW(cmdline, &argc); + + if (!argv) return FALSE; - while (*s) { - if (isspace(*s)) - i++; - s++; - } - - s = lpCmdLine; - argv = HeapAlloc(GetProcessHeap(), 0, i * sizeof(char *)); - - for (i = 0; *s; i++) + if (argc == 1) { - tok = get_token(s, &s); - argv[i] = HeapAlloc(GetProcessHeap(), 0, strlen(tok) + 1); - strcpy(argv[i], tok); - argc++; + LocalFree(argv); + return FALSE; } - for (i = 0; i < argc; i++) + for (i = 1; i < argc; i++) { if (argv[i][0] != '/' && argv[i][0] != '-') break; /* No flags specified. */ @@ -219,7 +154,7 @@ BOOL ProcessCmdLine(LPSTR lpCmdLine) if (argv[i][1] && argv[i][2] && argv[i][2] != ':') break; /* This is a file path beginning with '/'. */ - switch (toupper(argv[i][1])) + switch (toupperW(argv[i][1])) { case '?': fprintf(stderr, usage); @@ -241,7 +176,7 @@ BOOL ProcessCmdLine(LPSTR lpCmdLine) /* ignored */; break; default: - fprintf(stderr, "regedit: Invalid switch [%s]\n", argv[i]); + fprintf(stderr, "regedit: Invalid switch [%ls]\n", argv[i]); exit(1); } } @@ -265,9 +200,7 @@ BOOL ProcessCmdLine(LPSTR lpCmdLine) for (; i < argc; i++) PerformRegAction(action, argv, &i); - for (i = 0; i < argc; i++) - HeapFree(GetProcessHeap(), 0, argv[i]); - HeapFree(GetProcessHeap(), 0, argv); + LocalFree(argv); return TRUE; }