ReactOS 0.4.15-dev-7934-g1dc8d80
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
85BOOL
86SearchForExecutableSingle (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 GetFullPathName(szPathBuffer, MAX_PATH, pFullName, NULL);
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 GetFullPathName(szPathBuffer, MAX_PATH, pFullName, NULL);
134 return TRUE;
135 }
136 }
137 return FALSE;
138}
139
140
141BOOL
142SearchForExecutable (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 CMDLINE_LENGTH
Definition: help.h:12
BOOL IsExistingFile(IN LPCTSTR pszPath)
Definition: misc.c:498
#define debugstr_aw
Definition: precomp.h:43
#define ENV_BUFFER_SIZE
Definition: where.c:80
BOOL SearchForExecutable(LPCTSTR pFileName, LPTSTR pFullName)
Definition: where.c:142
BOOL SearchForExecutableSingle(LPCTSTR pFileName, LPTSTR pFullName, LPTSTR pPathExt, LPTSTR pDirectory)
Definition: where.c:86
#define WARN(fmt,...)
Definition: debug.h:112
#define cmd_realloc(ptr, size)
Definition: cmddbg.h:30
#define cmd_free(ptr)
Definition: cmddbg.h:31
#define cmd_alloc(size)
Definition: cmddbg.h:29
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define MAX_PATH
Definition: compat.h:34
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLdouble s
Definition: gl.h:2039
GLfloat f
Definition: glext.h:7540
#define _tcscpy
Definition: tchar.h:623
#define _tcsncpy
Definition: tchar.h:1410
#define _tcslwr
Definition: tchar.h:1465
#define _tcstok
Definition: tchar.h:1416
#define _tcschr
Definition: tchar.h:1406
#define f
Definition: ke_i.h:83
#define TRACE(s)
Definition: solgame.cpp:4
#define _T(x)
Definition: vfdio.h:22
#define GetEnvironmentVariable
Definition: winbase.h:3814
#define GetFullPathName
Definition: winbase.h:3821
char TCHAR
Definition: xmlstorage.h:189
const CHAR * LPCTSTR
Definition: xmlstorage.h:193
CHAR * LPTSTR
Definition: xmlstorage.h:192
#define _tcslen
Definition: xmlstorage.h:198