source: trunk/dll/filldir.c@ 1063

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

Fortify ifdef reformat

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