source: trunk/dll/filldir.c@ 1178

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

Remove extra pszLongName logic in FreeCnrItemData

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