source: trunk/dll/valid.c@ 1444

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

Rework of drivebar to rescan all drives and refresh media buttons and menu items grey out inappropriate menu items. Streamline Tree scan code and use semaphores to serialize access. Add NOEASUPPORT and LOCALHD driveflag; .LONGNAME usage fixes; (Tickets 377-386)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 28.5 KB
Line 
1
2/***********************************************************************
3
4 $Id: valid.c 1444 2009-07-22 23:24:23Z gyoung $
5
6 File name manipulation routines
7
8 Copyright (c) 1993, 1998 M. Kimes
9 Copyright (c) 2002, 2009 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 xDoxAlloc... 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
43***********************************************************************/
44
45#include <string.h>
46#include <ctype.h>
47
48#define INCL_DOS
49#define INCL_WIN
50#define INCL_DOSDEVIOCTL // DosDevIOCtl
51#define INCL_LONGLONG
52
53#include "fm3dll.h"
54#include "treecnr.h" // Data declaration(s)
55#include "info.h" // Data declaration(s)
56#include "notebook.h" // Data declaration(s)
57#include "fm3str.h"
58#include "errutil.h" // Dos_Error...
59#include "strutil.h" // GetPString
60#include "valid.h"
61#include "dirs.h" // save_dir2
62#include "strips.h" // bstrip
63#include "init.h" // GetTidForWindow
64#include "wrappers.h" // xDosAllocMem
65
66
67//static BOOL IsDesktop(HAB hab, HWND hwnd);
68//static BOOL IsFileSame(CHAR * filename1, CHAR * filename2);
69//static char *IsVowel(char a);
70
71// Data definitions
72static PSZ pszSrcFile = __FILE__;
73
74#pragma data_seg(GLOBAL2)
75PCSZ HPFS = "HPFS";
76PCSZ JFS = "JFS";
77PCSZ CDFS = "CDFS";
78PCSZ ISOFS = "ISOFS";
79PCSZ FAT32 = "FAT32";
80PCSZ HPFS386 = "HPFS386";
81PCSZ CBSIFS = "CBSIFS";
82PCSZ NDFS32 = "NDFS32";
83PCSZ RAMFS = "RAMFS";
84PCSZ NTFS = "NTFS";
85PCSZ LAN = "LAN";
86BOOL fVerifyOffChecked[26];
87
88APIRET MakeFullName(char *pszFileName)
89{
90 /* pszFileName must be CCHMAXPATH long minimum! */
91
92 char szPathName[CCHMAXPATH];
93 APIRET rc;
94
95 DosError(FERR_DISABLEHARDERR);
96 rc = DosQueryPathInfo(pszFileName,
97 FIL_QUERYFULLNAME, szPathName, sizeof(szPathName));
98 if (!rc)
99 strcpy(pszFileName, szPathName); // Pass back actual name
100 return rc;
101}
102
103char *RootName(char *filename)
104{
105 char *p = NULL, *pp;
106
107 // Return filename, strip path parts
108 // Return empty string when filename ends with backslash
109
110 if (filename) {
111 p = strrchr(filename, '\\');
112 pp = strrchr(filename, '/');
113 p = (p) ? (pp) ? (p > pp) ? p : pp : p : pp;
114 }
115 if (!p) /* name is itself a root */
116 p = filename;
117 else /* skip past backslash */
118 p++;
119 return p;
120}
121
122 /** TestFDate
123 * return 1 (file2 newer than file1),
124 * 0 (files same)
125 * or -1 (file1 newer than file2)
126 * Make the FILSTATUS pointers NULL if passing file names
127 * if the FILESTATUS information is already available it can be passed instead
128 * Make the files NULL if passing FILESTATUS buffers
129 */
130
131int TestFDates(char *file1, char *file2, FDATE *datevar1, FTIME *timevar1,
132 FDATE *datevar2, FTIME *timevar2)
133{
134 int comp = 0;
135 FILESTATUS3 fs3o, fs3n;
136
137 if (file1){
138 DosError(FERR_DISABLEHARDERR);
139 DosQueryPathInfo(file1, FIL_STANDARD, &fs3o, sizeof(fs3o));
140 datevar1 = &fs3o.fdateLastWrite;
141 timevar1 = &fs3o.ftimeLastWrite;
142 }
143 if (file2) {
144 DosError(FERR_DISABLEHARDERR);
145 DosQueryPathInfo(file2, FIL_STANDARD, &fs3n, sizeof(fs3n));
146 datevar2 = &fs3n.fdateLastWrite;
147 timevar2 = &fs3n.ftimeLastWrite;
148 }
149 if (&datevar1 && &datevar2 && &timevar1 && &timevar2) {
150 comp = (datevar2->year >
151 datevar1->year) ? 1 :
152 (datevar2->year <
153 datevar1->year) ? -1 :
154 (datevar2->month >
155 datevar1->month) ? 1 :
156 (datevar2->month <
157 datevar1->month) ? -1 :
158 (datevar2->day >
159 datevar1->day) ? 1 :
160 (datevar2->day <
161 datevar1->day) ? -1 :
162 (timevar2->hours >
163 timevar1->hours) ? 1 :
164 (timevar2->hours <
165 timevar1->hours) ? -1 :
166 (timevar2->minutes >
167 timevar1->minutes) ? 1 :
168 (timevar2->minutes <
169 timevar1->minutes) ? -1 :
170 (timevar2->twosecs >
171 timevar1->twosecs) ? 1 :
172 (timevar2->twosecs < timevar1->twosecs) ? -1 : 0;
173 }
174 return comp;
175}
176
177 /** TestCDate
178 * return 1 (file2 newer than file1),
179 * 0 (files same)
180 * or -1 (file1 newer than file2)
181 */
182
183int TestCDates(CDATE *datevar1, CTIME *timevar1,
184 CDATE *datevar2, CTIME *timevar2)
185{
186 int comp = 0;
187
188 if (&datevar1 && &datevar2 && &timevar1 && &timevar2) {
189 comp = (datevar2->year >
190 datevar1->year) ? 1 :
191 (datevar2->year <
192 datevar1->year) ? -1 :
193 (datevar2->month >
194 datevar1->month) ? 1 :
195 (datevar2->month <
196 datevar1->month) ? -1 :
197 (datevar2->day >
198 datevar1->day) ? 1 :
199 (datevar2->day <
200 datevar1->day) ? -1 :
201 (timevar2->hours >
202 timevar1->hours) ? 1 :
203 (timevar2->hours <
204 timevar1->hours) ? -1 :
205 (timevar2->minutes >
206 timevar1->minutes) ? 1 :
207 (timevar2->minutes <
208 timevar1->minutes) ? -1 :
209 (timevar2->seconds >
210 timevar1->seconds) ? 1 :
211 (timevar2->seconds < timevar1->seconds) ? -1 : 0;
212 }
213 return comp;
214}
215
216BOOL IsNewer(char *file1, char *file2)
217{
218 /* return TRUE if file2 is newer than file1 */
219
220 return (TestFDates(file1, file2, NULL, NULL, NULL, NULL) > 0);
221}
222
223#if 0 // JBS 11 Sep 08
224BOOL IsDesktop(HAB hab, HWND hwnd)
225{
226 HWND hwndDesktop;
227
228 if (hwnd == HWND_DESKTOP)
229 return TRUE;
230 hwndDesktop = WinQueryDesktopWindow(hab, NULLHANDLE);
231 if (hwnd == hwndDesktop)
232 return TRUE;
233 return FALSE;
234}
235#endif
236
237BOOL ParentIsDesktop(HWND hwnd, HWND hwndParent)
238{
239 HWND hwndDesktop;
240 BOOL ret = FALSE;
241
242 if (!hwndParent)
243 hwndParent = WinQueryWindow(hwnd, QW_PARENT);
244 if (hwndParent == HWND_DESKTOP)
245 ret = TRUE;
246 else {
247 hwndDesktop = WinQueryDesktopWindow(WinQueryAnchorBlock(hwnd), (HWND) 0);
248 if (hwndDesktop == hwndParent)
249 ret = TRUE;
250 }
251 return ret;
252}
253
254/** CheckDrive
255 * @param chDrive drive letter
256 * @param pszFileSystem pointer to buffer to return file system type or NULL
257 * @param pulType pointer to long word to return drive flags or NULL
258 * @returns removability flag, 1 = removable, 0 = not removable, -1 = error
259 */
260
261INT CheckDrive(CHAR chDrive, CHAR * pszFileSystem, ULONG * pulType)
262{
263 CHAR szPath[4];
264 VOID *pvBuffer = NULL;
265 CHAR *pfsn;
266 CHAR *pfsd;
267 ULONG clBufferSize;
268 APIRET rc;
269 ULONG ulAction;
270 ULONG clParmBytes;
271 ULONG clDataBytes;
272 HFILE hDev;
273 EASIZEBUF easize = {0};
274 ULONG ulDataLen = sizeof(EASIZEBUF);
275 ULONG ulParmLen = 0;
276
277# pragma pack(1)
278 struct
279 {
280 BYTE Cmd;
281 BYTE Unit;
282 }
283 parmPkt =
284 {
285 0, 0};
286# define BPB_REMOVABLE_MEDIA 0x08 // 3 - Media is removable
287 struct
288 {
289 BIOSPARAMETERBLOCK bpb;
290 USHORT cCylinders; // Documented but not implemented
291 BYTE bDeviceType; // Documented but not implemented
292 USHORT fsDeviceAttr; // Documented but not implemented
293 }
294 dataPkt;
295
296# pragma pack()
297 BYTE NonRemovable;
298 PFSQBUFFER2 pfsq;
299
300 if (pszFileSystem)
301 *pszFileSystem = 0;
302
303 if (pulType)
304 *pulType = 0;
305
306# define BUFFER_BYTES 8192
307 rc = xDosAllocMem(&pvBuffer, BUFFER_BYTES,
308 PAG_COMMIT | PAG_READ | PAG_WRITE, pszSrcFile, __LINE__);
309 if (rc) {
310 Dos_Error(MB_CANCEL, rc, HWND_DESKTOP, pszSrcFile, __LINE__,
311 GetPString(IDS_OUTOFMEMORY));
312 return -1; // Say failed
313 }
314
315 szPath[0] = chDrive;
316 szPath[1] = ':';
317 szPath[2] = 0;
318 clBufferSize = BUFFER_BYTES;
319 DosError(FERR_DISABLEHARDERR);
320 rc = DosQueryFSAttach(szPath, 0, FSAIL_QUERYNAME,
321 (PFSQBUFFER2) pvBuffer, &clBufferSize);
322 if (rc) {
323 /* can't get any info at all */
324 DosFreeMem(pvBuffer);
325 DosError(FERR_DISABLEHARDERR);
326 return -1; // Say failed
327 }
328
329 pfsq = (PFSQBUFFER2) pvBuffer;
330 pfsn = (PCHAR)(pfsq->szName) + pfsq->cbName + 1;
331 pfsd = pfsn + pfsq->cbFSDName + 1;
332 strupr(pfsn);
333
334 if (pszFileSystem) {
335 strncpy(pszFileSystem, pfsn, CCHMAXPATH);
336 pszFileSystem[CCHMAXPATH - 1] = 0;
337 }
338 szPath[2] = '\\';
339 szPath[3] = 0;
340 DosFSCtl(&easize, sizeof(EASIZEBUF), &ulDataLen, NULL, ulParmLen,
341 &ulParmLen, FSCTL_MAX_EASIZE, szPath, -1, FSCTL_PATHNAME);
342 //DbgMsg(pszSrcFile, __LINE__, "%i %i %s %s", easize.cbMaxEASize, easize.cbMaxEAListSize, szPath, pfsn);
343 szPath[2] = 0;
344 if (pulType && easize.cbMaxEASize == 0)
345 *pulType |= DRIVE_NOEASUPPORT;
346 if (pulType && (!strcmp(pfsn, CDFS) || !strcmp(pfsn, ISOFS)))
347 *pulType |= DRIVE_NOTWRITEABLE | DRIVE_CDROM | DRIVE_REMOVABLE;
348 if (pulType && !strcmp(pfsn, NTFS))
349 *pulType |= DRIVE_NOTWRITEABLE;
350 if (pulType && !strcmp(pfsn, NDFS32)){
351 *pulType |= DRIVE_VIRTUAL;
352 }
353 if (pulType && !strcmp(pfsn, RAMFS)){
354 *pulType |= DRIVE_RAMDISK;
355 }
356 if (((PFSQBUFFER2) pvBuffer)->iType == FSAT_REMOTEDRV) {
357 if (pulType)
358 *pulType |= DRIVE_REMOTE;
359
360 if (pulType && !strcmp(pfsn, CBSIFS)) {
361 *pulType |= DRIVE_ZIPSTREAM;
362 *pulType &= ~DRIVE_REMOTE;
363 *pulType |= DRIVE_NOLONGNAMES;
364 if (pfsq->cbFSAData) {
365 ULONG FType;
366
367 if (CheckDrive(*pfsd, NULL, &FType) != -1) {
368 if (FType & DRIVE_REMOVABLE)
369 *pulType |= DRIVE_REMOVABLE;
370 if (~FType & DRIVE_NOLONGNAMES)
371 *pulType &= ~DRIVE_NOLONGNAMES;
372 }
373
374 }
375 }
376 if (pulType &&
377 (!strcmp(pfsn, LAN) ||
378 !strcmp(pfsn, RAMFS) ||
379 !strcmp(pfsn, NDFS32))) {
380 *pulType &= ~DRIVE_NOLONGNAMES;
381 }
382
383 DosFreeMem(pvBuffer);
384 return 0; // Remotes are non-removable
385 }
386
387 // Local drive
388 if (strcmp(pfsn, HPFS) &&
389 strcmp(pfsn, CDFS) &&
390 strcmp(pfsn, ISOFS) &&
391 strcmp(pfsn, JFS) &&
392 strcmp(pfsn, FAT32) &&
393 strcmp(pfsn, NTFS) &&
394 strcmp(pfsn, HPFS386)) {
395 if (pulType)
396 (*pulType) |= DRIVE_NOLONGNAMES; // Others can not have long names
397 }
398
399 DosError(FERR_DISABLEHARDERR);
400 rc = DosOpen(szPath, &hDev, &ulAction, 0, 0, FILE_OPEN,
401 OPEN_ACCESS_READONLY | OPEN_SHARE_DENYNONE |
402 OPEN_FLAGS_DASD | OPEN_FLAGS_FAIL_ON_ERROR, 0);
403 if (rc) {
404 DosError(FERR_DISABLEHARDERR);
405 if (pulType)
406 *pulType |= DRIVE_REMOVABLE; // Assume removable if can not access
407 DosFreeMem(pvBuffer);
408 return 1; // Say removable
409 }
410
411 clParmBytes = sizeof(parmPkt.Cmd);
412 clDataBytes = sizeof(NonRemovable);
413 NonRemovable = 1; // Preset as non removable
414 DosError(FERR_DISABLEHARDERR);
415 rc = DosDevIOCtl(hDev, IOCTL_DISK, DSK_BLOCKREMOVABLE, &parmPkt.Cmd, /* Address of the command-specific argument list. */
416 sizeof(parmPkt.Cmd), /* Length, in bytes, of pParams. */
417 &clParmBytes, /* Pointer to the length of parameters. */
418 &NonRemovable, /* Address of the data area. */
419 sizeof(NonRemovable), /* Length, in bytes, of pData. */
420 &clDataBytes); /* Pointer to the length of data. */
421
422 if (!rc && NonRemovable) {
423 // Could be USB so check BPB flags
424 clParmBytes = sizeof(parmPkt.Cmd);
425 clDataBytes = sizeof(dataPkt);
426 memset(&dataPkt, 0xff, sizeof(dataPkt));
427 DosError(FERR_DISABLEHARDERR);
428 rc = DosDevIOCtl(hDev, IOCTL_DISK, DSK_GETDEVICEPARAMS, &parmPkt.Cmd, /* Address of the command-specific argument list. */
429 sizeof(parmPkt.Cmd), /* Length, in bytes, of pParams. */
430 &clParmBytes, /* Pointer to the length of parameters. */
431 &dataPkt, /* Address of the data area. */
432 sizeof(dataPkt), /* Length, in bytes, of pData. */
433 &clDataBytes); /* Pointer to the length of data. */
434
435 if (!rc && (dataPkt.bpb.fsDeviceAttr & BPB_REMOVABLE_MEDIA))
436 NonRemovable = 0;
437 }
438
439 DosClose(hDev);
440
441 if (!NonRemovable && pulType)
442 *pulType |= DRIVE_REMOVABLE;
443
444 DosFreeMem(pvBuffer);
445
446 return NonRemovable ? 0 : 1;
447}
448
449#if 0 // JBS 11 Sep 08
450BOOL IsFileSame(CHAR * filename1, CHAR * filename2)
451{
452 /* returns: -1 (error), 0 (is a directory), or 1 (is a file) */
453
454 FILESTATUS3L fsa1, fsa2;
455 APIRET ret;
456
457 if (filename1 && filename2) {
458 DosError(FERR_DISABLEHARDERR);
459 ret = DosQueryPathInfo(filename1, FIL_STANDARDL, &fsa1,
460 (ULONG) sizeof(fsa1));
461 if (!ret) {
462 DosError(FERR_DISABLEHARDERR);
463 ret = DosQueryPathInfo(filename2, FIL_STANDARDL, &fsa2,
464 (ULONG) sizeof(fsa2));
465 if (!ret) {
466 if (fsa1.cbFile == fsa2.cbFile &&
467 (fsa1.attrFile & (~FILE_ARCHIVED)) ==
468 (fsa2.attrFile & (~FILE_ARCHIVED)))
469 return TRUE;
470 }
471 }
472 }
473 return FALSE;
474}
475#endif
476
477INT IsFile(PCSZ filename)
478{
479 /* returns: -1 (error), 0 (is a directory), or 1 (is a file) */
480
481 FILESTATUS3 fsa;
482 APIRET ret;
483
484 if (filename && *filename) {
485 DosError(FERR_DISABLEHARDERR);
486 ret = DosQueryPathInfo(filename, FIL_STANDARD, &fsa, (ULONG) sizeof(fsa));
487 if (!ret)
488 return ((fsa.attrFile & FILE_DIRECTORY) == 0);
489 else if (IsValidDrive(*filename) && IsRoot(filename))
490 return 0;
491 }
492 return -1; /* error; doesn't exist or can't read or null filename */
493}
494
495BOOL IsFullName(CHAR * filename)
496{
497 return (filename) ?
498 (isalpha(*filename) && filename[1] == ':' && filename[2] == '\\') : 0;
499}
500
501BOOL IsRoot(PCSZ filename)
502{
503 return (filename && isalpha(*filename) && filename[1] == ':' &&
504 filename[2] == '\\' && !filename[3]);
505}
506
507BOOL IsValidDir(CHAR * path)
508{
509 CHAR fullname[CCHMAXPATH];
510 FILESTATUS3 fs;
511
512 if (path) {
513 DosError(FERR_DISABLEHARDERR);
514 if (!DosQueryPathInfo(path,
515 FIL_QUERYFULLNAME, fullname, sizeof(fullname))) {
516 if (IsValidDrive(*fullname)) {
517 if (!IsRoot(fullname)) {
518 DosError(FERR_DISABLEHARDERR);
519 if (!DosQueryPathInfo(fullname,
520 FIL_STANDARD,
521 &fs,
522 sizeof(fs)) && (fs.attrFile & FILE_DIRECTORY))
523 return TRUE;
524 }
525 else
526 return TRUE;
527 }
528 }
529 }
530 return FALSE;
531}
532
533BOOL IsValidDrive(CHAR drive)
534{
535 CHAR Path[] = " :", Buffer[256];
536 APIRET Status;
537 ULONG Size;
538 ULONG ulDriveNum, ulDriveMap;
539
540 if (!isalpha(drive) ||
541 (driveflags[toupper(drive) - 'A'] & (DRIVE_IGNORE | DRIVE_INVALID)))
542 return FALSE;
543 DosError(FERR_DISABLEHARDERR);
544 Status = DosQCurDisk(&ulDriveNum, &ulDriveMap);
545 if (!Status) {
546 if (!(ulDriveMap & (1 << (ULONG) (toupper(drive) - 'A'))))
547 return FALSE;
548 Path[0] = toupper(drive);
549 Size = sizeof(Buffer);
550 DosError(FERR_DISABLEHARDERR);
551 Status = DosQueryFSAttach(Path,
552 0,
553 FSAIL_QUERYNAME, (PFSQBUFFER2) Buffer, &Size);
554 }
555 return (Status == 0);
556}
557
558//=== MakeValidDir() build valid directory name ===
559
560CHAR *MakeValidDir(CHAR * path)
561{
562 ULONG ulDrv;
563 CHAR *p;
564 FILESTATUS3 fs;
565 APIRET rc;
566
567 if (!MakeFullName(path)) {
568 if (IsValidDrive(*path)) {
569 // Passed name is valid - trim to directory
570 for (;;) {
571 if (IsRoot(path))
572 return path;
573 DosError(FERR_DISABLEHARDERR);
574 rc = DosQueryPathInfo(path, FIL_STANDARD, &fs, sizeof(fs));
575 if (!rc && (fs.attrFile & FILE_DIRECTORY))
576 return path;
577 p = strrchr(path, '\\');
578 if (p) {
579 if (p < path + 3)
580 p++;
581 *p = 0;
582 }
583 else
584 break;
585 }
586 }
587 }
588 // Fall back to boot drive
589 DosError(FERR_DISABLEHARDERR);
590 if (!DosQuerySysInfo(QSV_BOOT_DRIVE, QSV_BOOT_DRIVE, &ulDrv, sizeof(ulDrv))) {
591 ulDrv += '@';
592 if (ulDrv < 'C')
593 ulDrv = 'C';
594 strcpy(path, " :\\");
595 *path = (CHAR) ulDrv;
596 }
597 else
598 strcpy(path, pFM2SaveDirectory); // Fall back to fm3.ini drive or current dir - should never occur
599 return path;
600}
601
602BOOL IsExecutable(CHAR * filename)
603{
604 register CHAR *p;
605 APIRET ret;
606 ULONG apptype;
607
608 if (filename) {
609 DosError(FERR_DISABLEHARDERR);
610 p = strrchr(filename, '.');
611 if (p)
612 ret = xDosQueryAppType(filename, &apptype);
613 else {
614
615 char fname[CCHMAXPATH + 2];
616
617 strcpy(fname, filename);
618 strcat(fname, ".");
619 ret = xDosQueryAppType(fname, &apptype);
620 }
621 if (apptype & (FAPPTYP_DLL |
622 FAPPTYP_PHYSDRV |
623 FAPPTYP_VIRTDRV |
624 FAPPTYP_PROTDLL))
625 return FALSE;
626 if (apptype == 0x000b && (!p ||
627 (stricmp(p, PCSZ_DOTEXE) &&
628 stricmp(p, PCSZ_DOTCOM) &&
629 stricmp(p, PCSZ_DOTCMD) &&
630 stricmp(p, PCSZ_DOTBAT) &&
631 stricmp(p, PCSZ_DOTBTM))))
632 return FALSE;
633 if (!fProtectOnly) {
634 if ((!ret && (!apptype ||
635 (apptype &
636 (FAPPTYP_NOTWINDOWCOMPAT |
637 FAPPTYP_WINDOWCOMPAT |
638 FAPPTYP_WINDOWAPI |
639 FAPPTYP_BOUND |
640 FAPPTYP_DOS |
641 FAPPTYP_WINDOWSREAL |
642 FAPPTYP_WINDOWSPROT |
643 FAPPTYP_32BIT |
644 FAPPTYP_WINDOWSPROT31)))) ||
645 (p && (!stricmp(p, PCSZ_DOTCMD) || !stricmp(p, PCSZ_DOTBAT) || !stricmp(p, PCSZ_DOTBTM))))
646 return TRUE;
647 }
648 else if ((!ret && (!apptype ||
649 (apptype &
650 (FAPPTYP_NOTWINDOWCOMPAT |
651 FAPPTYP_WINDOWCOMPAT |
652 FAPPTYP_WINDOWAPI |
653 FAPPTYP_BOUND |
654 FAPPTYP_32BIT)))) ||
655 (p && (!stricmp(p, PCSZ_DOTCMD) || !stricmp(p, PCSZ_DOTBTM))))
656 return TRUE;
657 if (fProtectOnly && (apptype &
658 (FAPPTYP_DOS |
659 FAPPTYP_WINDOWSREAL |
660 FAPPTYP_WINDOWSPROT |
661 FAPPTYP_WINDOWSPROT31)) &&
662 (p && (!stricmp(p, PCSZ_DOTEXE) || !stricmp(p, PCSZ_DOTCOM) ||
663 !stricmp(p, PCSZ_DOTBAT))))
664 saymsg(MB_OK,
665 HWND_DESKTOP,
666 NullStr,
667 GetPString(IDS_NOTPROTECTONLYEXE),
668 filename);
669 }
670 return FALSE;
671}
672
673VOID ArgDriveFlags(INT argc, CHAR ** argv)
674{
675 INT x;
676
677 for (x = 1; x < argc; x++) {
678 if (*argv[x] == '/' && isalpha(argv[x][1])) {
679
680 CHAR *p = &argv[x][1];
681
682 while (isalpha(*p)) {
683 driveflags[toupper(*p) - 'A'] |= DRIVE_IGNORE;
684 p++;
685 }
686 }
687 else if (*argv[x] == ';' && isalpha(argv[x][1])) {
688
689 CHAR *p = &argv[x][1];
690
691 while (isalpha(*p)) {
692 driveflags[toupper(*p) - 'A'] |= DRIVE_NOPRESCAN;
693 p++;
694 }
695 }
696 else if (*argv[x] == '`' && isalpha(argv[x][1])) {
697
698 CHAR *p = &argv[x][1];
699
700 while (isalpha(*p)) {
701 driveflags[toupper(*p) - 'A'] |= DRIVE_NOSTATS;
702 p++;
703 }
704 }
705 else if (*argv[x] == ',' && isalpha(argv[x][1])) {
706
707 CHAR *p = &argv[x][1];
708
709 while (isalpha(*p)) {
710 driveflags[toupper(*p) - 'A'] |= DRIVE_NOLOADICONS;
711 p++;
712 }
713 }
714 else if (*argv[x] == '-' && isalpha(argv[x][1])) {
715
716 CHAR *p = &argv[x][1];
717
718 while (isalpha(*p)) {
719 driveflags[toupper(*p) - 'A'] |= DRIVE_NOLOADSUBJS;
720 p++;
721 }
722 }
723 else if (*argv[x] == '\'' && isalpha(argv[x][1])) {
724
725 CHAR *p = &argv[x][1];
726
727 while (isalpha(*p)) {
728 driveflags[toupper(*p) - 'A'] |= DRIVE_NOLOADLONGS;
729 p++;
730 }
731 }
732 }
733}
734
735VOID DriveFlagsOne(INT x, CHAR *FileSystem, VOID *volser)
736{
737 INT removable;
738 CHAR szDrive[] = " :\\";
739 ULONG drvtype;
740
741 *szDrive = (CHAR) (x + 'A');
742 *FileSystem = 0;
743 drvtype = 0;
744 removable = CheckDrive(*szDrive, FileSystem, &drvtype);
745 strupr(FileSystem);
746 driveserial[x] = -1;
747 driveflags[x] &= (DRIVE_IGNORE | DRIVE_NOPRESCAN | DRIVE_NOLOADICONS |
748 DRIVE_NOLOADSUBJS | DRIVE_NOLOADLONGS |
749 DRIVE_INCLUDEFILES | DRIVE_SLOW | DRIVE_NOSTATS |
750 DRIVE_WRITEVERIFYOFF);
751 if (removable != -1) {
752 if (!volser) {
753 struct
754 {
755 ULONG serial;
756 CHAR volumelength;
757 CHAR volumelabel[CCHMAXPATH];
758 }
759 volserl;
760
761 DosError(FERR_DISABLEHARDERR);
762 if (!DosQueryFSInfo((ULONG) x + 1, FSIL_VOLSER, &volserl, sizeof(volserl)))
763 driveserial[x] = volserl.serial;
764 else
765 DosError(FERR_DISABLEHARDERR);
766 }
767 else {
768 DosError(FERR_DISABLEHARDERR);
769 if (DosQueryFSInfo((ULONG) x + 1, FSIL_VOLSER, volser,
770 sizeof(ULONG) + sizeof(CHAR) + CCHMAXPATH))
771 DosError(FERR_DISABLEHARDERR);
772 }
773 }
774 else
775 driveflags[x] |= DRIVE_INVALID;
776 driveflags[x] |= ((removable == -1 || removable == 1) ? DRIVE_REMOVABLE : 0);
777 if (drvtype & DRIVE_REMOTE)
778 driveflags[x] |= DRIVE_REMOTE;
779 if (drvtype & DRIVE_NOEASUPPORT)
780 driveflags[x] |= DRIVE_NOEASUPPORT;
781 if(!strcmp(FileSystem,NDFS32)){
782 driveflags[x] |= DRIVE_VIRTUAL;
783 driveflags[x] &= (~DRIVE_REMOTE);
784 }
785 if(!strcmp(FileSystem,RAMFS)){
786 driveflags[x] |= DRIVE_RAMDISK;
787 driveflags[x] &= (~DRIVE_REMOTE);
788 }
789 if(!strcmp(FileSystem,NTFS))
790 driveflags[x] |= DRIVE_NOTWRITEABLE;
791 if (strcmp(FileSystem, HPFS) &&
792 strcmp(FileSystem, CDFS) &&
793 strcmp(FileSystem, ISOFS) &&
794 strcmp(FileSystem, JFS) &&
795 strcmp(FileSystem, LAN) &&
796 strcmp(FileSystem, RAMFS) &&
797 strcmp(FileSystem, FAT32) &&
798 strcmp(FileSystem, NTFS) &&
799 strcmp(FileSystem, NDFS32) &&
800 strcmp(FileSystem, HPFS386)) {
801 driveflags[x] |= DRIVE_NOLONGNAMES;
802 }
803 if ((!strcmp(FileSystem, HPFS) ||
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.