source: trunk/dll/valid.c@ 1214

Last change on this file since 1214 was 1214, checked in by John Small, 17 years ago

Ticket 187: Move data declarations/definitions out of fm3dll.h

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 24.8 KB
Line 
1
2/***********************************************************************
3
4 $Id: valid.c 1214 2008-09-13 06:53:34Z jbs $
5
6 File name manipulation routines
7
8 Copyright (c) 1993, 1998 M. Kimes
9 Copyright (c) 2002, 2007 Steven H.Levine
10
11 23 Nov 02 SHL RootName: rework for sanity
12 27 Nov 02 SHL MakeFullName: correct typo
13 11 Jun 03 SHL Add JFS and FAT32 support
14 15 Jun 04 SHL Implement Jim Read's removable logic
15 31 Jul 04 SHL Comments
16 01 Aug 04 SHL Rework lstrip/rstrip usage
17 03 Jun 05 SHL Drop CD_DEBUG logic
18 28 Nov 05 SHL MakeValidDir: correct DosQuerySysInfo args
19 22 Jul 06 SHL Use Runtime_Error
20 22 Oct 06 GKY Add NDFS32 support
21 22 Oct 06 GKY Increased BUFFER_BYTES in CheckDrive to 8192 to fix NDFS32 scan failure
22 07 Jan 07 GKY Move error strings etc. to string file
23 18 Feb 07 GKY Add more drive types and icons
24 16 Jun 07 SHL Update for OpenWatcom
25 20 Aug 07 GKY Move #pragma alloc_text to end for OpenWatcom compat
26 30 Dec 07 GKY Change TestDates to TestFDates can compare by filename or FDATE/FTIME data
27 30 Dec 07 GKY Add TestCDates to compare CNRITEMs by CDATE/CTIME data
28 19 Jul 08 GKY Replace save_dir2(dir) with pFM2SaveDirectory
29
30***********************************************************************/
31
32#include <string.h>
33#include <ctype.h>
34
35#define INCL_DOS
36#define INCL_WIN
37#define INCL_DOSDEVIOCTL // DosDevIOCtl
38#define INCL_LONGLONG
39
40#include "fm3dll.h"
41#include "treecnr.h" // Data declaration(s)
42#include "info.h" // Data declaration(s)
43#include "notebook.h" // Data declaration(s)
44#include "fm3str.h"
45#include "errutil.h" // Dos_Error...
46#include "strutil.h" // GetPString
47#include "valid.h"
48#include "dirs.h" // save_dir2
49#include "strips.h" // bstrip
50#include "init.h" // GetTidForWindow
51
52
53//static BOOL IsDesktop(HAB hab, HWND hwnd);
54//static BOOL IsFileSame(CHAR * filename1, CHAR * filename2);
55//static char *IsVowel(char a);
56
57// Data definitions
58static PSZ pszSrcFile = __FILE__;
59
60#pragma data_seg(GLOBAL2)
61CHAR *CDFS;
62CHAR *FAT32;
63CHAR *HPFS;
64CHAR *HPFS386;
65CHAR *ISOFS;
66CHAR *JFS;
67CHAR *NDFS32;
68CHAR *NTFS;
69CHAR *RAMFS;
70
71APIRET MakeFullName(char *pszFileName)
72{
73 /* pszFileName must be CCHMAXPATH long minimum! */
74
75 char szPathName[CCHMAXPATH];
76 APIRET rc;
77
78 DosError(FERR_DISABLEHARDERR);
79 rc = DosQueryPathInfo(pszFileName,
80 FIL_QUERYFULLNAME, szPathName, sizeof(szPathName));
81 if (!rc)
82 strcpy(pszFileName, szPathName); // Pass back actual name
83 return rc;
84}
85
86char *RootName(char *filename)
87{
88 char *p = NULL, *pp;
89
90 // Return filename, strip path parts
91 // Return empty string when filename ends with backslash
92
93 if (filename) {
94 p = strrchr(filename, '\\');
95 pp = strrchr(filename, '/');
96 p = (p) ? (pp) ? (p > pp) ? p : pp : p : pp;
97 }
98 if (!p) /* name is itself a root */
99 p = filename;
100 else /* skip past backslash */
101 p++;
102 return p;
103}
104
105 /** TestFDate
106 * return 1 (file2 newer than file1),
107 * 0 (files same)
108 * or -1 (file1 newer than file2)
109 * Make the FILSTATUS pointers NULL if passing file names
110 * if the FILESTATUS information is already available it can be passed instead
111 * Make the files NULL if passing FILESTATUS buffers
112 */
113
114int TestFDates(char *file1, char *file2, FDATE *datevar1, FTIME *timevar1,
115 FDATE *datevar2, FTIME *timevar2)
116{
117 int comp = 0;
118 FILESTATUS3 fs3o, fs3n;
119
120 if (file1){
121 DosError(FERR_DISABLEHARDERR);
122 DosQueryPathInfo(file1, FIL_STANDARD, &fs3o, sizeof(fs3o));
123 datevar1 = &fs3o.fdateLastWrite;
124 timevar1 = &fs3o.ftimeLastWrite;
125 }
126 if (file2) {
127 DosError(FERR_DISABLEHARDERR);
128 DosQueryPathInfo(file2, FIL_STANDARD, &fs3n, sizeof(fs3n));
129 datevar2 = &fs3n.fdateLastWrite;
130 timevar2 = &fs3n.ftimeLastWrite;
131 }
132 if (&datevar1 && &datevar2 && &timevar1 && &timevar2) {
133 comp = (datevar2->year >
134 datevar1->year) ? 1 :
135 (datevar2->year <
136 datevar1->year) ? -1 :
137 (datevar2->month >
138 datevar1->month) ? 1 :
139 (datevar2->month <
140 datevar1->month) ? -1 :
141 (datevar2->day >
142 datevar1->day) ? 1 :
143 (datevar2->day <
144 datevar1->day) ? -1 :
145 (timevar2->hours >
146 timevar1->hours) ? 1 :
147 (timevar2->hours <
148 timevar1->hours) ? -1 :
149 (timevar2->minutes >
150 timevar1->minutes) ? 1 :
151 (timevar2->minutes <
152 timevar1->minutes) ? -1 :
153 (timevar2->twosecs >
154 timevar1->twosecs) ? 1 :
155 (timevar2->twosecs < timevar1->twosecs) ? -1 : 0;
156 }
157 return comp;
158}
159
160 /** TestCDate
161 * return 1 (file2 newer than file1),
162 * 0 (files same)
163 * or -1 (file1 newer than file2)
164 */
165
166int TestCDates(CDATE *datevar1, CTIME *timevar1,
167 CDATE *datevar2, CTIME *timevar2)
168{
169 int comp = 0;
170
171 if (&datevar1 && &datevar2 && &timevar1 && &timevar2) {
172 comp = (datevar2->year >
173 datevar1->year) ? 1 :
174 (datevar2->year <
175 datevar1->year) ? -1 :
176 (datevar2->month >
177 datevar1->month) ? 1 :
178 (datevar2->month <
179 datevar1->month) ? -1 :
180 (datevar2->day >
181 datevar1->day) ? 1 :
182 (datevar2->day <
183 datevar1->day) ? -1 :
184 (timevar2->hours >
185 timevar1->hours) ? 1 :
186 (timevar2->hours <
187 timevar1->hours) ? -1 :
188 (timevar2->minutes >
189 timevar1->minutes) ? 1 :
190 (timevar2->minutes <
191 timevar1->minutes) ? -1 :
192 (timevar2->seconds >
193 timevar1->seconds) ? 1 :
194 (timevar2->seconds < timevar1->seconds) ? -1 : 0;
195 }
196 return comp;
197}
198
199BOOL IsNewer(char *file1, char *file2)
200{
201 /* return TRUE if file2 is newer than file1 */
202
203 return (TestFDates(file1, file2, NULL, NULL, NULL, NULL) > 0);
204}
205
206#if 0 // JBS 11 Sep 08
207BOOL IsDesktop(HAB hab, HWND hwnd)
208{
209 HWND hwndDesktop;
210
211 if (hwnd == HWND_DESKTOP)
212 return TRUE;
213 hwndDesktop = WinQueryDesktopWindow(hab, NULLHANDLE);
214 if (hwnd == hwndDesktop)
215 return TRUE;
216 return FALSE;
217}
218#endif
219
220BOOL ParentIsDesktop(HWND hwnd, HWND hwndParent)
221{
222 HWND hwndDesktop;
223 BOOL ret = FALSE;
224
225 if (!hwndParent)
226 hwndParent = WinQueryWindow(hwnd, QW_PARENT);
227 if (hwndParent == HWND_DESKTOP)
228 ret = TRUE;
229 else {
230 hwndDesktop = WinQueryDesktopWindow(WinQueryAnchorBlock(hwnd), (HWND) 0);
231 if (hwndDesktop == hwndParent)
232 ret = TRUE;
233 }
234 return ret;
235}
236
237/** CheckDrive
238 * @param chDrive drive letter
239 * @param pszFileSystem pointer to buffer to return file system type or NULL
240 * @param pulType pointer to long word to return drive flags or NULL
241 * @returns removability flag, 1 = removable, 0 = not removable, -1 = error
242 */
243
244INT CheckDrive(CHAR chDrive, CHAR * pszFileSystem, ULONG * pulType)
245{
246 CHAR szPath[3];
247 VOID *pvBuffer = NULL;
248 CHAR *pfsn;
249 CHAR *pfsd;
250 ULONG clBufferSize;
251 APIRET rc;
252 ULONG ulAction;
253 ULONG clParmBytes;
254 ULONG clDataBytes;
255 HFILE hDev;
256
257# pragma pack(1)
258 struct
259 {
260 BYTE Cmd;
261 BYTE Unit;
262 }
263 parmPkt =
264 {
265 0, 0};
266# define BPB_REMOVABLE_MEDIA 0x08 // 3 - Media is removable
267 struct
268 {
269 BIOSPARAMETERBLOCK bpb;
270 USHORT cCylinders; // Documented but not implemented
271 BYTE bDeviceType; // Documented but not implemented
272 USHORT fsDeviceAttr; // Documented but not implemented
273 }
274 dataPkt;
275
276# pragma pack()
277 BYTE NonRemovable;
278 PFSQBUFFER2 pfsq;
279
280 if (pszFileSystem)
281 *pszFileSystem = 0;
282
283 if (pulType)
284 *pulType = 0;
285
286# define BUFFER_BYTES 8192
287 rc = DosAllocMem(&pvBuffer, BUFFER_BYTES,
288 PAG_COMMIT | OBJ_TILE | PAG_READ | PAG_WRITE);
289 if (rc) {
290 Dos_Error(MB_CANCEL, rc, HWND_DESKTOP, pszSrcFile, __LINE__,
291 GetPString(IDS_OUTOFMEMORY));
292 return -1; // Say failed
293 }
294
295 szPath[0] = chDrive;
296 szPath[1] = ':';
297 szPath[2] = 0;
298 clBufferSize = BUFFER_BYTES;
299 DosError(FERR_DISABLEHARDERR);
300 rc = DosQueryFSAttach(szPath, 0, FSAIL_QUERYNAME,
301 (PFSQBUFFER2) pvBuffer, &clBufferSize);
302 if (rc) {
303 /* can't get any info at all */
304 DosFreeMem(pvBuffer);
305 DosError(FERR_DISABLEHARDERR);
306 return -1; // Say failed
307 }
308
309 pfsq = (PFSQBUFFER2) pvBuffer;
310 pfsn = (PCHAR)(pfsq->szName) + pfsq->cbName + 1;
311 pfsd = pfsn + pfsq->cbFSDName + 1;
312
313 if (pszFileSystem) {
314 strncpy(pszFileSystem, pfsn, CCHMAXPATH);
315 pszFileSystem[CCHMAXPATH - 1] = 0;
316 }
317
318 if (pulType && (!strcmp(pfsn, CDFS) || !strcmp(pfsn, ISOFS)))
319 *pulType |= DRIVE_NOTWRITEABLE | DRIVE_CDROM | DRIVE_REMOVABLE;
320 if (pulType && !strcmp(pfsn, NTFS))
321 *pulType |= DRIVE_NOTWRITEABLE;
322 if (pulType && !strcmp(pfsn, NDFS32)){
323 *pulType |= DRIVE_VIRTUAL;
324 }
325 if (pulType && !strcmp(pfsn, RAMFS)){
326 *pulType |= DRIVE_RAMDISK;
327 }
328 if (((PFSQBUFFER2) pvBuffer)->iType == FSAT_REMOTEDRV &&
329 (strcmp(pfsn, CDFS) || strcmp(pfsn, ISOFS))) {
330 if (pulType)
331 *pulType |= DRIVE_REMOTE;
332
333 if (pulType && !strcmp(pfsn, CBSIFS)) {
334 *pulType |= DRIVE_ZIPSTREAM;
335 *pulType &= ~DRIVE_REMOTE;
336 *pulType |= DRIVE_NOLONGNAMES;
337 if (pfsq->cbFSAData) {
338 ULONG FType;
339
340 if (CheckDrive(*pfsd, NULL, &FType) != -1) {
341 if (FType & DRIVE_REMOVABLE)
342 *pulType |= DRIVE_REMOVABLE;
343 if (~FType & DRIVE_NOLONGNAMES)
344 *pulType &= ~DRIVE_NOLONGNAMES;
345 }
346
347 }
348 }
349 if (pulType &&
350 (!strcmp(pfsn, HPFS) ||
351 !strcmp(pfsn, JFS) ||
352 !strcmp(pfsn, FAT32) ||
353 !strcmp(pfsn, RAMFS) ||
354 !strcmp(pfsn, NDFS32) ||
355 !strcmp(pfsn, NTFS) ||
356 !strcmp(pfsn, HPFS386))) {
357 *pulType &= ~DRIVE_NOLONGNAMES;
358 }
359
360 DosFreeMem(pvBuffer);
361 return 0; // Remotes are non-removable
362 }
363
364 // Local drive
365 if (strcmp(pfsn, HPFS) &&
366 strcmp(pfsn, JFS) &&
367 strcmp(pfsn, CDFS) &&
368 strcmp(pfsn, ISOFS) &&
369 strcmp(pfsn, RAMFS) &&
370 strcmp(pfsn, FAT32) &&
371 strcmp(pfsn, NDFS32) &&
372 strcmp(pfsn, NTFS) &&
373 strcmp(pfsn, HPFS386)) {
374 if (pulType)
375 (*pulType) |= DRIVE_NOLONGNAMES; // Others can not have long names
376 }
377
378
379 DosError(FERR_DISABLEHARDERR);
380 rc = DosOpen(szPath, &hDev, &ulAction, 0, 0, FILE_OPEN,
381 OPEN_ACCESS_READONLY | OPEN_SHARE_DENYNONE |
382 OPEN_FLAGS_DASD | OPEN_FLAGS_FAIL_ON_ERROR, 0);
383 if (rc) {
384 DosError(FERR_DISABLEHARDERR);
385 if (pulType)
386 *pulType |= DRIVE_REMOVABLE; // Assume removable if can not access
387 DosFreeMem(pvBuffer);
388 return 1; // Say removable
389 }
390
391 clParmBytes = sizeof(parmPkt.Cmd);
392 clDataBytes = sizeof(NonRemovable);
393 NonRemovable = 1; // Preset as non removable
394 DosError(FERR_DISABLEHARDERR);
395 rc = DosDevIOCtl(hDev, IOCTL_DISK, DSK_BLOCKREMOVABLE, &parmPkt.Cmd, /* Address of the command-specific argument list. */
396 sizeof(parmPkt.Cmd), /* Length, in bytes, of pParams. */
397 &clParmBytes, /* Pointer to the length of parameters. */
398 &NonRemovable, /* Address of the data area. */
399 sizeof(NonRemovable), /* Length, in bytes, of pData. */
400 &clDataBytes); /* Pointer to the length of data. */
401
402 if (!rc && NonRemovable) {
403 // Could be USB so check BPB flags
404 clParmBytes = sizeof(parmPkt.Cmd);
405 clDataBytes = sizeof(dataPkt);
406 memset(&dataPkt, 0xff, sizeof(dataPkt));
407 DosError(FERR_DISABLEHARDERR);
408 rc = DosDevIOCtl(hDev, IOCTL_DISK, DSK_GETDEVICEPARAMS, &parmPkt.Cmd, /* Address of the command-specific argument list. */
409 sizeof(parmPkt.Cmd), /* Length, in bytes, of pParams. */
410 &clParmBytes, /* Pointer to the length of parameters. */
411 &dataPkt, /* Address of the data area. */
412 sizeof(dataPkt), /* Length, in bytes, of pData. */
413 &clDataBytes); /* Pointer to the length of data. */
414
415 if (!rc && (dataPkt.bpb.fsDeviceAttr & BPB_REMOVABLE_MEDIA))
416 NonRemovable = 0;
417 }
418
419 DosClose(hDev);
420
421 if (!NonRemovable && pulType)
422 *pulType |= DRIVE_REMOVABLE;
423
424 DosFreeMem(pvBuffer);
425
426 return NonRemovable ? 0 : 1;
427}
428
429#if 0 // JBS 11 Sep 08
430BOOL IsFileSame(CHAR * filename1, CHAR * filename2)
431{
432 /* returns: -1 (error), 0 (is a directory), or 1 (is a file) */
433
434 FILESTATUS3L fsa1, fsa2;
435 APIRET ret;
436
437 if (filename1 && filename2) {
438 DosError(FERR_DISABLEHARDERR);
439 ret = DosQueryPathInfo(filename1, FIL_STANDARDL, &fsa1,
440 (ULONG) sizeof(fsa1));
441 if (!ret) {
442 DosError(FERR_DISABLEHARDERR);
443 ret = DosQueryPathInfo(filename2, FIL_STANDARDL, &fsa2,
444 (ULONG) sizeof(fsa2));
445 if (!ret) {
446 if (fsa1.cbFile == fsa2.cbFile &&
447 (fsa1.attrFile & (~FILE_ARCHIVED)) ==
448 (fsa2.attrFile & (~FILE_ARCHIVED)))
449 return TRUE;
450 }
451 }
452 }
453 return FALSE;
454}
455#endif
456
457INT IsFile(CHAR * filename)
458{
459 /* returns: -1 (error), 0 (is a directory), or 1 (is a file) */
460
461 FILESTATUS3 fsa;
462 APIRET ret;
463
464 if (filename && *filename) {
465 DosError(FERR_DISABLEHARDERR);
466 ret = DosQueryPathInfo(filename, FIL_STANDARD, &fsa, (ULONG) sizeof(fsa));
467 if (!ret)
468 return ((fsa.attrFile & FILE_DIRECTORY) == 0);
469 else if (IsValidDrive(*filename) && IsRoot(filename))
470 return 0;
471 }
472 return -1; /* error; doesn't exist or can't read or null filename */
473}
474
475BOOL IsFullName(CHAR * filename)
476{
477 return (filename) ?
478 (isalpha(*filename) && filename[1] == ':' && filename[2] == '\\') : 0;
479}
480
481BOOL IsRoot(CHAR * filename)
482{
483 return (filename && isalpha(*filename) && filename[1] == ':' &&
484 filename[2] == '\\' && !filename[3]);
485}
486
487BOOL IsValidDir(CHAR * path)
488{
489 CHAR fullname[CCHMAXPATH];
490 FILESTATUS3 fs;
491
492 if (path) {
493 DosError(FERR_DISABLEHARDERR);
494 if (!DosQueryPathInfo(path,
495 FIL_QUERYFULLNAME, fullname, sizeof(fullname))) {
496 if (IsValidDrive(*fullname)) {
497 if (!IsRoot(fullname)) {
498 DosError(FERR_DISABLEHARDERR);
499 if (!DosQueryPathInfo(fullname,
500 FIL_STANDARD,
501 &fs,
502 sizeof(fs)) && (fs.attrFile & FILE_DIRECTORY))
503 return TRUE;
504 }
505 else
506 return TRUE;
507 }
508 }
509 }
510 return FALSE;
511}
512
513BOOL IsValidDrive(CHAR drive)
514{
515 CHAR Path[] = " :", Buffer[256];
516 APIRET Status;
517 ULONG Size;
518 ULONG ulDriveNum, ulDriveMap;
519
520 if (!isalpha(drive) ||
521 (driveflags[toupper(drive) - 'A'] & (DRIVE_IGNORE | DRIVE_INVALID)))
522 return FALSE;
523 DosError(FERR_DISABLEHARDERR);
524 Status = DosQCurDisk(&ulDriveNum, &ulDriveMap);
525 if (!Status) {
526 if (!(ulDriveMap & (1 << (ULONG) (toupper(drive) - 'A'))))
527 return FALSE;
528 Path[0] = toupper(drive);
529 Size = sizeof(Buffer);
530 DosError(FERR_DISABLEHARDERR);
531 Status = DosQueryFSAttach(Path,
532 0,
533 FSAIL_QUERYNAME, (PFSQBUFFER2) Buffer, &Size);
534 }
535 return (Status == 0);
536}
537
538//=== MakeValidDir() build valid directory name ===
539
540CHAR *MakeValidDir(CHAR * path)
541{
542 ULONG ulDrv;
543 CHAR *p;
544 FILESTATUS3 fs;
545 APIRET rc;
546
547 if (!MakeFullName(path)) {
548 if (IsValidDrive(*path)) {
549 // Passed name is valid - trim to directory
550 for (;;) {
551 if (IsRoot(path))
552 return path;
553 DosError(FERR_DISABLEHARDERR);
554 rc = DosQueryPathInfo(path, FIL_STANDARD, &fs, sizeof(fs));
555 if (!rc && (fs.attrFile & FILE_DIRECTORY))
556 return path;
557 p = strrchr(path, '\\');
558 if (p) {
559 if (p < path + 3)
560 p++;
561 *p = 0;
562 }
563 else
564 break;
565 }
566 }
567 }
568 // Fall back to boot drive
569 DosError(FERR_DISABLEHARDERR);
570 if (!DosQuerySysInfo(QSV_BOOT_DRIVE, QSV_BOOT_DRIVE, &ulDrv, sizeof(ulDrv))) {
571 ulDrv += '@';
572 if (ulDrv < 'C')
573 ulDrv = 'C';
574 strcpy(path, " :\\");
575 *path = (CHAR) ulDrv;
576 }
577 else
578 strcpy(path, pFM2SaveDirectory); // Fall back to fm3.ini drive or current dir - should never occur
579 return path;
580}
581
582BOOL IsExecutable(CHAR * filename)
583{
584 register CHAR *p;
585 APIRET ret;
586 ULONG apptype;
587
588 if (filename) {
589 DosError(FERR_DISABLEHARDERR);
590 p = strrchr(filename, '.');
591 if (p)
592 ret = DosQueryAppType(filename, &apptype);
593 else {
594
595 char fname[CCHMAXPATH + 2];
596
597 strcpy(fname, filename);
598 strcat(fname, ".");
599 ret = DosQueryAppType(fname, &apptype);
600 }
601 if ((!ret && (!apptype ||
602 (apptype &
603 (FAPPTYP_NOTWINDOWCOMPAT |
604 FAPPTYP_WINDOWCOMPAT |
605 FAPPTYP_WINDOWAPI |
606 FAPPTYP_BOUND |
607 FAPPTYP_DOS |
608 FAPPTYP_WINDOWSREAL |
609 FAPPTYP_WINDOWSPROT |
610 FAPPTYP_32BIT |
611 0x1000)))) ||
612 (p && (!stricmp(p, ".CMD") || !stricmp(p, ".BAT"))))
613 return TRUE;
614 }
615 return FALSE;
616}
617
618VOID ArgDriveFlags(INT argc, CHAR ** argv)
619{
620 INT x;
621
622 for (x = 1; x < argc; x++) {
623 if (*argv[x] == '/' && isalpha(argv[x][1])) {
624
625 CHAR *p = &argv[x][1];
626
627 while (isalpha(*p)) {
628 driveflags[toupper(*p) - 'A'] |= DRIVE_IGNORE;
629 p++;
630 }
631 }
632 else if (*argv[x] == ';' && isalpha(argv[x][1])) {
633
634 CHAR *p = &argv[x][1];
635
636 while (isalpha(*p)) {
637 driveflags[toupper(*p) - 'A'] |= DRIVE_NOPRESCAN;
638 p++;
639 }
640 }
641 else if (*argv[x] == '`' && isalpha(argv[x][1])) {
642
643 CHAR *p = &argv[x][1];
644
645 while (isalpha(*p)) {
646 driveflags[toupper(*p) - 'A'] |= DRIVE_NOSTATS;
647 p++;
648 }
649 }
650 else if (*argv[x] == ',' && isalpha(argv[x][1])) {
651
652 CHAR *p = &argv[x][1];
653
654 while (isalpha(*p)) {
655 driveflags[toupper(*p) - 'A'] |= DRIVE_NOLOADICONS;
656 p++;
657 }
658 }
659 else if (*argv[x] == '-' && isalpha(argv[x][1])) {
660
661 CHAR *p = &argv[x][1];
662
663 while (isalpha(*p)) {
664 driveflags[toupper(*p) - 'A'] |= DRIVE_NOLOADSUBJS;
665 p++;
666 }
667 }
668 else if (*argv[x] == '\'' && isalpha(argv[x][1])) {
669
670 CHAR *p = &argv[x][1];
671
672 while (isalpha(*p)) {
673 driveflags[toupper(*p) - 'A'] |= DRIVE_NOLOADLONGS;
674 p++;
675 }
676 }
677 }
678}
679
680VOID DriveFlagsOne(INT x)
681{
682 INT removable;
683 CHAR szDrive[] = " :\\", FileSystem[CCHMAXPATH];
684 ULONG drvtype;
685
686 *szDrive = (CHAR) (x + 'A');
687 *FileSystem = 0;
688 drvtype = 0;
689 removable = CheckDrive(*szDrive, FileSystem, &drvtype);
690 driveserial[x] = -1;
691 driveflags[x] &= (DRIVE_IGNORE | DRIVE_NOPRESCAN | DRIVE_NOLOADICONS |
692 DRIVE_NOLOADSUBJS | DRIVE_NOLOADLONGS |
693 DRIVE_INCLUDEFILES | DRIVE_SLOW | DRIVE_NOSTATS);
694 if (removable != -1) {
695 struct
696 {
697 ULONG serial;
698 CHAR volumelength;
699 CHAR volumelabel[CCHMAXPATH];
700 }
701 volser;
702
703 DosError(FERR_DISABLEHARDERR);
704 if (!DosQueryFSInfo((ULONG) x + 1, FSIL_VOLSER, &volser, sizeof(volser)))
705 driveserial[x] = volser.serial;
706 else
707 DosError(FERR_DISABLEHARDERR);
708 }
709 else
710 driveflags[x] |= DRIVE_INVALID;
711 driveflags[x] |= ((removable == -1 || removable == 1) ?
712 DRIVE_REMOVABLE : 0);
713 if (drvtype & DRIVE_REMOTE)
714 driveflags[x] |= DRIVE_REMOTE;
715 if(!stricmp(FileSystem,NDFS32)){
716 driveflags[x] |= DRIVE_VIRTUAL;
717 driveflags[x] &= (~DRIVE_REMOTE);
718 }
719 if(!stricmp(FileSystem,RAMFS)){
720 driveflags[x] |= DRIVE_RAMDISK;
721 driveflags[x] &= (~DRIVE_REMOTE);
722 }
723 if(!stricmp(FileSystem,NTFS))
724 driveflags[x] |= DRIVE_NOTWRITEABLE;
725 if (strcmp(FileSystem, HPFS) &&
726 strcmp(FileSystem, JFS) &&
727 strcmp(FileSystem, CDFS) &&
728 strcmp(FileSystem, ISOFS) &&
729 strcmp(FileSystem, RAMFS) &&
730 strcmp(FileSystem, FAT32) &&
731 strcmp(FileSystem, NTFS) &&
732 strcmp(FileSystem, NDFS32) &&
733 strcmp(FileSystem, HPFS386)) {
734 driveflags[x] |= DRIVE_NOLONGNAMES;
735 }
736
737 if (!strcmp(FileSystem, CDFS) || !strcmp(FileSystem, ISOFS)) {
738 removable = 1;
739 driveflags[x] |= (DRIVE_REMOVABLE | DRIVE_NOTWRITEABLE | DRIVE_CDROM);
740 }
741 else if (!stricmp(FileSystem, CBSIFS)) {
742 driveflags[x] |= DRIVE_ZIPSTREAM;
743 driveflags[x] &= (~DRIVE_REMOTE);
744 if (drvtype & DRIVE_REMOVABLE)
745 driveflags[x] |= DRIVE_REMOVABLE;
746 if (!(drvtype & DRIVE_NOLONGNAMES))
747 driveflags[x] &= (~DRIVE_NOLONGNAMES);
748 }
749}
750
751VOID FillInDriveFlags(VOID * dummy)
752{
753 ULONG ulDriveNum, ulDriveMap;
754 register INT x;
755
756 for (x = 0; x < 26; x++)
757 driveflags[x] &= (DRIVE_IGNORE | DRIVE_NOPRESCAN | DRIVE_NOLOADICONS |
758 DRIVE_NOLOADSUBJS | DRIVE_NOLOADLONGS |
759 DRIVE_INCLUDEFILES | DRIVE_SLOW | DRIVE_NOSTATS);
760 memset(driveserial, -1, sizeof(driveserial));
761 DosError(FERR_DISABLEHARDERR);
762 DosQCurDisk(&ulDriveNum, &ulDriveMap);
763 for (x = 0; x < 26; x++) {
764 if (ulDriveMap & (1 << x) && !(driveflags[x] & DRIVE_IGNORE)) {
765 {
766 CHAR s[80];
767 ULONG flags = 0, size = sizeof(ULONG);
768
769 sprintf(s, "%c.DriveFlags", (CHAR) (x + 'A'));
770 if (PrfQueryProfileData(fmprof, appname, s, &flags, &size) &&
771 size == sizeof(ULONG))
772 driveflags[x] |= flags;
773 }
774
775 if (x > 1) {
776 if (!(driveflags[x] & DRIVE_NOPRESCAN))
777 DriveFlagsOne(x);
778 else
779 driveserial[x] = -1;
780 }
781 else {
782 driveflags[x] |= (DRIVE_REMOVABLE | DRIVE_NOLONGNAMES);
783 driveserial[x] = -1;
784 }
785 }
786 else if (!(ulDriveMap & (1 << x)))
787 driveflags[x] |= DRIVE_INVALID;
788 }
789 {
790 ULONG startdrive = 3L;
791
792 DosError(FERR_DISABLEHARDERR);
793 DosQuerySysInfo(QSV_BOOT_DRIVE, QSV_BOOT_DRIVE,
794 (PVOID) & startdrive, (ULONG) sizeof(ULONG));
795 if (startdrive)
796 driveflags[startdrive - 1] |= DRIVE_BOOT;
797 }
798}
799
800CHAR *assign_ignores(CHAR * s)
801{
802 register INT x;
803 register CHAR *p, *pp;
804
805 *s = '/';
806 s[1] = 0;
807 p = s + 1;
808 if (s) {
809 for (x = 0; x < 26; x++) {
810 if ((driveflags[x] & DRIVE_IGNORE) != 0) {
811 *p = (CHAR) x + 'A';
812 p++;
813 *p = 0;
814 }
815 }
816 }
817 if (!s[1]) {
818 *s = 0;
819 pp = s;
820 }
821 else {
822 pp = &s[strlen(s)];
823 *pp = ' ';
824 pp++;
825 }
826 *pp = ';';
827 pp[1] = 0;
828 p = pp + 1;
829 if (pp) {
830 for (x = 0; x < 26; x++) {
831 if ((driveflags[x] & DRIVE_NOPRESCAN) != 0) {
832 *p = (CHAR) x + 'A';
833 p++;
834 *p = 0;
835 }
836 }
837 }
838 if (!pp[1])
839 *pp = 0;
840 pp = &s[strlen(s)];
841 *pp = ' ';
842 pp++;
843 *pp = ',';
844 pp[1] = 0;
845 p = pp + 1;
846 if (pp) {
847 for (x = 0; x < 26; x++) {
848 if ((driveflags[x] & DRIVE_NOLOADICONS) != 0) {
849 *p = (CHAR) x + 'A';
850 p++;
851 *p = 0;
852 }
853 }
854 }
855 if (!pp[1])
856 *pp = 0;
857 pp = &s[strlen(s)];
858 *pp = ' ';
859 pp++;
860 *pp = '-';
861 pp[1] = 0;
862 p = pp + 1;
863 if (pp) {
864 for (x = 0; x < 26; x++) {
865 if ((driveflags[x] & DRIVE_NOLOADSUBJS) != 0) {
866 *p = (CHAR) x + 'A';
867 p++;
868 *p = 0;
869 }
870 }
871 }
872 if (!pp[1])
873 *pp = 0;
874 pp = &s[strlen(s)];
875 *pp = ' ';
876 pp++;
877 *pp = '`';
878 pp[1] = 0;
879 p = pp + 1;
880 if (pp) {
881 for (x = 0; x < 26; x++) {
882 if ((driveflags[x] & DRIVE_NOSTATS) != 0) {
883 *p = (CHAR) x + 'A';
884 p++;
885 *p = 0;
886 }
887 }
888 }
889 if (!pp[1])
890 *pp = 0;
891 pp = &s[strlen(s)];
892 *pp = ' ';
893 pp++;
894 *pp = '\'';
895 pp[1] = 0;
896 p = pp + 1;
897 if (pp) {
898 for (x = 0; x < 26; x++) {
899 if ((driveflags[x] & DRIVE_NOLOADLONGS) != 0) {
900 *p = (CHAR) x + 'A';
901 p++;
902 *p = 0;
903 }
904 }
905 }
906 if (!pp[1])
907 *pp = 0;
908 bstrip(s);
909 return s;
910}
911
912BOOL needs_quoting(register CHAR * f)
913{
914 register CHAR *p = " &|<>";
915
916 while (*p) {
917 if (strchr(f, *p))
918 return TRUE;
919 p++;
920 }
921 return FALSE;
922}
923
924BOOL IsBinary(register CHAR * str, ULONG len)
925{
926 register ULONG x = 0;
927
928 if (str) {
929 while (x < len) {
930 if (str[x] < ' ' && str[x] != '\r' && str[x] != '\n' && str[x] != '\t'
931 && str[x] != '\x1b' && str[x] != '\x1a' && str[x] != '\07'
932 && str[x] != '\x0c')
933 return TRUE;
934 x++;
935 }
936 }
937 return FALSE;
938}
939
940BOOL TestBinary(CHAR * filename)
941{
942 HFILE handle;
943 ULONG ulAction;
944 ULONG len;
945 APIRET rc;
946 // CHAR buff[512];
947 CHAR buff[4096]; // 06 Oct 07 SHL protect against NTFS defect
948
949 if (filename) {
950 if (!DosOpen(filename, &handle, &ulAction, 0, 0,
951 OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS,
952 OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_NOINHERIT |
953 OPEN_FLAGS_SEQUENTIAL | OPEN_SHARE_DENYNONE |
954 OPEN_ACCESS_READONLY, 0)) {
955 len = 512;
956 rc = DosRead(handle, buff, len, &len);
957 DosClose(handle);
958 if (!rc && len)
959 return IsBinary(buff, len);
960 }
961 }
962 return FALSE;
963}
964
965#if 0 // JBS 11 Sep 08
966char *IsVowel(char a)
967{
968 return (strchr("aeiouAEIOU", a) != NULL) ? "n" : NullStr;
969}
970#endif
971
972VOID GetDesktopName(CHAR * objectpath, ULONG size)
973{
974 PFN WQDPath;
975 HMODULE hmod = 0;
976 APIRET rc;
977 ULONG startdrive = 3;
978 CHAR objerr[CCHMAXPATH];
979
980 if (!objectpath) {
981 Runtime_Error(pszSrcFile, __LINE__, "null pointer");
982 return;
983 }
984 *objectpath = 0;
985 if (OS2ver[0] > 20 || (OS2ver[0] == 20 && OS2ver[1] >= 30)) {
986 /*
987 * if running under warp, we can get the desktop name
988 * this way...
989 */
990 rc = DosLoadModule(objerr, sizeof(objerr), "PMWP", &hmod);
991 if (!rc) {
992 rc = DosQueryProcAddr(hmod, 262, NULL, &WQDPath);
993 if (!rc)
994 WQDPath(objectpath, size);
995 DosFreeModule(hmod);
996 }
997 }
998 if (!*objectpath) {
999 // Fall back to INI content
1000 if (!PrfQueryProfileString(HINI_SYSTEMPROFILE,
1001 "FolderWorkareaRunningObjects",
1002 NULL,
1003 "\0",
1004 (PVOID) objectpath, sizeof(objectpath))) {
1005 Win_Error(HWND_DESKTOP, HWND_DESKTOP, pszSrcFile, __LINE__,
1006 "PrfQueryProfileString");
1007 *objectpath = 0;
1008 }
1009 else if (!*objectpath || IsFile(objectpath)) {
1010 Runtime_Error(pszSrcFile, __LINE__, "bad FolderWorkareaRunningObjects");
1011 *objectpath = 0;
1012 }
1013 if (!*objectpath) {
1014 // Fall back
1015 DosError(FERR_DISABLEHARDERR);
1016 DosQuerySysInfo(QSV_BOOT_DRIVE, QSV_BOOT_DRIVE,
1017 (PVOID) & startdrive, (ULONG) sizeof(ULONG));
1018 sprintf(objectpath, GetPString(IDS_PATHTODESKTOP), ((CHAR) startdrive) + '@');
1019 }
1020 }
1021}
1022
1023#pragma alloc_text(VALID,CheckDrive,IsRoot,IsFile,IsFullName,needsquoting)
1024#pragma alloc_text(VALID,IsValidDir,IsValidDrive,MakeValidDir,IsVowel)
1025#pragma alloc_text(VALID,IsFileSame,IsNewer,TestFDates,TestCDates,RootName,MakeFullName)
1026#pragma alloc_text(VALID,IsExecutable,IsBinary,IsDesktop,ParentIsDesktop)
1027#pragma alloc_text(FILLFLAGS,FillInDriveFlags,assign_ignores)
1028#pragma alloc_text(FILLFLAGS,ArgDriveFlags,DriveFlagsOne)
1029#pragma alloc_text(FINDDESK,GetDesktopName)
Note: See TracBrowser for help on using the repository browser.