ReactOS  0.4.14-dev-342-gdc047f9
where.c
Go to the documentation of this file.
1 /*
2  * WHERE.C - file search functions.
3  *
4  *
5  * History:
6  *
7  * 07/15/95 (Tim Norman)
8  * started.
9  *
10  * 08/08/95 (Matt Rains)
11  * i have cleaned up the source code. changes now bring this source
12  * into guidelines for recommended programming practice.
13  *
14  * 12/12/95 (Steffan Kaiser & Tim Norman)
15  * added some patches to fix some things and make more efficient
16  *
17  * 1/6/96 (Tim Norman)
18  * fixed a stupid pointer mistake...
19  * Thanks to everyone who noticed it!
20  *
21  * 8/1/96 (Tim Norman)
22  * fixed a bug when getenv returns NULL
23  *
24  * 8/7/96 (Steffan Kaiser and Tim Norman)
25  * speed improvements and bug fixes
26  *
27  * 8/27/96 (Tim Norman)
28  * changed code to use pointers directly into PATH environment
29  * variable rather than making our own copy. This saves some memory,
30  * but requires we write our own function to copy pathnames out of
31  * the variable.
32  *
33  * 12/23/96 (Aaron Kaufman)
34  * Fixed a bug in get_paths() that did not point to the first PATH
35  * in the environment variable.
36  *
37  * 7/12/97 (Tim Norman)
38  * Apparently, Aaron's bugfix got lost, so I fixed it again.
39  *
40  * 16 July 1998 (John P. Price)
41  * Added stand alone code.
42  *
43  * 17 July 1998 (John P. Price)
44  * Rewrote find_which to use searchpath function
45  *
46  * 24-Jul-1998 (John P Price <linux-guru@gcfl.net>)
47  * fixed bug where didn't check all extensions when path was specified
48  *
49  * 27-Jul-1998 (John P Price <linux-guru@gcfl.net>)
50  * added config.h include
51  *
52  * 30-Jul-1998 (John P Price <linux-guru@gcfl.net>)
53  * fixed so that it find_which returns NULL if filename is not
54  * executable (does not have .bat, .com, or .exe extension).
55  * Before command would to execute any file with any extension (opps!)
56  *
57  * 03-Dec-1998 (Eric Kohl)
58  * Changed find_which().
59  *
60  * 07-Dec-1998 (Eric Kohl)
61  * Added ".CMD" extension.
62  * Replaced numeric constant by _NR_OF_EXTENSIONS.
63  *
64  * 26-Feb-1999 (Eric Kohl)
65  * Replaced find_which() by SearchForExecutable().
66  * Now files are searched using the right extension order.
67  *
68  * 20-Apr-1999 (Eric Kohl)
69  * Some minor changes and improvements.
70  *
71  * 10-Jul-2004 (Jens Collin <jens.collin@lakhei.com>)
72  * Fixed searching for files with specific extensions in PATHEXT order.
73  *
74  */
75 
76 #include "precomp.h"
77 
78 
79 /* initial size of environment variable buffer */
80 #define ENV_BUFFER_SIZE 1024
81 
82 
83 /* searches for file using path info. */
84 
85 BOOL
86 SearchForExecutableSingle (LPCTSTR pFileName, LPTSTR pFullName, LPTSTR pPathExt, LPTSTR pDirectory)
87 {
88  TCHAR szPathBuffer[CMDLINE_LENGTH], *pszPathEnd;
89  LPTSTR s,f;
90  /* initialize full name buffer */
91  *pFullName = _T('\0');
92 
93  TRACE ("SearchForExecutableSingle: \'%s\' in dir: \'%s\'\n",
94  debugstr_aw(pFileName), debugstr_aw(pDirectory));
95 
96  pszPathEnd = szPathBuffer;
97  if (pDirectory != NULL)
98  {
99  _tcscpy(szPathBuffer, pDirectory);
100  pszPathEnd += _tcslen(pszPathEnd);
101  *pszPathEnd++ = _T('\\');
102  }
103  _tcscpy(pszPathEnd, pFileName);
104  pszPathEnd += _tcslen(pszPathEnd);
105 
106  if (IsExistingFile (szPathBuffer))
107  {
108  TRACE ("Found: \'%s\'\n", debugstr_aw(szPathBuffer));
109  _tcscpy (pFullName, szPathBuffer);
110  return TRUE;
111  }
112 
113  s = pPathExt;
114  while (s && *s)
115  {
116  f = _tcschr (s, _T(';'));
117 
118  if (f)
119  {
120  _tcsncpy (pszPathEnd, s, (size_t)(f-s));
121  pszPathEnd[f-s] = _T('\0');
122  s = f + 1;
123  }
124  else
125  {
126  _tcscpy (pszPathEnd, s);
127  s = NULL;
128  }
129 
130  if (IsExistingFile (szPathBuffer))
131  {
132  TRACE ("Found: \'%s\'\n", debugstr_aw(szPathBuffer));
133  _tcscpy (pFullName, szPathBuffer);
134  return TRUE;
135  }
136  }
137  return FALSE;
138 }
139 
140 
141 BOOL
142 SearchForExecutable (LPCTSTR pFileName, LPTSTR pFullName)
143 {
144  static TCHAR pszDefaultPathExt[] = _T(".com;.exe;.bat;.cmd");
145  LPTSTR pszPathExt, pszPath;
146  LPTSTR pCh;
147  DWORD dwBuffer;
148  TRACE ("SearchForExecutable: \'%s\'\n", debugstr_aw(pFileName));
149 
150  /* load environment variable PATHEXT */
151  pszPathExt = (LPTSTR)cmd_alloc (ENV_BUFFER_SIZE * sizeof(TCHAR));
152  if (!pszPathExt)
153  {
154  WARN("Cannot allocate memory for pszPathExt!\n");
155  return FALSE;
156  }
157 
158  dwBuffer = GetEnvironmentVariable (_T("PATHEXT"), pszPathExt, ENV_BUFFER_SIZE);
159  if (dwBuffer > ENV_BUFFER_SIZE)
160  {
161  LPTSTR pszOldPathExt = pszPathExt;
162  pszPathExt = (LPTSTR)cmd_realloc (pszPathExt, dwBuffer * sizeof (TCHAR));
163  if (!pszPathExt)
164  {
165  WARN("Cannot reallocate memory for pszPathExt!\n");
166  cmd_free(pszOldPathExt);
167  return FALSE;
168  }
169  GetEnvironmentVariable (_T("PATHEXT"), pszPathExt, dwBuffer);
170  _tcslwr(pszPathExt);
171  }
172  else if (0 == dwBuffer)
173  {
174  _tcscpy(pszPathExt, pszDefaultPathExt);
175  }
176  else
177  {
178  _tcslwr(pszPathExt);
179  }
180 
181  /* Check if valid directly on specified path */
182  if (SearchForExecutableSingle(pFileName, pFullName, pszPathExt, NULL))
183  {
184  cmd_free(pszPathExt);
185  return TRUE;
186  }
187 
188  /* If an explicit directory was given, stop here - no need to search PATH. */
189  if (pFileName[1] == _T(':') || _tcschr(pFileName, _T('\\')))
190  {
191  cmd_free(pszPathExt);
192  return FALSE;
193  }
194 
195  /* load environment variable PATH into buffer */
196  pszPath = (LPTSTR)cmd_alloc (ENV_BUFFER_SIZE * sizeof(TCHAR));
197  if (!pszPath)
198  {
199  WARN("Cannot allocate memory for pszPath!\n");
200  return FALSE;
201  }
202 
203  dwBuffer = GetEnvironmentVariable (_T("PATH"), pszPath, ENV_BUFFER_SIZE);
204  if (dwBuffer > ENV_BUFFER_SIZE)
205  {
206  LPTSTR pszOldPath = pszPath;
207  pszPath = (LPTSTR)cmd_realloc (pszPath, dwBuffer * sizeof (TCHAR));
208  if (!pszPath)
209  {
210  WARN("Cannot reallocate memory for pszPath!\n");
211  cmd_free(pszOldPath);
212  cmd_free(pszPathExt);
213  return FALSE;
214  }
215  GetEnvironmentVariable (_T("PATH"), pszPath, dwBuffer);
216  }
217 
218  TRACE ("SearchForExecutable(): Loaded PATH: %s\n", debugstr_aw(pszPath));
219 
220  /* search in PATH */
221  pCh = _tcstok(pszPath, _T(";"));
222  while (pCh)
223  {
224  if (SearchForExecutableSingle(pFileName, pFullName, pszPathExt, pCh))
225  {
226  cmd_free(pszPath);
227  cmd_free(pszPathExt);
228  return TRUE;
229  }
230  pCh = _tcstok(NULL, _T(";"));
231  }
232 
233  cmd_free(pszPath);
234  cmd_free(pszPathExt);
235  return FALSE;
236 }
237 
238 /* EOF */
#define TRUE
Definition: types.h:120
const CHAR * LPCTSTR
Definition: xmlstorage.h:193
#define ENV_BUFFER_SIZE
Definition: where.c:80
BOOL SearchForExecutable(LPCTSTR pFileName, LPTSTR pFullName)
Definition: where.c:142
#define WARN(fmt,...)
Definition: debug.h:111
_TCHAR * _tcsncpy(_TCHAR *dst, const _TCHAR *src, size_t n)
Definition: tcsncpy.h:9
#define debugstr_aw
Definition: precomp.h:43
#define CMDLINE_LENGTH
Definition: help.h:12
_TCHAR * _tcscpy(_TCHAR *to, const _TCHAR *from)
Definition: tcscpy.h:8
CHAR * LPTSTR
Definition: xmlstorage.h:192
unsigned int BOOL
Definition: ntddk_ex.h:94
size_t __cdecl _tcslen(const _TCHAR *str)
Definition: tcslen.h:9
smooth NULL
Definition: ftsmooth.c:416
#define _tcslwr
Definition: tchar.h:1465
_TCHAR * _tcschr(const _TCHAR *s, _XINT c)
Definition: tcschr.h:4
char TCHAR
Definition: xmlstorage.h:189
GLfloat f
Definition: glext.h:7540
#define _T(x)
Definition: vfdio.h:22
#define TRACE(s)
Definition: solgame.cpp:4
unsigned long DWORD
Definition: ntddk_ex.h:95
#define cmd_realloc(ptr, size)
Definition: cmddbg.h:30
GLdouble s
Definition: gl.h:2039
#define cmd_alloc(size)
Definition: cmddbg.h:29
#define cmd_free(ptr)
Definition: cmddbg.h:31
#define f
Definition: ke_i.h:83
#define _tcstok
Definition: tchar.h:1416
#define GetEnvironmentVariable
Definition: winbase.h:3638
BOOL IsExistingFile(LPCTSTR)
Definition: misc.c:500
BOOL SearchForExecutableSingle(LPCTSTR pFileName, LPTSTR pFullName, LPTSTR pPathExt, LPTSTR pDirectory)
Definition: where.c:86