source: trunk/dll/valid.c@ 1354

Last change on this file since 1354 was 1354, checked in by Gregg Young, 17 years ago

Added driveflags to over ride write verify for USB removable drives that fail when it is on (Ticket 323); A flag to prevent directory name from being broadcast to drives in the tree cnr prior to a recursive scan of the drive (causes dbl directory names Ticket 321) Add option for multithreaded recursive scan of user selected drives at startup (Ticket 322).

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