source: trunk/dll/filldir.c@ 975

Last change on this file since 975 was 924, checked in by Steven Levine, 18 years ago

Avoid error reports for R/O FAT directories (ticket #116)
Change Config->Edit and Config->Palette menus to have no default
Move SpecialSelect to comp.c

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