source: trunk/dll/valid.c@ 1358

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

Comments for CS 1354/55

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 25.6 KB
RevLine 
[48]1
2/***********************************************************************
3
4 $Id: valid.c 1358 2008-12-27 00:03:08Z 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);
[1354]602 } //fixme protectonly BMT GKY 23 Dec 08
[551]603 if ((!ret && (!apptype ||
604 (apptype &
605 (FAPPTYP_NOTWINDOWCOMPAT |
606 FAPPTYP_WINDOWCOMPAT |
607 FAPPTYP_WINDOWAPI |
608 FAPPTYP_BOUND |
609 FAPPTYP_DOS |
610 FAPPTYP_WINDOWSREAL |
611 FAPPTYP_WINDOWSPROT |
612 FAPPTYP_32BIT |
613 0x1000)))) ||
614 (p && (!stricmp(p, ".CMD") || !stricmp(p, ".BAT"))))
[2]615 return TRUE;
616 }
617 return FALSE;
618}
619
[551]620VOID ArgDriveFlags(INT argc, CHAR ** argv)
[103]621{
[2]622 INT x;
623
[551]624 for (x = 1; x < argc; x++) {
625 if (*argv[x] == '/' && isalpha(argv[x][1])) {
[2]626
627 CHAR *p = &argv[x][1];
628
[551]629 while (isalpha(*p)) {
[103]630 driveflags[toupper(*p) - 'A'] |= DRIVE_IGNORE;
631 p++;
[2]632 }
633 }
[551]634 else if (*argv[x] == ';' && isalpha(argv[x][1])) {
[2]635
636 CHAR *p = &argv[x][1];
637
[551]638 while (isalpha(*p)) {
[103]639 driveflags[toupper(*p) - 'A'] |= DRIVE_NOPRESCAN;
640 p++;
[2]641 }
642 }
[552]643 else if (*argv[x] == '`' && isalpha(argv[x][1])) {
644
645 CHAR *p = &argv[x][1];
646
647 while (isalpha(*p)) {
648 driveflags[toupper(*p) - 'A'] |= DRIVE_NOSTATS;
649 p++;
650 }
651 }
[551]652 else if (*argv[x] == ',' && isalpha(argv[x][1])) {
[2]653
654 CHAR *p = &argv[x][1];
655
[551]656 while (isalpha(*p)) {
[103]657 driveflags[toupper(*p) - 'A'] |= DRIVE_NOLOADICONS;
658 p++;
[2]659 }
660 }
[552]661 else if (*argv[x] == '-' && isalpha(argv[x][1])) {
[2]662
663 CHAR *p = &argv[x][1];
664
[551]665 while (isalpha(*p)) {
[103]666 driveflags[toupper(*p) - 'A'] |= DRIVE_NOLOADSUBJS;
667 p++;
[2]668 }
669 }
[551]670 else if (*argv[x] == '\'' && isalpha(argv[x][1])) {
[2]671
672 CHAR *p = &argv[x][1];
673
[551]674 while (isalpha(*p)) {
[103]675 driveflags[toupper(*p) - 'A'] |= DRIVE_NOLOADLONGS;
676 p++;
[2]677 }
678 }
679 }
680}
681
[551]682VOID DriveFlagsOne(INT x)
[70]683{
[551]684 INT removable;
685 CHAR szDrive[] = " :\\", FileSystem[CCHMAXPATH];
686 ULONG drvtype;
[2]687
[551]688 *szDrive = (CHAR) (x + 'A');
[2]689 *FileSystem = 0;
690 drvtype = 0;
[551]691 removable = CheckDrive(*szDrive, FileSystem, &drvtype);
[2]692 driveserial[x] = -1;
693 driveflags[x] &= (DRIVE_IGNORE | DRIVE_NOPRESCAN | DRIVE_NOLOADICONS |
[103]694 DRIVE_NOLOADSUBJS | DRIVE_NOLOADLONGS |
[1354]695 DRIVE_INCLUDEFILES | DRIVE_SLOW | DRIVE_NOSTATS |
696 DRIVE_WRITEVERIFYOFF);
[551]697 if (removable != -1) {
[70]698 struct
699 {
[2]700 ULONG serial;
[551]701 CHAR volumelength;
702 CHAR volumelabel[CCHMAXPATH];
703 }
704 volser;
[2]705
706 DosError(FERR_DISABLEHARDERR);
[551]707 if (!DosQueryFSInfo((ULONG) x + 1, FSIL_VOLSER, &volser, sizeof(volser)))
[2]708 driveserial[x] = volser.serial;
709 else
710 DosError(FERR_DISABLEHARDERR);
711 }
712 else
713 driveflags[x] |= DRIVE_INVALID;
714 driveflags[x] |= ((removable == -1 || removable == 1) ?
[551]715 DRIVE_REMOVABLE : 0);
716 if (drvtype & DRIVE_REMOTE)
[2]717 driveflags[x] |= DRIVE_REMOTE;
[552]718 if(!stricmp(FileSystem,NDFS32)){
719 driveflags[x] |= DRIVE_VIRTUAL;
720 driveflags[x] &= (~DRIVE_REMOTE);
721 }
722 if(!stricmp(FileSystem,RAMFS)){
723 driveflags[x] |= DRIVE_RAMDISK;
724 driveflags[x] &= (~DRIVE_REMOTE);
725 }
[555]726 if(!stricmp(FileSystem,NTFS))
727 driveflags[x] |= DRIVE_NOTWRITEABLE;
[551]728 if (strcmp(FileSystem, HPFS) &&
729 strcmp(FileSystem, JFS) &&
730 strcmp(FileSystem, CDFS) &&
[552]731 strcmp(FileSystem, ISOFS) &&
732 strcmp(FileSystem, RAMFS) &&
733 strcmp(FileSystem, FAT32) &&
[555]734 strcmp(FileSystem, NTFS) &&
735 strcmp(FileSystem, NDFS32) &&
[552]736 strcmp(FileSystem, HPFS386)) {
[2]737 driveflags[x] |= DRIVE_NOLONGNAMES;
[70]738 }
[552]739
740 if (!strcmp(FileSystem, CDFS) || !strcmp(FileSystem, ISOFS)) {
[2]741 removable = 1;
[551]742 driveflags[x] |= (DRIVE_REMOVABLE | DRIVE_NOTWRITEABLE | DRIVE_CDROM);
[2]743 }
[1351]744 if (!stricmp(FileSystem, CBSIFS)) {
[2]745 driveflags[x] |= DRIVE_ZIPSTREAM;
746 driveflags[x] &= (~DRIVE_REMOTE);
[551]747 if (drvtype & DRIVE_REMOVABLE)
[2]748 driveflags[x] |= DRIVE_REMOVABLE;
[551]749 if (!(drvtype & DRIVE_NOLONGNAMES))
[2]750 driveflags[x] &= (~DRIVE_NOLONGNAMES);
751 }
752}
753
[551]754VOID FillInDriveFlags(VOID * dummy)
[103]755{
[1354]756 ULONG ulDriveNum, ulDriveMap, size;
[2]757 register INT x;
758
[551]759 for (x = 0; x < 26; x++)
[2]760 driveflags[x] &= (DRIVE_IGNORE | DRIVE_NOPRESCAN | DRIVE_NOLOADICONS |
[103]761 DRIVE_NOLOADSUBJS | DRIVE_NOLOADLONGS |
[1354]762 DRIVE_INCLUDEFILES | DRIVE_SLOW | DRIVE_NOSTATS |
763 DRIVE_WRITEVERIFYOFF);
[551]764 memset(driveserial, -1, sizeof(driveserial));
[2]765 DosError(FERR_DISABLEHARDERR);
[551]766 DosQCurDisk(&ulDriveNum, &ulDriveMap);
767 for (x = 0; x < 26; x++) {
[766]768 if (ulDriveMap & (1 << x) && !(driveflags[x] & DRIVE_IGNORE)) {
[2]769 {
[1354]770 ULONG flags = 0, size = sizeof(ULONG);
771 CHAR FlagKey[80];
[2]772
[1354]773 sprintf(FlagKey, "%c.DriveFlags", (CHAR) (x + 'A'));
774 if (PrfQueryProfileData(fmprof, appname, FlagKey, &flags, &size) &&
775 size == sizeof(ULONG))
776 driveflags[x] |= flags;
[2]777 }
778
[551]779 if (x > 1) {
780 if (!(driveflags[x] & DRIVE_NOPRESCAN))
[103]781 DriveFlagsOne(x);
782 else
783 driveserial[x] = -1;
[2]784 }
785 else {
[103]786 driveflags[x] |= (DRIVE_REMOVABLE | DRIVE_NOLONGNAMES);
787 driveserial[x] = -1;
[2]788 }
789 }
[766]790 else if (!(ulDriveMap & (1 << x)))
[2]791 driveflags[x] |= DRIVE_INVALID;
792 }
793 {
[551]794 ULONG startdrive = 3L;
[2]795
796 DosError(FERR_DISABLEHARDERR);
[551]797 DosQuerySysInfo(QSV_BOOT_DRIVE, QSV_BOOT_DRIVE,
798 (PVOID) & startdrive, (ULONG) sizeof(ULONG));
799 if (startdrive)
[2]800 driveflags[startdrive - 1] |= DRIVE_BOOT;
801 }
[1354]802 {
803 INT x;
804 CHAR Key[80];
805
806 for (x = 2; x < 26; x++) {
807 sprintf(Key, "%c.VerifyOffChecked", (CHAR) (x + 'A'));
808 size = sizeof(BOOL);
809 PrfQueryProfileData(fmprof, appname, Key, &fVerifyOffChecked[x], &size);
810 if (!fVerifyOffChecked[x]) {
811 if (driveflags[x] & DRIVE_REMOVABLE)
812 driveflags[x] |= DRIVE_WRITEVERIFYOFF;
[1355]813 if (!(driveflags[x] & DRIVE_INVALID)) {
[1354]814 fVerifyOffChecked[x] = TRUE;
815 PrfWriteProfileData(fmprof, appname, Key, &fVerifyOffChecked[x], sizeof(BOOL));
816 }
817 }
818 }
819 }
[2]820}
821
[551]822CHAR *assign_ignores(CHAR * s)
[103]823{
[551]824 register INT x;
825 register CHAR *p, *pp;
[2]826
827 *s = '/';
828 s[1] = 0;
829 p = s + 1;
[551]830 if (s) {
831 for (x = 0; x < 26; x++) {
832 if ((driveflags[x] & DRIVE_IGNORE) != 0) {
833 *p = (CHAR) x + 'A';
[103]834 p++;
835 *p = 0;
[2]836 }
837 }
838 }
[551]839 if (!s[1]) {
[2]840 *s = 0;
841 pp = s;
842 }
843 else {
844 pp = &s[strlen(s)];
845 *pp = ' ';
846 pp++;
847 }
848 *pp = ';';
849 pp[1] = 0;
850 p = pp + 1;
[551]851 if (pp) {
852 for (x = 0; x < 26; x++) {
853 if ((driveflags[x] & DRIVE_NOPRESCAN) != 0) {
854 *p = (CHAR) x + 'A';
[103]855 p++;
856 *p = 0;
[2]857 }
858 }
859 }
[551]860 if (!pp[1])
[2]861 *pp = 0;
862 pp = &s[strlen(s)];
863 *pp = ' ';
864 pp++;
865 *pp = ',';
866 pp[1] = 0;
867 p = pp + 1;
[551]868 if (pp) {
869 for (x = 0; x < 26; x++) {
870 if ((driveflags[x] & DRIVE_NOLOADICONS) != 0) {
871 *p = (CHAR) x + 'A';
[103]872 p++;
873 *p = 0;
[2]874 }
875 }
876 }
[551]877 if (!pp[1])
[2]878 *pp = 0;
879 pp = &s[strlen(s)];
880 *pp = ' ';
881 pp++;
[552]882 *pp = '-';
[2]883 pp[1] = 0;
884 p = pp + 1;
[551]885 if (pp) {
886 for (x = 0; x < 26; x++) {
887 if ((driveflags[x] & DRIVE_NOLOADSUBJS) != 0) {
888 *p = (CHAR) x + 'A';
[103]889 p++;
890 *p = 0;
[2]891 }
892 }
893 }
[551]894 if (!pp[1])
[2]895 *pp = 0;
896 pp = &s[strlen(s)];
897 *pp = ' ';
898 pp++;
[552]899 *pp = '`';
900 pp[1] = 0;
901 p = pp + 1;
902 if (pp) {
903 for (x = 0; x < 26; x++) {
904 if ((driveflags[x] & DRIVE_NOSTATS) != 0) {
905 *p = (CHAR) x + 'A';
906 p++;
907 *p = 0;
908 }
909 }
910 }
911 if (!pp[1])
912 *pp = 0;
913 pp = &s[strlen(s)];
914 *pp = ' ';
915 pp++;
[2]916 *pp = '\'';
917 pp[1] = 0;
918 p = pp + 1;
[551]919 if (pp) {
920 for (x = 0; x < 26; x++) {
921 if ((driveflags[x] & DRIVE_NOLOADLONGS) != 0) {
922 *p = (CHAR) x + 'A';
[103]923 p++;
924 *p = 0;
[2]925 }
926 }
927 }
[551]928 if (!pp[1])
[2]929 *pp = 0;
[123]930 bstrip(s);
[2]931 return s;
932}
933
[551]934BOOL needs_quoting(register CHAR * f)
[103]935{
[2]936 register CHAR *p = " &|<>";
937
[551]938 while (*p) {
939 if (strchr(f, *p))
[2]940 return TRUE;
941 p++;
942 }
943 return FALSE;
944}
945
[551]946BOOL IsBinary(register CHAR * str, ULONG len)
[103]947{
[766]948 register ULONG x = 0;
[2]949
[551]950 if (str) {
951 while (x < len) {
952 if (str[x] < ' ' && str[x] != '\r' && str[x] != '\n' && str[x] != '\t'
953 && str[x] != '\x1b' && str[x] != '\x1a' && str[x] != '\07'
954 && str[x] != '\x0c')
[103]955 return TRUE;
[2]956 x++;
957 }
958 }
959 return FALSE;
960}
961
[551]962BOOL TestBinary(CHAR * filename)
[103]963{
[551]964 HFILE handle;
965 ULONG ulAction;
966 ULONG len;
967 APIRET rc;
[850]968 CHAR buff[4096]; // 06 Oct 07 SHL protect against NTFS defect
[2]969
[551]970 if (filename) {
[844]971 if (!DosOpen(filename, &handle, &ulAction, 0, 0,
972 OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS,
973 OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_NOINHERIT |
974 OPEN_FLAGS_SEQUENTIAL | OPEN_SHARE_DENYNONE |
975 OPEN_ACCESS_READONLY, 0)) {
[2]976 len = 512;
[551]977 rc = DosRead(handle, buff, len, &len);
[2]978 DosClose(handle);
[551]979 if (!rc && len)
980 return IsBinary(buff, len);
[2]981 }
982 }
983 return FALSE;
984}
985
[1193]986#if 0 // JBS 11 Sep 08
[551]987char *IsVowel(char a)
[103]988{
[551]989 return (strchr("aeiouAEIOU", a) != NULL) ? "n" : NullStr;
[2]990}
[1187]991#endif
[2]992
[551]993VOID GetDesktopName(CHAR * objectpath, ULONG size)
[103]994{
[551]995 PFN WQDPath;
[2]996 HMODULE hmod = 0;
[551]997 APIRET rc;
[766]998 ULONG startdrive = 3;
[551]999 CHAR objerr[CCHMAXPATH];
[2]1000
[328]1001 if (!objectpath) {
1002 Runtime_Error(pszSrcFile, __LINE__, "null pointer");
[2]1003 return;
[328]1004 }
[2]1005 *objectpath = 0;
[328]1006 if (OS2ver[0] > 20 || (OS2ver[0] == 20 && OS2ver[1] >= 30)) {
[2]1007 /*
1008 * if running under warp, we can get the desktop name
1009 * this way...
1010 */
[551]1011 rc = DosLoadModule(objerr, sizeof(objerr), "PMWP", &hmod);
1012 if (!rc) {
1013 rc = DosQueryProcAddr(hmod, 262, NULL, &WQDPath);
1014 if (!rc)
1015 WQDPath(objectpath, size);
[2]1016 DosFreeModule(hmod);
1017 }
1018 }
[328]1019 if (!*objectpath) {
1020 // Fall back to INI content
1021 if (!PrfQueryProfileString(HINI_SYSTEMPROFILE,
1022 "FolderWorkareaRunningObjects",
1023 NULL,
1024 "\0",
[551]1025 (PVOID) objectpath, sizeof(objectpath))) {
1026 Win_Error(HWND_DESKTOP, HWND_DESKTOP, pszSrcFile, __LINE__,
1027 "PrfQueryProfileString");
[2]1028 *objectpath = 0;
[328]1029 }
1030 else if (!*objectpath || IsFile(objectpath)) {
1031 Runtime_Error(pszSrcFile, __LINE__, "bad FolderWorkareaRunningObjects");
1032 *objectpath = 0;
1033 }
1034 if (!*objectpath) {
[552]1035 // Fall back
[2]1036 DosError(FERR_DISABLEHARDERR);
[551]1037 DosQuerySysInfo(QSV_BOOT_DRIVE, QSV_BOOT_DRIVE,
1038 (PVOID) & startdrive, (ULONG) sizeof(ULONG));
[552]1039 sprintf(objectpath, GetPString(IDS_PATHTODESKTOP), ((CHAR) startdrive) + '@');
[2]1040 }
1041 }
1042}
[793]1043
1044#pragma alloc_text(VALID,CheckDrive,IsRoot,IsFile,IsFullName,needsquoting)
1045#pragma alloc_text(VALID,IsValidDir,IsValidDrive,MakeValidDir,IsVowel)
[897]1046#pragma alloc_text(VALID,IsFileSame,IsNewer,TestFDates,TestCDates,RootName,MakeFullName)
[793]1047#pragma alloc_text(VALID,IsExecutable,IsBinary,IsDesktop,ParentIsDesktop)
1048#pragma alloc_text(FILLFLAGS,FillInDriveFlags,assign_ignores)
1049#pragma alloc_text(FILLFLAGS,ArgDriveFlags,DriveFlagsOne)
1050#pragma alloc_text(FINDDESK,GetDesktopName)
Note: See TracBrowser for help on using the repository browser.