source: trunk/dll/valid.c@ 1036

Last change on this file since 1036 was 946, checked in by Gregg Young, 18 years ago

Minor code cleanup and documentation for some changes. (Tickets 3, 7, 184)

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