source: trunk/dll/valid.c@ 1162

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

Ticket 187: Draft 1: Functions only

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