2006-02-16 23:23:37 +00:00
|
|
|
/*
|
|
|
|
* WHERE.C - file search functions.
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* History:
|
|
|
|
*
|
|
|
|
* 07/15/95 (Tim Norman)
|
|
|
|
* started.
|
|
|
|
*
|
|
|
|
* 08/08/95 (Matt Rains)
|
|
|
|
* i have cleaned up the source code. changes now bring this source
|
|
|
|
* into guidelines for recommended programming practice.
|
|
|
|
*
|
|
|
|
* 12/12/95 (Steffan Kaiser & Tim Norman)
|
|
|
|
* added some patches to fix some things and make more efficient
|
|
|
|
*
|
|
|
|
* 1/6/96 (Tim Norman)
|
|
|
|
* fixed a stupid pointer mistake...
|
|
|
|
* Thanks to everyone who noticed it!
|
|
|
|
*
|
|
|
|
* 8/1/96 (Tim Norman)
|
|
|
|
* fixed a bug when getenv returns NULL
|
|
|
|
*
|
|
|
|
* 8/7/96 (Steffan Kaiser and Tim Norman)
|
|
|
|
* speed improvements and bug fixes
|
|
|
|
*
|
|
|
|
* 8/27/96 (Tim Norman)
|
|
|
|
* changed code to use pointers directly into PATH environment
|
|
|
|
* variable rather than making our own copy. This saves some memory,
|
|
|
|
* but requires we write our own function to copy pathnames out of
|
|
|
|
* the variable.
|
|
|
|
*
|
|
|
|
* 12/23/96 (Aaron Kaufman)
|
|
|
|
* Fixed a bug in get_paths() that did not point to the first PATH
|
|
|
|
* in the environment variable.
|
|
|
|
*
|
|
|
|
* 7/12/97 (Tim Norman)
|
|
|
|
* Apparently, Aaron's bugfix got lost, so I fixed it again.
|
|
|
|
*
|
|
|
|
* 16 July 1998 (John P. Price)
|
|
|
|
* Added stand alone code.
|
|
|
|
*
|
|
|
|
* 17 July 1998 (John P. Price)
|
|
|
|
* Rewrote find_which to use searchpath function
|
|
|
|
*
|
|
|
|
* 24-Jul-1998 (John P Price <linux-guru@gcfl.net>)
|
|
|
|
* fixed bug where didn't check all extensions when path was specified
|
|
|
|
*
|
|
|
|
* 27-Jul-1998 (John P Price <linux-guru@gcfl.net>)
|
|
|
|
* added config.h include
|
|
|
|
*
|
|
|
|
* 30-Jul-1998 (John P Price <linux-guru@gcfl.net>)
|
|
|
|
* fixed so that it find_which returns NULL if filename is not
|
|
|
|
* executable (does not have .bat, .com, or .exe extention).
|
|
|
|
* Before command would to execute any file with any extension (opps!)
|
|
|
|
*
|
2007-05-05 11:32:25 +00:00
|
|
|
* 03-Dec-1998 (Eric Kohl)
|
2006-02-16 23:23:37 +00:00
|
|
|
* Changed find_which().
|
|
|
|
*
|
2007-05-05 11:32:25 +00:00
|
|
|
* 07-Dec-1998 (Eric Kohl)
|
2006-02-16 23:23:37 +00:00
|
|
|
* Added ".CMD" extension.
|
|
|
|
* Replaced numeric constant by _NR_OF_EXTENSIONS.
|
|
|
|
*
|
2007-05-05 11:32:25 +00:00
|
|
|
* 26-Feb-1999 (Eric Kohl)
|
2006-02-16 23:23:37 +00:00
|
|
|
* Replaced find_which() by SearchForExecutable().
|
|
|
|
* Now files are searched using the right extension order.
|
|
|
|
*
|
2007-05-05 11:32:25 +00:00
|
|
|
* 20-Apr-1999 (Eric Kohl)
|
2006-02-16 23:23:37 +00:00
|
|
|
* Some minor changes and improvements.
|
|
|
|
*
|
|
|
|
* 10-Jul-2004 (Jens Collin <jens.collin@lakhei.com>)
|
|
|
|
* Fixed searxhing for files with specific extensions in PATHEXT order..
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <precomp.h>
|
|
|
|
|
|
|
|
|
|
|
|
/* initial size of environment variable buffer */
|
|
|
|
#define ENV_BUFFER_SIZE 1024
|
|
|
|
|
|
|
|
|
|
|
|
/* searches for file using path info. */
|
|
|
|
|
|
|
|
BOOL
|
|
|
|
SearchForExecutableSingle (LPCTSTR pFileName, LPTSTR pFullName, LPTSTR pExtension)
|
|
|
|
{
|
|
|
|
TCHAR szPathBuffer[CMDLINE_LENGTH];
|
|
|
|
LPTSTR pszBuffer = NULL;
|
|
|
|
DWORD dwBuffer, len;
|
|
|
|
LPTSTR s,f;
|
|
|
|
/* initialize full name buffer */
|
|
|
|
*pFullName = _T('\0');
|
|
|
|
|
2008-05-15 20:29:50 +00:00
|
|
|
TRACE ("SearchForExecutableSingle: \'%s\' with ext: \'%s\'\n",
|
|
|
|
debugstr_aw(pFileName), debugstr_aw(pExtension));
|
2006-02-16 23:23:37 +00:00
|
|
|
|
|
|
|
/* Check if valid directly on specified path */
|
|
|
|
if (_tcschr (pFileName, _T('\\')) != NULL)
|
|
|
|
{
|
|
|
|
LPTSTR pFilePart;
|
2008-05-15 20:02:05 +00:00
|
|
|
TRACE ("Absolute or relative path is given.\n");
|
2006-02-16 23:23:37 +00:00
|
|
|
|
|
|
|
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))
|
|
|
|
{
|
2008-05-15 20:29:50 +00:00
|
|
|
TRACE ("Found: \'%s\'\n", debugstr_aw(szPathBuffer));
|
2006-02-16 23:23:37 +00:00
|
|
|
_tcscpy (pFullName, szPathBuffer);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* search in current directory */
|
|
|
|
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))
|
|
|
|
{
|
2008-05-15 20:29:50 +00:00
|
|
|
TRACE ("Found: \'%s\'\n", debugstr_aw(szPathBuffer));
|
2006-02-16 23:23:37 +00:00
|
|
|
_tcscpy (pFullName, szPathBuffer);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* load environment varable PATH into buffer */
|
2007-08-01 10:17:13 +00:00
|
|
|
pszBuffer = (LPTSTR)cmd_alloc (ENV_BUFFER_SIZE * sizeof(TCHAR));
|
2006-02-16 23:23:37 +00:00
|
|
|
dwBuffer = GetEnvironmentVariable (_T("PATH"), pszBuffer, ENV_BUFFER_SIZE);
|
|
|
|
if (dwBuffer > ENV_BUFFER_SIZE)
|
|
|
|
{
|
2007-08-01 10:17:13 +00:00
|
|
|
pszBuffer = (LPTSTR)cmd_realloc (pszBuffer, dwBuffer * sizeof (TCHAR));
|
2006-02-16 23:23:37 +00:00
|
|
|
GetEnvironmentVariable (_T("PATH"), pszBuffer, dwBuffer);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* search in PATH */
|
|
|
|
s = pszBuffer;
|
|
|
|
while (s && *s)
|
|
|
|
{
|
|
|
|
f = _tcschr (s, _T(';'));
|
|
|
|
|
|
|
|
if (f)
|
|
|
|
{
|
|
|
|
_tcsncpy (szPathBuffer, s, (size_t)(f-s));
|
|
|
|
szPathBuffer[f-s] = _T('\0');
|
|
|
|
s = f + 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
_tcscpy (szPathBuffer, s);
|
|
|
|
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))
|
|
|
|
{
|
2008-05-15 20:29:50 +00:00
|
|
|
TRACE ("Found: \'%s\'\n", debugstr_aw(szPathBuffer));
|
2007-08-01 10:17:13 +00:00
|
|
|
cmd_free (pszBuffer);
|
2006-02-16 23:23:37 +00:00
|
|
|
_tcscpy (pFullName, szPathBuffer);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
2007-08-01 10:17:13 +00:00
|
|
|
cmd_free (pszBuffer);
|
2006-02-16 23:23:37 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
BOOL
|
|
|
|
SearchForExecutable (LPCTSTR pFileName, LPTSTR pFullName)
|
|
|
|
{
|
|
|
|
static TCHAR pszDefaultPathExt[] = _T(".COM;.EXE;.BAT;.CMD");
|
|
|
|
LPTSTR pszBuffer = NULL;
|
|
|
|
LPTSTR pCh;
|
|
|
|
LPTSTR pExt;
|
|
|
|
DWORD dwBuffer;
|
2008-05-15 20:29:50 +00:00
|
|
|
TRACE ("SearchForExecutable: \'%s\'\n", debugstr_aw(pFileName));
|
2006-02-16 23:23:37 +00:00
|
|
|
/* load environment varable PATHEXT */
|
2007-08-01 10:17:13 +00:00
|
|
|
pszBuffer = (LPTSTR)cmd_alloc (ENV_BUFFER_SIZE * sizeof(TCHAR));
|
2006-02-16 23:23:37 +00:00
|
|
|
dwBuffer = GetEnvironmentVariable (_T("PATHEXT"), pszBuffer, ENV_BUFFER_SIZE);
|
|
|
|
if (dwBuffer > ENV_BUFFER_SIZE)
|
|
|
|
{
|
2007-08-01 10:17:13 +00:00
|
|
|
pszBuffer = (LPTSTR)cmd_realloc (pszBuffer, dwBuffer * sizeof (TCHAR));
|
2006-02-16 23:23:37 +00:00
|
|
|
GetEnvironmentVariable (_T("PATHEXT"), pszBuffer, dwBuffer);
|
|
|
|
}
|
|
|
|
else if (0 == dwBuffer)
|
|
|
|
{
|
|
|
|
_tcscpy(pszBuffer, pszDefaultPathExt);
|
|
|
|
}
|
|
|
|
|
2008-05-15 20:29:50 +00:00
|
|
|
TRACE ("SearchForExecutable(): Loaded PATHEXT: %s\n", debugstr_aw(pszBuffer));
|
2006-02-16 23:23:37 +00:00
|
|
|
|
|
|
|
pExt = _tcsrchr(pFileName, _T('.'));
|
|
|
|
if (pExt != NULL)
|
|
|
|
{
|
|
|
|
LPTSTR pszBuffer2;
|
2007-10-27 03:13:37 +00:00
|
|
|
pszBuffer2 = cmd_dup(pszBuffer);
|
2006-02-16 23:23:37 +00:00
|
|
|
if (pszBuffer2)
|
|
|
|
{
|
|
|
|
pCh = _tcstok(pszBuffer2, _T(";"));
|
|
|
|
while (pCh)
|
|
|
|
{
|
|
|
|
if (0 == _tcsicmp(pCh, pExt))
|
|
|
|
{
|
2007-08-01 10:17:13 +00:00
|
|
|
cmd_free(pszBuffer);
|
2007-10-27 03:13:37 +00:00
|
|
|
cmd_free(pszBuffer2);
|
2006-02-16 23:23:37 +00:00
|
|
|
return SearchForExecutableSingle(pFileName, pFullName, NULL);
|
|
|
|
}
|
|
|
|
pCh = _tcstok(NULL, _T(";"));
|
|
|
|
}
|
2007-10-27 03:13:37 +00:00
|
|
|
cmd_free(pszBuffer2);
|
2006-02-16 23:23:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pCh = _tcstok(pszBuffer, _T(";"));
|
|
|
|
while (pCh)
|
|
|
|
{
|
|
|
|
if (SearchForExecutableSingle(pFileName, pFullName, pCh))
|
|
|
|
{
|
2007-08-01 10:17:13 +00:00
|
|
|
cmd_free(pszBuffer);
|
2006-02-16 23:23:37 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
pCh = _tcstok(NULL, _T(";"));
|
|
|
|
}
|
|
|
|
|
2007-08-01 10:17:13 +00:00
|
|
|
cmd_free(pszBuffer);
|
2006-02-16 23:23:37 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* EOF */
|