source: trunk/dll/filldir.c@ 1288

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

Fix combinations not being scanned (DRIVE_REMOTE DRIVE_SLOW) and (DRIVE_VIRTUAL DRIVE_SLOW) in 4 pass scan logic.

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