source: trunk/dll/pathutil.c@ 1438

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

Improved drivebar changes; Added AddBackslashToPath() to remove repeatative code. replaced "
" with PCSZ variable; ANY_OBJ added the DosAlloc... (experimental)

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