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
Line 
1
2/***********************************************************************
3
4 $Id: pathutil.c 1438 2009-06-28 20:47:00Z 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
18***********************************************************************/
19
20#include <stdlib.h>
21#include <string.h>
22
23#define INCL_WIN
24#define INCL_DOS
25#define INCL_LONGLONG
26
27#include "fm3dll.h" // needs_quoting
28#include "notebook.h" // Data declaration(s)
29#include "init.h" // Data declaration(s)
30#include "fm3str.h"
31#include "srchpath.h" // searchapath
32#include "pathutil.h"
33#include "strips.h" // remove_first_occurence_of_character
34#include "valid.h" // needs_quoting
35#include "errutil.h" // Dos_Error...
36#include "strutil.h" // GetPString
37#include "wrappers.h" // xmalloc
38#include "fortify.h"
39#include "stristr.h" //stristr
40
41static PSZ pszSrcFile = __FILE__;
42
43PSZ AddBackslashToPath(PSZ pszPathName)
44{
45 if (pszPathName[strlen(pszPathName) - 1] != '\\')
46 strcat(pszPathName, PCSZ_BACKSLASH);
47 return pszPathName;
48}
49
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
61PSZ BldFullPathName(PSZ pszFullPathName, PCSZ pszPathName, PCSZ pszFileName)
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
80PSZ BldQuotedFullPathName(PSZ pszFullPathName, PCSZ pszPathName, PCSZ pszFileName)
81{
82 UINT c = pszPathName ? strlen(pszPathName) : 0;
83 BOOL q = needs_quoting(pszPathName) || needs_quoting(pszFileName);
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
108PSZ BldQuotedFileName(PSZ pszQuotedFileName, PCSZ pszFileName)
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
124/** NormalizeCmdLine
125 * Checks a command line for common errors (missing quotes, missing extension,
126 * no space between exe and args etc) Also check for the existance of the file
127 * and checks .com and .exe file headers.
128 * Command line passed as pszCmdLine_
129 * A pointer to a buffer of the size MaxComLineStrg should be supplied in
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{
136 char *szCmdLine, *szArgs;
137 char *offset = '\0', *offsetexe, *offsetcom, *offsetcmd, *offsetbtm, *offsetbat;
138 APIRET ret;
139 ULONG ulAppType;
140 char *pszChar;
141 char *FullPath;
142 PSZ pszNewCmdLine = pszWorkBuf;
143
144 szCmdLine = xmalloc(MaxComLineStrg, pszSrcFile, __LINE__);
145 if (!szCmdLine)
146 return pszCmdLine_; //already complained
147 szArgs = xmalloc(MaxComLineStrg, pszSrcFile, __LINE__);
148 if (!szArgs) {
149 free(szCmdLine);
150 return pszCmdLine_; //already complained
151 }
152 bstrip(pszCmdLine_);
153 memset(pszWorkBuf, 0, MaxComLineStrg);
154 strcpy(szCmdLine, pszCmdLine_);
155 if (szCmdLine[0] != '\0') {
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);
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_);
193 if (!offsetexe && !offsetcom) {
194 FullPath = searchapath(PCSZ_PATH, szCmdLine);
195 if (*FullPath)
196 ret = 0;
197 }
198 else
199 ret = DosQueryAppType(szCmdLine, &ulAppType);
200 BldQuotedFileName(pszNewCmdLine, szCmdLine);
201 if (ret) {
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);
211 }
212 else{
213 fCancelAction = TRUE;
214 pszNewCmdLine = pszCmdLine_;
215 }
216 }
217 else{
218 if (szArgs[0] != ' ')
219 strcat(pszNewCmdLine, " ");
220 strcat(pszNewCmdLine, szArgs);
221 }
222
223 }
224 // if it doesn't have an extension try it with all the standard ones and add if found
225 else if (szCmdLine && (!strchr(szCmdLine, '.') ||
226 strrchr(szCmdLine, '.' ) < strrchr(szCmdLine, '\\'))) {
227 if (!strchr(szCmdLine, ' ')) {
228 // strip quotes readded by BuildQuotedFileName
229 while (strchr(szCmdLine, '\"'))
230 remove_first_occurence_of_character("\"", szCmdLine);
231 ret = DosQueryAppType(szCmdLine, &ulAppType); // exe automatically appended
232 if (!ret)
233 strcat(szCmdLine, PCSZ_DOTEXE);
234 else {
235 strcat(szCmdLine, PCSZ_DOTCOM);
236 ret = DosQueryAppType(szCmdLine, &ulAppType);
237 if (ret) {
238 offset = strrchr(szCmdLine, '.' );
239 *offset = 0;
240 strcat(szCmdLine, PCSZ_DOTCMD);
241 FullPath = searchapath(PCSZ_PATH, szCmdLine);
242 if (*FullPath)
243 ret = 0;
244 else {
245 *offset = 0;
246 strcat(szCmdLine, PCSZ_DOTBAT);
247 FullPath = searchapath(PCSZ_PATH, szCmdLine);
248 if (*FullPath)
249 ret = 0;
250 else {
251 *offset = 0;
252 strcat(szCmdLine, PCSZ_DOTBTM);
253 FullPath = searchapath(PCSZ_PATH, szCmdLine);
254 if (*FullPath)
255 ret = 0;
256 }
257 }
258 }
259 }
260 }
261 else {
262 pszChar = szCmdLine;
263 while (pszChar) {
264 while (strchr(szCmdLine, '\"'))
265 remove_first_occurence_of_character("\"", szCmdLine);
266 if (*pszChar == ' ') { //test at every space for the end of the filename
267 *pszChar = '\0';
268 ret = DosQueryAppType(szCmdLine, &ulAppType);
269 if (!ret) {
270 strcat(szCmdLine, PCSZ_DOTEXE);
271 break;
272 }
273 else {
274 strcat(szCmdLine, PCSZ_DOTCOM);
275 ret = DosQueryAppType(szCmdLine, &ulAppType);
276 if (ret) {
277 offset = strrchr(szCmdLine, '.' );
278 *offset = 0;
279 strcat(szCmdLine, PCSZ_DOTCMD);
280 FullPath = searchapath(PCSZ_PATH, szCmdLine);
281 if (*FullPath) {
282 ret = 0;
283 break;
284 }
285 else {
286 *offset = 0;
287 strcat(szCmdLine, PCSZ_DOTBAT);
288 FullPath = searchapath(PCSZ_PATH, szCmdLine);
289 if (*FullPath) {
290 ret = 0;
291 break;
292 }
293 else {
294 *offset = 0;
295 strcat(szCmdLine, PCSZ_DOTBTM);
296 FullPath = searchapath(PCSZ_PATH, szCmdLine);
297 if (*FullPath) {
298 ret = 0;
299 break;
300 }
301 }
302 }
303 }
304 else
305 break;
306 }
307 }
308 strcpy(szCmdLine, pszCmdLine_);
309 pszChar++;
310 }
311 }
312 if (!ret){
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);
327 }
328 else { // fail if no extension can be found runemf2 requires one
329 ret = saymsg(MB_OK,
330 HWND_DESKTOP,
331 NullStr,
332 GetPString(IDS_PROGRAMNOTEXE2TEXT),
333 pszCmdLine_);
334 fCancelAction = TRUE;
335 pszNewCmdLine = pszCmdLine_;
336 }
337 }
338 else { // file has a nonstandard extension for executible
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_);
356 FullPath = searchapath(PCSZ_PATH, szCmdLine);
357 BldQuotedFileName(pszNewCmdLine, szCmdLine);
358 if (!*FullPath) {
359 ret = saymsg(MB_YESNO,
360 HWND_DESKTOP,
361 NullStr,
362 GetPString(IDS_PROGRAMNOTFOUNDTEXT),
363 pszCmdLine_);
364 if (ret == MBID_YES) {
365 if (szArgs[0] != ' ')
366 strcat(pszNewCmdLine, " ");
367 strcat(pszNewCmdLine, szArgs);
368 }
369 else {
370 fCancelAction = TRUE;
371 pszWorkBuf = pszCmdLine_;
372 }
373 }
374 else {
375 ret = saymsg(MB_YESNOCANCEL,
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 }
389 }
390 }
391 }
392 free(szArgs);
393 free(szCmdLine);
394 return pszWorkBuf;
395}
396
397#pragma alloc_text(PATHUTIL,BldFullPathName)
398#pragma alloc_text(PATHUTIL,BldQuotedFileName)
399#pragma alloc_text(PATHUTIL,BldQuotedFullPathName)
400#pragma alloc_text(PATHUTIL,NormalizeCmdLine)
Note: See TracBrowser for help on using the repository browser.