diff --git a/programs/cmd/tests/test_builtins.cmd b/programs/cmd/tests/test_builtins.cmd index 1c0f8755a0b..3e064b9568c 100644 --- a/programs/cmd/tests/test_builtins.cmd +++ b/programs/cmd/tests/test_builtins.cmd @@ -1829,6 +1829,7 @@ rem Basic test of command line. Note a section prefix per command rem to resync, as wine does not output anything in these cases yet. echo --- Test 1 cmd.exe /c echo Line1 +cmd.exe /c echo "Line2" echo --- Test 2 cmd.exe /c echo Test quotes "&" work echo --- Test 3 diff --git a/programs/cmd/tests/test_builtins.cmd.exp b/programs/cmd/tests/test_builtins.cmd.exp index e81770600bd..6483f1ec05b 100644 --- a/programs/cmd/tests/test_builtins.cmd.exp +++ b/programs/cmd/tests/test_builtins.cmd.exp @@ -910,6 +910,7 @@ value1 ------------ cmd.exe command lines ------------ --- Test 1 Line1 +@todo_wine@"Line2" --- Test 2 @todo_wine@Test quotes "&" work --- Test 3 @@ -929,11 +930,11 @@ Line1 --- Test 10 --- Test 11 --- Test 12 -@todo_wine@passed1 +passed1 --- Test 13 -@todo_wine@passed2@space@ +passed2@space@ --- Test 14 -@todo_wine@foobar +foobar --- Test 15 No prompts or I would not get here1 No prompts or I would not get here2 diff --git a/programs/cmd/wcmdmain.c b/programs/cmd/wcmdmain.c index 0e7a197350e..675256b85da 100644 --- a/programs/cmd/wcmdmain.c +++ b/programs/cmd/wcmdmain.c @@ -2419,10 +2419,12 @@ int wmain (int argc, WCHAR *argvW[]) } } + /* If there is not exactly 2 quote characters, then /S (old behaviour) is enabled */ if (qcount!=2) opt_s = TRUE; - /* check argvW[0] for a space and invalid characters */ + /* check argvW[0] for a space and invalid characters. There must not be any invalid + * characters, but there must be one or more whitespace */ if (!opt_s) { opt_s = TRUE; p=*argvW; @@ -2432,7 +2434,7 @@ int wmain (int argc, WCHAR *argvW[]) opt_s = TRUE; break; } - if (*p==' ') + if (*p==' ' || *p=='\t') opt_s = FALSE; p++; } @@ -2507,6 +2509,71 @@ int wmain (int argc, WCHAR *argvW[]) WINE_TRACE("/c command line: '%s'\n", wine_dbgstr_w(cmd)); + /* Finally, we only stay in new mode IF the first parameter is quoted and + is a valid executable, ie must exist, otherwise drop back to old mode */ + if (!opt_s) { + WCHAR *thisArg = WCMD_parameter(cmd, 0, NULL, NULL, FALSE); + static const WCHAR extEXEW[] = {'.','e','x','e','\0'}; + static const WCHAR extCOMW[] = {'.','c','o','m','\0'}; + BOOL found = FALSE; + + /* If the supplied parameter has any directory information, look there */ + WINE_TRACE("First parameter is '%s'\n", wine_dbgstr_w(thisArg)); + if (strchrW(thisArg, '\\') != NULL) { + + GetFullPathNameW(thisArg, sizeof(string)/sizeof(WCHAR), string, NULL); + WINE_TRACE("Full path name '%s'\n", wine_dbgstr_w(string)); + p = string + strlenW(string); + + /* Does file exist with this name? */ + if (GetFileAttributesW(string) != INVALID_FILE_ATTRIBUTES) { + WINE_TRACE("Found file as '%s'\n", wine_dbgstr_w(string)); + found = TRUE; + } else strcpyW(p, extEXEW); + + /* Does file exist with .exe appended */ + if (!found && GetFileAttributesW(string) != INVALID_FILE_ATTRIBUTES) { + WINE_TRACE("Found file as '%s'\n", wine_dbgstr_w(string)); + found = TRUE; + } else strcpyW(p, extCOMW); + + /* Does file exist with .com appended */ + if (!found && GetFileAttributesW(string) != INVALID_FILE_ATTRIBUTES) { + WINE_TRACE("Found file as '%s'\n", wine_dbgstr_w(string)); + found = TRUE; + } + + /* Otherwise we now need to look in the path to see if we can find it */ + } else { + p = thisArg + strlenW(thisArg); + + /* Does file exist with this name? */ + if (SearchPathW(NULL, thisArg, NULL, sizeof(string)/sizeof(WCHAR), string, NULL) != 0) { + WINE_TRACE("Found on path as '%s'\n", wine_dbgstr_w(string)); + found = TRUE; + } + + /* Does file exist plus an extension of .exe? */ + if (SearchPathW(NULL, thisArg, extEXEW, sizeof(string)/sizeof(WCHAR), string, NULL) != 0) { + WINE_TRACE("Found on path as '%s'\n", wine_dbgstr_w(string)); + found = TRUE; + } + + /* Does file exist plus an extension of .com? */ + if (SearchPathW(NULL, thisArg, extCOMW, sizeof(string)/sizeof(WCHAR), string, NULL) != 0) { + WINE_TRACE("Found on path as '%s'\n", wine_dbgstr_w(string)); + found = TRUE; + } + } + + /* If not found, drop back to old behaviour */ + if (!found) { + WINE_TRACE("Binary not found, dropping back to old behaviour\n"); + opt_s = TRUE; + } + + } + /* strip first and last quote characters if opt_s; check for invalid * executable is done later */ if (opt_s && *cmd=='\"')