source: trunk/dll/filldir.c@ 760

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

Update #pragma alloc_test for new functions

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