source: trunk/dll/filldir.c@ 1344

Last change on this file since 1344 was 1335, checked in by Steven Levine, 17 years ago

Ticket 26: Add exception handlers to all threads using xbeginthread

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