source: trunk/dll/filldir.c@ 1427

Last change on this file since 1427 was 1427, checked in by Gregg Young, 16 years ago

Fix IDM_BLINK to not leave a DataBar on the screen when fDataMin is TRUE. (Ticket 364) Remove unused variable from stubbyscan struct

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