source: trunk/dll/filldir.c@ 1290

Last change on this file since 1290 was 1290, checked in by Steven Levine, 17 years ago

FillTreeCnr: ensure any unchecked drives checked in pass 4

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