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
RevLine 
[48]1
2/***********************************************************************
3
4 $Id: valid.c 1439 2009-07-12 21:57:04Z gyoung $
5
6 File name manipulation routines
7
[103]8 Copyright (c) 1993, 1998 M. Kimes
[1387]9 Copyright (c) 2002, 2009 Steven H.Levine
[48]10
[184]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
[274]18 28 Nov 05 SHL MakeValidDir: correct DosQuerySysInfo args
[328]19 22 Jul 06 SHL Use Runtime_Error
[530]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
[552]22 07 Jan 07 GKY Move error strings etc. to string file
23 18 Feb 07 GKY Add more drive types and icons
[697]24 16 Jun 07 SHL Update for OpenWatcom
[793]25 20 Aug 07 GKY Move #pragma alloc_text to end for OpenWatcom compat
[897]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
[1104]28 19 Jul 08 GKY Replace save_dir2(dir) with pFM2SaveDirectory
[1358]29 25 Dec 08 GKY Add code to allow write verify to be turned off on a per drive basis
[1375]30 03 Jan 09 GKY Check for system that is protectonly to gray out Dos/Win command lines and prevent
[1394]31 Dos/Win programs from being inserted into the execute dialog with message why.
[1387]32 03 Jan 09 GKY Modify IsExecutable to prevent some text files from being treated as executable
[1394]33 and prevent dlls from being loaded into execute dialog.
[1387]34 05 Jan 09 GKY Fix IsBinary to recognize values above \xc4 (maybe lower) as positive.
[1394]35 When these high codes were it text files they showed as hex in new view.
[1402]36 08 Mar 09 GKY Additional strings move to PCSZs
[1439]37 12 Jul 09 GKY Add xDosQueryAppType and xDoxAlloc... to allow FM/2 to load in high memory
[48]38
39***********************************************************************/
40
[907]41#include <string.h>
42#include <ctype.h>
43
[2]44#define INCL_DOS
45#define INCL_WIN
[551]46#define INCL_DOSDEVIOCTL // DosDevIOCtl
[841]47#define INCL_LONGLONG
[2]48
[1187]49#include "fm3dll.h"
[1214]50#include "treecnr.h" // Data declaration(s)
51#include "info.h" // Data declaration(s)
52#include "notebook.h" // Data declaration(s)
[907]53#include "fm3str.h"
54#include "errutil.h" // Dos_Error...
55#include "strutil.h" // GetPString
[1162]56#include "valid.h"
[1187]57#include "dirs.h" // save_dir2
58#include "strips.h" // bstrip
[1214]59#include "init.h" // GetTidForWindow
[1438]60#include "wrappers.h" // xDosAllocMem
[2]61
[328]62
[1162]63//static BOOL IsDesktop(HAB hab, HWND hwnd);
64//static BOOL IsFileSame(CHAR * filename1, CHAR * filename2);
[1187]65//static char *IsVowel(char a);
[1162]66
[1214]67// Data definitions
68static PSZ pszSrcFile = __FILE__;
69
70#pragma data_seg(GLOBAL2)
[1402]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";
[1354]81BOOL fVerifyOffChecked[26];
[1214]82
[551]83APIRET MakeFullName(char *pszFileName)
[103]84{
85 /* pszFileName must be CCHMAXPATH long minimum! */
[2]86
[551]87 char szPathName[CCHMAXPATH];
[2]88 APIRET rc;
89
90 DosError(FERR_DISABLEHARDERR);
[103]91 rc = DosQueryPathInfo(pszFileName,
[551]92 FIL_QUERYFULLNAME, szPathName, sizeof(szPathName));
93 if (!rc)
[103]94 strcpy(pszFileName, szPathName); // Pass back actual name
[2]95 return rc;
96}
97
[551]98char *RootName(char *filename)
[103]99{
[551]100 char *p = NULL, *pp;
[2]101
[48]102 // Return filename, strip path parts
[689]103 // Return empty string when filename ends with backslash
[48]104
[551]105 if (filename) {
106 p = strrchr(filename, '\\');
107 pp = strrchr(filename, '/');
108 p = (p) ? (pp) ? (p > pp) ? p : pp : p : pp;
[2]109 }
[551]110 if (!p) /* name is itself a root */
[2]111 p = filename;
[551]112 else /* skip past backslash */
[2]113 p++;
114 return p;
115}
116
[915]117 /** TestFDate
[2]118 * return 1 (file2 newer than file1),
119 * 0 (files same)
120 * or -1 (file1 newer than file2)
[897]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
[2]124 */
125
[915]126int TestFDates(char *file1, char *file2, FDATE *datevar1, FTIME *timevar1,
[1394]127 FDATE *datevar2, FTIME *timevar2)
[915]128{
[551]129 int comp = 0;
[847]130 FILESTATUS3 fs3o, fs3n;
[2]131
[897]132 if (file1){
[2]133 DosError(FERR_DISABLEHARDERR);
[897]134 DosQueryPathInfo(file1, FIL_STANDARD, &fs3o, sizeof(fs3o));
135 datevar1 = &fs3o.fdateLastWrite;
136 timevar1 = &fs3o.ftimeLastWrite;
[2]137 }
[897]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 >
[1394]146 datevar1->year) ? 1 :
[897]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;
[2]170}
171
[915]172 /** TestCDate
[897]173 * return 1 (file2 newer than file1),
174 * 0 (files same)
175 * or -1 (file1 newer than file2)
176 */
177
[915]178int TestCDates(CDATE *datevar1, CTIME *timevar1,
[1394]179 CDATE *datevar2, CTIME *timevar2)
[915]180{
[897]181 int comp = 0;
182
183 if (&datevar1 && &datevar2 && &timevar1 && &timevar2) {
184 comp = (datevar2->year >
[1394]185 datevar1->year) ? 1 :
[897]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
[551]211BOOL IsNewer(char *file1, char *file2)
[103]212{
[2]213 /* return TRUE if file2 is newer than file1 */
214
[897]215 return (TestFDates(file1, file2, NULL, NULL, NULL, NULL) > 0);
[2]216}
217
[1394]218#if 0 // JBS 11 Sep 08
[551]219BOOL IsDesktop(HAB hab, HWND hwnd)
[103]220{
[2]221 HWND hwndDesktop;
222
[551]223 if (hwnd == HWND_DESKTOP)
[2]224 return TRUE;
[551]225 hwndDesktop = WinQueryDesktopWindow(hab, NULLHANDLE);
226 if (hwnd == hwndDesktop)
[2]227 return TRUE;
228 return FALSE;
229}
[1162]230#endif
[2]231
[551]232BOOL ParentIsDesktop(HWND hwnd, HWND hwndParent)
[103]233{
[2]234 HWND hwndDesktop;
235 BOOL ret = FALSE;
236
[551]237 if (!hwndParent)
238 hwndParent = WinQueryWindow(hwnd, QW_PARENT);
239 if (hwndParent == HWND_DESKTOP)
[2]240 ret = TRUE;
241 else {
[551]242 hwndDesktop = WinQueryDesktopWindow(WinQueryAnchorBlock(hwnd), (HWND) 0);
243 if (hwndDesktop == hwndParent)
[2]244 ret = TRUE;
245 }
246 return ret;
247}
248
[946]249/** CheckDrive
[109]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 */
[2]255
[551]256INT CheckDrive(CHAR chDrive, CHAR * pszFileSystem, ULONG * pulType)
[70]257{
[551]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
[103]269# pragma pack(1)
[551]270 struct
271 {
272 BYTE Cmd;
273 BYTE Unit;
274 }
275 parmPkt =
276 {
277 0, 0};
[103]278# define BPB_REMOVABLE_MEDIA 0x08 // 3 - Media is removable
279 struct
280 {
281 BIOSPARAMETERBLOCK bpb;
[551]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
[103]288# pragma pack()
[551]289 BYTE NonRemovable;
[2]290 PFSQBUFFER2 pfsq;
291
[70]292 if (pszFileSystem)
293 *pszFileSystem = 0;
[530]294
[70]295 if (pulType)
296 *pulType = 0;
[2]297
[530]298# define BUFFER_BYTES 8192
[1438]299 rc = xDosAllocMem(&pvBuffer, BUFFER_BYTES,
[1439]300 PAG_COMMIT | PAG_READ | PAG_WRITE, pszSrcFile, __LINE__);
[328]301 if (rc) {
[551]302 Dos_Error(MB_CANCEL, rc, HWND_DESKTOP, pszSrcFile, __LINE__,
303 GetPString(IDS_OUTOFMEMORY));
[70]304 return -1; // Say failed
[2]305 }
306
[103]307 szPath[0] = chDrive;
308 szPath[1] = ':';
309 szPath[2] = 0;
310 clBufferSize = BUFFER_BYTES;
[2]311 DosError(FERR_DISABLEHARDERR);
[328]312 rc = DosQueryFSAttach(szPath, 0, FSAIL_QUERYNAME,
[551]313 (PFSQBUFFER2) pvBuffer, &clBufferSize);
314 if (rc) {
[70]315 /* can't get any info at all */
[103]316 DosFreeMem(pvBuffer);
[2]317 DosError(FERR_DISABLEHARDERR);
[70]318 return -1; // Say failed
[2]319 }
320
[551]321 pfsq = (PFSQBUFFER2) pvBuffer;
[689]322 pfsn = (PCHAR)(pfsq->szName) + pfsq->cbName + 1;
[2]323 pfsd = pfsn + pfsq->cbFSDName + 1;
324
[551]325 if (pszFileSystem) {
[70]326 strncpy(pszFileSystem, pfsn, CCHMAXPATH);
327 pszFileSystem[CCHMAXPATH - 1] = 0;
[2]328 }
329
[552]330 if (pulType && (!strcmp(pfsn, CDFS) || !strcmp(pfsn, ISOFS)))
[555]331 *pulType |= DRIVE_NOTWRITEABLE | DRIVE_CDROM | DRIVE_REMOVABLE;
332 if (pulType && !strcmp(pfsn, NTFS))
[1351]333 *pulType |= DRIVE_NOTWRITEABLE;
[552]334 if (pulType && !strcmp(pfsn, NDFS32)){
[1394]335 *pulType |= DRIVE_VIRTUAL;
[552]336 }
337 if (pulType && !strcmp(pfsn, RAMFS)){
[1394]338 *pulType |= DRIVE_RAMDISK;
[552]339 }
340 if (((PFSQBUFFER2) pvBuffer)->iType == FSAT_REMOTEDRV &&
[555]341 (strcmp(pfsn, CDFS) || strcmp(pfsn, ISOFS))) {
[70]342 if (pulType)
343 *pulType |= DRIVE_REMOTE;
[552]344
[551]345 if (pulType && !strcmp(pfsn, CBSIFS)) {
[70]346 *pulType |= DRIVE_ZIPSTREAM;
347 *pulType &= ~DRIVE_REMOTE;
348 *pulType |= DRIVE_NOLONGNAMES;
[551]349 if (pfsq->cbFSAData) {
[103]350 ULONG FType;
[2]351
[551]352 if (CheckDrive(*pfsd, NULL, &FType) != -1) {
[103]353 if (FType & DRIVE_REMOVABLE)
354 *pulType |= DRIVE_REMOVABLE;
355 if (~FType & DRIVE_NOLONGNAMES)
356 *pulType &= ~DRIVE_NOLONGNAMES;
357 }
[552]358
[2]359 }
360 }
[70]361 if (pulType &&
[551]362 (!strcmp(pfsn, HPFS) ||
363 !strcmp(pfsn, JFS) ||
364 !strcmp(pfsn, FAT32) ||
[1394]365 !strcmp(pfsn, RAMFS) ||
366 !strcmp(pfsn, NDFS32) ||
367 !strcmp(pfsn, NTFS) ||
368 !strcmp(pfsn, HPFS386))) {
[70]369 *pulType &= ~DRIVE_NOLONGNAMES;
370 }
[552]371
[103]372 DosFreeMem(pvBuffer);
373 return 0; // Remotes are non-removable
[2]374 }
375
[70]376 // Local drive
[551]377 if (strcmp(pfsn, HPFS) &&
378 strcmp(pfsn, JFS) &&
379 strcmp(pfsn, CDFS) &&
[552]380 strcmp(pfsn, ISOFS) &&
381 strcmp(pfsn, RAMFS) &&
382 strcmp(pfsn, FAT32) &&
383 strcmp(pfsn, NDFS32) &&
[555]384 strcmp(pfsn, NTFS) &&
[552]385 strcmp(pfsn, HPFS386)) {
[551]386 if (pulType)
[103]387 (*pulType) |= DRIVE_NOLONGNAMES; // Others can not have long names
[2]388 }
389
[552]390
[2]391 DosError(FERR_DISABLEHARDERR);
[844]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);
[551]395 if (rc) {
[2]396 DosError(FERR_DISABLEHARDERR);
[70]397 if (pulType)
398 *pulType |= DRIVE_REMOVABLE; // Assume removable if can not access
[103]399 DosFreeMem(pvBuffer);
[70]400 return 1; // Say removable
[2]401 }
[103]402
403 clParmBytes = sizeof(parmPkt.Cmd);
404 clDataBytes = sizeof(NonRemovable);
405 NonRemovable = 1; // Preset as non removable
[2]406 DosError(FERR_DISABLEHARDERR);
[1394]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. */
[103]413
[328]414 if (!rc && NonRemovable) {
[103]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);
[1394]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. */
[103]426
[328]427 if (!rc && (dataPkt.bpb.fsDeviceAttr & BPB_REMOVABLE_MEDIA))
[103]428 NonRemovable = 0;
429 }
430
431 DosClose(hDev);
432
[70]433 if (!NonRemovable && pulType)
434 *pulType |= DRIVE_REMOVABLE;
[103]435
436 DosFreeMem(pvBuffer);
437
[70]438 return NonRemovable ? 0 : 1;
[2]439}
440
[1193]441#if 0 // JBS 11 Sep 08
[551]442BOOL IsFileSame(CHAR * filename1, CHAR * filename2)
[103]443{
[1394]444 /* returns: -1 (error), 0 (is a directory), or 1 (is a file) */
[2]445
[841]446 FILESTATUS3L fsa1, fsa2;
[551]447 APIRET ret;
[2]448
[551]449 if (filename1 && filename2) {
[2]450 DosError(FERR_DISABLEHARDERR);
[841]451 ret = DosQueryPathInfo(filename1, FIL_STANDARDL, &fsa1,
[551]452 (ULONG) sizeof(fsa1));
453 if (!ret) {
[2]454 DosError(FERR_DISABLEHARDERR);
[841]455 ret = DosQueryPathInfo(filename2, FIL_STANDARDL, &fsa2,
[551]456 (ULONG) sizeof(fsa2));
457 if (!ret) {
458 if (fsa1.cbFile == fsa2.cbFile &&
459 (fsa1.attrFile & (~FILE_ARCHIVED)) ==
460 (fsa2.attrFile & (~FILE_ARCHIVED)))
[103]461 return TRUE;
[2]462 }
463 }
464 }
465 return FALSE;
466}
[1162]467#endif
[2]468
[1394]469INT IsFile(PCSZ filename)
[103]470{
[1394]471 /* returns: -1 (error), 0 (is a directory), or 1 (is a file) */
[2]472
[847]473 FILESTATUS3 fsa;
[551]474 APIRET ret;
[2]475
[551]476 if (filename && *filename) {
[2]477 DosError(FERR_DISABLEHARDERR);
[847]478 ret = DosQueryPathInfo(filename, FIL_STANDARD, &fsa, (ULONG) sizeof(fsa));
[551]479 if (!ret)
[2]480 return ((fsa.attrFile & FILE_DIRECTORY) == 0);
[551]481 else if (IsValidDrive(*filename) && IsRoot(filename))
[2]482 return 0;
483 }
[551]484 return -1; /* error; doesn't exist or can't read or null filename */
[2]485}
486
[551]487BOOL IsFullName(CHAR * filename)
[103]488{
[2]489 return (filename) ?
[551]490 (isalpha(*filename) && filename[1] == ':' && filename[2] == '\\') : 0;
[2]491}
492
[1394]493BOOL IsRoot(PCSZ filename)
[103]494{
[2]495 return (filename && isalpha(*filename) && filename[1] == ':' &&
[103]496 filename[2] == '\\' && !filename[3]);
[2]497}
498
[551]499BOOL IsValidDir(CHAR * path)
[103]500{
[551]501 CHAR fullname[CCHMAXPATH];
[847]502 FILESTATUS3 fs;
[2]503
[551]504 if (path) {
[2]505 DosError(FERR_DISABLEHARDERR);
[551]506 if (!DosQueryPathInfo(path,
507 FIL_QUERYFULLNAME, fullname, sizeof(fullname))) {
508 if (IsValidDrive(*fullname)) {
509 if (!IsRoot(fullname)) {
[103]510 DosError(FERR_DISABLEHARDERR);
[551]511 if (!DosQueryPathInfo(fullname,
[847]512 FIL_STANDARD,
[551]513 &fs,
514 sizeof(fs)) && (fs.attrFile & FILE_DIRECTORY))
[103]515 return TRUE;
516 }
517 else
518 return TRUE;
[2]519 }
520 }
521 }
522 return FALSE;
523}
524
[551]525BOOL IsValidDrive(CHAR drive)
[103]526{
[551]527 CHAR Path[] = " :", Buffer[256];
[2]528 APIRET Status;
[551]529 ULONG Size;
530 ULONG ulDriveNum, ulDriveMap;
[2]531
[551]532 if (!isalpha(drive) ||
533 (driveflags[toupper(drive) - 'A'] & (DRIVE_IGNORE | DRIVE_INVALID)))
[2]534 return FALSE;
535 DosError(FERR_DISABLEHARDERR);
[551]536 Status = DosQCurDisk(&ulDriveNum, &ulDriveMap);
537 if (!Status) {
[766]538 if (!(ulDriveMap & (1 << (ULONG) (toupper(drive) - 'A'))))
[2]539 return FALSE;
540 Path[0] = toupper(drive);
541 Size = sizeof(Buffer);
542 DosError(FERR_DISABLEHARDERR);
543 Status = DosQueryFSAttach(Path,
[103]544 0,
[551]545 FSAIL_QUERYNAME, (PFSQBUFFER2) Buffer, &Size);
[2]546 }
547 return (Status == 0);
548}
549
[274]550//=== MakeValidDir() build valid directory name ===
[2]551
[551]552CHAR *MakeValidDir(CHAR * path)
[103]553{
[551]554 ULONG ulDrv;
555 CHAR *p;
[847]556 FILESTATUS3 fs;
[551]557 APIRET rc;
[2]558
[274]559 if (!MakeFullName(path)) {
560 if (IsValidDrive(*path)) {
561 // Passed name is valid - trim to directory
562 for (;;) {
563 if (IsRoot(path))
[103]564 return path;
565 DosError(FERR_DISABLEHARDERR);
[847]566 rc = DosQueryPathInfo(path, FIL_STANDARD, &fs, sizeof(fs));
[274]567 if (!rc && (fs.attrFile & FILE_DIRECTORY))
[103]568 return path;
[551]569 p = strrchr(path, '\\');
[274]570 if (p) {
571 if (p < path + 3)
[103]572 p++;
573 *p = 0;
574 }
575 else
576 break;
[2]577 }
578 }
579 }
[274]580 // Fall back to boot drive
[2]581 DosError(FERR_DISABLEHARDERR);
[551]582 if (!DosQuerySysInfo(QSV_BOOT_DRIVE, QSV_BOOT_DRIVE, &ulDrv, sizeof(ulDrv))) {
[274]583 ulDrv += '@';
584 if (ulDrv < 'C')
585 ulDrv = 'C';
[551]586 strcpy(path, " :\\");
587 *path = (CHAR) ulDrv;
[2]588 }
589 else
[1104]590 strcpy(path, pFM2SaveDirectory); // Fall back to fm3.ini drive or current dir - should never occur
[2]591 return path;
592}
593
[551]594BOOL IsExecutable(CHAR * filename)
[103]595{
[2]596 register CHAR *p;
[551]597 APIRET ret;
598 ULONG apptype;
[2]599
[551]600 if (filename) {
[2]601 DosError(FERR_DISABLEHARDERR);
[551]602 p = strrchr(filename, '.');
603 if (p)
[1439]604 ret = xDosQueryAppType(filename, &apptype);
[2]605 else {
606
607 char fname[CCHMAXPATH + 2];
608
[551]609 strcpy(fname, filename);
610 strcat(fname, ".");
[1439]611 ret = xDosQueryAppType(fname, &apptype);
[1369]612 }
[1372]613 if (apptype & (FAPPTYP_DLL |
[1394]614 FAPPTYP_PHYSDRV |
615 FAPPTYP_VIRTDRV |
616 FAPPTYP_PROTDLL))
[1372]617 return FALSE;
618 if (apptype == 0x000b && (!p ||
[1398]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))))
[1372]624 return FALSE;
[1369]625 if (!fProtectOnly) {
626 if ((!ret && (!apptype ||
[1394]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)))) ||
[1398]637 (p && (!stricmp(p, PCSZ_DOTCMD) || !stricmp(p, PCSZ_DOTBAT) || !stricmp(p, PCSZ_DOTBTM))))
[1394]638 return TRUE;
[1369]639 }
640 else if ((!ret && (!apptype ||
[1394]641 (apptype &
642 (FAPPTYP_NOTWINDOWCOMPAT |
643 FAPPTYP_WINDOWCOMPAT |
644 FAPPTYP_WINDOWAPI |
645 FAPPTYP_BOUND |
646 FAPPTYP_32BIT)))) ||
[1398]647 (p && (!stricmp(p, PCSZ_DOTCMD) || !stricmp(p, PCSZ_DOTBTM))))
[2]648 return TRUE;
[1369]649 if (fProtectOnly && (apptype &
[1394]650 (FAPPTYP_DOS |
651 FAPPTYP_WINDOWSREAL |
652 FAPPTYP_WINDOWSPROT |
653 FAPPTYP_WINDOWSPROT31)) &&
[1398]654 (p && (!stricmp(p, PCSZ_DOTEXE) || !stricmp(p, PCSZ_DOTCOM) ||
655 !stricmp(p, PCSZ_DOTBAT))))
[1369]656 saymsg(MB_OK,
[1394]657 HWND_DESKTOP,
658 NullStr,
659 GetPString(IDS_NOTPROTECTONLYEXE),
660 filename);
[2]661 }
662 return FALSE;
663}
664
[551]665VOID ArgDriveFlags(INT argc, CHAR ** argv)
[103]666{
[2]667 INT x;
668
[551]669 for (x = 1; x < argc; x++) {
670 if (*argv[x] == '/' && isalpha(argv[x][1])) {
[2]671
672 CHAR *p = &argv[x][1];
673
[551]674 while (isalpha(*p)) {
[103]675 driveflags[toupper(*p) - 'A'] |= DRIVE_IGNORE;
676 p++;
[2]677 }
678 }
[551]679 else if (*argv[x] == ';' && isalpha(argv[x][1])) {
[2]680
681 CHAR *p = &argv[x][1];
682
[551]683 while (isalpha(*p)) {
[103]684 driveflags[toupper(*p) - 'A'] |= DRIVE_NOPRESCAN;
685 p++;
[2]686 }
687 }
[552]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 }
[551]697 else if (*argv[x] == ',' && isalpha(argv[x][1])) {
[2]698
699 CHAR *p = &argv[x][1];
700
[551]701 while (isalpha(*p)) {
[103]702 driveflags[toupper(*p) - 'A'] |= DRIVE_NOLOADICONS;
703 p++;
[2]704 }
705 }
[552]706 else if (*argv[x] == '-' && isalpha(argv[x][1])) {
[2]707
708 CHAR *p = &argv[x][1];
709
[551]710 while (isalpha(*p)) {
[103]711 driveflags[toupper(*p) - 'A'] |= DRIVE_NOLOADSUBJS;
712 p++;
[2]713 }
714 }
[551]715 else if (*argv[x] == '\'' && isalpha(argv[x][1])) {
[2]716
717 CHAR *p = &argv[x][1];
718
[551]719 while (isalpha(*p)) {
[103]720 driveflags[toupper(*p) - 'A'] |= DRIVE_NOLOADLONGS;
721 p++;
[2]722 }
723 }
724 }
725}
726
[551]727VOID DriveFlagsOne(INT x)
[70]728{
[551]729 INT removable;
730 CHAR szDrive[] = " :\\", FileSystem[CCHMAXPATH];
731 ULONG drvtype;
[2]732
[551]733 *szDrive = (CHAR) (x + 'A');
[2]734 *FileSystem = 0;
735 drvtype = 0;
[551]736 removable = CheckDrive(*szDrive, FileSystem, &drvtype);
[2]737 driveserial[x] = -1;
738 driveflags[x] &= (DRIVE_IGNORE | DRIVE_NOPRESCAN | DRIVE_NOLOADICONS |
[103]739 DRIVE_NOLOADSUBJS | DRIVE_NOLOADLONGS |
[1394]740 DRIVE_INCLUDEFILES | DRIVE_SLOW | DRIVE_NOSTATS |
741 DRIVE_WRITEVERIFYOFF);
[551]742 if (removable != -1) {
[70]743 struct
744 {
[2]745 ULONG serial;
[551]746 CHAR volumelength;
747 CHAR volumelabel[CCHMAXPATH];
748 }
749 volser;
[2]750
751 DosError(FERR_DISABLEHARDERR);
[551]752 if (!DosQueryFSInfo((ULONG) x + 1, FSIL_VOLSER, &volser, sizeof(volser)))
[2]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) ?
[551]760 DRIVE_REMOVABLE : 0);
761 if (drvtype & DRIVE_REMOTE)
[2]762 driveflags[x] |= DRIVE_REMOTE;
[552]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 }
[555]771 if(!stricmp(FileSystem,NTFS))
772 driveflags[x] |= DRIVE_NOTWRITEABLE;
[551]773 if (strcmp(FileSystem, HPFS) &&
774 strcmp(FileSystem, JFS) &&
775 strcmp(FileSystem, CDFS) &&
[552]776 strcmp(FileSystem, ISOFS) &&
777 strcmp(FileSystem, RAMFS) &&
778 strcmp(FileSystem, FAT32) &&
[555]779 strcmp(FileSystem, NTFS) &&
780 strcmp(FileSystem, NDFS32) &&
[552]781 strcmp(FileSystem, HPFS386)) {
[2]782 driveflags[x] |= DRIVE_NOLONGNAMES;
[70]783 }
[552]784
785 if (!strcmp(FileSystem, CDFS) || !strcmp(FileSystem, ISOFS)) {
[2]786 removable = 1;
[551]787 driveflags[x] |= (DRIVE_REMOVABLE | DRIVE_NOTWRITEABLE | DRIVE_CDROM);
[2]788 }
[1351]789 if (!stricmp(FileSystem, CBSIFS)) {
[2]790 driveflags[x] |= DRIVE_ZIPSTREAM;
791 driveflags[x] &= (~DRIVE_REMOTE);
[551]792 if (drvtype & DRIVE_REMOVABLE)
[2]793 driveflags[x] |= DRIVE_REMOVABLE;
[551]794 if (!(drvtype & DRIVE_NOLONGNAMES))
[2]795 driveflags[x] &= (~DRIVE_NOLONGNAMES);
796 }
797}
798
[551]799VOID FillInDriveFlags(VOID * dummy)
[103]800{
[1354]801 ULONG ulDriveNum, ulDriveMap, size;
[2]802 register INT x;
803
[551]804 for (x = 0; x < 26; x++)
[2]805 driveflags[x] &= (DRIVE_IGNORE | DRIVE_NOPRESCAN | DRIVE_NOLOADICONS |
[103]806 DRIVE_NOLOADSUBJS | DRIVE_NOLOADLONGS |
[1394]807 DRIVE_INCLUDEFILES | DRIVE_SLOW | DRIVE_NOSTATS |
808 DRIVE_WRITEVERIFYOFF);
[551]809 memset(driveserial, -1, sizeof(driveserial));
[2]810 DosError(FERR_DISABLEHARDERR);
[551]811 DosQCurDisk(&ulDriveNum, &ulDriveMap);
812 for (x = 0; x < 26; x++) {
[766]813 if (ulDriveMap & (1 << x) && !(driveflags[x] & DRIVE_IGNORE)) {
[2]814 {
[1394]815 ULONG flags = 0, size = sizeof(ULONG);
816 CHAR FlagKey[80];
[2]817
[1394]818 sprintf(FlagKey, "%c.DriveFlags", (CHAR) (x + 'A'));
819 if (PrfQueryProfileData(fmprof, appname, FlagKey, &flags, &size) &&
820 size == sizeof(ULONG))
821 driveflags[x] |= flags;
[2]822 }
823
[551]824 if (x > 1) {
825 if (!(driveflags[x] & DRIVE_NOPRESCAN))
[103]826 DriveFlagsOne(x);
827 else
828 driveserial[x] = -1;
[2]829 }
830 else {
[103]831 driveflags[x] |= (DRIVE_REMOVABLE | DRIVE_NOLONGNAMES);
832 driveserial[x] = -1;
[2]833 }
834 }
[766]835 else if (!(ulDriveMap & (1 << x)))
[2]836 driveflags[x] |= DRIVE_INVALID;
837 }
838 {
[551]839 ULONG startdrive = 3L;
[2]840
841 DosError(FERR_DISABLEHARDERR);
[551]842 DosQuerySysInfo(QSV_BOOT_DRIVE, QSV_BOOT_DRIVE,
843 (PVOID) & startdrive, (ULONG) sizeof(ULONG));
844 if (startdrive)
[2]845 driveflags[startdrive - 1] |= DRIVE_BOOT;
846 }
[1354]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]) {
[1394]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 }
[1354]862 }
863 }
864 }
[2]865}
866
[551]867CHAR *assign_ignores(CHAR * s)
[103]868{
[551]869 register INT x;
870 register CHAR *p, *pp;
[2]871
872 *s = '/';
873 s[1] = 0;
874 p = s + 1;
[551]875 if (s) {
876 for (x = 0; x < 26; x++) {
877 if ((driveflags[x] & DRIVE_IGNORE) != 0) {
878 *p = (CHAR) x + 'A';
[103]879 p++;
880 *p = 0;
[2]881 }
882 }
883 }
[551]884 if (!s[1]) {
[2]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;
[551]896 if (pp) {
897 for (x = 0; x < 26; x++) {
898 if ((driveflags[x] & DRIVE_NOPRESCAN) != 0) {
899 *p = (CHAR) x + 'A';
[103]900 p++;
901 *p = 0;
[2]902 }
903 }
904 }
[551]905 if (!pp[1])
[2]906 *pp = 0;
907 pp = &s[strlen(s)];
908 *pp = ' ';
909 pp++;
910 *pp = ',';
911 pp[1] = 0;
912 p = pp + 1;
[551]913 if (pp) {
914 for (x = 0; x < 26; x++) {
915 if ((driveflags[x] & DRIVE_NOLOADICONS) != 0) {
916 *p = (CHAR) x + 'A';
[103]917 p++;
918 *p = 0;
[2]919 }
920 }
921 }
[551]922 if (!pp[1])
[2]923 *pp = 0;
924 pp = &s[strlen(s)];
925 *pp = ' ';
926 pp++;
[552]927 *pp = '-';
[2]928 pp[1] = 0;
929 p = pp + 1;
[551]930 if (pp) {
931 for (x = 0; x < 26; x++) {
932 if ((driveflags[x] & DRIVE_NOLOADSUBJS) != 0) {
933 *p = (CHAR) x + 'A';
[103]934 p++;
935 *p = 0;
[2]936 }
937 }
938 }
[551]939 if (!pp[1])
[2]940 *pp = 0;
941 pp = &s[strlen(s)];
942 *pp = ' ';
943 pp++;
[552]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++;
[2]961 *pp = '\'';
962 pp[1] = 0;
963 p = pp + 1;
[551]964 if (pp) {
965 for (x = 0; x < 26; x++) {
966 if ((driveflags[x] & DRIVE_NOLOADLONGS) != 0) {
967 *p = (CHAR) x + 'A';
[103]968 p++;
969 *p = 0;
[2]970 }
971 }
972 }
[551]973 if (!pp[1])
[2]974 *pp = 0;
[123]975 bstrip(s);
[2]976 return s;
977}
978
[1394]979BOOL needs_quoting(PCSZ f)
[103]980{
[2]981 register CHAR *p = " &|<>";
982
[551]983 while (*p) {
984 if (strchr(f, *p))
[2]985 return TRUE;
986 p++;
987 }
988 return FALSE;
989}
990
[551]991BOOL IsBinary(register CHAR * str, ULONG len)
[103]992{
[766]993 register ULONG x = 0;
[2]994
[551]995 if (str) {
996 while (x < len) {
[1386]997 if ((UINT) str[x] < ' ' && str[x] != '\r' && str[x] != '\n' && str[x] != '\t'
998 && str[x] != '\x1b' && str[x] != '\x1a' && str[x] != '\x07'
[1394]999 && str[x] != '\x0c') {
1000 return TRUE;
[1386]1001 }
[2]1002 x++;
1003 }
1004 }
1005 return FALSE;
1006}
1007
[551]1008BOOL TestBinary(CHAR * filename)
[103]1009{
[551]1010 HFILE handle;
1011 ULONG ulAction;
1012 ULONG len;
1013 APIRET rc;
[850]1014 CHAR buff[4096]; // 06 Oct 07 SHL protect against NTFS defect
[2]1015
[551]1016 if (filename) {
[844]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)) {
[2]1022 len = 512;
[551]1023 rc = DosRead(handle, buff, len, &len);
[2]1024 DosClose(handle);
[551]1025 if (!rc && len)
1026 return IsBinary(buff, len);
[2]1027 }
1028 }
1029 return FALSE;
1030}
1031
[1193]1032#if 0 // JBS 11 Sep 08
[551]1033char *IsVowel(char a)
[103]1034{
[551]1035 return (strchr("aeiouAEIOU", a) != NULL) ? "n" : NullStr;
[2]1036}
[1187]1037#endif
[2]1038
[551]1039VOID GetDesktopName(CHAR * objectpath, ULONG size)
[103]1040{
[551]1041 PFN WQDPath;
[2]1042 HMODULE hmod = 0;
[551]1043 APIRET rc;
[766]1044 ULONG startdrive = 3;
[551]1045 CHAR objerr[CCHMAXPATH];
[2]1046
[328]1047 if (!objectpath) {
1048 Runtime_Error(pszSrcFile, __LINE__, "null pointer");
[2]1049 return;
[328]1050 }
[2]1051 *objectpath = 0;
[328]1052 if (OS2ver[0] > 20 || (OS2ver[0] == 20 && OS2ver[1] >= 30)) {
[2]1053 /*
1054 * if running under warp, we can get the desktop name
1055 * this way...
1056 */
[551]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);
[2]1062 DosFreeModule(hmod);
1063 }
1064 }
[328]1065 if (!*objectpath) {
1066 // Fall back to INI content
1067 if (!PrfQueryProfileString(HINI_SYSTEMPROFILE,
1068 "FolderWorkareaRunningObjects",
1069 NULL,
1070 "\0",
[551]1071 (PVOID) objectpath, sizeof(objectpath))) {
1072 Win_Error(HWND_DESKTOP, HWND_DESKTOP, pszSrcFile, __LINE__,
[1398]1073 PCSZ_PRFQUERYPROFILESTRING);
[2]1074 *objectpath = 0;
[328]1075 }
1076 else if (!*objectpath || IsFile(objectpath)) {
1077 Runtime_Error(pszSrcFile, __LINE__, "bad FolderWorkareaRunningObjects");
1078 *objectpath = 0;
1079 }
1080 if (!*objectpath) {
[552]1081 // Fall back
[2]1082 DosError(FERR_DISABLEHARDERR);
[551]1083 DosQuerySysInfo(QSV_BOOT_DRIVE, QSV_BOOT_DRIVE,
1084 (PVOID) & startdrive, (ULONG) sizeof(ULONG));
[552]1085 sprintf(objectpath, GetPString(IDS_PATHTODESKTOP), ((CHAR) startdrive) + '@');
[2]1086 }
1087 }
1088}
[793]1089
1090#pragma alloc_text(VALID,CheckDrive,IsRoot,IsFile,IsFullName,needsquoting)
1091#pragma alloc_text(VALID,IsValidDir,IsValidDrive,MakeValidDir,IsVowel)
[897]1092#pragma alloc_text(VALID,IsFileSame,IsNewer,TestFDates,TestCDates,RootName,MakeFullName)
[793]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.