source: trunk/dll/filldir.c@ 1323

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

Use event semaphore to prevent rescan of drives while StubbySacnTreads are still running; code cleanup.

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