source: trunk/dll/flesh.c@ 1323

Last change on this file since 1323 was 1299, checked in by Gregg Young, 17 years ago

Scan each drive on separate thread (added StubbyScanThread) to speed treecnr scans

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 13.2 KB
RevLine 
[145]1
2/***********************************************************************
3
4 $Id: flesh.c 1299 2008-11-28 23:48:50Z gyoung $
5
6 Flesh
7
8 Copyright (c) 1993-98 M. Kimes
[907]9 Copyright (c) 2005, 2008 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
[145]23
24***********************************************************************/
25
[907]26#include <stdlib.h>
27#include <string.h>
28#include <ctype.h>
29
[2]30#define INCL_DOS
31#define INCL_DOSERRORS
32#define INCL_WIN
[907]33#define INCL_LONGLONG // dircnrs.h
[2]34
[1177]35#include "fm3dll.h"
[1207]36#include "draglist.h" // Data declaration(s)
37#include "notebook.h" // Data declaration(s)
38#include "info.h" // Data declaration(s)
39#include "init.h" // Data declaration(s)
40#include "mainwnd.h" // Data declaration(s)
[907]41#include "fm3str.h"
42#include "filldir.h" // FileAttrToString...
43#include "errutil.h" // Dos_Error...
44#include "strutil.h" // GetPString
[1155]45#include "flesh.h"
46#include "valid.h" // IsValidDir
47#include "misc.h" // LoadLibPath
[1177]48#include "findrec.h" // FindCnrRecord
49#include "notify.h" // Notify
50#include "wrappers.h" // xfree
[2]51
[1207]52// Data definitions
[2]53#pragma data_seg(DATA1)
[340]54
55static PSZ pszSrcFile = __FILE__;
56
[1207]57#pragma data_seg(GLOBAL1)
58ULONG NoBrokenNotify;
59BOOL fFilesInTree;
60
[551]61BOOL FleshEnv(HWND hwndCnr, PCNRITEM pciParent)
[175]62{
[551]63 PCNRITEM pciL;
[2]64 DIRCNRDATA *dcd;
[551]65 CHAR path[CCHMAXPATH + 12],
66 fullpath[CCHMAXPATH + 12], *env, *p, *pp, *var = NULL;
[2]67
[551]68 if (!pciParent || (INT) pciParent == -1 || !hwndCnr)
[2]69 return FALSE;
[574]70 dcd = (DIRCNRDATA *) WinQueryWindowPtr(hwndCnr, QWL_USER);
[551]71 if (!dcd)
[2]72 return FALSE;
73
[730]74 strcpy(path, pciParent->pszFileName + 1);
[551]75 if (stricmp(path, GetPString(IDS_ENVVARSTEXT) + 1))
76 UnFlesh(hwndCnr, pciParent);
77 if (*path) {
[2]78 path[strlen(path) - 1] = 0;
[551]79 if (!stricmp(path, "LIBPATH")) {
80 var = xmalloc(65536, pszSrcFile, __LINE__);
81 if (var)
82 LoadLibPath(var, 65536);
[2]83 env = var;
84 }
85 else
86 env = getenv(path);
[551]87 if (env && *env) {
[2]88 p = env;
[551]89 while (*p) {
90 pp = path;
91 while (*p == ';')
92 p++;
93 while (*p && *p != ';') {
94 *pp = *p;
95 p++;
96 pp++;
97 }
98 *pp = 0;
99 if (*path &&
100 strcmp(path, ".") &&
101 strcmp(path, ".\\") &&
102 strcmp(path, "..") &&
103 strcmp(path, "..\\") &&
104 strncmp(path, ".\\", 2) && strncmp(path, "..\\", 3)) {
105 if (!DosQueryPathInfo(path,
106 FIL_QUERYFULLNAME,
107 fullpath,
108 sizeof(fullpath)) && IsValidDir(fullpath)) {
109 pciL = FindCnrRecord(hwndCnr,
110 fullpath, pciParent, FALSE, FALSE, FALSE);
111 if (pciL) {
112 while (pciL && pciL != (PCNRITEM) - 1 && pciL != pciParent)
113 pciL = WinSendMsg(hwndCnr,
114 CM_QUERYRECORD,
115 MPFROMP(pciL),
116 MPFROM2SHORT(CMA_PARENT, CMA_ITEMORDER));
117 }
118 if (!pciL) {
[2]119
[551]120 RECORDINSERT ri;
[2]121
[551]122 pciL = WinSendMsg(hwndCnr,
123 CM_ALLOCRECORD,
[751]124 MPFROMLONG(EXTRA_RECORD_BYTES),
[551]125 MPFROMLONG(1));
126 if (pciL) {
[730]127 pciL->pszFileName = xstrdup(fullpath, pszSrcFile, __LINE__);
[751]128 pciL->rc.pszIcon = pciL->pszFileName;
[551]129 if (!fNoIconsDirs &&
130 (!isalpha(*fullpath) ||
131 !(driveflags[toupper(*fullpath) - 'A'] &
132 DRIVE_NOLOADICONS)))
133 pciL->rc.hptrIcon = WinLoadFileIcon(fullpath, FALSE);
134 if (!pciL->rc.hptrIcon)
135 pciL->rc.hptrIcon = hptrDir;
136 pciL->attrFile = FILE_DIRECTORY;
[751]137 pciL->pszDispAttr = FileAttrToString(pciL->attrFile);
[551]138 memset(&ri, 0, sizeof(ri));
139 ri.cb = sizeof(ri);
140 ri.pRecordOrder = (PRECORDCORE) CMA_END;
141 ri.pRecordParent = (PRECORDCORE) pciParent;
142 ri.zOrder = (ULONG) CMA_TOP;
143 ri.cRecordsInsert = 1;
144 ri.fInvalidateRecord = FALSE;
145 if (!WinSendMsg(hwndCnr,
146 CM_INSERTRECORD, MPFROMP(pciL), MPFROMP(&ri)))
[751]147 FreeCnrItem(hwndCnr, pciL);
[551]148 }
149 }
150 }
151 }
[2]152 }
153 }
[1009]154 xfree(var, pszSrcFile, __LINE__);
[551]155 pciL = (PCNRITEM) WinSendMsg(hwndCnr,
156 CM_QUERYRECORD,
157 MPFROMP(pciParent),
158 MPFROM2SHORT(CMA_FIRSTCHILD, CMA_ITEMORDER));
159 while (pciL && (INT) pciL != -1) {
[2]160 pciL->flags |= (RECFLAGS_NODRAG | RECFLAGS_UNDERENV);
161 WinSendMsg(hwndCnr,
[551]162 CM_INVALIDATERECORD, MPFROMP(&pciL), MPFROM2SHORT(1, 0));
[2]163 pciL = WinSendMsg(hwndCnr,
[551]164 CM_QUERYRECORD,
165 MPFROMP(pciL), MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
[2]166 }
167 }
168 return TRUE;
169}
170
[551]171BOOL Flesh(HWND hwndCnr, PCNRITEM pciParent)
[166]172{
[551]173 PCNRITEM pciL;
[2]174 DIRCNRDATA *dcd;
[551]175 BOOL includefiles = fFilesInTree;
[2]176
[551]177 if (!pciParent || (INT) pciParent == -1 || !hwndCnr)
[2]178 return FALSE;
[551]179 pciL = (PCNRITEM) WinSendMsg(hwndCnr,
180 CM_QUERYRECORD,
181 MPFROMP(pciParent),
182 MPFROM2SHORT(CMA_FIRSTCHILD, CMA_ITEMORDER));
[730]183 if (!pciL || !*pciL->pszFileName) {
[751]184 if (pciL && (INT) pciL != -1)
185 RemoveCnrItems(hwndCnr, pciL, 1, CMA_FREE);
[2]186 dcd = INSTDATA(hwndCnr);
[166]187 if (dcd && dcd->size != sizeof(DIRCNRDATA))
[2]188 dcd = NULL;
[730]189 if (driveflags[toupper(*pciParent->pszFileName) - 'A'] &
[551]190 DRIVE_INCLUDEFILES)
[2]191 includefiles = TRUE;
192 ProcessDirectory(hwndCnr,
[551]193 pciParent,
[730]194 pciParent->pszFileName,
[736]195 includefiles, // filestoo
196 TRUE, // recurse
197 TRUE, // partial
[924]198 NULL, // stop flag
[736]199 dcd,
[924]200 NULL, // total files
201 NULL); // total bytes
[2]202 }
203 return TRUE;
204}
205
[551]206BOOL UnFlesh(HWND hwndCnr, PCNRITEM pciParent)
[175]207{
[551]208 BOOL ret = FALSE;
[2]209 PCNRITEM pciL;
210
[175]211 if (!pciParent || !hwndCnr)
[2]212 return FALSE;
[551]213 for (;;) {
214 pciL = (PCNRITEM) WinSendMsg(hwndCnr,
215 CM_QUERYRECORD,
216 MPFROMP(pciParent),
217 MPFROM2SHORT(CMA_FIRSTCHILD, CMA_ITEMORDER));
218 if (pciL && (INT) pciL != -1) {
[2]219 ret = TRUE;
[751]220 RemoveCnrItems(hwndCnr, pciL, 1, CMA_FREE);
[2]221 }
222 else
223 break;
224 }
[551]225 if (ret) {
[2]226 WinSendMsg(hwndCnr,
[551]227 CM_INVALIDATERECORD,
228 MPFROMP(&pciParent),
229 MPFROM2SHORT(1, CMA_ERASE | CMA_REPOSITION));
[175]230 }
[2]231 return ret;
232}
233
234#define DDEPTH 16
235
[551]236BOOL Stubby(HWND hwndCnr, PCNRITEM pciParent)
[175]237{
[2]238 /*
239 * this code is full of workarounds for screwed up LANs.
240 * let's hope all the current LAN programmers fall into
241 * a black hole and make way for people who can get it right...
242 */
243
[551]244 BOOL ret = FALSE;
[847]245 FILEFINDBUF3 ffb[DDEPTH];
246 PFILEFINDBUF3 pffb;
[551]247 HDIR hDir = HDIR_CREATE;
[761]248 ULONG nm, ulM = 1, total = 0, fl = MUST_HAVE_DIRECTORY;
[551]249 CHAR str[CCHMAXPATH];
250 register INT len;
251 APIRET rc, prc;
252 BOOL isadir = FALSE, isremote = FALSE, includefiles = fFilesInTree;
[761]253 ULONG ddepth = 3;
[1299]254 ULONG drvNum;
255 ULONG flags;
[551]256 static BOOL brokenlan = FALSE, isbroken = FALSE;
[2]257
[730]258 if (!pciParent || !*pciParent->pszFileName || !hwndCnr)
[2]259 return FALSE;
260
[730]261 len = strlen(pciParent->pszFileName);
262 memcpy(str, pciParent->pszFileName, len + 1);
[551]263 if (str[len - 1] != '\\')
[2]264 str[len++] = '\\';
265 str[len++] = '*';
266 str[len] = 0;
267
[551]268 if (!isalpha(*str) || str[1] != ':' || str[2] != '\\')
[2]269 MakeFullName(str);
270
[1299]271 drvNum = toupper(*pciParent->pszFileName) - 'A';
272 flags = driveflags[drvNum];
[551]273 if (!isalpha(*str) ||
274 str[1] != ':' ||
[1299]275 str[2] != '\\' || ((flags & DRIVE_IGNORE)))
[2]276 return FALSE;
277
[1299]278 //if (isalpha(*str) && // redundant check GKY 11/24/08
279 if (flags & DRIVE_INCLUDEFILES)
[2]280 includefiles = TRUE;
281
[1299]282 /*if (!isalpha(*str) || // redundant check GKY 11/24/08
[551]283 str[1] != ':' ||
[1299]284 str[2] != '\\' || */
285 if (flags & DRIVE_REMOTE)
[2]286 isremote = TRUE;
287
[551]288 if (isremote) {
[2]289 ddepth = 14;
[551]290 if (fRemoteBug) {
291 if (brokenlan) {
292 ddepth = (ULONG) - 1;
293 ddepth--;
[2]294 }
[761]295 ulM = 1;
[2]296 }
297 }
[551]298 else if (isbroken)
[2]299 ddepth = 14;
300
[551]301 if (!isremote || !fRemoteBug)
[847]302 ulM = (ddepth < 16) ? ddepth : 1;
[2]303
304 nm = ulM;
305
306 DosError(FERR_DISABLEHARDERR);
[551]307 if (includefiles)
[2]308 fl = FILE_DIRECTORY;
[847]309 rc = DosFindFirst(str,
310 &hDir,
311 FILE_NORMAL | fl |
312 FILE_READONLY | FILE_ARCHIVED |
313 FILE_SYSTEM | FILE_HIDDEN,
314 &ffb, ulM * sizeof(FILEFINDBUF3), &nm, FIL_STANDARD);
[761]315 if (ulM == 1 && !rc) {
[2]316 do {
317 pffb = &ffb[0];
[551]318 if (!includefiles && !(pffb->attrFile & FILE_DIRECTORY) && !brokenlan) {
319 brokenlan = TRUE;
[847]320 ddepth = (ULONG) - 1;
[551]321 ddepth--;
322 if (!NoBrokenNotify) {
323 prc = saymsg(MB_YESNO | MB_ICONEXCLAMATION,
324 HWND_DESKTOP,
325 GetPString(IDS_LANERRORTITLETEXT),
326 GetPString(IDS_LANERRORTEXT));
327 if (prc == MBID_NO) {
328 saymsg(MB_ENTER,
329 HWND_DESKTOP,
330 GetPString(IDS_LANERROR2TITLETEXT),
331 GetPString(IDS_LANERROR2TEXT));
[847]332 NoBrokenNotify = 255;
[551]333 PrfWriteProfileData(fmprof,
334 FM3Str,
335 "NoBrokenNotify",
336 &NoBrokenNotify, sizeof(ULONG));
337 }
338 }
339 else {
340 NoBrokenNotify--;
341 PrfWriteProfileData(fmprof,
342 FM3Str,
343 "NoBrokenNotify",
344 &NoBrokenNotify, sizeof(ULONG));
345 }
[2]346 }
[515]347 if (*pffb->achName &&
[551]348 (includefiles || (pffb->attrFile & FILE_DIRECTORY)) &&
[515]349 // Skip . and ..
[551]350 (pffb->achName[0] != '.' ||
[515]351 (pffb->achName[1] &&
[551]352 (pffb->achName[1] != '.' || pffb->achName[2])))) {
353 DosFindClose(hDir);
354 isadir = TRUE;
355 goto Interruptus;
[2]356 }
[761]357 nm = 1;
[2]358 DosError(FERR_DISABLEHARDERR);
[847]359 } while (++total < ddepth && !(rc = (DosFindNext(hDir,
360 &ffb,
361 sizeof(FILEFINDBUF3),
362 &nm))));
[2]363 DosFindClose(hDir);
[730]364 if (toupper(*pciParent->pszFileName) > 'B' &&
[751]365 (*(pciParent->pszFileName + 1)) == ':' &&
[730]366 (*(pciParent->pszFileName + 2)) == '\\' && !(*(pciParent->pszFileName + 3))) {
[2]367
368 CHAR s[132];
369
370 sprintf(s,
[551]371 GetPString(IDS_NOSUBDIRSTEXT),
[730]372 total, toupper(*pciParent->pszFileName));
[551]373 if (rc && rc != ERROR_NO_MORE_FILES)
374 sprintf(&s[strlen(s)], GetPString(IDS_SEARCHERRORTEXT), rc, str);
[847]375 else if (ddepth < 16)
[551]376 brokenlan = TRUE;
[2]377 Notify(s);
378 }
379 goto None;
380 }
381
[551]382 if (!rc) {
[2]383 DosFindClose(hDir);
[551]384 if (nm) {
[2]385
[551]386 register PBYTE fb = (PBYTE) & ffb[0];
[2]387
[551]388 for (len = 0; len < nm; len++) {
[847]389 pffb = (PFILEFINDBUF3) fb;
[551]390 if (!includefiles && !(pffb->attrFile & FILE_DIRECTORY)) {
391 if (!isbroken) {
392 isbroken = TRUE;
393 if (!NoBrokenNotify) {
394 prc = saymsg(MB_YESNO | MB_ICONEXCLAMATION,
395 HWND_DESKTOP,
396 GetPString(IDS_FSDERRORTITLETEXT),
397 GetPString(IDS_FSDERRORTEXT),
398 (isremote) ?
399 GetPString(IDS_REMOTETEXT) :
400 GetPString(IDS_LOCALTEXT), *str);
401 if (prc == MBID_NO) {
402 saymsg(MB_ENTER,
403 HWND_DESKTOP,
404 GetPString(IDS_FSDERROR2TITLETEXT),
405 GetPString(IDS_FSDERROR2TEXT));
[847]406 NoBrokenNotify = 255;
[551]407 PrfWriteProfileData(fmprof,
408 FM3Str,
409 "NoBrokenNotify",
410 &NoBrokenNotify, sizeof(ULONG));
411 }
412 }
413 else {
414 NoBrokenNotify--;
415 PrfWriteProfileData(fmprof,
416 FM3Str,
417 "NoBrokenNotify",
418 &NoBrokenNotify, sizeof(ULONG));
419 }
420 }
421 }
422 if (*pffb->achName &&
423 (includefiles || (pffb->attrFile & FILE_DIRECTORY)) &&
[515]424 // Skip . and ..
[551]425 (pffb->achName[0] != '.' || (pffb->achName[1]
426 && (pffb->achName[1] != '.'
427 || pffb->achName[2])))) {
428 isadir = TRUE;
429 break;
430 }
431 fb += pffb->oNextEntryOffset;
[2]432 }
433
[551]434 Interruptus:
[2]435
[551]436 if (isadir) {
[2]437
[1299]438 PCNRITEM pci;
[2]439
[1299]440 if (WinIsWindow((HAB)0, hwndCnr)) {
441 pci = WinSendMsg(hwndCnr,
442 CM_ALLOCRECORD,
443 MPFROMLONG(EXTRA_RECORD_BYTES), MPFROMLONG(1));
444 if (!pci) {
445 Win_Error(hwndCnr, HWND_DESKTOP, __FILE__, __LINE__,
446 GetPString(IDS_RECORDALLOCFAILEDTEXT));
447 }
448 else {
449 RECORDINSERT ri;
450 pci->pszFileName = NullStr;
451 pci->pszDisplayName = pci->pszFileName;
452 pci->rc.pszIcon = pci->pszDisplayName;
453 memset(&ri, 0, sizeof(RECORDINSERT));
454 ri.cb = sizeof(RECORDINSERT);
455 ri.pRecordOrder = (PRECORDCORE) CMA_END;
456 ri.pRecordParent = (PRECORDCORE) pciParent;
457 ri.zOrder = (ULONG) CMA_TOP;
458 ri.cRecordsInsert = 1L;
459 ri.fInvalidateRecord = TRUE;
460 if (!WinSendMsg(hwndCnr,
461 CM_INSERTRECORD, MPFROMP(pci), MPFROMP(&ri))) {
462 DosSleep(50); //05 Aug 07 GKY 100
463 WinSetFocus(HWND_DESKTOP, hwndCnr);
464 if (WinIsWindow((HAB)0, hwndCnr)) {
465 if (!WinSendMsg(hwndCnr,
466 CM_INSERTRECORD, MPFROMP(pci), MPFROMP(&ri))) {
467 Win_Error(hwndCnr, HWND_DESKTOP, __FILE__, __LINE__,
468 GetPString(IDS_RECORDINSERTFAILEDTEXT));
469 FreeCnrItem(hwndCnr, pci);
470 }
471 else
472 ret = TRUE;
473 }
474 }
475 else
476 ret = TRUE;
477 }
478 }
[2]479 }
[551]480 else if (toupper(*str) > 'B' && str[1] == ':' && str[2] == '\\' &&
481 !str[3]) {
[2]482
[551]483 CHAR s[162];
[2]484
[551]485 sprintf(s,
486 GetPString(IDS_NOSUBDIRS2TEXT),
487 nm,
[730]488 toupper(*pciParent->pszFileName),
[551]489 (isremote) ? GetPString(IDS_NOSUBDIRS3TEXT) : NullStr);
490 Notify(s);
[2]491 }
492 }
493 }
[551]494 else if (toupper(*str) > 'B' && rc != ERROR_NO_MORE_FILES) {
[2]495
496 CHAR s[CCHMAXPATH + 80];
497
[551]498 sprintf(s, GetPString(IDS_SEARCHERRORTEXT), rc, str);
[2]499 Notify(s);
500 }
501
502None:
503
504 DosError(FERR_DISABLEHARDERR);
505 return ret;
506}
[793]507
508#pragma alloc_text(FLESH,Flesh,FleshEnv,Unflesh,Stubby)
Note: See TracBrowser for help on using the repository browser.