source: trunk/dll/filldir.c@ 1347

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

More code cleanup

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 55.5 KB
RevLine 
[31]1
2/***********************************************************************
3
4 $Id: filldir.c 1347 2008-12-20 04:22:16Z 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
[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),
[1347]215 MPFROM2SHORT(1, CMA_ERASE | CMA_REPOSITION));
216 }
[1308]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 memset(&ri, 0, sizeof(RECORDINSERT));
995 ri.cb = sizeof(RECORDINSERT);
996 ri.pRecordOrder = (PRECORDCORE) CMA_END;
997 ri.pRecordParent = (PRECORDCORE) pciParent;
998 ri.zOrder = (ULONG) CMA_TOP;
999 ri.cRecordsInsert = ulSelCnt;
[1316]1000 ri.fInvalidateRecord = TRUE;
1001 // !fSyncUpdates && dcd && dcd->type == DIR_FRAME ? FALSE : TRUE; //fSyncUpdates always TRUE 12-1-08 GKY
[783]1002 if (!WinSendMsg(hwndCnr,
1003 CM_INSERTRECORD,
1004 MPFROMP(pciFirst), MPFROMP(&ri))) {
1005 DosSleep(10); // Give GUI time to work
1006 WinSetFocus(HWND_DESKTOP, hwndCnr);
[214]1007 if (!WinSendMsg(hwndCnr,
1008 CM_INSERTRECORD,
[551]1009 MPFROMP(pciFirst), MPFROMP(&ri))) {
[783]1010 Win_Error2(hwndCnr, HWND_DESKTOP, pszSrcFile, __LINE__,
1011 IDS_CMINSERTERRTEXT);
1012 ok = FALSE;
1013 ullTotalBytes = 0;
1014 if (WinIsWindow((HAB) 0, hwndCnr))
[1335]1015 FreeCnrItemList(hwndCnr, pciFirst);
[214]1016 }
[783]1017 // }
[214]1018 }
1019 }
[551]1020 if (ok) {
[214]1021 ullReturnBytes += ullTotalBytes;
[783]1022 ulReturnFiles += ulSelCnt;
[1335]1023 }
[783]1024 } // if sync updates
[551]1025 else {
[783]1026 // Append newly selected entries to aggregate list
[359]1027 paffbTemp = xrealloc(paffbTotal,
[841]1028 sizeof(FILEFINDBUF4L) * (ulSelCnt + ulTotal),
[551]1029 pszSrcFile, __LINE__);
1030 if (paffbTemp) {
[783]1031 // 13 Aug 07 SHL fixme to optimize copy
[214]1032 paffbTotal = paffbTemp;
[783]1033 for (x = 0; x < ulSelCnt; x++)
[214]1034 paffbTotal[x + ulTotal] = *papffbSelected[x];
[783]1035 ulTotal += ulSelCnt;
[214]1036 }
[551]1037 else {
[214]1038 saymsg(MB_ENTER,
1039 HWND_DESKTOP,
[551]1040 GetPString(IDS_ERRORTEXT), GetPString(IDS_OUTOFMEMORY));
[214]1041 break;
1042 }
1043 }
[783]1044 } // if entries selected
[214]1045 if (stopflag && *stopflag)
[551]1046 goto Abort;
[214]1047 DosError(FERR_DISABLEHARDERR);
[783]1048 ulFindCnt = ulFindMax;
[850]1049 rc = xDosFindNext(hdir, paffbFound, ulBufBytes, &ulFindCnt, FIL_QUERYEASIZEL);
[214]1050 priority_normal();
1051 if (rc)
1052 DosError(FERR_DISABLEHARDERR);
[783]1053 } while (!rc);
1054
[2]1055 DosFindClose(hdir);
[1009]1056 xfree(paffbFound, pszSrcFile, __LINE__);
[985]1057 paffbFound = NULL;
[1009]1058 xfree(papffbSelected, pszSrcFile, __LINE__);
[985]1059 papffbSelected = NULL;
[2]1060
[551]1061 if (ulTotal && paffbTotal) {
[167]1062
[214]1063 if (stopflag && *stopflag)
1064 goto Abort;
[167]1065
[214]1066 pciFirst = WinSendMsg(hwndCnr, CM_ALLOCRECORD,
[783]1067 MPFROMLONG(EXTRA_RECORD_BYTES), MPFROMLONG(ulTotal));
[359]1068 if (!pciFirst) {
[551]1069 Win_Error2(hwndCnr, HWND_DESKTOP, pszSrcFile, __LINE__,
1070 IDS_CMALLOCRECERRTEXT);
[359]1071 ok = FALSE;
1072 ullTotalBytes = 0;
1073 }
1074 else {
[907]1075 // 04 Jan 08 SHL fixme like comp.c to handle less than ulSelCnt records
[214]1076 pci = pciFirst;
1077 ullTotalBytes = 0;
[783]1078 pffbFile = paffbTotal;
1079 for (x = 0; x < ulTotal; x++) {
[551]1080 ullBytes = FillInRecordFromFFB(hwndCnr, pci, pszFileSpec,
1081 pffbFile, partial, dcd);
1082 pci = (PCNRITEM) pci->rc.preccNextRecord;
[214]1083 ullTotalBytes += ullBytes;
[783]1084 // Can not use offset since we have merged lists - this should be equivalent
[841]1085 pffbFile = (PFILEFINDBUF4L)((PBYTE)pffbFile + sizeof(FILEFINDBUF4L));
[214]1086 }
[551]1087 if (ulTotal) {
1088 memset(&ri, 0, sizeof(RECORDINSERT));
1089 ri.cb = sizeof(RECORDINSERT);
1090 ri.pRecordOrder = (PRECORDCORE) CMA_END;
1091 ri.pRecordParent = (PRECORDCORE) pciParent;
1092 ri.zOrder = (ULONG) CMA_TOP;
1093 ri.cRecordsInsert = ulTotal;
1094 ri.fInvalidateRecord = (!fSyncUpdates && dcd &&
1095 dcd->type == DIR_FRAME) ? FALSE : TRUE;
1096 if (!WinSendMsg(hwndCnr, CM_INSERTRECORD,
1097 MPFROMP(pciFirst), MPFROMP(&ri))) {
[783]1098 DosSleep(10); // Give GUI time to work
[551]1099 WinSetFocus(HWND_DESKTOP, hwndCnr);
1100 if (!WinSendMsg(hwndCnr, CM_INSERTRECORD,
1101 MPFROMP(pciFirst), MPFROMP(&ri))) {
1102 Win_Error2(hwndCnr, HWND_DESKTOP, pszSrcFile, __LINE__,
1103 IDS_CMINSERTERRTEXT);
[214]1104 ok = FALSE;
1105 ullTotalBytes = 0;
[751]1106 if (WinIsWindow((HAB) 0, hwndCnr))
[1335]1107 FreeCnrItemList(hwndCnr, pciFirst);
[214]1108 }
1109 }
1110 }
1111 }
[551]1112 if (ok) {
[214]1113 ullReturnBytes += ullTotalBytes;
[783]1114 ulReturnFiles += ulFindCnt;
[214]1115 }
[2]1116 }
1117 }
1118
[924]1119 /**
1120 * DosFind for subdirectories of a read-only directory on a FAT volume
1121 * returns path not found if there are no subdirectories
1122 * FAT FS seems to ignore . and .. in this case
1123 * Map to no more files
1124 * We could verify that directory is marked read-only, it's probably not
1125 * worth the extra code since we do verify 2 out of 3 prerequisites
1126 * 15 Jan 08 SHL
1127 */
1128 if (rc == ERROR_PATH_NOT_FOUND && !filestoo) {
1129 ULONG ulDriveType = 0;
1130 CHAR szFSType[CCHMAXPATH];
1131 INT removable = CheckDrive(*pszFileSpec, szFSType, &ulDriveType);
1132 if (removable != -1 && strcmp(szFSType, "FAT") == 0)
1133 rc = ERROR_NO_MORE_FILES;
1134 }
1135
[783]1136 if (rc && rc != ERROR_NO_MORE_FILES) {
1137 Dos_Error(MB_ENTER, rc, HWND_DESKTOP, pszSrcFile, __LINE__,
1138 GetPString(IDS_CANTFINDDIRTEXT), pszFileSpec);
1139 }
1140
[167]1141 if (!fSyncUpdates && dcd && dcd->type == DIR_FRAME)
[551]1142 WinSendMsg(hwndCnr, CM_INVALIDATERECORD, MPVOID,
1143 MPFROM2SHORT(0, CMA_ERASE));
[2]1144 }
1145Abort:
[1009]1146 xfree(paffbTotal, pszSrcFile, __LINE__);
1147 xfree(pszFileSpec, pszSrcFile, __LINE__);
1148 xfree(paffbFound, pszSrcFile, __LINE__);
1149 xfree(papffbSelected, pszSrcFile, __LINE__);
[783]1150
[551]1151 if (recurse) {
[2]1152 pci = WinSendMsg(hwndCnr, CM_QUERYRECORD, MPFROMP(pciParent),
[214]1153 MPFROM2SHORT(CMA_FIRSTCHILD, CMA_ITEMORDER));
[762]1154 while (pci && (INT)pci != -1) {
[167]1155 if (pci->attrFile & FILE_DIRECTORY)
[551]1156 Stubby(hwndCnr, pci);
[2]1157 pci = WinSendMsg(hwndCnr, CM_QUERYRECORD, MPFROMP(pci),
[214]1158 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
[2]1159 }
1160 }
1161
[167]1162 if (pulTotalFiles)
1163 *pulTotalFiles = ulReturnFiles;
[2]1164
[167]1165 if (pullTotalBytes)
1166 *pullTotalBytes = ullReturnBytes;
[2]1167
[731]1168} // ProcessDirectory
[167]1169
1170VOID FillDirCnr(HWND hwndCnr,
[551]1171 CHAR * pszDirectory,
[924]1172 DIRCNRDATA * dcd,
1173 PULONGLONG pullTotalBytes)
[90]1174{
[167]1175 ProcessDirectory(hwndCnr,
[924]1176 (PCNRITEM)NULL,
[167]1177 pszDirectory,
[737]1178 TRUE, // filestoo
1179 FALSE, // recurse
1180 TRUE, // partial
1181 dcd ? &dcd->stopflag : NULL,
1182 dcd,
[924]1183 NULL, // total files
[737]1184 pullTotalBytes);
[2]1185 DosPostEventSem(CompactSem);
1186
[762]1187#if 0 // fixme to be gone or to be configurable
[751]1188 {
1189 int state = _heapchk();
1190 if (state != _HEAPOK)
1191 Runtime_Error(pszSrcFile, __LINE__, "heap corrupted %d", state);
[763]1192 else
1193 DbgMsg(pszSrcFile, __LINE__, "_memavl %u", _memavl());
[751]1194 }
1195#endif
1196
[731]1197} // FillDirCnr
[2]1198
[551]1199VOID FillTreeCnr(HWND hwndCnr, HWND hwndParent)
[90]1200{
[924]1201 ULONG ulCurDriveNum, ulDriveMap, numtoinsert = 0;
1202 ULONG ulDriveType;
[551]1203 PCNRITEM pci, pciFirst = NULL, pciNext, pciParent = NULL;
1204 INT x, removable;
[731]1205 CHAR suggest[32];
[739]1206 CHAR szDrive[] = " :\\";
[924]1207 CHAR szFSType[CCHMAXPATH];
[841]1208 FILESTATUS4L fsa4;
[551]1209 APIRET rc;
1210 BOOL drivesbuilt = FALSE;
[739]1211 ULONG startdrive = 3;
[2]1212 static BOOL didonce = FALSE;
1213
1214 fDummy = TRUE;
1215 *suggest = 0;
[689]1216 for (x = 0; x < 26; x++) {
[2]1217 driveflags[x] &= (DRIVE_IGNORE | DRIVE_NOPRESCAN | DRIVE_NOLOADICONS |
[214]1218 DRIVE_NOLOADSUBJS | DRIVE_NOLOADLONGS |
[552]1219 DRIVE_INCLUDEFILES | DRIVE_SLOW | DRIVE_NOSTATS);
[689]1220 }
[551]1221 memset(driveserial, -1, sizeof(driveserial));
[739]1222
1223 DosError(FERR_DISABLEHARDERR);
1224 if (!DosQuerySysInfo(QSV_BOOT_DRIVE,
1225 QSV_BOOT_DRIVE,
1226 (PVOID) &startdrive,
1227 (ULONG) sizeof(ULONG)) &&
1228 startdrive)
[2]1229 {
[739]1230 driveflags[startdrive - 1] |= DRIVE_BOOT;
1231 }
[2]1232
1233 DosError(FERR_DISABLEHARDERR);
[731]1234 rc = DosQCurDisk(&ulCurDriveNum, &ulDriveMap);
[551]1235 if (rc) {
[2]1236 Dos_Error(MB_CANCEL,
[214]1237 rc,
1238 HWND_DESKTOP,
[551]1239 pszSrcFile, __LINE__, GetPString(IDS_FILLDIRQCURERRTEXT));
[2]1240 exit(0);
1241 }
[739]1242
[731]1243 // Calc number of drive items to create
[689]1244 for (x = 0; x < 26; x++) {
[167]1245 if ((ulDriveMap & (1L << x)) && !(driveflags[x] & DRIVE_IGNORE))
[2]1246 numtoinsert++;
[689]1247 }
[739]1248
[689]1249 if (numtoinsert) {
[2]1250 pciFirst = WinSendMsg(hwndCnr,
[214]1251 CM_ALLOCRECORD,
[751]1252 MPFROMLONG(EXTRA_RECORD_BYTES),
[551]1253 MPFROMLONG((ULONG) numtoinsert));
[689]1254 }
[739]1255
[359]1256 if (!pciFirst) {
[744]1257 Win_Error2(hwndCnr, HWND_DESKTOP, pszSrcFile, __LINE__, IDS_CMALLOCRECERRTEXT);
[907]1258 // 04 Jan 08 SHL fixme not just up and die
[359]1259 exit(0);
1260 }
[689]1261
[907]1262 // 04 Jan 08 SHL fixme like comp.c to handle less than ulSelCnt records
[739]1263 pci = pciFirst;
1264 for (x = 0; x < 26; x++) {
1265 if ((ulDriveMap & (1L << x)) && !(driveflags[x] & DRIVE_IGNORE)) {
[2]1266
[739]1267 CHAR s[80];
1268 ULONG flags = 0;
[1328]1269 ULONG size = sizeof(ULONG);
[2]1270
[739]1271 *szDrive = (CHAR)x + 'A'; // Build path spec
[731]1272
[739]1273 sprintf(s, "%c.DriveFlags", toupper(*szDrive));
[1328]1274 if (PrfQueryProfileData(fmprof, appname, s, &flags, &size)) {
[739]1275 driveflags[toupper(*szDrive) - 'A'] |= flags;
1276 }
[2]1277
[739]1278 if (x > 1) {
1279 // Hard drive (2..N)
1280 if (!(driveflags[x] & DRIVE_NOPRESCAN)) {
[924]1281 *szFSType = 0;
1282 ulDriveType = 0;
1283 removable = CheckDrive(*szDrive, szFSType, &ulDriveType);
[739]1284 driveserial[x] = -1;
1285 if (removable != -1) {
1286 struct {
1287 ULONG serial;
1288 CHAR volumelength;
1289 CHAR volumelabel[CCHMAXPATH];
1290 } volser;
[2]1291
[739]1292 DosError(FERR_DISABLEHARDERR);
1293 if (!DosQueryFSInfo((ULONG) x,
1294 FSIL_VOLSER, &volser, sizeof(volser))) {
1295 driveserial[x] = volser.serial;
[731]1296 }
[739]1297 }
1298 else
1299 driveflags[x] |= DRIVE_INVALID;
[731]1300
[841]1301 memset(&fsa4, 0, sizeof(FILESTATUS4L));
[739]1302 driveflags[x] |= removable == -1 || removable == 1 ?
1303 DRIVE_REMOVABLE : 0;
[924]1304 if (ulDriveType & DRIVE_REMOTE)
[739]1305 driveflags[x] |= DRIVE_REMOTE;
[924]1306 if (!stricmp(szFSType,RAMFS)) {
[739]1307 driveflags[x] |= DRIVE_RAMDISK;
1308 driveflags[x] &= ~DRIVE_REMOTE;
1309 }
[924]1310 if (!stricmp(szFSType,NDFS32)) {
[739]1311 driveflags[x] |= DRIVE_VIRTUAL;
1312 driveflags[x] &= ~DRIVE_REMOTE;
1313 }
[924]1314 if (!stricmp(szFSType,NTFS))
[739]1315 driveflags[x] |= DRIVE_NOTWRITEABLE;
[924]1316 if (strcmp(szFSType, HPFS) &&
1317 strcmp(szFSType, JFS) &&
1318 strcmp(szFSType, ISOFS) &&
1319 strcmp(szFSType, CDFS) &&
1320 strcmp(szFSType, FAT32) &&
1321 strcmp(szFSType, NDFS32) &&
1322 strcmp(szFSType, RAMFS) &&
[1347]1323 strcmp(szFSType, NTFS) &&
[924]1324 strcmp(szFSType, HPFS386)) {
[739]1325 driveflags[x] |= DRIVE_NOLONGNAMES;
1326 }
[534]1327
[924]1328 if (!strcmp(szFSType, CDFS) || !strcmp(szFSType,ISOFS)) {
[739]1329 removable = 1;
[1347]1330 driveflags[x] |= DRIVE_REMOVABLE | DRIVE_NOTWRITEABLE | DRIVE_CDROM;
[739]1331 }
[1347]1332 if (!stricmp(szFSType, CBSIFS)) {
[739]1333 driveflags[x] |= DRIVE_ZIPSTREAM;
1334 driveflags[x] &= ~DRIVE_REMOTE;
[924]1335 if (ulDriveType & DRIVE_REMOVABLE)
[739]1336 driveflags[x] |= DRIVE_REMOVABLE;
[924]1337 if (!(ulDriveType & DRIVE_NOLONGNAMES))
[739]1338 driveflags[x] &= ~DRIVE_NOLONGNAMES;
[1347]1339 }
[2]1340
[739]1341 pci->rc.flRecordAttr |= CRA_RECORDREADONLY;
1342 if ((ULONG)(toupper(*szDrive) - '@') == ulCurDriveNum)
1343 pci->rc.flRecordAttr |= (CRA_CURSORED | CRA_SELECTED);
[2]1344
[739]1345 if (removable == 0) {
1346 // Fixed volume
1347 pci->attrFile |= FILE_DIRECTORY;
1348 DosError(FERR_DISABLEHARDERR);
1349 rc = DosQueryPathInfo(szDrive,
[841]1350 FIL_QUERYEASIZEL,
1351 &fsa4, (ULONG) sizeof(FILESTATUS4L));
[739]1352 // ERROR_BAD_NET_RSP = 58
1353 if (rc == 58) {
[214]1354 DosError(FERR_DISABLEHARDERR);
1355 rc = DosQueryPathInfo(szDrive,
[841]1356 FIL_STANDARDL,
[847]1357 &fsa4, (ULONG) sizeof(FILESTATUS4L));
[739]1358 fsa4.cbList = 0;
1359 }
1360 if (rc && !didonce) {
1361 // Guess drive letter
1362 if (!*suggest) {
1363 *suggest = '/';
1364 suggest[1] = 0;
[214]1365 }
[739]1366 sprintf(suggest + strlen(suggest), "%c" , toupper(*szDrive));
[773]1367 pci->pszFileName = xstrdup(szDrive, pszSrcFile, __LINE__);
[739]1368 pci->pszDisplayName = pci->pszFileName;
1369 pci->rc.pszIcon = pci->pszDisplayName;
[214]1370 pci->attrFile = FILE_DIRECTORY;
[751]1371 pci->pszDispAttr = FileAttrToString(pci->attrFile);
[739]1372 driveserial[x] = -1;
[731]1373 }
[739]1374 else
1375 FillInRecordFromFSA(hwndCnr, pci, szDrive, &fsa4, TRUE, NULL);
[214]1376 }
[551]1377 else {
[739]1378 // Removable volume
[773]1379 pci->pszFileName = xstrdup(szDrive, pszSrcFile, __LINE__);
[739]1380 pci->pszDisplayName = pci->pszFileName;
1381 pci->rc.pszIcon = pci->pszDisplayName;
[214]1382 pci->attrFile = FILE_DIRECTORY;
[751]1383 pci->pszDispAttr = FileAttrToString(pci->attrFile);
[214]1384 }
[1284]1385 SelectDriveIcon(pci);
[1250]1386# ifdef FORTIFY
1387 // Will be freed by TreeCnrWndProc WM_DESTROY
1388 Fortify_SetScope(pci->pszFileName, 2);
1389# endif
[214]1390 }
[1284]1391 else {
[739]1392 pci->rc.hptrIcon = hptrDunno;
[773]1393 pci->pszFileName = xstrdup(szDrive, pszSrcFile, __LINE__);
[1154]1394# ifdef FORTIFY
1395 // Will be freed by TreeCnrWndProc WM_DESTROY
1396 Fortify_SetScope(pci->pszFileName, 2);
1397# endif
[739]1398 pci->pszDisplayName = pci->pszFileName;
[214]1399 pci->rc.pszIcon = pci->pszFileName;
1400 pci->attrFile = FILE_DIRECTORY;
[751]1401 pci->pszDispAttr = FileAttrToString(pci->attrFile);
[214]1402 driveserial[x] = -1;
1403 }
[2]1404 }
[739]1405 else {
1406 // diskette drive (A or B)
1407 pci->rc.hptrIcon = hptrFloppy;
[773]1408 pci->pszFileName = xstrdup(szDrive, pszSrcFile, __LINE__);
[739]1409 pci->pszDisplayName = pci->pszFileName;
1410 pci->rc.pszIcon = pci->pszDisplayName;
1411 pci->attrFile = FILE_DIRECTORY;
[751]1412 pci->pszDispAttr = FileAttrToString(pci->attrFile);
[739]1413 driveflags[x] |= (DRIVE_REMOVABLE | DRIVE_NOLONGNAMES);
1414 driveserial[x] = -1;
1415 }
1416 pci->rc.flRecordAttr |= CRA_RECORDREADONLY;
[783]1417 pci = (PCNRITEM) pci->rc.preccNextRecord; // next rec
[739]1418 }
1419 else if (!(ulDriveMap & (1L << x)))
1420 driveflags[x] |= DRIVE_INVALID;
1421 } // for drives
[689]1422
[739]1423 PostMsg(hwndMain, UM_BUILDDRIVEBAR, MPVOID, MPVOID);
1424 drivesbuilt = TRUE;
[2]1425
[783]1426 // insert the drives
[739]1427 if (numtoinsert && pciFirst) {
1428 RECORDINSERT ri;
1429
1430 memset(&ri, 0, sizeof(RECORDINSERT));
1431 ri.cb = sizeof(RECORDINSERT);
1432 ri.pRecordOrder = (PRECORDCORE) CMA_END;
1433 ri.pRecordParent = (PRECORDCORE) NULL;
1434 ri.zOrder = (ULONG) CMA_TOP;
1435 ri.cRecordsInsert = numtoinsert;
1436 ri.fInvalidateRecord = FALSE;
1437 if (!WinSendMsg(hwndCnr,
1438 CM_INSERTRECORD, MPFROMP(pciFirst), MPFROMP(&ri)))
1439 {
[744]1440 Win_Error2(hwndCnr, HWND_DESKTOP, pszSrcFile, __LINE__,
[739]1441 IDS_CMINSERTERRTEXT);
[2]1442 }
[739]1443 }
[689]1444
[783]1445 // move cursor onto the default drive rather than the first drive
[739]1446 if (!fSwitchTree) {
1447 pci = (PCNRITEM) WinSendMsg(hwndCnr,
1448 CM_QUERYRECORD,
1449 MPVOID,
1450 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
[762]1451 while (pci && (INT)pci != -1) {
[739]1452 if ((ULONG) (toupper(*pci->pszFileName) - '@') == ulCurDriveNum) {
1453 WinSendMsg(hwndCnr,
1454 CM_SETRECORDEMPHASIS,
1455 MPFROMP(pci), MPFROM2SHORT(TRUE, CRA_CURSORED));
1456 break;
1457 }
[551]1458 pci = (PCNRITEM) WinSendMsg(hwndCnr,
1459 CM_QUERYRECORD,
[739]1460 MPFROMP(pci),
1461 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
[2]1462 }
[739]1463 }
[2]1464
[739]1465 if (hwndParent) {
1466 WinSendMsg(WinWindowFromID(WinQueryWindow(hwndParent, QW_PARENT),
1467 MAIN_DRIVELIST),
1468 LM_DELETEALL, MPVOID, MPVOID);
1469 }
[2]1470
[739]1471 if (fShowEnv) {
1472 RECORDINSERT ri;
[2]1473
[739]1474 pciParent = WinSendMsg(hwndCnr,
1475 CM_ALLOCRECORD,
[751]1476 MPFROMLONG(EXTRA_RECORD_BYTES), MPFROMLONG(1));
[739]1477 if (pciParent) {
1478 pciParent->flags |= RECFLAGS_ENV;
[773]1479 pciParent->pszFileName = xstrdup(GetPString(IDS_ENVVARSTEXT), pszSrcFile, __LINE__);
[763]1480 pciParent->pszDisplayName = pciParent->pszFileName; // 03 Aug 07 SHL
[739]1481 pciParent->rc.hptrIcon = hptrEnv;
1482 pciParent->rc.pszIcon = pciParent->pszFileName;
[751]1483 pciParent->pszDispAttr = FileAttrToString(0);
[739]1484 memset(&ri, 0, sizeof(RECORDINSERT));
1485 ri.cb = sizeof(RECORDINSERT);
1486 ri.pRecordOrder = (PRECORDCORE) CMA_END;
1487 ri.pRecordParent = (PRECORDCORE) NULL;
1488 ri.zOrder = (ULONG) CMA_TOP;
1489 ri.cRecordsInsert = 1;
1490 ri.fInvalidateRecord = FALSE;
1491 if (WinSendMsg(hwndCnr,
1492 CM_INSERTRECORD, MPFROMP(pciParent), MPFROMP(&ri))) {
[2]1493
[739]1494 char *p, *pp;
[2]1495
[1154]1496 p = pszTreeEnvVarList;
[1090]1497 while (*p == ';')
[739]1498 p++;
1499 while (*p) {
[924]1500 *szFSType = 0;
1501 pp = szFSType;
[1090]1502 while (*p && *p != ';')
[739]1503 *pp++ = *p++;
1504 *pp = 0;
[1090]1505 while (*p == ';')
[214]1506 p++;
[924]1507 if (*szFSType &&
1508 (!stricmp(szFSType, "LIBPATH") || getenv(szFSType))) {
[739]1509 pci = WinSendMsg(hwndCnr,
1510 CM_ALLOCRECORD,
[751]1511 MPFROMLONG(EXTRA_RECORD_BYTES),
[739]1512 MPFROMLONG(1));
1513 if (pci) {
1514 CHAR fname[CCHMAXPATH];
1515 pci->flags |= RECFLAGS_ENV;
[924]1516 sprintf(fname, "%%%s%%", szFSType);
[739]1517 pci->pszFileName = xstrdup(fname, pszSrcFile, __LINE__);
1518 pci->rc.hptrIcon = hptrEnv;
1519 pci->rc.pszIcon = pci->pszFileName;
[751]1520 pci->pszDispAttr = FileAttrToString(0);
[739]1521 memset(&ri, 0, sizeof(RECORDINSERT));
1522 ri.cb = sizeof(RECORDINSERT);
1523 ri.pRecordOrder = (PRECORDCORE) CMA_END;
1524 ri.pRecordParent = (PRECORDCORE) pciParent;
1525 ri.zOrder = (ULONG) CMA_TOP;
1526 ri.cRecordsInsert = 1;
1527 ri.fInvalidateRecord = FALSE;
1528 if (!WinSendMsg(hwndCnr,
1529 CM_INSERTRECORD,
1530 MPFROMP(pci), MPFROMP(&ri))) {
[744]1531 Win_Error2(hwndCnr, HWND_DESKTOP, pszSrcFile, __LINE__,
[739]1532 IDS_CMINSERTERRTEXT);
[751]1533 FreeCnrItem(hwndCnr, pci);
[214]1534 }
1535 }
1536 }
1537 }
[739]1538 WinSendMsg(hwndCnr,
1539 CM_INVALIDATERECORD,
1540 MPFROMP(&pciParent),
1541 MPFROM2SHORT(1, CMA_ERASE | CMA_REPOSITION));
[2]1542 }
[739]1543 else
[751]1544 FreeCnrItem(hwndCnr, pciParent);
[739]1545 }
1546 } // if show env
[1299]1547 {
[1335]1548 STUBBYSCAN *stubbyScan;
[1299]1549 HWND hwndDrivesList = WinWindowFromID(WinQueryWindow(hwndParent, QW_PARENT),
[1335]1550 MAIN_DRIVELIST);
[1299]1551
[1250]1552 pci = (PCNRITEM) WinSendMsg(hwndCnr,
[1308]1553 CM_QUERYRECORD,
1554 MPVOID,
[1335]1555 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
[1317]1556 StubbyScanCount ++;
[1250]1557 while (pci && (INT)pci != -1) {
[1335]1558 stubbyScan = xmallocz(sizeof(STUBBYSCAN), pszSrcFile, __LINE__);
1559 if (!stubbyScan)
[1308]1560 break;
[1335]1561 stubbyScan->pci = pci;
1562 stubbyScan->hwndCnr = hwndCnr;
1563 stubbyScan->hwndDrivesList = hwndDrivesList;
1564 stubbyScan->RamDrive = FALSE;
[1250]1565 pciNext = (PCNRITEM) WinSendMsg(hwndCnr,
[1308]1566 CM_QUERYRECORD,
1567 MPFROMP(pci),
1568 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
[1284]1569 if (~pci->flags & RECFLAGS_ENV) {
[1308]1570 ULONG drvNum = toupper(*pci->pszFileName) - 'A'; // 0..25
1571 if (drvNum == ulCurDriveNum || drvNum >= 2) {
1572 ULONG flags = driveflags[drvNum]; // Speed up
1573 if (~flags & DRIVE_INVALID &&
1574 ~flags & DRIVE_NOPRESCAN &&
[1326]1575 (!fNoRemovableScan || ~flags & DRIVE_REMOVABLE) && !fDrivetoSkip[drvNum])
[1308]1576 {
1577 if (DRIVE_RAMDISK)
[1335]1578 stubbyScan->RamDrive = TRUE;
1579 if (xbeginthread(StubbyScanThread,
1580 65536,
1581 stubbyScan,
1582 pszSrcFile,
1583 __LINE__) == -1)
1584 {
1585 xfree(stubbyScan, pszSrcFile, __LINE__);
1586 }
[1308]1587 } // if drive for scanning
1588 else
1589 WinSendMsg(hwndDrivesList,
1590 LM_INSERTITEM,
1591 MPFROM2SHORT(LIT_SORTASCENDING, 0),
1592 MPFROMP(pci->pszFileName));
1593 }
1594 else {
1595 WinSendMsg(hwndCnr,
1596 CM_INVALIDATERECORD,
1597 MPFROMP(&pci),
1598 MPFROM2SHORT(1, CMA_ERASE | CMA_REPOSITION));
1599 WinSendMsg(hwndDrivesList,
1600 LM_INSERTITEM,
1601 MPFROM2SHORT(LIT_SORTASCENDING, 0),
1602 MPFROMP(pci->pszFileName));
[1335]1603 }
1604 fDrivetoSkip[drvNum] = FALSE;
[739]1605 }
[1250]1606 pci = pciNext;
1607 } // while
[1326]1608 StubbyScanCount--;
1609 if (StubbyScanCount == 0)
1610 fInitialDriveScan = FALSE;
[1299]1611 }
[739]1612 if (hwndParent)
1613 WinSendMsg(WinWindowFromID(WinQueryWindow(hwndParent, QW_PARENT),
1614 MAIN_DRIVELIST), LM_SELECTITEM,
1615 MPFROM2SHORT(0, 0), MPFROMLONG(TRUE));
[2]1616
[739]1617 pci = (PCNRITEM) WinSendMsg(hwndCnr,
1618 CM_QUERYRECORD,
1619 MPVOID,
1620 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
[762]1621 while (pci && (INT)pci != -1) {
[739]1622 pciNext = (PCNRITEM) WinSendMsg(hwndCnr,
[551]1623 CM_QUERYRECORD,
1624 MPFROMP(pci),
[739]1625 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
1626 if (pci->flags & RECFLAGS_ENV) {
[551]1627 pci = (PCNRITEM) WinSendMsg(hwndCnr,
1628 CM_QUERYRECORD,
1629 MPFROMP(pci),
[739]1630 MPFROM2SHORT(CMA_FIRSTCHILD,
1631 CMA_ITEMORDER));
[762]1632 while (pci && (INT)pci != -1) {
[739]1633 if (pci->flags & RECFLAGS_ENV)
1634 FleshEnv(hwndCnr, pci);
1635 pci = (PCNRITEM) WinSendMsg(hwndCnr,
1636 CM_QUERYRECORD,
1637 MPFROMP(pci),
1638 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
1639 }
1640 break;
[2]1641 }
[739]1642 pci = (PCNRITEM) WinSendMsg(hwndCnr,
1643 CM_QUERYRECORD,
1644 MPFROMP(pci),
1645 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
1646 }
[2]1647
[167]1648 if (!drivesbuilt && hwndMain)
[551]1649 PostMsg(hwndMain, UM_BUILDDRIVEBAR, MPVOID, MPVOID);
[783]1650 DosSleep(16); // 05 Aug 07 GKY 33
[2]1651 fDummy = FALSE;
1652 DosPostEventSem(CompactSem);
[739]1653
[2]1654 {
1655 BYTE info;
1656 BOOL includesyours = FALSE;
1657
[917]1658 // 10 Jan 08 SHL fixme to understand fFirstTime
[551]1659 if (*suggest || (!(driveflags[1] & DRIVE_IGNORE) && fFirstTime)) {
1660 if (!DosDevConfig(&info, DEVINFO_FLOPPY) && info == 1) {
1661 if (!*suggest) {
[214]1662 *suggest = '/';
1663 suggest[1] = 0;
1664 }
1665 else
[551]1666 memmove(suggest + 2, suggest + 1, strlen(suggest));
[214]1667 suggest[1] = 'B';
[2]1668 }
1669 }
[551]1670 if (*suggest) {
1671 for (x = 2; x < 26; x++) {
1672 if (driveflags[x] & DRIVE_IGNORE) {
[214]1673 includesyours = TRUE;
[551]1674 sprintf(suggest + strlen(suggest), "%c", (char)(x + 'A'));
[214]1675 }
[2]1676 }
[551]1677 strcat(suggest, " %*");
[167]1678 if (saymsg(MB_YESNO | MB_ICONEXCLAMATION,
[214]1679 (hwndParent) ? hwndParent : hwndCnr,
1680 GetPString(IDS_SUGGESTTITLETEXT),
1681 GetPString(IDS_SUGGEST1TEXT),
1682 (includesyours) ? GetPString(IDS_SUGGEST2TEXT) : NullStr,
[551]1683 suggest) == MBID_YES) {
[214]1684 char s[64];
[2]1685
[214]1686 sprintf(s, "PARAMETERS=%s", suggest);
[551]1687 WinCreateObject(WPProgram, "FM/2", s, FM3Folder, CO_UPDATEIFEXISTS);
[214]1688 WinCreateObject(WPProgram,
[551]1689 "FM/2 Lite", s, FM3Folder, CO_UPDATEIFEXISTS);
[214]1690 WinCreateObject(WPProgram,
[551]1691 "Archive Viewer/2", s, FM3Tools, CO_UPDATEIFEXISTS);
[214]1692 WinCreateObject(WPProgram,
[551]1693 "Dir Sizes", s, FM3Tools, CO_UPDATEIFEXISTS);
[214]1694 WinCreateObject(WPProgram,
[551]1695 "Visual Tree", s, FM3Tools, CO_UPDATEIFEXISTS);
[214]1696 WinCreateObject(WPProgram,
[551]1697 "Visual Directory", s, FM3Tools, CO_UPDATEIFEXISTS);
[214]1698 WinCreateObject(WPProgram,
[551]1699 "Global File Viewer", s, FM3Tools, CO_UPDATEIFEXISTS);
1700 WinCreateObject(WPProgram, "Databar", s, FM3Tools, CO_UPDATEIFEXISTS);
[2]1701 }
1702 }
1703 }
[739]1704
[2]1705 didonce = TRUE;
1706
[731]1707} // FillTreeCnr
[743]1708
1709
1710/**
1711 * Empty all records from a container and free associated storage and
1712 * Free up field infos
1713 */
1714
1715VOID EmptyCnr(HWND hwnd)
1716{
1717 PFIELDINFO pfi;
1718
[762]1719#if 0 // fixme to be gone or to be configurable
[751]1720 {
1721 int state = _heapchk();
1722 if (state != _HEAPOK)
1723 Runtime_Error(pszSrcFile, __LINE__, "heap corrupted %d", state);
1724 }
1725#endif
1726
[743]1727 // Remove all records
1728 RemoveCnrItems(hwnd, NULL, 0, CMA_FREE);
1729
1730 // Remove field info descriptors
1731 pfi = (PFIELDINFO) WinSendMsg(hwnd, CM_QUERYDETAILFIELDINFO, MPVOID,
1732 MPFROMSHORT(CMA_FIRST));
[745]1733 if (pfi &&
1734 (INT)WinSendMsg(hwnd, CM_REMOVEDETAILFIELDINFO, MPVOID,
1735 MPFROM2SHORT(0, CMA_FREE)) == -1) {
1736 Win_Error(hwnd, HWND_DESKTOP, pszSrcFile, __LINE__,"CM_REMOVEDETAILFIELDINFO hwnd %x", hwnd);
1737 }
[743]1738}
1739
1740/**
1741 * Free storage associated with container item
1742 */
1743
[751]1744VOID FreeCnrItemData(PCNRITEM pci)
[743]1745{
[1308]1746 if (pci->pszSubject) {
1747 if (pci->pszSubject != NullStr)
1748 free(pci->pszSubject);
[1174]1749 pci->pszSubject = NULL; // Catch illegal references
[762]1750 }
[743]1751
[1174]1752 // 08 Sep 08 SHL Remove excess logic
[1308]1753 if (pci->pszLongName) {
1754 if (pci->pszLongName != NullStr)
1755 free(pci->pszLongName);
[1174]1756 pci->pszLongName = NULL; // Catch illegal references
[762]1757 }
[1154]1758
1759 // Bypass free if pszDisplayName points into pszFileName buffer
1760 // 05 Sep 08 SHL Correct pointer overlap compare logic
[1308]1761 if (pci->pszDisplayName) {
1762 if (pci->pszDisplayName != NullStr) {
1763 if (!pci->pszFileName ||
1764 pci->pszDisplayName < pci->pszFileName ||
1765 pci->pszDisplayName >= pci->pszFileName + _msize(pci->pszFileName))
1766 {
1767 free(pci->pszDisplayName);
1768 }
[1154]1769 }
[1308]1770 pci->pszDisplayName = NULL; // Catch illegal references
[1154]1771 }
[1113]1772
[1308]1773 if (!pci->pszFileName)
1774 Runtime_Error(pszSrcFile, __LINE__, "FreeCnrItemData attempting free %p data twice", pci);
1775 else {
1776 if (pci->pszFileName != NullStr)
1777 free(pci->pszFileName);
1778 pci->pszFileName = NULL; // Catch illegal references
1779 }
1780
[1299]1781 // 08 Sep 08 SHL Remove excess logic
[1308]1782 if (pci->pszLongName) {
1783 if (pci->pszLongName != NullStr)
1784 free(pci->pszLongName);
[1299]1785 pci->pszLongName = NULL; // Catch illegal references
1786 }
[1174]1787
[1308]1788 if (pci->pszFmtFileSize) {
1789 if (pci->pszFmtFileSize != NullStr)
1790 free(pci->pszFmtFileSize);
[1174]1791 pci->pszFmtFileSize = NULL; // Catch illegal references
[857]1792 }
[743]1793}
1794
1795/**
[762]1796 * Free single container item and associated storage
[743]1797 */
1798
[762]1799VOID FreeCnrItem(HWND hwnd, PCNRITEM pci)
[743]1800{
[745]1801 // DbgMsg(pszSrcFile, __LINE__, "FreeCnrItem hwnd %x pci %p", hwnd, pci);
1802
[743]1803 FreeCnrItemData(pci);
1804
[762]1805 if (!WinSendMsg(hwnd, CM_FREERECORD, MPFROMP(&pci), MPFROMSHORT(1))) {
[744]1806 // Win_Error2(hwnd, HWND_DESKTOP, pszSrcFile, __LINE__,IDS_CMFREEERRTEXT);
[773]1807 Win_Error(hwnd, HWND_DESKTOP, pszSrcFile, __LINE__,
1808 "CM_FREERECORD hwnd %x pci %p file %s",
[783]1809 hwnd, pci,
[773]1810 pci && pci->pszFileName ? pci->pszFileName : "n/a");
[743]1811 }
1812}
1813
1814/**
[751]1815 * Free container item list and associated storage
[743]1816 */
1817
[751]1818VOID FreeCnrItemList(HWND hwnd, PCNRITEM pciFirst)
[743]1819{
[751]1820 PCNRITEM pci = pciFirst;
1821 PCNRITEM pciNext;
[762]1822 USHORT usCount;
[751]1823
[762]1824 for (usCount = 0; pci; usCount++) {
[751]1825 pciNext = (PCNRITEM) pci->rc.preccNextRecord;
[762]1826 FreeCnrItemData(pci);
[751]1827 pci = pciNext;
1828 }
[762]1829
1830 if (usCount) {
1831 if (!WinSendMsg(hwnd, CM_FREERECORD, MPFROMP(&pci), MPFROMSHORT(usCount))) {
1832 // Win_Error2(hwnd, HWND_DESKTOP, pszSrcFile, __LINE__,IDS_CMFREEERRTEXT);
1833 Win_Error(hwnd, HWND_DESKTOP, pszSrcFile, __LINE__,"CM_FREERECORD hwnd %x pci %p cnt %u", hwnd, pci, usCount);
1834 }
1835 }
[751]1836}
1837
1838/**
1839 * Remove item(s) from container and free associated storage if requested
[762]1840 * @param pciFirst points to first item to remove or NULL to remove all
1841 * @param usCnt is remove count or 0 to remove all
[751]1842 * @returns count of items remaining in container or -1 if error
1843 */
1844
[762]1845INT RemoveCnrItems(HWND hwnd, PCNRITEM pciFirst, USHORT usCnt, USHORT usFlags)
[751]1846{
[762]1847 INT remaining = usCnt;
1848 PCNRITEM pci;
[751]1849
[762]1850 if ((usCnt && !pciFirst) || (!usCnt && pciFirst)) {
1851 Runtime_Error(pszSrcFile, __LINE__, "pciFirst %p usCnt %u mismatch", pciFirst, usCnt);
[751]1852 remaining = -1;
[762]1853 }
1854 else {
1855 // Free our buffers if free requested
1856 if (usFlags & CMA_FREE) {
1857 if (pciFirst)
1858 pci = pciFirst;
1859 else {
[743]1860 pci = (PCNRITEM)WinSendMsg(hwnd, CM_QUERYRECORD, MPVOID,
[744]1861 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
[762]1862 if ((INT)pci == -1) {
[744]1863 Win_Error(hwnd, HWND_DESKTOP, pszSrcFile, __LINE__,"CM_QUERYRECORD");
[751]1864 remaining = -1;
[762]1865 pci = NULL;
1866 }
1867 }
1868 while (pci) {
[850]1869 // 12 Sep 07 SHL dwg drivebar crash testing - ticket# ???
[1174]1870 static PCNRITEM pciLast; // 12 Sep 07 SHL
[907]1871 ULONG ulSize = sizeof(*pci);
1872 ULONG ulAttr;
[850]1873 APIRET apiret = DosQueryMem((PVOID)pci, &ulSize, &ulAttr);
1874 if (apiret)
[907]1875 Dos_Error(MB_ENTER, apiret, HWND_DESKTOP, pszSrcFile, __LINE__,
[850]1876 "DosQueryMem failed pci %p pciLast %p", pci, pciLast);
[1308]1877 FreeCnrItemData(pci);
[850]1878 pciLast = pci;
[762]1879 pci = (PCNRITEM)pci->rc.preccNextRecord;
1880 if (remaining && --remaining == 0)
[744]1881 break;
[762]1882 }
[743]1883 }
1884 }
[745]1885
[762]1886 // DbgMsg(pszSrcFile, __LINE__, "RemoveCnrItems %p %u %s", pci, usCnt, pci->pszFileName);
[743]1887
[762]1888 if (remaining != - 1) {
1889 remaining = (INT)WinSendMsg(hwnd, CM_REMOVERECORD, MPFROMP(&pciFirst), MPFROM2SHORT(usCnt, usFlags));
[751]1890 if (remaining == -1) {
[744]1891 // Win_Error2(hwnd, HWND_DESKTOP, pszSrcFile, __LINE__,IDS_CMREMOVEERRTEXT);
[762]1892 Win_Error(hwnd, HWND_DESKTOP, pszSrcFile, __LINE__,"CM_REMOVERECORD hwnd %x pci %p cnt %u", hwnd, pciFirst, usCnt);
[743]1893 }
1894 }
[762]1895
[751]1896 return remaining;
[743]1897}
1898
[783]1899#pragma alloc_text(FILLDIR,FillInRecordFromFFB,FillInRecordFromFSA,IDFile)
[1299]1900#pragma alloc_text(FILLDIR1,ProcessDirectory,FillDirCnr,FillTreeCnr,FileAttrToString,StubbyScanThread)
[783]1901#pragma alloc_text(EMPTYCNR,EmptyCnr,FreeCnrItemData,FreeCnrItem,FreeCnrItemList,RemoveCnrItems)
1902
Note: See TracBrowser for help on using the repository browser.