source: trunk/dll/filldir.c@ 1099

Last change on this file since 1099 was 1099, checked in by Gregg Young, 17 years ago

Remove redundent strcpys from fill dir inner loop

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