source: trunk/dll/valid.c@ 1387

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

Comments and cleanup for CS 1386

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