source: trunk/dll/valid.c@ 1439

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

Changes to allow high mem loading of dll; Refactor .LONGNAME and .SUBJECT EA fetch to FetchCommonEAs. Add szFSType to FillInRecordFromFSA use to bypass EA scan and size formatting for tree container; Fix labels/FS type to work on scan on NOPRESCAN Drives; Fixed dbl directory names on restore of dir cnrs; (Tickets 47, 339, 363, 368, 369, 370)

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