source: trunk/dll/filldir.c@ 743

Last change on this file since 743 was 743, checked in by Steven Levine, 18 years ago

Baseline code for ticket 24 CNRITEM remove/free

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