source: trunk/dll/filldir.c@ 1439

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

Changes to allow high mem loading of dll; Refactor .LONGNAME and .SUBJECT EA fetch to FetchCommonEAs. Add szFSType to FillInRecordFromFSA use to bypass EA scan and size formatting for tree container; Fix labels/FS type to work on scan on NOPRESCAN Drives; Fixed dbl directory names on restore of dir cnrs; (Tickets 47, 339, 363, 368, 369, 370)

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