source: trunk/dll/filldir.c@ 783

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

Rework DosFindFirst/Next loops to optimize memory allocation and code paths
Adjust FilesToGet limits
Update configuration notebook scanning page
Start updating #pragma alloc_text positioning for OpenWatcom compatibility

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