source: trunk/dll/valid.c@ 1498

Last change on this file since 1498 was 1498, checked in by Gregg Young, 16 years ago

Changes to get FM2 to compile with the latest watcom 1.9 beta (mostly type casts of CHAR CONSTANT * to CHAR *). Changes to get the environment settings working everywhere again (broken by the change that moved commands to the INI); Added an environment size variable (set to 2048 which was the largest I found hard coded). Still need to find everywhere the environment size is set and use this variable.

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