source: trunk/dll/filldir.c@ 1211

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

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