source: trunk/dll/filldir.c@ 1438

Last change on this file since 1438 was 1438, checked in by Gregg Young, 16 years ago

Improved drivebar changes; Added AddBackslashToPath() to remove repeatative code. replaced "
" with PCSZ variable; ANY_OBJ added the DosAlloc... (experimental)

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