source: trunk/dll/valid.c@ 1544

Last change on this file since 1544 was 1544, checked in by Gregg Young, 15 years ago

Changes to fopen and _fsopen to allow FM2 to be loaded in high memory

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