source: trunk/dll/valid.c@ 1628

Last change on this file since 1628 was 1628, checked in by Gregg Young, 14 years ago

Hard coded the flags for the xDosAlloc* wrappers and added a description for each of them.

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