source: trunk/dll/filldir.c@ 1250

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

Scan drives in 4 passes to speed up tree scans (Ticket 25)

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