- Fix cmd's SearchForExecutable: it was inside out, giving extension priority over directory.

- Remove code that checked if the file's extension was in PATHEXT. Windows does not check, and it's very handy to be able to "run" non-executable files.
- Allow explicit paths with no backslash (like "A:file")
- Batch: use GetFullPathName to get the batch file's absolute path; this way %~dp0 will always give the right directory even in the weird case of running the .bat via a relative path in PATH. Remove code in SearchForExecutable which tried to make sure it returned an absolute path (but it didn't in that case).

svn path=/trunk/; revision=35187
This commit is contained in:
Jeffrey Morlan 2008-08-08 16:48:21 +00:00
parent fbb7095a67
commit b75ff606ba
2 changed files with 54 additions and 107 deletions

View file

@ -263,10 +263,10 @@ BOOL Batch (LPTSTR fullname, LPTSTR firstword, LPTSTR param)
cmd_free (bc->raw_params); cmd_free (bc->raw_params);
} }
ZeroMemory(bc->BatchFilePath, sizeof(bc->BatchFilePath)); GetFullPathName(fullname, sizeof(bc->BatchFilePath), bc->BatchFilePath, &tmp);
*tmp = '\0';
bc->hBatchFile = hFile; bc->hBatchFile = hFile;
tmp = _tcsrchr(fullname, '\\');
_tcsncpy(bc->BatchFilePath, fullname, ((_tcslen(fullname) - _tcslen(tmp)) + 1));
SetFilePointer (bc->hBatchFile, 0, NULL, FILE_BEGIN); SetFilePointer (bc->hBatchFile, 0, NULL, FILE_BEGIN);
bc->bEcho = bEcho; /* Preserve echo across batch calls */ bc->bEcho = bEcho; /* Preserve echo across batch calls */
bc->shiftlevel = 0; bc->shiftlevel = 0;

View file

@ -83,56 +83,25 @@
/* searches for file using path info. */ /* searches for file using path info. */
BOOL BOOL
SearchForExecutableSingle (LPCTSTR pFileName, LPTSTR pFullName, LPTSTR pExtension) SearchForExecutableSingle (LPCTSTR pFileName, LPTSTR pFullName, LPTSTR pPathExt, LPTSTR pDirectory)
{ {
TCHAR szPathBuffer[CMDLINE_LENGTH]; TCHAR szPathBuffer[CMDLINE_LENGTH], *pszPathEnd;
LPTSTR pszBuffer = NULL;
DWORD dwBuffer, len;
LPTSTR s,f; LPTSTR s,f;
/* initialize full name buffer */ /* initialize full name buffer */
*pFullName = _T('\0'); *pFullName = _T('\0');
TRACE ("SearchForExecutableSingle: \'%s\' with ext: \'%s\'\n", TRACE ("SearchForExecutableSingle: \'%s\' in dir: \'%s\'\n",
debugstr_aw(pFileName), debugstr_aw(pExtension)); debugstr_aw(pFileName), debugstr_aw(pDirectory));
/* Check if valid directly on specified path */ pszPathEnd = szPathBuffer;
if (_tcschr (pFileName, _T('\\')) != NULL) if (pDirectory != NULL)
{ {
LPTSTR pFilePart; _tcscpy(szPathBuffer, pDirectory);
TRACE ("Absolute or relative path is given.\n"); pszPathEnd += _tcslen(pszPathEnd);
*pszPathEnd++ = _T('\\');
if (GetFullPathName (pFileName,
CMDLINE_LENGTH,
szPathBuffer,
&pFilePart) ==0)
return FALSE;
if(pFilePart == 0)
return FALSE;
/* Add extension and test file: */
if (pExtension)
_tcscat(szPathBuffer, pExtension);
if (IsExistingFile (szPathBuffer))
{
TRACE ("Found: \'%s\'\n", debugstr_aw(szPathBuffer));
_tcscpy (pFullName, szPathBuffer);
return TRUE;
}
return FALSE;
} }
_tcscpy(pszPathEnd, pFileName);
/* search in current directory */ pszPathEnd += _tcslen(pszPathEnd);
len = GetCurrentDirectory (CMDLINE_LENGTH, szPathBuffer);
if (szPathBuffer[len - 1] != _T('\\'))
{
szPathBuffer[len] = _T('\\');
szPathBuffer[len + 1] = _T('\0');
}
_tcscat (szPathBuffer, pFileName);
if (pExtension)
_tcscat (szPathBuffer, pExtension);
if (IsExistingFile (szPathBuffer)) if (IsExistingFile (szPathBuffer))
{ {
@ -141,56 +110,30 @@ SearchForExecutableSingle (LPCTSTR pFileName, LPTSTR pFullName, LPTSTR pExtensio
return TRUE; return TRUE;
} }
s = pPathExt;
/* load environment varable PATH into buffer */
pszBuffer = (LPTSTR)cmd_alloc (ENV_BUFFER_SIZE * sizeof(TCHAR));
dwBuffer = GetEnvironmentVariable (_T("PATH"), pszBuffer, ENV_BUFFER_SIZE);
if (dwBuffer > ENV_BUFFER_SIZE)
{
pszBuffer = (LPTSTR)cmd_realloc (pszBuffer, dwBuffer * sizeof (TCHAR));
GetEnvironmentVariable (_T("PATH"), pszBuffer, dwBuffer);
}
/* search in PATH */
s = pszBuffer;
while (s && *s) while (s && *s)
{ {
f = _tcschr (s, _T(';')); f = _tcschr (s, _T(';'));
if (f) if (f)
{ {
_tcsncpy (szPathBuffer, s, (size_t)(f-s)); _tcsncpy (pszPathEnd, s, (size_t)(f-s));
szPathBuffer[f-s] = _T('\0'); pszPathEnd[f-s] = _T('\0');
s = f + 1; s = f + 1;
} }
else else
{ {
_tcscpy (szPathBuffer, s); _tcscpy (pszPathEnd, s);
s = NULL; s = NULL;
} }
len = _tcslen(szPathBuffer);
if (szPathBuffer[len - 1] != _T('\\'))
{
szPathBuffer[len] = _T('\\');
szPathBuffer[len + 1] = _T('\0');
}
_tcscat (szPathBuffer, pFileName);
if (pExtension)
_tcscat (szPathBuffer, pExtension);
if (IsExistingFile (szPathBuffer)) if (IsExistingFile (szPathBuffer))
{ {
TRACE ("Found: \'%s\'\n", debugstr_aw(szPathBuffer)); TRACE ("Found: \'%s\'\n", debugstr_aw(szPathBuffer));
cmd_free (pszBuffer);
_tcscpy (pFullName, szPathBuffer); _tcscpy (pFullName, szPathBuffer);
return TRUE; return TRUE;
} }
} }
cmd_free (pszBuffer);
return FALSE; return FALSE;
} }
@ -199,60 +142,64 @@ BOOL
SearchForExecutable (LPCTSTR pFileName, LPTSTR pFullName) SearchForExecutable (LPCTSTR pFileName, LPTSTR pFullName)
{ {
static TCHAR pszDefaultPathExt[] = _T(".COM;.EXE;.BAT;.CMD"); static TCHAR pszDefaultPathExt[] = _T(".COM;.EXE;.BAT;.CMD");
LPTSTR pszBuffer = NULL; LPTSTR pszPathExt, pszPath;
LPTSTR pCh; LPTSTR pCh;
LPTSTR pExt;
DWORD dwBuffer; DWORD dwBuffer;
TRACE ("SearchForExecutable: \'%s\'\n", debugstr_aw(pFileName)); TRACE ("SearchForExecutable: \'%s\'\n", debugstr_aw(pFileName));
/* load environment varable PATHEXT */ /* load environment varable PATHEXT */
pszBuffer = (LPTSTR)cmd_alloc (ENV_BUFFER_SIZE * sizeof(TCHAR)); pszPathExt = (LPTSTR)cmd_alloc (ENV_BUFFER_SIZE * sizeof(TCHAR));
dwBuffer = GetEnvironmentVariable (_T("PATHEXT"), pszBuffer, ENV_BUFFER_SIZE); dwBuffer = GetEnvironmentVariable (_T("PATHEXT"), pszPathExt, ENV_BUFFER_SIZE);
if (dwBuffer > ENV_BUFFER_SIZE) if (dwBuffer > ENV_BUFFER_SIZE)
{ {
pszBuffer = (LPTSTR)cmd_realloc (pszBuffer, dwBuffer * sizeof (TCHAR)); pszPathExt = (LPTSTR)cmd_realloc (pszPathExt, dwBuffer * sizeof (TCHAR));
GetEnvironmentVariable (_T("PATHEXT"), pszBuffer, dwBuffer); GetEnvironmentVariable (_T("PATHEXT"), pszPathExt, dwBuffer);
} }
else if (0 == dwBuffer) else if (0 == dwBuffer)
{ {
_tcscpy(pszBuffer, pszDefaultPathExt); _tcscpy(pszPathExt, pszDefaultPathExt);
} }
TRACE ("SearchForExecutable(): Loaded PATHEXT: %s\n", debugstr_aw(pszBuffer)); /* Check if valid directly on specified path */
if (SearchForExecutableSingle(pFileName, pFullName, pszPathExt, NULL))
pExt = _tcsrchr(pFileName, _T('.'));
if (pExt != NULL)
{ {
LPTSTR pszBuffer2; cmd_free(pszPathExt);
pszBuffer2 = cmd_dup(pszBuffer); return TRUE;
if (pszBuffer2)
{
pCh = _tcstok(pszBuffer2, _T(";"));
while (pCh)
{
if (0 == _tcsicmp(pCh, pExt))
{
cmd_free(pszBuffer);
cmd_free(pszBuffer2);
return SearchForExecutableSingle(pFileName, pFullName, NULL);
}
pCh = _tcstok(NULL, _T(";"));
}
cmd_free(pszBuffer2);
}
} }
pCh = _tcstok(pszBuffer, _T(";")); /* If an explicit directory was given, stop here - no need to search PATH. */
if (pFileName[1] == _T(':') || _tcschr(pFileName, _T('\\')))
{
cmd_free(pszPathExt);
return FALSE;
}
/* load environment varable PATH into buffer */
pszPath = (LPTSTR)cmd_alloc (ENV_BUFFER_SIZE * sizeof(TCHAR));
dwBuffer = GetEnvironmentVariable (_T("PATH"), pszPath, ENV_BUFFER_SIZE);
if (dwBuffer > ENV_BUFFER_SIZE)
{
pszPath = (LPTSTR)cmd_realloc (pszPath, dwBuffer * sizeof (TCHAR));
GetEnvironmentVariable (_T("PATH"), pszPath, dwBuffer);
}
TRACE ("SearchForExecutable(): Loaded PATH: %s\n", debugstr_aw(pszPath));
/* search in PATH */
pCh = _tcstok(pszPath, _T(";"));
while (pCh) while (pCh)
{ {
if (SearchForExecutableSingle(pFileName, pFullName, pCh)) if (SearchForExecutableSingle(pFileName, pFullName, pszPathExt, pCh))
{ {
cmd_free(pszBuffer); cmd_free(pszPath);
cmd_free(pszPathExt);
return TRUE; return TRUE;
} }
pCh = _tcstok(NULL, _T(";")); pCh = _tcstok(NULL, _T(";"));
} }
cmd_free(pszBuffer); cmd_free(pszPath);
cmd_free(pszPathExt);
return FALSE; return FALSE;
} }