source: trunk/dll/valid.c@ 1402

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

Remove variable aurgs from docopy & unlinkf (not used); Move more strings to PCSZs and string table; Move PCSZs to compile time initialization; Fix hang on startup caused by a drive scan and a dircnr scan trying to update a drive in the tree at the same time (related to the "treeswitch options); Code cleanup mainly removal of old printfs, SayMsgs, DbgMsg and unneeded %s.

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