source: trunk/dll/filldir.c@ 1036

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

Fortify updates including a leave scope wrapper which frees and in some cases reloads commands, archivers, association, etc.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 50.4 KB
RevLine 
[31]1
2/***********************************************************************
3
4 $Id: filldir.c 1032 2008-06-30 02:55:36Z gyoung $
5
6 Fill Directory Tree Containers
7
8 Copyright (c) 1993-98 M. Kimes
[907]9 Copyright (c) 2001, 2008 Steven H. Levine
[31]10
[145]11 10 Jan 04 SHL ProcessDirectory: avoid most large drive failures
12 24 May 05 SHL Rework Win_Error usage
[167]13 24 May 05 SHL Rework for CNRITEM.szSubject
14 25 May 05 SHL Rework for ULONGLONG
15 25 May 05 SHL Rework FillInRecordFromFFB
16 25 May 05 SHL Rework FillTreeCnr
[174]17 28 May 05 SHL Drop stale debug code
[188]18 05 Jun 05 SHL Comments
[214]19 09 Jun 05 SHL Rework WinLoadFileIcon enables
20 09 Jun 05 SHL Rework IDFile
[246]21 13 Aug 05 SHL Renames
[282]22 24 Oct 05 SHL FillInRecordFromFFB: correct longname display enable
23 24 Oct 05 SHL FillInRecordFromFSA: correct longname display enable
24 24 Oct 05 SHL Drop obsolete code
[359]25 22 Jul 06 SHL Check more run time errors
[534]26 20 Oct 06 SHL Sync . .. check code
27 22 Oct 06 GKY Add NDFS32 support
[552]28 17 Feb 07 GKY Additional archive and image file tyoes identifed by extension
29 17 Feb 07 GKY Add more drive types
[557]30 09 Mar 07 GKY Use SelectDriveIcon
[572]31 20 Mar 07 GKY Increase extention check to 4 letters for icon selections
[705]32 23 Jun 07 GKY Fixed ram disk without a directory not appearing on states drive list
[737]33 23 Jul 07 SHL Sync with CNRITEM updates (ticket#24)
[744]34 29 Jul 07 SHL Add CNRITEM free and remove support (ticket#24)
[751]35 02 Aug 07 SHL Add FileAttrToString
[756]36 03 Aug 07 GKY Enlarged and made setable everywhere Findbuf (speed file loading)
[760]37 04 Aug 07 SHL Update #pragma alloc_test for new functions
[775]38 06 Aug 07 GKY Reduce DosSleep times (ticket 148)
[783]39 13 Aug 07 SHL Sync code with other FilesToGet usage and optimize
40 13 Aug 07 SHL Move #pragma alloc_text to end for OpenWatcom compat
[856]41 04 Nov 07 GKY Use commaFmtULL to display large file sizes
[985]42 29 Feb 08 GKY Use xfree where appropriate
[31]43
44***********************************************************************/
45
[2]46#include <stdlib.h>
47#include <string.h>
48#include <ctype.h>
[763]49
[783]50#if 0 // fixme to disable or to be configurable
[751]51#include <malloc.h> // _heapchk
[763]52#endif
[167]53
[907]54#define INCL_DOS
55#define INCL_WIN
56#define INCL_DOSERRORS
57#define INCL_LONGLONG
58
59#include "fm3str.h"
60#include "filldir.h"
61#include "errutil.h" // Dos_Error...
62#include "strutil.h" // GetPString
[2]63#include "fm3dll.h"
64
[1009]65#include "fortify.h" // 06 May 08 SHL
66
[359]67static PSZ pszSrcFile = __FILE__;
68
[751]69/**
70 * Return display string given standard file attribute mask
71 * @param fileAttr attribute mask in FILEFINDBUF format
72 * @return fixed length string for display
73 */
74
75const PSZ FileAttrToString(ULONG fileAttr)
76{
77 // From os2win.h
78 // FILE_ATTRIBUTE_READONLY 0x00000001
79 // FILE_ATTRIBUTE_HIDDEN 0x00000002
80 // FILE_ATTRIBUTE_SYSTEM 0x00000004
81 // 0x00000008
82 // FILE_ATTRIBUTE_DIRECTORY 0x00000010
83 // FILE_ATTRIBUTE_ARCHIVE 0x00000020
84
85 static CHAR *apszAttrString[] = {
86 // RHSDA
87 "-----",
88 "R----",
89 "-H---",
90 "RH---",
91 "--S--",
92 "R-S--",
93 "-HS--",
94 "RHS--",
95 "---D-",
96 "R--D-",
97 "-H-D-",
98 "RH-D-",
99 "--SD-",
100 "R-SD-",
101 "-HSD-",
102 "RHSD-",
103 "----A",
104 "R---A",
105 "-H--A",
106 "RH--A",
107 "--S-A",
108 "R-S-A",
109 "-HS-A",
110 "RHS-A",
111 "---DA",
112 "R--DA",
113 "-H-DA",
114 "RH-DA",
115 "--SDA",
116 "R-SDA",
117 "-HSDA",
118 "RHSDA"
119 };
120
121 fileAttr = ((fileAttr & 0x30) >> 1) | (fileAttr & 7); // Drop don't care bit from index
122
123 return apszAttrString[fileAttr];
124
125}
126
[214]127static HPOINTER IDFile(PSZ p)
[90]128{
[2]129 HPOINTER hptr;
[551]130 ULONG cmp;
[572]131 CHAR cmps[5];
[2]132
[551]133 p = strrchr(p, '.');
[572]134 if (p && !p[5]) {
[214]135 cmps[0] = '.';
136 cmps[1] = toupper(p[1]);
137 cmps[2] = toupper(p[2]);
138 cmps[3] = toupper(p[3]);
[572]139 cmps[4] = toupper(p[4]);
[214]140
[551]141 cmp = *(ULONG *) cmps;
[214]142
[551]143 if (cmp == *(ULONG *) ".EXE" || cmp == *(ULONG *) ".CMD" ||
144 cmp == *(ULONG *) ".BAT" || cmp == *(ULONG *) ".COM")
[214]145 hptr = hptrApp;
[551]146 else if (cmp == *(ULONG *) ".ZIP" || cmp == *(ULONG *) ".LZH" ||
147 cmp == *(ULONG *) ".ARJ" || cmp == *(ULONG *) ".ARC" ||
[552]148 cmp == *(ULONG *) ".ZOO" || cmp == *(ULONG *) ".RAR" ||
149 cmp == *(ULONG *) ".TAR" || cmp == *(ULONG *) ".TGZ" ||
150 cmp == *(ULONG *) ".GZ" || cmp == *(ULONG *) ".Z" ||
151 cmp == *(ULONG *) ".CAB" || cmp == *(ULONG *) ".BZ2")
[214]152 hptr = hptrArc;
[551]153 else if (cmp == *(ULONG *) ".BMP" || cmp == *(ULONG *) ".ICO" ||
154 cmp == *(ULONG *) ".PTR" || cmp == *(ULONG *) ".GIF" ||
155 cmp == *(ULONG *) ".TIF" || cmp == *(ULONG *) ".PCX" ||
[552]156 cmp == *(ULONG *) ".TGA" || cmp == *(ULONG *) ".XBM" ||
157 cmp == *(ULONG *) ".JPEG" || cmp == *(ULONG *) ".JPG" ||
158 cmp == *(ULONG *) ".PNG" || cmp == *(ULONG *) ".PSD" ||
159 cmp == *(ULONG *) ".LGO" || cmp == *(ULONG *) ".EPS" ||
160 cmp == *(ULONG *) ".RLE" || cmp == *(ULONG *) ".RAS" ||
161 cmp == *(ULONG *) ".PLC" || cmp == *(ULONG *) ".MSP" ||
162 cmp == *(ULONG *) ".IFF" || cmp == *(ULONG *) ".FIT" ||
163 cmp == *(ULONG *) ".DCX" || cmp == *(ULONG *) ".MAC" ||
164 cmp == *(ULONG *) ".SFF" || cmp == *(ULONG *) ".SGI" ||
165 cmp == *(ULONG *) ".XWD" || cmp == *(ULONG *) ".XPM" ||
166 cmp == *(ULONG *) ".WPG" || cmp == *(ULONG *) ".CUR" ||
167 cmp == *(ULONG *) ".PNM" || cmp == *(ULONG *) ".PPM" ||
168 cmp == *(ULONG *) ".PGM" || cmp == *(ULONG *) ".PBM")
[214]169 hptr = hptrArt;
170 else
[551]171 hptr = (HPOINTER) 0;
[214]172 }
173 else
[551]174 hptr = (HPOINTER) 0;
[214]175
[2]176 return hptr;
177}
178
[214]179static BOOL IsDefaultIcon(HPOINTER hptr)
180{
181 HPOINTER hptr2;
182 HPOINTER hptr3;
183 UINT u;
184
185 static HPOINTER hptrPMFile;
186 static HPOINTER hptrWPSFile;
187
[551]188 if (!hptrPMFile) {
189 hptrPMFile = WinQuerySysPointer(HWND_DESKTOP, SPTR_FILE, FALSE);
[214]190 }
191
192 // try to guess WPS default file icon
[551]193 hptr2 = (HPOINTER) 0;
194 for (u = 0; !hptrWPSFile && u < 10; u++) {
[214]195 char szFileName[CCHMAXPATH];
196 char *psz;
197
198 psz = getenv("TMP");
199 if (!psz && *psz)
200 psz = getenv("TEMP");
[551]201 if (psz && *psz) {
[214]202 strcpy(szFileName, psz);
203 psz = szFileName + strlen(szFileName) - 1;
[551]204 if (*psz != '\\') {
[214]205 psz++;
206 *psz++ = '\\';
207 }
208 }
209 else
210 psz = szFileName;
211
[551]212 sprintf(psz, "%08x.%03x", rand() & 0xffffffff, rand() & 0xfff);
213 if (IsFile(szFileName) != 1) {
214 FILE *fp = fopen(szFileName, "w");
215
216 if (fp) {
[214]217 fclose(fp);
218 hptr3 = WinLoadFileIcon(szFileName, FALSE);
219 unlinkf("%s", szFileName);
220 if (!hptr2)
221 hptr2 = hptr3;
[551]222 else if (hptr3 == hptr3) {
[214]223 hptrWPSFile = hptr3; // Got same icon twice
224 break;
225 }
226 }
227 }
228 DosSleep(rand() % 100);
229
[731]230 } // for
[214]231
232 return hptr == hptrPMFile || hptr == hptrWPSFile;
233
[731]234} // IsDefaultIcon
[214]235
[731]236ULONGLONG FillInRecordFromFFB(HWND hwndCnr,
237 PCNRITEM pci,
[551]238 const PSZ pszDirectory,
[841]239 const PFILEFINDBUF4L pffb,
[731]240 const BOOL partial,
[737]241 DIRCNRDATA *dcd)
[31]242{
[841]243 // fill in a container record from a FILEFINDBUF4L structure
[2]244
[551]245 CHAR *p;
246 HPOINTER hptr;
[2]247
248 pci->hwndCnr = hwndCnr;
[731]249
250 /* note that we cheat below, and accept the full pathname in pszDirectory
251 if !*pffb->achName. This speeds up and simplifies processing elsewhere
[167]252 (like in update.c)
[551]253 */
[763]254 if (!*pffb->achName) {
[773]255 pci->pszFileName = xstrdup(pszDirectory, pszSrcFile, __LINE__);
[1018]256 //strcpy(pci->pszFileName, pszDirectory);
[763]257 }
[731]258 else {
259 INT c = strlen(pszDirectory);
260 INT c2 = pffb->cchName + 1;
261 if (pszDirectory[c - 1] != '\\')
262 c2++;
[773]263 pci->pszFileName = xmalloc(c + c2, pszSrcFile, __LINE__);
[731]264 memcpy(pci->pszFileName, pszDirectory, c + 1);
265 p = pci->pszFileName + c - 1;
[167]266 if (*p != '\\') {
[2]267 p++;
268 *p = '\\';
269 }
270 p++;
[551]271 memcpy(p, pffb->achName, pffb->cchName + 1);
[2]272 }
[731]273
[783]274 // load the object's Subject, if required
[756]275 pci->pszSubject = NullStr;
[167]276 if (pffb->cbList > 4L &&
277 dcd && fLoadSubject &&
[730]278 (isalpha(*pci->pszFileName) &&
[731]279 !(driveflags[toupper(*pci->pszFileName) - 'A'] & DRIVE_NOLOADSUBJS)))
280 {
[551]281 APIRET rc;
282 EAOP2 eaop;
[2]283 PGEA2LIST pgealist;
284 PFEA2LIST pfealist;
[551]285 PGEA2 pgea;
286 PFEA2 pfea;
287 CHAR *value;
[2]288
[551]289 pgealist = xmallocz(sizeof(GEA2LIST) + 32, pszSrcFile, __LINE__);
[359]290 if (pgealist) {
[2]291 pgea = &pgealist->list[0];
[551]292 strcpy(pgea->szName, SUBJECT);
[2]293 pgea->cbName = strlen(pgea->szName);
[188]294 pgea->oNextEntryOffset = 0;
[2]295 pgealist->cbList = (sizeof(GEA2LIST) + pgea->cbName);
[551]296 pfealist = xmallocz(1532, pszSrcFile, __LINE__);
[359]297 if (pfealist) {
[214]298 pfealist->cbList = 1024;
299 eaop.fpGEA2List = pgealist;
300 eaop.fpFEA2List = pfealist;
301 eaop.oError = 0;
[730]302 rc = DosQueryPathInfo(pci->pszFileName, FIL_QUERYEASFROMLIST,
[551]303 (PVOID) & eaop, (ULONG) sizeof(EAOP2));
[214]304 if (!rc) {
305 pfea = &eaop.fpFEA2List->list[0];
306 value = pfea->szName + pfea->cbName + 1;
307 value[pfea->cbValue] = 0;
[551]308 if (*(USHORT *) value == EAT_ASCII)
[730]309 pci->pszSubject = xstrdup(value + (sizeof(USHORT) * 2), pszSrcFile, __LINE__);
[214]310 }
[1009]311 xfree(pfealist, pszSrcFile, __LINE__);
[2]312 }
[1009]313 xfree(pgealist, pszSrcFile, __LINE__);
[2]314 }
315 }
[731]316 if (!pci->pszSubject)
[751]317 pci->pszSubject = NullStr;
[731]318
[783]319 // load the object's longname
[762]320 pci->pszLongName = 0;
[282]321 if (fLoadLongnames &&
322 dcd &&
323 pffb->cbList > 4L &&
[730]324 isalpha(*pci->pszFileName) &&
325 ~driveflags[toupper(*pci->pszFileName) - 'A'] & DRIVE_NOLONGNAMES &&
[731]326 ~driveflags[toupper(*pci->pszFileName) - 'A'] & DRIVE_NOLOADLONGS)
327 {
[551]328 APIRET rc;
329 EAOP2 eaop;
[2]330 PGEA2LIST pgealist;
331 PFEA2LIST pfealist;
[551]332 PGEA2 pgea;
333 PFEA2 pfea;
334 CHAR *value;
[2]335
[551]336 pgealist = xmallocz(sizeof(GEA2LIST) + 32, pszSrcFile, __LINE__);
[359]337 if (pgealist) {
[2]338 pgea = &pgealist->list[0];
[551]339 strcpy(pgea->szName, LONGNAME);
[2]340 pgea->cbName = strlen(pgea->szName);
[188]341 pgea->oNextEntryOffset = 0;
[2]342 pgealist->cbList = (sizeof(GEA2LIST) + pgea->cbName);
[551]343 pfealist = xmallocz(1532, pszSrcFile, __LINE__);
[167]344 if (pfealist) {
[214]345 pfealist->cbList = 1024;
346 eaop.fpGEA2List = pgealist;
347 eaop.fpFEA2List = pfealist;
348 eaop.oError = 0;
[730]349 rc = DosQueryPathInfo(pci->pszFileName, FIL_QUERYEASFROMLIST,
[551]350 (PVOID) & eaop, (ULONG) sizeof(EAOP2));
351 if (!rc) {
[214]352 pfea = &eaop.fpFEA2List->list[0];
353 value = pfea->szName + pfea->cbName + 1;
354 value[pfea->cbValue] = 0;
[551]355 if (*(USHORT *) value == EAT_ASCII)
[762]356 pci->pszLongName = xstrdup(value + (sizeof(USHORT) * 2), pszSrcFile, __LINE__);
[214]357 }
[1009]358 xfree(pfealist, pszSrcFile, __LINE__);
[2]359 }
[1009]360 xfree(pgealist, pszSrcFile, __LINE__);
[2]361 }
362 }
[762]363 if (!pci->pszLongName)
364 pci->pszLongName = NullStr;
[731]365
[783]366 // do anything required to case of filename
[167]367 if (fForceUpper)
[730]368 strupr(pci->pszFileName);
[167]369 else if (fForceLower)
[730]370 strlwr(pci->pszFileName);
[2]371
[783]372 // get an icon to use with it
[551]373 if (pffb->attrFile & FILE_DIRECTORY) {
[214]374 // is directory
375 if (fNoIconsDirs ||
[730]376 (driveflags[toupper(*pci->pszFileName) - 'A'] & DRIVE_NOLOADICONS) ||
377 !isalpha(*pci->pszFileName)) {
[551]378 hptr = (HPOINTER) 0;
[214]379 }
380 else
[730]381 hptr = WinLoadFileIcon(pci->pszFileName, FALSE);
[2]382 }
[551]383 else {
[214]384 // is file
385 if (fNoIconsFiles ||
[730]386 (driveflags[toupper(*pci->pszFileName) - 'A'] & DRIVE_NOLOADICONS) ||
387 !isalpha(*pci->pszFileName)) {
[551]388 hptr = (HPOINTER) 0;
[167]389 }
[42]390 else
[730]391 hptr = WinLoadFileIcon(pci->pszFileName, FALSE);
[167]392
[214]393 if (!hptr || IsDefaultIcon(hptr))
[730]394 hptr = IDFile(pci->pszFileName);
[2]395 }
[214]396
[551]397 if (!hptr) {
[214]398 hptr = pffb->attrFile & FILE_DIRECTORY ?
[731]399 hptrDir : pffb->attrFile & FILE_SYSTEM ?
400 hptrSystem :
401 pffb->attrFile & FILE_HIDDEN ?
402 hptrHidden :
403 pffb->attrFile & FILE_READONLY ?
404 hptrReadonly : hptrFile;
[167]405 }
[2]406
[737]407 // Tell container what part of pathname to display
[551]408 if (partial) {
[730]409 p = strrchr(pci->pszFileName, '\\');
[551]410 if (!p) {
[730]411 p = strrchr(pci->pszFileName, ':');
[167]412 if (!p)
[730]413 p = pci->pszFileName;
[2]414 else
[214]415 p++;
[2]416 }
[167]417 else if ((dcd && dcd->type == TREE_FRAME) ||
[551]418 (!(pffb->attrFile & FILE_DIRECTORY) || !*(p + 1))) {
[2]419 p++;
[167]420 }
421 if (!*p)
[730]422 p = pci->pszFileName;
[2]423 }
424 else
[730]425 p = pci->pszFileName;
[737]426 pci->pszDisplayName = p;
427
[856]428 //comma format the file size for large file support
[859]429 {
[856]430 CHAR szBuf[30];
431 CommaFmtULL(szBuf, sizeof(szBuf), pffb->cbFile, ' ');
432 pci->pszFmtFileSize = xstrdup(szBuf, pszSrcFile, __LINE__);
433 }
434
[783]435 // now fill the darned thing in...
[551]436 pci->date.day = pffb->fdateLastWrite.day;
437 pci->date.month = pffb->fdateLastWrite.month;
438 pci->date.year = pffb->fdateLastWrite.year + 1980;
439 pci->time.seconds = pffb->ftimeLastWrite.twosecs * 2;
440 pci->time.minutes = pffb->ftimeLastWrite.minutes;
441 pci->time.hours = pffb->ftimeLastWrite.hours;
442 pci->ladate.day = pffb->fdateLastAccess.day;
443 pci->ladate.month = pffb->fdateLastAccess.month;
444 pci->ladate.year = pffb->fdateLastAccess.year + 1980;
[2]445 pci->latime.seconds = pffb->ftimeLastAccess.twosecs * 2;
446 pci->latime.minutes = pffb->ftimeLastAccess.minutes;
[551]447 pci->latime.hours = pffb->ftimeLastAccess.hours;
448 pci->crdate.day = pffb->fdateCreation.day;
449 pci->crdate.month = pffb->fdateCreation.month;
450 pci->crdate.year = pffb->fdateCreation.year + 1980;
[2]451 pci->crtime.seconds = pffb->ftimeCreation.twosecs * 2;
452 pci->crtime.minutes = pffb->ftimeCreation.minutes;
[551]453 pci->crtime.hours = pffb->ftimeCreation.hours;
454 pci->easize = CBLIST_TO_EASIZE(pffb->cbList);
455 pci->cbFile = pffb->cbFile;
456 pci->attrFile = pffb->attrFile;
[751]457 pci->pszDispAttr = FileAttrToString(pci->attrFile);
[739]458 pci->rc.pszIcon = pci->pszDisplayName;
[551]459 pci->rc.hptrIcon = hptr;
[2]460
[783]461 // check to see if record should be visible
[167]462 if (dcd && (*dcd->mask.szMask || dcd->mask.antiattr ||
[551]463 ((dcd->mask.attrFile &
464 (FILE_HIDDEN | FILE_SYSTEM | FILE_READONLY | FILE_ARCHIVED))
465 !=
466 (FILE_HIDDEN | FILE_SYSTEM | FILE_READONLY | FILE_ARCHIVED))))
[167]467 {
[551]468 if (*dcd->mask.szMask || dcd->mask.antiattr) {
469 if (!Filter((PMINIRECORDCORE) pci, (PVOID) & dcd->mask))
[214]470 pci->rc.flRecordAttr |= CRA_FILTERED;
[2]471 }
[551]472 else if ((!(dcd->mask.attrFile & FILE_HIDDEN) &&
473 (pci->attrFile & FILE_HIDDEN)) ||
474 (!(dcd->mask.attrFile & FILE_SYSTEM) &&
475 (pci->attrFile & FILE_SYSTEM)) ||
476 (!(dcd->mask.attrFile & FILE_READONLY) &&
477 (pci->attrFile & FILE_READONLY)) ||
478 (!(dcd->mask.attrFile & FILE_ARCHIVED) &&
479 (pci->attrFile & FILE_ARCHIVED))) {
[2]480 pci->rc.flRecordAttr |= CRA_FILTERED;
[167]481 }
[2]482 }
483
484 return pffb->cbFile + pci->easize;
485
[731]486} // FillInRecordFromFFB
[2]487
[841]488ULONGLONG FillInRecordFromFSA(HWND hwndCnr, PCNRITEM pci,
[907]489 const PSZ pszFileName,
490 const PFILESTATUS4L pfsa4,
491 const BOOL partial, DIRCNRDATA * dcd) // Optional
[31]492{
[551]493 HPOINTER hptr;
[731]494 CHAR *p;
[2]495
[841]496 // fill in a container record from a FILESTATUS4L structure
[2]497
498 pci->hwndCnr = hwndCnr;
[773]499 pci->pszFileName = xstrdup(pszFileName, pszSrcFile, __LINE__);
[763]500 strcpy(pci->pszFileName, pszFileName);
[731]501
[783]502 // load the object's Subject, if required
[756]503 pci->pszSubject = NullStr;
[841]504 if (pfsa4->cbList > 4 &&
[167]505 dcd &&
506 fLoadSubject &&
[730]507 (!isalpha(*pci->pszFileName) ||
[731]508 !(driveflags[toupper(*pci->pszFileName) - 'A'] & DRIVE_NOLOADSUBJS)))
509 {
[551]510 APIRET rc;
511 EAOP2 eaop;
[2]512 PGEA2LIST pgealist;
513 PFEA2LIST pfealist;
[551]514 PGEA2 pgea;
515 PFEA2 pfea;
516 CHAR *value;
[2]517
[551]518 pgealist = xmallocz(sizeof(GEA2LIST) + 32, pszSrcFile, __LINE__);
[167]519 if (pgealist) {
[2]520 pgea = &pgealist->list[0];
[551]521 strcpy(pgea->szName, SUBJECT);
[2]522 pgea->cbName = strlen(pgea->szName);
[188]523 pgea->oNextEntryOffset = 0;
[2]524 pgealist->cbList = (sizeof(GEA2LIST) + pgea->cbName);
[551]525 pfealist = xmallocz(1532, pszSrcFile, __LINE__);
[167]526 if (pfealist) {
[214]527 pfealist->cbList = 1024;
528 eaop.fpGEA2List = pgealist;
529 eaop.fpFEA2List = pfealist;
530 eaop.oError = 0;
[730]531 rc = DosQueryPathInfo(pci->pszFileName, FIL_QUERYEASFROMLIST,
[551]532 (PVOID) & eaop, (ULONG) sizeof(EAOP2));
[214]533 if (!rc) {
534 pfea = &eaop.fpFEA2List->list[0];
535 value = pfea->szName + pfea->cbName + 1;
536 value[pfea->cbValue] = 0;
[551]537 if (*(USHORT *) value == EAT_ASCII)
[731]538 pci->pszSubject = xstrdup(value + (sizeof(USHORT) * 2), pszSrcFile, __LINE__);
[214]539 }
[1009]540 xfree(pfealist, pszSrcFile, __LINE__);
[2]541 }
[1009]542 xfree(pgealist, pszSrcFile, __LINE__);
[2]543 }
544 }
[731]545 if (!pci->pszSubject)
[751]546 pci->pszSubject = NullStr;
[731]547
[762]548 pci->pszLongName = 0;
[282]549 if (fLoadLongnames &&
[167]550 dcd &&
[282]551 pfsa4->cbList > 4L &&
[730]552 isalpha(*pci->pszFileName) &&
553 ~driveflags[toupper(*pci->pszFileName) - 'A'] & DRIVE_NOLONGNAMES &&
[731]554 ~driveflags[toupper(*pci->pszFileName) - 'A'] & DRIVE_NOLOADLONGS)
555 {
[551]556 APIRET rc;
557 EAOP2 eaop;
[2]558 PGEA2LIST pgealist;
559 PFEA2LIST pfealist;
[551]560 PGEA2 pgea;
561 PFEA2 pfea;
562 CHAR *value;
[2]563
[551]564 pgealist = xmallocz(sizeof(GEA2LIST) + 32, pszSrcFile, __LINE__);
[167]565 if (pgealist) {
[2]566 pgea = &pgealist->list[0];
[551]567 strcpy(pgea->szName, LONGNAME);
[2]568 pgea->cbName = strlen(pgea->szName);
[188]569 pgea->oNextEntryOffset = 0;
[2]570 pgealist->cbList = (sizeof(GEA2LIST) + pgea->cbName);
[551]571 pfealist = xmallocz(1532, pszSrcFile, __LINE__);
[167]572 if (pfealist) {
[214]573 pfealist->cbList = 1024;
574 eaop.fpGEA2List = pgealist;
575 eaop.fpFEA2List = pfealist;
576 eaop.oError = 0;
[730]577 rc = DosQueryPathInfo(pci->pszFileName, FIL_QUERYEASFROMLIST,
[551]578 (PVOID) & eaop, (ULONG) sizeof(EAOP2));
[214]579 if (!rc) {
580 pfea = &eaop.fpFEA2List->list[0];
[731]581 value = pfea->szName + pfea->cbName + 1; // Point at EA value
582 value[pfea->cbValue] = 0; // Terminate
583 if (*(USHORT *) value == EAT_ASCII) {
584 p = value + sizeof(USHORT) * 2; // Point at value string
[762]585 pci->pszLongName = xstrdup(p, pszSrcFile, __LINE__);
[731]586 }
[214]587 }
[1009]588 xfree(pfealist, pszSrcFile, __LINE__);
[2]589 }
[1009]590 xfree(pgealist, pszSrcFile, __LINE__);
[2]591 }
592 }
[762]593 if (!pci->pszLongName)
594 pci->pszLongName = NullStr;
[731]595
[167]596 if (fForceUpper)
[730]597 strupr(pci->pszFileName);
[167]598 else if (fForceLower)
[730]599 strlwr(pci->pszFileName);
[2]600
[551]601 if (pfsa4->attrFile & FILE_DIRECTORY) {
[214]602 if (fNoIconsDirs ||
[730]603 (driveflags[toupper(*pci->pszFileName) - 'A'] & DRIVE_NOLOADICONS) ||
604 !isalpha(*pci->pszFileName)) {
[551]605 hptr = (HPOINTER) 0;
[214]606 }
607 else
[730]608 hptr = WinLoadFileIcon(pci->pszFileName, FALSE);
[2]609 }
[551]610 else {
[214]611 if (fNoIconsFiles ||
[730]612 (driveflags[toupper(*pci->pszFileName) - 'A'] & DRIVE_NOLOADICONS) ||
613 !isalpha(*pci->pszFileName)) {
614 hptr = IDFile(pci->pszFileName);
[2]615 }
[214]616 else
[730]617 hptr = WinLoadFileIcon(pci->pszFileName, FALSE);
[2]618 }
[551]619 if (!hptr) {
[214]620 hptr = pfsa4->attrFile & FILE_DIRECTORY ?
[551]621 hptrDir :
622 pfsa4->attrFile & FILE_SYSTEM ?
623 hptrSystem :
624 pfsa4->attrFile & FILE_HIDDEN ?
625 hptrHidden : pfsa4->attrFile & FILE_READONLY ? hptrReadonly : hptrFile;
[214]626 }
[2]627
[737]628 // Tell container what part of pathname to display
[551]629 if (partial) {
[730]630 p = strrchr(pci->pszFileName, '\\');
[167]631 if (!p) {
[730]632 p = strrchr(pci->pszFileName, ':');
[167]633 if (!p)
[730]634 p = pci->pszFileName;
[2]635 else
[214]636 p++;
[2]637 }
[167]638 else if ((dcd && dcd->type == TREE_FRAME) ||
[551]639 !(pfsa4->attrFile & FILE_DIRECTORY) || !*(p + 1))
[2]640 p++;
[167]641 if (!*p)
[730]642 p = pci->pszFileName;
[2]643 }
644 else
[730]645 p = pci->pszFileName;
[737]646 pci->pszDisplayName = p;
647
[856]648 //comma format the file size for large file support
[859]649 {
650 CHAR szBuf[30];
[856]651 CommaFmtULL(szBuf, sizeof(szBuf), pfsa4->cbFile, ' ');
652 pci->pszFmtFileSize = xstrdup(szBuf, pszSrcFile, __LINE__);
653 }
[551]654 pci->date.day = pfsa4->fdateLastWrite.day;
655 pci->date.month = pfsa4->fdateLastWrite.month;
656 pci->date.year = pfsa4->fdateLastWrite.year + 1980;
657 pci->time.seconds = pfsa4->ftimeLastWrite.twosecs * 2;
658 pci->time.minutes = pfsa4->ftimeLastWrite.minutes;
659 pci->time.hours = pfsa4->ftimeLastWrite.hours;
660 pci->ladate.day = pfsa4->fdateLastAccess.day;
661 pci->ladate.month = pfsa4->fdateLastAccess.month;
662 pci->ladate.year = pfsa4->fdateLastAccess.year + 1980;
[2]663 pci->latime.seconds = pfsa4->ftimeLastAccess.twosecs * 2;
664 pci->latime.minutes = pfsa4->ftimeLastAccess.minutes;
[551]665 pci->latime.hours = pfsa4->ftimeLastAccess.hours;
666 pci->crdate.day = pfsa4->fdateCreation.day;
667 pci->crdate.month = pfsa4->fdateCreation.month;
668 pci->crdate.year = pfsa4->fdateCreation.year + 1980;
[2]669 pci->crtime.seconds = pfsa4->ftimeCreation.twosecs * 2;
670 pci->crtime.minutes = pfsa4->ftimeCreation.minutes;
[551]671 pci->crtime.hours = pfsa4->ftimeCreation.hours;
672 pci->easize = CBLIST_TO_EASIZE(pfsa4->cbList);
673 pci->cbFile = pfsa4->cbFile;
674 pci->attrFile = pfsa4->attrFile;
[751]675 pci->pszDispAttr = FileAttrToString(pci->attrFile);
[739]676 pci->rc.pszIcon = pci->pszDisplayName;
[551]677 pci->rc.hptrIcon = hptr;
[2]678
[167]679 if (dcd &&
680 (*dcd->mask.szMask || dcd->mask.antiattr ||
681 ((dcd->mask.attrFile &
[551]682 (FILE_HIDDEN | FILE_SYSTEM | FILE_READONLY | FILE_ARCHIVED)) !=
683 (FILE_HIDDEN | FILE_SYSTEM | FILE_READONLY | FILE_ARCHIVED)))) {
684 if (*dcd->mask.szMask || dcd->mask.antiattr) {
685 if (!Filter((PMINIRECORDCORE) pci, (PVOID) & dcd->mask))
[214]686 pci->rc.flRecordAttr |= CRA_FILTERED;
[2]687 }
[167]688 else if ((!(dcd->mask.attrFile & FILE_HIDDEN) &&
[214]689 (pci->attrFile & FILE_HIDDEN)) ||
690 (!(dcd->mask.attrFile & FILE_SYSTEM) &&
691 (pci->attrFile & FILE_SYSTEM)) ||
692 (!(dcd->mask.attrFile & FILE_READONLY) &&
693 (pci->attrFile & FILE_READONLY)) ||
694 (!(dcd->mask.attrFile & FILE_ARCHIVED) &&
695 (pci->attrFile & FILE_ARCHIVED)))
[2]696 pci->rc.flRecordAttr |= CRA_FILTERED;
697 }
698
699 return pfsa4->cbFile + pci->easize;
700
[731]701} // FillInRecordFromFSA
[2]702
[737]703VOID ProcessDirectory(const HWND hwndCnr,
704 const PCNRITEM pciParent,
705 const CHAR *szDirBase,
706 const BOOL filestoo,
707 const BOOL recurse,
708 const BOOL partial,
709 CHAR *stopflag,
710 DIRCNRDATA *dcd, // Optional
711 ULONG *pulTotalFiles, // Optional
[167]712 PULONGLONG pullTotalBytes) // Optional
[31]713{
[2]714 /* put all the directories (and files if filestoo is TRUE) from a
715 * directory into the container. recurse through subdirectories if
716 * recurse is TRUE.
717 */
718
[551]719 PSZ pszFileSpec;
720 INT t;
[841]721 PFILEFINDBUF4L paffbFound;
722 PFILEFINDBUF4L *papffbSelected;
723 PFILEFINDBUF4L pffbFile;
724 PFILEFINDBUF4L paffbTotal = NULL;
725 PFILEFINDBUF4L paffbTemp;
[551]726 HDIR hdir = HDIR_CREATE;
[783]727 ULONG ulFindCnt;
728 ULONG ulFindMax;
729 ULONG ulSelCnt;
[551]730 ULONG ulTotal = 0;
731 ULONGLONG ullBytes;
732 ULONGLONG ullTotalBytes;
733 ULONG ulReturnFiles = 0;
734 ULONGLONG ullReturnBytes = 0;
735 PCH pchEndPath;
736 APIRET rc;
737 PCNRITEM pci;
738 PCNRITEM pciFirst;
739 RECORDINSERT ri;
740 BOOL ok = TRUE;
[783]741 ULONG ulBufBytes;
742 ULONG x;
[2]743
[551]744 if (isalpha(*szDirBase) && szDirBase[1] == ':' && szDirBase[2] == '\\') {
[167]745 if ((driveflags[toupper(*szDirBase) - 'A'] & DRIVE_REMOTE) && fRemoteBug)
[783]746 ulFindMax = 1; // file system gets confused
[167]747 else if (driveflags[toupper(*szDirBase) - 'A'] & DRIVE_ZIPSTREAM)
[783]748 ulFindMax = min(FilesToGet, 225); // anything more is wasted
[2]749 else
[783]750 ulFindMax = FilesToGet; // full-out
[2]751 }
[924]752 else
[783]753 ulFindMax = FilesToGet;
[924]754
[167]755 if (OS2ver[0] == 20 && OS2ver[1] < 30)
[841]756 ulFindMax = min(ulFindMax, (65535 / sizeof(FILEFINDBUF4L)));
[2]757
[841]758 ulBufBytes = ulFindMax * sizeof(FILEFINDBUF4L);
[783]759
[551]760 pszFileSpec = xmalloc(CCHMAXPATH + 2, pszSrcFile, __LINE__);
[783]761 paffbFound = xmalloc(ulBufBytes, pszSrcFile, __LINE__);
[841]762 papffbSelected = xmalloc(sizeof(PFILEFINDBUF4L) * ulFindMax, pszSrcFile, __LINE__);
[783]763
[167]764 if (paffbFound && papffbSelected && pszFileSpec) {
[2]765 t = strlen(szDirBase);
[551]766 memcpy(pszFileSpec, szDirBase, t + 1);
[42]767 pchEndPath = pszFileSpec + t;
[167]768 if (*(pchEndPath - 1) != '\\') {
[551]769 memcpy(pchEndPath, "\\", 2);
[2]770 pchEndPath++;
771 }
[551]772 memcpy(pchEndPath, "*", 2);
[2]773 DosError(FERR_DISABLEHARDERR);
[783]774 ulFindCnt = ulFindMax;
[838]775 rc = xDosFindFirst(pszFileSpec,
776 &hdir,
777 FILE_NORMAL | FILE_READONLY | FILE_ARCHIVED |
778 FILE_SYSTEM | FILE_HIDDEN |
779 (filestoo ? FILE_DIRECTORY : MUST_HAVE_DIRECTORY),
780 paffbFound,
781 ulBufBytes,
782 &ulFindCnt,
[841]783 FIL_QUERYEASIZEL);
[2]784 priority_normal();
[924]785 *pchEndPath = 0; // Chop off wildcard
[551]786 if (!rc) {
[783]787 do {
[214]788 /*
789 * remove . and .. from list if present
790 * also counter file system bugs that sometimes
791 * allows normal files to slip through when
792 * only directories should appear (only a few
793 * network file systems exhibit such a problem).
794 */
[2]795
[214]796 if (stopflag && *stopflag)
797 goto Abort;
[783]798 pffbFile = paffbFound;
799 ulSelCnt = 0;
800 for (;;) {
[214]801 if (!*pffbFile->achName ||
[783]802 (!filestoo && ~pffbFile->attrFile & FILE_DIRECTORY) ||
803 (pffbFile->attrFile & FILE_DIRECTORY &&
[534]804 pffbFile->achName[0] == '.' &&
805 (!pffbFile->achName[1] ||
[551]806 (pffbFile->achName[1] == '.' && !pffbFile->achName[2])))) {
[783]807 // ulFindCnt--; // Got . or .. or file to be skipped
[174]808 }
[214]809 else
[783]810 papffbSelected[ulSelCnt++] = pffbFile; // Remember selected file
[551]811 if (!pffbFile->oNextEntryOffset) {
[783]812 // ulFindCnt = ulSelCnt; // Remember number selected
[214]813 break;
814 }
[841]815 pffbFile = (PFILEFINDBUF4L)((PBYTE)pffbFile + pffbFile->oNextEntryOffset);
[763]816 } // for
[783]817 if (ulSelCnt) {
818 // One or more entries selected
[214]819 if (stopflag && *stopflag)
820 goto Abort;
[551]821 if (fSyncUpdates) {
[214]822 pciFirst = WinSendMsg(hwndCnr, CM_ALLOCRECORD,
[783]823 MPFROMLONG(EXTRA_RECORD_BYTES),
824 MPFROMLONG(ulSelCnt));
[359]825 if (!pciFirst) {
[551]826 Win_Error2(hwndCnr, HWND_DESKTOP, pszSrcFile, __LINE__,
827 IDS_CMALLOCRECERRTEXT);
[359]828 ok = FALSE;
829 ullTotalBytes = 0;
830 }
831 else {
[907]832 // 04 Jan 08 SHL fixme like comp.c to handle less than ulSelCnt records
[214]833 pci = pciFirst;
834 ullTotalBytes = 0;
[783]835 // Insert selected in container
836 for (x = 0; x < ulSelCnt; x++) {
837 pffbFile = papffbSelected[x];
[551]838 ullBytes = FillInRecordFromFFB(hwndCnr, pci, pszFileSpec,
839 pffbFile, partial, dcd);
840 pci = (PCNRITEM) pci->rc.preccNextRecord;
[214]841 ullTotalBytes += ullBytes;
[731]842 } // for
[783]843 // 13 Aug 07 SHL ulSelCnt checked already?
844 // if (ulSelCnt) {
845 memset(&ri, 0, sizeof(RECORDINSERT));
846 ri.cb = sizeof(RECORDINSERT);
847 ri.pRecordOrder = (PRECORDCORE) CMA_END;
848 ri.pRecordParent = (PRECORDCORE) pciParent;
849 ri.zOrder = (ULONG) CMA_TOP;
850 ri.cRecordsInsert = ulSelCnt;
851 ri.fInvalidateRecord =
852 !fSyncUpdates && dcd && dcd->type == DIR_FRAME ?
[551]853 FALSE : TRUE;
[783]854 if (!WinSendMsg(hwndCnr,
855 CM_INSERTRECORD,
856 MPFROMP(pciFirst), MPFROMP(&ri))) {
857 DosSleep(10); // Give GUI time to work
858 WinSetFocus(HWND_DESKTOP, hwndCnr);
[214]859 if (!WinSendMsg(hwndCnr,
860 CM_INSERTRECORD,
[551]861 MPFROMP(pciFirst), MPFROMP(&ri))) {
[783]862 Win_Error2(hwndCnr, HWND_DESKTOP, pszSrcFile, __LINE__,
863 IDS_CMINSERTERRTEXT);
864 ok = FALSE;
865 ullTotalBytes = 0;
866 if (WinIsWindow((HAB) 0, hwndCnr))
867 FreeCnrItemList(hwndCnr, pciFirst);
[214]868 }
[783]869 // }
[214]870 }
871 }
[551]872 if (ok) {
[214]873 ullReturnBytes += ullTotalBytes;
[783]874 ulReturnFiles += ulSelCnt;
[214]875 }
[783]876 } // if sync updates
[551]877 else {
[783]878 // Append newly selected entries to aggregate list
[359]879 paffbTemp = xrealloc(paffbTotal,
[841]880 sizeof(FILEFINDBUF4L) * (ulSelCnt + ulTotal),
[551]881 pszSrcFile, __LINE__);
882 if (paffbTemp) {
[783]883 // 13 Aug 07 SHL fixme to optimize copy
[214]884 paffbTotal = paffbTemp;
[783]885 for (x = 0; x < ulSelCnt; x++)
[214]886 paffbTotal[x + ulTotal] = *papffbSelected[x];
[783]887 ulTotal += ulSelCnt;
[214]888 }
[551]889 else {
[214]890 saymsg(MB_ENTER,
891 HWND_DESKTOP,
[551]892 GetPString(IDS_ERRORTEXT), GetPString(IDS_OUTOFMEMORY));
[214]893 break;
894 }
895 }
[783]896 } // if entries selected
[214]897 if (stopflag && *stopflag)
[551]898 goto Abort;
[214]899 DosError(FERR_DISABLEHARDERR);
[783]900 ulFindCnt = ulFindMax;
[850]901 rc = xDosFindNext(hdir, paffbFound, ulBufBytes, &ulFindCnt, FIL_QUERYEASIZEL);
[214]902 priority_normal();
903 if (rc)
904 DosError(FERR_DISABLEHARDERR);
[783]905 } while (!rc);
906
[2]907 DosFindClose(hdir);
[1009]908 xfree(paffbFound, pszSrcFile, __LINE__);
[985]909 paffbFound = NULL;
[1009]910 xfree(papffbSelected, pszSrcFile, __LINE__);
[985]911 papffbSelected = NULL;
[2]912
[551]913 if (ulTotal && paffbTotal) {
[167]914
[214]915 if (stopflag && *stopflag)
916 goto Abort;
[167]917
[214]918 pciFirst = WinSendMsg(hwndCnr, CM_ALLOCRECORD,
[783]919 MPFROMLONG(EXTRA_RECORD_BYTES), MPFROMLONG(ulTotal));
[359]920 if (!pciFirst) {
[551]921 Win_Error2(hwndCnr, HWND_DESKTOP, pszSrcFile, __LINE__,
922 IDS_CMALLOCRECERRTEXT);
[359]923 ok = FALSE;
924 ullTotalBytes = 0;
925 }
926 else {
[907]927 // 04 Jan 08 SHL fixme like comp.c to handle less than ulSelCnt records
[214]928 pci = pciFirst;
929 ullTotalBytes = 0;
[783]930 pffbFile = paffbTotal;
931 for (x = 0; x < ulTotal; x++) {
[551]932 ullBytes = FillInRecordFromFFB(hwndCnr, pci, pszFileSpec,
933 pffbFile, partial, dcd);
934 pci = (PCNRITEM) pci->rc.preccNextRecord;
[214]935 ullTotalBytes += ullBytes;
[783]936 // Can not use offset since we have merged lists - this should be equivalent
[841]937 pffbFile = (PFILEFINDBUF4L)((PBYTE)pffbFile + sizeof(FILEFINDBUF4L));
[214]938 }
[551]939 if (ulTotal) {
940 memset(&ri, 0, sizeof(RECORDINSERT));
941 ri.cb = sizeof(RECORDINSERT);
942 ri.pRecordOrder = (PRECORDCORE) CMA_END;
943 ri.pRecordParent = (PRECORDCORE) pciParent;
944 ri.zOrder = (ULONG) CMA_TOP;
945 ri.cRecordsInsert = ulTotal;
946 ri.fInvalidateRecord = (!fSyncUpdates && dcd &&
947 dcd->type == DIR_FRAME) ? FALSE : TRUE;
948 if (!WinSendMsg(hwndCnr, CM_INSERTRECORD,
949 MPFROMP(pciFirst), MPFROMP(&ri))) {
[783]950 DosSleep(10); // Give GUI time to work
[551]951 WinSetFocus(HWND_DESKTOP, hwndCnr);
952 if (!WinSendMsg(hwndCnr, CM_INSERTRECORD,
953 MPFROMP(pciFirst), MPFROMP(&ri))) {
954 Win_Error2(hwndCnr, HWND_DESKTOP, pszSrcFile, __LINE__,
955 IDS_CMINSERTERRTEXT);
[214]956 ok = FALSE;
957 ullTotalBytes = 0;
[751]958 if (WinIsWindow((HAB) 0, hwndCnr))
959 FreeCnrItemList(hwndCnr, pciFirst);
[214]960 }
961 }
962 }
963 }
[551]964 if (ok) {
[214]965 ullReturnBytes += ullTotalBytes;
[783]966 ulReturnFiles += ulFindCnt;
[214]967 }
[2]968 }
969 }
970
[924]971 /**
972 * DosFind for subdirectories of a read-only directory on a FAT volume
973 * returns path not found if there are no subdirectories
974 * FAT FS seems to ignore . and .. in this case
975 * Map to no more files
976 * We could verify that directory is marked read-only, it's probably not
977 * worth the extra code since we do verify 2 out of 3 prerequisites
978 * 15 Jan 08 SHL
979 */
980 if (rc == ERROR_PATH_NOT_FOUND && !filestoo) {
981 ULONG ulDriveType = 0;
982 CHAR szFSType[CCHMAXPATH];
983 INT removable = CheckDrive(*pszFileSpec, szFSType, &ulDriveType);
984 if (removable != -1 && strcmp(szFSType, "FAT") == 0)
985 rc = ERROR_NO_MORE_FILES;
986 }
987
[783]988 if (rc && rc != ERROR_NO_MORE_FILES) {
989 Dos_Error(MB_ENTER, rc, HWND_DESKTOP, pszSrcFile, __LINE__,
990 GetPString(IDS_CANTFINDDIRTEXT), pszFileSpec);
991 }
992
[167]993 if (!fSyncUpdates && dcd && dcd->type == DIR_FRAME)
[551]994 WinSendMsg(hwndCnr, CM_INVALIDATERECORD, MPVOID,
995 MPFROM2SHORT(0, CMA_ERASE));
[2]996 }
997Abort:
[1009]998 xfree(paffbTotal, pszSrcFile, __LINE__);
999 xfree(pszFileSpec, pszSrcFile, __LINE__);
1000 xfree(paffbFound, pszSrcFile, __LINE__);
1001 xfree(papffbSelected, pszSrcFile, __LINE__);
[783]1002
[551]1003 if (recurse) {
[2]1004 pci = WinSendMsg(hwndCnr, CM_QUERYRECORD, MPFROMP(pciParent),
[214]1005 MPFROM2SHORT(CMA_FIRSTCHILD, CMA_ITEMORDER));
[762]1006 while (pci && (INT)pci != -1) {
[167]1007 if (pci->attrFile & FILE_DIRECTORY)
[551]1008 Stubby(hwndCnr, pci);
[2]1009 pci = WinSendMsg(hwndCnr, CM_QUERYRECORD, MPFROMP(pci),
[214]1010 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
[2]1011 }
1012 }
1013
[167]1014 if (pulTotalFiles)
1015 *pulTotalFiles = ulReturnFiles;
[2]1016
[167]1017 if (pullTotalBytes)
1018 *pullTotalBytes = ullReturnBytes;
[2]1019
[731]1020} // ProcessDirectory
[167]1021
1022VOID FillDirCnr(HWND hwndCnr,
[551]1023 CHAR * pszDirectory,
[924]1024 DIRCNRDATA * dcd,
1025 PULONGLONG pullTotalBytes)
[90]1026{
[167]1027 ProcessDirectory(hwndCnr,
[924]1028 (PCNRITEM)NULL,
[167]1029 pszDirectory,
[737]1030 TRUE, // filestoo
1031 FALSE, // recurse
1032 TRUE, // partial
1033 dcd ? &dcd->stopflag : NULL,
1034 dcd,
[924]1035 NULL, // total files
[737]1036 pullTotalBytes);
[2]1037 DosPostEventSem(CompactSem);
1038
[762]1039#if 0 // fixme to be gone or to be configurable
[751]1040 {
1041 int state = _heapchk();
1042 if (state != _HEAPOK)
1043 Runtime_Error(pszSrcFile, __LINE__, "heap corrupted %d", state);
[763]1044 else
1045 DbgMsg(pszSrcFile, __LINE__, "_memavl %u", _memavl());
[751]1046 }
1047#endif
1048
[731]1049} // FillDirCnr
[2]1050
[551]1051VOID FillTreeCnr(HWND hwndCnr, HWND hwndParent)
[90]1052{
[924]1053 ULONG ulCurDriveNum, ulDriveMap, numtoinsert = 0;
1054 ULONG ulDriveType;
[551]1055 PCNRITEM pci, pciFirst = NULL, pciNext, pciParent = NULL;
1056 INT x, removable;
[731]1057 CHAR suggest[32];
[739]1058 CHAR szDrive[] = " :\\";
[924]1059 CHAR szFSType[CCHMAXPATH];
[841]1060 FILESTATUS4L fsa4;
[551]1061 APIRET rc;
1062 BOOL drivesbuilt = FALSE;
[739]1063 ULONG startdrive = 3;
1064
[2]1065 static BOOL didonce = FALSE;
1066
1067 fDummy = TRUE;
1068 *suggest = 0;
[689]1069 for (x = 0; x < 26; x++) {
[2]1070 driveflags[x] &= (DRIVE_IGNORE | DRIVE_NOPRESCAN | DRIVE_NOLOADICONS |
[214]1071 DRIVE_NOLOADSUBJS | DRIVE_NOLOADLONGS |
[552]1072 DRIVE_INCLUDEFILES | DRIVE_SLOW | DRIVE_NOSTATS);
[689]1073 }
[551]1074 memset(driveserial, -1, sizeof(driveserial));
[739]1075
1076 DosError(FERR_DISABLEHARDERR);
1077 if (!DosQuerySysInfo(QSV_BOOT_DRIVE,
1078 QSV_BOOT_DRIVE,
1079 (PVOID) &startdrive,
1080 (ULONG) sizeof(ULONG)) &&
1081 startdrive)
[2]1082 {
[739]1083 driveflags[startdrive - 1] |= DRIVE_BOOT;
1084 }
[2]1085
1086 DosError(FERR_DISABLEHARDERR);
[731]1087 rc = DosQCurDisk(&ulCurDriveNum, &ulDriveMap);
[551]1088 if (rc) {
[2]1089 Dos_Error(MB_CANCEL,
[214]1090 rc,
1091 HWND_DESKTOP,
[551]1092 pszSrcFile, __LINE__, GetPString(IDS_FILLDIRQCURERRTEXT));
[2]1093 exit(0);
1094 }
[739]1095
[731]1096 // Calc number of drive items to create
[689]1097 for (x = 0; x < 26; x++) {
[167]1098 if ((ulDriveMap & (1L << x)) && !(driveflags[x] & DRIVE_IGNORE))
[2]1099 numtoinsert++;
[689]1100 }
[739]1101
[689]1102 if (numtoinsert) {
[2]1103 pciFirst = WinSendMsg(hwndCnr,
[214]1104 CM_ALLOCRECORD,
[751]1105 MPFROMLONG(EXTRA_RECORD_BYTES),
[551]1106 MPFROMLONG((ULONG) numtoinsert));
[689]1107 }
[739]1108
[359]1109 if (!pciFirst) {
[744]1110 Win_Error2(hwndCnr, HWND_DESKTOP, pszSrcFile, __LINE__, IDS_CMALLOCRECERRTEXT);
[907]1111 // 04 Jan 08 SHL fixme not just up and die
[359]1112 exit(0);
1113 }
[689]1114
[907]1115 // 04 Jan 08 SHL fixme like comp.c to handle less than ulSelCnt records
[739]1116 pci = pciFirst;
1117 for (x = 0; x < 26; x++) {
1118 if ((ulDriveMap & (1L << x)) && !(driveflags[x] & DRIVE_IGNORE)) {
[2]1119
[739]1120 CHAR s[80];
1121 ULONG flags = 0;
1122 ULONG size = sizeof(ULONG);
[2]1123
[739]1124 *szDrive = (CHAR)x + 'A'; // Build path spec
[731]1125
[739]1126 sprintf(s, "%c.DriveFlags", toupper(*szDrive));
1127 if (PrfQueryProfileData(fmprof, appname, s, &flags, &size) &&
1128 size == sizeof(ULONG)) {
1129 driveflags[toupper(*szDrive) - 'A'] |= flags;
1130 }
[2]1131
[739]1132 if (x > 1) {
1133 // Hard drive (2..N)
1134 if (!(driveflags[x] & DRIVE_NOPRESCAN)) {
[924]1135 *szFSType = 0;
1136 ulDriveType = 0;
1137 removable = CheckDrive(*szDrive, szFSType, &ulDriveType);
[739]1138 driveserial[x] = -1;
1139 if (removable != -1) {
1140 struct {
1141 ULONG serial;
1142 CHAR volumelength;
1143 CHAR volumelabel[CCHMAXPATH];
1144 } volser;
[2]1145
[739]1146 DosError(FERR_DISABLEHARDERR);
1147 if (!DosQueryFSInfo((ULONG) x,
1148 FSIL_VOLSER, &volser, sizeof(volser))) {
1149 driveserial[x] = volser.serial;
[731]1150 }
[739]1151 }
1152 else
1153 driveflags[x] |= DRIVE_INVALID;
[731]1154
[841]1155 memset(&fsa4, 0, sizeof(FILESTATUS4L));
[739]1156 driveflags[x] |= removable == -1 || removable == 1 ?
1157 DRIVE_REMOVABLE : 0;
[924]1158 if (ulDriveType & DRIVE_REMOTE)
[739]1159 driveflags[x] |= DRIVE_REMOTE;
[924]1160 if (!stricmp(szFSType,RAMFS)) {
[739]1161 driveflags[x] |= DRIVE_RAMDISK;
1162 driveflags[x] &= ~DRIVE_REMOTE;
1163 }
[924]1164 if (!stricmp(szFSType,NDFS32)) {
[739]1165 driveflags[x] |= DRIVE_VIRTUAL;
1166 driveflags[x] &= ~DRIVE_REMOTE;
1167 }
[924]1168 if (!stricmp(szFSType,NTFS))
[739]1169 driveflags[x] |= DRIVE_NOTWRITEABLE;
[924]1170 if (strcmp(szFSType, HPFS) &&
1171 strcmp(szFSType, JFS) &&
1172 strcmp(szFSType, ISOFS) &&
1173 strcmp(szFSType, CDFS) &&
1174 strcmp(szFSType, FAT32) &&
1175 strcmp(szFSType, NDFS32) &&
1176 strcmp(szFSType, RAMFS) &&
1177 strcmp(szFSType, NTFS) &&
1178 strcmp(szFSType, HPFS386)) {
[739]1179 driveflags[x] |= DRIVE_NOLONGNAMES;
1180 }
[534]1181
[924]1182 if (!strcmp(szFSType, CDFS) || !strcmp(szFSType,ISOFS)) {
[739]1183 removable = 1;
1184 driveflags[x] |= DRIVE_REMOVABLE | DRIVE_NOTWRITEABLE |
1185 DRIVE_CDROM;
1186 }
[924]1187 else if (!stricmp(szFSType, CBSIFS)) {
[739]1188 driveflags[x] |= DRIVE_ZIPSTREAM;
1189 driveflags[x] &= ~DRIVE_REMOTE;
[924]1190 if (ulDriveType & DRIVE_REMOVABLE)
[739]1191 driveflags[x] |= DRIVE_REMOVABLE;
[924]1192 if (!(ulDriveType & DRIVE_NOLONGNAMES))
[739]1193 driveflags[x] &= ~DRIVE_NOLONGNAMES;
1194 }
[2]1195
[739]1196 pci->rc.flRecordAttr |= CRA_RECORDREADONLY;
1197 // if ((ULONG) (toupper(*pci->pszFileName) - '@') == ulCurDriveNum) // 23 Jul 07 SHL
1198 if ((ULONG)(toupper(*szDrive) - '@') == ulCurDriveNum)
1199 pci->rc.flRecordAttr |= (CRA_CURSORED | CRA_SELECTED);
[2]1200
[739]1201 if (removable == 0) {
1202 // Fixed volume
1203 pci->attrFile |= FILE_DIRECTORY;
1204 DosError(FERR_DISABLEHARDERR);
1205 rc = DosQueryPathInfo(szDrive,
[841]1206 FIL_QUERYEASIZEL,
1207 &fsa4, (ULONG) sizeof(FILESTATUS4L));
[739]1208 // ERROR_BAD_NET_RSP = 58
1209 if (rc == 58) {
[214]1210 DosError(FERR_DISABLEHARDERR);
1211 rc = DosQueryPathInfo(szDrive,
[841]1212 FIL_STANDARDL,
[847]1213 &fsa4, (ULONG) sizeof(FILESTATUS4L));
[739]1214 fsa4.cbList = 0;
1215 }
1216 if (rc && !didonce) {
1217 // Guess drive letter
1218 if (!*suggest) {
1219 *suggest = '/';
1220 suggest[1] = 0;
[214]1221 }
[739]1222 sprintf(suggest + strlen(suggest), "%c" , toupper(*szDrive));
[773]1223 pci->pszFileName = xstrdup(szDrive, pszSrcFile, __LINE__);
[763]1224 strcpy(pci->pszFileName, szDrive);
[739]1225 pci->pszDisplayName = pci->pszFileName;
1226 pci->rc.pszIcon = pci->pszDisplayName;
[214]1227 pci->attrFile = FILE_DIRECTORY;
[751]1228 pci->pszDispAttr = FileAttrToString(pci->attrFile);
[739]1229 driveserial[x] = -1;
[731]1230 }
[739]1231 else
1232 FillInRecordFromFSA(hwndCnr, pci, szDrive, &fsa4, TRUE, NULL);
[214]1233 }
[551]1234 else {
[739]1235 // Removable volume
[773]1236 pci->pszFileName = xstrdup(szDrive, pszSrcFile, __LINE__);
[763]1237 strcpy(pci->pszFileName, szDrive);
[739]1238 pci->pszDisplayName = pci->pszFileName;
1239 pci->rc.pszIcon = pci->pszDisplayName;
[214]1240 pci->attrFile = FILE_DIRECTORY;
[751]1241 pci->pszDispAttr = FileAttrToString(pci->attrFile);
[214]1242 }
[739]1243 SelectDriveIcon(pci);
[214]1244 }
[551]1245 else {
[739]1246 pci->rc.hptrIcon = hptrDunno;
[773]1247 pci->pszFileName = xstrdup(szDrive, pszSrcFile, __LINE__);
[763]1248 strcpy(pci->pszFileName, szDrive);
[739]1249 pci->pszDisplayName = pci->pszFileName;
[214]1250 pci->rc.pszIcon = pci->pszFileName;
1251 pci->attrFile = FILE_DIRECTORY;
[751]1252 pci->pszDispAttr = FileAttrToString(pci->attrFile);
[214]1253 driveserial[x] = -1;
1254 }
[2]1255 }
[739]1256 else {
1257 // diskette drive (A or B)
1258 pci->rc.hptrIcon = hptrFloppy;
[773]1259 pci->pszFileName = xstrdup(szDrive, pszSrcFile, __LINE__);
[763]1260 strcpy(pci->pszFileName, szDrive);
[739]1261 pci->pszDisplayName = pci->pszFileName;
1262 pci->rc.pszIcon = pci->pszDisplayName;
1263 pci->attrFile = FILE_DIRECTORY;
[751]1264 pci->pszDispAttr = FileAttrToString(pci->attrFile);
[739]1265 driveflags[x] |= (DRIVE_REMOVABLE | DRIVE_NOLONGNAMES);
1266 driveserial[x] = -1;
1267 }
1268 pci->rc.flRecordAttr |= CRA_RECORDREADONLY;
[783]1269 pci = (PCNRITEM) pci->rc.preccNextRecord; // next rec
[739]1270 }
1271 else if (!(ulDriveMap & (1L << x)))
1272 driveflags[x] |= DRIVE_INVALID;
1273 } // for drives
[689]1274
[739]1275 PostMsg(hwndMain, UM_BUILDDRIVEBAR, MPVOID, MPVOID);
1276 drivesbuilt = TRUE;
[2]1277
[783]1278 // insert the drives
[739]1279 if (numtoinsert && pciFirst) {
1280 RECORDINSERT ri;
1281
1282 memset(&ri, 0, sizeof(RECORDINSERT));
1283 ri.cb = sizeof(RECORDINSERT);
1284 ri.pRecordOrder = (PRECORDCORE) CMA_END;
1285 ri.pRecordParent = (PRECORDCORE) NULL;
1286 ri.zOrder = (ULONG) CMA_TOP;
1287 ri.cRecordsInsert = numtoinsert;
1288 ri.fInvalidateRecord = FALSE;
1289 if (!WinSendMsg(hwndCnr,
1290 CM_INSERTRECORD, MPFROMP(pciFirst), MPFROMP(&ri)))
1291 {
[744]1292 Win_Error2(hwndCnr, HWND_DESKTOP, pszSrcFile, __LINE__,
[739]1293 IDS_CMINSERTERRTEXT);
[2]1294 }
[739]1295 }
[689]1296
[783]1297 // move cursor onto the default drive rather than the first drive
[739]1298 if (!fSwitchTree) {
1299 pci = (PCNRITEM) WinSendMsg(hwndCnr,
1300 CM_QUERYRECORD,
1301 MPVOID,
1302 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
[762]1303 while (pci && (INT)pci != -1) {
[739]1304 if ((ULONG) (toupper(*pci->pszFileName) - '@') == ulCurDriveNum) {
1305 WinSendMsg(hwndCnr,
1306 CM_SETRECORDEMPHASIS,
1307 MPFROMP(pci), MPFROM2SHORT(TRUE, CRA_CURSORED));
1308 break;
1309 }
[551]1310 pci = (PCNRITEM) WinSendMsg(hwndCnr,
1311 CM_QUERYRECORD,
[739]1312 MPFROMP(pci),
1313 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
[2]1314 }
[739]1315 }
[2]1316
[739]1317 if (hwndParent) {
1318 WinSendMsg(WinWindowFromID(WinQueryWindow(hwndParent, QW_PARENT),
1319 MAIN_DRIVELIST),
1320 LM_DELETEALL, MPVOID, MPVOID);
1321 }
[2]1322
[739]1323 if (fShowEnv) {
1324 RECORDINSERT ri;
[2]1325
[739]1326 pciParent = WinSendMsg(hwndCnr,
1327 CM_ALLOCRECORD,
[751]1328 MPFROMLONG(EXTRA_RECORD_BYTES), MPFROMLONG(1));
[739]1329 if (pciParent) {
1330 pciParent->flags |= RECFLAGS_ENV;
[773]1331 pciParent->pszFileName = xstrdup(GetPString(IDS_ENVVARSTEXT), pszSrcFile, __LINE__);
[763]1332 strcpy(pciParent->pszFileName, GetPString(IDS_ENVVARSTEXT));
1333 pciParent->pszDisplayName = pciParent->pszFileName; // 03 Aug 07 SHL
[739]1334 pciParent->rc.hptrIcon = hptrEnv;
1335 pciParent->rc.pszIcon = pciParent->pszFileName;
[751]1336 pciParent->pszDispAttr = FileAttrToString(0);
[739]1337 memset(&ri, 0, sizeof(RECORDINSERT));
1338 ri.cb = sizeof(RECORDINSERT);
1339 ri.pRecordOrder = (PRECORDCORE) CMA_END;
1340 ri.pRecordParent = (PRECORDCORE) NULL;
1341 ri.zOrder = (ULONG) CMA_TOP;
1342 ri.cRecordsInsert = 1;
1343 ri.fInvalidateRecord = FALSE;
1344 if (WinSendMsg(hwndCnr,
1345 CM_INSERTRECORD, MPFROMP(pciParent), MPFROMP(&ri))) {
[2]1346
[739]1347 char *p, *pp;
[2]1348
[739]1349 p = GetPString(IDS_ENVVARNAMES);
1350 while (*p == ' ')
1351 p++;
1352 while (*p) {
[924]1353 *szFSType = 0;
1354 pp = szFSType;
[739]1355 while (*p && *p != ' ')
1356 *pp++ = *p++;
1357 *pp = 0;
[551]1358 while (*p == ' ')
[214]1359 p++;
[924]1360 if (*szFSType &&
1361 (!stricmp(szFSType, "LIBPATH") || getenv(szFSType))) {
[739]1362 pci = WinSendMsg(hwndCnr,
1363 CM_ALLOCRECORD,
[751]1364 MPFROMLONG(EXTRA_RECORD_BYTES),
[739]1365 MPFROMLONG(1));
1366 if (pci) {
1367 CHAR fname[CCHMAXPATH];
1368 pci->flags |= RECFLAGS_ENV;
[924]1369 sprintf(fname, "%%%s%%", szFSType);
[739]1370 pci->pszFileName = xstrdup(fname, pszSrcFile, __LINE__);
1371 pci->rc.hptrIcon = hptrEnv;
1372 pci->rc.pszIcon = pci->pszFileName;
[751]1373 pci->pszDispAttr = FileAttrToString(0);
[739]1374 memset(&ri, 0, sizeof(RECORDINSERT));
1375 ri.cb = sizeof(RECORDINSERT);
1376 ri.pRecordOrder = (PRECORDCORE) CMA_END;
1377 ri.pRecordParent = (PRECORDCORE) pciParent;
1378 ri.zOrder = (ULONG) CMA_TOP;
1379 ri.cRecordsInsert = 1;
1380 ri.fInvalidateRecord = FALSE;
1381 if (!WinSendMsg(hwndCnr,
1382 CM_INSERTRECORD,
1383 MPFROMP(pci), MPFROMP(&ri))) {
[744]1384 Win_Error2(hwndCnr, HWND_DESKTOP, pszSrcFile, __LINE__,
[739]1385 IDS_CMINSERTERRTEXT);
[751]1386 FreeCnrItem(hwndCnr, pci);
[214]1387 }
1388 }
1389 }
1390 }
[739]1391 WinSendMsg(hwndCnr,
1392 CM_INVALIDATERECORD,
1393 MPFROMP(&pciParent),
1394 MPFROM2SHORT(1, CMA_ERASE | CMA_REPOSITION));
[2]1395 }
[739]1396 else
[751]1397 FreeCnrItem(hwndCnr, pciParent);
[739]1398 }
1399 } // if show env
[2]1400
[739]1401 x = 0;
1402 pci = (PCNRITEM) WinSendMsg(hwndCnr,
1403 CM_QUERYRECORD,
1404 MPVOID,
1405 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
[762]1406 while (pci && (INT)pci != -1) {
[739]1407 pciNext = (PCNRITEM) WinSendMsg(hwndCnr,
1408 CM_QUERYRECORD,
1409 MPFROMP(pci),
1410 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
1411 if (!(pci->flags & RECFLAGS_ENV)) {
1412 if ((ULONG) (toupper(*pci->pszFileName) - '@') == ulCurDriveNum ||
1413 toupper(*pci->pszFileName) > 'B')
1414 {
1415 if (!(driveflags[toupper(*pci->pszFileName) - 'A'] & DRIVE_INVALID) &&
1416 !(driveflags[toupper(*pci->pszFileName) - 'A'] & DRIVE_NOPRESCAN) &&
1417 (!fNoRemovableScan ||
1418 !(driveflags[toupper(*pci->pszFileName) - 'A'] & DRIVE_REMOVABLE)))
1419 {
1420 if (!Stubby(hwndCnr, pci) && !DRIVE_RAMDISK) {
1421 WinSendMsg(hwndCnr,
1422 CM_INVALIDATERECORD,
1423 MPFROMP(&pci),
1424 MPFROM2SHORT(1, CMA_ERASE | CMA_REPOSITION));
1425 goto SkipBadRec;
[214]1426 }
1427 }
[739]1428 }
1429 else {
1430 WinSendMsg(hwndCnr,
1431 CM_INVALIDATERECORD,
1432 MPFROMP(&pci),
1433 MPFROM2SHORT(1, CMA_ERASE | CMA_REPOSITION));
1434 }
[167]1435
[739]1436 WinSendMsg(WinWindowFromID(WinQueryWindow(hwndParent, QW_PARENT),
1437 MAIN_DRIVELIST),
1438 LM_INSERTITEM,
1439 MPFROM2SHORT(LIT_SORTASCENDING, 0),
1440 MPFROMP(pci->pszFileName));
[2]1441 }
[739]1442 SkipBadRec:
1443 x++;
1444 pci = pciNext;
[924]1445 } // while
[739]1446 if (hwndParent)
1447 WinSendMsg(WinWindowFromID(WinQueryWindow(hwndParent, QW_PARENT),
1448 MAIN_DRIVELIST), LM_SELECTITEM,
1449 MPFROM2SHORT(0, 0), MPFROMLONG(TRUE));
[2]1450
[739]1451 pci = (PCNRITEM) WinSendMsg(hwndCnr,
1452 CM_QUERYRECORD,
1453 MPVOID,
1454 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
[762]1455 while (pci && (INT)pci != -1) {
[739]1456 pciNext = (PCNRITEM) WinSendMsg(hwndCnr,
[551]1457 CM_QUERYRECORD,
1458 MPFROMP(pci),
[739]1459 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
1460 if (pci->flags & RECFLAGS_ENV) {
[551]1461 pci = (PCNRITEM) WinSendMsg(hwndCnr,
1462 CM_QUERYRECORD,
1463 MPFROMP(pci),
[739]1464 MPFROM2SHORT(CMA_FIRSTCHILD,
1465 CMA_ITEMORDER));
[762]1466 while (pci && (INT)pci != -1) {
[739]1467 if (pci->flags & RECFLAGS_ENV)
1468 FleshEnv(hwndCnr, pci);
1469 pci = (PCNRITEM) WinSendMsg(hwndCnr,
1470 CM_QUERYRECORD,
1471 MPFROMP(pci),
1472 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
1473 }
1474 break;
[2]1475 }
[739]1476 pci = (PCNRITEM) WinSendMsg(hwndCnr,
1477 CM_QUERYRECORD,
1478 MPFROMP(pci),
1479 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
1480 }
[2]1481
[167]1482 if (!drivesbuilt && hwndMain)
[551]1483 PostMsg(hwndMain, UM_BUILDDRIVEBAR, MPVOID, MPVOID);
[783]1484 DosSleep(16); // 05 Aug 07 GKY 33
[2]1485 fDummy = FALSE;
1486 DosPostEventSem(CompactSem);
[739]1487
[2]1488 {
1489 BYTE info;
1490 BOOL includesyours = FALSE;
1491
[917]1492 // 10 Jan 08 SHL fixme to understand fFirstTime
[551]1493 if (*suggest || (!(driveflags[1] & DRIVE_IGNORE) && fFirstTime)) {
1494 if (!DosDevConfig(&info, DEVINFO_FLOPPY) && info == 1) {
1495 if (!*suggest) {
[214]1496 *suggest = '/';
1497 suggest[1] = 0;
1498 }
1499 else
[551]1500 memmove(suggest + 2, suggest + 1, strlen(suggest));
[214]1501 suggest[1] = 'B';
[2]1502 }
1503 }
[551]1504 if (*suggest) {
1505 for (x = 2; x < 26; x++) {
1506 if (driveflags[x] & DRIVE_IGNORE) {
[214]1507 includesyours = TRUE;
[551]1508 sprintf(suggest + strlen(suggest), "%c", (char)(x + 'A'));
[214]1509 }
[2]1510 }
[551]1511 strcat(suggest, " %*");
[167]1512 if (saymsg(MB_YESNO | MB_ICONEXCLAMATION,
[214]1513 (hwndParent) ? hwndParent : hwndCnr,
1514 GetPString(IDS_SUGGESTTITLETEXT),
1515 GetPString(IDS_SUGGEST1TEXT),
1516 (includesyours) ? GetPString(IDS_SUGGEST2TEXT) : NullStr,
[551]1517 suggest) == MBID_YES) {
[214]1518 char s[64];
[2]1519
[214]1520 sprintf(s, "PARAMETERS=%s", suggest);
[551]1521 WinCreateObject(WPProgram, "FM/2", s, FM3Folder, CO_UPDATEIFEXISTS);
[214]1522 WinCreateObject(WPProgram,
[551]1523 "FM/2 Lite", s, FM3Folder, CO_UPDATEIFEXISTS);
[214]1524 WinCreateObject(WPProgram,
[551]1525 "Archive Viewer/2", s, FM3Tools, CO_UPDATEIFEXISTS);
[214]1526 WinCreateObject(WPProgram,
[551]1527 "Dir Sizes", s, FM3Tools, CO_UPDATEIFEXISTS);
[214]1528 WinCreateObject(WPProgram,
[551]1529 "Visual Tree", s, FM3Tools, CO_UPDATEIFEXISTS);
[214]1530 WinCreateObject(WPProgram,
[551]1531 "Visual Directory", s, FM3Tools, CO_UPDATEIFEXISTS);
[214]1532 WinCreateObject(WPProgram,
[551]1533 "Global File Viewer", s, FM3Tools, CO_UPDATEIFEXISTS);
1534 WinCreateObject(WPProgram, "Databar", s, FM3Tools, CO_UPDATEIFEXISTS);
[2]1535 }
1536 }
1537 }
[739]1538
[2]1539 didonce = TRUE;
1540
[731]1541} // FillTreeCnr
[743]1542
1543
1544/**
1545 * Empty all records from a container and free associated storage and
1546 * Free up field infos
1547 */
1548
1549VOID EmptyCnr(HWND hwnd)
1550{
1551 PFIELDINFO pfi;
1552
[762]1553#if 0 // fixme to be gone or to be configurable
[751]1554 {
1555 int state = _heapchk();
1556 if (state != _HEAPOK)
1557 Runtime_Error(pszSrcFile, __LINE__, "heap corrupted %d", state);
1558 }
1559#endif
1560
[743]1561 // Remove all records
1562 RemoveCnrItems(hwnd, NULL, 0, CMA_FREE);
1563
1564 // Remove field info descriptors
1565 pfi = (PFIELDINFO) WinSendMsg(hwnd, CM_QUERYDETAILFIELDINFO, MPVOID,
1566 MPFROMSHORT(CMA_FIRST));
[745]1567 if (pfi &&
1568 (INT)WinSendMsg(hwnd, CM_REMOVEDETAILFIELDINFO, MPVOID,
1569 MPFROM2SHORT(0, CMA_FREE)) == -1) {
1570 Win_Error(hwnd, HWND_DESKTOP, pszSrcFile, __LINE__,"CM_REMOVEDETAILFIELDINFO hwnd %x", hwnd);
1571 }
[743]1572}
1573
1574/**
1575 * Free storage associated with container item
1576 */
1577
[751]1578VOID FreeCnrItemData(PCNRITEM pci)
[743]1579{
[762]1580 PSZ psz;
[745]1581 // DbgMsg(pszSrcFile, __LINE__, "FreeCnrItemData %p", pci);
1582
[762]1583 if (pci->pszSubject && pci->pszSubject != NullStr) {
[743]1584
[762]1585 psz = pci->pszSubject;
1586 pci->pszSubject = NullStr;
[1032]1587# ifdef FORTIFY
1588 xfree(psz, pszSrcFile, __LINE__);
1589# else
[762]1590 free(psz);
[1032]1591# endif
[762]1592 }
[743]1593
[762]1594 // +1 in case long name pointing after last backslash
1595 if (pci->pszLongName &&
1596 pci->pszLongName != NullStr &&
1597 pci->pszLongName != pci->pszFileName &&
1598 pci->pszLongName != pci->pszDisplayName &&
1599 pci->pszLongName != pci->pszDisplayName + 1) {
1600 psz = pci->pszLongName;
1601 pci->pszLongName = NullStr;
[1032]1602# ifdef FORTIFY
1603 xfree(psz, pszSrcFile, __LINE__);
1604# else
[762]1605 free(psz);
[1032]1606# endif
[762]1607 }
1608
1609 if (pci->pszFileName && pci->pszFileName != NullStr) {
1610 psz = pci->pszFileName;
1611 pci->pszFileName = NullStr;
[1032]1612# ifdef FORTIFY
1613 xfree(psz, pszSrcFile, __LINE__);
1614# else
[762]1615 free(psz);
[1032]1616# endif
[762]1617 }
[857]1618
1619 if (pci->pszFmtFileSize && pci->pszFmtFileSize != NullStr) {
1620 psz = pci->pszFmtFileSize;
1621 pci->pszFmtFileSize = NullStr;
[1032]1622# ifdef FORTIFY
1623 xfree(psz, pszSrcFile, __LINE__);
1624# else
[857]1625 free(psz);
[1032]1626# endif
[857]1627 }
[743]1628}
1629
1630/**
[762]1631 * Free single container item and associated storage
[743]1632 */
1633
[762]1634VOID FreeCnrItem(HWND hwnd, PCNRITEM pci)
[743]1635{
[745]1636 // DbgMsg(pszSrcFile, __LINE__, "FreeCnrItem hwnd %x pci %p", hwnd, pci);
1637
[743]1638 FreeCnrItemData(pci);
1639
[762]1640 if (!WinSendMsg(hwnd, CM_FREERECORD, MPFROMP(&pci), MPFROMSHORT(1))) {
[744]1641 // Win_Error2(hwnd, HWND_DESKTOP, pszSrcFile, __LINE__,IDS_CMFREEERRTEXT);
[773]1642 Win_Error(hwnd, HWND_DESKTOP, pszSrcFile, __LINE__,
1643 "CM_FREERECORD hwnd %x pci %p file %s",
[783]1644 hwnd, pci,
[773]1645 pci && pci->pszFileName ? pci->pszFileName : "n/a");
[743]1646 }
1647}
1648
1649/**
[751]1650 * Free container item list and associated storage
[743]1651 */
1652
[751]1653VOID FreeCnrItemList(HWND hwnd, PCNRITEM pciFirst)
[743]1654{
[751]1655 PCNRITEM pci = pciFirst;
1656 PCNRITEM pciNext;
[762]1657 USHORT usCount;
[751]1658
[762]1659 for (usCount = 0; pci; usCount++) {
[751]1660 pciNext = (PCNRITEM) pci->rc.preccNextRecord;
[762]1661 FreeCnrItemData(pci);
[751]1662 pci = pciNext;
1663 }
[762]1664
1665 if (usCount) {
1666 if (!WinSendMsg(hwnd, CM_FREERECORD, MPFROMP(&pci), MPFROMSHORT(usCount))) {
1667 // Win_Error2(hwnd, HWND_DESKTOP, pszSrcFile, __LINE__,IDS_CMFREEERRTEXT);
1668 Win_Error(hwnd, HWND_DESKTOP, pszSrcFile, __LINE__,"CM_FREERECORD hwnd %x pci %p cnt %u", hwnd, pci, usCount);
1669 }
1670 }
[751]1671}
1672
1673/**
1674 * Remove item(s) from container and free associated storage if requested
[762]1675 * @param pciFirst points to first item to remove or NULL to remove all
1676 * @param usCnt is remove count or 0 to remove all
[751]1677 * @returns count of items remaining in container or -1 if error
1678 */
1679
[762]1680INT RemoveCnrItems(HWND hwnd, PCNRITEM pciFirst, USHORT usCnt, USHORT usFlags)
[751]1681{
[762]1682 INT remaining = usCnt;
1683 PCNRITEM pci;
[751]1684
[762]1685 if ((usCnt && !pciFirst) || (!usCnt && pciFirst)) {
1686 Runtime_Error(pszSrcFile, __LINE__, "pciFirst %p usCnt %u mismatch", pciFirst, usCnt);
[751]1687 remaining = -1;
[762]1688 }
1689 else {
1690 // Free our buffers if free requested
1691 if (usFlags & CMA_FREE) {
1692 if (pciFirst)
1693 pci = pciFirst;
1694 else {
[743]1695 pci = (PCNRITEM)WinSendMsg(hwnd, CM_QUERYRECORD, MPVOID,
[744]1696 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
[762]1697 if ((INT)pci == -1) {
[744]1698 Win_Error(hwnd, HWND_DESKTOP, pszSrcFile, __LINE__,"CM_QUERYRECORD");
[751]1699 remaining = -1;
[762]1700 pci = NULL;
1701 }
1702 }
1703 while (pci) {
[850]1704 // 12 Sep 07 SHL dwg drivebar crash testing - ticket# ???
[907]1705 static PCNRITEM pciLast; // 12 Sep 07 SHL
1706 ULONG ulSize = sizeof(*pci);
1707 ULONG ulAttr;
[850]1708 APIRET apiret = DosQueryMem((PVOID)pci, &ulSize, &ulAttr);
1709 if (apiret)
[907]1710 Dos_Error(MB_ENTER, apiret, HWND_DESKTOP, pszSrcFile, __LINE__,
[850]1711 "DosQueryMem failed pci %p pciLast %p", pci, pciLast);
[762]1712 FreeCnrItemData(pci);
[850]1713 pciLast = pci;
[762]1714 pci = (PCNRITEM)pci->rc.preccNextRecord;
1715 if (remaining && --remaining == 0)
[744]1716 break;
[762]1717 }
[743]1718 }
1719 }
[745]1720
[762]1721 // DbgMsg(pszSrcFile, __LINE__, "RemoveCnrItems %p %u %s", pci, usCnt, pci->pszFileName);
[743]1722
[762]1723 if (remaining != - 1) {
1724 remaining = (INT)WinSendMsg(hwnd, CM_REMOVERECORD, MPFROMP(&pciFirst), MPFROM2SHORT(usCnt, usFlags));
[751]1725 if (remaining == -1) {
[744]1726 // Win_Error2(hwnd, HWND_DESKTOP, pszSrcFile, __LINE__,IDS_CMREMOVEERRTEXT);
[762]1727 Win_Error(hwnd, HWND_DESKTOP, pszSrcFile, __LINE__,"CM_REMOVERECORD hwnd %x pci %p cnt %u", hwnd, pciFirst, usCnt);
[743]1728 }
1729 }
[762]1730
[751]1731 return remaining;
[743]1732}
1733
[783]1734#pragma alloc_text(FILLDIR,FillInRecordFromFFB,FillInRecordFromFSA,IDFile)
1735#pragma alloc_text(FILLDIR1,ProcessDirectory,FillDirCnr,FillTreeCnr,FileAttrToString)
1736#pragma alloc_text(EMPTYCNR,EmptyCnr,FreeCnrItemData,FreeCnrItem,FreeCnrItemList,RemoveCnrItems)
1737
Note: See TracBrowser for help on using the repository browser.