--- /dev/null
+/*
+ * Windows regedit.exe registry editor implementation.
+ *
+ * Copyright 2002 Andriy Palamarchuk
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <windows.h>
+#include "regproc.h"
+
+static 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 is called without any switches adds contents of the specified\n"
+"registry 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"
+" 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. 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. The difference with Windows regedit - this application has\n"
+"command-line interface only.\n";
+
+typedef enum {
+ ACTION_UNDEF, ACTION_ADD, ACTION_EXPORT, ACTION_DELETE
+} REGEDIT_ACTION;
+
+BOOL PerformRegAction(REGEDIT_ACTION action, LPSTR s);
+
+/**
+ * Process unknown switch.
+ *
+ * Params:
+ * chu - the switch character in upper-case.
+ * s - the command line string where s points to the switch character.
+ */
+void error_unknown_switch(char chu, char *s)
+{
+ if (isalpha(chu))
+ {
+ printf("%s: Undefined switch /%c!\n", getAppName(), chu);
+ } else {
+ printf("%s: Alphabetic character is expected after '%c' "
+ "in switch specification\n", getAppName(), *(s - 1));
+ }
+ exit(1);
+}
+
+BOOL ProcessCmdLine(LPSTR lpCmdLine)
+{
+ REGEDIT_ACTION action = ACTION_UNDEF;
+ LPSTR s = lpCmdLine; /* command line pointer */
+ CHAR ch = *s; /* current character */
+
+ setAppName("regedit");
+ while (ch && ((ch == '-') || (ch == '/')))
+ {
+ char chu;
+ char ch2;
+
+ s++;
+ ch = *s;
+ ch2 = *(s+1);
+ chu = toupper(ch);
+ if (!ch2 || isspace(ch2))
+ {
+ if (chu == 'S' || chu == 'V')
+ {
+ /* ignore these switches */
+ } else {
+ switch (chu)
+ {
+ case 'D':
+ action = ACTION_DELETE;
+ break;
+ case 'E':
+ action = ACTION_EXPORT;
+ break;
+ case '?':
+ printf(usage);
+ exit(0);
+ break;
+ default:
+ error_unknown_switch(chu, s);
+ break;
+ }
+ }
+ s++;
+ } else {
+ if (ch2 == ':')
+ {
+ switch (chu)
+ {
+ case 'L':
+ /* fall through */
+ case 'R':
+ s += 2;
+ while (*s && !isspace(*s))
+ {
+ s++;
+ }
+ break;
+ default:
+ error_unknown_switch(chu, s);
+ break;
+ }
+ } else {
+ /* this is a file name, starting from '/' */
+ s--;
+ break;
+ }
+ }
+ /* skip spaces to the next parameter */
+ ch = *s;
+ while (ch && isspace(ch))
+ {
+ s++;
+ ch = *s;
+ }
+ }
+
+ if (*s && action == ACTION_UNDEF)
+ action = ACTION_ADD;
+
+ 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])
+ {
+ printf("%s: No file name is specified\n", getAppName());
+ printf(usage);
+ exit(1);
+ }
+
+ while(filename[0])
+ {
+ reg_file = fopen(filename, "r");
+ if (reg_file)
+ {
+ processRegLines(reg_file, doSetValue);
+ } else {
+ perror("");
+ printf("%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])
+ {
+ printf("%s: No registry key is specified for removal\n",
+ getAppName());
+ printf(usage);
+ exit(1);
+ }
+ delete_registry_key(reg_key_name);
+ break;
+ }
+ case ACTION_EXPORT:
+ {
+ CHAR filename[MAX_PATH];
+
+ filename[0] = '\0';
+ get_file_name(&s, filename);
+ if (!filename[0])
+ {
+ printf("%s: No file name is specified\n", getAppName());
+ printf(usage);
+ exit(1);
+ }
+
+ if (s[0])
+ {
+ CHAR reg_key_name[KEY_MAX_LEN];
+
+ get_file_name(&s, reg_key_name);
+ export_registry_key(filename, reg_key_name);
+ } else {
+ export_registry_key(filename, NULL);
+ }
+ break;
+ }
+ default:
+ printf("%s: Unhandled action!\n", getAppName());
+ exit(1);
+ break;
+ }
+ return TRUE;
+}