source: trunk/dll/filldir.c@ 744

Last change on this file since 744 was 744, checked in by Steven Levine, 18 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: 44.7 KB
Line 
1
2/***********************************************************************
3
4 $Id: filldir.c 744 2007-07-30 02:42:59Z 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 WinSendMsg(hwnd, CM_REMOVEDETAILFIELDINFO, MPVOID,
1490 MPFROM2SHORT(0, CMA_FREE));
1491}
1492
1493
1494/**
1495 * Free storage associated with container item
1496 */
1497
1498static VOID FreeCnrItemData(PCNRITEM pci)
1499{
1500 if (pci->pszSubject && pci->pszSubject != NullStr)
1501 xfree(pci->pszSubject);
1502
1503 if (pci->pszLongname && pci->pszLongname != NullStr &&
1504 pci->pszLongname != pci->pszFileName && pci->pszLongname != pci->pszDisplayName)
1505 xfree(pci->pszLongname);
1506
1507 if (pci->pszFileName && pci->pszFileName != NullStr)
1508 xfree(pci->pszFileName);
1509}
1510
1511/**
1512 * Free container item and associated storage
1513 */
1514
1515VOID FreeCnrItem(HWND hwnd, PCNRITEM pci)
1516{
1517 FreeCnrItemData(pci);
1518
1519 if (!WinSendMsg(hwnd, CM_FREERECORD, MPFROMP(&pci), MPFROMSHORT(1))) {
1520 // Win_Error2(hwnd, HWND_DESKTOP, pszSrcFile, __LINE__,IDS_CMFREEERRTEXT);
1521 Win_Error(hwnd, HWND_DESKTOP, pszSrcFile, __LINE__,"CM_FREERECORD");
1522 }
1523}
1524
1525/**
1526 * Remove item from container and free associated storage
1527 */
1528
1529VOID RemoveCnrItems(HWND hwnd, PCNRITEM pci, USHORT usCnt, USHORT usFlags)
1530{
1531 if (usCnt == 0) {
1532 if (pci != NULL)
1533 Runtime_Error(pszSrcFile, __LINE__, "pci not NULL");
1534 else {
1535 for (;;) {
1536 pci = (PCNRITEM)WinSendMsg(hwnd, CM_QUERYRECORD, MPVOID,
1537 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
1538 if (!pci)
1539 break;
1540 else if ((INT)pci == -1) {
1541 Win_Error(hwnd, HWND_DESKTOP, pszSrcFile, __LINE__,"CM_QUERYRECORD");
1542 break;
1543 }
1544 else
1545 RemoveCnrItems(hwnd, pci, 1, usFlags);
1546 }
1547 }
1548 }
1549 else if (usCnt != 1)
1550 Runtime_Error(pszSrcFile, __LINE__, "count not 1");
1551 else {
1552 FreeCnrItemData(pci);
1553
1554 DbgMsg(pszSrcFile, __LINE__, "removing %p %u", pci, usCnt);
1555 if (!WinSendMsg(hwnd, CM_REMOVERECORD, MPFROMP(&pci), MPFROM2SHORT(usCnt, CMA_FREE))) {
1556 // Win_Error2(hwnd, HWND_DESKTOP, pszSrcFile, __LINE__,IDS_CMREMOVEERRTEXT);
1557 Win_Error(hwnd, HWND_DESKTOP, pszSrcFile, __LINE__,"CM_REMOVERECORD");
1558 }
1559 }
1560}
1561
Note: See TracBrowser for help on using the repository browser.