source: trunk/dll/filldir.c@ 985

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

Update sizes dialog (ticket 44); Make max command line length user settable (ticket 199); use xfree for free in most cases (ticket 212); initial code to check for valid ini file (ticket 102); Some additional refactoring and structure rework; Some documentation updates;

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