source: trunk/dll/filldir.c@ 1401

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

Remainder of changes to rename commafmt.h/c (Ticket 28, 82); Additional strings moved to PCSZs in init.c (Ticket 6); Added WriteDetailsSwitches used it and LoadDetailsSwitches to consolidate inline code (Ticket 343, 344)

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