source: trunk/dll/valid.c@ 1844

Last change on this file since 1844 was 1749, checked in by John Small, 12 years ago

Ticket #522: Ensure use of wrapper functions where needed

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 28.7 KB
Line 
1
2/***********************************************************************
3
4 $Id: valid.c 1749 2014-02-28 16:46:26Z jbs $
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 //DbgMsg(pszSrcFile, __LINE__, "%i %i %s %s", easize.cbMaxEASize, easize.cbMaxEAListSize, szPath, pfsn);
342 szPath[2] = 0;
343 if (pulType && easize.cbMaxEASize == 0)
344 *pulType |= DRIVE_NOEASUPPORT;
345 if (pulType && (!strcmp(pfsn, CDFS) || !strcmp(pfsn, ISOFS)))
346 *pulType |= DRIVE_NOTWRITEABLE | DRIVE_CDROM | DRIVE_REMOVABLE;
347 if (pulType && !strcmp(pfsn, NTFS))
348 *pulType |= DRIVE_NOTWRITEABLE;
349 if (pulType && !strcmp(pfsn, NDFS32)){
350 *pulType |= DRIVE_VIRTUAL;
351 }
352 if (pulType && !strcmp(pfsn, RAMFS)){
353 *pulType |= DRIVE_RAMDISK;
354 }
355 if (((PFSQBUFFER2) pvBuffer)->iType == FSAT_REMOTEDRV) {
356 if (pulType)
357 *pulType |= DRIVE_REMOTE;
358
359 if (pulType && !strcmp(pfsn, CBSIFS)) {
360 *pulType |= DRIVE_ZIPSTREAM;
361 *pulType &= ~DRIVE_REMOTE;
362 *pulType |= DRIVE_NOLONGNAMES;
363 if (pfsq->cbFSAData) {
364 ULONG FType;
365
366 if (CheckDrive(*pfsd, NULL, &FType) != -1) {
367 if (FType & DRIVE_REMOVABLE)
368 *pulType |= DRIVE_REMOVABLE;
369 if (~FType & DRIVE_NOLONGNAMES)
370 *pulType &= ~DRIVE_NOLONGNAMES;
371 }
372
373 }
374 }
375 if (pulType &&
376 (!strcmp(pfsn, LAN) ||
377 !strcmp(pfsn, RAMFS) ||
378 !strcmp(pfsn, NDFS32))) {
379 *pulType &= ~DRIVE_NOLONGNAMES;
380 }
381
382 DosFreeMem(pvBuffer);
383 return 0; // Remotes are non-removable
384 }
385
386 // Local drive
387 if (strcmp(pfsn, HPFS) &&
388 strcmp(pfsn, CDFS) &&
389 strcmp(pfsn, ISOFS) &&
390 strcmp(pfsn, JFS) &&
391 strcmp(pfsn, FAT32) &&
392 strcmp(pfsn, NTFS) &&
393 strcmp(pfsn, HPFS386)) {
394 if (pulType)
395 (*pulType) |= DRIVE_NOLONGNAMES; // Others can not have long names
396 }
397
398 DosError(FERR_DISABLEHARDERR);
399 rc = DosOpen(szPath, &hDev, &ulAction, 0, 0, FILE_OPEN,
400 OPEN_ACCESS_READONLY | OPEN_SHARE_DENYNONE |
401 OPEN_FLAGS_DASD | OPEN_FLAGS_FAIL_ON_ERROR, 0);
402 if (rc) {
403 DosError(FERR_DISABLEHARDERR);
404 if (pulType)
405 *pulType |= DRIVE_REMOVABLE; // Assume removable if can not access
406 DosFreeMem(pvBuffer);
407 return 1; // Say removable
408 }
409
410 clParmBytes = sizeof(parmPkt.Cmd);
411 clDataBytes = sizeof(NonRemovable);
412 NonRemovable = 1; // Preset as non removable
413 DosError(FERR_DISABLEHARDERR);
414 rc = DosDevIOCtl(hDev, IOCTL_DISK, DSK_BLOCKREMOVABLE, &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 &NonRemovable, // Address of the data area.
418 sizeof(NonRemovable),// Length, in bytes, of pData.
419 &clDataBytes); // Pointer to the length of data.
420
421 if (!rc && NonRemovable) {
422 // Could be USB so check BPB flags
423 clParmBytes = sizeof(parmPkt.Cmd);
424 clDataBytes = sizeof(dataPkt);
425 memset(&dataPkt, 0xff, sizeof(dataPkt));
426 DosError(FERR_DISABLEHARDERR);
427 rc = DosDevIOCtl(hDev, IOCTL_DISK, DSK_GETDEVICEPARAMS, &parmPkt.Cmd,// Address of the command-specific argument list.
428 sizeof(parmPkt.Cmd), // Length, in bytes, of pParams.
429 &clParmBytes, // Pointer to the length of parameters.
430 &dataPkt, // Address of the data area.
431 sizeof(dataPkt), // Length, in bytes, of pData.
432 &clDataBytes); // Pointer to the length of data.
433
434 if (!rc && (dataPkt.bpb.fsDeviceAttr & BPB_REMOVABLE_MEDIA))
435 NonRemovable = 0;
436 }
437
438 DosClose(hDev);
439
440 if (!NonRemovable && pulType)
441 *pulType |= DRIVE_REMOVABLE;
442
443 DosFreeMem(pvBuffer);
444
445 return NonRemovable ? 0 : 1;
446}
447
448#if 0 // JBS 11 Sep 08
449BOOL IsFileSame(CHAR * filename1, CHAR * filename2)
450{
451 // returns: -1 (error), 0 (is a directory), or 1 (is a file)
452
453 FILESTATUS3L fsa1, fsa2;
454 APIRET ret;
455
456 if (filename1 && filename2) {
457 DosError(FERR_DISABLEHARDERR);
458 ret = DosQueryPathInfo(filename1, FIL_STANDARDL, &fsa1,
459 (ULONG) sizeof(fsa1));
460 if (!ret) {
461 DosError(FERR_DISABLEHARDERR);
462 ret = DosQueryPathInfo(filename2, FIL_STANDARDL, &fsa2,
463 (ULONG) sizeof(fsa2));
464 if (!ret) {
465 if (fsa1.cbFile == fsa2.cbFile &&
466 (fsa1.attrFile & (~FILE_ARCHIVED)) ==
467 (fsa2.attrFile & (~FILE_ARCHIVED)))
468 return TRUE;
469 }
470 }
471 }
472 return FALSE;
473}
474#endif
475
476/**
477 * Check if argument is file or directory
478 * @returns: -1 (error), 0 (is a directory), or 1 (is a file)
479 */
480
481INT IsFile(PCSZ filename)
482{
483
484 FILESTATUS3 fsa;
485 APIRET ret;
486
487 if (filename && *filename) {
488 DosError(FERR_DISABLEHARDERR);
489 ret = DosQueryPathInfo((CHAR *) filename, FIL_STANDARD, &fsa, (ULONG) sizeof(fsa));
490 if (!ret)
491 return ((fsa.attrFile & FILE_DIRECTORY) == 0);
492 else if (IsValidDrive(*filename) && IsRoot(filename))
493 return 0;
494 }
495 return -1; // error; doesn't exist or can't read or null filename
496}
497
498BOOL IsFullName(CHAR * filename)
499{
500 return (filename) ?
501 (isalpha(*filename) && filename[1] == ':' && filename[2] == '\\') : 0;
502}
503
504BOOL IsRoot(PCSZ filename)
505{
506 return (filename && isalpha(*filename) && filename[1] == ':' &&
507 filename[2] == '\\' && !filename[3]);
508}
509
510BOOL IsValidDir(CHAR * path)
511{
512 CHAR fullname[CCHMAXPATH];
513 FILESTATUS3 fs;
514
515 if (path) {
516 DosError(FERR_DISABLEHARDERR);
517 if (!DosQueryPathInfo(path,
518 FIL_QUERYFULLNAME, fullname, sizeof(fullname))) {
519 if (IsValidDrive(*fullname)) {
520 if (!IsRoot(fullname)) {
521 DosError(FERR_DISABLEHARDERR);
522 if (!DosQueryPathInfo(fullname,
523 FIL_STANDARD,
524 &fs,
525 sizeof(fs)) && (fs.attrFile & FILE_DIRECTORY))
526 return TRUE;
527 }
528 else
529 return TRUE;
530 }
531 }
532 }
533 return FALSE;
534}
535
536BOOL IsValidDrive(CHAR drive)
537{
538 CHAR Path[] = " :", Buffer[256];
539 APIRET Status;
540 ULONG Size;
541 ULONG ulDriveNum, ulDriveMap;
542
543 if (!isalpha(drive) ||
544 (driveflags[toupper(drive) - 'A'] & (DRIVE_IGNORE | DRIVE_INVALID)))
545 return FALSE;
546 DosError(FERR_DISABLEHARDERR);
547 Status = DosQCurDisk(&ulDriveNum, &ulDriveMap);
548 if (!Status) {
549 if (!(ulDriveMap & (1 << (ULONG) (toupper(drive) - 'A'))))
550 return FALSE;
551 Path[0] = toupper(drive);
552 Size = sizeof(Buffer);
553 DosError(FERR_DISABLEHARDERR);
554 Status = DosQueryFSAttach(Path,
555 0,
556 FSAIL_QUERYNAME, (PFSQBUFFER2) Buffer, &Size);
557 }
558 return (Status == 0);
559}
560
561//=== MakeValidDir() build valid directory name ===
562
563CHAR *MakeValidDir(CHAR * path)
564{
565 ULONG ulDrv;
566 CHAR *p;
567 FILESTATUS3 fs;
568 APIRET rc;
569
570 if (!MakeFullName(path)) {
571 if (IsValidDrive(*path)) {
572 // Passed name is valid - trim to directory
573 for (;;) {
574 if (IsRoot(path))
575 return path;
576 DosError(FERR_DISABLEHARDERR);
577 rc = DosQueryPathInfo(path, FIL_STANDARD, &fs, sizeof(fs));
578 if (!rc && (fs.attrFile & FILE_DIRECTORY))
579 return path;
580 p = strrchr(path, '\\');
581 if (p) {
582 if (p < path + 3)
583 p++;
584 *p = 0;
585 }
586 else
587 break;
588 }
589 }
590 }
591 // Fall back to boot drive
592 DosError(FERR_DISABLEHARDERR);
593 if (!DosQuerySysInfo(QSV_BOOT_DRIVE, QSV_BOOT_DRIVE, &ulDrv, sizeof(ulDrv))) {
594 ulDrv += '@';
595 if (ulDrv < 'C')
596 ulDrv = 'C';
597 strcpy(path, " :\\");
598 *path = (CHAR) ulDrv;
599 }
600 else
601 strcpy(path, pFM2SaveDirectory); // Fall back to fm3.ini drive or current dir - should never occur
602 return path;
603}
604
605BOOL IsExecutable(CHAR *filename)
606{
607 register CHAR *p;
608 APIRET ret;
609 ULONG apptype;
610
611 if (filename) {
612 DosError(FERR_DISABLEHARDERR);
613 p = strrchr(filename, '.');
614 if (p)
615 ret = xDosQueryAppType(filename, &apptype);
616 else {
617
618 char fname[CCHMAXPATH + 2];
619
620 strcpy(fname, filename);
621 strcat(fname, ".");
622 ret = xDosQueryAppType(fname, &apptype);
623 }
624 if (apptype & (FAPPTYP_DLL |
625 FAPPTYP_PHYSDRV |
626 FAPPTYP_VIRTDRV |
627 FAPPTYP_PROTDLL))
628 return FALSE;
629 if (apptype == 0x000b && (!p ||
630 (stricmp(p, PCSZ_DOTEXE) &&
631 stricmp(p, PCSZ_DOTCOM) &&
632 stricmp(p, PCSZ_DOTCMD) &&
633 stricmp(p, PCSZ_DOTBAT) &&
634 stricmp(p, PCSZ_DOTBTM))))
635 return FALSE;
636 if (!fProtectOnly) {
637 if ((!ret && (!apptype ||
638 (apptype &
639 (FAPPTYP_NOTWINDOWCOMPAT |
640 FAPPTYP_WINDOWCOMPAT |
641 FAPPTYP_WINDOWAPI |
642 FAPPTYP_BOUND |
643 FAPPTYP_DOS |
644 FAPPTYP_WINDOWSREAL |
645 FAPPTYP_WINDOWSPROT |
646 FAPPTYP_32BIT |
647 FAPPTYP_WINDOWSPROT31)))) ||
648 (p && (!stricmp(p, PCSZ_DOTCMD) || !stricmp(p, PCSZ_DOTBAT) || !stricmp(p, PCSZ_DOTBTM))))
649 return TRUE;
650 }
651 else if ((!ret && (!apptype ||
652 (apptype &
653 (FAPPTYP_NOTWINDOWCOMPAT |
654 FAPPTYP_WINDOWCOMPAT |
655 FAPPTYP_WINDOWAPI |
656 FAPPTYP_BOUND |
657 FAPPTYP_32BIT)))) ||
658 (p && (!stricmp(p, PCSZ_DOTCMD) || !stricmp(p, PCSZ_DOTBTM))))
659 return TRUE;
660 if (fProtectOnly && (apptype &
661 (FAPPTYP_DOS |
662 FAPPTYP_WINDOWSREAL |
663 FAPPTYP_WINDOWSPROT |
664 FAPPTYP_WINDOWSPROT31)) &&
665 (p && (!stricmp(p, PCSZ_DOTEXE) || !stricmp(p, PCSZ_DOTCOM) ||
666 !stricmp(p, PCSZ_DOTBAT))))
667 saymsg(MB_OK,
668 HWND_DESKTOP,
669 NullStr,
670 GetPString(IDS_NOTPROTECTONLYEXE),
671 filename);
672 }
673 return FALSE;
674}
675
676VOID ArgDriveFlags(INT argc, CHAR ** argv)
677{
678 INT x;
679
680 for (x = 1; x < argc; x++) {
681 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_IGNORE;
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_NOPRESCAN;
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_NOSTATS;
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_NOLOADICONS;
714 p++;
715 }
716 }
717 else if (*argv[x] == '-' && isalpha(argv[x][1])) {
718
719 CHAR *p = &argv[x][1];
720
721 while (isalpha(*p)) {
722 driveflags[toupper(*p) - 'A'] |= DRIVE_NOLOADSUBJS;
723 p++;
724 }
725 }
726 else if (*argv[x] == '\'' && isalpha(argv[x][1])) {
727
728 CHAR *p = &argv[x][1];
729
730 while (isalpha(*p)) {
731 driveflags[toupper(*p) - 'A'] |= DRIVE_NOLOADLONGS;
732 p++;
733 }
734 }
735 }
736}
737
738VOID DriveFlagsOne(INT x, CHAR *FileSystem, VOID *volser)
739{
740 INT removable;
741 CHAR szDrive[] = " :\\";
742 ULONG drvtype;
743
744 *szDrive = (CHAR) (x + 'A');
745 *FileSystem = 0;
746 drvtype = 0;
747 removable = CheckDrive(*szDrive, FileSystem, &drvtype);
748 strupr(FileSystem);
749 driveserial[x] = -1;
750 driveflags[x] &= (DRIVE_IGNORE | DRIVE_NOPRESCAN | DRIVE_NOLOADICONS |
751 DRIVE_NOLOADSUBJS | DRIVE_NOLOADLONGS |
752 DRIVE_INCLUDEFILES | DRIVE_SLOW | DRIVE_NOSTATS |
753 DRIVE_WRITEVERIFYOFF);
754 if (removable != -1) {
755 if (!volser) {
756 struct
757 {
758 ULONG serial;
759 CHAR volumelength;
760 CHAR volumelabel[CCHMAXPATH];
761 }
762 volserl;
763
764 DosError(FERR_DISABLEHARDERR);
765 if (!DosQueryFSInfo((ULONG) x + 1, FSIL_VOLSER, &volserl, sizeof(volserl)))
766 driveserial[x] = volserl.serial;
767 else
768 DosError(FERR_DISABLEHARDERR);
769 }
770 else {
771 DosError(FERR_DISABLEHARDERR);
772 if (DosQueryFSInfo((ULONG) x + 1, FSIL_VOLSER, volser,
773 sizeof(ULONG) + sizeof(CHAR) + CCHMAXPATH))
774 DosError(FERR_DISABLEHARDERR);
775 }
776 }
777 else
778 driveflags[x] |= DRIVE_INVALID;
779 driveflags[x] |= ((removable == -1 || removable == 1) ? DRIVE_REMOVABLE : 0);
780 if (drvtype & DRIVE_REMOTE)
781 driveflags[x] |= DRIVE_REMOTE;
782 if (drvtype & DRIVE_NOEASUPPORT)
783 driveflags[x] |= DRIVE_NOEASUPPORT;
784 if(!strcmp(FileSystem,NDFS32)){
785 driveflags[x] |= DRIVE_VIRTUAL;
786 driveflags[x] &= (~DRIVE_REMOTE);
787 }
788 if(!strcmp(FileSystem,RAMFS)){
789 driveflags[x] |= DRIVE_RAMDISK;
790 driveflags[x] &= (~DRIVE_REMOTE);
791 }
792 if(!strcmp(FileSystem,NTFS))
793 driveflags[x] |= DRIVE_NOTWRITEABLE;
794 if (strcmp(FileSystem, HPFS) &&
795 strcmp(FileSystem, CDFS) &&
796 strcmp(FileSystem, ISOFS) &&
797 strcmp(FileSystem, JFS) &&
798 strcmp(FileSystem, LAN) &&
799 strcmp(FileSystem, RAMFS) &&
800 strcmp(FileSystem, FAT32) &&
801 strcmp(FileSystem, NTFS) &&
802 strcmp(FileSystem, NDFS32) &&
803 strcmp(FileSystem, HPFS386)) {
804 driveflags[x] |= DRIVE_NOLONGNAMES;
805 }
806 if ((!strcmp(FileSystem, HPFS) ||
807 !strcmp(FileSystem, FAT) ||
808 !strcmp(FileSystem, JFS) ||
809 !strcmp(FileSystem, FAT32) ||
810 !strcmp(FileSystem, NTFS) ||
811 !strcmp(FileSystem, HPFS386)) && ~driveflags[x] & DRIVE_REMOVABLE) {
812 driveflags[x] |= DRIVE_LOCALHD;
813 }
814 if (!strcmp(FileSystem, CDFS) || !strcmp(FileSystem, ISOFS)) {
815 driveflags[x] |= (DRIVE_REMOVABLE | DRIVE_NOTWRITEABLE | DRIVE_CDROM);
816 }
817 if (!strcmp(FileSystem, CBSIFS)) {
818 driveflags[x] |= DRIVE_ZIPSTREAM;
819 driveflags[x] &= (~DRIVE_REMOTE);
820 if (drvtype & DRIVE_REMOVABLE)
821 driveflags[x] |= DRIVE_REMOVABLE;
822 if (!(drvtype & DRIVE_NOLONGNAMES))
823 driveflags[x] &= (~DRIVE_NOLONGNAMES);
824 }
825}
826
827VOID FillInDriveFlags(VOID * dummy)
828{
829 ULONG ulDriveNum, ulDriveMap, size;
830 register INT x;
831
832 for (x = 0; x < 26; x++)
833 driveflags[x] &= (DRIVE_IGNORE | DRIVE_NOPRESCAN | DRIVE_NOLOADICONS |
834 DRIVE_NOLOADSUBJS | DRIVE_NOLOADLONGS |
835 DRIVE_INCLUDEFILES | DRIVE_SLOW | DRIVE_NOSTATS |
836 DRIVE_WRITEVERIFYOFF);
837 memset(driveserial, -1, sizeof(driveserial));
838 DosError(FERR_DISABLEHARDERR);
839 DosQCurDisk(&ulDriveNum, &ulDriveMap);
840 for (x = 0; x < 26; x++) {
841 if (ulDriveMap & (1 << x) && !(driveflags[x] & DRIVE_IGNORE)) {
842 {
843 ULONG flags = 0, size = sizeof(ULONG);
844 CHAR FlagKey[80];
845
846 sprintf(FlagKey, "%c.DriveFlags", (CHAR) (x + 'A'));
847 if (PrfQueryProfileData(fmprof, appname, FlagKey, &flags, &size) &&
848 size == sizeof(ULONG))
849 driveflags[x] |= flags;
850 }
851
852 if (x > 1) {
853 if (!(driveflags[x] & DRIVE_NOPRESCAN)) {
854 CHAR FileSystem[CCHMAXPATH];
855 DriveFlagsOne(x, FileSystem, NULL);
856 }
857 else
858 driveserial[x] = -1;
859 }
860 else {
861 driveflags[x] |= (DRIVE_REMOVABLE | DRIVE_NOLONGNAMES);
862 driveserial[x] = -1;
863 }
864 }
865 else if (!(ulDriveMap & (1 << x)))
866 driveflags[x] |= DRIVE_INVALID;
867 }
868 {
869 ULONG startdrive = 3L;
870
871 DosError(FERR_DISABLEHARDERR);
872 DosQuerySysInfo(QSV_BOOT_DRIVE, QSV_BOOT_DRIVE,
873 (PVOID) & startdrive, (ULONG) sizeof(ULONG));
874 if (startdrive)
875 driveflags[startdrive - 1] |= DRIVE_BOOT;
876 }
877 {
878 INT x;
879 CHAR Key[80];
880
881 for (x = 2; x < 26; x++) {
882 sprintf(Key, "%c.VerifyOffChecked", (CHAR) (x + 'A'));
883 size = sizeof(BOOL);
884 PrfQueryProfileData(fmprof, appname, Key, &fVerifyOffChecked[x], &size);
885 if (!fVerifyOffChecked[x]) {
886 if (driveflags[x] & DRIVE_REMOVABLE)
887 driveflags[x] |= DRIVE_WRITEVERIFYOFF;
888 if (!(driveflags[x] & DRIVE_INVALID)) {
889 fVerifyOffChecked[x] = TRUE;
890 PrfWriteProfileData(fmprof, appname, Key, &fVerifyOffChecked[x], sizeof(BOOL));
891 }
892 }
893 }
894 }
895}
896
897CHAR *assign_ignores(CHAR * s)
898{
899 register INT x;
900 register CHAR *p, *pp;
901
902 *s = '/';
903 s[1] = 0;
904 p = s + 1;
905 if (s) {
906 for (x = 0; x < 26; x++) {
907 if ((driveflags[x] & DRIVE_IGNORE) != 0) {
908 *p = (CHAR) x + 'A';
909 p++;
910 *p = 0;
911 }
912 }
913 }
914 if (!s[1]) {
915 *s = 0;
916 pp = s;
917 }
918 else {
919 pp = &s[strlen(s)];
920 *pp = ' ';
921 pp++;
922 }
923 *pp = ';';
924 pp[1] = 0;
925 p = pp + 1;
926 if (pp) {
927 for (x = 0; x < 26; x++) {
928 if ((driveflags[x] & DRIVE_NOPRESCAN) != 0) {
929 *p = (CHAR) x + 'A';
930 p++;
931 *p = 0;
932 }
933 }
934 }
935 if (!pp[1])
936 *pp = 0;
937 pp = &s[strlen(s)];
938 *pp = ' ';
939 pp++;
940 *pp = ',';
941 pp[1] = 0;
942 p = pp + 1;
943 if (pp) {
944 for (x = 0; x < 26; x++) {
945 if ((driveflags[x] & DRIVE_NOLOADICONS) != 0) {
946 *p = (CHAR) x + 'A';
947 p++;
948 *p = 0;
949 }
950 }
951 }
952 if (!pp[1])
953 *pp = 0;
954 pp = &s[strlen(s)];
955 *pp = ' ';
956 pp++;
957 *pp = '-';
958 pp[1] = 0;
959 p = pp + 1;
960 if (pp) {
961 for (x = 0; x < 26; x++) {
962 if ((driveflags[x] & DRIVE_NOLOADSUBJS) != 0) {
963 *p = (CHAR) x + 'A';
964 p++;
965 *p = 0;
966 }
967 }
968 }
969 if (!pp[1])
970 *pp = 0;
971 pp = &s[strlen(s)];
972 *pp = ' ';
973 pp++;
974 *pp = '`';
975 pp[1] = 0;
976 p = pp + 1;
977 if (pp) {
978 for (x = 0; x < 26; x++) {
979 if ((driveflags[x] & DRIVE_NOSTATS) != 0) {
980 *p = (CHAR) x + 'A';
981 p++;
982 *p = 0;
983 }
984 }
985 }
986 if (!pp[1])
987 *pp = 0;
988 pp = &s[strlen(s)];
989 *pp = ' ';
990 pp++;
991 *pp = '\'';
992 pp[1] = 0;
993 p = pp + 1;
994 if (pp) {
995 for (x = 0; x < 26; x++) {
996 if ((driveflags[x] & DRIVE_NOLOADLONGS) != 0) {
997 *p = (CHAR) x + 'A';
998 p++;
999 *p = 0;
1000 }
1001 }
1002 }
1003 if (!pp[1])
1004 *pp = 0;
1005 bstrip(s);
1006 return s;
1007}
1008
1009BOOL needs_quoting(PCSZ f)
1010{
1011 register CHAR *p = " &|<>";
1012
1013 while (*p) {
1014 if (strchr(f, *p))
1015 return TRUE;
1016 p++;
1017 }
1018 return FALSE;
1019}
1020
1021BOOL IsBinary(register CHAR * str, ULONG len)
1022{
1023 register ULONG x = 0;
1024
1025 if (str) {
1026 while (x < len) {
1027 if ((UINT) str[x] < ' ' && str[x] != '\r' && str[x] != '\n' && str[x] != '\t'
1028 && str[x] != '\x1b' && str[x] != '\x1a' && str[x] != '\x07'
1029 && str[x] != '\x0c') {
1030 return TRUE;
1031 }
1032 x++;
1033 }
1034 }
1035 return FALSE;
1036}
1037
1038BOOL TestBinary(CHAR * filename)
1039{
1040 HFILE handle;
1041 ULONG ulAction;
1042 ULONG len;
1043 APIRET rc;
1044 CHAR buff[4096]; // 06 Oct 07 SHL protect against NTFS defect
1045
1046 if (filename) {
1047 if (!DosOpen(filename, &handle, &ulAction, 0, 0,
1048 OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS,
1049 OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_NOINHERIT |
1050 OPEN_FLAGS_SEQUENTIAL | OPEN_SHARE_DENYNONE |
1051 OPEN_ACCESS_READONLY, 0)) {
1052 len = 512;
1053 rc = DosRead(handle, buff, len, &len);
1054 DosClose(handle);
1055 if (!rc && len)
1056 return IsBinary(buff, len);
1057 }
1058 }
1059 return FALSE;
1060}
1061
1062#if 0 // JBS 11 Sep 08
1063char *IsVowel(char a)
1064{
1065 return (strchr("aeiouAEIOU", a) != NULL) ? "n" : NullStr;
1066}
1067#endif
1068
1069VOID GetDesktopName(CHAR * objectpath, ULONG size)
1070{
1071 PFN WQDPath;
1072 HMODULE hmod = 0;
1073 APIRET rc;
1074 ULONG startdrive = 3;
1075 CHAR objerr[CCHMAXPATH];
1076
1077 if (!objectpath) {
1078 Runtime_Error(pszSrcFile, __LINE__, "null pointer");
1079 return;
1080 }
1081 *objectpath = 0;
1082 if (OS2ver[0] > 20 || (OS2ver[0] == 20 && OS2ver[1] >= 30)) {
1083 /**
1084 * if running under warp, we can get the desktop name
1085 * this way...
1086 */
1087 rc = DosLoadModule(objerr, sizeof(objerr), "PMWP", &hmod);
1088 if (!rc) {
1089 rc = DosQueryProcAddr(hmod, 262, NULL, &WQDPath);
1090 if (!rc)
1091 WQDPath(objectpath, size);
1092 DosFreeModule(hmod);
1093 }
1094 }
1095 if (!*objectpath) {
1096 // Fall back to INI content
1097 if (!PrfQueryProfileString(HINI_SYSTEMPROFILE,
1098 "FolderWorkareaRunningObjects",
1099 NULL,
1100 "\0",
1101 (PVOID) objectpath, sizeof(objectpath))) {
1102 Win_Error(HWND_DESKTOP, HWND_DESKTOP, pszSrcFile, __LINE__,
1103 PCSZ_PRFQUERYPROFILESTRING);
1104 *objectpath = 0;
1105 }
1106 else if (!*objectpath || IsFile(objectpath)) {
1107 Runtime_Error(pszSrcFile, __LINE__, "bad FolderWorkareaRunningObjects");
1108 *objectpath = 0;
1109 }
1110 if (!*objectpath) {
1111 // Fall back
1112 DosError(FERR_DISABLEHARDERR);
1113 DosQuerySysInfo(QSV_BOOT_DRIVE, QSV_BOOT_DRIVE,
1114 (PVOID) & startdrive, (ULONG) sizeof(ULONG));
1115 sprintf(objectpath, GetPString(IDS_PATHTODESKTOP), ((CHAR) startdrive) + '@');
1116 }
1117 }
1118}
1119
1120#pragma alloc_text(VALID,CheckDrive,IsRoot,IsFile,IsFullName,needs_quoting)
1121#pragma alloc_text(VALID,IsValidDir,IsValidDrive,MakeValidDir,IsVowel)
1122#pragma alloc_text(VALID,IsFileSame,IsNewer,TestFDates,TestCDates,RootName,MakeFullName)
1123#pragma alloc_text(VALID,IsExecutable,IsBinary,IsDesktop,ParentIsDesktop)
1124#pragma alloc_text(FILLFLAGS,FillInDriveFlags,assign_ignores)
1125#pragma alloc_text(FILLFLAGS,ArgDriveFlags,DriveFlagsOne)
1126#pragma alloc_text(FINDDESK,GetDesktopName)
Note: See TracBrowser for help on using the repository browser.