source: trunk/dll/valid.c@ 1627

Last change on this file since 1627 was 1627, checked in by Gregg Young, 14 years ago

Add a low mem version of xDosAlloc* wrappers; move error checking into all the xDosAlloc* wrappers. Ticket 471

  • 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 1627 2011-08-26 21:48:06Z 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
46***********************************************************************/
47
48#include <string.h>
49#include <ctype.h>
50
51#define INCL_DOS
52#define INCL_WIN
53#define INCL_DOSDEVIOCTL // DosDevIOCtl
54#define INCL_LONGLONG
55
56#include "fm3dll.h"
57#include "treecnr.h" // Data declaration(s)
58#include "info.h" // Data declaration(s)
59#include "notebook.h" // Data declaration(s)
60#include "fm3str.h"
61#include "errutil.h" // Dos_Error...
62#include "strutil.h" // GetPString
63#include "valid.h"
64#include "dirs.h" // save_dir2
65#include "strips.h" // bstrip
66#include "init.h" // GetTidForWindow
67#include "wrappers.h" // xDosAllocMem
68
69
70//static BOOL IsDesktop(HAB hab, HWND hwnd);
71//static BOOL IsFileSame(CHAR * filename1, CHAR * filename2);
72//static char *IsVowel(char a);
73
74// Data definitions
75static PSZ pszSrcFile = __FILE__;
76
77#pragma data_seg(GLOBAL2)
78PCSZ HPFS = "HPFS";
79PCSZ JFS = "JFS";
80PCSZ CDFS = "CDFS";
81PCSZ ISOFS = "ISOFS";
82PCSZ FAT32 = "FAT32";
83PCSZ FAT = "FAT";
84PCSZ HPFS386 = "HPFS386";
85PCSZ CBSIFS = "CBSIFS";
86PCSZ NDFS32 = "NDFS32";
87PCSZ RAMFS = "RAMFS";
88PCSZ NTFS = "NTFS";
89PCSZ LAN = "LAN";
90BOOL fVerifyOffChecked[26];
91
92APIRET MakeFullName(char *pszFileName)
93{
94 /* pszFileName must be CCHMAXPATH long minimum! */
95
96 char szPathName[CCHMAXPATH];
97 APIRET rc;
98
99 DosError(FERR_DISABLEHARDERR);
100 rc = DosQueryPathInfo(pszFileName,
101 FIL_QUERYFULLNAME, szPathName, sizeof(szPathName));
102 if (!rc)
103 strcpy(pszFileName, szPathName); // Pass back actual name
104 return rc;
105}
106
107char *RootName(char *filename)
108{
109 char *p = NULL, *pp;
110
111 // Return filename, strip path parts
112 // Return empty string when filename ends with backslash
113
114 if (filename) {
115 p = strrchr(filename, '\\');
116 pp = strrchr(filename, '/');
117 p = (p) ? (pp) ? (p > pp) ? p : pp : p : pp;
118 }
119 if (!p) /* name is itself a root */
120 p = filename;
121 else /* skip past backslash */
122 p++;
123 return p;
124}
125
126 /** TestFDate
127 * return 1 (file2 newer than file1),
128 * 0 (files same)
129 * or -1 (file1 newer than file2)
130 * Make the FILSTATUS pointers NULL if passing file names
131 * if the FILESTATUS information is already available it can be passed instead
132 * Make the files NULL if passing FILESTATUS buffers
133 */
134
135int TestFDates(char *file1, char *file2, FDATE *datevar1, FTIME *timevar1,
136 FDATE *datevar2, FTIME *timevar2)
137{
138 int comp = 0;
139 FILESTATUS3 fs3o, fs3n;
140
141 if (file1){
142 DosError(FERR_DISABLEHARDERR);
143 DosQueryPathInfo(file1, FIL_STANDARD, &fs3o, sizeof(fs3o));
144 datevar1 = &fs3o.fdateLastWrite;
145 timevar1 = &fs3o.ftimeLastWrite;
146 }
147 if (file2) {
148 DosError(FERR_DISABLEHARDERR);
149 DosQueryPathInfo(file2, FIL_STANDARD, &fs3n, sizeof(fs3n));
150 datevar2 = &fs3n.fdateLastWrite;
151 timevar2 = &fs3n.ftimeLastWrite;
152 }
153 if (&datevar1 && &datevar2 && &timevar1 && &timevar2) {
154 comp = (datevar2->year >
155 datevar1->year) ? 1 :
156 (datevar2->year <
157 datevar1->year) ? -1 :
158 (datevar2->month >
159 datevar1->month) ? 1 :
160 (datevar2->month <
161 datevar1->month) ? -1 :
162 (datevar2->day >
163 datevar1->day) ? 1 :
164 (datevar2->day <
165 datevar1->day) ? -1 :
166 (timevar2->hours >
167 timevar1->hours) ? 1 :
168 (timevar2->hours <
169 timevar1->hours) ? -1 :
170 (timevar2->minutes >
171 timevar1->minutes) ? 1 :
172 (timevar2->minutes <
173 timevar1->minutes) ? -1 :
174 (timevar2->twosecs >
175 timevar1->twosecs) ? 1 :
176 (timevar2->twosecs < timevar1->twosecs) ? -1 : 0;
177 }
178 return comp;
179}
180
181 /** TestCDate
182 * return 1 (file2 newer than file1),
183 * 0 (files same)
184 * or -1 (file1 newer than file2)
185 */
186
187int TestCDates(CDATE *datevar1, CTIME *timevar1,
188 CDATE *datevar2, CTIME *timevar2)
189{
190 int comp = 0;
191
192 if (&datevar1 && &datevar2 && &timevar1 && &timevar2) {
193 comp = (datevar2->year >
194 datevar1->year) ? 1 :
195 (datevar2->year <
196 datevar1->year) ? -1 :
197 (datevar2->month >
198 datevar1->month) ? 1 :
199 (datevar2->month <
200 datevar1->month) ? -1 :
201 (datevar2->day >
202 datevar1->day) ? 1 :
203 (datevar2->day <
204 datevar1->day) ? -1 :
205 (timevar2->hours >
206 timevar1->hours) ? 1 :
207 (timevar2->hours <
208 timevar1->hours) ? -1 :
209 (timevar2->minutes >
210 timevar1->minutes) ? 1 :
211 (timevar2->minutes <
212 timevar1->minutes) ? -1 :
213 (timevar2->seconds >
214 timevar1->seconds) ? 1 :
215 (timevar2->seconds < timevar1->seconds) ? -1 : 0;
216 }
217 return comp;
218}
219
220BOOL IsNewer(char *file1, char *file2)
221{
222 /* return TRUE if file2 is newer than file1 */
223
224 return (TestFDates(file1, file2, NULL, NULL, NULL, NULL) > 0);
225}
226
227#if 0 // JBS 11 Sep 08
228BOOL IsDesktop(HAB hab, HWND hwnd)
229{
230 HWND hwndDesktop;
231
232 if (hwnd == HWND_DESKTOP)
233 return TRUE;
234 hwndDesktop = WinQueryDesktopWindow(hab, NULLHANDLE);
235 if (hwnd == hwndDesktop)
236 return TRUE;
237 return FALSE;
238}
239#endif
240
241BOOL ParentIsDesktop(HWND hwnd, HWND hwndParent)
242{
243 HWND hwndDesktop;
244 BOOL ret = FALSE;
245
246 if (!hwndParent)
247 hwndParent = WinQueryWindow(hwnd, QW_PARENT);
248 if (hwndParent == HWND_DESKTOP)
249 ret = TRUE;
250 else {
251 hwndDesktop = WinQueryDesktopWindow(WinQueryAnchorBlock(hwnd), (HWND) 0);
252 if (hwndDesktop == hwndParent)
253 ret = TRUE;
254 }
255 return ret;
256}
257
258/** CheckDrive
259 * @param chDrive drive letter
260 * @param pszFileSystem pointer to buffer to return file system type or NULL
261 * @param pulType pointer to long word to return drive flags or NULL
262 * @returns removability flag, 1 = removable, 0 = not removable, -1 = error
263 */
264
265INT CheckDrive(CHAR chDrive, CHAR * pszFileSystem, ULONG * pulType)
266{
267 CHAR szPath[4];
268 VOID *pvBuffer = NULL;
269 CHAR *pfsn;
270 CHAR *pfsd;
271 ULONG clBufferSize;
272 APIRET rc;
273 ULONG ulAction;
274 ULONG clParmBytes;
275 ULONG clDataBytes;
276 HFILE hDev;
277 EASIZEBUF easize = {0};
278 ULONG ulDataLen = sizeof(EASIZEBUF);
279 ULONG ulParmLen = 0;
280
281# pragma pack(1)
282 struct
283 {
284 BYTE Cmd;
285 BYTE Unit;
286 }
287 parmPkt =
288 {
289 0, 0};
290# define BPB_REMOVABLE_MEDIA 0x08 // 3 - Media is removable
291 struct
292 {
293 BIOSPARAMETERBLOCK bpb;
294 USHORT cCylinders; // Documented but not implemented
295 BYTE bDeviceType; // Documented but not implemented
296 USHORT fsDeviceAttr; // Documented but not implemented
297 }
298 dataPkt;
299
300# pragma pack()
301 BYTE NonRemovable;
302 PFSQBUFFER2 pfsq;
303
304 if (pszFileSystem)
305 *pszFileSystem = 0;
306
307 if (pulType)
308 *pulType = 0;
309
310# define BUFFER_BYTES 8192
311 if (xDosAllocMem(&pvBuffer, BUFFER_BYTES,
312 PAG_COMMIT | PAG_READ | PAG_WRITE, 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
476INT IsFile(PCSZ filename)
477{
478 /* returns: -1 (error), 0 (is a directory), or 1 (is a file) */
479
480 FILESTATUS3 fsa;
481 APIRET ret;
482
483 if (filename && *filename) {
484 DosError(FERR_DISABLEHARDERR);
485 ret = DosQueryPathInfo((CHAR *) filename, FIL_STANDARD, &fsa, (ULONG) sizeof(fsa));
486 if (!ret)
487 return ((fsa.attrFile & FILE_DIRECTORY) == 0);
488 else if (IsValidDrive(*filename) && IsRoot(filename))
489 return 0;
490 }
491 return -1; /* error; doesn't exist or can't read or null filename */
492}
493
494BOOL IsFullName(CHAR * filename)
495{
496 return (filename) ?
497 (isalpha(*filename) && filename[1] == ':' && filename[2] == '\\') : 0;
498}
499
500BOOL IsRoot(PCSZ filename)
501{
502 return (filename && isalpha(*filename) && filename[1] == ':' &&
503 filename[2] == '\\' && !filename[3]);
504}
505
506BOOL IsValidDir(CHAR * path)
507{
508 CHAR fullname[CCHMAXPATH];
509 FILESTATUS3 fs;
510
511 if (path) {
512 DosError(FERR_DISABLEHARDERR);
513 if (!DosQueryPathInfo(path,
514 FIL_QUERYFULLNAME, fullname, sizeof(fullname))) {
515 if (IsValidDrive(*fullname)) {
516 if (!IsRoot(fullname)) {
517 DosError(FERR_DISABLEHARDERR);
518 if (!DosQueryPathInfo(fullname,
519 FIL_STANDARD,
520 &fs,
521 sizeof(fs)) && (fs.attrFile & FILE_DIRECTORY))
522 return TRUE;
523 }
524 else
525 return TRUE;
526 }
527 }
528 }
529 return FALSE;
530}
531
532BOOL IsValidDrive(CHAR drive)
533{
534 CHAR Path[] = " :", Buffer[256];
535 APIRET Status;
536 ULONG Size;
537 ULONG ulDriveNum, ulDriveMap;
538
539 if (!isalpha(drive) ||
540 (driveflags[toupper(drive) - 'A'] & (DRIVE_IGNORE | DRIVE_INVALID)))
541 return FALSE;
542 DosError(FERR_DISABLEHARDERR);
543 Status = DosQCurDisk(&ulDriveNum, &ulDriveMap);
544 if (!Status) {
545 if (!(ulDriveMap & (1 << (ULONG) (toupper(drive) - 'A'))))
546 return FALSE;
547 Path[0] = toupper(drive);
548 Size = sizeof(Buffer);
549 DosError(FERR_DISABLEHARDERR);
550 Status = DosQueryFSAttach(Path,
551 0,
552 FSAIL_QUERYNAME, (PFSQBUFFER2) Buffer, &Size);
553 }
554 return (Status == 0);
555}
556
557//=== MakeValidDir() build valid directory name ===
558
559CHAR *MakeValidDir(CHAR * path)
560{
561 ULONG ulDrv;
562 CHAR *p;
563 FILESTATUS3 fs;
564 APIRET rc;
565
566 if (!MakeFullName(path)) {
567 if (IsValidDrive(*path)) {
568 // Passed name is valid - trim to directory
569 for (;;) {
570 if (IsRoot(path))
571 return path;
572 DosError(FERR_DISABLEHARDERR);
573 rc = DosQueryPathInfo(path, FIL_STANDARD, &fs, sizeof(fs));
574 if (!rc && (fs.attrFile & FILE_DIRECTORY))
575 return path;
576 p = strrchr(path, '\\');
577 if (p) {
578 if (p < path + 3)
579 p++;
580 *p = 0;
581 }
582 else
583 break;
584 }
585 }
586 }
587 // Fall back to boot drive
588 DosError(FERR_DISABLEHARDERR);
589 if (!DosQuerySysInfo(QSV_BOOT_DRIVE, QSV_BOOT_DRIVE, &ulDrv, sizeof(ulDrv))) {
590 ulDrv += '@';
591 if (ulDrv < 'C')
592 ulDrv = 'C';
593 strcpy(path, " :\\");
594 *path = (CHAR) ulDrv;
595 }
596 else
597 strcpy(path, pFM2SaveDirectory); // Fall back to fm3.ini drive or current dir - should never occur
598 return path;
599}
600
601BOOL IsExecutable(CHAR *filename)
602{
603 register CHAR *p;
604 APIRET ret;
605 ULONG apptype;
606
607 if (filename) {
608 DosError(FERR_DISABLEHARDERR);
609 p = strrchr(filename, '.');
610 if (p)
611 ret = DosQueryAppType(filename, &apptype);
612 else {
613
614 char fname[CCHMAXPATH + 2];
615
616 strcpy(fname, filename);
617 strcat(fname, ".");
618 ret = DosQueryAppType(fname, &apptype);
619 }
620 if (apptype & (FAPPTYP_DLL |
621 FAPPTYP_PHYSDRV |
622 FAPPTYP_VIRTDRV |
623 FAPPTYP_PROTDLL))
624 return FALSE;
625 if (apptype == 0x000b && (!p ||
626 (stricmp(p, PCSZ_DOTEXE) &&
627 stricmp(p, PCSZ_DOTCOM) &&
628 stricmp(p, PCSZ_DOTCMD) &&
629 stricmp(p, PCSZ_DOTBAT) &&
630 stricmp(p, PCSZ_DOTBTM))))
631 return FALSE;
632 if (!fProtectOnly) {
633 if ((!ret && (!apptype ||
634 (apptype &
635 (FAPPTYP_NOTWINDOWCOMPAT |
636 FAPPTYP_WINDOWCOMPAT |
637 FAPPTYP_WINDOWAPI |
638 FAPPTYP_BOUND |
639 FAPPTYP_DOS |
640 FAPPTYP_WINDOWSREAL |
641 FAPPTYP_WINDOWSPROT |
642 FAPPTYP_32BIT |
643 FAPPTYP_WINDOWSPROT31)))) ||
644 (p && (!stricmp(p, PCSZ_DOTCMD) || !stricmp(p, PCSZ_DOTBAT) || !stricmp(p, PCSZ_DOTBTM))))
645 return TRUE;
646 }
647 else if ((!ret && (!apptype ||
648 (apptype &
649 (FAPPTYP_NOTWINDOWCOMPAT |
650 FAPPTYP_WINDOWCOMPAT |
651 FAPPTYP_WINDOWAPI |
652 FAPPTYP_BOUND |
653 FAPPTYP_32BIT)))) ||
654 (p && (!stricmp(p, PCSZ_DOTCMD) || !stricmp(p, PCSZ_DOTBTM))))
655 return TRUE;
656 if (fProtectOnly && (apptype &
657 (FAPPTYP_DOS |
658 FAPPTYP_WINDOWSREAL |
659 FAPPTYP_WINDOWSPROT |
660 FAPPTYP_WINDOWSPROT31)) &&
661 (p && (!stricmp(p, PCSZ_DOTEXE) || !stricmp(p, PCSZ_DOTCOM) ||
662 !stricmp(p, PCSZ_DOTBAT))))
663 saymsg(MB_OK,
664 HWND_DESKTOP,
665 NullStr,
666 GetPString(IDS_NOTPROTECTONLYEXE),
667 filename);
668 }
669 return FALSE;
670}
671
672VOID ArgDriveFlags(INT argc, CHAR ** argv)
673{
674 INT x;
675
676 for (x = 1; x < argc; x++) {
677 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_IGNORE;
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_NOPRESCAN;
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_NOSTATS;
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_NOLOADICONS;
710 p++;
711 }
712 }
713 else if (*argv[x] == '-' && isalpha(argv[x][1])) {
714
715 CHAR *p = &argv[x][1];
716
717 while (isalpha(*p)) {
718 driveflags[toupper(*p) - 'A'] |= DRIVE_NOLOADSUBJS;
719 p++;
720 }
721 }
722 else if (*argv[x] == '\'' && isalpha(argv[x][1])) {
723
724 CHAR *p = &argv[x][1];
725
726 while (isalpha(*p)) {
727 driveflags[toupper(*p) - 'A'] |= DRIVE_NOLOADLONGS;
728 p++;
729 }
730 }
731 }
732}
733
734VOID DriveFlagsOne(INT x, CHAR *FileSystem, VOID *volser)
735{
736 INT removable;
737 CHAR szDrive[] = " :\\";
738 ULONG drvtype;
739
740 *szDrive = (CHAR) (x + 'A');
741 *FileSystem = 0;
742 drvtype = 0;
743 removable = CheckDrive(*szDrive, FileSystem, &drvtype);
744 strupr(FileSystem);
745 driveserial[x] = -1;
746 driveflags[x] &= (DRIVE_IGNORE | DRIVE_NOPRESCAN | DRIVE_NOLOADICONS |
747 DRIVE_NOLOADSUBJS | DRIVE_NOLOADLONGS |
748 DRIVE_INCLUDEFILES | DRIVE_SLOW | DRIVE_NOSTATS |
749 DRIVE_WRITEVERIFYOFF);
750 if (removable != -1) {
751 if (!volser) {
752 struct
753 {
754 ULONG serial;
755 CHAR volumelength;
756 CHAR volumelabel[CCHMAXPATH];
757 }
758 volserl;
759
760 DosError(FERR_DISABLEHARDERR);
761 if (!DosQueryFSInfo((ULONG) x + 1, FSIL_VOLSER, &volserl, sizeof(volserl)))
762 driveserial[x] = volserl.serial;
763 else
764 DosError(FERR_DISABLEHARDERR);
765 }
766 else {
767 DosError(FERR_DISABLEHARDERR);
768 if (DosQueryFSInfo((ULONG) x + 1, FSIL_VOLSER, volser,
769 sizeof(ULONG) + sizeof(CHAR) + CCHMAXPATH))
770 DosError(FERR_DISABLEHARDERR);
771 }
772 }
773 else
774 driveflags[x] |= DRIVE_INVALID;
775 driveflags[x] |= ((removable == -1 || removable == 1) ? DRIVE_REMOVABLE : 0);
776 if (drvtype & DRIVE_REMOTE)
777 driveflags[x] |= DRIVE_REMOTE;
778 if (drvtype & DRIVE_NOEASUPPORT)
779 driveflags[x] |= DRIVE_NOEASUPPORT;
780 if(!strcmp(FileSystem,NDFS32)){
781 driveflags[x] |= DRIVE_VIRTUAL;
782 driveflags[x] &= (~DRIVE_REMOTE);
783 }
784 if(!strcmp(FileSystem,RAMFS)){
785 driveflags[x] |= DRIVE_RAMDISK;
786 driveflags[x] &= (~DRIVE_REMOTE);
787 }
788 if(!strcmp(FileSystem,NTFS))
789 driveflags[x] |= DRIVE_NOTWRITEABLE;
790 if (strcmp(FileSystem, HPFS) &&
791 strcmp(FileSystem, CDFS) &&
792 strcmp(FileSystem, ISOFS) &&
793 strcmp(FileSystem, JFS) &&
794 strcmp(FileSystem, LAN) &&
795 strcmp(FileSystem, RAMFS) &&
796 strcmp(FileSystem, FAT32) &&
797 strcmp(FileSystem, NTFS) &&
798 strcmp(FileSystem, NDFS32) &&
799 strcmp(FileSystem, HPFS386)) {
800 driveflags[x] |= DRIVE_NOLONGNAMES;
801 }
802 if ((!strcmp(FileSystem, HPFS) ||
803 !strcmp(FileSystem, FAT) ||
804 !strcmp(FileSystem, JFS) ||
805 !strcmp(FileSystem, FAT32) ||
806 !strcmp(FileSystem, NTFS) ||
807 !strcmp(FileSystem, HPFS386)) && ~driveflags[x] & DRIVE_REMOVABLE) {
808 driveflags[x] |= DRIVE_LOCALHD;
809 }
810 if (!strcmp(FileSystem, CDFS) || !strcmp(FileSystem, ISOFS)) {
811 driveflags[x] |= (DRIVE_REMOVABLE | DRIVE_NOTWRITEABLE | DRIVE_CDROM);
812 }
813 if (!strcmp(FileSystem, CBSIFS)) {
814 driveflags[x] |= DRIVE_ZIPSTREAM;
815 driveflags[x] &= (~DRIVE_REMOTE);
816 if (drvtype & DRIVE_REMOVABLE)
817 driveflags[x] |= DRIVE_REMOVABLE;
818 if (!(drvtype & DRIVE_NOLONGNAMES))
819 driveflags[x] &= (~DRIVE_NOLONGNAMES);
820 }
821}
822
823VOID FillInDriveFlags(VOID * dummy)
824{
825 ULONG ulDriveNum, ulDriveMap, size;
826 register INT x;
827
828 for (x = 0; x < 26; x++)
829 driveflags[x] &= (DRIVE_IGNORE | DRIVE_NOPRESCAN | DRIVE_NOLOADICONS |
830 DRIVE_NOLOADSUBJS | DRIVE_NOLOADLONGS |
831 DRIVE_INCLUDEFILES | DRIVE_SLOW | DRIVE_NOSTATS |
832 DRIVE_WRITEVERIFYOFF);
833 memset(driveserial, -1, sizeof(driveserial));
834 DosError(FERR_DISABLEHARDERR);
835 DosQCurDisk(&ulDriveNum, &ulDriveMap);
836 for (x = 0; x < 26; x++) {
837 if (ulDriveMap & (1 << x) && !(driveflags[x] & DRIVE_IGNORE)) {
838 {
839 ULONG flags = 0, size = sizeof(ULONG);
840 CHAR FlagKey[80];
841
842 sprintf(FlagKey, "%c.DriveFlags", (CHAR) (x + 'A'));
843 if (PrfQueryProfileData(fmprof, appname, FlagKey, &flags, &size) &&
844 size == sizeof(ULONG))
845 driveflags[x] |= flags;
846 }
847
848 if (x > 1) {
849 if (!(driveflags[x] & DRIVE_NOPRESCAN)) {
850 CHAR FileSystem[CCHMAXPATH];
851 DriveFlagsOne(x, FileSystem, NULL);
852 }
853 else
854 driveserial[x] = -1;
855 }
856 else {
857 driveflags[x] |= (DRIVE_REMOVABLE | DRIVE_NOLONGNAMES);
858 driveserial[x] = -1;
859 }
860 }
861 else if (!(ulDriveMap & (1 << x)))
862 driveflags[x] |= DRIVE_INVALID;
863 }
864 {
865 ULONG startdrive = 3L;
866
867 DosError(FERR_DISABLEHARDERR);
868 DosQuerySysInfo(QSV_BOOT_DRIVE, QSV_BOOT_DRIVE,
869 (PVOID) & startdrive, (ULONG) sizeof(ULONG));
870 if (startdrive)
871 driveflags[startdrive - 1] |= DRIVE_BOOT;
872 }
873 {
874 INT x;
875 CHAR Key[80];
876
877 for (x = 2; x < 26; x++) {
878 sprintf(Key, "%c.VerifyOffChecked", (CHAR) (x + 'A'));
879 size = sizeof(BOOL);
880 PrfQueryProfileData(fmprof, appname, Key, &fVerifyOffChecked[x], &size);
881 if (!fVerifyOffChecked[x]) {
882 if (driveflags[x] & DRIVE_REMOVABLE)
883 driveflags[x] |= DRIVE_WRITEVERIFYOFF;
884 if (!(driveflags[x] & DRIVE_INVALID)) {
885 fVerifyOffChecked[x] = TRUE;
886 PrfWriteProfileData(fmprof, appname, Key, &fVerifyOffChecked[x], sizeof(BOOL));
887 }
888 }
889 }
890 }
891}
892
893CHAR *assign_ignores(CHAR * s)
894{
895 register INT x;
896 register CHAR *p, *pp;
897
898 *s = '/';
899 s[1] = 0;
900 p = s + 1;
901 if (s) {
902 for (x = 0; x < 26; x++) {
903 if ((driveflags[x] & DRIVE_IGNORE) != 0) {
904 *p = (CHAR) x + 'A';
905 p++;
906 *p = 0;
907 }
908 }
909 }
910 if (!s[1]) {
911 *s = 0;
912 pp = s;
913 }
914 else {
915 pp = &s[strlen(s)];
916 *pp = ' ';
917 pp++;
918 }
919 *pp = ';';
920 pp[1] = 0;
921 p = pp + 1;
922 if (pp) {
923 for (x = 0; x < 26; x++) {
924 if ((driveflags[x] & DRIVE_NOPRESCAN) != 0) {
925 *p = (CHAR) x + 'A';
926 p++;
927 *p = 0;
928 }
929 }
930 }
931 if (!pp[1])
932 *pp = 0;
933 pp = &s[strlen(s)];
934 *pp = ' ';
935 pp++;
936 *pp = ',';
937 pp[1] = 0;
938 p = pp + 1;
939 if (pp) {
940 for (x = 0; x < 26; x++) {
941 if ((driveflags[x] & DRIVE_NOLOADICONS) != 0) {
942 *p = (CHAR) x + 'A';
943 p++;
944 *p = 0;
945 }
946 }
947 }
948 if (!pp[1])
949 *pp = 0;
950 pp = &s[strlen(s)];
951 *pp = ' ';
952 pp++;
953 *pp = '-';
954 pp[1] = 0;
955 p = pp + 1;
956 if (pp) {
957 for (x = 0; x < 26; x++) {
958 if ((driveflags[x] & DRIVE_NOLOADSUBJS) != 0) {
959 *p = (CHAR) x + 'A';
960 p++;
961 *p = 0;
962 }
963 }
964 }
965 if (!pp[1])
966 *pp = 0;
967 pp = &s[strlen(s)];
968 *pp = ' ';
969 pp++;
970 *pp = '`';
971 pp[1] = 0;
972 p = pp + 1;
973 if (pp) {
974 for (x = 0; x < 26; x++) {
975 if ((driveflags[x] & DRIVE_NOSTATS) != 0) {
976 *p = (CHAR) x + 'A';
977 p++;
978 *p = 0;
979 }
980 }
981 }
982 if (!pp[1])
983 *pp = 0;
984 pp = &s[strlen(s)];
985 *pp = ' ';
986 pp++;
987 *pp = '\'';
988 pp[1] = 0;
989 p = pp + 1;
990 if (pp) {
991 for (x = 0; x < 26; x++) {
992 if ((driveflags[x] & DRIVE_NOLOADLONGS) != 0) {
993 *p = (CHAR) x + 'A';
994 p++;
995 *p = 0;
996 }
997 }
998 }
999 if (!pp[1])
1000 *pp = 0;
1001 bstrip(s);
1002 return s;
1003}
1004
1005BOOL needs_quoting(PCSZ f)
1006{
1007 register CHAR *p = " &|<>";
1008
1009 while (*p) {
1010 if (strchr(f, *p))
1011 return TRUE;
1012 p++;
1013 }
1014 return FALSE;
1015}
1016
1017BOOL IsBinary(register CHAR * str, ULONG len)
1018{
1019 register ULONG x = 0;
1020
1021 if (str) {
1022 while (x < len) {
1023 if ((UINT) str[x] < ' ' && str[x] != '\r' && str[x] != '\n' && str[x] != '\t'
1024 && str[x] != '\x1b' && str[x] != '\x1a' && str[x] != '\x07'
1025 && str[x] != '\x0c') {
1026 return TRUE;
1027 }
1028 x++;
1029 }
1030 }
1031 return FALSE;
1032}
1033
1034BOOL TestBinary(CHAR * filename)
1035{
1036 HFILE handle;
1037 ULONG ulAction;
1038 ULONG len;
1039 APIRET rc;
1040 CHAR buff[4096]; // 06 Oct 07 SHL protect against NTFS defect
1041
1042 if (filename) {
1043 if (!DosOpen(filename, &handle, &ulAction, 0, 0,
1044 OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS,
1045 OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_NOINHERIT |
1046 OPEN_FLAGS_SEQUENTIAL | OPEN_SHARE_DENYNONE |
1047 OPEN_ACCESS_READONLY, 0)) {
1048 len = 512;
1049 rc = DosRead(handle, buff, len, &len);
1050 DosClose(handle);
1051 if (!rc && len)
1052 return IsBinary(buff, len);
1053 }
1054 }
1055 return FALSE;
1056}
1057
1058#if 0 // JBS 11 Sep 08
1059char *IsVowel(char a)
1060{
1061 return (strchr("aeiouAEIOU", a) != NULL) ? "n" : NullStr;
1062}
1063#endif
1064
1065VOID GetDesktopName(CHAR * objectpath, ULONG size)
1066{
1067 PFN WQDPath;
1068 HMODULE hmod = 0;
1069 APIRET rc;
1070 ULONG startdrive = 3;
1071 CHAR objerr[CCHMAXPATH];
1072
1073 if (!objectpath) {
1074 Runtime_Error(pszSrcFile, __LINE__, "null pointer");
1075 return;
1076 }
1077 *objectpath = 0;
1078 if (OS2ver[0] > 20 || (OS2ver[0] == 20 && OS2ver[1] >= 30)) {
1079 /*
1080 * if running under warp, we can get the desktop name
1081 * this way...
1082 */
1083 rc = DosLoadModule(objerr, sizeof(objerr), "PMWP", &hmod);
1084 if (!rc) {
1085 rc = DosQueryProcAddr(hmod, 262, NULL, &WQDPath);
1086 if (!rc)
1087 WQDPath(objectpath, size);
1088 DosFreeModule(hmod);
1089 }
1090 }
1091 if (!*objectpath) {
1092 // Fall back to INI content
1093 if (!PrfQueryProfileString(HINI_SYSTEMPROFILE,
1094 "FolderWorkareaRunningObjects",
1095 NULL,
1096 "\0",
1097 (PVOID) objectpath, sizeof(objectpath))) {
1098 Win_Error(HWND_DESKTOP, HWND_DESKTOP, pszSrcFile, __LINE__,
1099 PCSZ_PRFQUERYPROFILESTRING);
1100 *objectpath = 0;
1101 }
1102 else if (!*objectpath || IsFile(objectpath)) {
1103 Runtime_Error(pszSrcFile, __LINE__, "bad FolderWorkareaRunningObjects");
1104 *objectpath = 0;
1105 }
1106 if (!*objectpath) {
1107 // Fall back
1108 DosError(FERR_DISABLEHARDERR);
1109 DosQuerySysInfo(QSV_BOOT_DRIVE, QSV_BOOT_DRIVE,
1110 (PVOID) & startdrive, (ULONG) sizeof(ULONG));
1111 sprintf(objectpath, GetPString(IDS_PATHTODESKTOP), ((CHAR) startdrive) + '@');
1112 }
1113 }
1114}
1115
1116#pragma alloc_text(VALID,CheckDrive,IsRoot,IsFile,IsFullName,needsquoting)
1117#pragma alloc_text(VALID,IsValidDir,IsValidDrive,MakeValidDir,IsVowel)
1118#pragma alloc_text(VALID,IsFileSame,IsNewer,TestFDates,TestCDates,RootName,MakeFullName)
1119#pragma alloc_text(VALID,IsExecutable,IsBinary,IsDesktop,ParentIsDesktop)
1120#pragma alloc_text(FILLFLAGS,FillInDriveFlags,assign_ignores)
1121#pragma alloc_text(FILLFLAGS,ArgDriveFlags,DriveFlagsOne)
1122#pragma alloc_text(FINDDESK,GetDesktopName)
Note: See TracBrowser for help on using the repository browser.