source: trunk/dll/filldir.c@ 1319

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

Part of 1318 Event seamphore code.

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