source: trunk/dll/valid.c@ 1375

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

Updated history; comments minor code cleanup for recent changes

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