source: trunk/dll/flesh.c@ 1874

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

DosSleep times in WaitFleshWorkListEmpty set by caller; TOPDIR code calls WaitFleshWorkListEmpty before ShowCnrRecord and now actually exists for directory containers in tree view. These calls are made from the object windows.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 33.4 KB
RevLine 
[145]1
2/***********************************************************************
3
4 $Id: flesh.c 1874 2015-09-27 17:20:10Z gyoung $
5
[1856]6 Drive tree container management
[145]7
8 Copyright (c) 1993-98 M. Kimes
[1858]9 Copyright (c) 2005, 2015 Steven H. Levine
[145]10
11 24 May 05 SHL Rework Win_Error usage
[166]12 25 May 05 SHL Rework for ProcessDirectory
[284]13 28 May 05 SHL Clean while reading code
14 24 Oct 05 SHL Delete obsolete code
[340]15 22 Jul 06 SHL Check more run time errors
[515]16 19 Oct 06 SHL Stubby - correct . and .. detect
[574]17 22 Mar 07 GKY Use QWL_USER
[751]18 01 Aug 07 SHL Sync with CNRITEM mods
[775]19 06 Aug 07 GKY Reduce DosSleep times (ticket 148)
[793]20 20 Aug 07 GKY Move #pragma alloc_text to end for OpenWatcom compat
[985]21 29 Feb 08 GKY Use xfree where appropriate
[1299]22 24 Nov 08 GKY remove redundant code and minor speed up of Stubby
[1358]23 25 Dec 08 GKY Add ProcessDirectoryThread to allow optional recursive drive scan at startup.
24 25 Dec 08 GKY Add DRIVE_RSCANNED flag to monitor for the first recursive drive scan per session
[1471]25 to prevent duplicate directory names in tree following a copy before initial scan.
[1400]26 08 Mar 09 GKY Additional strings move to PCSZs in init.c
[1482]27 13 Dec 09 GKY Fixed separate paramenters. Please note that appname should be used in
[1856]28 profile calls for user settings that work and are setable in more than one
29 miniapp; FM3Str should be used for setting only relavent to FM/2 or that
30 aren't user settable; realappname should be used for setting applicable to
31 one or more miniapp but not to FM/2
[1662]32 17 Jan 10 GKY Changes to get working with Watcom 1.9 Beta (1/16/10). Mostly cast CHAR CONSTANT * as CHAR *.
33 04 Aug 12 GKY Fix trap on close during drive scan
[1837]34 02 Aug 15 GKY Fix trap in Stubby
[1856]35 03 Aug 15 SHL Document Stubby a bit better
36 07 Aug 15 SHL Rework to use AddFleshWorkRequest rather than direct calls to Stubby/Flesh/Unflesh
[1858]37 19 Aug 15 SHL Allow WaitFleshWorkListEmpty to wait for dependent items
[1864]38 23 Aug 15 GKY Fixed code to notify on drive with no subdirectories in first 64 entries
[1871]39 20 Sep 15 GKY Add code for Flesh to skip the directory entry added by Stubby (eliminate
40 use of NULL/Nullstr pszFileNames by Stubby). Add code in Stubby to insert a
41 complete container item. Add a flag to indicate when a directory needed to be
42 Fleshed
[1873]43 26 Sep 15 GKY Changes to speed up ExpandAll
44 26 Sep 15 GKY WaitFleshWorkListEmpty now gives error message and returns if semaphore request
45 fails more than 5 consecutive times.
[1874]46 27 Sep 15 GKY DosSleep times in WaitFleshWorkListEmpty set by caller
[145]47
48***********************************************************************/
49
[907]50#include <stdlib.h>
51#include <string.h>
52#include <ctype.h>
[1831]53//#include <malloc.h>
[907]54
[2]55#define INCL_DOS
56#define INCL_DOSERRORS
57#define INCL_WIN
[907]58#define INCL_LONGLONG // dircnrs.h
[2]59
[1177]60#include "fm3dll.h"
[1207]61#include "draglist.h" // Data declaration(s)
62#include "notebook.h" // Data declaration(s)
63#include "info.h" // Data declaration(s)
64#include "init.h" // Data declaration(s)
65#include "mainwnd.h" // Data declaration(s)
[907]66#include "fm3str.h"
67#include "filldir.h" // FileAttrToString...
68#include "errutil.h" // Dos_Error...
69#include "strutil.h" // GetPString
[1155]70#include "flesh.h"
71#include "valid.h" // IsValidDir
[1856]72#include "misc.h" // LoadLibPath GetTidForThread
[1177]73#include "findrec.h" // FindCnrRecord
74#include "notify.h" // Notify
75#include "wrappers.h" // xfree
[1354]76#include "excputil.h" // xbeginthread
[1856]77#include "listutil.h" // List...
78#include "common.h" // IncrThreadUsage DecrThreadUsage
[1871]79#include "pathutil.h"
[1873]80#include "treecnr.h" // fExpandAll
[1831]81#if 0
82#define __PMPRINTF__
83#include "PMPRINTF.H"
84#endif
[2]85
[1207]86// Data definitions
[2]87#pragma data_seg(DATA1)
[340]88
89static PSZ pszSrcFile = __FILE__;
90
[1856]91
92static INT tidFleshWorkListThread = -1; // 2015-08-08 SHL
93
[1860]94static PCSZ pszFleshFocusPath; // 2015-08-20 SHL
[1871]95#if 0
[1856]96BOOL fNoFleshDbgMsg; // 2015-08-09 SHL FIXME to be gone
[1871]97#endif
[1207]98#pragma data_seg(GLOBAL1)
99ULONG NoBrokenNotify;
100BOOL fFilesInTree;
101
[1856]102BOOL Flesh(HWND hwndCnr, PCNRITEM pciParent);
103
104BOOL Stubby(HWND hwndCnr, PCNRITEM pciParent);
105BOOL FleshEnv(HWND hwndCnr, PCNRITEM pciParent);
[1858]106VOID UnFlesh(HWND hwndCnr, PCNRITEM pciParent);
[1856]107
108/**
109 * Insert CNRITEMs for members of PATH-like environment variable
110 * @param hwndCnr is the container to be populated
111 * @param pciParent is CNRITEM defining PATH-like environment variable
112 * @return TRUE if OK, FALSE is error detected
113 */
114
[551]115BOOL FleshEnv(HWND hwndCnr, PCNRITEM pciParent)
[175]116{
[551]117 PCNRITEM pciL;
[2]118 DIRCNRDATA *dcd;
[551]119 CHAR path[CCHMAXPATH + 12],
120 fullpath[CCHMAXPATH + 12], *env, *p, *pp, *var = NULL;
[2]121
[1858]122 if (!pciParent || (INT)pciParent == -1 || !hwndCnr)
[2]123 return FALSE;
[1856]124
[574]125 dcd = (DIRCNRDATA *) WinQueryWindowPtr(hwndCnr, QWL_USER);
[551]126 if (!dcd)
[2]127 return FALSE;
128
[730]129 strcpy(path, pciParent->pszFileName + 1);
[551]130 if (stricmp(path, GetPString(IDS_ENVVARSTEXT) + 1))
131 UnFlesh(hwndCnr, pciParent);
132 if (*path) {
[2]133 path[strlen(path) - 1] = 0;
[1400]134 if (!stricmp(path, PCSZ_LIBPATH)) {
[551]135 var = xmalloc(65536, pszSrcFile, __LINE__);
136 if (var)
137 LoadLibPath(var, 65536);
[2]138 env = var;
139 }
140 else
141 env = getenv(path);
[551]142 if (env && *env) {
[2]143 p = env;
[551]144 while (*p) {
145 pp = path;
146 while (*p == ';')
147 p++;
148 while (*p && *p != ';') {
149 *pp = *p;
150 p++;
151 pp++;
152 }
153 *pp = 0;
154 if (*path &&
155 strcmp(path, ".") &&
156 strcmp(path, ".\\") &&
157 strcmp(path, "..") &&
158 strcmp(path, "..\\") &&
159 strncmp(path, ".\\", 2) && strncmp(path, "..\\", 3)) {
160 if (!DosQueryPathInfo(path,
161 FIL_QUERYFULLNAME,
162 fullpath,
163 sizeof(fullpath)) && IsValidDir(fullpath)) {
164 pciL = FindCnrRecord(hwndCnr,
165 fullpath, pciParent, FALSE, FALSE, FALSE);
166 if (pciL) {
[1858]167 while (pciL && pciL != (PCNRITEM)-1 && pciL != pciParent)
[551]168 pciL = WinSendMsg(hwndCnr,
169 CM_QUERYRECORD,
170 MPFROMP(pciL),
171 MPFROM2SHORT(CMA_PARENT, CMA_ITEMORDER));
172 }
173 if (!pciL) {
[2]174
[551]175 RECORDINSERT ri;
[2]176
[551]177 pciL = WinSendMsg(hwndCnr,
178 CM_ALLOCRECORD,
[751]179 MPFROMLONG(EXTRA_RECORD_BYTES),
[551]180 MPFROMLONG(1));
181 if (pciL) {
[730]182 pciL->pszFileName = xstrdup(fullpath, pszSrcFile, __LINE__);
[751]183 pciL->rc.pszIcon = pciL->pszFileName;
[551]184 if (!fNoIconsDirs &&
185 (!isalpha(*fullpath) ||
186 !(driveflags[toupper(*fullpath) - 'A'] &
187 DRIVE_NOLOADICONS)))
188 pciL->rc.hptrIcon = WinLoadFileIcon(fullpath, FALSE);
189 if (!pciL->rc.hptrIcon)
190 pciL->rc.hptrIcon = hptrDir;
191 pciL->attrFile = FILE_DIRECTORY;
[751]192 pciL->pszDispAttr = FileAttrToString(pciL->attrFile);
[551]193 memset(&ri, 0, sizeof(ri));
194 ri.cb = sizeof(ri);
[1858]195 ri.pRecordOrder = (PRECORDCORE)CMA_END;
196 ri.pRecordParent = (PRECORDCORE)pciParent;
197 ri.zOrder = (ULONG)CMA_TOP;
[551]198 ri.cRecordsInsert = 1;
199 ri.fInvalidateRecord = FALSE;
[1871]200#if 0 // 2015-08-03 SHL FIXME debug
[1858]201 if (pciL->pszFileName == NullStr)
202 DbgMsg(pszSrcFile, __LINE__, "Stubby CM_INSERTRECORD pci %p pszFileName \"%s\"", pciL, pciL->pszFileName); // 2015-08-03 SHL FIXME debug
[1871]203#endif
204 if (!WinSendMsg(hwndCnr,
[551]205 CM_INSERTRECORD, MPFROMP(pciL), MPFROMP(&ri)))
[751]206 FreeCnrItem(hwndCnr, pciL);
[551]207 }
208 }
209 }
210 }
[2]211 }
212 }
[1009]213 xfree(var, pszSrcFile, __LINE__);
[1858]214 pciL = (PCNRITEM)WinSendMsg(hwndCnr,
215 CM_QUERYRECORD,
216 MPFROMP(pciParent),
217 MPFROM2SHORT(CMA_FIRSTCHILD, CMA_ITEMORDER));
218 while (pciL && (INT)pciL != -1) {
[2]219 pciL->flags |= (RECFLAGS_NODRAG | RECFLAGS_UNDERENV);
220 WinSendMsg(hwndCnr,
[551]221 CM_INVALIDATERECORD, MPFROMP(&pciL), MPFROM2SHORT(1, 0));
[2]222 pciL = WinSendMsg(hwndCnr,
[551]223 CM_QUERYRECORD,
224 MPFROMP(pciL), MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
[2]225 }
226 }
227 return TRUE;
228}
229
[1856]230/**
231 * Insert CNRITEMs for all children of pciParent
232 * @param hwnCnr is container to receive CNRITEMs
233 * @param pciParent is CNRITEM to have children inserted
234 * @return TRUE if OK, FALSE is error detected
235 */
236
[551]237BOOL Flesh(HWND hwndCnr, PCNRITEM pciParent)
[166]238{
[551]239 PCNRITEM pciL;
[2]240 DIRCNRDATA *dcd;
[1856]241 BOOL includefiles;
[2]242
[1856]243 if (!pciParent || (INT)pciParent == -1 || !hwndCnr)
[2]244 return FALSE;
[1856]245
[1858]246 // 2015-08-13 SHL
247 if (fAmQuitting)
248 return FALSE;
[1856]249
[1871]250#if 0 // 2015-08-03 SHL FIXME debug
[1856]251 if (!fNoFleshDbgMsg) {
252 DbgMsg(pszSrcFile, __LINE__, "Flesh %s pciParent %p pszFileName %p",
253 pciParent && (INT)pciParent != -1 && pciParent->pszFileName ?
254 pciParent->pszFileName : "(null)",
255 pciParent,
256 pciParent && (INT)pciParent != -1 ? pciParent->pszFileName : (PVOID)-1); // 2015-08-03 SHL FIXME debug
257 }
[1871]258#endif
[1856]259 // 2015-08-06 SHL allow pciL -1
[1858]260 // 2015-08-06 SHL FIXME to not need pszFileName check
[1871]261 if (!pciParent->fleshed) {
262 pciL = (PCNRITEM)WinSendMsg(hwndCnr,
263 CM_QUERYRECORD,
264 MPFROMP(pciParent),
265 MPFROM2SHORT(CMA_FIRSTCHILD, CMA_ITEMORDER));
[1874]266 // Added by Stubby to create plus sign run Stubby on it here and skip it in ProcessDirectory
[1856]267 if (pciL && (INT)pciL != -1) {
[1871]268 AddFleshWorkRequest(hwndCnr, pciL, eStubby);
[1874]269 // 2015-08-06 SHL FIXME to ensure this can not happen
[1871]270 if (!*pciL->pszFileName || !strcmp(pciL->pszFileName, NullStr))
271 Runtime_Error(pszSrcFile, __LINE__, "Flesh called with pci %p pszFileName (null)", pciL);
272#if 0
[1856]273 if (!fNoFleshDbgMsg)
[1858]274 DbgMsg(pszSrcFile, __LINE__, "Flesh RemoveCnrItems() pciL %p \"%s\"",
275 pciL,
276 pciL->pszFileName ? pciL->pszFileName : "(null)"); // 2015-08-04 SHL FIXME debug
277 // Assume refernces to pciL already removed from work list
[1871]278#endif
[1856]279 }
[1651]280 dcd = INSTDATA(hwndCnr);
281 if (dcd && dcd->size != sizeof(DIRCNRDATA))
282 dcd = NULL;
[1856]283
284 includefiles =
285 driveflags[toupper(*pciParent->pszFileName) - 'A'] & DRIVE_INCLUDEFILES ?
286 TRUE : fFilesInTree;
287
[1662]288 ProcessDirectory(hwndCnr,
[1856]289 pciParent,
290 pciParent->pszFileName,
291 includefiles, // filestoo
292 TRUE, // recurse
293 TRUE, // partial
294 NULL, // stop flag
295 dcd,
296 NULL, // total files
[1871]297 NULL, // total bytes
298 (pciL && (INT)pciL != -1) ? pciL->pszDisplayName : 0);
299 pciParent->fleshed = TRUE;
[1655]300 return TRUE;
[1651]301 }
[1856]302
[1655]303 return FALSE;
[2]304}
305
[1858]306/**
307 * Remove children from container
[1865]308 * @param pciParent is parent of children to be removed
[1858]309 */
[1856]310
[1858]311VOID UnFlesh(HWND hwndCnr, PCNRITEM pciParent)
[175]312{
[1856]313 BOOL removed = FALSE;
[2]314 PCNRITEM pciL;
315
[175]316 if (!pciParent || !hwndCnr)
[1858]317 return;
[1871]318#if 0
[1856]319 if (!fNoFleshDbgMsg)
[1865]320 DbgMsg(pszSrcFile, __LINE__, "UnFlesh pciParent %p pszFileName \"%s\"", pciParent, pciParent->pszFileName ? pciParent->pszFileName : "(null)"); // 2015-08-03 SHL FIXME debug
[1871]321#endif
[551]322 for (;;) {
[1858]323 pciL = (PCNRITEM)WinSendMsg(hwndCnr,
324 CM_QUERYRECORD,
325 MPFROMP(pciParent),
326 MPFROM2SHORT(CMA_FIRSTCHILD, CMA_ITEMORDER));
[1856]327 if (!pciL || (INT)pciL == -1)
328 break; // Done
[1871]329#if 0
[1856]330 if (!fNoFleshDbgMsg)
[1865]331 DbgMsg(pszSrcFile, __LINE__, "UnFlesh RemoveCnrItems() pciL %p \"%s\"", pciL, pciL->pszFileName ? pciL->pszFileName : "(null)"); // 2015-08-03 SHL FIXME debug
[1871]332#endif
[1856]333 RemoveCnrItems(hwndCnr, pciL, 1, CMA_FREE);
334 removed = TRUE;
335 } // for
336
337 if (removed) {
[2]338 WinSendMsg(hwndCnr,
[551]339 CM_INVALIDATERECORD,
340 MPFROMP(&pciParent),
[1871]341 MPFROM2SHORT(1, CMA_ERASE | CMA_REPOSITION));
342 pciParent->fleshed = FALSE;
343 DosSleep(1); // Let container items go away
[175]344 }
[1858]345 return;
[2]346}
347
[1482]348#define DDEPTH 64
[2]349
[1471]350/**
[1856]351 * Insert CNRITEM for 1st subdirectory [or file] of pciParent
352 * @param hwdCnr is container to be filled
353 * @param pciParent is CNRITEM to receive child record
354 * @return TRUE if record inserted, else FALSE
355 * Ensures that expand/collapse button displays if directory has children
356 * Secondary purpose is to detect broken LANs and inaccesible mapped drives
[1471]357 */
358
[551]359BOOL Stubby(HWND hwndCnr, PCNRITEM pciParent)
[175]360{
[1409]361 /**
[2]362 * this code is full of workarounds for screwed up LANs.
363 * let's hope all the current LAN programmers fall into
364 * a black hole and make way for people who can get it right...
365 */
366
[1471]367 BOOL ok = FALSE;
[847]368 FILEFINDBUF3 ffb[DDEPTH];
369 PFILEFINDBUF3 pffb;
[551]370 HDIR hDir = HDIR_CREATE;
[1856]371 ULONG nm, ulM = 1, total = 0, fl;
[1858]372 CHAR wildcard[CCHMAXPATH];
[551]373 register INT len;
374 APIRET rc, prc;
[1858]375 BOOL isadir = FALSE;
376 BOOL isremote;
377 BOOL includefiles;
[1482]378 ULONG ddepth = DDEPTH;
[1299]379 ULONG drvNum;
380 ULONG flags;
[551]381 static BOOL brokenlan = FALSE, isbroken = FALSE;
[2]382
[1871]383 //DbgMsg(pszSrcFile, __LINE__,"Stubby pciParent %p", pciParent);
[1858]384 if (!pciParent || (INT)pciParent == -1 || !*pciParent->pszFileName
[1832]385 || pciParent->pszFileName == NullStr || !hwndCnr)
[2]386 return FALSE;
[1871]387#if 0
[1856]388 if (!fNoFleshDbgMsg)
389 DbgMsg(pszSrcFile, __LINE__, "Stubby pciParent %p pszFileName %s", pciParent, pciParent->pszFileName); // 2015-08-03 SHL FIXME debug
[1871]390#endif
[1856]391 // Build wildcard
[730]392 len = strlen(pciParent->pszFileName);
[1858]393 memcpy(wildcard, pciParent->pszFileName, len + 1);
394 if (wildcard[len - 1] != '\\')
395 wildcard[len++] = '\\';
396 wildcard[len++] = '*';
397 wildcard[len] = 0;
[2]398
[1858]399 // 2015-08-19 SHL FIXME to know how this can happen
400 if (!isalpha(*wildcard) || wildcard[1] != ':' || wildcard[2] != '\\') {
401 MakeFullName(wildcard);
[1871]402 //DbgMsg(pszSrcFile, __LINE__, "Stubby MakeFullName returned %s", wildcard); // 2015-08-19 SHL FIXME debug
[1858]403 }
[1299]404 drvNum = toupper(*pciParent->pszFileName) - 'A';
405 flags = driveflags[drvNum];
[1858]406 if (!isalpha(*wildcard) ||
407 wildcard[1] != ':' ||
408 wildcard[2] != '\\' || ((flags & DRIVE_IGNORE)))
[1856]409 return FALSE; // Not a directory or ignore requested
[2]410
[1856]411 includefiles = flags & DRIVE_INCLUDEFILES ? TRUE : fFilesInTree;
[2]412
[1856]413 isremote = flags & DRIVE_REMOTE ? TRUE : FALSE;
[2]414
[551]415 if (isremote) {
416 if (fRemoteBug) {
417 if (brokenlan) {
[1858]418 ddepth = (ULONG)-1;
[551]419 ddepth--;
[2]420 }
[761]421 ulM = 1;
[2]422 }
423 }
[551]424 else if (isbroken)
[2]425 ddepth = 14;
426
[1482]427 if (!fRemoteBug)
[1856]428 ulM = ddepth <= DDEPTH ? ddepth : 1;
[2]429
430 nm = ulM;
431
432 DosError(FERR_DISABLEHARDERR);
[1856]433
434 fl = includefiles ? FILE_DIRECTORY : MUST_HAVE_DIRECTORY;
435
[1871]436 //DbgMsg(pszSrcFile, __LINE__, "Stubby DosFindFirst(%s)", wildcard); // 2015-08-19 SHL FIXME debug
[1858]437
438 rc = DosFindFirst(wildcard,
[847]439 &hDir,
440 FILE_NORMAL | fl |
441 FILE_READONLY | FILE_ARCHIVED |
442 FILE_SYSTEM | FILE_HIDDEN,
443 &ffb, ulM * sizeof(FILEFINDBUF3), &nm, FIL_STANDARD);
[761]444 if (ulM == 1 && !rc) {
[1856]445 // Loop looking for 1st directory (or file)
[2]446 do {
447 pffb = &ffb[0];
[551]448 if (!includefiles && !(pffb->attrFile & FILE_DIRECTORY) && !brokenlan) {
[1856]449 // Find returned file when only directories requested
[551]450 brokenlan = TRUE;
[1858]451 ddepth = (ULONG)-1;
[551]452 ddepth--;
453 if (!NoBrokenNotify) {
454 prc = saymsg(MB_YESNO | MB_ICONEXCLAMATION,
455 HWND_DESKTOP,
456 GetPString(IDS_LANERRORTITLETEXT),
457 GetPString(IDS_LANERRORTEXT));
458 if (prc == MBID_NO) {
459 saymsg(MB_ENTER,
460 HWND_DESKTOP,
461 GetPString(IDS_LANERROR2TITLETEXT),
462 GetPString(IDS_LANERROR2TEXT));
[847]463 NoBrokenNotify = 255;
[1505]464 PrfWriteProfileData(fmprof, FM3Str, "NoBrokenNotify",
[551]465 &NoBrokenNotify, sizeof(ULONG));
466 }
467 }
468 else {
469 NoBrokenNotify--;
[1505]470 PrfWriteProfileData(fmprof, FM3Str, "NoBrokenNotify",
[551]471 &NoBrokenNotify, sizeof(ULONG));
472 }
[2]473 }
[1856]474
[515]475 if (*pffb->achName &&
[551]476 (includefiles || (pffb->attrFile & FILE_DIRECTORY)) &&
477 (pffb->achName[0] != '.' ||
[515]478 (pffb->achName[1] &&
[551]479 (pffb->achName[1] != '.' || pffb->achName[2])))) {
[1856]480 // Got directory other than . or .. (or a file)
[551]481 DosFindClose(hDir);
482 isadir = TRUE;
483 goto Interruptus;
[2]484 }
[761]485 nm = 1;
[2]486 DosError(FERR_DISABLEHARDERR);
[1856]487 } while (++total < ddepth && !(rc = (DosFindNext(hDir,
488 &ffb,
489 sizeof(FILEFINDBUF3),
490 &nm))));
491 DosFindClose(hDir);
492
[730]493 if (toupper(*pciParent->pszFileName) > 'B' &&
[751]494 (*(pciParent->pszFileName + 1)) == ':' &&
[730]495 (*(pciParent->pszFileName + 2)) == '\\' && !(*(pciParent->pszFileName + 3))) {
[2]496
[1856]497 // Searching root of hard or remote drive and find reported error
[2]498 CHAR s[132];
499 sprintf(s,
[551]500 GetPString(IDS_NOSUBDIRSTEXT),
[730]501 total, toupper(*pciParent->pszFileName));
[551]502 if (rc && rc != ERROR_NO_MORE_FILES)
[1858]503 sprintf(&s[strlen(s)], GetPString(IDS_SEARCHERRORTEXT), rc, wildcard);
[847]504 else if (ddepth < 16)
[551]505 brokenlan = TRUE;
[2]506 Notify(s);
507 }
[1856]508 goto None; // Done
[2]509 }
[551]510 if (!rc) {
[2]511 DosFindClose(hDir);
[551]512 if (nm) {
[1353]513 PBYTE fb = (PBYTE)&ffb[0];
[551]514 for (len = 0; len < nm; len++) {
[847]515 pffb = (PFILEFINDBUF3) fb;
[551]516 if (!includefiles && !(pffb->attrFile & FILE_DIRECTORY)) {
[1856]517 // Got file(s), but did not ask for files
[551]518 if (!isbroken) {
519 isbroken = TRUE;
520 if (!NoBrokenNotify) {
521 prc = saymsg(MB_YESNO | MB_ICONEXCLAMATION,
522 HWND_DESKTOP,
523 GetPString(IDS_FSDERRORTITLETEXT),
524 GetPString(IDS_FSDERRORTEXT),
[1471]525 isremote ? GetPString(IDS_REMOTETEXT) :
526 GetPString(IDS_LOCALTEXT),
[1858]527 *wildcard);
[551]528 if (prc == MBID_NO) {
529 saymsg(MB_ENTER,
530 HWND_DESKTOP,
531 GetPString(IDS_FSDERROR2TITLETEXT),
532 GetPString(IDS_FSDERROR2TEXT));
[847]533 NoBrokenNotify = 255;
[1505]534 PrfWriteProfileData(fmprof, FM3Str, "NoBrokenNotify",
[551]535 &NoBrokenNotify, sizeof(ULONG));
536 }
537 }
538 else {
539 NoBrokenNotify--;
[1505]540 PrfWriteProfileData(fmprof, FM3Str, "NoBrokenNotify",
[551]541 &NoBrokenNotify, sizeof(ULONG));
542 }
[1856]543 } // if !broken
544 } // if !directory
545
[551]546 if (*pffb->achName &&
547 (includefiles || (pffb->attrFile & FILE_DIRECTORY)) &&
[1856]548 ((pffb->achName[0] && pffb->achName[0] != '.') ||
549 (pffb->achName[1] &&
550 (pffb->achName[1] != '.' || pffb->achName[2]))))
551 {
[1871]552 // Got directory other than . or .. (or a file)
[551]553 isadir = TRUE;
554 break;
555 }
556 fb += pffb->oNextEntryOffset;
[1353]557 } // for
[2]558
[551]559 Interruptus:
[2]560
[551]561 if (isadir) {
[2]562
[1856]563 // Insert CNRITEM for selected directory (or file)
[1471]564 PCNRITEM pci;
[2]565
[1471]566 if (WinIsWindow((HAB)0, hwndCnr)) {
567 pci = WinSendMsg(hwndCnr,
568 CM_ALLOCRECORD,
569 MPFROMLONG(EXTRA_RECORD_BYTES), MPFROMLONG(1));
570 if (!pci) {
571 Win_Error(hwndCnr, HWND_DESKTOP, __FILE__, __LINE__,
572 GetPString(IDS_RECORDALLOCFAILEDTEXT));
573 }
574 else {
[1871]575 RECORDINSERT ri;
576 CHAR szBuffer[CCHMAXPATH + 14];
577 CHAR *p;
578 HPOINTER hptr;
579
580 p = strchr(wildcard, '*');
581 *p = 0;;
582 BldFullPathName(szBuffer, wildcard, pffb->achName);
583 pci->pszFileName = xstrdup(szBuffer, pszSrcFile, __LINE__); //NullStr; // 2015-08-19 SHL FIXME to doc why
584 p = strrchr(pci->pszFileName, '\\');
585 p++;
586 pci->pszDisplayName = p; //NullStr;
587 pci->rc.pszIcon = pci->pszDisplayName;
588 if (fForceUpper)
589 strupr(pci->pszFileName);
590 else if (fForceLower)
591 strlwr(pci->pszFileName);
592
593 flags = driveflags[toupper(*pci->pszFileName) - 'A'];
594
595 // get an icon to use with it
596 if (pffb->attrFile & FILE_DIRECTORY) {
597 // is directory
598 if (fNoIconsDirs ||
599 (flags & DRIVE_NOLOADICONS) ||
600 !isalpha(*pci->pszFileName)) {
601 hptr = (HPOINTER) 0;
602 }
603 else
604 hptr = WinLoadFileIcon(pci->pszFileName, FALSE);
605 }
606 else {
607 // is file
608 if (fNoIconsFiles ||
609 (flags & DRIVE_NOLOADICONS) ||
610 !isalpha(*pci->pszFileName)) {
611 hptr = (HPOINTER) 0;
612 }
613 else
614 hptr = WinLoadFileIcon(pci->pszFileName, FALSE);
615
616 if (!hptr || IsDefaultIcon(hptr))
617 hptr = IDFile(pci->pszFileName);
618 }
619
620 if (!hptr) {
621 hptr = pffb->attrFile & FILE_DIRECTORY ?
622 hptrDir : pffb->attrFile & FILE_SYSTEM ?
623 hptrSystem : pffb->attrFile & FILE_HIDDEN ?
624 hptrHidden : pffb->attrFile & FILE_READONLY ?
625 hptrReadonly : hptrFile;
626 }
627 pci->rc.hptrIcon = hptr;
[1471]628 memset(&ri, 0, sizeof(RECORDINSERT));
629 ri.cb = sizeof(RECORDINSERT);
[1858]630 ri.pRecordOrder = (PRECORDCORE)CMA_END;
631 ri.pRecordParent = (PRECORDCORE)pciParent;
632 ri.zOrder = (ULONG)CMA_TOP;
[1471]633 ri.cRecordsInsert = 1;
[1856]634 ri.fInvalidateRecord = TRUE;
[1871]635#if 0 // 2015-08-03 SHL FIXME debug
[1858]636 if (pci->pszFileName == NullStr)
637 DbgMsg(pszSrcFile, __LINE__, "Stubby CM_INSERTRECORD %p \"%s\" %.255s", pci, pci->pszFileName, pffb->achName);
[1871]638#endif
639 if (!WinSendMsg(hwndCnr,
[1471]640 CM_INSERTRECORD, MPFROMP(pci), MPFROMP(&ri))) {
[1856]641 // Assume busy and try again
[1471]642 DosSleep(50); //05 Aug 07 GKY 100
[1856]643 WinSetFocus(HWND_DESKTOP, hwndCnr);
[1871]644 if (WinIsWindow((HAB)0, hwndCnr)) {
645#if 0
[1858]646 if (!fNoFleshDbgMsg) {
[1871]647 // 2015-08-03 SHL FIXME debug
648 //if (pci->pszFileName == NullStr)
649 // DbgMsg(pszSrcFile, __LINE__, "Stubby CM_INSERTRECORD pci %p pszFileName \"%s\"", pci, pci->pszFileName); // 2015-08-03 SHL FIXME debug
650 }
651#endif
[1471]652 if (!WinSendMsg(hwndCnr,
653 CM_INSERTRECORD, MPFROMP(pci), MPFROMP(&ri))) {
654 Win_Error(hwndCnr, HWND_DESKTOP, __FILE__, __LINE__,
655 GetPString(IDS_RECORDINSERTFAILEDTEXT));
656 FreeCnrItem(hwndCnr, pci);
657 }
[1871]658 else
[1471]659 ok = TRUE;
660 }
661 }
662 else
[1856]663 ok = TRUE;
[1471]664 }
665 }
[1856]666 } // if isadir
[2]667 }
[1864]668 } // if !rc
669 else if (toupper(*wildcard) > 'B' && wildcard[1] == ':' && wildcard[2] == '\\' &&
[1865]670 wildcard[3] == '*' && !wildcard[4]) {
[1864]671 // Is root and no subdirectories
672 CHAR s[162];
[1865]673
[1864]674 sprintf(s,
[1865]675 GetPString(IDS_NOSUBDIRS2TEXT),
676 nm,
677 toupper(*pciParent->pszFileName),
678 isremote ? GetPString(IDS_NOSUBDIRS3TEXT) : NullStr);
[1864]679 Notify(s);
[2]680 }
[1858]681 else if (toupper(*wildcard) > 'B' && rc != ERROR_NO_MORE_FILES) {
[1856]682 // Find for remote or hard drive failed with error
[2]683 CHAR s[CCHMAXPATH + 80];
[1858]684 sprintf(s, GetPString(IDS_SEARCHERRORTEXT), rc, wildcard);
[2]685 Notify(s);
686 }
687
688None:
689
690 DosError(FERR_DISABLEHARDERR);
[1471]691 return ok;
[1856]692} // Stubby
693
694// Stubby/Flesh/Unflesh work list item
695
696typedef struct {
697 LIST2 list;
698 HWND hwndCnr;
699 PCNRITEM pci;
700 FLESHWORKACTION action;
701} FLESHWORKITEM;
702typedef FLESHWORKITEM *PFLESHWORKITEM;
703
704// Stubby/Flesh/Unflesh work list
705LIST2 FleshWorkList;
706
707HMTX hmtxFleshWork;
708HEV hevFleshWorkListChanged;
709
710/**
[1858]711 * Check work list item pci matches passed pci
[1856]712 */
713
714BOOL WorkListItemMatches(PLIST2 item, PVOID data)
715{
716 return ((PFLESHWORKITEM)data)->pci == ((PFLESHWORKITEM)item)->pci;
[2]717}
[793]718
[1856]719/**
720 * Delete stale items from flesh queue
721 */
722
723VOID DeleteStaleFleshWorkListItems(PCNRITEM pci)
724{
725 FLESHWORKITEM match;
726 PLIST2 item;
727
728 match.pci = pci;
729
730 for (;;) {
731 item = List2Search(&FleshWorkList, WorkListItemMatches, &match);
732 if (!item)
733 break;
[1871]734 //DbgMsg(pszSrcFile, __LINE__, "DeleteStaleFleshWorkListItems deleting %p %s", pci, pci->pszFileName ? pci->pszFileName : "(null)"); // 2015-08-03 SHL FIXME debug
[1856]735 List2Delete(&FleshWorkList, item);
736 xfree(item, pszSrcFile, __LINE__);
737 }
738}
739
740/**
741 * Add item to flesh work list
742 * eUnFlesh requests get special handling
743 * eFlesh etc. items for the same CNRITEM are considered stale and are
744 * deleted because eUnFlesh will free the CNRITEM associated with the item
745 * before the work list item is processed
746 */
747
[1865]748#ifndef AddFleshWorkRequest // 2015-08-03 SHL FIXME debug
[1856]749BOOL AddFleshWorkRequest(HWND hwndCnr, PCNRITEM pci, FLESHWORKACTION action)
750#else
751BOOL AddFleshWorkRequestDbg(HWND hwndCnr, PCNRITEM pci, FLESHWORKACTION action, PCSZ pszSrcFile_, UINT uSrcLineNo)
752#endif
753{
754 PFLESHWORKITEM item = xmallocz(sizeof(FLESHWORKITEM), pszSrcFile, __LINE__);
755 item->hwndCnr = hwndCnr;
756 item->pci = pci;
757 item->action= action;
758
[1858]759 if (fAmQuitting)
760 return FALSE;
[1856]761
762 // 2015-08-03 SHL FIXME debug
[1858]763#if 0 // 2015-08-13 SHL FIXME to be gone
[1856]764 {
765 static PSZ itemNames[] = {
766 "eStubby", "eFlesh", "eFleshEnv", "eUnFlesh"
767 };
768
769# ifdef AddFleshWorkRequest
770 if (!pci || (INT)pci == -1) {
771 Runtime_Error(pszSrcFile, __LINE__, "AddFleshWorkRequest called with action %s pci %p by %s:%u",
772 itemNames[item->action],
773 pci,
[1858]774 pszSrcFile_, uSrcLineNo);
[1856]775 }
776 else if (!pci->pszFileName) {
777 Runtime_Error(pszSrcFile, __LINE__, "AddFleshWorkRequest call with action %s pci %p pszFileName (null) by %s:%u",
778 itemNames[item->action],
779 pci,
[1858]780 pszSrcFile_, uSrcLineNo);
[1856]781 }
782 else if (!fNoFleshDbgMsg) {
783 DbgMsg(pszSrcFile, __LINE__, "AddFleshWorkRequest called with action %s pci %p pszFileName %s by %s:%u",
784 itemNames[item->action],
785 pci,
786 pci->pszFileName,
787 pszSrcFile_, uSrcLineNo); // 2015-08-03 SHL FIXME debug
788 }
789#else
790 if (!pci || (INT)pci == -1) {
791 Runtime_Error(pszSrcFile, __LINE__, "AddFleshWorkRequest call with action %s pci %p",
792 itemNames[item->action],
[1858]793 pci);
[1856]794 }
795 else if (!pci->pszFileName) {
796 Runtime_Error(pszSrcFile, __LINE__, "AddFleshWorkRequest called with action %s pci %p pszFileName (null)",
797 itemNames[item->action],
[1858]798 pci);
[1856]799 }
800 else if (!fNoFleshDbgMsg) {
801 DbgMsg(pszSrcFile, __LINE__, "AddFleshWorkRequest action %s pci %p pszFileName %s",
802 itemNames[item->action],
803 pci,
804 pci->pszFileName); // 2015-08-03 SHL FIXME debug
805 }
806#endif
[1858]807 }
[1856]808#endif
809
[1860]810 xDosRequestMutexSem(hmtxFleshWork, SEM_INDEFINITE_WAIT);
[1856]811
812 // Delete stale requests
[1858]813 if (item->action == eUnFlesh)
[1856]814 DeleteStaleFleshWorkListItems(pci);
815
816 List2Append(&FleshWorkList, (PLIST2)item);
817
[1860]818 xDosReleaseMutexSem(hmtxFleshWork);
819 xDosPostEventSem(hevFleshWorkListChanged);
[1856]820
821 return TRUE;
822}
823
824/**
825 * Return TRUE if work list empty
826 * Advisory only
827 */
828
829BOOL IsFleshWorkListEmpty()
830{
831 return FleshWorkList.next == NULL;
832}
833
834/**
[1858]835 * Check if pci pathname is parent of child path name
836 * @param data is child path name
[1860]837 * @return TRUE if is work item path is parent of given path
[1858]838 */
839
840BOOL IsParentOfChildPath(PLIST2 item, PVOID data)
841{
842 UINT c;
843 if (!((PFLESHWORKITEM)item)->pci->pszFileName) {
[1861]844 Runtime_Error(pszSrcFile, __LINE__, "IsParentOfChildPath called with pci %p pszFileName (null)", ((PFLESHWORKITEM)item)->pci);
[1858]845 return FALSE;
846 }
847 c = strlen(((PFLESHWORKITEM)item)->pci->pszFileName);
[1865]848 // 2015-08-23 SHL FIXME to not trap for Gregg
849 return strncmp(((PFLESHWORKITEM)item)->pci->pszFileName, (PCSZ)data, c) == 0;
[1858]850}
851
852/**
853 * Wait until work list empty or until dependent items removed from list
[1856]854 * Advisory only
[1858]855 * @parse pszFileName is dependent pathName
[1856]856 */
857
[1865]858#ifndef WaitFleshWorkListEmpty // 2015-08-03 SHL FIXME debug
[1874]859VOID WaitFleshWorkListEmpty(PCSZ pszDirName, ULONG ulSleep)
[1856]860#else
[1874]861VOID WaitFleshWorkListEmptyDbg(PCSZ pszDirName, ULONG ulSleep, PCSZ pszSrcFile_, UINT uSrcLineNo_)
[1856]862#endif
863{
[1858]864 APIRET rc;
865 PFLESHWORKITEM item;
[1856]866 INT tid = GetTidForThread();
[1860]867 BOOL pathSaved = FALSE;
[1867]868 BOOL waited;
[1860]869 PCSZ pszSavedFleshFocusPath;
[1873]870 INT rcCount = 0;
[1856]871
872 if (tid == 1 || tid == tidFleshWorkListThread) {
873# ifdef WaitFleshWorkListEmpty
874 Runtime_Error(pszSrcFile, __LINE__, "WaitFleshWorkListEmpty called with worklist %sempty by tid %u at %s:%u", IsFleshWorkListEmpty() ? "" : "not ", tid, pszSrcFile_, uSrcLineNo_);
875# else
876 Runtime_Error(pszSrcFile, __LINE__, "WaitFleshWorkListEmpty called by tid %u", tid);
877# endif
878 return; // Avoid hang
879 }
[1871]880#if 0
[1856]881 else if (IsFleshWorkListEmpty()) {
882# ifdef WaitFleshWorkListEmpty
[1858]883 DbgMsg(pszSrcFile, __LINE__, "WaitFleshWorkListEmpty called with worklist empty at %s:%u", pszSrcFile_, uSrcLineNo_);
[1856]884# else
[1858]885 DbgMsg(pszSrcFile, __LINE__, "WaitFleshWorkListEmpty called with work list empty");
[1856]886# endif
887 }
[1871]888#endif
[1856]889
890 // Can not wait if call from thread 1 or FleshWorkListThread
[1867]891 for (waited = FALSE; !IsFleshWorkListEmpty(); waited = TRUE) {
[1858]892
893#if 0 // 2015-08-19 SHL FIXME debug
[1856]894# ifdef WaitFleshWorkListEmpty
895 if (!fNoFleshDbgMsg)
[1858]896 DbgMsg(pszSrcFile, __LINE__, "WaitFleshWorkListEmpty called with work list not empty by %s:%u", pszSrcFile_, uSrcLineNo_); // 2015-08-07 SHL FIXME debug
[1856]897# else
898 if (!fNoFleshDbgMsg)
[1858]899 DbgMsg(pszSrcFile, __LINE__, "WaitFleshWorkListEmpty called with work list not empty"); // 2015-08-07 SHL FIXME debug
[1856]900# endif
[1858]901#endif // 2015-08-19 SHL FIXME debug
902
903 // 2015-08-13 SHL
904 if (fAmQuitting)
905 return;
906
[1860]907 // Just wait for dependents to be gone if path name given
908 if (pszDirName) {
909 rc = xDosRequestMutexSem(hmtxFleshWork, SEM_INDEFINITE_WAIT);
[1873]910 if (rc) {
911 rcCount++;
912 if (rcCount < 6)
913 continue; // Maybe should return ???
914 else {
915 Dos_Error(MB_CANCEL, rc, HWND_DESKTOP, pszSrcFile, __LINE__,
916 PCSZ_DOSREQUESTMUTEXSEM);
917 return;
918 }
[1860]919
[1873]920 }
921
[1860]922 if (!pathSaved) {
923 // Give priority to work items for parents of this path
924 pathSaved = TRUE;
925 pszSavedFleshFocusPath = pszFleshFocusPath;
926 pszFleshFocusPath = pszDirName;
[1858]927 }
928
[1860]929 item = (PFLESHWORKITEM)List2Search(&FleshWorkList, IsParentOfChildPath, (PVOID)pszDirName);
[1858]930
[1860]931 xDosReleaseMutexSem(hmtxFleshWork);
[1873]932 rcCount = 0;
[1858]933
[1867]934 if (!item) {
935 if (waited)
[1874]936 DosSleep(ulSleep); // Let PM do some work
[1858]937 break; // Dependents gone from work list
[1867]938 }
[1860]939 } // if pszDirName
[1874]940 DosSleep(ulSleep);
[1867]941 } // for
[1858]942
[1865]943 if (pathSaved) {
[1860]944 xDosRequestMutexSem(hmtxFleshWork, SEM_INDEFINITE_WAIT);
945 pszFleshFocusPath = pszSavedFleshFocusPath;
946 xDosReleaseMutexSem(hmtxFleshWork);
947 }
[1858]948
[1856]949}
950
951/**
952 * Set focus drive to optimize work list processing
953 * @param chDriveLetter is upper case drive letter (A-Z)
954 */
955
[1860]956VOID SetFleshFocusPath(PCSZ pszPath) {
957 PCSZ pszOld;
958 PCSZ pszNew = strdup(pszPath);
959 xDosRequestMutexSem(hmtxFleshWork, SEM_INDEFINITE_WAIT);
960 pszOld = pszFleshFocusPath;
961 pszFleshFocusPath = pszNew;
962 xDosReleaseMutexSem(hmtxFleshWork);
963 if (pszOld)
964 xfree((PVOID)pszOld, pszSrcFile, __LINE__);
[1871]965 //DbgMsg(pszSrcFile, __LINE__, "SetFleshFocusPath focus path set to %s", pszFleshFocusPath); // 2015-08-03 SHL FIXME debug
[1856]966
967}
968
969/**
970 * Run Flesh, UnFlesh, FleshEnv, Stubby for directory for items in work list
971 */
972
973VOID FleshWorkThread(PVOID arg)
974{
975 HAB thab;
976 HMQ hmq = (HMQ)0;
977
978 // 2015-08-07 SHL FIXME to be gone
979 static INT ProcessDirCount = 0;
980
981 DosError(FERR_DISABLEHARDERR);
982
983# ifdef FORTIFY
984 Fortify_EnterScope();
985# endif
986
987 thab = WinInitialize(0);
988 if (thab) {
989 hmq = WinCreateMsgQueue(thab, 0);
990 if (hmq) {
991 IncrThreadUsage();
992 priority_normal();
993
[1858]994 // process list entries until time to die
995 for (;!fAmQuitting;) {
[1856]996
997 PFLESHWORKITEM item;
998
999 // 2015-08-07 SHL FIXME to use SMPSafe...
[1860]1000 xDosRequestMutexSem(hmtxFleshWork, SEM_INDEFINITE_WAIT);
[1856]1001
1002 // 2015-08-14 SHL
1003 // Get next work list item and remove from list
[1860]1004 // If focus path set, process parents of focus path first
1005 if (pszFleshFocusPath) {
1006 item = (PFLESHWORKITEM)List2Search(&FleshWorkList, IsParentOfChildPath, (PVOID)pszFleshFocusPath);
1007 if (!item) {
1008 xfree((PSZ)pszFleshFocusPath, pszSrcFile, __LINE__);
1009 pszFleshFocusPath = NULL; // Revert to normal
1010 }
[1856]1011 else
1012 List2Delete(&FleshWorkList, (PLIST2)item);
1013 }
1014 else
1015 item = NULL;
1016
1017 if (!item)
1018 item = (PFLESHWORKITEM)List2DeleteFirst(&FleshWorkList);
1019
[1860]1020 xDosReleaseMutexSem(hmtxFleshWork);
[1856]1021
[1858]1022 // Wait for new items to be added to list
[1856]1023 if (!item) {
[1871]1024 ULONG ul;
1025#if 0
[1856]1026 if (!fNoFleshDbgMsg)
1027 DbgMsg(pszSrcFile, __LINE__, "FleshWorkThread work list empty - waiting"); // 2015-08-03 SHL FIXME debug
[1871]1028#endif
1029 xDosWaitEventSem(hevFleshWorkListChanged, SEM_INDEFINITE_WAIT);
1030 xDosResetEventSem(hevFleshWorkListChanged, &ul);
1031#if 0
[1856]1032 if (!fNoFleshDbgMsg)
1033 DbgMsg(pszSrcFile, __LINE__, "FleshWorkThread work hev posted"); // 2015-08-03 SHL FIXME debug
[1871]1034#endif
1035 continue;
[1856]1036 }
1037
[1871]1038 if (WinIsWindow((HAB)0, item->hwndCnr)) {
1039#if 0 // 2015-08-07 SHL FIXME debug
[1856]1040 {
1041 static PSZ itemNames[] = {
1042 "eStubby", "eFlesh", "eFleshEnv", "eUnFlesh"
1043 };
1044
1045 PCNRITEM pci = item->pci;
1046 if (!fNoFleshDbgMsg) {
1047 DbgMsg(pszSrcFile, __LINE__, "FleshWorkThread action %s pci %p pszFileName %s",
1048 itemNames[item->action],
1049 pci,
1050 pci && (INT)pci != -1 ?
1051 (pci->pszFileName ? pci->pszFileName : "(nullname)") :
1052 "(nullpci)"); // 2015-08-03 SHL FIXME debug
1053 }
1054 }
1055#endif
1056
1057 switch (item->action) {
[1871]1058 case eUnFlesh:
1059 UnFlesh(item->hwndCnr, item->pci);
[1856]1060 break;
1061 case eFleshEnv:
1062 FleshEnv(item->hwndCnr, item->pci);
1063 break;
1064 case eStubby:
1065 // DbgMsg(pszSrcFile, __LINE__, "FleshWorkThread pci %p pszFileName %s", stubbyArgs->pci, stubbyArgs->pci->pszFileName); // 2015-08-03 SHL FIXME debug
[1871]1066 priority_bumped();
1067 Stubby(item->hwndCnr, item->pci);
1068 priority_normal();
[1865]1069 break;
[1856]1070 case eFlesh:
1071 if (Flesh(item->hwndCnr, item->pci)) {
1072 // 2015-08-06 SHL FIXME to report?
1073 }
1074 break;
1075 default:
1076 Runtime_Error(pszSrcFile, __LINE__, "item %u unexpected", item->action);
1077 } // switch
1078
1079
1080 } // if window
1081
1082 xfree(item, pszSrcFile, __LINE__);
1083
1084 } // for
1085
1086 WinDestroyMsgQueue(hmq);
1087 }
1088 DecrThreadUsage();
1089 WinTerminate(thab);
1090 }
1091
1092 ProcessDirCount++;
1093 // DbgMsg(pszSrcFile, __LINE__, "ProcessDirCount %i FixedVolume %i", ProcessDirCount, FixedVolume);
1094 if (ProcessDirCount >= FixedVolume) {
1095 ProcessDirCount = 0;
1096 FixedVolume = 0;
1097 }
1098
1099# ifdef FORTIFY
1100 Fortify_LeaveScope();
1101# endif
1102
1103}
1104
1105/**
1106 * Allocate resources and start FleshWorkThread
1107 * @return TRUE if OK
1108 */
1109
1110BOOL StartFleshWorkThread()
1111{
1112 APIRET rc = DosCreateMutexSem(NULL, &hmtxFleshWork, 0L /* Not shared */, FALSE /* Not owned */);
1113 if (rc) {
1114 Dos_Error(MB_CANCEL, rc, HWND_DESKTOP, pszSrcFile, __LINE__,
1115 PCSZ_DOSCREATEMUTEXSEM);
1116 return FALSE;
1117 }
1118
[1860]1119 rc = xDosCreateEventSem(NULL, &hevFleshWorkListChanged, 0 /* Not shared */, FALSE /* Reset */);
1120 if (rc)
1121 return FALSE; // Give up
[1871]1122#if 0
1123 /*DbgMsg is time consuming
[1856]1124 define FM2_NO_FLESH_DBGMSG to suppress
1125 2015-08-09 SHL FIXME to be gone
[1871]1126 */
[1856]1127
1128 fNoFleshDbgMsg = getenv("FM2_NO_FLESH_DBGMSG") != NULL;
[1871]1129#endif
[1856]1130 tidFleshWorkListThread = xbeginthread(FleshWorkThread,
1131 65536,
1132 NULL,
1133 pszSrcFile, __LINE__);
1134 return tidFleshWorkListThread != -1;
1135
1136}
1137
1138#pragma alloc_text(FLESH,Flesh,FleshEnv,UnFlesh,Stubby,FleshWorkThread,StartFleshWorkThread,AddFleshWorkRequest)
Note: See TracBrowser for help on using the repository browser.