source: trunk/dll/filldir.c@ 1089

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

Ticket 114: Support user-selectable env. strings in Tree container.

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