source: trunk/dll/flesh.c@ 1211

Last change on this file since 1211 was 1207, checked in by John Small, 17 years ago

Ticket 187: Move data declarations/definitions out of fm3dll.h

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