source: trunk/dll/filldir.c@ 775

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

Minor clean up add comments re recent changes

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