* Sync with recent trunk (r52637).
[reactos.git] / base / applications / regedit / regedit.c
index e157295..e49f0e0 100644 (file)
@@ -52,11 +52,169 @@ static const char *usage =
     "This program is command-line compatible with Microsoft Windows\n"
     "regedit.\n";
 
-typedef enum {
+typedef enum
+{
     ACTION_UNDEF, ACTION_ADD, ACTION_EXPORT, ACTION_DELETE
 } REGEDIT_ACTION;
 
-BOOL PerformRegAction(REGEDIT_ACTION action, LPSTR s);
+
+const CHAR *getAppName(void)
+{
+    return "regedit";
+}
+
+/******************************************************************************
+ * Copies file name from command line string to the buffer.
+ * Rewinds the command line string pointer to the next non-space character
+ * after the file name.
+ * Buffer contains an empty string if no filename was found;
+ *
+ * params:
+ * command_line - command line current position pointer
+ *      where *s[0] is the first symbol of the file name.
+ * file_name - buffer to write the file name to.
+ */
+void get_file_name(LPWSTR *command_line, LPWSTR file_name)
+{
+    WCHAR *s = *command_line;
+    int pos = 0;                /* position of pointer "s" in *command_line */
+    file_name[0] = 0;
+
+    if (!s[0])
+    {
+        return;
+    }
+
+    if (s[0] == L'"')
+    {
+        s++;
+        (*command_line)++;
+        while(s[0] != L'"')
+        {
+            if (!s[0])
+            {
+                fprintf(stderr, "%s: Unexpected end of file name!\n", getAppName());
+                exit(1);
+            }
+            s++;
+            pos++;
+        }
+    }
+    else
+    {
+        while(s[0] && !iswspace(s[0]))
+        {
+            s++;
+            pos++;
+        }
+    }
+    memcpy(file_name, *command_line, pos * sizeof((*command_line)[0]));
+    /* remove the last backslash */
+    if (file_name[pos - 1] == L'\\')
+    {
+        file_name[pos - 1] = L'\0';
+    }
+    else
+    {
+        file_name[pos] = L'\0';
+    }
+
+    if (s[0])
+    {
+        s++;
+        pos++;
+    }
+    while(s[0] && iswspace(s[0]))
+    {
+        s++;
+        pos++;
+    }
+    (*command_line) += pos;
+}
+
+BOOL PerformRegAction(REGEDIT_ACTION action, LPWSTR s)
+{
+    TCHAR szTitle[256], szText[256];
+    switch (action)
+    {
+    case ACTION_ADD:
+    {
+        WCHAR filename[MAX_PATH];
+        FILE *fp;
+
+        get_file_name(&s, filename);
+        if (!filename[0])
+        {
+            fprintf(stderr, "%s: No file name is specified\n", getAppName());
+            fprintf(stderr, usage);
+            exit(4);
+        }
+
+        while(filename[0])
+        {
+            fp = _wfopen(filename, L"r");
+            if (fp == NULL)
+            {
+                LPSTR p = GetMultiByteString(filename);
+                perror("");
+                fprintf(stderr, "%s: Can't open file \"%s\"\n", getAppName(), p);
+                HeapFree(GetProcessHeap(), 0, p);
+                exit(5);
+            }
+            import_registry_file(fp);
+            get_file_name(&s, filename);
+            LoadString(hInst, IDS_APP_TITLE, szTitle, sizeof(szTitle));
+            LoadString(hInst, IDS_IMPORTED_OK, szText, sizeof(szTitle));
+            /* show successful import */
+            MessageBox(NULL, szText, szTitle, MB_OK);
+        }
+        break;
+    }
+    case ACTION_DELETE:
+    {
+        WCHAR reg_key_name[KEY_MAX_LEN];
+        get_file_name(&s, reg_key_name);
+        if (!reg_key_name[0])
+        {
+            fprintf(stderr, "%s: No registry key is specified for removal\n", getAppName());
+            fprintf(stderr, usage);
+            exit(6);
+        }
+        delete_registry_key(reg_key_name);
+        break;
+    }
+    case ACTION_EXPORT:
+    {
+        WCHAR filename[MAX_PATH];
+
+        filename[0] = _T('\0');
+        get_file_name(&s, filename);
+        if (!filename[0])
+        {
+            fprintf(stderr, "%s: No file name is specified\n", getAppName());
+            fprintf(stderr, usage);
+            exit(7);
+        }
+
+        if (s[0])
+        {
+            WCHAR reg_key_name[KEY_MAX_LEN];
+            get_file_name(&s, reg_key_name);
+            export_registry_key(filename, reg_key_name, REG_FORMAT_4);
+        }
+        else
+        {
+            export_registry_key(filename, NULL, REG_FORMAT_4);
+        }
+        break;
+    }
+    default:
+        fprintf(stderr, "%s: Unhandled action!\n", getAppName());
+        exit(8);
+        break;
+    }
+    return TRUE;
+}
 
 /**
  * Process unknown switch.
@@ -65,46 +223,54 @@ BOOL PerformRegAction(REGEDIT_ACTION action, LPSTR s);
  *   chu - the switch character in upper-case.
  *   s - the command line string where s points to the switch character.
  */
-static void error_unknown_switch(char chu, char *s)
+static void error_unknown_switch(WCHAR chu, LPWSTR s)
 {
-    if (isalpha(chu)) {
-        fprintf(stderr,"%s: Undefined switch /%c!\n", getAppName(), chu);
-    } else {
-        fprintf(stderr,"%s: Alphabetic character is expected after '%c' "
+    if (iswalpha(chu))
+    {
+        fprintf(stderr, "%s: Undefined switch /%c!\n", getAppName(), chu);
+    }
+    else
+    {
+        fprintf(stderr, "%s: Alphabetic character is expected after '%c' "
                 "in swit ch specification\n", getAppName(), *(s - 1));
     }
     exit(1);
 }
 
-BOOL ProcessCmdLine(LPSTR lpCmdLine)
+BOOL ProcessCmdLine(LPWSTR lpCmdLine)
 {
     REGEDIT_ACTION action = ACTION_UNDEF;
-    LPSTR s = lpCmdLine;        /* command line pointer */
-    CHAR ch = *s;               /* current character */
+    LPWSTR s = lpCmdLine;       /* command line pointer */
+    WCHAR ch = *s;              /* current character */
 
-    setAppName("regedit");
-    while (ch && ((ch == '-') || (ch == '/'))) {
-        char chu;
-        char ch2;
+    while (ch && ((ch == L'-') || (ch == L'/')))
+    {
+        WCHAR chu;
+        WCHAR ch2;
 
         s++;
         ch = *s;
-        ch2 = *(s+1);
-        chu = (CHAR) toupper(ch);
-        if (!ch2 || isspace(ch2)) {
-            if (chu == 'S' || chu == 'V') {
+        ch2 = *(s + 1);
+        chu = (WCHAR)towupper(ch);
+        if (!ch2 || iswspace(ch2))
+        {
+            if (chu == L'S' || chu == L'V')
+            {
                 /* ignore these switches */
-            } else {
-                switch (chu) {
-                case 'D':
+            }
+            else
+            {
+                switch (chu)
+                {
+                case L'D':
                     action = ACTION_DELETE;
                     break;
-                case 'E':
+                case L'E':
                     action = ACTION_EXPORT;
                     break;
-                case '?':
-                    fprintf(stderr,usage);
-                    exit(0);
+                case L'?':
+                    fprintf(stderr, usage);
+                    exit(3);
                     break;
                 default:
                     error_unknown_switch(chu, s);
@@ -112,14 +278,19 @@ BOOL ProcessCmdLine(LPSTR lpCmdLine)
                 }
             }
             s++;
-        } else {
-            if (ch2 == ':') {
-                switch (chu) {
-                case 'L':
+        }
+        else
+        {
+            if (ch2 == L':')
+            {
+                switch (chu)
+                {
+                case L'L':
                     /* fall through */
-                case 'R':
+                case L'R':
                     s += 2;
-                    while (*s && !isspace(*s)) {
+                    while (*s && !iswspace(*s))
+                    {
                         s++;
                     }
                     break;
@@ -127,7 +298,9 @@ BOOL ProcessCmdLine(LPSTR lpCmdLine)
                     error_unknown_switch(chu, s);
                     break;
                 }
-            } else {
+            }
+            else
+            {
                 /* this is a file name, starting from '/' */
                 s--;
                 break;
@@ -135,99 +308,27 @@ BOOL ProcessCmdLine(LPSTR lpCmdLine)
         }
         /* skip spaces to the next parameter */
         ch = *s;
-        while (ch && isspace(ch)) {
+        while (ch && iswspace(ch))
+        {
             s++;
             ch = *s;
         }
     }
 
     if (*s && action == ACTION_UNDEF)
-        action = ACTION_ADD;
-
-    if (action == ACTION_UNDEF)
+           {
+         TCHAR szTitle[256], szText[256];
+         LoadString(hInst, IDS_APP_TITLE, szTitle, sizeof(szTitle));
+         LoadString(hInst, IDS_IMPORT_PROMPT, szText, sizeof(szTitle));        
+         /* request import confirmation */
+            if (MessageBox(NULL, szText, szTitle, MB_YESNO) == IDYES) 
+            {
+          action = ACTION_ADD;
+         }
+                else return TRUE;
+        }
+       if (action == ACTION_UNDEF)
         return FALSE;
 
     return PerformRegAction(action, s);
 }
-
-BOOL PerformRegAction(REGEDIT_ACTION action, LPSTR s)
-{
-    switch (action) {
-    case ACTION_ADD: {
-            CHAR filename[MAX_PATH];
-            FILE *reg_file;
-
-            get_file_name(&s, filename);
-            if (!filename[0]) {
-                fprintf(stderr,"%s: No file name is specified\n", getAppName());
-                fprintf(stderr,usage);
-                exit(1);
-            }
-
-            while(filename[0]) {
-                reg_file = fopen(filename, "r");
-                if (reg_file) {
-                    processRegLines(reg_file, doSetValue);
-                    fclose(reg_file);
-                } else {
-                    perror("");
-                    fprintf(stderr,"%s: Can't open file \"%s\"\n", getAppName(), filename);
-                    exit(1);
-                }
-                get_file_name(&s, filename);
-            }
-            break;
-        }
-    case ACTION_DELETE: {
-            CHAR reg_key_name[KEY_MAX_LEN];
-
-            get_file_name(&s, reg_key_name);
-            if (!reg_key_name[0]) {
-                fprintf(stderr,"%s: No registry key is specified for removal\n",
-                        getAppName());
-                fprintf(stderr,usage);
-                exit(1);
-            }
-            delete_registry_key(reg_key_name);
-            break;
-        }
-    case ACTION_EXPORT: {
-            CHAR filename[MAX_PATH];
-            LPCTSTR pszFilename;
-#ifdef UNICODE
-            WCHAR filename_wide[MAX_PATH];
-#endif
-
-            filename[0] = '\0';
-            get_file_name(&s, filename);
-            if (!filename[0]) {
-                fprintf(stderr,"%s: No file name is specified\n", getAppName());
-                fprintf(stderr,usage);
-                exit(1);
-            }
-
-#ifdef UNICODE
-            MultiByteToWideChar(CP_ACP, 0, filename, -1, filename_wide,
-                sizeof(filename_wide) / sizeof(filename_wide[0]));
-            pszFilename = filename_wide;
-#else
-            pszFilename = filename;
-#endif
-
-            if (s[0]) {
-                CHAR reg_key_name[KEY_MAX_LEN];
-
-                get_file_name(&s, reg_key_name);
-                export_registry_key(pszFilename, reg_key_name);
-            } else {
-                export_registry_key(pszFilename, NULL);
-            }
-            break;
-        }
-    default:
-        fprintf(stderr,"%s: Unhandled action!\n", getAppName());
-        exit(1);
-        break;
-    }
-    return TRUE;
-}