cmd.exe: Handle command line as Unicode.
This commit is contained in:
parent
926da13e56
commit
398e710376
@ -26,6 +26,7 @@
|
|||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <wine/unicode.h>
|
||||||
|
|
||||||
void WCMD_assoc (char *, BOOL);
|
void WCMD_assoc (char *, BOOL);
|
||||||
void WCMD_batch (char *, char *, int, char *, HANDLE);
|
void WCMD_batch (char *, char *, int, char *, HANDLE);
|
||||||
|
@ -59,6 +59,9 @@ static char *WCMD_expand_envvar(char *start);
|
|||||||
|
|
||||||
int main (int argc, char *argv[])
|
int main (int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
LPWSTR *argvW = NULL;
|
||||||
|
int args;
|
||||||
|
WCHAR *cmdW = NULL;
|
||||||
char string[1024];
|
char string[1024];
|
||||||
char envvar[4];
|
char envvar[4];
|
||||||
char* cmd=NULL;
|
char* cmd=NULL;
|
||||||
@ -67,34 +70,44 @@ int main (int argc, char *argv[])
|
|||||||
int opt_q;
|
int opt_q;
|
||||||
int opt_t = 0;
|
int opt_t = 0;
|
||||||
|
|
||||||
|
/* Get a Unicode command line */
|
||||||
|
argvW = CommandLineToArgvW( GetCommandLineW(), &argc );
|
||||||
|
args = argc;
|
||||||
|
|
||||||
opt_c=opt_k=opt_q=opt_s=0;
|
opt_c=opt_k=opt_q=opt_s=0;
|
||||||
while (*argv!=NULL)
|
while (args > 0)
|
||||||
{
|
{
|
||||||
char c;
|
WCHAR c;
|
||||||
if ((*argv)[0]!='/' || (*argv)[1]=='\0') {
|
WINE_TRACE("Command line parm: '%s'\n", wine_dbgstr_w(*argvW));
|
||||||
argv++;
|
if ((*argvW)[0]!='/' || (*argvW)[1]=='\0') {
|
||||||
|
argvW++;
|
||||||
|
args--;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
c=(*argv)[1];
|
c=(*argvW)[1];
|
||||||
if (tolower(c)=='c') {
|
if (tolowerW(c)=='c') {
|
||||||
opt_c=1;
|
opt_c=1;
|
||||||
} else if (tolower(c)=='q') {
|
} else if (tolowerW(c)=='q') {
|
||||||
opt_q=1;
|
opt_q=1;
|
||||||
} else if (tolower(c)=='k') {
|
} else if (tolowerW(c)=='k') {
|
||||||
opt_k=1;
|
opt_k=1;
|
||||||
} else if (tolower(c)=='s') {
|
} else if (tolowerW(c)=='s') {
|
||||||
opt_s=1;
|
opt_s=1;
|
||||||
} else if (tolower(c)=='t' && (*argv)[2]==':') {
|
} else if (tolowerW(c)=='t' && (*argvW)[2]==':') {
|
||||||
opt_t=strtoul(&(*argv)[3], NULL, 16);
|
opt_t=strtoulW(&(*argvW)[3], NULL, 16);
|
||||||
} else if (tolower(c)=='x' || tolower(c)=='y') {
|
} else if (tolowerW(c)=='x' || tolowerW(c)=='y') {
|
||||||
/* Ignored for compatibility with Windows */
|
/* Ignored for compatibility with Windows */
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((*argv)[2]==0)
|
if ((*argvW)[2]==0) {
|
||||||
argv++;
|
argvW++;
|
||||||
|
args--;
|
||||||
|
}
|
||||||
else /* handle `cmd /cnotepad.exe` and `cmd /x/c ...` */
|
else /* handle `cmd /cnotepad.exe` and `cmd /x/c ...` */
|
||||||
*argv+=2;
|
{
|
||||||
|
*argvW+=2;
|
||||||
|
}
|
||||||
|
|
||||||
if (opt_c || opt_k) /* break out of parsing immediately after c or k */
|
if (opt_c || opt_k) /* break out of parsing immediately after c or k */
|
||||||
break;
|
break;
|
||||||
@ -105,9 +118,10 @@ int main (int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (opt_c || opt_k) {
|
if (opt_c || opt_k) {
|
||||||
int len,qcount;
|
int len,qcount;
|
||||||
char** arg;
|
WCHAR** arg;
|
||||||
char* p;
|
int argsLeft;
|
||||||
|
WCHAR* p;
|
||||||
|
|
||||||
/* opt_s left unflagged if the command starts with and contains exactly
|
/* opt_s left unflagged if the command starts with and contains exactly
|
||||||
* one quoted string (exactly two quote characters). The quoted string
|
* one quoted string (exactly two quote characters). The quoted string
|
||||||
@ -117,10 +131,11 @@ int main (int argc, char *argv[])
|
|||||||
/* Build the command to execute */
|
/* Build the command to execute */
|
||||||
len = 0;
|
len = 0;
|
||||||
qcount = 0;
|
qcount = 0;
|
||||||
for (arg = argv; *arg; arg++)
|
argsLeft = args;
|
||||||
|
for (arg = argvW; argsLeft>0; arg++,argsLeft--)
|
||||||
{
|
{
|
||||||
int has_space,bcount;
|
int has_space,bcount;
|
||||||
char* a;
|
WCHAR* a;
|
||||||
|
|
||||||
has_space=0;
|
has_space=0;
|
||||||
bcount=0;
|
bcount=0;
|
||||||
@ -143,7 +158,7 @@ int main (int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
a++;
|
a++;
|
||||||
}
|
}
|
||||||
len+=(a-*arg)+1 /* for the separating space */;
|
len+=(a-*arg) + 1; /* for the separating space */
|
||||||
if (has_space)
|
if (has_space)
|
||||||
{
|
{
|
||||||
len+=2; /* for the quotes */
|
len+=2; /* for the quotes */
|
||||||
@ -154,10 +169,10 @@ int main (int argc, char *argv[])
|
|||||||
if (qcount!=2)
|
if (qcount!=2)
|
||||||
opt_s=1;
|
opt_s=1;
|
||||||
|
|
||||||
/* check argv[0] for a space and invalid characters */
|
/* check argvW[0] for a space and invalid characters */
|
||||||
if (!opt_s) {
|
if (!opt_s) {
|
||||||
opt_s=1;
|
opt_s=1;
|
||||||
p=*argv;
|
p=*argvW;
|
||||||
while (*p!='\0') {
|
while (*p!='\0') {
|
||||||
if (*p=='&' || *p=='<' || *p=='>' || *p=='(' || *p==')'
|
if (*p=='&' || *p=='<' || *p=='>' || *p=='(' || *p==')'
|
||||||
|| *p=='@' || *p=='^' || *p=='|') {
|
|| *p=='@' || *p=='^' || *p=='|') {
|
||||||
@ -170,15 +185,16 @@ int main (int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd = HeapAlloc(GetProcessHeap(), 0, len);
|
cmdW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
|
||||||
if (!cmd)
|
if (!cmdW)
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
||||||
p = cmd;
|
p = cmdW;
|
||||||
for (arg = argv; *arg; arg++)
|
argsLeft = args;
|
||||||
|
for (arg = argvW; argsLeft>0; arg++,argsLeft--)
|
||||||
{
|
{
|
||||||
int has_space,has_quote;
|
int has_space,has_quote;
|
||||||
char* a;
|
WCHAR* a;
|
||||||
|
|
||||||
/* Check for quotes and spaces in this argument */
|
/* Check for quotes and spaces in this argument */
|
||||||
has_space=has_quote=0;
|
has_space=has_quote=0;
|
||||||
@ -202,7 +218,7 @@ int main (int argc, char *argv[])
|
|||||||
*p++='"';
|
*p++='"';
|
||||||
if (has_quote) {
|
if (has_quote) {
|
||||||
int bcount;
|
int bcount;
|
||||||
char* a;
|
WCHAR* a;
|
||||||
|
|
||||||
bcount=0;
|
bcount=0;
|
||||||
a=*arg;
|
a=*arg;
|
||||||
@ -226,17 +242,27 @@ int main (int argc, char *argv[])
|
|||||||
a++;
|
a++;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
strcpy(p,*arg);
|
strcpyW(p,*arg);
|
||||||
p+=strlen(*arg);
|
p+=strlenW(*arg);
|
||||||
}
|
}
|
||||||
if (has_space)
|
if (has_space)
|
||||||
*p++='"';
|
*p++='"';
|
||||||
*p++=' ';
|
*p++=' ';
|
||||||
}
|
}
|
||||||
if (p > cmd)
|
if (p > cmdW)
|
||||||
p--; /* remove last space */
|
p--; /* remove last space */
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
|
|
||||||
|
/* FIXME: Convert back to ansi until more is in unicode */
|
||||||
|
cmd = HeapAlloc(GetProcessHeap(), 0, len);
|
||||||
|
if (!cmd) {
|
||||||
|
exit(1);
|
||||||
|
} else {
|
||||||
|
WideCharToMultiByte(CP_ACP, 0, cmdW, len, cmd, len, NULL, NULL);
|
||||||
|
}
|
||||||
|
WINE_TRACE("Input (U): '%s'\n", wine_dbgstr_w(cmdW));
|
||||||
|
WINE_TRACE("Input (A): '%s'\n", cmd);
|
||||||
|
|
||||||
/* strip first and last quote characters if opt_s; check for invalid
|
/* strip first and last quote characters if opt_s; check for invalid
|
||||||
* executable is done later */
|
* executable is done later */
|
||||||
if (opt_s && *cmd=='\"')
|
if (opt_s && *cmd=='\"')
|
||||||
@ -254,6 +280,7 @@ int main (int argc, char *argv[])
|
|||||||
else
|
else
|
||||||
WCMD_process_command(cmd);
|
WCMD_process_command(cmd);
|
||||||
HeapFree(GetProcessHeap(), 0, cmd);
|
HeapFree(GetProcessHeap(), 0, cmd);
|
||||||
|
HeapFree(GetProcessHeap(), 0, cmdW);
|
||||||
return errorlevel;
|
return errorlevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -338,6 +365,7 @@ int main (int argc, char *argv[])
|
|||||||
if (opt_k) {
|
if (opt_k) {
|
||||||
WCMD_process_command(cmd);
|
WCMD_process_command(cmd);
|
||||||
HeapFree(GetProcessHeap(), 0, cmd);
|
HeapFree(GetProcessHeap(), 0, cmd);
|
||||||
|
HeapFree(GetProcessHeap(), 0, cmdW);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user