source: trunk/dll/filldir.c@ 841

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

This implements large file support; The wrappers to allow WARP3 compatibility are not done so this will not run on Warp3or Warp 4 pre fixpack 12(?)

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