source: trunk/dll/filldir.c@ 1223

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

Ticket 187: Moved typedef's and some #define's from fm3dll.h

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