source: trunk/dll/filldir.c@ 1330

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

Code cleanup replace sizeof calls for threaded drive scans

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