source: trunk/dll/valid.c@ 1544

Last change on this file since 1544 was 1544, checked in by Gregg Young, 15 years ago

Changes to fopen and _fsopen to allow FM2 to be loaded in high memory

  • 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 1544 2010-09-30 13:00:59Z 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
44***********************************************************************/
45
46#include <string.h>
47#include <ctype.h>
48
49#define INCL_DOS
50#define INCL_WIN
51#define INCL_DOSDEVIOCTL // DosDevIOCtl
52#define INCL_LONGLONG
53
54#include "fm3dll.h"
55#include "treecnr.h" // Data declaration(s)
56#include "info.h" // Data declaration(s)
57#include "notebook.h" // Data declaration(s)
58#include "fm3str.h"
59#include "errutil.h" // Dos_Error...
60#include "strutil.h" // GetPString
61#include "valid.h"
62#include "dirs.h" // save_dir2
63#include "strips.h" // bstrip
64#include "init.h" // GetTidForWindow
65#include "wrappers.h" // xDosAllocMem
66
67
68//static BOOL IsDesktop(HAB hab, HWND hwnd);
69//static BOOL IsFileSame(CHAR * filename1, CHAR * filename2);
70//static char *IsVowel(char a);
71
72// Data definitions
73static PSZ pszSrcFile = __FILE__;
74
75#pragma data_seg(GLOBAL2)
76PCSZ HPFS = "HPFS";
77PCSZ JFS = "JFS";
78PCSZ CDFS = "CDFS";
79PCSZ ISOFS = "ISOFS";
80PCSZ FAT32 = "FAT32";
81PCSZ FAT = "FAT";
82PCSZ HPFS386 = "HPFS386";
83PCSZ CBSIFS = "CBSIFS";
84PCSZ NDFS32 = "NDFS32";
85PCSZ RAMFS = "RAMFS";
86PCSZ NTFS = "NTFS";
87PCSZ LAN = "LAN";
88BOOL fVerifyOffChecked[26];
89
90APIRET MakeFullName(char *pszFileName)
91{
92 /* pszFileName must be CCHMAXPATH long minimum! */
93
94 char szPathName[CCHMAXPATH];
95 APIRET rc;
96
97 DosError(FERR_DISABLEHARDERR);
98 rc = DosQueryPathInfo(pszFileName,
99 FIL_QUERYFULLNAME, szPathName, sizeof(szPathName));
100 if (!rc)
101 strcpy(pszFileName, szPathName); // Pass back actual name
102 return rc;
103}
104
105char *RootName(char *filename)
106{
107 char *p = NULL, *pp;
108
109 // Return filename, strip path parts
110 // Return empty string when filename ends with backslash
111
112 if (filename) {
113 p = strrchr(filename, '\\');
114 pp = strrchr(filename, '/');
115 p = (p) ? (pp) ? (p > pp) ? p : pp : p : pp;
116 }
117 if (!p) /* name is itself a root */
118 p = filename;
119 else /* skip past backslash */
120 p++;
121 return p;
122}
123
124 /** TestFDate
125 * return 1 (file2 newer than file1),
126 * 0 (files same)
127 * or -1 (file1 newer than file2)
128 * Make the FILSTATUS pointers NULL if passing file names
129 * if the FILESTATUS information is already available it can be passed instead
130 * Make the files NULL if passing FILESTATUS buffers
131 */
132
133int TestFDates(char *file1, char *file2, FDATE *datevar1, FTIME *timevar1,
134 FDATE *datevar2, FTIME *timevar2)
135{
136 int comp = 0;
137 FILESTATUS3 fs3o, fs3n;
138
139 if (file1){
140 DosError(FERR_DISABLEHARDERR);
141 DosQueryPathInfo(file1, FIL_STANDARD, &fs3o, sizeof(fs3o));
142 datevar1 = &fs3o.fdateLastWrite;
143 timevar1 = &fs3o.ftimeLastWrite;
144 }
145 if (file2) {
146 DosError(FERR_DISABLEHARDERR);
147 DosQueryPathInfo(file2, FIL_STANDARD, &fs3n, sizeof(fs3n));
148 datevar2 = &fs3n.fdateLastWrite;
149 timevar2 = &fs3n.ftimeLastWrite;
150 }
151 if (&datevar1 && &datevar2 && &timevar1 && &timevar2) {
152 comp = (datevar2->year >
153 datevar1->year) ? 1 :
154 (datevar2->year <
155 datevar1->year) ? -1 :
156 (datevar2->month >
157 datevar1->month) ? 1 :
158 (datevar2->month <
159 datevar1->month) ? -1 :
160 (datevar2->day >
161 datevar1->day) ? 1 :
162 (datevar2->day <
163 datevar1->day) ? -1 :
164 (timevar2->hours >
165 timevar1->hours) ? 1 :
166 (timevar2->hours <
167 timevar1->hours) ? -1 :
168 (timevar2->minutes >
169 timevar1->minutes) ? 1 :
170 (timevar2->minutes <
171 timevar1->minutes) ? -1 :
172 (timevar2->twosecs >
173 timevar1->twosecs) ? 1 :
174 (timevar2->twosecs < timevar1->twosecs) ? -1 : 0;
175 }
176 return comp;
177}
178
179 /** TestCDate
180 * return 1 (file2 newer than file1),
181 * 0 (files same)
182 * or -1 (file1 newer than file2)
183 */
184
185int TestCDates(CDATE *datevar1, CTIME *timevar1,
186 CDATE *datevar2, CTIME *timevar2)
187{
188 int comp = 0;
189
190 if (&datevar1 && &datevar2 && &timevar1 && &timevar2) {
191 comp = (datevar2->year >
192 datevar1->year) ? 1 :
193 (datevar2->year <
194 datevar1->year) ? -1 :
195 (datevar2->month >
196 datevar1->month) ? 1 :
197 (datevar2->month <
198 datevar1->month) ? -1 :
199 (datevar2->day >
200 datevar1->day) ? 1 :
201 (datevar2->day <
202 datevar1->day) ? -1 :
203 (timevar2->hours >
204 timevar1->hours) ? 1 :
205 (timevar2->hours <
206 timevar1->hours) ? -1 :
207 (timevar2->minutes >
208 timevar1->minutes) ? 1 :
209 (timevar2->minutes <
210 timevar1->minutes) ? -1 :
211 (timevar2->seconds >
212 timevar1->seconds) ? 1 :
213 (timevar2->seconds < timevar1->seconds) ? -1 : 0;
214 }
215 return comp;
216}
217
218BOOL IsNewer(char *file1, char *file2)
219{
220 /* return TRUE if file2 is newer than file1 */
221
222 return (TestFDates(file1, file2, NULL, NULL, NULL, NULL) > 0);
223}
224
225#if 0 // JBS 11 Sep 08
226BOOL IsDesktop(HAB hab, HWND hwnd)
227{
228 HWND hwndDesktop;
229
230 if (hwnd == HWND_DESKTOP)
231 return TRUE;
232 hwndDesktop = WinQueryDesktopWindow(hab, NULLHANDLE);
233 if (hwnd == hwndDesktop)
234 return TRUE;
235 return FALSE;
236}
237#endif
238
239BOOL ParentIsDesktop(HWND hwnd, HWND hwndParent)
240{
241 HWND hwndDesktop;
242 BOOL ret = FALSE;
243
244 if (!hwndParent)
245 hwndParent = WinQueryWindow(hwnd, QW_PARENT);
246 if (hwndParent == HWND_DESKTOP)
247 ret = TRUE;
248 else {
249 hwndDesktop = WinQueryDesktopWindow(WinQueryAnchorBlock(hwnd), (HWND) 0);
250 if (hwndDesktop == hwndParent)
251 ret = TRUE;
252 }
253 return ret;
254}
255
256/** CheckDrive
257 * @param chDrive drive letter
258 * @param pszFileSystem pointer to buffer to return file system type or NULL
259 * @param pulType pointer to long word to return drive flags or NULL
260 * @returns removability flag, 1 = removable, 0 = not removable, -1 = error
261 */
262
263INT CheckDrive(CHAR chDrive, CHAR * pszFileSystem, ULONG * pulType)
264{
265 CHAR szPath[4];
266 VOID *pvBuffer = NULL;
267 CHAR *pfsn;
268 CHAR *pfsd;
269 ULONG clBufferSize;
270 APIRET rc;
271 ULONG ulAction;
272 ULONG clParmBytes;
273 ULONG clDataBytes;
274 HFILE hDev;
275 EASIZEBUF easize = {0};
276 ULONG ulDataLen = sizeof(EASIZEBUF);
277 ULONG ulParmLen = 0;
278
279# pragma pack(1)
280 struct
281 {
282 BYTE Cmd;
283 BYTE Unit;
284 }
285 parmPkt =
286 {
287 0, 0};
288# define BPB_REMOVABLE_MEDIA 0x08 // 3 - Media is removable
289 struct
290 {
291 BIOSPARAMETERBLOCK bpb;
292 USHORT cCylinders; // Documented but not implemented
293 BYTE bDeviceType; // Documented but not implemented
294 USHORT fsDeviceAttr; // Documented but not implemented
295 }
296 dataPkt;
297
298# pragma pack()
299 BYTE NonRemovable;
300 PFSQBUFFER2 pfsq;
301
302 if (pszFileSystem)
303 *pszFileSystem = 0;
304
305 if (pulType)
306 *pulType = 0;
307
308# define BUFFER_BYTES 8192
309 rc = xDosAllocMem(&pvBuffer, BUFFER_BYTES,
310 PAG_COMMIT | PAG_READ | PAG_WRITE, pszSrcFile, __LINE__);
311 if (rc) {
312 Dos_Error(MB_CANCEL, rc, HWND_DESKTOP, pszSrcFile, __LINE__,
313 GetPString(IDS_OUTOFMEMORY));
314 return -1; // Say failed
315 }
316
317 szPath[0] = chDrive;
318 szPath[1] = ':';
319 szPath[2] = 0;
320 clBufferSize = BUFFER_BYTES;
321 DosError(FERR_DISABLEHARDERR);
322 rc = DosQueryFSAttach(szPath, 0, FSAIL_QUERYNAME,
323 (PFSQBUFFER2) pvBuffer, &clBufferSize);
324 if (rc) {
325 /* can't get any info at all */
326 DosFreeMem(pvBuffer);
327 DosError(FERR_DISABLEHARDERR);
328 return -1; // Say failed
329 }
330
331 pfsq = (PFSQBUFFER2) pvBuffer;
332 pfsn = (PCHAR)(pfsq->szName) + pfsq->cbName + 1;
333 pfsd = pfsn + pfsq->cbFSDName + 1;
334 strupr(pfsn);
335
336 if (pszFileSystem) {
337 strncpy(pszFileSystem, pfsn, CCHMAXPATH);
338 pszFileSystem[CCHMAXPATH - 1] = 0;
339 }
340 szPath[2] = '\\';
341 szPath[3] = 0;
342 DosFSCtl(&easize, sizeof(EASIZEBUF), &ulDataLen, NULL, ulParmLen,
343 &ulParmLen, FSCTL_MAX_EASIZE, szPath, -1, FSCTL_PATHNAME);
344 //DbgMsg(pszSrcFile, __LINE__, "%i %i %s %s", easize.cbMaxEASize, easize.cbMaxEAListSize, szPath, pfsn);
345 szPath[2] = 0;
346 if (pulType && easize.cbMaxEASize == 0)
347 *pulType |= DRIVE_NOEASUPPORT;
348 if (pulType && (!strcmp(pfsn, CDFS) || !strcmp(pfsn, ISOFS)))
349 *pulType |= DRIVE_NOTWRITEABLE | DRIVE_CDROM | DRIVE_REMOVABLE;
350 if (pulType && !strcmp(pfsn, NTFS))
351 *pulType |= DRIVE_NOTWRITEABLE;
352 if (pulType && !strcmp(pfsn, NDFS32)){
353 *pulType |= DRIVE_VIRTUAL;
354 }
355 if (pulType && !strcmp(pfsn, RAMFS)){
356 *pulType |= DRIVE_RAMDISK;
357 }
358 if (((PFSQBUFFER2) pvBuffer)->iType == FSAT_REMOTEDRV) {
359 if (pulType)
360 *pulType |= DRIVE_REMOTE;
361
362 if (pulType && !strcmp(pfsn, CBSIFS)) {
363 *pulType |= DRIVE_ZIPSTREAM;
364 *pulType &= ~DRIVE_REMOTE;
365 *pulType |= DRIVE_NOLONGNAMES;
366 if (pfsq->cbFSAData) {
367 ULONG FType;
368
369 if (CheckDrive(*pfsd, NULL, &FType) != -1) {
370 if (FType & DRIVE_REMOVABLE)
371 *pulType |= DRIVE_REMOVABLE;
372 if (~FType & DRIVE_NOLONGNAMES)
373 *pulType &= ~DRIVE_NOLONGNAMES;
374 }
375
376 }
377 }
378 if (pulType &&
379 (!strcmp(pfsn, LAN) ||
380 !strcmp(pfsn, RAMFS) ||
381 !strcmp(pfsn, NDFS32))) {
382 *pulType &= ~DRIVE_NOLONGNAMES;
383 }
384
385 DosFreeMem(pvBuffer);
386 return 0; // Remotes are non-removable
387 }
388
389 // Local drive
390 if (strcmp(pfsn, HPFS) &&
391 strcmp(pfsn, CDFS) &&
392 strcmp(pfsn, ISOFS) &&
393 strcmp(pfsn, JFS) &&
394 strcmp(pfsn, FAT32) &&
395 strcmp(pfsn, NTFS) &&
396 strcmp(pfsn, HPFS386)) {
397 if (pulType)
398 (*pulType) |= DRIVE_NOLONGNAMES; // Others can not have long names
399 }
400
401 DosError(FERR_DISABLEHARDERR);
402 rc = DosOpen(szPath, &hDev, &ulAction, 0, 0, FILE_OPEN,
403 OPEN_ACCESS_READONLY | OPEN_SHARE_DENYNONE |
404 OPEN_FLAGS_DASD | OPEN_FLAGS_FAIL_ON_ERROR, 0);
405 if (rc) {
406 DosError(FERR_DISABLEHARDERR);
407 if (pulType)
408 *pulType |= DRIVE_REMOVABLE; // Assume removable if can not access
409 DosFreeMem(pvBuffer);
410 return 1; // Say removable
411 }
412
413 clParmBytes = sizeof(parmPkt.Cmd);
414 clDataBytes = sizeof(NonRemovable);
415 NonRemovable = 1; // Preset as non removable
416 DosError(FERR_DISABLEHARDERR);
417 rc = DosDevIOCtl(hDev, IOCTL_DISK, DSK_BLOCKREMOVABLE, &parmPkt.Cmd, /* Address of the command-specific argument list. */
418 sizeof(parmPkt.Cmd), /* Length, in bytes, of pParams. */
419 &clParmBytes, /* Pointer to the length of parameters. */
420 &NonRemovable, /* Address of the data area. */
421 sizeof(NonRemovable), /* Length, in bytes, of pData. */
422 &clDataBytes); /* Pointer to the length of data. */
423
424 if (!rc && NonRemovable) {
425 // Could be USB so check BPB flags
426 clParmBytes = sizeof(parmPkt.Cmd);
427 clDataBytes = sizeof(dataPkt);
428 memset(&dataPkt, 0xff, sizeof(dataPkt));
429 DosError(FERR_DISABLEHARDERR);
430 rc = DosDevIOCtl(hDev, IOCTL_DISK, DSK_GETDEVICEPARAMS, &parmPkt.Cmd, /* Address of the command-specific argument list. */
431 sizeof(parmPkt.Cmd), /* Length, in bytes, of pParams. */
432 &clParmBytes, /* Pointer to the length of parameters. */
433 &dataPkt, /* Address of the data area. */
434 sizeof(dataPkt), /* Length, in bytes, of pData. */
435 &clDataBytes); /* Pointer to the length of data. */
436
437 if (!rc && (dataPkt.bpb.fsDeviceAttr & BPB_REMOVABLE_MEDIA))
438 NonRemovable = 0;
439 }
440
441 DosClose(hDev);
442
443 if (!NonRemovable && pulType)
444 *pulType |= DRIVE_REMOVABLE;
445
446 DosFreeMem(pvBuffer);
447
448 return NonRemovable ? 0 : 1;
449}
450
451#if 0 // JBS 11 Sep 08
452BOOL IsFileSame(CHAR * filename1, CHAR * filename2)
453{
454 /* returns: -1 (error), 0 (is a directory), or 1 (is a file) */
455
456 FILESTATUS3L fsa1, fsa2;
457 APIRET ret;
458
459 if (filename1 && filename2) {
460 DosError(FERR_DISABLEHARDERR);
461 ret = DosQueryPathInfo(filename1, FIL_STANDARDL, &fsa1,
462 (ULONG) sizeof(fsa1));
463 if (!ret) {
464 DosError(FERR_DISABLEHARDERR);
465 ret = DosQueryPathInfo(filename2, FIL_STANDARDL, &fsa2,
466 (ULONG) sizeof(fsa2));
467 if (!ret) {
468 if (fsa1.cbFile == fsa2.cbFile &&
469 (fsa1.attrFile & (~FILE_ARCHIVED)) ==
470 (fsa2.attrFile & (~FILE_ARCHIVED)))
471 return TRUE;
472 }
473 }
474 }
475 return FALSE;
476}
477#endif
478
479INT IsFile(PCSZ filename)
480{
481 /* returns: -1 (error), 0 (is a directory), or 1 (is a file) */
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 = DosQueryAppType(filename, &apptype);
615 else {
616
617 char fname[CCHMAXPATH + 2];
618
619 strcpy(fname, filename);
620 strcat(fname, ".");
621 ret = DosQueryAppType(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 (!(driveflags[x] & DRIVE_NOPRESCAN)) {
853 CHAR FileSystem[CCHMAXPATH];
854 DriveFlagsOne(x, FileSystem, NULL);
855 }
856 else
857 driveserial[x] = -1;
858 }
859 else {
860 driveflags[x] |= (DRIVE_REMOVABLE | DRIVE_NOLONGNAMES);
861 driveserial[x] = -1;
862 }
863 }
864 else if (!(ulDriveMap & (1 << x)))
865 driveflags[x] |= DRIVE_INVALID;
866 }
867 {
868 ULONG startdrive = 3L;
869
870 DosError(FERR_DISABLEHARDERR);
871 DosQuerySysInfo(QSV_BOOT_DRIVE, QSV_BOOT_DRIVE,
872 (PVOID) & startdrive, (ULONG) sizeof(ULONG));
873 if (startdrive)
874 driveflags[startdrive - 1] |= DRIVE_BOOT;
875 }
876 {
877 INT x;
878 CHAR Key[80];
879
880 for (x = 2; x < 26; x++) {
881 sprintf(Key, "%c.VerifyOffChecked", (CHAR) (x + 'A'));
882 size = sizeof(BOOL);
883 PrfQueryProfileData(fmprof, appname, Key, &fVerifyOffChecked[x], &size);
884 if (!fVerifyOffChecked[x]) {
885 if (driveflags[x] & DRIVE_REMOVABLE)
886 driveflags[x] |= DRIVE_WRITEVERIFYOFF;
887 if (!(driveflags[x] & DRIVE_INVALID)) {
888 fVerifyOffChecked[x] = TRUE;
889 PrfWriteProfileData(fmprof, appname, Key, &fVerifyOffChecked[x], sizeof(BOOL));
890 }
891 }
892 }
893 }
894}
895
896CHAR *assign_ignores(CHAR * s)
897{
898 register INT x;
899 register CHAR *p, *pp;
900
901 *s = '/';
902 s[1] = 0;
903 p = s + 1;
904 if (s) {
905 for (x = 0; x < 26; x++) {
906 if ((driveflags[x] & DRIVE_IGNORE) != 0) {
907 *p = (CHAR) x + 'A';
908 p++;
909 *p = 0;
910 }
911 }
912 }
913 if (!s[1]) {
914 *s = 0;
915 pp = s;
916 }
917 else {
918 pp = &s[strlen(s)];
919 *pp = ' ';
920 pp++;
921 }
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_NOPRESCAN) != 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_NOLOADICONS) != 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_NOLOADSUBJS) != 0) {
962 *p = (CHAR) x + 'A';
963 p++;
964 *p = 0;
965 }
966 }
967 }
968 if (!pp[1])
969 *pp = 0;
970 pp = &s[strlen(s)];
971 *pp = ' ';
972 pp++;
973 *pp = '`';
974 pp[1] = 0;
975 p = pp + 1;
976 if (pp) {
977 for (x = 0; x < 26; x++) {
978 if ((driveflags[x] & DRIVE_NOSTATS) != 0) {
979 *p = (CHAR) x + 'A';
980 p++;
981 *p = 0;
982 }
983 }
984 }
985 if (!pp[1])
986 *pp = 0;
987 pp = &s[strlen(s)];
988 *pp = ' ';
989 pp++;
990 *pp = '\'';
991 pp[1] = 0;
992 p = pp + 1;
993 if (pp) {
994 for (x = 0; x < 26; x++) {
995 if ((driveflags[x] & DRIVE_NOLOADLONGS) != 0) {
996 *p = (CHAR) x + 'A';
997 p++;
998 *p = 0;
999 }
1000 }
1001 }
1002 if (!pp[1])
1003 *pp = 0;
1004 bstrip(s);
1005 return s;
1006}
1007
1008BOOL needs_quoting(PCSZ f)
1009{
1010 register CHAR *p = " &|<>";
1011
1012 while (*p) {
1013 if (strchr(f, *p))
1014 return TRUE;
1015 p++;
1016 }
1017 return FALSE;
1018}
1019
1020BOOL IsBinary(register CHAR * str, ULONG len)
1021{
1022 register ULONG x = 0;
1023
1024 if (str) {
1025 while (x < len) {
1026 if ((UINT) str[x] < ' ' && str[x] != '\r' && str[x] != '\n' && str[x] != '\t'
1027 && str[x] != '\x1b' && str[x] != '\x1a' && str[x] != '\x07'
1028 && str[x] != '\x0c') {
1029 return TRUE;
1030 }
1031 x++;
1032 }
1033 }
1034 return FALSE;
1035}
1036
1037BOOL TestBinary(CHAR * filename)
1038{
1039 HFILE handle;
1040 ULONG ulAction;
1041 ULONG len;
1042 APIRET rc;
1043 CHAR buff[4096]; // 06 Oct 07 SHL protect against NTFS defect
1044
1045 if (filename) {
1046 if (!DosOpen(filename, &handle, &ulAction, 0, 0,
1047 OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS,
1048 OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_NOINHERIT |
1049 OPEN_FLAGS_SEQUENTIAL | OPEN_SHARE_DENYNONE |
1050 OPEN_ACCESS_READONLY, 0)) {
1051 len = 512;
1052 rc = DosRead(handle, buff, len, &len);
1053 DosClose(handle);
1054 if (!rc && len)
1055 return IsBinary(buff, len);
1056 }
1057 }
1058 return FALSE;
1059}
1060
1061#if 0 // JBS 11 Sep 08
1062char *IsVowel(char a)
1063{
1064 return (strchr("aeiouAEIOU", a) != NULL) ? "n" : NullStr;
1065}
1066#endif
1067
1068VOID GetDesktopName(CHAR * objectpath, ULONG size)
1069{
1070 PFN WQDPath;
1071 HMODULE hmod = 0;
1072 APIRET rc;
1073 ULONG startdrive = 3;
1074 CHAR objerr[CCHMAXPATH];
1075
1076 if (!objectpath) {
1077 Runtime_Error(pszSrcFile, __LINE__, "null pointer");
1078 return;
1079 }
1080 *objectpath = 0;
1081 if (OS2ver[0] > 20 || (OS2ver[0] == 20 && OS2ver[1] >= 30)) {
1082 /*
1083 * if running under warp, we can get the desktop name
1084 * this way...
1085 */
1086 rc = DosLoadModule(objerr, sizeof(objerr), "PMWP", &hmod);
1087 if (!rc) {
1088 rc = DosQueryProcAddr(hmod, 262, NULL, &WQDPath);
1089 if (!rc)
1090 WQDPath(objectpath, size);
1091 DosFreeModule(hmod);
1092 }
1093 }
1094 if (!*objectpath) {
1095 // Fall back to INI content
1096 if (!PrfQueryProfileString(HINI_SYSTEMPROFILE,
1097 "FolderWorkareaRunningObjects",
1098 NULL,
1099 "\0",
1100 (PVOID) objectpath, sizeof(objectpath))) {
1101 Win_Error(HWND_DESKTOP, HWND_DESKTOP, pszSrcFile, __LINE__,
1102 PCSZ_PRFQUERYPROFILESTRING);
1103 *objectpath = 0;
1104 }
1105 else if (!*objectpath || IsFile(objectpath)) {
1106 Runtime_Error(pszSrcFile, __LINE__, "bad FolderWorkareaRunningObjects");
1107 *objectpath = 0;
1108 }
1109 if (!*objectpath) {
1110 // Fall back
1111 DosError(FERR_DISABLEHARDERR);
1112 DosQuerySysInfo(QSV_BOOT_DRIVE, QSV_BOOT_DRIVE,
1113 (PVOID) & startdrive, (ULONG) sizeof(ULONG));
1114 sprintf(objectpath, GetPString(IDS_PATHTODESKTOP), ((CHAR) startdrive) + '@');
1115 }
1116 }
1117}
1118
1119#pragma alloc_text(VALID,CheckDrive,IsRoot,IsFile,IsFullName,needsquoting)
1120#pragma alloc_text(VALID,IsValidDir,IsValidDrive,MakeValidDir,IsVowel)
1121#pragma alloc_text(VALID,IsFileSame,IsNewer,TestFDates,TestCDates,RootName,MakeFullName)
1122#pragma alloc_text(VALID,IsExecutable,IsBinary,IsDesktop,ParentIsDesktop)
1123#pragma alloc_text(FILLFLAGS,FillInDriveFlags,assign_ignores)
1124#pragma alloc_text(FILLFLAGS,ArgDriveFlags,DriveFlagsOne)
1125#pragma alloc_text(FINDDESK,GetDesktopName)
Note: See TracBrowser for help on using the repository browser.