source: trunk/dll/pathutil.c@ 1480

Last change on this file since 1480 was 1480, checked in by Gregg Young, 16 years ago

Fix failure to correctly check for large file support in FindSwapperDat fall back code minor streamling. Add LVM.EXE to partition submenu. Stop using xDosQueryAppType where the file name it is passed is already a local stack variable. Correct a typo in several file header comments.

  • Property svn:keywords set to Author Date Id Revision
File size: 11.3 KB
Line 
1
2/***********************************************************************
3
4 $Id: pathutil.c 1480 2009-11-22 22:58:49Z gyoung $
5
6 Path handling utility functions
7
8 Copyright (c) 1993-98 M. Kimes
9 Copyright (c) 2001, 2009 Steven H. Levine
10
11 05 Jan 08 SHL Move from arccnrs.c and comp.c to here
12 06 Jan 08 GKY Add NormalizeCmdLine to check program strings on entry
13 29 Feb 08 GKY Changes to enable user settable command line length
14 15 Oct 08 GKY Fix NormalizeCmdLine to check all 5 executible extensions when no extension provided;
15 use searchapath to check for existance of file types not checked by DosQAppType;
16 close DosFind.
17 28 Jun 09 GKY Added AddBackslashToPath() to remove repeatative code
18 12 Jul 09 GKY Add xDosQueryAppType and xDosAlloc... to allow FM/2 to load in high memory
19
20***********************************************************************/
21
22#include <stdlib.h>
23#include <string.h>
24
25#define INCL_WIN
26#define INCL_DOS
27#define INCL_LONGLONG
28
29#include "fm3dll.h" // needs_quoting
30#include "notebook.h" // Data declaration(s)
31#include "init.h" // Data declaration(s)
32#include "fm3str.h"
33#include "srchpath.h" // searchapath
34#include "pathutil.h"
35#include "strips.h" // remove_first_occurence_of_character
36#include "valid.h" // needs_quoting
37#include "errutil.h" // Dos_Error...
38#include "strutil.h" // GetPString
39#include "wrappers.h" // xmalloc
40#include "fortify.h"
41#include "stristr.h" //stristr
42
43static PSZ pszSrcFile = __FILE__;
44
45PSZ AddBackslashToPath(PSZ pszPathName)
46{
47 if (pszPathName[strlen(pszPathName) - 1] != '\\')
48 strcat(pszPathName, PCSZ_BACKSLASH);
49 return pszPathName;
50}
51
52// #pragma data_seg(DATA1)
53
54/**
55 * Build full path name in callers buffer given directory
56 * name and filename
57 * @param pszPathName points to drive/directory if not NULL
58 * @returns pointer to full path name in caller's buffer
59 * @note OK for pszFullPathName and pszPathName to point to same buffer
60 *
61 */
62
63PSZ BldFullPathName(PSZ pszFullPathName, PCSZ pszPathName, PCSZ pszFileName)
64{
65 UINT c = pszPathName ? strlen(pszPathName) : 0;
66 if (c > 0) {
67 memcpy(pszFullPathName, pszPathName, c);
68 if (pszFullPathName[c - 1] != '\\')
69 pszFullPathName[c++] = '\\';
70 }
71 strcpy(pszFullPathName + c, pszFileName);
72 return pszFullPathName;
73}
74
75/**
76 * Build quoted full path name in callers buffer given
77 * directory name and filename
78 * @param pszPathName points to drive/directory if not NULL
79 * @returns pointer to quoted path name in caller's buffer
80 */
81
82PSZ BldQuotedFullPathName(PSZ pszFullPathName, PCSZ pszPathName, PCSZ pszFileName)
83{
84 UINT c = pszPathName ? strlen(pszPathName) : 0;
85 BOOL q = needs_quoting(pszPathName) || needs_quoting(pszFileName);
86 PSZ psz = pszFullPathName;
87
88 if (q)
89 *psz++ = '"';
90 if (c > 0) {
91 memcpy(psz, pszPathName, c);
92 psz += c;
93 if (*(psz - 1) != '\\')
94 *psz++ = '\\';
95 }
96 strcpy(psz, pszFileName);
97 if (q) {
98 psz += strlen(psz);
99 *psz++ = '"';
100 *psz = 0;
101 }
102 return pszFullPathName;
103}
104
105/**
106 * Build quoted full path name in callers buffer given a filename
107 * @returns pointer to quoted file name in caller's buffer
108 */
109
110PSZ BldQuotedFileName(PSZ pszQuotedFileName, PCSZ pszFileName)
111{
112 BOOL q = needs_quoting(pszFileName);
113 PSZ psz = pszQuotedFileName;
114
115 if (q)
116 *psz++ = '"';
117 strcpy(psz, pszFileName);
118 if (q) {
119 psz += strlen(psz);
120 *psz++ = '"';
121 *psz = 0;
122 }
123 return pszQuotedFileName;
124}
125
126/** NormalizeCmdLine
127 * Checks a command line for common errors (missing quotes, missing extension,
128 * no space between exe and args etc) Also check for the existance of the file
129 * and checks .com and .exe file headers.
130 * Command line passed as pszCmdLine_
131 * A pointer to a buffer of the size MaxComLineStrg should be supplied in
132 * pszWorkBuf. This is where the quoted etc as necessary command
133 * line string will be returned.
134 */
135
136PCSZ NormalizeCmdLine(PSZ pszWorkBuf, PSZ pszCmdLine_)
137{
138 char *szCmdLine, *szArgs;
139 char *offset = '\0', *offsetexe, *offsetcom, *offsetcmd, *offsetbtm, *offsetbat;
140 APIRET ret;
141 ULONG ulAppType;
142 char *pszChar;
143 char *FullPath;
144 PSZ pszNewCmdLine = pszWorkBuf;
145
146 szCmdLine = xmalloc(MaxComLineStrg, pszSrcFile, __LINE__);
147 if (!szCmdLine)
148 return pszCmdLine_; //already complained
149 szArgs = xmalloc(MaxComLineStrg, pszSrcFile, __LINE__);
150 if (!szArgs) {
151 free(szCmdLine);
152 return pszCmdLine_; //already complained
153 }
154 bstrip(pszCmdLine_);
155 memset(pszWorkBuf, 0, MaxComLineStrg);
156 strcpy(szCmdLine, pszCmdLine_);
157 if (szCmdLine[0] != '\0') {
158 offsetexe = stristr(pszCmdLine_, PCSZ_DOTEXE);
159 offsetcmd = stristr(pszCmdLine_, PCSZ_DOTCMD);
160 offsetcom = stristr(pszCmdLine_, PCSZ_DOTCOM);
161 offsetbtm = stristr(pszCmdLine_, PCSZ_DOTBTM);
162 offsetbat = stristr(pszCmdLine_, PCSZ_DOTBAT);
163 if (offsetexe)
164 offset = offsetexe;
165 else {
166 if (offsetcom)
167 offset = offsetcom;
168 else {
169 if (offsetcmd)
170 offset = offsetcmd;
171 else {
172 if (offsetbtm)
173 offset = offsetbtm;
174 else {
175 if (offsetbat)
176 offset = offsetexe;
177 }
178 }
179 }
180 }
181 if (offset) {
182 szCmdLine[offset + 4 - pszCmdLine_] = '\0';
183 strcpy(szArgs, &pszCmdLine_[offset + 4 - pszCmdLine_]);
184 while (strchr(szCmdLine, '\"'))
185 remove_first_occurence_of_character("\"", szCmdLine);
186 if ((szArgs[0] == '\"' && szArgs[1] == ' ') ||
187 !strstr(pszCmdLine_, "\\:")||
188 strchr(szArgs, '\"') == strrchr(szArgs, '\"'))
189 remove_first_occurence_of_character("\"", szArgs);
190 if (strchr(szArgs, '\"') != strrchr(szArgs, '\"'))
191 saymsg(MB_OK, HWND_DESKTOP,
192 NullStr,
193 GetPString(IDS_QUOTESINARGSTEXT),
194 pszCmdLine_);
195 if (!offsetexe && !offsetcom) {
196 FullPath = searchapath(PCSZ_PATH, szCmdLine);
197 if (*FullPath)
198 ret = 0;
199 }
200 else
201 ret = xDosQueryAppType(szCmdLine, &ulAppType);
202 BldQuotedFileName(pszNewCmdLine, szCmdLine);
203 if (ret) {
204 ret = saymsg(MB_YESNO,
205 HWND_DESKTOP,
206 NullStr,
207 GetPString(IDS_PROGRAMNOTFOUNDTEXT),
208 pszCmdLine_);
209 if (ret == MBID_YES){
210 if (szArgs[0] != ' ')
211 strcat(pszNewCmdLine, " ");
212 strcat(pszNewCmdLine, szArgs);
213 }
214 else{
215 fCancelAction = TRUE;
216 pszNewCmdLine = pszCmdLine_;
217 }
218 }
219 else{
220 if (szArgs[0] != ' ')
221 strcat(pszNewCmdLine, " ");
222 strcat(pszNewCmdLine, szArgs);
223 }
224
225 }
226 // if it doesn't have an extension try it with all the standard ones and add if found
227 else if (szCmdLine && (!strchr(szCmdLine, '.') ||
228 strrchr(szCmdLine, '.' ) < strrchr(szCmdLine, '\\'))) {
229 if (!strchr(szCmdLine, ' ')) {
230 // strip quotes readded by BuildQuotedFileName
231 while (strchr(szCmdLine, '\"'))
232 remove_first_occurence_of_character("\"", szCmdLine);
233 ret = xDosQueryAppType(szCmdLine, &ulAppType); // exe automatically appended
234 if (!ret)
235 strcat(szCmdLine, PCSZ_DOTEXE);
236 else {
237 strcat(szCmdLine, PCSZ_DOTCOM);
238 ret = xDosQueryAppType(szCmdLine, &ulAppType);
239 if (ret) {
240 offset = strrchr(szCmdLine, '.' );
241 *offset = 0;
242 strcat(szCmdLine, PCSZ_DOTCMD);
243 FullPath = searchapath(PCSZ_PATH, szCmdLine);
244 if (*FullPath)
245 ret = 0;
246 else {
247 *offset = 0;
248 strcat(szCmdLine, PCSZ_DOTBAT);
249 FullPath = searchapath(PCSZ_PATH, szCmdLine);
250 if (*FullPath)
251 ret = 0;
252 else {
253 *offset = 0;
254 strcat(szCmdLine, PCSZ_DOTBTM);
255 FullPath = searchapath(PCSZ_PATH, szCmdLine);
256 if (*FullPath)
257 ret = 0;
258 }
259 }
260 }
261 }
262 }
263 else {
264 pszChar = szCmdLine;
265 while (pszChar) {
266 while (strchr(szCmdLine, '\"'))
267 remove_first_occurence_of_character("\"", szCmdLine);
268 if (*pszChar == ' ') { //test at every space for the end of the filename
269 *pszChar = '\0';
270 ret = xDosQueryAppType(szCmdLine, &ulAppType);
271 if (!ret) {
272 strcat(szCmdLine, PCSZ_DOTEXE);
273 break;
274 }
275 else {
276 strcat(szCmdLine, PCSZ_DOTCOM);
277 ret = xDosQueryAppType(szCmdLine, &ulAppType);
278 if (ret) {
279 offset = strrchr(szCmdLine, '.' );
280 *offset = 0;
281 strcat(szCmdLine, PCSZ_DOTCMD);
282 FullPath = searchapath(PCSZ_PATH, szCmdLine);
283 if (*FullPath) {
284 ret = 0;
285 break;
286 }
287 else {
288 *offset = 0;
289 strcat(szCmdLine, PCSZ_DOTBAT);
290 FullPath = searchapath(PCSZ_PATH, szCmdLine);
291 if (*FullPath) {
292 ret = 0;
293 break;
294 }
295 else {
296 *offset = 0;
297 strcat(szCmdLine, PCSZ_DOTBTM);
298 FullPath = searchapath(PCSZ_PATH, szCmdLine);
299 if (*FullPath) {
300 ret = 0;
301 break;
302 }
303 }
304 }
305 }
306 else
307 break;
308 }
309 }
310 strcpy(szCmdLine, pszCmdLine_);
311 pszChar++;
312 }
313 }
314 if (!ret){
315 BldQuotedFileName(pszNewCmdLine, szCmdLine);
316 strcpy(szArgs, pszCmdLine_ + strlen(szCmdLine) - 3);
317 if ((szArgs[0] == '\"' && szArgs[1] == ' ') ||
318 !strstr(pszCmdLine_, "\\:" ) ||
319 strchr(szArgs, '\"') == strrchr(szArgs, '\"'))
320 remove_first_occurence_of_character("\"", szArgs);
321 if (strchr(szArgs, '\"') != strrchr(szArgs, '\"'))
322 saymsg(MB_OK, HWND_DESKTOP,
323 NullStr,
324 GetPString(IDS_QUOTESINARGSTEXT),
325 pszCmdLine_);
326 if (szArgs[0] != ' ')
327 strcat(pszNewCmdLine, " ");
328 strcat(pszNewCmdLine, szArgs);
329 }
330 else { // fail if no extension can be found runemf2 requires one
331 ret = saymsg(MB_OK,
332 HWND_DESKTOP,
333 NullStr,
334 GetPString(IDS_PROGRAMNOTEXE2TEXT),
335 pszCmdLine_);
336 fCancelAction = TRUE;
337 pszNewCmdLine = pszCmdLine_;
338 }
339 }
340 else { // file has a nonstandard extension for executible
341 pszChar = strrchr(szCmdLine, '.');
342 while (pszChar && *pszChar !=' ') {
343 pszChar++;
344 }
345 *pszChar = '\0';
346 strcpy (szArgs, pszCmdLine_ + strlen(szCmdLine));
347 while (strchr(szCmdLine, '\"'))
348 remove_first_occurence_of_character("\"", szCmdLine);
349 if ((szArgs[0] == '\"' && szArgs[1] == ' ') ||
350 !strstr(pszCmdLine_, "\\:")||
351 strchr(szArgs, '\"') == strrchr(szArgs, '\"'))
352 remove_first_occurence_of_character("\"", szArgs);
353 if (strchr(szArgs, '\"') != strrchr(szArgs, '\"'))
354 saymsg(MB_OK, HWND_DESKTOP,
355 NullStr,
356 GetPString(IDS_QUOTESINARGSTEXT),
357 pszCmdLine_);
358 FullPath = searchapath(PCSZ_PATH, szCmdLine);
359 BldQuotedFileName(pszNewCmdLine, szCmdLine);
360 if (!*FullPath) {
361 ret = saymsg(MB_YESNO,
362 HWND_DESKTOP,
363 NullStr,
364 GetPString(IDS_PROGRAMNOTFOUNDTEXT),
365 pszCmdLine_);
366 if (ret == MBID_YES) {
367 if (szArgs[0] != ' ')
368 strcat(pszNewCmdLine, " ");
369 strcat(pszNewCmdLine, szArgs);
370 }
371 else {
372 fCancelAction = TRUE;
373 pszWorkBuf = pszCmdLine_;
374 }
375 }
376 else {
377 ret = saymsg(MB_YESNOCANCEL,
378 HWND_DESKTOP,
379 NullStr,
380 GetPString(IDS_PROGRAMNOTEXE3TEXT),
381 pszCmdLine_, pszNewCmdLine);
382 if (ret == MBID_YES){
383 if (szArgs[0] != ' ')
384 strcat(pszNewCmdLine, " ");
385 strcat(pszNewCmdLine, szArgs);
386 }
387 if (ret == MBID_CANCEL){
388 fCancelAction = TRUE;
389 pszNewCmdLine = pszCmdLine_;
390 }
391 }
392 }
393 }
394 free(szArgs);
395 free(szCmdLine);
396 return pszWorkBuf;
397}
398
399#pragma alloc_text(PATHUTIL,BldFullPathName)
400#pragma alloc_text(PATHUTIL,BldQuotedFileName)
401#pragma alloc_text(PATHUTIL,BldQuotedFullPathName)
402#pragma alloc_text(PATHUTIL,NormalizeCmdLine)
Note: See TracBrowser for help on using the repository browser.