Commit 398e7103 authored by Jason Edmeades's avatar Jason Edmeades Committed by Alexandre Julliard

cmd.exe: Handle command line as Unicode.

parent 926da13e
...@@ -26,6 +26,7 @@ ...@@ -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); ...@@ -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[]) ...@@ -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;
...@@ -106,8 +119,9 @@ int main (int argc, char *argv[]) ...@@ -106,8 +119,9 @@ 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[]) ...@@ -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[]) ...@@ -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[]) ...@@ -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[]) ...@@ -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[]) ...@@ -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[]) ...@@ -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[]) ...@@ -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[]) ...@@ -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);
} }
/* /*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment