regedit: Parse command-line input using Unicode.
Signed-off-by: Hugh McMaster <hugh.mcmaster@outlook.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
d44ec680da
commit
256290f74f
|
@ -1,5 +1,5 @@
|
||||||
MODULE = regedit.exe
|
MODULE = regedit.exe
|
||||||
APPMODE = -mwindows -mno-cygwin
|
APPMODE = -mwindows -municode -mno-cygwin
|
||||||
IMPORTS = advapi32
|
IMPORTS = advapi32
|
||||||
DELAYIMPORTS = shlwapi shell32 comdlg32 comctl32 user32 gdi32
|
DELAYIMPORTS = shlwapi shell32 comdlg32 comctl32 user32 gdi32
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
|
|
||||||
WCHAR g_pszDefaultValueName[64];
|
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_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};
|
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;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int APIENTRY WinMain(HINSTANCE hInstance,
|
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow)
|
||||||
HINSTANCE hPrevInstance,
|
|
||||||
LPSTR lpCmdLine,
|
|
||||||
int nCmdShow)
|
|
||||||
{
|
{
|
||||||
MSG msg;
|
MSG msg;
|
||||||
HACCEL hAccel;
|
HACCEL hAccel;
|
||||||
|
|
||||||
if (ProcessCmdLine(lpCmdLine)) {
|
if (ProcessCmdLine(GetCommandLineW())) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,10 +18,11 @@
|
||||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#include <shellapi.h>
|
||||||
|
#include "wine/unicode.h"
|
||||||
#include "regproc.h"
|
#include "regproc.h"
|
||||||
|
|
||||||
static const char *usage =
|
static const char *usage =
|
||||||
|
@ -59,43 +60,41 @@ typedef enum {
|
||||||
ACTION_ADD, ACTION_EXPORT, ACTION_DELETE
|
ACTION_ADD, ACTION_EXPORT, ACTION_DELETE
|
||||||
} REGEDIT_ACTION;
|
} REGEDIT_ACTION;
|
||||||
|
|
||||||
static BOOL PerformRegAction(REGEDIT_ACTION action, char **argv, int *i)
|
static BOOL PerformRegAction(REGEDIT_ACTION action, WCHAR **argv, int *i)
|
||||||
{
|
{
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case ACTION_ADD: {
|
case ACTION_ADD: {
|
||||||
char *filename = argv[*i];
|
WCHAR *filename = argv[*i];
|
||||||
|
WCHAR hyphen[] = {'-',0};
|
||||||
FILE *reg_file;
|
FILE *reg_file;
|
||||||
|
|
||||||
if (filename[0]) {
|
if (!strcmpW(filename, hyphen))
|
||||||
char* realname = NULL;
|
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;
|
fprintf(stderr, "regedit: File not found \"%ls\" (%d)\n",
|
||||||
|
filename, GetLastError());
|
||||||
size = SearchPathA(NULL, filename, NULL, 0, NULL, NULL);
|
exit(1);
|
||||||
if (size > 0)
|
}
|
||||||
{
|
reg_file = _wfopen(realname, rb_mode);
|
||||||
realname = HeapAlloc(GetProcessHeap(), 0, size);
|
if (reg_file == NULL)
|
||||||
size = SearchPathA(NULL, filename, NULL, size, realname, NULL);
|
{
|
||||||
}
|
WCHAR regedit[] = {'r','e','g','e','d','i','t',0};
|
||||||
if (size == 0)
|
_wperror(regedit);
|
||||||
{
|
fprintf(stderr, "regedit: Can't open file \"%ls\"\n", filename);
|
||||||
fprintf(stderr, "regedit: File not found \"%s\" (%d)\n",
|
exit(1);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
import_registry_file(reg_file);
|
import_registry_file(reg_file);
|
||||||
if (realname)
|
if (realname)
|
||||||
|
@ -106,29 +105,17 @@ static BOOL PerformRegAction(REGEDIT_ACTION action, char **argv, int *i)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ACTION_DELETE: {
|
case ACTION_DELETE:
|
||||||
WCHAR *reg_key_nameW = GetWideString(argv[*i]);
|
delete_registry_key(argv[*i]);
|
||||||
|
|
||||||
delete_registry_key(reg_key_nameW);
|
|
||||||
HeapFree(GetProcessHeap(), 0, reg_key_nameW);
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case ACTION_EXPORT: {
|
case ACTION_EXPORT: {
|
||||||
char *filename = argv[*i];
|
WCHAR *filename = argv[*i];
|
||||||
WCHAR* filenameW;
|
WCHAR *key_name = argv[++(*i)];
|
||||||
|
|
||||||
filenameW = GetWideString(filename);
|
if (key_name && *key_name)
|
||||||
if (filenameW[0]) {
|
export_registry_key(filename, key_name, REG_FORMAT_4);
|
||||||
char *reg_key_name = argv[++(*i)];
|
else
|
||||||
WCHAR* reg_key_nameW;
|
export_registry_key(filename, NULL, REG_FORMAT_4);
|
||||||
|
|
||||||
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);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -139,76 +126,24 @@ static BOOL PerformRegAction(REGEDIT_ACTION action, char **argv, int *i)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *get_token(char *input, char **next)
|
BOOL ProcessCmdLine(WCHAR *cmdline)
|
||||||
{
|
{
|
||||||
char *ch = input;
|
WCHAR **argv;
|
||||||
char *str;
|
int argc, i;
|
||||||
|
|
||||||
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;
|
|
||||||
REGEDIT_ACTION action = ACTION_ADD;
|
REGEDIT_ACTION action = ACTION_ADD;
|
||||||
|
|
||||||
if (!*lpCmdLine)
|
argv = CommandLineToArgvW(cmdline, &argc);
|
||||||
|
|
||||||
|
if (!argv)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
while (*s) {
|
if (argc == 1)
|
||||||
if (isspace(*s))
|
|
||||||
i++;
|
|
||||||
s++;
|
|
||||||
}
|
|
||||||
|
|
||||||
s = lpCmdLine;
|
|
||||||
argv = HeapAlloc(GetProcessHeap(), 0, i * sizeof(char *));
|
|
||||||
|
|
||||||
for (i = 0; *s; i++)
|
|
||||||
{
|
{
|
||||||
tok = get_token(s, &s);
|
LocalFree(argv);
|
||||||
argv[i] = HeapAlloc(GetProcessHeap(), 0, strlen(tok) + 1);
|
return FALSE;
|
||||||
strcpy(argv[i], tok);
|
|
||||||
argc++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < argc; i++)
|
for (i = 1; i < argc; i++)
|
||||||
{
|
{
|
||||||
if (argv[i][0] != '/' && argv[i][0] != '-')
|
if (argv[i][0] != '/' && argv[i][0] != '-')
|
||||||
break; /* No flags specified. */
|
break; /* No flags specified. */
|
||||||
|
@ -219,7 +154,7 @@ BOOL ProcessCmdLine(LPSTR lpCmdLine)
|
||||||
if (argv[i][1] && argv[i][2] && argv[i][2] != ':')
|
if (argv[i][1] && argv[i][2] && argv[i][2] != ':')
|
||||||
break; /* This is a file path beginning with '/'. */
|
break; /* This is a file path beginning with '/'. */
|
||||||
|
|
||||||
switch (toupper(argv[i][1]))
|
switch (toupperW(argv[i][1]))
|
||||||
{
|
{
|
||||||
case '?':
|
case '?':
|
||||||
fprintf(stderr, usage);
|
fprintf(stderr, usage);
|
||||||
|
@ -241,7 +176,7 @@ BOOL ProcessCmdLine(LPSTR lpCmdLine)
|
||||||
/* ignored */;
|
/* ignored */;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "regedit: Invalid switch [%s]\n", argv[i]);
|
fprintf(stderr, "regedit: Invalid switch [%ls]\n", argv[i]);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -265,9 +200,7 @@ BOOL ProcessCmdLine(LPSTR lpCmdLine)
|
||||||
for (; i < argc; i++)
|
for (; i < argc; i++)
|
||||||
PerformRegAction(action, argv, &i);
|
PerformRegAction(action, argv, &i);
|
||||||
|
|
||||||
for (i = 0; i < argc; i++)
|
LocalFree(argv);
|
||||||
HeapFree(GetProcessHeap(), 0, argv[i]);
|
|
||||||
HeapFree(GetProcessHeap(), 0, argv);
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue