source: trunk/dll/filldir.c@ 1080

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

More Fortify infrastructure enhancements
Rework Fortify_SetOwner
Add Fortify_BecomeOwner
Avoid more spurious leak reports

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