source: trunk/dll/filldir.c@ 1398

Last change on this file since 1398 was 1398, checked in by Gregg Young, 17 years ago

Move embeded strings to PCSZ variables or string table; Eliminate Error2 functions Runtime_Error with NULL format string returns "No data" error. Change declares from PSZ to PCSZ in functions where the variable isn't changed. Added btm as an executable file type in several additional places. Use fProtectOnly to prevent attempt to execute Dos and Win programs on "Protect only" installs in several additional places.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 59.8 KB
Line 
1
2/***********************************************************************
3
4 $Id: filldir.c 1398 2009-02-21 17:43:00Z gyoung $
5
6 Fill Directory Tree Containers
7
8 Copyright (c) 1993-98 M. Kimes
9 Copyright (c) 2001, 2008 Steven H. Levine
10
11 10 Jan 04 SHL ProcessDirectory: avoid most large drive failures
12 24 May 05 SHL Rework Win_Error usage
13 24 May 05 SHL Rework for CNRITEM.szSubject
14 25 May 05 SHL Rework for ULONGLONG
15 25 May 05 SHL Rework FillInRecordFromFFB
16 25 May 05 SHL Rework FillTreeCnr
17 28 May 05 SHL Drop stale debug code
18 05 Jun 05 SHL Comments
19 09 Jun 05 SHL Rework WinLoadFileIcon enables
20 09 Jun 05 SHL Rework IDFile
21 13 Aug 05 SHL Renames
22 24 Oct 05 SHL FillInRecordFromFFB: correct longname display enable
23 24 Oct 05 SHL FillInRecordFromFSA: correct longname display enable
24 24 Oct 05 SHL Drop obsolete code
25 22 Jul 06 SHL Check more run time errors
26 20 Oct 06 SHL Sync . .. check code
27 22 Oct 06 GKY Add NDFS32 support
28 17 Feb 07 GKY Additional archive and image file tyoes identifed by extension
29 17 Feb 07 GKY Add more drive types
30 09 Mar 07 GKY Use SelectDriveIcon
31 20 Mar 07 GKY Increase extention check to 4 letters for icon selections
32 23 Jun 07 GKY Fixed ram disk without a directory not appearing on states drive list
33 23 Jul 07 SHL Sync with CNRITEM updates (ticket#24)
34 29 Jul 07 SHL Add CNRITEM free and remove support (ticket#24)
35 02 Aug 07 SHL Add FileAttrToString
36 03 Aug 07 GKY Enlarged and made setable everywhere Findbuf (speed file loading)
37 04 Aug 07 SHL Update #pragma alloc_test for new functions
38 06 Aug 07 GKY Reduce DosSleep times (ticket 148)
39 13 Aug 07 SHL Sync code with other FilesToGet usage and optimize
40 13 Aug 07 SHL Move #pragma alloc_text to end for OpenWatcom compat
41 04 Nov 07 GKY Use commaFmtULL to display large file sizes
42 29 Feb 08 GKY Use xfree where appropriate
43 07 Jul 08 SHL Use NULL rather than NullStr in FreeCnrItemData
44 16 JUL 08 GKY Use TMP directory for temp files
45 20 Jul 08 JBS Ticket 114: Support user-selectable env. strings in Tree container.
46 21 Jul 08 JBS Ticket 114: Change env var separator from blank to semicolon
47 02 Aug 08 GKY Remove redundant strcpys from inner loop
48 23 Aug 08 GKY Free pszDisplayName when appropriate
49 01 Sep 08 GKY Updated FreeCnrItemData to prevent trap in strrchr if pci->pszFileName is NULL.
50 05 Sep 08 SHL Correct FreeCnrItemData pszDisplayName pointer overlap check
51 08 Sep 08 SHL Remove extra pszLongName logic in FreeCnrItemData
52 18 Oct 08 GKY Scan drives in 4 passes (local, virtual, remote, flagged slow) to speed tree scans
53 19 Nov 08 SHL Correct and sanitize 4 pass scan logic
54 21 Nov 08 SHL FillTreeCnr: ensure any unchecked drives checked in pass 4
55 24 Nov 08 GKY Add StubyScanThread to treecnr scan/rescan drives all on separate threads
56 24 Nov 08 GKY Replace 4 pass drive scan code with StubyScanThread multithread scan
57 28 Nov 08 SHL FreeCnrItemData: optimize and always NULL pointers
58 28 Nov 08 SHL StubbyScanThread: add else lost in translation
59 30 Nov 08 SHL StubbyScanThread: restore else - we want all drives listed
60 30 Nov 08 SHL FreeCnrItemData: report double free with Runtime_Error
61 04 Dec 08 GKY Use event semaphore to prevent scan of "last" directory container prior to
62 tree scan completion; prevents duplicate directory names in tree.
63 10 Dec 08 SHL Integrate exception handler support
64 25 Dec 08 GKY Add code to allow write verify to be turned off on a per drive basis
65 25 Dec 08 GKY Add ProcessDirectoryThread to allow optional recursive drive scan at startup.
66 07 Feb 09 GKY Eliminate Win_Error2 by moving function names to PCSZs used in Win_Error
67
68***********************************************************************/
69
70#include <stdlib.h>
71#include <string.h>
72#include <malloc.h> // _msize _heapchk
73#include <ctype.h>
74// #include <process.h> // _beginthread
75
76#define INCL_DOS
77#define INCL_WIN
78#define INCL_DOSERRORS
79#define INCL_LONGLONG
80
81#include "fm3dll.h"
82#include "fm3dll2.h" // #define's for UM_*, control id's, etc.
83#include "draglist.h" // Data declaration(s)
84#include "treecnr.h" // Data declaration(s)
85#include "info.h" // Data declaration(s)
86#include "newview.h" // Data declaration(s)
87#include "fm3str.h"
88#include "filldir.h"
89#include "errutil.h" // Dos_Error...
90#include "strutil.h" // GetPString
91#include "misc.h" // GetTidForWindow
92#include "fortify.h" // 06 May 08 SHL
93#include "notebook.h" // INI file fields
94#include "flesh.h" // FleshEnv, Stubby
95#include "update.h" // SelectDriveIcon
96#include "valid.h" // CheckDrive
97#include "filter.h" // Filter
98#include "subj.h" // Subject
99#include "copyf.h" // unlinkf
100#include "literal.h" // wildcard
101#include "commafmt.h" // CommaFmtULL
102#include "wrappers.h" // xDosFindNext
103#include "init.h" // GetTidForWindow
104#include "common.h" // IncrThreadUsage
105#include "excputil.h" // xbeginthread
106
107VOID StubbyScanThread(VOID * arg);
108
109// Data definitions
110static PSZ pszSrcFile = __FILE__;
111static BOOL fFirstTime;
112
113#pragma data_seg(GLOBAL1)
114HPOINTER hptrEnv;
115HPOINTER hptrHidden;
116HPOINTER hptrReadonly;
117HPOINTER hptrSystem;
118
119#pragma data_seg(GLOBAL2)
120CHAR *FM3Tools;
121CHAR *WPProgram;
122volatile INT StubbyScanCount;
123volatile INT ProcessDirCount;
124
125typedef struct {
126 PCNRITEM pci;
127 HWND hwndCnr; // hwnd you want the message posted to
128 HWND hwndDrivesList;
129 BOOL RamDrive;
130}
131STUBBYSCAN;
132
133/**
134 * Return display string given standard file attribute mask
135 * @param fileAttr attribute mask in FILEFINDBUF format
136 * @return fixed length string for display
137 */
138
139const PSZ FileAttrToString(ULONG fileAttr)
140{
141 // From os2win.h
142 // FILE_ATTRIBUTE_READONLY 0x00000001
143 // FILE_ATTRIBUTE_HIDDEN 0x00000002
144 // FILE_ATTRIBUTE_SYSTEM 0x00000004
145 // 0x00000008
146 // FILE_ATTRIBUTE_DIRECTORY 0x00000010
147 // FILE_ATTRIBUTE_ARCHIVE 0x00000020
148
149 static CHAR *apszAttrString[] = {
150 // RHSDA
151 "-----",
152 "R----",
153 "-H---",
154 "RH---",
155 "--S--",
156 "R-S--",
157 "-HS--",
158 "RHS--",
159 "---D-",
160 "R--D-",
161 "-H-D-",
162 "RH-D-",
163 "--SD-",
164 "R-SD-",
165 "-HSD-",
166 "RHSD-",
167 "----A",
168 "R---A",
169 "-H--A",
170 "RH--A",
171 "--S-A",
172 "R-S-A",
173 "-HS-A",
174 "RHS-A",
175 "---DA",
176 "R--DA",
177 "-H-DA",
178 "RH-DA",
179 "--SDA",
180 "R-SDA",
181 "-HSDA",
182 "RHSDA"
183 };
184
185 fileAttr = ((fileAttr & 0x30) >> 1) | (fileAttr & 7); // Drop don't care bit from index
186
187 return apszAttrString[fileAttr];
188
189}
190
191VOID StubbyScanThread(VOID * arg)
192{
193 STUBBYSCAN *StubbyScan;
194 HAB thab;
195 HMQ hmq = (HMQ) 0;
196 BOOL ret;
197
198 DosError(FERR_DISABLEHARDERR);
199
200# ifdef FORTIFY
201 Fortify_EnterScope();
202# endif
203
204 StubbyScan = (STUBBYSCAN *)arg;
205 if (StubbyScan && StubbyScan->pci && StubbyScan->pci->pszFileName && StubbyScan->hwndCnr) {
206 thab = WinInitialize(0);
207 if (thab) {
208 hmq = WinCreateMsgQueue(thab, 0);
209 if (hmq) {
210 StubbyScanCount++;
211 IncrThreadUsage();
212 priority_normal();
213 ret = Stubby(StubbyScan->hwndCnr, StubbyScan->pci);
214 //DbgMsg(pszSrcFile, __LINE__, "Stubby %i ", ret);
215 if (ret == 1) {
216 if (WinIsWindow((HAB)0, StubbyScan->hwndCnr)) {
217 WinSendMsg(StubbyScan->hwndCnr,
218 CM_INVALIDATERECORD,
219 MPFROMP(&StubbyScan->pci),
220 MPFROM2SHORT(1, CMA_ERASE | CMA_REPOSITION));
221 if (fRScanLocal) {
222 if (!(driveflags[toupper(*StubbyScan->pci->pszFileName) - 'A'] &
223 ((fRScanNoWrite ? 0 : DRIVE_NOTWRITEABLE) |
224 (fRScanRemote ? 0 : DRIVE_REMOTE) |
225 (fRScanSlow ? 0 : DRIVE_SLOW) |
226 (fRScanVirtual ? 0 : DRIVE_VIRTUAL)))
227 && fInitialDriveScan) {
228 WinSendMsg(StubbyScan->hwndCnr, CM_EXPANDTREE, MPFROMP(StubbyScan->pci), MPVOID);
229 //DbgMsg(pszSrcFile, __LINE__, "expanded %x %s", StubbyScan->hwndCnr, StubbyScan->pci->pszFileName);
230 WinSendMsg(StubbyScan->hwndCnr, CM_COLLAPSETREE, MPFROMP(StubbyScan->pci), MPVOID);
231 }
232 }
233 else if ((fRScanRemote && (driveflags[toupper(*StubbyScan->pci->pszFileName) - 'A'] &
234 DRIVE_REMOTE)) ||
235 (fRScanVirtual && (driveflags[toupper(*StubbyScan->pci->pszFileName) - 'A'] &
236 DRIVE_VIRTUAL)) && fInitialDriveScan) {
237 if (!(driveflags[toupper(*StubbyScan->pci->pszFileName) - 'A'] &
238 ((fRScanNoWrite ? NULL : DRIVE_NOTWRITEABLE) |
239 (fRScanSlow ? NULL : DRIVE_SLOW)))) {
240 WinSendMsg(StubbyScan->hwndCnr, CM_EXPANDTREE, MPFROMP(StubbyScan->pci), MPVOID);
241 //DbgMsg(pszSrcFile, __LINE__, "expanded %x %s", StubbyScan->hwndCnr, StubbyScan->pci->pszFileName);
242 WinSendMsg(StubbyScan->hwndCnr, CM_COLLAPSETREE, MPFROMP(StubbyScan->pci), MPVOID);
243 }
244 }
245 }
246 }
247 if (WinIsWindow((HAB)0, StubbyScan->hwndDrivesList)) {
248 WinSendMsg(StubbyScan->hwndDrivesList,
249 LM_INSERTITEM,
250 MPFROM2SHORT(LIT_SORTASCENDING, 0),
251 MPFROMP(StubbyScan->pci->pszFileName));
252 }
253 StubbyScanCount--;
254 /* if (StubbyScanCount == 0) {
255 if (fInitialDriveScan) {
256 WinShowWindow(StubbyScan->hwndCnr, TRUE);
257 WinShowWindow(StubbyScan->hwndDrivesList, TRUE);
258 }
259 fInitialDriveScan = FALSE;
260 }*/
261 WinDestroyMsgQueue(hmq);
262 }
263 DecrThreadUsage();
264 WinTerminate(thab);
265 }
266 free(StubbyScan);
267 } // if StubbyScan
268# ifdef FORTIFY
269 Fortify_LeaveScope();
270# endif
271
272 // _endthread(); // 10 Dec 08 SHL
273}
274
275VOID ProcessDirectoryThread(VOID * arg)
276{
277 PROCESSDIR *ProcessDir;
278 HAB thab;
279 HMQ hmq = (HMQ) 0;
280 //BOOL ret;
281
282 DosError(FERR_DISABLEHARDERR);
283
284# ifdef FORTIFY
285 Fortify_EnterScope();
286# endif
287
288 ProcessDir = (PROCESSDIR *)arg;
289 if (ProcessDir && ProcessDir->pciParent && ProcessDir->pciParent->pszFileName && ProcessDir->hwndCnr) {
290 thab = WinInitialize(0);
291 if (thab) {
292 hmq = WinCreateMsgQueue(thab, 0);
293 if (hmq) {
294 ProcessDirCount ++;
295 IncrThreadUsage();
296 priority_normal();
297 ProcessDirectory(ProcessDir->hwndCnr,
298 ProcessDir->pciParent,
299 ProcessDir->szDirBase,
300 ProcessDir->filestoo,
301 ProcessDir->recurse,
302 ProcessDir->partial,
303 ProcessDir->stopflag,
304 ProcessDir->dcd, // Optional
305 ProcessDir->pulTotalFiles, // Optional
306 ProcessDir->pullTotalBytes); // Optional
307 ProcessDirCount --;
308 WinDestroyMsgQueue(hmq);
309 }
310 DecrThreadUsage();
311 WinTerminate(thab);
312 }
313 free(ProcessDir);
314 } // if ProcessDir
315# ifdef FORTIFY
316 Fortify_LeaveScope();
317# endif
318
319 // _endthread(); // 10 Dec 08 SHL
320}
321
322static HPOINTER IDFile(PSZ p)
323{
324 HPOINTER hptr;
325 ULONG cmp;
326 CHAR cmps[5];
327
328 p = strrchr(p, '.');
329 if (p && !p[5]) {
330 cmps[0] = '.';
331 cmps[1] = toupper(p[1]);
332 cmps[2] = toupper(p[2]);
333 cmps[3] = toupper(p[3]);
334 cmps[4] = toupper(p[4]);
335
336 cmp = *(ULONG *) cmps;
337
338 if (cmp == *(ULONG *) PCSZ_DOTEXE || cmp == *(ULONG *) PCSZ_DOTCMD ||
339 cmp == *(ULONG *) PCSZ_DOTBAT || cmp == *(ULONG *) PCSZ_DOTCOM ||
340 cmp == *(ULONG *) PCSZ_DOTBTM)
341 hptr = hptrApp;
342 else if (cmp == *(ULONG *) ".ZIP" || cmp == *(ULONG *) ".LZH" ||
343 cmp == *(ULONG *) ".ARJ" || cmp == *(ULONG *) ".ARC" ||
344 cmp == *(ULONG *) ".ZOO" || cmp == *(ULONG *) ".RAR" ||
345 cmp == *(ULONG *) ".TAR" || cmp == *(ULONG *) ".TGZ" ||
346 cmp == *(ULONG *) ".GZ" || cmp == *(ULONG *) ".Z" ||
347 cmp == *(ULONG *) ".CAB" || cmp == *(ULONG *) ".BZ2")
348 hptr = hptrArc;
349 else if (cmp == *(ULONG *) PCSZ_DOTBMP ||
350 cmp == *(ULONG *) PCSZ_DOTICO ||
351 cmp == *(ULONG *) PCSZ_DOTPTR ||
352 cmp == *(ULONG *) PCSZ_DOTJPEG ||
353 cmp == *(ULONG *) PCSZ_DOTJPG ||
354 cmp == *(ULONG *) ".GIF" ||
355 cmp == *(ULONG *) ".TIF" || cmp == *(ULONG *) ".PCX" ||
356 cmp == *(ULONG *) ".TGA" || cmp == *(ULONG *) ".XBM" ||
357 cmp == *(ULONG *) ".PNG" || cmp == *(ULONG *) ".PSD" ||
358 cmp == *(ULONG *) ".LGO" || cmp == *(ULONG *) ".EPS" ||
359 cmp == *(ULONG *) ".RLE" || cmp == *(ULONG *) ".RAS" ||
360 cmp == *(ULONG *) ".PLC" || cmp == *(ULONG *) ".MSP" ||
361 cmp == *(ULONG *) ".IFF" || cmp == *(ULONG *) ".FIT" ||
362 cmp == *(ULONG *) ".DCX" || cmp == *(ULONG *) ".MAC" ||
363 cmp == *(ULONG *) ".SFF" || cmp == *(ULONG *) ".SGI" ||
364 cmp == *(ULONG *) ".XWD" || cmp == *(ULONG *) ".XPM" ||
365 cmp == *(ULONG *) ".WPG" || cmp == *(ULONG *) ".CUR" ||
366 cmp == *(ULONG *) ".PNM" || cmp == *(ULONG *) ".PPM" ||
367 cmp == *(ULONG *) ".PGM" || cmp == *(ULONG *) ".PBM")
368 hptr = hptrArt;
369 else
370 hptr = (HPOINTER) 0;
371 }
372 else
373 hptr = (HPOINTER) 0;
374
375 return hptr;
376}
377
378static BOOL IsDefaultIcon(HPOINTER hptr)
379{
380 HPOINTER hptr2;
381 HPOINTER hptr3;
382 UINT u;
383
384 static HPOINTER hptrPMFile;
385 static HPOINTER hptrWPSFile;
386
387 if (!hptrPMFile) {
388 hptrPMFile = WinQuerySysPointer(HWND_DESKTOP, SPTR_FILE, FALSE);
389 }
390
391 // try to guess WPS default file icon
392 hptr2 = (HPOINTER) 0;
393 for (u = 0; !hptrWPSFile && u < 10; u++) {
394 char szFileName[CCHMAXPATH];
395 char *psz;
396
397 if (pTmpDir) {
398 psz = pTmpDir;
399 strcpy(szFileName, psz);
400 psz = szFileName + strlen(szFileName) - 1;
401 if (*psz != '\\') {
402 psz++;
403 *psz++ = '\\';
404 }
405 }
406 else
407 psz = szFileName;
408
409 sprintf(psz, "%08x.%03x", rand() & 0xffffffff, rand() & 0xfff);
410 if (IsFile(szFileName) != 1) {
411 FILE *fp = fopen(szFileName, "w");
412
413 if (fp) {
414 fclose(fp);
415 hptr3 = WinLoadFileIcon(szFileName, FALSE);
416 unlinkf("%s", szFileName);
417 if (!hptr2)
418 hptr2 = hptr3;
419 else if (hptr3 == hptr3) {
420 hptrWPSFile = hptr3; // Got same icon twice
421 break;
422 }
423 }
424 }
425 DosSleep(rand() % 100);
426
427 } // for
428
429 return hptr == hptrPMFile || hptr == hptrWPSFile;
430
431} // IsDefaultIcon
432
433ULONGLONG FillInRecordFromFFB(HWND hwndCnr,
434 PCNRITEM pci,
435 const PSZ pszDirectory,
436 const PFILEFINDBUF4L pffb,
437 const BOOL partial,
438 DIRCNRDATA *dcd)
439{
440 // fill in a container record from a FILEFINDBUF4L structure
441
442 CHAR *p;
443 HPOINTER hptr;
444 ULONG flags;
445
446 pci->hwndCnr = hwndCnr;
447
448 /* note that we cheat below, and accept the full pathname in pszDirectory
449 if !*pffb->achName. This speeds up and simplifies processing elsewhere
450 (like in update.c)
451 */
452 if (!*pffb->achName) {
453 pci->pszFileName = xstrdup(pszDirectory, pszSrcFile, __LINE__);
454 //strcpy(pci->pszFileName, pszDirectory);
455 }
456 else {
457 INT c = strlen(pszDirectory);
458 INT c2 = pffb->cchName + 1;
459 if (pszDirectory[c - 1] != '\\')
460 c2++;
461 pci->pszFileName = xmalloc(c + c2, pszSrcFile, __LINE__);
462# ifdef FORTIFY
463 {
464 if (dcd->type != TREE_FRAME)
465 Fortify_ChangeScope(pci->pszFileName, -1);
466 else {
467 Fortify_SetOwner(pci->pszFileName, 1);
468 Fortify_SetScope(pci->pszFileName, 2);
469 }
470 }
471# endif
472 memcpy(pci->pszFileName, pszDirectory, c + 1);
473 p = pci->pszFileName + c - 1;
474 if (*p != '\\') {
475 p++;
476 *p = '\\';
477 }
478 p++;
479 memcpy(p, pffb->achName, pffb->cchName + 1);
480 }
481 flags = driveflags[toupper(*pci->pszFileName) - 'A'];
482 // load the object's Subject, if required
483 // pci->pszSubject = NullStr; dubplicate see below 12-05-08 GKY
484 if (pffb->cbList > 4L &&
485 dcd && fLoadSubject &&
486 (isalpha(*pci->pszFileName) &&
487 !(flags & DRIVE_NOLOADSUBJS)))
488 {
489 APIRET rc;
490 EAOP2 eaop;
491 PGEA2LIST pgealist;
492 PFEA2LIST pfealist;
493 PGEA2 pgea;
494 PFEA2 pfea;
495 CHAR *value;
496
497 pgealist = xmallocz(sizeof(GEA2LIST) + 32, pszSrcFile, __LINE__);
498 if (pgealist) {
499 pgea = &pgealist->list[0];
500 strcpy(pgea->szName, SUBJECT);
501 pgea->cbName = strlen(pgea->szName);
502 pgea->oNextEntryOffset = 0;
503 pgealist->cbList = (sizeof(GEA2LIST) + pgea->cbName);
504 pfealist = xmallocz(1532, pszSrcFile, __LINE__);
505 if (pfealist) {
506 pfealist->cbList = 1024;
507 eaop.fpGEA2List = pgealist;
508 eaop.fpFEA2List = pfealist;
509 eaop.oError = 0;
510 rc = DosQueryPathInfo(pci->pszFileName, FIL_QUERYEASFROMLIST,
511 (PVOID) & eaop, (ULONG) sizeof(EAOP2));
512 if (!rc) {
513 pfea = &eaop.fpFEA2List->list[0];
514 value = pfea->szName + pfea->cbName + 1;
515 value[pfea->cbValue] = 0;
516 if (*(USHORT *) value == EAT_ASCII)
517 pci->pszSubject = xstrdup(value + (sizeof(USHORT) * 2), pszSrcFile, __LINE__);
518 }
519 free(pfealist);
520 }
521 free(pgealist);
522 }
523 }
524 if (!pci->pszSubject)
525 pci->pszSubject = NullStr;
526
527 // load the object's longname
528 pci->pszLongName = NULL;
529 if (fLoadLongnames &&
530 dcd &&
531 pffb->cbList > 4L &&
532 isalpha(*pci->pszFileName) &&
533 ~flags & DRIVE_NOLONGNAMES &&
534 ~flags & DRIVE_NOLOADLONGS)
535 {
536 APIRET rc;
537 EAOP2 eaop;
538 PGEA2LIST pgealist;
539 PFEA2LIST pfealist;
540 PGEA2 pgea;
541 PFEA2 pfea;
542 CHAR *value;
543
544 pgealist = xmallocz(sizeof(GEA2LIST) + 32, pszSrcFile, __LINE__);
545 if (pgealist) {
546 pgea = &pgealist->list[0];
547 strcpy(pgea->szName, LONGNAME);
548 pgea->cbName = strlen(pgea->szName);
549 pgea->oNextEntryOffset = 0;
550 pgealist->cbList = (sizeof(GEA2LIST) + pgea->cbName);
551 pfealist = xmallocz(1532, pszSrcFile, __LINE__);
552 if (pfealist) {
553 pfealist->cbList = 1024;
554 eaop.fpGEA2List = pgealist;
555 eaop.fpFEA2List = pfealist;
556 eaop.oError = 0;
557 rc = DosQueryPathInfo(pci->pszFileName, FIL_QUERYEASFROMLIST,
558 (PVOID) & eaop, (ULONG) sizeof(EAOP2));
559 if (!rc) {
560 pfea = &eaop.fpFEA2List->list[0];
561 value = pfea->szName + pfea->cbName + 1;
562 value[pfea->cbValue] = 0;
563 if (*(USHORT *) value == EAT_ASCII) {
564 pci->pszLongName = xstrdup(value + (sizeof(USHORT) * 2), pszSrcFile, __LINE__);
565# ifdef FORTIFY
566 {
567 unsigned tid = GetTidForWindow(hwndCnr);
568 if (tid == 1)
569 Fortify_ChangeScope(pci->pszLongName, -1);
570 else
571 Fortify_SetOwner(pci->pszLongName, 1);
572 }
573# endif
574 }
575 }
576 free(pfealist);
577 }
578 free(pgealist);
579 }
580 }
581 if (!pci->pszLongName)
582 pci->pszLongName = NullStr;
583
584 // do anything required to case of filename
585 if (fForceUpper)
586 strupr(pci->pszFileName);
587 else if (fForceLower)
588 strlwr(pci->pszFileName);
589
590 // get an icon to use with it
591 if (pffb->attrFile & FILE_DIRECTORY) {
592 // is directory
593 if (fNoIconsDirs ||
594 (flags & DRIVE_NOLOADICONS) ||
595 !isalpha(*pci->pszFileName)) {
596 hptr = (HPOINTER) 0;
597 }
598 else
599 hptr = WinLoadFileIcon(pci->pszFileName, FALSE);
600 }
601 else {
602 // is file
603 if (fNoIconsFiles ||
604 (flags & DRIVE_NOLOADICONS) ||
605 !isalpha(*pci->pszFileName)) {
606 hptr = (HPOINTER) 0;
607 }
608 else
609 hptr = WinLoadFileIcon(pci->pszFileName, FALSE);
610
611 if (!hptr || IsDefaultIcon(hptr))
612 hptr = IDFile(pci->pszFileName);
613 }
614
615 if (!hptr) {
616 hptr = pffb->attrFile & FILE_DIRECTORY ?
617 hptrDir : pffb->attrFile & FILE_SYSTEM ?
618 hptrSystem : pffb->attrFile & FILE_HIDDEN ?
619 hptrHidden : pffb->attrFile & FILE_READONLY ?
620 hptrReadonly : hptrFile;
621 }
622
623 // Tell container what part of pathname to display
624 if (partial) {
625 p = strrchr(pci->pszFileName, '\\');
626 if (!p) {
627 p = strrchr(pci->pszFileName, ':');
628 if (!p)
629 p = pci->pszFileName;
630 else
631 p++;
632 }
633 else if ((dcd && dcd->type == TREE_FRAME) ||
634 (!(pffb->attrFile & FILE_DIRECTORY) || !*(p + 1))) {
635 p++;
636 }
637 if (!*p)
638 p = pci->pszFileName;
639 }
640 else
641 p = pci->pszFileName;
642 pci->pszDisplayName = p;
643
644 //comma format the file size for large file support
645 {
646 CHAR szBuf[30];
647 CommaFmtULL(szBuf, sizeof(szBuf), pffb->cbFile, ' ');
648 pci->pszFmtFileSize = xstrdup(szBuf, pszSrcFile, __LINE__);
649# ifdef FORTIFY
650 {
651 unsigned tid = GetTidForWindow(hwndCnr);
652 if (tid == 1)
653 Fortify_ChangeScope(pci->pszFmtFileSize, -1);
654 else
655 Fortify_SetOwner(pci->pszFmtFileSize, 1);
656 }
657# endif
658 }
659
660 // now fill the darned thing in...
661 pci->date.day = pffb->fdateLastWrite.day;
662 pci->date.month = pffb->fdateLastWrite.month;
663 pci->date.year = pffb->fdateLastWrite.year + 1980;
664 pci->time.seconds = pffb->ftimeLastWrite.twosecs * 2;
665 pci->time.minutes = pffb->ftimeLastWrite.minutes;
666 pci->time.hours = pffb->ftimeLastWrite.hours;
667 pci->ladate.day = pffb->fdateLastAccess.day;
668 pci->ladate.month = pffb->fdateLastAccess.month;
669 pci->ladate.year = pffb->fdateLastAccess.year + 1980;
670 pci->latime.seconds = pffb->ftimeLastAccess.twosecs * 2;
671 pci->latime.minutes = pffb->ftimeLastAccess.minutes;
672 pci->latime.hours = pffb->ftimeLastAccess.hours;
673 pci->crdate.day = pffb->fdateCreation.day;
674 pci->crdate.month = pffb->fdateCreation.month;
675 pci->crdate.year = pffb->fdateCreation.year + 1980;
676 pci->crtime.seconds = pffb->ftimeCreation.twosecs * 2;
677 pci->crtime.minutes = pffb->ftimeCreation.minutes;
678 pci->crtime.hours = pffb->ftimeCreation.hours;
679 pci->easize = CBLIST_TO_EASIZE(pffb->cbList);
680 pci->cbFile = pffb->cbFile;
681 pci->attrFile = pffb->attrFile;
682 pci->pszDispAttr = FileAttrToString(pci->attrFile);
683 pci->rc.pszIcon = pci->pszDisplayName;
684 pci->rc.hptrIcon = hptr;
685
686 // check to see if record should be visible
687 if (dcd && (*dcd->mask.szMask || dcd->mask.antiattr ||
688 ((dcd->mask.attrFile &
689 (FILE_HIDDEN | FILE_SYSTEM | FILE_READONLY | FILE_ARCHIVED))
690 !=
691 (FILE_HIDDEN | FILE_SYSTEM | FILE_READONLY | FILE_ARCHIVED))))
692 {
693 if (*dcd->mask.szMask || dcd->mask.antiattr) {
694 if (!Filter((PMINIRECORDCORE) pci, (PVOID) & dcd->mask))
695 pci->rc.flRecordAttr |= CRA_FILTERED;
696 }
697 else if ((!(dcd->mask.attrFile & FILE_HIDDEN) &&
698 (pci->attrFile & FILE_HIDDEN)) ||
699 (!(dcd->mask.attrFile & FILE_SYSTEM) &&
700 (pci->attrFile & FILE_SYSTEM)) ||
701 (!(dcd->mask.attrFile & FILE_READONLY) &&
702 (pci->attrFile & FILE_READONLY)) ||
703 (!(dcd->mask.attrFile & FILE_ARCHIVED) &&
704 (pci->attrFile & FILE_ARCHIVED))) {
705 pci->rc.flRecordAttr |= CRA_FILTERED;
706 }
707 }
708
709 return pffb->cbFile + pci->easize;
710
711} // FillInRecordFromFFB
712
713ULONGLONG FillInRecordFromFSA(HWND hwndCnr,
714 PCNRITEM pci,
715 const PSZ pszFileName,
716 const PFILESTATUS4L pfsa4,
717 const BOOL partial,
718 DIRCNRDATA *dcd) // Optional
719{
720 HPOINTER hptr;
721 CHAR *p;
722 ULONG flags;
723
724 // fill in a container record from a FILESTATUS4L structure
725
726 pci->hwndCnr = hwndCnr;
727 pci->pszFileName = xstrdup(pszFileName, pszSrcFile, __LINE__);
728 //strcpy(pci->pszFileName, pszFileName);
729 flags = driveflags[toupper(*pci->pszFileName) - 'A'];
730 // load the object's Subject, if required
731 //pci->pszSubject = NullStr;
732 if (pfsa4->cbList > 4 &&
733 dcd &&
734 fLoadSubject &&
735 (!isalpha(*pci->pszFileName) ||
736 !(flags & DRIVE_NOLOADSUBJS)))
737 {
738 APIRET rc;
739 EAOP2 eaop;
740 PGEA2LIST pgealist;
741 PFEA2LIST pfealist;
742 PGEA2 pgea;
743 PFEA2 pfea;
744 CHAR *value;
745
746 pgealist = xmallocz(sizeof(GEA2LIST) + 32, pszSrcFile, __LINE__);
747 if (pgealist) {
748 pgea = &pgealist->list[0];
749 strcpy(pgea->szName, SUBJECT);
750 pgea->cbName = strlen(pgea->szName);
751 pgea->oNextEntryOffset = 0;
752 pgealist->cbList = (sizeof(GEA2LIST) + pgea->cbName);
753 pfealist = xmallocz(1532, pszSrcFile, __LINE__);
754 if (pfealist) {
755 pfealist->cbList = 1024;
756 eaop.fpGEA2List = pgealist;
757 eaop.fpFEA2List = pfealist;
758 eaop.oError = 0;
759 rc = DosQueryPathInfo(pci->pszFileName, FIL_QUERYEASFROMLIST,
760 (PVOID) & eaop, (ULONG) sizeof(EAOP2));
761 if (!rc) {
762 pfea = &eaop.fpFEA2List->list[0];
763 value = pfea->szName + pfea->cbName + 1;
764 value[pfea->cbValue] = 0;
765 if (*(USHORT *) value == EAT_ASCII)
766 pci->pszSubject = xstrdup(value + (sizeof(USHORT) * 2), pszSrcFile, __LINE__);
767 }
768 free(pfealist);
769 }
770 free(pgealist);
771 }
772 }
773 if (!pci->pszSubject)
774 pci->pszSubject = NullStr;
775
776 pci->pszLongName = NULL;
777 if (fLoadLongnames &&
778 dcd &&
779 pfsa4->cbList > 4L &&
780 isalpha(*pci->pszFileName) &&
781 ~flags & DRIVE_NOLONGNAMES &&
782 ~flags & DRIVE_NOLOADLONGS)
783 {
784 APIRET rc;
785 EAOP2 eaop;
786 PGEA2LIST pgealist;
787 PFEA2LIST pfealist;
788 PGEA2 pgea;
789 PFEA2 pfea;
790 CHAR *value;
791
792 pgealist = xmallocz(sizeof(GEA2LIST) + 32, pszSrcFile, __LINE__);
793 if (pgealist) {
794 pgea = &pgealist->list[0];
795 strcpy(pgea->szName, LONGNAME);
796 pgea->cbName = strlen(pgea->szName);
797 pgea->oNextEntryOffset = 0;
798 pgealist->cbList = (sizeof(GEA2LIST) + pgea->cbName);
799 pfealist = xmallocz(1532, pszSrcFile, __LINE__);
800 if (pfealist) {
801 pfealist->cbList = 1024;
802 eaop.fpGEA2List = pgealist;
803 eaop.fpFEA2List = pfealist;
804 eaop.oError = 0;
805 rc = DosQueryPathInfo(pci->pszFileName, FIL_QUERYEASFROMLIST,
806 (PVOID) & eaop, (ULONG) sizeof(EAOP2));
807 if (!rc) {
808 pfea = &eaop.fpFEA2List->list[0];
809 value = pfea->szName + pfea->cbName + 1; // Point at EA value
810 value[pfea->cbValue] = 0; // Terminate
811 if (*(USHORT *) value == EAT_ASCII) {
812 p = value + sizeof(USHORT) * 2; // Point at value string
813 pci->pszLongName = xstrdup(p, pszSrcFile, __LINE__);
814 }
815 }
816 free(pfealist);
817 }
818 free(pgealist);
819 }
820 }
821 if (!pci->pszLongName)
822 pci->pszLongName = NullStr;
823
824 if (fForceUpper)
825 strupr(pci->pszFileName);
826 else if (fForceLower)
827 strlwr(pci->pszFileName);
828
829 if (pfsa4->attrFile & FILE_DIRECTORY) {
830 if (fNoIconsDirs ||
831 (flags & DRIVE_NOLOADICONS) ||
832 !isalpha(*pci->pszFileName)) {
833 hptr = (HPOINTER) 0;
834 }
835 else
836 hptr = WinLoadFileIcon(pci->pszFileName, FALSE);
837 }
838 else {
839 if (fNoIconsFiles ||
840 (flags & DRIVE_NOLOADICONS) ||
841 !isalpha(*pci->pszFileName)) {
842 hptr = IDFile(pci->pszFileName);
843 }
844 else
845 hptr = WinLoadFileIcon(pci->pszFileName, FALSE);
846 }
847 if (!hptr) {
848 hptr = pfsa4->attrFile & FILE_DIRECTORY ?
849 hptrDir :
850 pfsa4->attrFile & FILE_SYSTEM ?
851 hptrSystem :
852 pfsa4->attrFile & FILE_HIDDEN ?
853 hptrHidden : pfsa4->attrFile & FILE_READONLY ? hptrReadonly : hptrFile;
854 }
855
856 // Tell container what part of pathname to display
857 if (partial) {
858 p = strrchr(pci->pszFileName, '\\');
859 if (!p) {
860 p = strrchr(pci->pszFileName, ':');
861 if (!p)
862 p = pci->pszFileName;
863 else
864 p++;
865 }
866 else if ((dcd && dcd->type == TREE_FRAME) ||
867 !(pfsa4->attrFile & FILE_DIRECTORY) || !*(p + 1))
868 p++;
869 if (!*p)
870 p = pci->pszFileName;
871 }
872 else
873 p = pci->pszFileName;
874 pci->pszDisplayName = p;
875
876 //comma format the file size for large file support
877 {
878 CHAR szBuf[30];
879 CommaFmtULL(szBuf, sizeof(szBuf), pfsa4->cbFile, ' ');
880 pci->pszFmtFileSize = xstrdup(szBuf, pszSrcFile, __LINE__);
881# ifdef FORTIFY
882 {
883 if (dcd && dcd->type == TREE_FRAME) {
884 // Will be freed in TreeCnrWndProc WM_DESTROY
885 // Fortify_SetOwner(pci->pszFmtFileSize, 1);
886 Fortify_SetScope(pci->pszFmtFileSize, 2);
887 }
888 }
889# endif
890 }
891 pci->date.day = pfsa4->fdateLastWrite.day;
892 pci->date.month = pfsa4->fdateLastWrite.month;
893 pci->date.year = pfsa4->fdateLastWrite.year + 1980;
894 pci->time.seconds = pfsa4->ftimeLastWrite.twosecs * 2;
895 pci->time.minutes = pfsa4->ftimeLastWrite.minutes;
896 pci->time.hours = pfsa4->ftimeLastWrite.hours;
897 pci->ladate.day = pfsa4->fdateLastAccess.day;
898 pci->ladate.month = pfsa4->fdateLastAccess.month;
899 pci->ladate.year = pfsa4->fdateLastAccess.year + 1980;
900 pci->latime.seconds = pfsa4->ftimeLastAccess.twosecs * 2;
901 pci->latime.minutes = pfsa4->ftimeLastAccess.minutes;
902 pci->latime.hours = pfsa4->ftimeLastAccess.hours;
903 pci->crdate.day = pfsa4->fdateCreation.day;
904 pci->crdate.month = pfsa4->fdateCreation.month;
905 pci->crdate.year = pfsa4->fdateCreation.year + 1980;
906 pci->crtime.seconds = pfsa4->ftimeCreation.twosecs * 2;
907 pci->crtime.minutes = pfsa4->ftimeCreation.minutes;
908 pci->crtime.hours = pfsa4->ftimeCreation.hours;
909 pci->easize = CBLIST_TO_EASIZE(pfsa4->cbList);
910 pci->cbFile = pfsa4->cbFile;
911 pci->attrFile = pfsa4->attrFile;
912 pci->pszDispAttr = FileAttrToString(pci->attrFile);
913 pci->rc.pszIcon = pci->pszDisplayName;
914 pci->rc.hptrIcon = hptr;
915
916 if (dcd &&
917 (*dcd->mask.szMask || dcd->mask.antiattr ||
918 ((dcd->mask.attrFile &
919 (FILE_HIDDEN | FILE_SYSTEM | FILE_READONLY | FILE_ARCHIVED)) !=
920 (FILE_HIDDEN | FILE_SYSTEM | FILE_READONLY | FILE_ARCHIVED)))) {
921 if (*dcd->mask.szMask || dcd->mask.antiattr) {
922 if (!Filter((PMINIRECORDCORE) pci, (PVOID) & dcd->mask))
923 pci->rc.flRecordAttr |= CRA_FILTERED;
924 }
925 else if ((!(dcd->mask.attrFile & FILE_HIDDEN) &&
926 (pci->attrFile & FILE_HIDDEN)) ||
927 (!(dcd->mask.attrFile & FILE_SYSTEM) &&
928 (pci->attrFile & FILE_SYSTEM)) ||
929 (!(dcd->mask.attrFile & FILE_READONLY) &&
930 (pci->attrFile & FILE_READONLY)) ||
931 (!(dcd->mask.attrFile & FILE_ARCHIVED) &&
932 (pci->attrFile & FILE_ARCHIVED)))
933 pci->rc.flRecordAttr |= CRA_FILTERED;
934 }
935
936 return pfsa4->cbFile + pci->easize;
937
938} // FillInRecordFromFSA
939
940VOID ProcessDirectory(const HWND hwndCnr,
941 const PCNRITEM pciParent,
942 const CHAR *szDirBase,
943 const BOOL filestoo,
944 const BOOL recurse,
945 const BOOL partial,
946 CHAR *stopflag,
947 DIRCNRDATA *dcd, // Optional
948 ULONG *pulTotalFiles, // Optional
949 PULONGLONG pullTotalBytes) // Optional
950{
951 /* put all the directories (and files if filestoo is TRUE) from a
952 * directory into the container. recurse through subdirectories if
953 * recurse is TRUE.
954 */
955
956 PSZ pszFileSpec;
957 INT t;
958 PFILEFINDBUF4L paffbFound;
959 PFILEFINDBUF4L *papffbSelected;
960 PFILEFINDBUF4L pffbFile;
961 PFILEFINDBUF4L paffbTotal = NULL;
962 PFILEFINDBUF4L paffbTemp;
963 HDIR hdir = HDIR_CREATE;
964 ULONG ulFindCnt;
965 ULONG ulFindMax;
966 ULONG ulSelCnt;
967 ULONG ulTotal = 0;
968 ULONGLONG ullBytes;
969 ULONGLONG ullTotalBytes;
970 ULONG ulReturnFiles = 0;
971 ULONGLONG ullReturnBytes = 0;
972 PCH pchEndPath;
973 APIRET rc;
974 PCNRITEM pci;
975 PCNRITEM pciFirst;
976 RECORDINSERT ri;
977 BOOL ok = TRUE;
978 ULONG ulBufBytes;
979 ULONG x;
980
981 if (isalpha(*szDirBase) && szDirBase[1] == ':' && szDirBase[2] == '\\') {
982 if ((driveflags[toupper(*szDirBase) - 'A'] & DRIVE_REMOTE) && fRemoteBug)
983 ulFindMax = 1; // file system gets confused
984 else if (driveflags[toupper(*szDirBase) - 'A'] & DRIVE_ZIPSTREAM)
985 ulFindMax = min(FilesToGet, 225); // anything more is wasted
986 else
987 ulFindMax = FilesToGet; // full-out
988 }
989 else
990 ulFindMax = FilesToGet;
991
992 if (OS2ver[0] == 20 && OS2ver[1] < 30)
993 ulFindMax = min(ulFindMax, (65535 / sizeof(FILEFINDBUF4L)));
994
995 ulBufBytes = ulFindMax * sizeof(FILEFINDBUF4L);
996
997 pszFileSpec = xmalloc(CCHMAXPATH + 2, pszSrcFile, __LINE__);
998 paffbFound = xmalloc(ulBufBytes, pszSrcFile, __LINE__);
999 papffbSelected = xmalloc(sizeof(PFILEFINDBUF4L) * ulFindMax, pszSrcFile, __LINE__);
1000
1001 if (paffbFound && papffbSelected && pszFileSpec) {
1002 t = strlen(szDirBase);
1003 memcpy(pszFileSpec, szDirBase, t + 1);
1004 pchEndPath = pszFileSpec + t;
1005 if (*(pchEndPath - 1) != '\\') {
1006 memcpy(pchEndPath, "\\", 2);
1007 pchEndPath++;
1008 }
1009 memcpy(pchEndPath, "*", 2);
1010 DosError(FERR_DISABLEHARDERR);
1011 ulFindCnt = ulFindMax;
1012 rc = xDosFindFirst(pszFileSpec,
1013 &hdir,
1014 FILE_NORMAL | FILE_READONLY | FILE_ARCHIVED |
1015 FILE_SYSTEM | FILE_HIDDEN |
1016 (filestoo ? FILE_DIRECTORY : MUST_HAVE_DIRECTORY),
1017 paffbFound,
1018 ulBufBytes,
1019 &ulFindCnt,
1020 FIL_QUERYEASIZEL);
1021 priority_normal();
1022 *pchEndPath = 0; // Chop off wildcard
1023 if (!rc) {
1024 do {
1025 /*
1026 * remove . and .. from list if present
1027 * also counter file system bugs that sometimes
1028 * allows normal files to slip through when
1029 * only directories should appear (only a few
1030 * network file systems exhibit such a problem).
1031 */
1032
1033 if (stopflag && *stopflag)
1034 goto Abort;
1035 pffbFile = paffbFound;
1036 ulSelCnt = 0;
1037 for (;;) {
1038 if (!*pffbFile->achName ||
1039 (!filestoo && ~pffbFile->attrFile & FILE_DIRECTORY) ||
1040 (pffbFile->attrFile & FILE_DIRECTORY &&
1041 pffbFile->achName[0] == '.' &&
1042 (!pffbFile->achName[1] ||
1043 (pffbFile->achName[1] == '.' && !pffbFile->achName[2])))) {
1044 // ulFindCnt--; // Got . or .. or file to be skipped
1045 }
1046 else
1047 papffbSelected[ulSelCnt++] = pffbFile; // Remember selected file
1048 if (!pffbFile->oNextEntryOffset) {
1049 // ulFindCnt = ulSelCnt; // Remember number selected
1050 break;
1051 }
1052 pffbFile = (PFILEFINDBUF4L)((PBYTE)pffbFile + pffbFile->oNextEntryOffset);
1053 } // for
1054 if (ulSelCnt) {
1055 // One or more entries selected
1056 if (stopflag && *stopflag)
1057 goto Abort;
1058 if (fSyncUpdates) {
1059 pciFirst = WinSendMsg(hwndCnr, CM_ALLOCRECORD,
1060 MPFROMLONG(EXTRA_RECORD_BYTES),
1061 MPFROMLONG(ulSelCnt));
1062 if (!pciFirst) {
1063 Win_Error(hwndCnr, HWND_DESKTOP, pszSrcFile, __LINE__,
1064 GetPString(IDS_CMALLOCRECERRTEXT));
1065 ok = FALSE;
1066 ullTotalBytes = 0;
1067 }
1068 else {
1069 // 04 Jan 08 SHL fixme like comp.c to handle less than ulSelCnt records
1070 pci = pciFirst;
1071 ullTotalBytes = 0;
1072 // Insert selected in container
1073 for (x = 0; x < ulSelCnt; x++) {
1074 pffbFile = papffbSelected[x];
1075 ullBytes = FillInRecordFromFFB(hwndCnr, pci, pszFileSpec,
1076 pffbFile, partial, dcd);
1077 pci = (PCNRITEM) pci->rc.preccNextRecord;
1078 ullTotalBytes += ullBytes;
1079 } // for
1080 memset(&ri, 0, sizeof(RECORDINSERT));
1081 ri.cb = sizeof(RECORDINSERT);
1082 ri.pRecordOrder = (PRECORDCORE) CMA_END;
1083 ri.pRecordParent = (PRECORDCORE) pciParent;
1084 ri.zOrder = (ULONG) CMA_TOP;
1085 ri.cRecordsInsert = ulSelCnt;
1086 ri.fInvalidateRecord = TRUE;
1087 // !fSyncUpdates && dcd && dcd->type == DIR_FRAME ? FALSE : TRUE; //fSyncUpdates always TRUE 12-1-08 GKY
1088 if (!WinSendMsg(hwndCnr,
1089 CM_INSERTRECORD,
1090 MPFROMP(pciFirst), MPFROMP(&ri))) {
1091 DosSleep(10); // Give GUI time to work
1092 WinSetFocus(HWND_DESKTOP, hwndCnr);
1093 if (!WinSendMsg(hwndCnr,
1094 CM_INSERTRECORD,
1095 MPFROMP(pciFirst), MPFROMP(&ri))) {
1096 Win_Error(hwndCnr, HWND_DESKTOP, pszSrcFile, __LINE__,
1097 GetPString(IDS_CMINSERTERRTEXT));
1098 ok = FALSE;
1099 ullTotalBytes = 0;
1100 if (WinIsWindow((HAB) 0, hwndCnr))
1101 FreeCnrItemList(hwndCnr, pciFirst);
1102 }
1103 // }
1104 }
1105 }
1106 if (ok) {
1107 ullReturnBytes += ullTotalBytes;
1108 ulReturnFiles += ulSelCnt;
1109 }
1110 } // if sync updates
1111 else {
1112 // Append newly selected entries to aggregate list
1113 paffbTemp = xrealloc(paffbTotal,
1114 sizeof(FILEFINDBUF4L) * (ulSelCnt + ulTotal),
1115 pszSrcFile, __LINE__);
1116 if (paffbTemp) {
1117 // 13 Aug 07 SHL fixme to optimize copy
1118 paffbTotal = paffbTemp;
1119 for (x = 0; x < ulSelCnt; x++)
1120 paffbTotal[x + ulTotal] = *papffbSelected[x];
1121 ulTotal += ulSelCnt;
1122 }
1123 else {
1124 saymsg(MB_ENTER,
1125 HWND_DESKTOP,
1126 GetPString(IDS_ERRORTEXT), GetPString(IDS_OUTOFMEMORY));
1127 break;
1128 }
1129 }
1130 } // if entries selected
1131 if (stopflag && *stopflag)
1132 goto Abort;
1133 DosError(FERR_DISABLEHARDERR);
1134 ulFindCnt = ulFindMax;
1135 rc = xDosFindNext(hdir, paffbFound, ulBufBytes, &ulFindCnt, FIL_QUERYEASIZEL);
1136 priority_normal();
1137 if (rc)
1138 DosError(FERR_DISABLEHARDERR);
1139 } while (!rc);
1140
1141 DosFindClose(hdir);
1142 xfree(paffbFound, pszSrcFile, __LINE__);
1143 paffbFound = NULL;
1144 xfree(papffbSelected, pszSrcFile, __LINE__);
1145 papffbSelected = NULL;
1146
1147 if (ulTotal && paffbTotal) {
1148
1149 if (stopflag && *stopflag)
1150 goto Abort;
1151
1152 pciFirst = WinSendMsg(hwndCnr, CM_ALLOCRECORD,
1153 MPFROMLONG(EXTRA_RECORD_BYTES), MPFROMLONG(ulTotal));
1154 if (!pciFirst) {
1155 Win_Error(hwndCnr, HWND_DESKTOP, pszSrcFile, __LINE__,
1156 GetPString(IDS_CMALLOCRECERRTEXT));
1157 ok = FALSE;
1158 ullTotalBytes = 0;
1159 }
1160 else {
1161 // 04 Jan 08 SHL fixme like comp.c to handle less than ulSelCnt records
1162 pci = pciFirst;
1163 ullTotalBytes = 0;
1164 pffbFile = paffbTotal;
1165 for (x = 0; x < ulTotal; x++) {
1166 ullBytes = FillInRecordFromFFB(hwndCnr, pci, pszFileSpec,
1167 pffbFile, partial, dcd);
1168 pci = (PCNRITEM) pci->rc.preccNextRecord;
1169 ullTotalBytes += ullBytes;
1170 // Can not use offset since we have merged lists - this should be equivalent
1171 pffbFile = (PFILEFINDBUF4L)((PBYTE)pffbFile + sizeof(FILEFINDBUF4L));
1172 }
1173 if (ulTotal) {
1174 memset(&ri, 0, sizeof(RECORDINSERT));
1175 ri.cb = sizeof(RECORDINSERT);
1176 ri.pRecordOrder = (PRECORDCORE) CMA_END;
1177 ri.pRecordParent = (PRECORDCORE) pciParent;
1178 ri.zOrder = (ULONG) CMA_TOP;
1179 ri.cRecordsInsert = ulTotal;
1180 ri.fInvalidateRecord = (!fSyncUpdates && dcd &&
1181 dcd->type == DIR_FRAME) ? FALSE : TRUE;
1182 if (!WinSendMsg(hwndCnr, CM_INSERTRECORD,
1183 MPFROMP(pciFirst), MPFROMP(&ri))) {
1184 DosSleep(10); // Give GUI time to work
1185 WinSetFocus(HWND_DESKTOP, hwndCnr);
1186 if (!WinSendMsg(hwndCnr, CM_INSERTRECORD,
1187 MPFROMP(pciFirst), MPFROMP(&ri))) {
1188 Win_Error(hwndCnr, HWND_DESKTOP, pszSrcFile, __LINE__,
1189 GetPString(IDS_CMINSERTERRTEXT));
1190 ok = FALSE;
1191 ullTotalBytes = 0;
1192 if (WinIsWindow((HAB) 0, hwndCnr))
1193 FreeCnrItemList(hwndCnr, pciFirst);
1194 }
1195 }
1196 }
1197 }
1198 if (ok) {
1199 ullReturnBytes += ullTotalBytes;
1200 ulReturnFiles += ulFindCnt;
1201 }
1202 }
1203 }
1204
1205 /**
1206 * DosFind for subdirectories of a read-only directory on a FAT volume
1207 * returns path not found if there are no subdirectories
1208 * FAT FS seems to ignore . and .. in this case
1209 * Map to no more files
1210 * We could verify that directory is marked read-only, it's probably not
1211 * worth the extra code since we do verify 2 out of 3 prerequisites
1212 * 15 Jan 08 SHL
1213 */
1214 if (rc == ERROR_PATH_NOT_FOUND && !filestoo) {
1215 ULONG ulDriveType = 0;
1216 CHAR szFSType[CCHMAXPATH];
1217 INT removable = CheckDrive(*pszFileSpec, szFSType, &ulDriveType);
1218 if (removable != -1 && strcmp(szFSType, "FAT") == 0)
1219 rc = ERROR_NO_MORE_FILES;
1220 }
1221
1222 if (rc && rc != ERROR_NO_MORE_FILES) {
1223 Dos_Error(MB_ENTER, rc, HWND_DESKTOP, pszSrcFile, __LINE__,
1224 GetPString(IDS_CANTFINDDIRTEXT), pszFileSpec);
1225 }
1226
1227 if (!fSyncUpdates && dcd && dcd->type == DIR_FRAME)
1228 WinSendMsg(hwndCnr, CM_INVALIDATERECORD, MPVOID,
1229 MPFROM2SHORT(0, CMA_ERASE));
1230 }
1231Abort:
1232 xfree(paffbTotal, pszSrcFile, __LINE__);
1233 xfree(pszFileSpec, pszSrcFile, __LINE__);
1234 xfree(paffbFound, pszSrcFile, __LINE__);
1235 xfree(papffbSelected, pszSrcFile, __LINE__);
1236
1237 if (recurse) {
1238 pci = WinSendMsg(hwndCnr, CM_QUERYRECORD, MPFROMP(pciParent),
1239 MPFROM2SHORT(CMA_FIRSTCHILD, CMA_ITEMORDER));
1240 while (pci && (INT)pci != -1) {
1241 if ((pci->attrFile & FILE_DIRECTORY))
1242 if (fInitialDriveScan)
1243 Stubby(hwndCnr, pci);
1244 else {
1245 while (StubbyScanCount != 0)
1246 DosSleep(50);
1247 Stubby(hwndCnr, pci);
1248 }
1249 //Stubby(hwndCnr, pci);
1250 pci = WinSendMsg(hwndCnr, CM_QUERYRECORD, MPFROMP(pci),
1251 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
1252 }
1253 }
1254
1255 if (pulTotalFiles)
1256 *pulTotalFiles = ulReturnFiles;
1257
1258 if (pullTotalBytes)
1259 *pullTotalBytes = ullReturnBytes;
1260
1261} // ProcessDirectory
1262
1263VOID FillDirCnr(HWND hwndCnr,
1264 CHAR * pszDirectory,
1265 DIRCNRDATA * dcd,
1266 PULONGLONG pullTotalBytes)
1267{
1268 ProcessDirectory(hwndCnr,
1269 (PCNRITEM)NULL,
1270 pszDirectory,
1271 TRUE, // filestoo
1272 FALSE, // recurse
1273 TRUE, // partial
1274 dcd ? &dcd->stopflag : NULL,
1275 dcd,
1276 NULL, // total files
1277 pullTotalBytes);
1278 DosPostEventSem(CompactSem);
1279
1280#if 0 // fixme to be gone or to be configurable
1281 {
1282 int state = _heapchk();
1283 if (state != _HEAPOK)
1284 Runtime_Error(pszSrcFile, __LINE__, "heap corrupted %d", state);
1285 else
1286 DbgMsg(pszSrcFile, __LINE__, "_memavl %u", _memavl());
1287 }
1288#endif
1289
1290} // FillDirCnr
1291
1292VOID FillTreeCnr(HWND hwndCnr, HWND hwndParent)
1293{
1294 ULONG ulCurDriveNum, ulDriveMap, numtoinsert = 0;
1295 ULONG ulDriveType;
1296 PCNRITEM pci, pciFirst = NULL, pciNext, pciParent = NULL;
1297 INT x, removable;
1298 CHAR suggest[32];
1299 CHAR szDrive[] = " :\\";
1300 CHAR szFSType[CCHMAXPATH];
1301 FILESTATUS4L fsa4;
1302 APIRET rc;
1303 BOOL drivesbuilt = FALSE;
1304 ULONG startdrive = 3;
1305 static BOOL didonce = FALSE;
1306
1307 fDummy = TRUE;
1308 *suggest = 0;
1309 for (x = 0; x < 26; x++) {
1310 driveflags[x] &= (DRIVE_IGNORE | DRIVE_NOPRESCAN | DRIVE_NOLOADICONS |
1311 DRIVE_NOLOADSUBJS | DRIVE_NOLOADLONGS |
1312 DRIVE_INCLUDEFILES | DRIVE_SLOW | DRIVE_NOSTATS |
1313 DRIVE_WRITEVERIFYOFF);
1314 }
1315 memset(driveserial, -1, sizeof(driveserial));
1316
1317 DosError(FERR_DISABLEHARDERR);
1318 if (!DosQuerySysInfo(QSV_BOOT_DRIVE,
1319 QSV_BOOT_DRIVE,
1320 (PVOID) &startdrive,
1321 (ULONG) sizeof(ULONG)) &&
1322 startdrive)
1323 {
1324 driveflags[startdrive - 1] |= DRIVE_BOOT;
1325 }
1326
1327 DosError(FERR_DISABLEHARDERR);
1328 rc = DosQCurDisk(&ulCurDriveNum, &ulDriveMap);
1329 if (rc) {
1330 Dos_Error(MB_CANCEL,
1331 rc,
1332 HWND_DESKTOP,
1333 pszSrcFile, __LINE__, PCSZ_FILLDIRQCURERRTEXT);
1334 exit(0);
1335 }
1336
1337 // Calc number of drive items to create
1338 for (x = 0; x < 26; x++) {
1339 if ((ulDriveMap & (1L << x)) && !(driveflags[x] & DRIVE_IGNORE))
1340 numtoinsert++;
1341 }
1342
1343 if (numtoinsert) {
1344 pciFirst = WinSendMsg(hwndCnr,
1345 CM_ALLOCRECORD,
1346 MPFROMLONG(EXTRA_RECORD_BYTES),
1347 MPFROMLONG((ULONG) numtoinsert));
1348 }
1349
1350 if (!pciFirst) {
1351 Win_Error(hwndCnr, HWND_DESKTOP, pszSrcFile, __LINE__, GetPString(IDS_CMALLOCRECERRTEXT));
1352 // 04 Jan 08 SHL fixme not just up and die
1353 exit(0);
1354 }
1355
1356 // 04 Jan 08 SHL fixme like comp.c to handle less than ulSelCnt records
1357 pci = pciFirst;
1358 for (x = 0; x < 26; x++) {
1359 if ((ulDriveMap & (1L << x)) && !(driveflags[x] & DRIVE_IGNORE)) {
1360
1361 CHAR s[80];
1362 ULONG flags = 0;
1363 ULONG size = sizeof(ULONG);
1364
1365 *szDrive = (CHAR)x + 'A'; // Build path spec
1366
1367 sprintf(s, "%c.DriveFlags", toupper(*szDrive));
1368 if (PrfQueryProfileData(fmprof, appname, s, &flags, &size)) {
1369 driveflags[toupper(*szDrive) - 'A'] |= flags;
1370 }
1371
1372 if (x > 1) {
1373 // Hard drive (2..N)
1374 if (!(driveflags[x] & DRIVE_NOPRESCAN)) {
1375 *szFSType = 0;
1376 ulDriveType = 0;
1377 removable = CheckDrive(*szDrive, szFSType, &ulDriveType);
1378 driveserial[x] = -1;
1379 if (removable != -1) {
1380 struct {
1381 ULONG serial;
1382 CHAR volumelength;
1383 CHAR volumelabel[CCHMAXPATH];
1384 } volser;
1385
1386 DosError(FERR_DISABLEHARDERR);
1387 if (!DosQueryFSInfo((ULONG) x,
1388 FSIL_VOLSER, &volser, sizeof(volser))) {
1389 driveserial[x] = volser.serial;
1390 }
1391 }
1392 else
1393 driveflags[x] |= DRIVE_INVALID;
1394
1395 memset(&fsa4, 0, sizeof(FILESTATUS4L));
1396 driveflags[x] |= removable == -1 || removable == 1 ?
1397 DRIVE_REMOVABLE : 0;
1398 if (ulDriveType & DRIVE_REMOTE)
1399 driveflags[x] |= DRIVE_REMOTE;
1400 if (!stricmp(szFSType,RAMFS)) {
1401 driveflags[x] |= DRIVE_RAMDISK;
1402 driveflags[x] &= ~DRIVE_REMOTE;
1403 }
1404 if (!stricmp(szFSType,NDFS32)) {
1405 driveflags[x] |= DRIVE_VIRTUAL;
1406 driveflags[x] &= ~DRIVE_REMOTE;
1407 }
1408 if (!stricmp(szFSType,NTFS))
1409 driveflags[x] |= DRIVE_NOTWRITEABLE;
1410 if (strcmp(szFSType, HPFS) &&
1411 strcmp(szFSType, JFS) &&
1412 strcmp(szFSType, ISOFS) &&
1413 strcmp(szFSType, CDFS) &&
1414 strcmp(szFSType, FAT32) &&
1415 strcmp(szFSType, NDFS32) &&
1416 strcmp(szFSType, RAMFS) &&
1417 strcmp(szFSType, NTFS) &&
1418 strcmp(szFSType, HPFS386)) {
1419 driveflags[x] |= DRIVE_NOLONGNAMES;
1420 }
1421
1422 if (!strcmp(szFSType, CDFS) || !strcmp(szFSType,ISOFS)) {
1423 removable = 1;
1424 driveflags[x] |= DRIVE_REMOVABLE | DRIVE_NOTWRITEABLE | DRIVE_CDROM;
1425 }
1426 if (!stricmp(szFSType, CBSIFS)) {
1427 driveflags[x] |= DRIVE_ZIPSTREAM;
1428 driveflags[x] &= ~DRIVE_REMOTE;
1429 if (ulDriveType & DRIVE_REMOVABLE)
1430 driveflags[x] |= DRIVE_REMOVABLE;
1431 if (!(ulDriveType & DRIVE_NOLONGNAMES))
1432 driveflags[x] &= ~DRIVE_NOLONGNAMES;
1433 }
1434 if (!fVerifyOffChecked[x]) {
1435 if (driveflags[x] & DRIVE_REMOVABLE)
1436 driveflags[x] |= DRIVE_WRITEVERIFYOFF;
1437 if (!(driveflags[x] & DRIVE_INVALID)) {
1438 CHAR Key[80];
1439
1440 sprintf(Key, "%c.VerifyOffChecked", (CHAR) (x + 'A'));
1441 fVerifyOffChecked[x] = TRUE;
1442 PrfWriteProfileData(fmprof, appname, Key, &fVerifyOffChecked[x], sizeof(BOOL));
1443 }
1444 }
1445 pci->rc.flRecordAttr |= CRA_RECORDREADONLY;
1446 if ((ULONG)(toupper(*szDrive) - '@') == ulCurDriveNum)
1447 pci->rc.flRecordAttr |= (CRA_CURSORED | CRA_SELECTED);
1448
1449 if (removable == 0) {
1450 // Fixed volume
1451 pci->attrFile |= FILE_DIRECTORY;
1452 DosError(FERR_DISABLEHARDERR);
1453 rc = DosQueryPathInfo(szDrive,
1454 FIL_QUERYEASIZEL,
1455 &fsa4, (ULONG) sizeof(FILESTATUS4L));
1456 // ERROR_BAD_NET_RSP = 58
1457 if (rc == 58) {
1458 DosError(FERR_DISABLEHARDERR);
1459 rc = DosQueryPathInfo(szDrive,
1460 FIL_STANDARDL,
1461 &fsa4, (ULONG) sizeof(FILESTATUS4L));
1462 fsa4.cbList = 0;
1463 }
1464 if (rc && !didonce) {
1465 // Guess drive letter
1466 if (!*suggest) {
1467 *suggest = '/';
1468 suggest[1] = 0;
1469 }
1470 sprintf(suggest + strlen(suggest), "%c" , toupper(*szDrive));
1471 pci->pszFileName = xstrdup(szDrive, pszSrcFile, __LINE__);
1472 pci->pszDisplayName = pci->pszFileName;
1473 pci->rc.pszIcon = pci->pszDisplayName;
1474 pci->attrFile = FILE_DIRECTORY;
1475 pci->pszDispAttr = FileAttrToString(pci->attrFile);
1476 driveserial[x] = -1;
1477 }
1478 else
1479 FillInRecordFromFSA(hwndCnr, pci, szDrive, &fsa4, TRUE, NULL);
1480 }
1481 else {
1482 // Removable volume
1483 pci->pszFileName = xstrdup(szDrive, pszSrcFile, __LINE__);
1484 pci->pszDisplayName = pci->pszFileName;
1485 pci->rc.pszIcon = pci->pszDisplayName;
1486 pci->attrFile = FILE_DIRECTORY;
1487 pci->pszDispAttr = FileAttrToString(pci->attrFile);
1488 }
1489 SelectDriveIcon(pci);
1490# ifdef FORTIFY
1491 // Will be freed by TreeCnrWndProc WM_DESTROY
1492 Fortify_SetScope(pci->pszFileName, 2);
1493# endif
1494 }
1495 else {
1496 pci->rc.hptrIcon = hptrDunno;
1497 pci->pszFileName = xstrdup(szDrive, pszSrcFile, __LINE__);
1498# ifdef FORTIFY
1499 // Will be freed by TreeCnrWndProc WM_DESTROY
1500 Fortify_SetScope(pci->pszFileName, 2);
1501# endif
1502 pci->pszDisplayName = pci->pszFileName;
1503 pci->rc.pszIcon = pci->pszFileName;
1504 pci->attrFile = FILE_DIRECTORY;
1505 pci->pszDispAttr = FileAttrToString(pci->attrFile);
1506 driveserial[x] = -1;
1507 }
1508 }
1509 else {
1510 // diskette drive (A or B)
1511 pci->rc.hptrIcon = hptrFloppy;
1512 pci->pszFileName = xstrdup(szDrive, pszSrcFile, __LINE__);
1513 pci->pszDisplayName = pci->pszFileName;
1514 pci->rc.pszIcon = pci->pszDisplayName;
1515 pci->attrFile = FILE_DIRECTORY;
1516 pci->pszDispAttr = FileAttrToString(pci->attrFile);
1517 driveflags[x] |= (DRIVE_REMOVABLE | DRIVE_NOLONGNAMES);
1518 driveserial[x] = -1;
1519 }
1520 pci->rc.flRecordAttr |= CRA_RECORDREADONLY;
1521 pci = (PCNRITEM) pci->rc.preccNextRecord; // next rec
1522 }
1523 else if (!(ulDriveMap & (1L << x)))
1524 driveflags[x] |= DRIVE_INVALID;
1525 } // for drives
1526
1527 PostMsg(hwndMain, UM_BUILDDRIVEBAR, MPVOID, MPVOID);
1528 drivesbuilt = TRUE;
1529
1530 // insert the drives
1531 if (numtoinsert && pciFirst) {
1532 RECORDINSERT ri;
1533
1534 memset(&ri, 0, sizeof(RECORDINSERT));
1535 ri.cb = sizeof(RECORDINSERT);
1536 ri.pRecordOrder = (PRECORDCORE) CMA_END;
1537 ri.pRecordParent = (PRECORDCORE) NULL;
1538 ri.zOrder = (ULONG) CMA_TOP;
1539 ri.cRecordsInsert = numtoinsert;
1540 ri.fInvalidateRecord = FALSE;
1541 if (!WinSendMsg(hwndCnr,
1542 CM_INSERTRECORD, MPFROMP(pciFirst), MPFROMP(&ri)))
1543 {
1544 Win_Error(hwndCnr, HWND_DESKTOP, pszSrcFile, __LINE__,
1545 GetPString(IDS_CMINSERTERRTEXT));
1546 }
1547 }
1548
1549 // move cursor onto the default drive rather than the first drive
1550 if (!fSwitchTree) {
1551 pci = (PCNRITEM) WinSendMsg(hwndCnr,
1552 CM_QUERYRECORD,
1553 MPVOID,
1554 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
1555 while (pci && (INT)pci != -1) {
1556 if ((ULONG) (toupper(*pci->pszFileName) - '@') == ulCurDriveNum) {
1557 WinSendMsg(hwndCnr,
1558 CM_SETRECORDEMPHASIS,
1559 MPFROMP(pci), MPFROM2SHORT(TRUE, CRA_CURSORED));
1560 break;
1561 }
1562 pci = (PCNRITEM) WinSendMsg(hwndCnr,
1563 CM_QUERYRECORD,
1564 MPFROMP(pci),
1565 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
1566 }
1567 }
1568
1569 if (hwndParent) {
1570 WinSendMsg(WinWindowFromID(WinQueryWindow(hwndParent, QW_PARENT),
1571 MAIN_DRIVELIST),
1572 LM_DELETEALL, MPVOID, MPVOID);
1573 }
1574
1575 if (fShowEnv) {
1576 RECORDINSERT ri;
1577
1578 pciParent = WinSendMsg(hwndCnr,
1579 CM_ALLOCRECORD,
1580 MPFROMLONG(EXTRA_RECORD_BYTES), MPFROMLONG(1));
1581 if (pciParent) {
1582 pciParent->flags |= RECFLAGS_ENV;
1583 pciParent->pszFileName = xstrdup(GetPString(IDS_ENVVARSTEXT), pszSrcFile, __LINE__);
1584 pciParent->pszDisplayName = pciParent->pszFileName; // 03 Aug 07 SHL
1585 pciParent->rc.hptrIcon = hptrEnv;
1586 pciParent->rc.pszIcon = pciParent->pszFileName;
1587 pciParent->pszDispAttr = FileAttrToString(0);
1588 memset(&ri, 0, sizeof(RECORDINSERT));
1589 ri.cb = sizeof(RECORDINSERT);
1590 ri.pRecordOrder = (PRECORDCORE) CMA_END;
1591 ri.pRecordParent = (PRECORDCORE) NULL;
1592 ri.zOrder = (ULONG) CMA_TOP;
1593 ri.cRecordsInsert = 1;
1594 ri.fInvalidateRecord = FALSE;
1595 if (WinSendMsg(hwndCnr,
1596 CM_INSERTRECORD, MPFROMP(pciParent), MPFROMP(&ri))) {
1597
1598 char *p, *pp;
1599
1600 p = pszTreeEnvVarList;
1601 while (*p == ';')
1602 p++;
1603 while (*p) {
1604 *szFSType = 0;
1605 pp = szFSType;
1606 while (*p && *p != ';')
1607 *pp++ = *p++;
1608 *pp = 0;
1609 while (*p == ';')
1610 p++;
1611 if (*szFSType &&
1612 (!stricmp(szFSType, "LIBPATH") || getenv(szFSType))) {
1613 pci = WinSendMsg(hwndCnr,
1614 CM_ALLOCRECORD,
1615 MPFROMLONG(EXTRA_RECORD_BYTES),
1616 MPFROMLONG(1));
1617 if (pci) {
1618 CHAR fname[CCHMAXPATH];
1619 pci->flags |= RECFLAGS_ENV;
1620 sprintf(fname, "%%%s%%", szFSType);
1621 pci->pszFileName = xstrdup(fname, pszSrcFile, __LINE__);
1622 pci->rc.hptrIcon = hptrEnv;
1623 pci->rc.pszIcon = pci->pszFileName;
1624 pci->pszDispAttr = FileAttrToString(0);
1625 memset(&ri, 0, sizeof(RECORDINSERT));
1626 ri.cb = sizeof(RECORDINSERT);
1627 ri.pRecordOrder = (PRECORDCORE) CMA_END;
1628 ri.pRecordParent = (PRECORDCORE) pciParent;
1629 ri.zOrder = (ULONG) CMA_TOP;
1630 ri.cRecordsInsert = 1;
1631 ri.fInvalidateRecord = FALSE;
1632 if (!WinSendMsg(hwndCnr,
1633 CM_INSERTRECORD,
1634 MPFROMP(pci), MPFROMP(&ri))) {
1635 Win_Error(hwndCnr, HWND_DESKTOP, pszSrcFile, __LINE__,
1636 GetPString(IDS_CMINSERTERRTEXT));
1637 FreeCnrItem(hwndCnr, pci);
1638 }
1639 }
1640 }
1641 }
1642 WinSendMsg(hwndCnr,
1643 CM_INVALIDATERECORD,
1644 MPFROMP(&pciParent),
1645 MPFROM2SHORT(1, CMA_ERASE | CMA_REPOSITION));
1646 }
1647 else
1648 FreeCnrItem(hwndCnr, pciParent);
1649 }
1650 } // if show env
1651 {
1652 STUBBYSCAN *stubbyScan;
1653 HWND hwndDrivesList = WinWindowFromID(WinQueryWindow(hwndParent, QW_PARENT),
1654 MAIN_DRIVELIST);
1655
1656 pci = (PCNRITEM) WinSendMsg(hwndCnr,
1657 CM_QUERYRECORD,
1658 MPVOID,
1659 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
1660 StubbyScanCount ++;
1661 while (pci && (INT)pci != -1) {
1662 stubbyScan = xmallocz(sizeof(STUBBYSCAN), pszSrcFile, __LINE__);
1663 if (!stubbyScan)
1664 break;
1665 stubbyScan->pci = pci;
1666 stubbyScan->hwndCnr = hwndCnr;
1667 stubbyScan->hwndDrivesList = hwndDrivesList;
1668 stubbyScan->RamDrive = FALSE;
1669 pciNext = (PCNRITEM) WinSendMsg(hwndCnr,
1670 CM_QUERYRECORD,
1671 MPFROMP(pci),
1672 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
1673 if (~pci->flags & RECFLAGS_ENV) {
1674 ULONG drvNum = toupper(*pci->pszFileName) - 'A'; // 0..25
1675 if (drvNum == ulCurDriveNum || drvNum >= 2) {
1676 ULONG flags = driveflags[drvNum]; // Speed up
1677 if (~flags & DRIVE_INVALID &&
1678 ~flags & DRIVE_NOPRESCAN &&
1679 (!fNoRemovableScan || ~flags & DRIVE_REMOVABLE) && !fDrivetoSkip[drvNum])
1680 {
1681 if (DRIVE_RAMDISK)
1682 stubbyScan->RamDrive = TRUE;
1683 if (xbeginthread(StubbyScanThread,
1684 65536,
1685 stubbyScan,
1686 pszSrcFile,
1687 __LINE__) == -1)
1688 {
1689 xfree(stubbyScan, pszSrcFile, __LINE__);
1690 }
1691 } // if drive for scanning
1692 else
1693 WinSendMsg(hwndDrivesList,
1694 LM_INSERTITEM,
1695 MPFROM2SHORT(LIT_SORTASCENDING, 0),
1696 MPFROMP(pci->pszFileName));
1697 }
1698 else {
1699 WinSendMsg(hwndCnr,
1700 CM_INVALIDATERECORD,
1701 MPFROMP(&pci),
1702 MPFROM2SHORT(1, CMA_ERASE | CMA_REPOSITION));
1703 WinSendMsg(hwndDrivesList,
1704 LM_INSERTITEM,
1705 MPFROM2SHORT(LIT_SORTASCENDING, 0),
1706 MPFROMP(pci->pszFileName));
1707 }
1708 fDrivetoSkip[drvNum] = FALSE;
1709 }
1710 pci = pciNext;
1711 } // while
1712 StubbyScanCount--;
1713 }
1714 if (hwndParent)
1715 WinSendMsg(WinWindowFromID(WinQueryWindow(hwndParent, QW_PARENT),
1716 MAIN_DRIVELIST), LM_SELECTITEM,
1717 MPFROM2SHORT(0, 0), MPFROMLONG(TRUE));
1718
1719 pci = (PCNRITEM) WinSendMsg(hwndCnr,
1720 CM_QUERYRECORD,
1721 MPVOID,
1722 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
1723 while (pci && (INT)pci != -1) {
1724 pciNext = (PCNRITEM) WinSendMsg(hwndCnr,
1725 CM_QUERYRECORD,
1726 MPFROMP(pci),
1727 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
1728 if (pci->flags & RECFLAGS_ENV) {
1729 pci = (PCNRITEM) WinSendMsg(hwndCnr,
1730 CM_QUERYRECORD,
1731 MPFROMP(pci),
1732 MPFROM2SHORT(CMA_FIRSTCHILD,
1733 CMA_ITEMORDER));
1734 while (pci && (INT)pci != -1) {
1735 if (pci->flags & RECFLAGS_ENV)
1736 FleshEnv(hwndCnr, pci);
1737 pci = (PCNRITEM) WinSendMsg(hwndCnr,
1738 CM_QUERYRECORD,
1739 MPFROMP(pci),
1740 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
1741 }
1742 break;
1743 }
1744 pci = (PCNRITEM) WinSendMsg(hwndCnr,
1745 CM_QUERYRECORD,
1746 MPFROMP(pci),
1747 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
1748 }
1749
1750 if (!drivesbuilt && hwndMain)
1751 PostMsg(hwndMain, UM_BUILDDRIVEBAR, MPVOID, MPVOID);
1752 DosSleep(16); // 05 Aug 07 GKY 33
1753 fDummy = FALSE;
1754 DosPostEventSem(CompactSem);
1755
1756 {
1757 BYTE info;
1758 BOOL includesyours = FALSE;
1759
1760 // 10 Jan 08 SHL fixme to understand fFirstTime
1761 if (*suggest || (!(driveflags[1] & DRIVE_IGNORE) && fFirstTime)) {
1762 if (!DosDevConfig(&info, DEVINFO_FLOPPY) && info == 1) {
1763 if (!*suggest) {
1764 *suggest = '/';
1765 suggest[1] = 0;
1766 }
1767 else
1768 memmove(suggest + 2, suggest + 1, strlen(suggest));
1769 suggest[1] = 'B';
1770 }
1771 }
1772 if (*suggest) {
1773 for (x = 2; x < 26; x++) {
1774 if (driveflags[x] & DRIVE_IGNORE) {
1775 includesyours = TRUE;
1776 sprintf(suggest + strlen(suggest), "%c", (char)(x + 'A'));
1777 }
1778 }
1779 strcat(suggest, " %*");
1780 if (saymsg(MB_YESNO | MB_ICONEXCLAMATION,
1781 (hwndParent) ? hwndParent : hwndCnr,
1782 GetPString(IDS_SUGGESTTITLETEXT),
1783 GetPString(IDS_SUGGEST1TEXT),
1784 (includesyours) ? GetPString(IDS_SUGGEST2TEXT) : NullStr,
1785 suggest) == MBID_YES) {
1786 char s[64];
1787
1788 sprintf(s, "PARAMETERS=%s", suggest);
1789 WinCreateObject(WPProgram, "FM/2", s, FM3Folder, CO_UPDATEIFEXISTS);
1790 WinCreateObject(WPProgram,
1791 "FM/2 Lite", s, FM3Folder, CO_UPDATEIFEXISTS);
1792 WinCreateObject(WPProgram,
1793 "Archive Viewer/2", s, FM3Tools, CO_UPDATEIFEXISTS);
1794 WinCreateObject(WPProgram,
1795 "Dir Sizes", s, FM3Tools, CO_UPDATEIFEXISTS);
1796 WinCreateObject(WPProgram,
1797 "Visual Tree", s, FM3Tools, CO_UPDATEIFEXISTS);
1798 WinCreateObject(WPProgram,
1799 "Visual Directory", s, FM3Tools, CO_UPDATEIFEXISTS);
1800 WinCreateObject(WPProgram,
1801 "Global File Viewer", s, FM3Tools, CO_UPDATEIFEXISTS);
1802 WinCreateObject(WPProgram, "Databar", s, FM3Tools, CO_UPDATEIFEXISTS);
1803 }
1804 }
1805 }
1806 didonce = TRUE;
1807 if (fInitialDriveScan) {
1808 HWND hwndDrivesList = WinWindowFromID(WinQueryWindow(hwndParent, QW_PARENT),
1809 MAIN_DRIVELIST);
1810 while (StubbyScanCount != 0 || ProcessDirCount != 0)
1811 DosSleep(50);
1812 WinShowWindow(hwndCnr, TRUE);
1813 WinShowWindow(hwndDrivesList, TRUE);
1814 fInitialDriveScan = FALSE;
1815 }
1816} // FillTreeCnr
1817
1818
1819/**
1820 * Empty all records from a container and free associated storage and
1821 * Free up field infos
1822 */
1823
1824VOID EmptyCnr(HWND hwnd)
1825{
1826 PFIELDINFO pfi;
1827
1828#if 0 // fixme to be gone or to be configurable
1829 {
1830 int state = _heapchk();
1831 if (state != _HEAPOK)
1832 Runtime_Error(pszSrcFile, __LINE__, "heap corrupted %d", state);
1833 }
1834#endif
1835
1836 // Remove all records
1837 RemoveCnrItems(hwnd, NULL, 0, CMA_FREE);
1838
1839 // Remove field info descriptors
1840 pfi = (PFIELDINFO) WinSendMsg(hwnd, CM_QUERYDETAILFIELDINFO, MPVOID,
1841 MPFROMSHORT(CMA_FIRST));
1842 if (pfi &&
1843 (INT)WinSendMsg(hwnd, CM_REMOVEDETAILFIELDINFO, MPVOID,
1844 MPFROM2SHORT(0, CMA_FREE)) == -1) {
1845 Win_Error(hwnd, HWND_DESKTOP, pszSrcFile, __LINE__,"CM_REMOVEDETAILFIELDINFO hwnd %x", hwnd);
1846 }
1847}
1848
1849/**
1850 * Free storage associated with container item
1851 */
1852
1853VOID FreeCnrItemData(PCNRITEM pci)
1854{
1855 if (pci->pszSubject) {
1856 if (pci->pszSubject != NullStr)
1857 free(pci->pszSubject);
1858 pci->pszSubject = NULL; // Catch illegal references
1859 }
1860
1861 // 08 Sep 08 SHL Remove excess logic
1862 if (pci->pszLongName) {
1863 if (pci->pszLongName != NullStr)
1864 free(pci->pszLongName);
1865 pci->pszLongName = NULL; // Catch illegal references
1866 }
1867
1868 // Bypass free if pszDisplayName points into pszFileName buffer
1869 // 05 Sep 08 SHL Correct pointer overlap compare logic
1870 if (pci->pszDisplayName) {
1871 if (pci->pszDisplayName != NullStr) {
1872 if (!pci->pszFileName ||
1873 pci->pszDisplayName < pci->pszFileName ||
1874 pci->pszDisplayName >= pci->pszFileName + _msize(pci->pszFileName))
1875 {
1876 free(pci->pszDisplayName);
1877 }
1878 }
1879 pci->pszDisplayName = NULL; // Catch illegal references
1880 }
1881
1882 if (!pci->pszFileName)
1883 Runtime_Error(pszSrcFile, __LINE__, "FreeCnrItemData attempting free %p data twice", pci);
1884 else {
1885 if (pci->pszFileName != NullStr)
1886 free(pci->pszFileName);
1887 pci->pszFileName = NULL; // Catch illegal references
1888 }
1889
1890 // 08 Sep 08 SHL Remove excess logic
1891 if (pci->pszLongName) {
1892 if (pci->pszLongName != NullStr)
1893 free(pci->pszLongName);
1894 pci->pszLongName = NULL; // Catch illegal references
1895 }
1896
1897 if (pci->pszFmtFileSize) {
1898 if (pci->pszFmtFileSize != NullStr)
1899 free(pci->pszFmtFileSize);
1900 pci->pszFmtFileSize = NULL; // Catch illegal references
1901 }
1902}
1903
1904/**
1905 * Free single container item and associated storage
1906 */
1907
1908VOID FreeCnrItem(HWND hwnd, PCNRITEM pci)
1909{
1910 // DbgMsg(pszSrcFile, __LINE__, "FreeCnrItem hwnd %x pci %p", hwnd, pci);
1911
1912 FreeCnrItemData(pci);
1913
1914 if (!WinSendMsg(hwnd, CM_FREERECORD, MPFROMP(&pci), MPFROMSHORT(1))) {
1915 Win_Error(hwnd, HWND_DESKTOP, pszSrcFile, __LINE__,
1916 "CM_FREERECORD hwnd %x pci %p file %s",
1917 hwnd, pci,
1918 pci && pci->pszFileName ? pci->pszFileName : "n/a");
1919 }
1920}
1921
1922/**
1923 * Free container item list and associated storage
1924 */
1925
1926VOID FreeCnrItemList(HWND hwnd, PCNRITEM pciFirst)
1927{
1928 PCNRITEM pci = pciFirst;
1929 PCNRITEM pciNext;
1930 USHORT usCount;
1931
1932 for (usCount = 0; pci; usCount++) {
1933 pciNext = (PCNRITEM) pci->rc.preccNextRecord;
1934 FreeCnrItemData(pci);
1935 pci = pciNext;
1936 }
1937
1938 if (usCount) {
1939 if (!WinSendMsg(hwnd, CM_FREERECORD, MPFROMP(&pci), MPFROMSHORT(usCount))) {
1940 Win_Error(hwnd, HWND_DESKTOP, pszSrcFile, __LINE__,"CM_FREERECORD hwnd %x pci %p cnt %u", hwnd, pci, usCount);
1941 }
1942 }
1943}
1944
1945/**
1946 * Remove item(s) from container and free associated storage if requested
1947 * @param pciFirst points to first item to remove or NULL to remove all
1948 * @param usCnt is remove count or 0 to remove all
1949 * @returns count of items remaining in container or -1 if error
1950 */
1951
1952INT RemoveCnrItems(HWND hwnd, PCNRITEM pciFirst, USHORT usCnt, USHORT usFlags)
1953{
1954 INT remaining = usCnt;
1955 PCNRITEM pci;
1956
1957 if ((usCnt && !pciFirst) || (!usCnt && pciFirst)) {
1958 Runtime_Error(pszSrcFile, __LINE__, "pciFirst %p usCnt %u mismatch", pciFirst, usCnt);
1959 remaining = -1;
1960 }
1961 else {
1962 // Free our buffers if free requested
1963 if (usFlags & CMA_FREE) {
1964 if (pciFirst)
1965 pci = pciFirst;
1966 else {
1967 pci = (PCNRITEM)WinSendMsg(hwnd, CM_QUERYRECORD, MPVOID,
1968 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
1969 if ((INT)pci == -1) {
1970 Win_Error(hwnd, HWND_DESKTOP, pszSrcFile, __LINE__,"CM_QUERYRECORD");
1971 remaining = -1;
1972 pci = NULL;
1973 }
1974 }
1975 while (pci) {
1976 // 12 Sep 07 SHL dwg drivebar crash testing - ticket# ???
1977 static PCNRITEM pciLast; // 12 Sep 07 SHL
1978 ULONG ulSize = sizeof(*pci);
1979 ULONG ulAttr;
1980 APIRET apiret = DosQueryMem((PVOID)pci, &ulSize, &ulAttr);
1981 if (apiret)
1982 Dos_Error(MB_ENTER, apiret, HWND_DESKTOP, pszSrcFile, __LINE__,
1983 "DosQueryMem failed pci %p pciLast %p", pci, pciLast);
1984 FreeCnrItemData(pci);
1985 pciLast = pci;
1986 pci = (PCNRITEM)pci->rc.preccNextRecord;
1987 if (remaining && --remaining == 0)
1988 break;
1989 }
1990 }
1991 }
1992
1993 // DbgMsg(pszSrcFile, __LINE__, "RemoveCnrItems %p %u %s", pci, usCnt, pci->pszFileName);
1994
1995 if (remaining != - 1) {
1996 remaining = (INT)WinSendMsg(hwnd, CM_REMOVERECORD, MPFROMP(&pciFirst), MPFROM2SHORT(usCnt, usFlags));
1997 if (remaining == -1) {
1998 Win_Error(hwnd, HWND_DESKTOP, pszSrcFile, __LINE__,"CM_REMOVERECORD hwnd %x pci %p cnt %u", hwnd, pciFirst, usCnt);
1999 }
2000 }
2001
2002 return remaining;
2003}
2004
2005#pragma alloc_text(FILLDIR,FillInRecordFromFFB,FillInRecordFromFSA,IDFile)
2006#pragma alloc_text(FILLDIR1,ProcessDirectory,FillDirCnr,FillTreeCnr,FileAttrToString,StubbyScanThread)
2007#pragma alloc_text(EMPTYCNR,EmptyCnr,FreeCnrItemData,FreeCnrItem,FreeCnrItemList,RemoveCnrItems)
2008
Note: See TracBrowser for help on using the repository browser.