source: trunk/dll/filldir.c@ 1882

Last change on this file since 1882 was 1880, checked in by Gregg Young, 10 years ago

Remove dead code and comments from remaining c files. #if 0 and #if NEVER were not addressed

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