source: trunk/dll/valid.c@ 1372

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

Prevent IsExecutable from identifying dlls as executable. Work around DosQueryAppType identifying text files whos first to characters are NE as executable. Use fProtectOnly to prevent execution of Dos/Win programs. Tickets 330, 325, 332

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