source: trunk/dll/filldir.c@ 1159

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

Ticket 187: Draft 1: Functions only

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