source: trunk/dll/valid.c@ 1369

Last change on this file since 1369 was 1369, checked in by Gregg Young, 17 years ago

Add check for p-rotectonly system to gray out dos/win commandline choices etc. Ticket 325 It also fixes problem with some drives not being scanned on startup.

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