source: trunk/dll/filldir.c@ 756

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

Cleanup for ticket 138 & 24

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