cmd.exe: Don't treat explicit paths as a PATH search list.

For example, the explicit path "C:\some;path" is currently treated as if
the PATH environment variable is "C:\some;path" which is obviously wrong,
and searches for the directories "C:\some" and "path".

Signed-off-by: Gabriel Ivăncescu <gabrielopcode@gmail.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Gabriel Ivăncescu 2020-05-05 16:10:37 +03:00 committed by Alexandre Julliard
parent d784de82c8
commit a19a770f96
1 changed files with 40 additions and 27 deletions

View File

@ -1045,6 +1045,7 @@ void WCMD_run_program (WCHAR *command, BOOL called)
WCHAR pathext[MAXSTRING]; WCHAR pathext[MAXSTRING];
WCHAR *firstParam; WCHAR *firstParam;
BOOL extensionsupplied = FALSE; BOOL extensionsupplied = FALSE;
BOOL explicit_path = FALSE;
BOOL status; BOOL status;
DWORD len; DWORD len;
static const WCHAR envPath[] = {'P','A','T','H','\0'}; static const WCHAR envPath[] = {'P','A','T','H','\0'};
@ -1084,6 +1085,7 @@ void WCMD_run_program (WCHAR *command, BOOL called)
/* Reduce pathtosearch to a path with trailing '\' to support c:\a.bat and /* Reduce pathtosearch to a path with trailing '\' to support c:\a.bat and
c:\windows\a.bat syntax */ c:\windows\a.bat syntax */
if (lastSlash) *(lastSlash + 1) = 0x00; if (lastSlash) *(lastSlash + 1) = 0x00;
explicit_path = TRUE;
} }
/* Now extract PATHEXT */ /* Now extract PATHEXT */
@ -1103,37 +1105,48 @@ void WCMD_run_program (WCHAR *command, BOOL called)
BOOL found = FALSE; BOOL found = FALSE;
BOOL inside_quotes = FALSE; BOOL inside_quotes = FALSE;
/* Work on the first directory on the search path */ if (explicit_path)
pos = pathposn;
while ((inside_quotes || *pos != ';') && *pos != 0)
{ {
if (*pos == '"') lstrcpyW(thisDir, pathposn);
inside_quotes = !inside_quotes; pathposn = NULL;
pos++;
} }
if (*pos) { /* Reached semicolon */
memcpy(thisDir, pathposn, (pos-pathposn) * sizeof(WCHAR));
thisDir[(pos-pathposn)] = 0x00;
pathposn = pos+1;
} else { /* Reached string end */
lstrcpyW(thisDir, pathposn);
pathposn = NULL;
}
/* Remove quotes */
length = lstrlenW(thisDir);
if (thisDir[length - 1] == '"')
thisDir[length - 1] = 0;
if (*thisDir != '"')
lstrcpyW(temp, thisDir);
else else
lstrcpyW(temp, thisDir + 1); {
/* Work on the next directory on the search path */
pos = pathposn;
while ((inside_quotes || *pos != ';') && *pos != 0)
{
if (*pos == '"')
inside_quotes = !inside_quotes;
pos++;
}
/* Since you can have eg. ..\.. on the path, need to expand if (*pos) /* Reached semicolon */
to full information */ {
GetFullPathNameW(temp, MAX_PATH, thisDir, NULL); memcpy(thisDir, pathposn, (pos-pathposn) * sizeof(WCHAR));
thisDir[(pos-pathposn)] = 0x00;
pathposn = pos+1;
}
else /* Reached string end */
{
lstrcpyW(thisDir, pathposn);
pathposn = NULL;
}
/* Remove quotes */
length = lstrlenW(thisDir);
if (thisDir[length - 1] == '"')
thisDir[length - 1] = 0;
if (*thisDir != '"')
lstrcpyW(temp, thisDir);
else
lstrcpyW(temp, thisDir + 1);
/* Since you can have eg. ..\.. on the path, need to expand
to full information */
GetFullPathNameW(temp, MAX_PATH, thisDir, NULL);
}
/* 1. If extension supplied, see if that file exists */ /* 1. If extension supplied, see if that file exists */
lstrcatW(thisDir, slashW); lstrcatW(thisDir, slashW);