source: trunk/dll/filldir.c@ 850

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

Rework large file support wrappers (ticket #41)
Add code to avoid NTFS driver small file read defect (ticket #159)
Add debug code to try to catch David's drive bar exception
Another attempt to correct newview fast viewer text load failure

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