source: trunk/dll/filldir.c@ 771

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

Increase subject to 1024 reduce DosSleep times

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