source: trunk/dll/filldir.c@ 907

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

Avoid out of memory traps in Compare Directories
Rework Compare Directories progress display for 2 second update rate
Start refactoring to reduce dependence on fm3dll.h
Add timer services (IsITimerExpired etc.)

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