source: branches/ticket_150/dll/filldir.c@ 1036

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

Changed display logic so CommaFmtULL is used both with and without large file support for file size display. GiB notation can actually be selected in the source (in addition to being used automatically on very large drives).

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