source: trunk/dll/flesh.c@ 1858

Last change on this file since 1858 was 1858, checked in by Steven Levine, 10 years ago

Rework FlestWaitForWorkListEmpty to support wait for parents of path
Clean up some obsolete code

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