source: trunk/dll/flesh.c@ 1155

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

Ticket 187: Draft 1: Functions only

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