source: trunk/dll/pathutil.c@ 1454

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

Changes to allow high mem loading of dll; Refactor .LONGNAME and .SUBJECT EA fetch to FetchCommonEAs. Add szFSType to FillInRecordFromFSA use to bypass EA scan and size formatting for tree container; Fix labels/FS type to work on scan on NOPRESCAN Drives; Fixed dbl directory names on restore of dir cnrs; (Tickets 47, 339, 363, 368, 369, 370)

  • Property svn:keywords set to Author Date Id Revision
File size: 11.3 KB
RevLine 
[907]1
2/***********************************************************************
3
[1323]4 $Id: pathutil.c 1439 2009-07-12 21:57:04Z gyoung $
[907]5
6 Path handling utility functions
7
8 Copyright (c) 1993-98 M. Kimes
[1394]9 Copyright (c) 2001, 2009 Steven H. Levine
[907]10
11 05 Jan 08 SHL Move from arccnrs.c and comp.c to here
[920]12 06 Jan 08 GKY Add NormalizeCmdLine to check program strings on entry
[985]13 29 Feb 08 GKY Changes to enable user settable command line length
[1247]14 15 Oct 08 GKY Fix NormalizeCmdLine to check all 5 executible extensions when no extension provided;
[1394]15 use searchapath to check for existance of file types not checked by DosQAppType;
[1439]16 close DosFind.
17 28 Jun 09 GKY Added AddBackslashToPath() to remove repeatative code
18 12 Jul 09 GKY Add xDosQueryAppType and xDoxAlloc... to allow FM/2 to load in high memory
[907]19
20***********************************************************************/
21
[1039]22#include <stdlib.h>
[907]23#include <string.h>
24
25#define INCL_WIN
[920]26#define INCL_DOS
[907]27#define INCL_LONGLONG
28
[1185]29#include "fm3dll.h" // needs_quoting
[1211]30#include "notebook.h" // Data declaration(s)
31#include "init.h" // Data declaration(s)
[1185]32#include "fm3str.h"
[1247]33#include "srchpath.h" // searchapath
[907]34#include "pathutil.h"
[1161]35#include "strips.h" // remove_first_occurence_of_character
[1185]36#include "valid.h" // needs_quoting
[920]37#include "errutil.h" // Dos_Error...
38#include "strutil.h" // GetPString
[1185]39#include "wrappers.h" // xmalloc
[1039]40#include "fortify.h"
[1398]41#include "stristr.h" //stristr
[907]42
[985]43static PSZ pszSrcFile = __FILE__;
44
[1438]45PSZ AddBackslashToPath(PSZ pszPathName)
46{
47 if (pszPathName[strlen(pszPathName) - 1] != '\\')
48 strcat(pszPathName, PCSZ_BACKSLASH);
49 return pszPathName;
50}
51
[907]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
[1398]63PSZ BldFullPathName(PSZ pszFullPathName, PCSZ pszPathName, PCSZ pszFileName)
[907]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
[1398]82PSZ BldQuotedFullPathName(PSZ pszFullPathName, PCSZ pszPathName, PCSZ pszFileName)
[907]83{
84 UINT c = pszPathName ? strlen(pszPathName) : 0;
[1161]85 BOOL q = needs_quoting(pszPathName) || needs_quoting(pszFileName);
[907]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
[1394]110PSZ BldQuotedFileName(PSZ pszQuotedFileName, PCSZ pszFileName)
[907]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
[920]126/** NormalizeCmdLine
127 * Checks a command line for common errors (missing quotes, missing extension,
[1248]128 * no space between exe and args etc) Also check for the existance of the file
129 * and checks .com and .exe file headers.
[920]130 * Command line passed as pszCmdLine_
[985]131 * A pointer to a buffer of the size MaxComLineStrg should be supplied in
[920]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{
[985]138 char *szCmdLine, *szArgs;
[920]139 char *offset = '\0', *offsetexe, *offsetcom, *offsetcmd, *offsetbtm, *offsetbat;
140 APIRET ret;
141 ULONG ulAppType;
142 char *pszChar;
[1247]143 char *FullPath;
[920]144 PSZ pszNewCmdLine = pszWorkBuf;
145
[985]146 szCmdLine = xmalloc(MaxComLineStrg, pszSrcFile, __LINE__);
147 if (!szCmdLine)
148 return pszCmdLine_; //already complained
149 szArgs = xmalloc(MaxComLineStrg, pszSrcFile, __LINE__);
150 if (!szArgs) {
[1039]151 free(szCmdLine);
[985]152 return pszCmdLine_; //already complained
153 }
[920]154 bstrip(pszCmdLine_);
[985]155 memset(pszWorkBuf, 0, MaxComLineStrg);
[920]156 strcpy(szCmdLine, pszCmdLine_);
157 if (szCmdLine[0] != '\0') {
[1398]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);
[920]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_);
[1247]195 if (!offsetexe && !offsetcom) {
[1398]196 FullPath = searchapath(PCSZ_PATH, szCmdLine);
[1394]197 if (*FullPath)
198 ret = 0;
[920]199 }
200 else
[1439]201 ret = xDosQueryAppType(szCmdLine, &ulAppType);
[920]202 BldQuotedFileName(pszNewCmdLine, szCmdLine);
203 if (ret) {
[1394]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);
[920]213 }
[1394]214 else{
215 fCancelAction = TRUE;
216 pszNewCmdLine = pszCmdLine_;
217 }
[920]218 }
219 else{
[1394]220 if (szArgs[0] != ' ')
221 strcat(pszNewCmdLine, " ");
222 strcat(pszNewCmdLine, szArgs);
[920]223 }
224
225 }
[1247]226 // if it doesn't have an extension try it with all the standard ones and add if found
[920]227 else if (szCmdLine && (!strchr(szCmdLine, '.') ||
[1247]228 strrchr(szCmdLine, '.' ) < strrchr(szCmdLine, '\\'))) {
[920]229 if (!strchr(szCmdLine, ' ')) {
[1394]230 // strip quotes readded by BuildQuotedFileName
[920]231 while (strchr(szCmdLine, '\"'))
232 remove_first_occurence_of_character("\"", szCmdLine);
[1439]233 ret = xDosQueryAppType(szCmdLine, &ulAppType); // exe automatically appended
[1394]234 if (!ret)
[1398]235 strcat(szCmdLine, PCSZ_DOTEXE);
[1394]236 else {
[1398]237 strcat(szCmdLine, PCSZ_DOTCOM);
[1439]238 ret = xDosQueryAppType(szCmdLine, &ulAppType);
[1394]239 if (ret) {
240 offset = strrchr(szCmdLine, '.' );
241 *offset = 0;
[1398]242 strcat(szCmdLine, PCSZ_DOTCMD);
243 FullPath = searchapath(PCSZ_PATH, szCmdLine);
[1394]244 if (*FullPath)
245 ret = 0;
246 else {
247 *offset = 0;
[1398]248 strcat(szCmdLine, PCSZ_DOTBAT);
249 FullPath = searchapath(PCSZ_PATH, szCmdLine);
[1394]250 if (*FullPath)
251 ret = 0;
252 else {
253 *offset = 0;
[1398]254 strcat(szCmdLine, PCSZ_DOTBTM);
255 FullPath = searchapath(PCSZ_PATH, szCmdLine);
[1394]256 if (*FullPath)
257 ret = 0;
258 }
259 }
260 }
261 }
[920]262 }
263 else {
264 pszChar = szCmdLine;
265 while (pszChar) {
266 while (strchr(szCmdLine, '\"'))
267 remove_first_occurence_of_character("\"", szCmdLine);
[1247]268 if (*pszChar == ' ') { //test at every space for the end of the filename
[920]269 *pszChar = '\0';
[1439]270 ret = xDosQueryAppType(szCmdLine, &ulAppType);
[1394]271 if (!ret) {
[1398]272 strcat(szCmdLine, PCSZ_DOTEXE);
[1394]273 break;
274 }
275 else {
[1398]276 strcat(szCmdLine, PCSZ_DOTCOM);
[1439]277 ret = xDosQueryAppType(szCmdLine, &ulAppType);
[1394]278 if (ret) {
279 offset = strrchr(szCmdLine, '.' );
280 *offset = 0;
[1398]281 strcat(szCmdLine, PCSZ_DOTCMD);
282 FullPath = searchapath(PCSZ_PATH, szCmdLine);
[1394]283 if (*FullPath) {
284 ret = 0;
285 break;
286 }
287 else {
288 *offset = 0;
[1398]289 strcat(szCmdLine, PCSZ_DOTBAT);
290 FullPath = searchapath(PCSZ_PATH, szCmdLine);
[1394]291 if (*FullPath) {
292 ret = 0;
293 break;
294 }
295 else {
296 *offset = 0;
[1398]297 strcat(szCmdLine, PCSZ_DOTBTM);
298 FullPath = searchapath(PCSZ_PATH, szCmdLine);
[1394]299 if (*FullPath) {
300 ret = 0;
301 break;
302 }
303 }
304 }
305 }
306 else
307 break;
308 }
[920]309 }
310 strcpy(szCmdLine, pszCmdLine_);
311 pszChar++;
312 }
313 }
314 if (!ret){
[1394]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);
[920]329 }
[1248]330 else { // fail if no extension can be found runemf2 requires one
[1394]331 ret = saymsg(MB_OK,
332 HWND_DESKTOP,
333 NullStr,
334 GetPString(IDS_PROGRAMNOTEXE2TEXT),
335 pszCmdLine_);
336 fCancelAction = TRUE;
337 pszNewCmdLine = pszCmdLine_;
[920]338 }
339 }
[1247]340 else { // file has a nonstandard extension for executible
[920]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_);
[1398]358 FullPath = searchapath(PCSZ_PATH, szCmdLine);
[920]359 BldQuotedFileName(pszNewCmdLine, szCmdLine);
[1248]360 if (!*FullPath) {
[920]361 ret = saymsg(MB_YESNO,
362 HWND_DESKTOP,
363 NullStr,
364 GetPString(IDS_PROGRAMNOTFOUNDTEXT),
365 pszCmdLine_);
366 if (ret == MBID_YES) {
[1394]367 if (szArgs[0] != ' ')
368 strcat(pszNewCmdLine, " ");
369 strcat(pszNewCmdLine, szArgs);
[920]370 }
371 else {
372 fCancelAction = TRUE;
373 pszWorkBuf = pszCmdLine_;
374 }
375 }
[1248]376 else {
377 ret = saymsg(MB_YESNOCANCEL,
[1394]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 }
[920]391 }
392 }
393 }
[1039]394 free(szArgs);
395 free(szCmdLine);
[920]396 return pszWorkBuf;
397}
398
[907]399#pragma alloc_text(PATHUTIL,BldFullPathName)
400#pragma alloc_text(PATHUTIL,BldQuotedFileName)
401#pragma alloc_text(PATHUTIL,BldQuotedFullPathName)
[920]402#pragma alloc_text(PATHUTIL,NormalizeCmdLine)
Note: See TracBrowser for help on using the repository browser.