[PATCH 1/3] regedit: Parse command-line input using Unicode

Hugh McMaster hugh.mcmaster at outlook.com
Tue Jul 5 00:15:22 CDT 2016


Signed-off-by: Hugh McMaster <hugh.mcmaster at outlook.com>
---
 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 acbfbd4..54f00f7 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 593ffef..8f82580 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 cbe3616..ae268b6 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 <ctype.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <windows.h>
+#include <shellapi.h>
+#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;
-
-            filenameW = GetWideString(filename);
-            if (filenameW[0]) {
-                char *reg_key_name = argv[++(*i)];
-                WCHAR* reg_key_nameW;
+            WCHAR *filename = argv[*i];
+            WCHAR *key_name = argv[++(*i)];
 
-                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)
-{
-    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)
+BOOL ProcessCmdLine(WCHAR *cmdline)
 {
-    char *s = lpCmdLine;
-    char **argv;
-    char *tok;
-    int argc = 0, i = 1;
+    WCHAR **argv;
+    int argc, i;
     REGEDIT_ACTION action = ACTION_ADD;
 
-    if (!*lpCmdLine)
-        return FALSE;
+    argv = CommandLineToArgvW(cmdline, &argc);
 
-    while (*s) {
-        if (isspace(*s))
-            i++;
-        s++;
-    }
-
-    s = lpCmdLine;
-    argv = HeapAlloc(GetProcessHeap(), 0, i * sizeof(char *));
+    if (!argv)
+        return FALSE;
 
-    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;
 }
-- 
2.7.4




More information about the wine-patches mailing list