source: trunk/dll/filldir.c@ 1299

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

Scan each drive on separate thread (added StubbyScanThread) to speed treecnr scans

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