source: trunk/dll/filldir.c@ 1551

Last change on this file since 1551 was 1551, checked in by Gregg Young, 15 years ago

This code adds the semaphores to prevent a rescan from starting before the current one is finished; it fixes the double directory listing in the tree container and streamlines scanning. It update mapsym.pl to the latest version. Some code cleanup is included

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