source: trunk/dll/filldir.c@ 1120

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

Comments for CS 1113

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