source: trunk/dll/filldir.c@ 1194

Last change on this file since 1194 was 1182, checked in by John Small, 17 years ago

Ticket 187: Draft 2: Move remaining function declarations

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