source: trunk/dll/valid.c@ 946

Last change on this file since 946 was 946, checked in by Gregg Young, 18 years ago

Minor code cleanup and documentation for some changes. (Tickets 3, 7, 184)

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