source: trunk/dll/filldir.c@ 756

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

Cleanup for ticket 138 & 24

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