source: trunk/dll/filldir.c@ 1113

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

Use pszDisplayName for display in dirsize.c change free code to free it; fix memory leak in dirsize. (Ticket 269)

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