source: trunk/dll/valid.c@ 1104

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

Replace save_dir2(dir) with strcpy(dir, pFM2SaveDirectory)

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