source: trunk/dll/valid.c@ 1187

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

Ticket 187: Draft 2: Move remaining function declarations

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