source: trunk/dll/valid.c

Last change on this file was 1903, checked in by Gregg Young, 15 months ago

Allow no prescan drives to determine their type and file format at startup

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