source: trunk/dll/filldir.c@ 772

Last change on this file since 772 was 771, checked in by Gregg Young, 18 years ago

Increase subject to 1024 reduce DosSleep times

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