source: trunk/dll/filldir.c@ 858

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

Free strdup memory for large file size formatting Add GiB label to CommaFmtULL

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 49.3 KB
Line 
1
2/***********************************************************************
3
4 $Id: filldir.c 857 2007-11-04 20:58:30Z 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 if(!fNoLargeFileSupport){
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 if(!fNoLargeFileSupport){
650 CHAR szBuf[30];
651 CommaFmtULL(szBuf, sizeof(szBuf), pfsa4->cbFile, ' ');
652 pci->pszFmtFileSize = xstrdup(szBuf, pszSrcFile, __LINE__);
653 }
654 pci->date.day = pfsa4->fdateLastWrite.day;
655 pci->date.month = pfsa4->fdateLastWrite.month;
656 pci->date.year = pfsa4->fdateLastWrite.year + 1980;
657 pci->time.seconds = pfsa4->ftimeLastWrite.twosecs * 2;
658 pci->time.minutes = pfsa4->ftimeLastWrite.minutes;
659 pci->time.hours = pfsa4->ftimeLastWrite.hours;
660 pci->ladate.day = pfsa4->fdateLastAccess.day;
661 pci->ladate.month = pfsa4->fdateLastAccess.month;
662 pci->ladate.year = pfsa4->fdateLastAccess.year + 1980;
663 pci->latime.seconds = pfsa4->ftimeLastAccess.twosecs * 2;
664 pci->latime.minutes = pfsa4->ftimeLastAccess.minutes;
665 pci->latime.hours = pfsa4->ftimeLastAccess.hours;
666 pci->crdate.day = pfsa4->fdateCreation.day;
667 pci->crdate.month = pfsa4->fdateCreation.month;
668 pci->crdate.year = pfsa4->fdateCreation.year + 1980;
669 pci->crtime.seconds = pfsa4->ftimeCreation.twosecs * 2;
670 pci->crtime.minutes = pfsa4->ftimeCreation.minutes;
671 pci->crtime.hours = pfsa4->ftimeCreation.hours;
672 pci->easize = CBLIST_TO_EASIZE(pfsa4->cbList);
673 pci->cbFile = pfsa4->cbFile;
674 pci->attrFile = pfsa4->attrFile;
675 pci->pszDispAttr = FileAttrToString(pci->attrFile);
676 pci->rc.pszIcon = pci->pszDisplayName;
677 pci->rc.hptrIcon = hptr;
678
679 if (dcd &&
680 (*dcd->mask.szMask || dcd->mask.antiattr ||
681 ((dcd->mask.attrFile &
682 (FILE_HIDDEN | FILE_SYSTEM | FILE_READONLY | FILE_ARCHIVED)) !=
683 (FILE_HIDDEN | FILE_SYSTEM | FILE_READONLY | FILE_ARCHIVED)))) {
684 if (*dcd->mask.szMask || dcd->mask.antiattr) {
685 if (!Filter((PMINIRECORDCORE) pci, (PVOID) & dcd->mask))
686 pci->rc.flRecordAttr |= CRA_FILTERED;
687 }
688 else if ((!(dcd->mask.attrFile & FILE_HIDDEN) &&
689 (pci->attrFile & FILE_HIDDEN)) ||
690 (!(dcd->mask.attrFile & FILE_SYSTEM) &&
691 (pci->attrFile & FILE_SYSTEM)) ||
692 (!(dcd->mask.attrFile & FILE_READONLY) &&
693 (pci->attrFile & FILE_READONLY)) ||
694 (!(dcd->mask.attrFile & FILE_ARCHIVED) &&
695 (pci->attrFile & FILE_ARCHIVED)))
696 pci->rc.flRecordAttr |= CRA_FILTERED;
697 }
698
699 return pfsa4->cbFile + pci->easize;
700
701} // FillInRecordFromFSA
702
703VOID ProcessDirectory(const HWND hwndCnr,
704 const PCNRITEM pciParent,
705 const CHAR *szDirBase,
706 const BOOL filestoo,
707 const BOOL recurse,
708 const BOOL partial,
709 CHAR *stopflag,
710 DIRCNRDATA *dcd, // Optional
711 ULONG *pulTotalFiles, // Optional
712 PULONGLONG pullTotalBytes) // Optional
713{
714 /* put all the directories (and files if filestoo is TRUE) from a
715 * directory into the container. recurse through subdirectories if
716 * recurse is TRUE.
717 */
718
719 PSZ pszFileSpec;
720 INT t;
721 PFILEFINDBUF4L paffbFound;
722 PFILEFINDBUF4L *papffbSelected;
723 PFILEFINDBUF4L pffbFile;
724 PFILEFINDBUF4L paffbTotal = NULL;
725 PFILEFINDBUF4L paffbTemp;
726 HDIR hdir = HDIR_CREATE;
727 ULONG ulFindCnt;
728 ULONG ulFindMax;
729 ULONG ulSelCnt;
730 ULONG ulTotal = 0;
731 ULONGLONG ullBytes;
732 ULONGLONG ullTotalBytes;
733 ULONG ulReturnFiles = 0;
734 ULONGLONG ullReturnBytes = 0;
735 PCH pchEndPath;
736 APIRET rc;
737 PCNRITEM pci;
738 PCNRITEM pciFirst;
739 RECORDINSERT ri;
740 BOOL ok = TRUE;
741 ULONG ulBufBytes;
742 ULONG x;
743
744 if (isalpha(*szDirBase) && szDirBase[1] == ':' && szDirBase[2] == '\\') {
745 if ((driveflags[toupper(*szDirBase) - 'A'] & DRIVE_REMOTE) && fRemoteBug)
746 ulFindMax = 1; // file system gets confused
747 else if (driveflags[toupper(*szDirBase) - 'A'] & DRIVE_ZIPSTREAM)
748 ulFindMax = min(FilesToGet, 225); // anything more is wasted
749 else
750 ulFindMax = FilesToGet; // full-out
751 }
752 else {
753 ulFindMax = FilesToGet;
754 }
755 if (OS2ver[0] == 20 && OS2ver[1] < 30)
756 ulFindMax = min(ulFindMax, (65535 / sizeof(FILEFINDBUF4L)));
757
758 ulBufBytes = ulFindMax * sizeof(FILEFINDBUF4L);
759
760 pszFileSpec = xmalloc(CCHMAXPATH + 2, pszSrcFile, __LINE__);
761 paffbFound = xmalloc(ulBufBytes, pszSrcFile, __LINE__);
762 papffbSelected = xmalloc(sizeof(PFILEFINDBUF4L) * ulFindMax, pszSrcFile, __LINE__);
763
764 if (paffbFound && papffbSelected && pszFileSpec) {
765 t = strlen(szDirBase);
766 memcpy(pszFileSpec, szDirBase, t + 1);
767 pchEndPath = pszFileSpec + t;
768 if (*(pchEndPath - 1) != '\\') {
769 memcpy(pchEndPath, "\\", 2);
770 pchEndPath++;
771 }
772 memcpy(pchEndPath, "*", 2);
773 DosError(FERR_DISABLEHARDERR);
774 ulFindCnt = ulFindMax;
775 rc = xDosFindFirst(pszFileSpec,
776 &hdir,
777 FILE_NORMAL | FILE_READONLY | FILE_ARCHIVED |
778 FILE_SYSTEM | FILE_HIDDEN |
779 (filestoo ? FILE_DIRECTORY : MUST_HAVE_DIRECTORY),
780 paffbFound,
781 ulBufBytes,
782 &ulFindCnt,
783 FIL_QUERYEASIZEL);
784 priority_normal();
785 *pchEndPath = 0;
786 if (!rc) {
787 do {
788 /*
789 * remove . and .. from list if present
790 * also counter file system bugs that sometimes
791 * allows normal files to slip through when
792 * only directories should appear (only a few
793 * network file systems exhibit such a problem).
794 */
795#if 0 // 13 Aug 07 SHL fixme to be gone
796 {
797 static ULONG ulMaxCnt = 1;
798 if (ulFindCnt > ulMaxCnt) {
799 ulMaxCnt = ulFindCnt;
800 DbgMsg(pszSrcFile, __LINE__, "ulMaxCnt %u/%u", ulMaxCnt, ulFindMax);
801 }
802 }
803#endif // fixme to be gone
804
805 if (stopflag && *stopflag)
806 goto Abort;
807 pffbFile = paffbFound;
808 ulSelCnt = 0;
809 for (;;) {
810 if (!*pffbFile->achName ||
811 (!filestoo && ~pffbFile->attrFile & FILE_DIRECTORY) ||
812 (pffbFile->attrFile & FILE_DIRECTORY &&
813 pffbFile->achName[0] == '.' &&
814 (!pffbFile->achName[1] ||
815 (pffbFile->achName[1] == '.' && !pffbFile->achName[2])))) {
816 // ulFindCnt--; // Got . or .. or file to be skipped
817 }
818 else
819 papffbSelected[ulSelCnt++] = pffbFile; // Remember selected file
820 if (!pffbFile->oNextEntryOffset) {
821 // ulFindCnt = ulSelCnt; // Remember number selected
822 break;
823 }
824 pffbFile = (PFILEFINDBUF4L)((PBYTE)pffbFile + pffbFile->oNextEntryOffset);
825 } // for
826 if (ulSelCnt) {
827 // One or more entries selected
828 if (stopflag && *stopflag)
829 goto Abort;
830 if (fSyncUpdates) {
831 pciFirst = WinSendMsg(hwndCnr, CM_ALLOCRECORD,
832 MPFROMLONG(EXTRA_RECORD_BYTES),
833 MPFROMLONG(ulSelCnt));
834 if (!pciFirst) {
835 Win_Error2(hwndCnr, HWND_DESKTOP, pszSrcFile, __LINE__,
836 IDS_CMALLOCRECERRTEXT);
837 ok = FALSE;
838 ullTotalBytes = 0;
839 }
840 else {
841 pci = pciFirst;
842 ullTotalBytes = 0;
843 // Insert selected in container
844 for (x = 0; x < ulSelCnt; x++) {
845 pffbFile = papffbSelected[x];
846 ullBytes = FillInRecordFromFFB(hwndCnr, pci, pszFileSpec,
847 pffbFile, partial, dcd);
848 pci = (PCNRITEM) pci->rc.preccNextRecord;
849 ullTotalBytes += ullBytes;
850 } // for
851 // 13 Aug 07 SHL ulSelCnt checked already?
852 // if (ulSelCnt) {
853 memset(&ri, 0, sizeof(RECORDINSERT));
854 ri.cb = sizeof(RECORDINSERT);
855 ri.pRecordOrder = (PRECORDCORE) CMA_END;
856 ri.pRecordParent = (PRECORDCORE) pciParent;
857 ri.zOrder = (ULONG) CMA_TOP;
858 ri.cRecordsInsert = ulSelCnt;
859 ri.fInvalidateRecord =
860 !fSyncUpdates && dcd && dcd->type == DIR_FRAME ?
861 FALSE : TRUE;
862 if (!WinSendMsg(hwndCnr,
863 CM_INSERTRECORD,
864 MPFROMP(pciFirst), MPFROMP(&ri))) {
865 DosSleep(10); // Give GUI time to work
866 WinSetFocus(HWND_DESKTOP, hwndCnr);
867 if (!WinSendMsg(hwndCnr,
868 CM_INSERTRECORD,
869 MPFROMP(pciFirst), MPFROMP(&ri))) {
870 Win_Error2(hwndCnr, HWND_DESKTOP, pszSrcFile, __LINE__,
871 IDS_CMINSERTERRTEXT);
872 ok = FALSE;
873 ullTotalBytes = 0;
874 if (WinIsWindow((HAB) 0, hwndCnr))
875 FreeCnrItemList(hwndCnr, pciFirst);
876 }
877 // }
878 }
879 }
880 if (ok) {
881 ullReturnBytes += ullTotalBytes;
882 ulReturnFiles += ulSelCnt;
883 }
884 } // if sync updates
885 else {
886 // Append newly selected entries to aggregate list
887 paffbTemp = xrealloc(paffbTotal,
888 sizeof(FILEFINDBUF4L) * (ulSelCnt + ulTotal),
889 pszSrcFile, __LINE__);
890 if (paffbTemp) {
891 // 13 Aug 07 SHL fixme to optimize copy
892 paffbTotal = paffbTemp;
893 for (x = 0; x < ulSelCnt; x++)
894 paffbTotal[x + ulTotal] = *papffbSelected[x];
895 ulTotal += ulSelCnt;
896 }
897 else {
898 saymsg(MB_ENTER,
899 HWND_DESKTOP,
900 GetPString(IDS_ERRORTEXT), GetPString(IDS_OUTOFMEMORY));
901 break;
902 }
903 }
904 } // if entries selected
905 if (stopflag && *stopflag)
906 goto Abort;
907 DosError(FERR_DISABLEHARDERR);
908 ulFindCnt = ulFindMax;
909 rc = xDosFindNext(hdir, paffbFound, ulBufBytes, &ulFindCnt, FIL_QUERYEASIZEL);
910 priority_normal();
911 if (rc)
912 DosError(FERR_DISABLEHARDERR);
913 } while (!rc);
914
915 DosFindClose(hdir);
916
917 if (paffbFound) {
918 free(paffbFound);
919 paffbFound = NULL;
920 }
921 if (papffbSelected) {
922 free(papffbSelected);
923 papffbSelected = NULL;
924 }
925
926 if (ulTotal && paffbTotal) {
927
928 if (stopflag && *stopflag)
929 goto Abort;
930
931 pciFirst = WinSendMsg(hwndCnr, CM_ALLOCRECORD,
932 MPFROMLONG(EXTRA_RECORD_BYTES), MPFROMLONG(ulTotal));
933 if (!pciFirst) {
934 Win_Error2(hwndCnr, HWND_DESKTOP, pszSrcFile, __LINE__,
935 IDS_CMALLOCRECERRTEXT);
936 ok = FALSE;
937 ullTotalBytes = 0;
938 }
939 else {
940 pci = pciFirst;
941 ullTotalBytes = 0;
942 pffbFile = paffbTotal;
943 for (x = 0; x < ulTotal; x++) {
944 ullBytes = FillInRecordFromFFB(hwndCnr, pci, pszFileSpec,
945 pffbFile, partial, dcd);
946 pci = (PCNRITEM) pci->rc.preccNextRecord;
947 ullTotalBytes += ullBytes;
948 // Can not use offset since we have merged lists - this should be equivalent
949 pffbFile = (PFILEFINDBUF4L)((PBYTE)pffbFile + sizeof(FILEFINDBUF4L));
950 }
951 if (ulTotal) {
952 memset(&ri, 0, sizeof(RECORDINSERT));
953 ri.cb = sizeof(RECORDINSERT);
954 ri.pRecordOrder = (PRECORDCORE) CMA_END;
955 ri.pRecordParent = (PRECORDCORE) pciParent;
956 ri.zOrder = (ULONG) CMA_TOP;
957 ri.cRecordsInsert = ulTotal;
958 ri.fInvalidateRecord = (!fSyncUpdates && dcd &&
959 dcd->type == DIR_FRAME) ? FALSE : TRUE;
960 if (!WinSendMsg(hwndCnr, CM_INSERTRECORD,
961 MPFROMP(pciFirst), MPFROMP(&ri))) {
962 DosSleep(10); // Give GUI time to work
963 WinSetFocus(HWND_DESKTOP, hwndCnr);
964 if (!WinSendMsg(hwndCnr, CM_INSERTRECORD,
965 MPFROMP(pciFirst), MPFROMP(&ri))) {
966 Win_Error2(hwndCnr, HWND_DESKTOP, pszSrcFile, __LINE__,
967 IDS_CMINSERTERRTEXT);
968 ok = FALSE;
969 ullTotalBytes = 0;
970 if (WinIsWindow((HAB) 0, hwndCnr))
971 FreeCnrItemList(hwndCnr, pciFirst);
972 }
973 }
974 }
975 }
976 if (ok) {
977 ullReturnBytes += ullTotalBytes;
978 ulReturnFiles += ulFindCnt;
979 }
980 }
981 }
982
983 if (rc && rc != ERROR_NO_MORE_FILES) {
984 Dos_Error(MB_ENTER, rc, HWND_DESKTOP, pszSrcFile, __LINE__,
985 GetPString(IDS_CANTFINDDIRTEXT), pszFileSpec);
986 }
987
988 if (!fSyncUpdates && dcd && dcd->type == DIR_FRAME)
989 WinSendMsg(hwndCnr, CM_INVALIDATERECORD, MPVOID,
990 MPFROM2SHORT(0, CMA_ERASE));
991 }
992Abort:
993 if (paffbTotal)
994 free(paffbTotal);
995 if (pszFileSpec)
996 free(pszFileSpec);
997 if (paffbFound)
998 free(paffbFound);
999 if (papffbSelected)
1000 free(papffbSelected);
1001
1002 if (recurse) {
1003 pci = WinSendMsg(hwndCnr, CM_QUERYRECORD, MPFROMP(pciParent),
1004 MPFROM2SHORT(CMA_FIRSTCHILD, CMA_ITEMORDER));
1005 while (pci && (INT)pci != -1) {
1006 if (pci->attrFile & FILE_DIRECTORY)
1007 Stubby(hwndCnr, pci);
1008 pci = WinSendMsg(hwndCnr, CM_QUERYRECORD, MPFROMP(pci),
1009 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
1010 }
1011 }
1012
1013 if (pulTotalFiles)
1014 *pulTotalFiles = ulReturnFiles;
1015
1016 if (pullTotalBytes)
1017 *pullTotalBytes = ullReturnBytes;
1018
1019} // ProcessDirectory
1020
1021VOID FillDirCnr(HWND hwndCnr,
1022 CHAR * pszDirectory,
1023 DIRCNRDATA * dcd, PULONGLONG pullTotalBytes)
1024{
1025 ProcessDirectory(hwndCnr,
1026 (PCNRITEM) NULL,
1027 pszDirectory,
1028 TRUE, // filestoo
1029 FALSE, // recurse
1030 TRUE, // partial
1031 dcd ? &dcd->stopflag : NULL,
1032 dcd,
1033 NULL,
1034 pullTotalBytes);
1035 DosPostEventSem(CompactSem);
1036
1037#if 0 // fixme to be gone or to be configurable
1038 {
1039 int state = _heapchk();
1040 if (state != _HEAPOK)
1041 Runtime_Error(pszSrcFile, __LINE__, "heap corrupted %d", state);
1042 else
1043 DbgMsg(pszSrcFile, __LINE__, "_memavl %u", _memavl());
1044 }
1045#endif
1046
1047} // FillDirCnr
1048
1049VOID FillTreeCnr(HWND hwndCnr, HWND hwndParent)
1050{
1051 ULONG ulCurDriveNum, ulDriveMap, numtoinsert = 0, drvtype;
1052 PCNRITEM pci, pciFirst = NULL, pciNext, pciParent = NULL;
1053 INT x, removable;
1054 CHAR suggest[32];
1055 CHAR szDrive[] = " :\\";
1056 CHAR szFileSystem[CCHMAXPATH];
1057 FILESTATUS4L fsa4;
1058 APIRET rc;
1059 BOOL drivesbuilt = FALSE;
1060 ULONG startdrive = 3;
1061
1062 static BOOL didonce = FALSE;
1063
1064 fDummy = TRUE;
1065 *suggest = 0;
1066 for (x = 0; x < 26; x++) {
1067 driveflags[x] &= (DRIVE_IGNORE | DRIVE_NOPRESCAN | DRIVE_NOLOADICONS |
1068 DRIVE_NOLOADSUBJS | DRIVE_NOLOADLONGS |
1069 DRIVE_INCLUDEFILES | DRIVE_SLOW | DRIVE_NOSTATS);
1070 }
1071 memset(driveserial, -1, sizeof(driveserial));
1072
1073 DosError(FERR_DISABLEHARDERR);
1074 if (!DosQuerySysInfo(QSV_BOOT_DRIVE,
1075 QSV_BOOT_DRIVE,
1076 (PVOID) &startdrive,
1077 (ULONG) sizeof(ULONG)) &&
1078 startdrive)
1079 {
1080 driveflags[startdrive - 1] |= DRIVE_BOOT;
1081 }
1082
1083 DosError(FERR_DISABLEHARDERR);
1084 rc = DosQCurDisk(&ulCurDriveNum, &ulDriveMap);
1085 if (rc) {
1086 Dos_Error(MB_CANCEL,
1087 rc,
1088 HWND_DESKTOP,
1089 pszSrcFile, __LINE__, GetPString(IDS_FILLDIRQCURERRTEXT));
1090 exit(0);
1091 }
1092
1093 // Calc number of drive items to create
1094 for (x = 0; x < 26; x++) {
1095 if ((ulDriveMap & (1L << x)) && !(driveflags[x] & DRIVE_IGNORE))
1096 numtoinsert++;
1097 }
1098
1099 if (numtoinsert) {
1100 pciFirst = WinSendMsg(hwndCnr,
1101 CM_ALLOCRECORD,
1102 MPFROMLONG(EXTRA_RECORD_BYTES),
1103 MPFROMLONG((ULONG) numtoinsert));
1104 }
1105
1106 if (!pciFirst) {
1107 Win_Error2(hwndCnr, HWND_DESKTOP, pszSrcFile, __LINE__, IDS_CMALLOCRECERRTEXT);
1108 exit(0);
1109 }
1110
1111 pci = pciFirst;
1112 for (x = 0; x < 26; x++) {
1113 if ((ulDriveMap & (1L << x)) && !(driveflags[x] & DRIVE_IGNORE)) {
1114
1115 CHAR s[80];
1116 ULONG flags = 0;
1117 ULONG size = sizeof(ULONG);
1118
1119 *szDrive = (CHAR)x + 'A'; // Build path spec
1120
1121 sprintf(s, "%c.DriveFlags", toupper(*szDrive));
1122 if (PrfQueryProfileData(fmprof, appname, s, &flags, &size) &&
1123 size == sizeof(ULONG)) {
1124 driveflags[toupper(*szDrive) - 'A'] |= flags;
1125 }
1126
1127 if (x > 1) {
1128 // Hard drive (2..N)
1129 if (!(driveflags[x] & DRIVE_NOPRESCAN)) {
1130 *szFileSystem = 0;
1131 drvtype = 0;
1132 removable = CheckDrive(*szDrive, szFileSystem, &drvtype);
1133 driveserial[x] = -1;
1134 if (removable != -1) {
1135 struct {
1136 ULONG serial;
1137 CHAR volumelength;
1138 CHAR volumelabel[CCHMAXPATH];
1139 } volser;
1140
1141 DosError(FERR_DISABLEHARDERR);
1142 if (!DosQueryFSInfo((ULONG) x,
1143 FSIL_VOLSER, &volser, sizeof(volser))) {
1144 driveserial[x] = volser.serial;
1145 }
1146 }
1147 else
1148 driveflags[x] |= DRIVE_INVALID;
1149
1150 memset(&fsa4, 0, sizeof(FILESTATUS4L));
1151 driveflags[x] |= removable == -1 || removable == 1 ?
1152 DRIVE_REMOVABLE : 0;
1153 if (drvtype & DRIVE_REMOTE)
1154 driveflags[x] |= DRIVE_REMOTE;
1155 if (!stricmp(szFileSystem,RAMFS)) {
1156 driveflags[x] |= DRIVE_RAMDISK;
1157 driveflags[x] &= ~DRIVE_REMOTE;
1158 }
1159 if (!stricmp(szFileSystem,NDFS32)) {
1160 driveflags[x] |= DRIVE_VIRTUAL;
1161 driveflags[x] &= ~DRIVE_REMOTE;
1162 }
1163 if (!stricmp(szFileSystem,NTFS))
1164 driveflags[x] |= DRIVE_NOTWRITEABLE;
1165 if (strcmp(szFileSystem, HPFS) &&
1166 strcmp(szFileSystem, JFS) &&
1167 strcmp(szFileSystem, ISOFS) &&
1168 strcmp(szFileSystem, CDFS) &&
1169 strcmp(szFileSystem, FAT32) &&
1170 strcmp(szFileSystem, NDFS32) &&
1171 strcmp(szFileSystem, RAMFS) &&
1172 strcmp(szFileSystem, NTFS) &&
1173 strcmp(szFileSystem, HPFS386)) {
1174 driveflags[x] |= DRIVE_NOLONGNAMES;
1175 }
1176
1177 if (!strcmp(szFileSystem, CDFS) || !strcmp(szFileSystem,ISOFS)) {
1178 removable = 1;
1179 driveflags[x] |= DRIVE_REMOVABLE | DRIVE_NOTWRITEABLE |
1180 DRIVE_CDROM;
1181 }
1182 else if (!stricmp(szFileSystem, CBSIFS)) {
1183 driveflags[x] |= DRIVE_ZIPSTREAM;
1184 driveflags[x] &= ~DRIVE_REMOTE;
1185 if (drvtype & DRIVE_REMOVABLE)
1186 driveflags[x] |= DRIVE_REMOVABLE;
1187 if (!(drvtype & DRIVE_NOLONGNAMES))
1188 driveflags[x] &= ~DRIVE_NOLONGNAMES;
1189 }
1190
1191 pci->rc.flRecordAttr |= CRA_RECORDREADONLY;
1192 // if ((ULONG) (toupper(*pci->pszFileName) - '@') == ulCurDriveNum) // 23 Jul 07 SHL
1193 if ((ULONG)(toupper(*szDrive) - '@') == ulCurDriveNum)
1194 pci->rc.flRecordAttr |= (CRA_CURSORED | CRA_SELECTED);
1195
1196 if (removable == 0) {
1197 // Fixed volume
1198 pci->attrFile |= FILE_DIRECTORY;
1199 DosError(FERR_DISABLEHARDERR);
1200 rc = DosQueryPathInfo(szDrive,
1201 FIL_QUERYEASIZEL,
1202 &fsa4, (ULONG) sizeof(FILESTATUS4L));
1203 // ERROR_BAD_NET_RSP = 58
1204 if (rc == 58) {
1205 DosError(FERR_DISABLEHARDERR);
1206 rc = DosQueryPathInfo(szDrive,
1207 FIL_STANDARDL,
1208 &fsa4, (ULONG) sizeof(FILESTATUS4L));
1209 fsa4.cbList = 0;
1210 }
1211 if (rc && !didonce) {
1212 // Guess drive letter
1213 if (!*suggest) {
1214 *suggest = '/';
1215 suggest[1] = 0;
1216 }
1217 sprintf(suggest + strlen(suggest), "%c" , toupper(*szDrive));
1218 pci->pszFileName = xstrdup(szDrive, pszSrcFile, __LINE__);
1219 strcpy(pci->pszFileName, szDrive);
1220 pci->pszDisplayName = pci->pszFileName;
1221 pci->rc.pszIcon = pci->pszDisplayName;
1222 pci->attrFile = FILE_DIRECTORY;
1223 pci->pszDispAttr = FileAttrToString(pci->attrFile);
1224 driveserial[x] = -1;
1225 }
1226 else
1227 FillInRecordFromFSA(hwndCnr, pci, szDrive, &fsa4, TRUE, NULL);
1228 }
1229 else {
1230 // Removable volume
1231 pci->pszFileName = xstrdup(szDrive, pszSrcFile, __LINE__);
1232 strcpy(pci->pszFileName, szDrive);
1233 pci->pszDisplayName = pci->pszFileName;
1234 pci->rc.pszIcon = pci->pszDisplayName;
1235 pci->attrFile = FILE_DIRECTORY;
1236 pci->pszDispAttr = FileAttrToString(pci->attrFile);
1237 }
1238 SelectDriveIcon(pci);
1239 }
1240 else {
1241 pci->rc.hptrIcon = hptrDunno;
1242 pci->pszFileName = xstrdup(szDrive, pszSrcFile, __LINE__);
1243 strcpy(pci->pszFileName, szDrive);
1244 pci->pszDisplayName = pci->pszFileName;
1245 pci->rc.pszIcon = pci->pszFileName;
1246 pci->attrFile = FILE_DIRECTORY;
1247 pci->pszDispAttr = FileAttrToString(pci->attrFile);
1248 driveserial[x] = -1;
1249 }
1250 }
1251 else {
1252 // diskette drive (A or B)
1253 pci->rc.hptrIcon = hptrFloppy;
1254 pci->pszFileName = xstrdup(szDrive, pszSrcFile, __LINE__);
1255 strcpy(pci->pszFileName, szDrive);
1256 pci->pszDisplayName = pci->pszFileName;
1257 pci->rc.pszIcon = pci->pszDisplayName;
1258 pci->attrFile = FILE_DIRECTORY;
1259 pci->pszDispAttr = FileAttrToString(pci->attrFile);
1260 driveflags[x] |= (DRIVE_REMOVABLE | DRIVE_NOLONGNAMES);
1261 driveserial[x] = -1;
1262 }
1263 pci->rc.flRecordAttr |= CRA_RECORDREADONLY;
1264 pci = (PCNRITEM) pci->rc.preccNextRecord; // next rec
1265 }
1266 else if (!(ulDriveMap & (1L << x)))
1267 driveflags[x] |= DRIVE_INVALID;
1268 } // for drives
1269
1270 PostMsg(hwndMain, UM_BUILDDRIVEBAR, MPVOID, MPVOID);
1271 drivesbuilt = TRUE;
1272
1273 // insert the drives
1274 if (numtoinsert && pciFirst) {
1275 RECORDINSERT ri;
1276
1277 memset(&ri, 0, sizeof(RECORDINSERT));
1278 ri.cb = sizeof(RECORDINSERT);
1279 ri.pRecordOrder = (PRECORDCORE) CMA_END;
1280 ri.pRecordParent = (PRECORDCORE) NULL;
1281 ri.zOrder = (ULONG) CMA_TOP;
1282 ri.cRecordsInsert = numtoinsert;
1283 ri.fInvalidateRecord = FALSE;
1284 if (!WinSendMsg(hwndCnr,
1285 CM_INSERTRECORD, MPFROMP(pciFirst), MPFROMP(&ri)))
1286 {
1287 Win_Error2(hwndCnr, HWND_DESKTOP, pszSrcFile, __LINE__,
1288 IDS_CMINSERTERRTEXT);
1289 }
1290 }
1291
1292 // move cursor onto the default drive rather than the first drive
1293 if (!fSwitchTree) {
1294 pci = (PCNRITEM) WinSendMsg(hwndCnr,
1295 CM_QUERYRECORD,
1296 MPVOID,
1297 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
1298 while (pci && (INT)pci != -1) {
1299 if ((ULONG) (toupper(*pci->pszFileName) - '@') == ulCurDriveNum) {
1300 WinSendMsg(hwndCnr,
1301 CM_SETRECORDEMPHASIS,
1302 MPFROMP(pci), MPFROM2SHORT(TRUE, CRA_CURSORED));
1303 break;
1304 }
1305 pci = (PCNRITEM) WinSendMsg(hwndCnr,
1306 CM_QUERYRECORD,
1307 MPFROMP(pci),
1308 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
1309 }
1310 }
1311
1312 if (hwndParent) {
1313 WinSendMsg(WinWindowFromID(WinQueryWindow(hwndParent, QW_PARENT),
1314 MAIN_DRIVELIST),
1315 LM_DELETEALL, MPVOID, MPVOID);
1316 }
1317
1318 if (fShowEnv) {
1319 RECORDINSERT ri;
1320
1321 pciParent = WinSendMsg(hwndCnr,
1322 CM_ALLOCRECORD,
1323 MPFROMLONG(EXTRA_RECORD_BYTES), MPFROMLONG(1));
1324 if (pciParent) {
1325 pciParent->flags |= RECFLAGS_ENV;
1326 pciParent->pszFileName = xstrdup(GetPString(IDS_ENVVARSTEXT), pszSrcFile, __LINE__);
1327 strcpy(pciParent->pszFileName, GetPString(IDS_ENVVARSTEXT));
1328 pciParent->pszDisplayName = pciParent->pszFileName; // 03 Aug 07 SHL
1329 pciParent->rc.hptrIcon = hptrEnv;
1330 pciParent->rc.pszIcon = pciParent->pszFileName;
1331 pciParent->pszDispAttr = FileAttrToString(0);
1332 memset(&ri, 0, sizeof(RECORDINSERT));
1333 ri.cb = sizeof(RECORDINSERT);
1334 ri.pRecordOrder = (PRECORDCORE) CMA_END;
1335 ri.pRecordParent = (PRECORDCORE) NULL;
1336 ri.zOrder = (ULONG) CMA_TOP;
1337 ri.cRecordsInsert = 1;
1338 ri.fInvalidateRecord = FALSE;
1339 if (WinSendMsg(hwndCnr,
1340 CM_INSERTRECORD, MPFROMP(pciParent), MPFROMP(&ri))) {
1341
1342 char *p, *pp;
1343
1344 p = GetPString(IDS_ENVVARNAMES);
1345 while (*p == ' ')
1346 p++;
1347 while (*p) {
1348 *szFileSystem = 0;
1349 pp = szFileSystem;
1350 while (*p && *p != ' ')
1351 *pp++ = *p++;
1352 *pp = 0;
1353 while (*p == ' ')
1354 p++;
1355 if (*szFileSystem &&
1356 (!stricmp(szFileSystem, "LIBPATH") || getenv(szFileSystem))) {
1357 pci = WinSendMsg(hwndCnr,
1358 CM_ALLOCRECORD,
1359 MPFROMLONG(EXTRA_RECORD_BYTES),
1360 MPFROMLONG(1));
1361 if (pci) {
1362 CHAR fname[CCHMAXPATH];
1363 pci->flags |= RECFLAGS_ENV;
1364 sprintf(fname, "%%%s%%", szFileSystem);
1365 pci->pszFileName = xstrdup(fname, pszSrcFile, __LINE__);
1366 pci->rc.hptrIcon = hptrEnv;
1367 pci->rc.pszIcon = pci->pszFileName;
1368 pci->pszDispAttr = FileAttrToString(0);
1369 memset(&ri, 0, sizeof(RECORDINSERT));
1370 ri.cb = sizeof(RECORDINSERT);
1371 ri.pRecordOrder = (PRECORDCORE) CMA_END;
1372 ri.pRecordParent = (PRECORDCORE) pciParent;
1373 ri.zOrder = (ULONG) CMA_TOP;
1374 ri.cRecordsInsert = 1;
1375 ri.fInvalidateRecord = FALSE;
1376 if (!WinSendMsg(hwndCnr,
1377 CM_INSERTRECORD,
1378 MPFROMP(pci), MPFROMP(&ri))) {
1379 Win_Error2(hwndCnr, HWND_DESKTOP, pszSrcFile, __LINE__,
1380 IDS_CMINSERTERRTEXT);
1381 FreeCnrItem(hwndCnr, pci);
1382 }
1383 }
1384 }
1385 }
1386 WinSendMsg(hwndCnr,
1387 CM_INVALIDATERECORD,
1388 MPFROMP(&pciParent),
1389 MPFROM2SHORT(1, CMA_ERASE | CMA_REPOSITION));
1390 }
1391 else
1392 FreeCnrItem(hwndCnr, pciParent);
1393 }
1394 } // if show env
1395
1396 x = 0;
1397 pci = (PCNRITEM) WinSendMsg(hwndCnr,
1398 CM_QUERYRECORD,
1399 MPVOID,
1400 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
1401 while (pci && (INT)pci != -1) {
1402 pciNext = (PCNRITEM) WinSendMsg(hwndCnr,
1403 CM_QUERYRECORD,
1404 MPFROMP(pci),
1405 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
1406 if (!(pci->flags & RECFLAGS_ENV)) {
1407 if ((ULONG) (toupper(*pci->pszFileName) - '@') == ulCurDriveNum ||
1408 toupper(*pci->pszFileName) > 'B')
1409 {
1410 if (!(driveflags[toupper(*pci->pszFileName) - 'A'] & DRIVE_INVALID) &&
1411 !(driveflags[toupper(*pci->pszFileName) - 'A'] & DRIVE_NOPRESCAN) &&
1412 (!fNoRemovableScan ||
1413 !(driveflags[toupper(*pci->pszFileName) - 'A'] & DRIVE_REMOVABLE)))
1414 {
1415 if (!Stubby(hwndCnr, pci) && !DRIVE_RAMDISK) {
1416 WinSendMsg(hwndCnr,
1417 CM_INVALIDATERECORD,
1418 MPFROMP(&pci),
1419 MPFROM2SHORT(1, CMA_ERASE | CMA_REPOSITION));
1420 goto SkipBadRec;
1421 }
1422 }
1423 }
1424 else {
1425 WinSendMsg(hwndCnr,
1426 CM_INVALIDATERECORD,
1427 MPFROMP(&pci),
1428 MPFROM2SHORT(1, CMA_ERASE | CMA_REPOSITION));
1429 }
1430
1431 WinSendMsg(WinWindowFromID(WinQueryWindow(hwndParent, QW_PARENT),
1432 MAIN_DRIVELIST),
1433 LM_INSERTITEM,
1434 MPFROM2SHORT(LIT_SORTASCENDING, 0),
1435 MPFROMP(pci->pszFileName));
1436 }
1437 SkipBadRec:
1438 x++;
1439 pci = pciNext;
1440 }
1441 if (hwndParent)
1442 WinSendMsg(WinWindowFromID(WinQueryWindow(hwndParent, QW_PARENT),
1443 MAIN_DRIVELIST), LM_SELECTITEM,
1444 MPFROM2SHORT(0, 0), MPFROMLONG(TRUE));
1445
1446 pci = (PCNRITEM) WinSendMsg(hwndCnr,
1447 CM_QUERYRECORD,
1448 MPVOID,
1449 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
1450 while (pci && (INT)pci != -1) {
1451 pciNext = (PCNRITEM) WinSendMsg(hwndCnr,
1452 CM_QUERYRECORD,
1453 MPFROMP(pci),
1454 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
1455 if (pci->flags & RECFLAGS_ENV) {
1456 pci = (PCNRITEM) WinSendMsg(hwndCnr,
1457 CM_QUERYRECORD,
1458 MPFROMP(pci),
1459 MPFROM2SHORT(CMA_FIRSTCHILD,
1460 CMA_ITEMORDER));
1461 while (pci && (INT)pci != -1) {
1462 if (pci->flags & RECFLAGS_ENV)
1463 FleshEnv(hwndCnr, pci);
1464 pci = (PCNRITEM) WinSendMsg(hwndCnr,
1465 CM_QUERYRECORD,
1466 MPFROMP(pci),
1467 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
1468 }
1469 break;
1470 }
1471 pci = (PCNRITEM) WinSendMsg(hwndCnr,
1472 CM_QUERYRECORD,
1473 MPFROMP(pci),
1474 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
1475 }
1476
1477 if (!drivesbuilt && hwndMain)
1478 PostMsg(hwndMain, UM_BUILDDRIVEBAR, MPVOID, MPVOID);
1479 DosSleep(16); // 05 Aug 07 GKY 33
1480 fDummy = FALSE;
1481 DosPostEventSem(CompactSem);
1482
1483 {
1484 BYTE info;
1485 BOOL includesyours = FALSE;
1486
1487 if (*suggest || (!(driveflags[1] & DRIVE_IGNORE) && fFirstTime)) {
1488 if (!DosDevConfig(&info, DEVINFO_FLOPPY) && info == 1) {
1489 if (!*suggest) {
1490 *suggest = '/';
1491 suggest[1] = 0;
1492 }
1493 else
1494 memmove(suggest + 2, suggest + 1, strlen(suggest));
1495 suggest[1] = 'B';
1496 }
1497 }
1498 if (*suggest) {
1499 for (x = 2; x < 26; x++) {
1500 if (driveflags[x] & DRIVE_IGNORE) {
1501 includesyours = TRUE;
1502 sprintf(suggest + strlen(suggest), "%c", (char)(x + 'A'));
1503 }
1504 }
1505 strcat(suggest, " %*");
1506 if (saymsg(MB_YESNO | MB_ICONEXCLAMATION,
1507 (hwndParent) ? hwndParent : hwndCnr,
1508 GetPString(IDS_SUGGESTTITLETEXT),
1509 GetPString(IDS_SUGGEST1TEXT),
1510 (includesyours) ? GetPString(IDS_SUGGEST2TEXT) : NullStr,
1511 suggest) == MBID_YES) {
1512 char s[64];
1513
1514 sprintf(s, "PARAMETERS=%s", suggest);
1515 WinCreateObject(WPProgram, "FM/2", s, FM3Folder, CO_UPDATEIFEXISTS);
1516 WinCreateObject(WPProgram,
1517 "FM/2 Lite", s, FM3Folder, CO_UPDATEIFEXISTS);
1518 WinCreateObject(WPProgram,
1519 "Archive Viewer/2", s, FM3Tools, CO_UPDATEIFEXISTS);
1520 WinCreateObject(WPProgram,
1521 "Dir Sizes", s, FM3Tools, CO_UPDATEIFEXISTS);
1522 WinCreateObject(WPProgram,
1523 "Visual Tree", s, FM3Tools, CO_UPDATEIFEXISTS);
1524 WinCreateObject(WPProgram,
1525 "Visual Directory", s, FM3Tools, CO_UPDATEIFEXISTS);
1526 WinCreateObject(WPProgram,
1527 "Global File Viewer", s, FM3Tools, CO_UPDATEIFEXISTS);
1528 WinCreateObject(WPProgram, "Databar", s, FM3Tools, CO_UPDATEIFEXISTS);
1529 }
1530 }
1531 }
1532
1533 didonce = TRUE;
1534
1535} // FillTreeCnr
1536
1537
1538/**
1539 * Empty all records from a container and free associated storage and
1540 * Free up field infos
1541 */
1542
1543VOID EmptyCnr(HWND hwnd)
1544{
1545 PFIELDINFO pfi;
1546
1547#if 0 // fixme to be gone or to be configurable
1548 {
1549 int state = _heapchk();
1550 if (state != _HEAPOK)
1551 Runtime_Error(pszSrcFile, __LINE__, "heap corrupted %d", state);
1552 }
1553#endif
1554
1555 // Remove all records
1556 RemoveCnrItems(hwnd, NULL, 0, CMA_FREE);
1557
1558 // Remove field info descriptors
1559 pfi = (PFIELDINFO) WinSendMsg(hwnd, CM_QUERYDETAILFIELDINFO, MPVOID,
1560 MPFROMSHORT(CMA_FIRST));
1561 if (pfi &&
1562 (INT)WinSendMsg(hwnd, CM_REMOVEDETAILFIELDINFO, MPVOID,
1563 MPFROM2SHORT(0, CMA_FREE)) == -1) {
1564 Win_Error(hwnd, HWND_DESKTOP, pszSrcFile, __LINE__,"CM_REMOVEDETAILFIELDINFO hwnd %x", hwnd);
1565 }
1566}
1567
1568/**
1569 * Free storage associated with container item
1570 */
1571
1572VOID FreeCnrItemData(PCNRITEM pci)
1573{
1574 PSZ psz;
1575 // DbgMsg(pszSrcFile, __LINE__, "FreeCnrItemData %p", pci);
1576
1577 if (pci->pszSubject && pci->pszSubject != NullStr) {
1578
1579 psz = pci->pszSubject;
1580 pci->pszSubject = NullStr;
1581 free(psz);
1582 }
1583
1584 // +1 in case long name pointing after last backslash
1585 if (pci->pszLongName &&
1586 pci->pszLongName != NullStr &&
1587 pci->pszLongName != pci->pszFileName &&
1588 pci->pszLongName != pci->pszDisplayName &&
1589 pci->pszLongName != pci->pszDisplayName + 1) {
1590 psz = pci->pszLongName;
1591 pci->pszLongName = NullStr;
1592 free(psz);
1593 }
1594
1595 if (pci->pszFileName && pci->pszFileName != NullStr) {
1596 psz = pci->pszFileName;
1597 pci->pszFileName = NullStr;
1598 free(psz);
1599 }
1600
1601 if (pci->pszFmtFileSize && pci->pszFmtFileSize != NullStr) {
1602 psz = pci->pszFmtFileSize;
1603 pci->pszFmtFileSize = NullStr;
1604 free(psz);
1605 }
1606}
1607
1608/**
1609 * Free single container item and associated storage
1610 */
1611
1612VOID FreeCnrItem(HWND hwnd, PCNRITEM pci)
1613{
1614 // DbgMsg(pszSrcFile, __LINE__, "FreeCnrItem hwnd %x pci %p", hwnd, pci);
1615
1616 FreeCnrItemData(pci);
1617
1618 if (!WinSendMsg(hwnd, CM_FREERECORD, MPFROMP(&pci), MPFROMSHORT(1))) {
1619 // Win_Error2(hwnd, HWND_DESKTOP, pszSrcFile, __LINE__,IDS_CMFREEERRTEXT);
1620 Win_Error(hwnd, HWND_DESKTOP, pszSrcFile, __LINE__,
1621 "CM_FREERECORD hwnd %x pci %p file %s",
1622 hwnd, pci,
1623 pci && pci->pszFileName ? pci->pszFileName : "n/a");
1624 }
1625}
1626
1627/**
1628 * Free container item list and associated storage
1629 */
1630
1631VOID FreeCnrItemList(HWND hwnd, PCNRITEM pciFirst)
1632{
1633 PCNRITEM pci = pciFirst;
1634 PCNRITEM pciNext;
1635 USHORT usCount;
1636
1637 for (usCount = 0; pci; usCount++) {
1638 pciNext = (PCNRITEM) pci->rc.preccNextRecord;
1639 FreeCnrItemData(pci);
1640 pci = pciNext;
1641 }
1642
1643 if (usCount) {
1644 if (!WinSendMsg(hwnd, CM_FREERECORD, MPFROMP(&pci), MPFROMSHORT(usCount))) {
1645 // Win_Error2(hwnd, HWND_DESKTOP, pszSrcFile, __LINE__,IDS_CMFREEERRTEXT);
1646 Win_Error(hwnd, HWND_DESKTOP, pszSrcFile, __LINE__,"CM_FREERECORD hwnd %x pci %p cnt %u", hwnd, pci, usCount);
1647 }
1648 }
1649}
1650
1651/**
1652 * Remove item(s) from container and free associated storage if requested
1653 * @param pciFirst points to first item to remove or NULL to remove all
1654 * @param usCnt is remove count or 0 to remove all
1655 * @returns count of items remaining in container or -1 if error
1656 */
1657
1658INT RemoveCnrItems(HWND hwnd, PCNRITEM pciFirst, USHORT usCnt, USHORT usFlags)
1659{
1660 INT remaining = usCnt;
1661 PCNRITEM pci;
1662
1663 if ((usCnt && !pciFirst) || (!usCnt && pciFirst)) {
1664 Runtime_Error(pszSrcFile, __LINE__, "pciFirst %p usCnt %u mismatch", pciFirst, usCnt);
1665 remaining = -1;
1666 }
1667 else {
1668 // Free our buffers if free requested
1669 if (usFlags & CMA_FREE) {
1670 if (pciFirst)
1671 pci = pciFirst;
1672 else {
1673 pci = (PCNRITEM)WinSendMsg(hwnd, CM_QUERYRECORD, MPVOID,
1674 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
1675 if ((INT)pci == -1) {
1676 Win_Error(hwnd, HWND_DESKTOP, pszSrcFile, __LINE__,"CM_QUERYRECORD");
1677 remaining = -1;
1678 pci = NULL;
1679 }
1680 }
1681 while (pci) {
1682 // 12 Sep 07 SHL dwg drivebar crash testing - ticket# ???
1683 static PCNRITEM pciLast; // 12 Sep 07 SHL
1684 ULONG ulSize = sizeof(*pci);
1685 ULONG ulAttr;
1686 APIRET apiret = DosQueryMem((PVOID)pci, &ulSize, &ulAttr);
1687 if (apiret)
1688 Dos_Error(MB_ENTER, apiret, HWND_DESKTOP, pszSrcFile, __LINE__,
1689 "DosQueryMem failed pci %p pciLast %p", pci, pciLast);
1690 FreeCnrItemData(pci);
1691 pciLast = pci;
1692 pci = (PCNRITEM)pci->rc.preccNextRecord;
1693 if (remaining && --remaining == 0)
1694 break;
1695 }
1696 }
1697 }
1698
1699 // DbgMsg(pszSrcFile, __LINE__, "RemoveCnrItems %p %u %s", pci, usCnt, pci->pszFileName);
1700
1701 if (remaining != - 1) {
1702 remaining = (INT)WinSendMsg(hwnd, CM_REMOVERECORD, MPFROMP(&pciFirst), MPFROM2SHORT(usCnt, usFlags));
1703 if (remaining == -1) {
1704 // Win_Error2(hwnd, HWND_DESKTOP, pszSrcFile, __LINE__,IDS_CMREMOVEERRTEXT);
1705 Win_Error(hwnd, HWND_DESKTOP, pszSrcFile, __LINE__,"CM_REMOVERECORD hwnd %x pci %p cnt %u", hwnd, pciFirst, usCnt);
1706 }
1707 }
1708
1709 return remaining;
1710}
1711
1712#pragma alloc_text(FILLDIR,FillInRecordFromFFB,FillInRecordFromFSA,IDFile)
1713#pragma alloc_text(FILLDIR1,ProcessDirectory,FillDirCnr,FillTreeCnr,FileAttrToString)
1714#pragma alloc_text(EMPTYCNR,EmptyCnr,FreeCnrItemData,FreeCnrItem,FreeCnrItemList,RemoveCnrItems)
1715
Note: See TracBrowser for help on using the repository browser.