/*
* Windows regedit.exe registry editor implementation.
*
- * Copyright 2002 Andriy Palamarchuk
+ * Copyright (C) 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
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include <regedit.h>
+#include "regedit.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 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.\n";
+static const LPCWSTR usage =
+ L"Usage:\n"
+ L" regedit filenames\n"
+ L" regedit /E filename [regpath]\n"
+ L" regedit /D regpath\n"
+ L"\n"
+ L"filenames - List of registry files names\n"
+ L"filename - Registry file name\n"
+ L"regpath - Name of the registry key\n"
+ L"\n"
+ L"When is called without any switches adds contents of the specified\n"
+ L"registry files to the registry.\n"
+ L"\n"
+ L"Switches:\n"
+ L" /E - Exports contents of the specified registry key to the specified\n"
+ L" file. Exports the whole registry if no key is specified.\n"
+ L" /D - Deletes specified registry key\n"
+ L" /S - Silent execution, can be used with any other switch.\n"
+ L" The only existing mode, exists for compatibility with Windows regedit.\n"
+ L" /V - Advanced mode, can be used with any other switch.\n"
+ L" Ignored, exists for compatibility with Windows regedit.\n"
+ L" /L - Location of system.dat file. Can be used with any other switch.\n"
+ L" Ignored. Exists for compatibility with Windows regedit.\n"
+ L" /R - Location of user.dat file. Can be used with any other switch.\n"
+ L" Ignored. Exists for compatibility with Windows regedit.\n"
+ L" /? - Print this help. Any other switches are ignored.\n"
+ L" /C - Create registry from. Not implemented.\n"
+ L"\n"
+ L"The switches are case-insensitive, can be prefixed either by '-' or '/'.\n"
+ L"This program is command-line compatible with Microsoft Windows\n"
+ L"regedit.\n";
typedef enum
{
} REGEDIT_ACTION;
-const CHAR *getAppName(void)
+LPCWSTR getAppName(void)
{
- return "regedit";
+ return L"regedit";
}
/******************************************************************************
void get_file_name(LPWSTR *command_line, LPWSTR file_name)
{
WCHAR *s = *command_line;
- int pos = 0; /* position of pointer "s" in *command_line */
+ size_t pos = 0; /* position of pointer "s" in *command_line */
file_name[0] = 0;
if (!s[0])
{
if (!s[0])
{
- fprintf(stderr, "%s: Unexpected end of file name!\n", getAppName());
+ fwprintf(stderr, L"%s: Unexpected end of file name!\n", getAppName());
exit(1);
}
s++;
pos++;
}
}
- memcpy(file_name, *command_line, pos * sizeof((*command_line)[0]));
+ memcpy(file_name, *command_line, pos * sizeof(WCHAR));
/* remove the last backslash */
if (file_name[pos - 1] == L'\\')
{
(*command_line) += pos;
}
-BOOL PerformRegAction(REGEDIT_ACTION action, LPWSTR s)
+BOOL PerformRegAction(REGEDIT_ACTION action, LPWSTR s, BOOL silent)
{
- TCHAR szTitle[256], szText[256];
switch (action)
{
- case ACTION_ADD:
- {
- WCHAR filename[MAX_PATH];
- FILE *fp;
-
- get_file_name(&s, filename);
- if (!filename[0])
+ case ACTION_ADD:
{
- fprintf(stderr, "%s: No file name is specified\n", getAppName());
- fprintf(stderr, usage);
- exit(4);
- }
+ WCHAR szText[512];
+ WCHAR filename[MAX_PATH];
+ FILE *fp;
- while(filename[0])
- {
- fp = _wfopen(filename, L"r");
- if (fp == NULL)
+ get_file_name(&s, filename);
+ if (!filename[0])
{
- LPSTR p = GetMultiByteString(filename);
- perror("");
- fprintf(stderr, "%s: Can't open file \"%s\"\n", getAppName(), p);
- HeapFree(GetProcessHeap(), 0, p);
- exit(5);
+ InfoMessageBox(NULL, MB_OK | MB_ICONINFORMATION, NULL, L"No file name is specified.");
+ InfoMessageBox(NULL, MB_OK | MB_ICONINFORMATION, szTitle, usage);
+ exit(4);
}
- 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);
+ while (filename[0])
+ {
+ /* Request import confirmation */
+ if (!silent)
+ {
+ int choice;
+
+ LoadStringW(hInst, IDS_IMPORT_PROMPT, szText, COUNT_OF(szText));
+
+ choice = InfoMessageBox(NULL, MB_YESNOCANCEL | MB_ICONWARNING, szTitle, szText, filename);
+
+ switch (choice)
+ {
+ case IDNO:
+ goto cont;
+ case IDCANCEL:
+ /* The cancel case is useful if the user is importing more than one registry file
+ at a time, and wants to back out anytime during the import process. This way, the
+ user doesn't have to resort to ending the regedit process abruptly just to cancel
+ the operation. */
+ return TRUE;
+ default:
+ break;
+ }
+ }
+
+ /* Open the file */
+ fp = _wfopen(filename, L"r");
+
+ /* Import it */
+ if (fp == NULL || !import_registry_file(fp))
+ {
+ /* Error opening the file */
+ if (!silent)
+ {
+ LoadStringW(hInst, IDS_IMPORT_ERROR, szText, COUNT_OF(szText));
+ InfoMessageBox(NULL, MB_OK | MB_ICONERROR, szTitle, szText, filename);
+ }
+ }
+ else
+ {
+ /* Show successful import */
+ if (!silent)
+ {
+ LoadStringW(hInst, IDS_IMPORT_OK, szText, COUNT_OF(szText));
+ InfoMessageBox(NULL, MB_OK | MB_ICONINFORMATION, szTitle, szText, filename);
+ }
+ }
+
+ /* Close the file */
+ if (fp) fclose(fp);
+
+cont:
+ get_file_name(&s, filename);
+ }
+ break;
}
- if (s[0])
+ case ACTION_DELETE:
{
WCHAR reg_key_name[KEY_MAX_LEN];
get_file_name(&s, reg_key_name);
- export_registry_key(filename, reg_key_name, REG_FORMAT_4);
+ if (!reg_key_name[0])
+ {
+ InfoMessageBox(NULL, MB_OK | MB_ICONINFORMATION, NULL, L"No registry key is specified for removal.");
+ InfoMessageBox(NULL, MB_OK | MB_ICONINFORMATION, szTitle, usage);
+ exit(6);
+ }
+ delete_registry_key(reg_key_name);
+ break;
}
- else
+
+ case ACTION_EXPORT:
{
- export_registry_key(filename, NULL, REG_FORMAT_4);
+ WCHAR filename[MAX_PATH];
+
+ filename[0] = L'\0';
+ get_file_name(&s, filename);
+ if (!filename[0])
+ {
+ InfoMessageBox(NULL, MB_OK | MB_ICONINFORMATION, NULL, L"No file name is specified.");
+ InfoMessageBox(NULL, MB_OK | MB_ICONINFORMATION, szTitle, 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;
}
- break;
- }
- default:
- fprintf(stderr, "%s: Unhandled action!\n", getAppName());
- exit(8);
- break;
+
+ default:
+ fwprintf(stderr, L"%s: Unhandled action!\n", getAppName());
+ exit(8);
+ break;
}
+
return TRUE;
}
{
if (iswalpha(chu))
{
- fprintf(stderr, "%s: Undefined switch /%c!\n", getAppName(), chu);
+ fwprintf(stderr, L"%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));
+ fwprintf(stderr, L"%s: Alphabetic character is expected after '%c' "
+ L"in switch specification\n", getAppName(), *(s - 1));
}
exit(1);
}
BOOL ProcessCmdLine(LPWSTR lpCmdLine)
{
+ BOOL silent = FALSE;
REGEDIT_ACTION action = ACTION_UNDEF;
LPWSTR s = lpCmdLine; /* command line pointer */
WCHAR ch = *s; /* current character */
s++;
ch = *s;
ch2 = *(s + 1);
- chu = (WCHAR)towupper(ch);
+ chu = towupper(ch);
if (!ch2 || iswspace(ch2))
{
- if (chu == L'S' || chu == L'V')
+ if (chu == L'S')
{
- /* ignore these switches */
+ /* Silence dialogs */
+ silent = TRUE;
+ }
+ else if (chu == L'V')
+ {
+ /* Ignore this switch */
}
else
{
switch (chu)
{
- case L'D':
- action = ACTION_DELETE;
- break;
- case L'E':
- action = ACTION_EXPORT;
- break;
- case L'?':
- fprintf(stderr, usage);
- exit(3);
- break;
- default:
- error_unknown_switch(chu, s);
- break;
+ case L'D':
+ action = ACTION_DELETE;
+ break;
+ case L'E':
+ action = ACTION_EXPORT;
+ break;
+ case L'?':
+ InfoMessageBox(NULL, MB_OK | MB_ICONINFORMATION, szTitle, usage);
+ exit(3);
+ break;
+ default:
+ error_unknown_switch(chu, s);
+ break;
}
}
s++;
{
switch (chu)
{
- case L'L':
- /* fall through */
- case L'R':
- s += 2;
- while (*s && !iswspace(*s))
- {
- s++;
- }
- break;
- default:
- error_unknown_switch(chu, s);
- break;
+ case L'L':
+ /* fall through */
+ case L'R':
+ s += 2;
+ while (*s && !iswspace(*s))
+ {
+ s++;
+ }
+ break;
+ default:
+ error_unknown_switch(chu, s);
+ break;
}
}
else
}
if (*s && 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;
+ action = ACTION_ADD;
- return PerformRegAction(action, s);
+ if (action != ACTION_UNDEF)
+ return PerformRegAction(action, s, silent);
+ else
+ return FALSE;
}