source: trunk/dll/filldir.c @ 745

Last change on this file since 745 was 745, checked in by Steven Levine, 13 years ago

Add CNRITEM free and remove support (ticket#24)

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