source: trunk/dll/valid.c@ 897

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

Use CommaFmtULL for additional file, EA etc sizes display; Modify/Create TestFDates & TestCDates for comparing/sorting files or CNRITEMS by date/time.

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