source: trunk/dll/filldir.c@ 1146

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

Fixes strrchr trap in FreeCnrItemData when pci->pszFileName is NULL (Ticket 278)

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