source: trunk/dll/filldir.c@ 1154

Last change on this file since 1154 was 1154, checked in by Steven Levine, 17 years ago

Correct FreeCnrItemData pszDisplayName pointer overlap check

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