source: trunk/dll/flesh.c@ 1207

Last change on this file since 1207 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
Line 
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
9 Copyright (c) 2005, 2008 Steven H. Levine
10
11 24 May 05 SHL Rework Win_Error usage
12 25 May 05 SHL Rework for ProcessDirectory
13 28 May 05 SHL Clean while reading code
14 24 Oct 05 SHL Delete obsolete code
15 22 Jul 06 SHL Check more run time errors
16 19 Oct 06 SHL Stubby - correct . and .. detect
17 22 Mar 07 GKY Use QWL_USER
18 01 Aug 07 SHL Sync with CNRITEM mods
19 06 Aug 07 GKY Reduce DosSleep times (ticket 148)
20 20 Aug 07 GKY Move #pragma alloc_text to end for OpenWatcom compat
21 29 Feb 08 GKY Use xfree where appropriate
22
23***********************************************************************/
24
25#include <stdlib.h>
26#include <string.h>
27#include <ctype.h>
28
29#define INCL_DOS
30#define INCL_DOSERRORS
31#define INCL_WIN
32#define INCL_LONGLONG // dircnrs.h
33
34#include "fm3dll.h"
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)
40#include "fm3str.h"
41#include "filldir.h" // FileAttrToString...
42#include "errutil.h" // Dos_Error...
43#include "strutil.h" // GetPString
44#include "flesh.h"
45#include "valid.h" // IsValidDir
46#include "misc.h" // LoadLibPath
47#include "findrec.h" // FindCnrRecord
48#include "notify.h" // Notify
49#include "wrappers.h" // xfree
50
51// Data definitions
52#pragma data_seg(DATA1)
53
54static PSZ pszSrcFile = __FILE__;
55
56#pragma data_seg(GLOBAL1)
57ULONG NoBrokenNotify;
58BOOL fFilesInTree;
59
60BOOL FleshEnv(HWND hwndCnr, PCNRITEM pciParent)
61{
62 PCNRITEM pciL;
63 DIRCNRDATA *dcd;
64 CHAR path[CCHMAXPATH + 12],
65 fullpath[CCHMAXPATH + 12], *env, *p, *pp, *var = NULL;
66
67 if (!pciParent || (INT) pciParent == -1 || !hwndCnr)
68 return FALSE;
69 dcd = (DIRCNRDATA *) WinQueryWindowPtr(hwndCnr, QWL_USER);
70 if (!dcd)
71 return FALSE;
72
73 strcpy(path, pciParent->pszFileName + 1);
74 if (stricmp(path, GetPString(IDS_ENVVARSTEXT) + 1))
75 UnFlesh(hwndCnr, pciParent);
76 if (*path) {
77 path[strlen(path) - 1] = 0;
78 if (!stricmp(path, "LIBPATH")) {
79 var = xmalloc(65536, pszSrcFile, __LINE__);
80 if (var)
81 LoadLibPath(var, 65536);
82 env = var;
83 }
84 else
85 env = getenv(path);
86 if (env && *env) {
87 p = env;
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) {
118
119 RECORDINSERT ri;
120
121 pciL = WinSendMsg(hwndCnr,
122 CM_ALLOCRECORD,
123 MPFROMLONG(EXTRA_RECORD_BYTES),
124 MPFROMLONG(1));
125 if (pciL) {
126 pciL->pszFileName = xstrdup(fullpath, pszSrcFile, __LINE__);
127 pciL->rc.pszIcon = pciL->pszFileName;
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;
136 pciL->pszDispAttr = FileAttrToString(pciL->attrFile);
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)))
146 FreeCnrItem(hwndCnr, pciL);
147 }
148 }
149 }
150 }
151 }
152 }
153 xfree(var, pszSrcFile, __LINE__);
154 pciL = (PCNRITEM) WinSendMsg(hwndCnr,
155 CM_QUERYRECORD,
156 MPFROMP(pciParent),
157 MPFROM2SHORT(CMA_FIRSTCHILD, CMA_ITEMORDER));
158 while (pciL && (INT) pciL != -1) {
159 pciL->flags |= (RECFLAGS_NODRAG | RECFLAGS_UNDERENV);
160 WinSendMsg(hwndCnr,
161 CM_INVALIDATERECORD, MPFROMP(&pciL), MPFROM2SHORT(1, 0));
162 pciL = WinSendMsg(hwndCnr,
163 CM_QUERYRECORD,
164 MPFROMP(pciL), MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
165 }
166 }
167 return TRUE;
168}
169
170BOOL Flesh(HWND hwndCnr, PCNRITEM pciParent)
171{
172 PCNRITEM pciL;
173 DIRCNRDATA *dcd;
174 BOOL includefiles = fFilesInTree;
175
176 if (!pciParent || (INT) pciParent == -1 || !hwndCnr)
177 return FALSE;
178 pciL = (PCNRITEM) WinSendMsg(hwndCnr,
179 CM_QUERYRECORD,
180 MPFROMP(pciParent),
181 MPFROM2SHORT(CMA_FIRSTCHILD, CMA_ITEMORDER));
182 if (!pciL || !*pciL->pszFileName) {
183 if (pciL && (INT) pciL != -1)
184 RemoveCnrItems(hwndCnr, pciL, 1, CMA_FREE);
185 dcd = INSTDATA(hwndCnr);
186 if (dcd && dcd->size != sizeof(DIRCNRDATA))
187 dcd = NULL;
188 if (driveflags[toupper(*pciParent->pszFileName) - 'A'] &
189 DRIVE_INCLUDEFILES)
190 includefiles = TRUE;
191 ProcessDirectory(hwndCnr,
192 pciParent,
193 pciParent->pszFileName,
194 includefiles, // filestoo
195 TRUE, // recurse
196 TRUE, // partial
197 NULL, // stop flag
198 dcd,
199 NULL, // total files
200 NULL); // total bytes
201 }
202 return TRUE;
203}
204
205BOOL UnFlesh(HWND hwndCnr, PCNRITEM pciParent)
206{
207 BOOL ret = FALSE;
208 PCNRITEM pciL;
209
210 if (!pciParent || !hwndCnr)
211 return FALSE;
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) {
218 ret = TRUE;
219 RemoveCnrItems(hwndCnr, pciL, 1, CMA_FREE);
220 }
221 else
222 break;
223 }
224 if (ret) {
225 WinSendMsg(hwndCnr,
226 CM_INVALIDATERECORD,
227 MPFROMP(&pciParent),
228 MPFROM2SHORT(1, CMA_ERASE | CMA_REPOSITION));
229 }
230 return ret;
231}
232
233#define DDEPTH 16
234
235BOOL Stubby(HWND hwndCnr, PCNRITEM pciParent)
236{
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
243 BOOL ret = FALSE;
244 FILEFINDBUF3 ffb[DDEPTH];
245 PFILEFINDBUF3 pffb;
246 HDIR hDir = HDIR_CREATE;
247 ULONG nm, ulM = 1, total = 0, fl = MUST_HAVE_DIRECTORY;
248 CHAR str[CCHMAXPATH];
249 register INT len;
250 APIRET rc, prc;
251 BOOL isadir = FALSE, isremote = FALSE, includefiles = fFilesInTree;
252 ULONG ddepth = 3;
253 static BOOL brokenlan = FALSE, isbroken = FALSE;
254
255 if (!pciParent || !*pciParent->pszFileName || !hwndCnr)
256 return FALSE;
257
258 len = strlen(pciParent->pszFileName);
259 memcpy(str, pciParent->pszFileName, len + 1);
260 if (str[len - 1] != '\\')
261 str[len++] = '\\';
262 str[len++] = '*';
263 str[len] = 0;
264
265 if (!isalpha(*str) || str[1] != ':' || str[2] != '\\')
266 MakeFullName(str);
267
268 if (!isalpha(*str) ||
269 str[1] != ':' ||
270 str[2] != '\\' || ((driveflags[toupper(*str) - 'A'] & DRIVE_IGNORE)))
271 return FALSE;
272
273 if (isalpha(*str) && driveflags[toupper(*str) - 'A'] & DRIVE_INCLUDEFILES)
274 includefiles = TRUE;
275
276 if (!isalpha(*str) ||
277 str[1] != ':' ||
278 str[2] != '\\' || ((driveflags[toupper(*str) - 'A'] & DRIVE_REMOTE)))
279 isremote = TRUE;
280
281 if (isremote) {
282 ddepth = 14;
283 if (fRemoteBug) {
284 if (brokenlan) {
285 ddepth = (ULONG) - 1;
286 ddepth--;
287 }
288 ulM = 1;
289 }
290 }
291 else if (isbroken)
292 ddepth = 14;
293
294 if (!isremote || !fRemoteBug)
295 ulM = (ddepth < 16) ? ddepth : 1;
296
297 nm = ulM;
298
299 DosError(FERR_DISABLEHARDERR);
300 if (includefiles)
301 fl = FILE_DIRECTORY;
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);
308 if (ulM == 1 && !rc) {
309 do {
310 pffb = &ffb[0];
311 if (!includefiles && !(pffb->attrFile & FILE_DIRECTORY) && !brokenlan) {
312 brokenlan = TRUE;
313 ddepth = (ULONG) - 1;
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));
325 NoBrokenNotify = 255;
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 }
339 }
340 if (*pffb->achName &&
341 (includefiles || (pffb->attrFile & FILE_DIRECTORY)) &&
342 // Skip . and ..
343 (pffb->achName[0] != '.' ||
344 (pffb->achName[1] &&
345 (pffb->achName[1] != '.' || pffb->achName[2])))) {
346 DosFindClose(hDir);
347 isadir = TRUE;
348 goto Interruptus;
349 }
350 nm = 1;
351 DosError(FERR_DISABLEHARDERR);
352 } while (++total < ddepth && !(rc = (DosFindNext(hDir,
353 &ffb,
354 sizeof(FILEFINDBUF3),
355 &nm))));
356 DosFindClose(hDir);
357 if (toupper(*pciParent->pszFileName) > 'B' &&
358 (*(pciParent->pszFileName + 1)) == ':' &&
359 (*(pciParent->pszFileName + 2)) == '\\' && !(*(pciParent->pszFileName + 3))) {
360
361 CHAR s[132];
362
363 sprintf(s,
364 GetPString(IDS_NOSUBDIRSTEXT),
365 total, toupper(*pciParent->pszFileName));
366 if (rc && rc != ERROR_NO_MORE_FILES)
367 sprintf(&s[strlen(s)], GetPString(IDS_SEARCHERRORTEXT), rc, str);
368 else if (ddepth < 16)
369 brokenlan = TRUE;
370 Notify(s);
371 }
372 goto None;
373 }
374
375 if (!rc) {
376 DosFindClose(hDir);
377 if (nm) {
378
379 register PBYTE fb = (PBYTE) & ffb[0];
380
381 for (len = 0; len < nm; len++) {
382 pffb = (PFILEFINDBUF3) fb;
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));
399 NoBrokenNotify = 255;
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)) &&
417 // Skip . and ..
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;
425 }
426
427 Interruptus:
428
429 if (isadir) {
430
431 PCNRITEM pci;
432
433 pci = WinSendMsg(hwndCnr,
434 CM_ALLOCRECORD,
435 MPFROMLONG(EXTRA_RECORD_BYTES), MPFROMLONG(1));
436 if (!pci) {
437 Win_Error(hwndCnr, HWND_DESKTOP, __FILE__, __LINE__,
438 GetPString(IDS_RECORDALLOCFAILEDTEXT));
439 }
440 else {
441 RECORDINSERT ri;
442 pci->pszFileName = NullStr;
443 pci->pszDisplayName = pci->pszFileName;
444 pci->rc.pszIcon = pci->pszDisplayName;
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))) {
454 DosSleep(50); //05 Aug 07 GKY 100
455 WinSetFocus(HWND_DESKTOP, hwndCnr);
456 if (WinIsWindow((HAB)0, hwndCnr)) {
457 if (!WinSendMsg(hwndCnr,
458 CM_INSERTRECORD, MPFROMP(pci), MPFROMP(&ri))) {
459 Win_Error(hwndCnr, HWND_DESKTOP, __FILE__, __LINE__,
460 GetPString(IDS_RECORDINSERTFAILEDTEXT));
461 FreeCnrItem(hwndCnr, pci);
462 }
463 else
464 ret = TRUE;
465 }
466 }
467 else
468 ret = TRUE;
469 }
470 }
471 else if (toupper(*str) > 'B' && str[1] == ':' && str[2] == '\\' &&
472 !str[3]) {
473
474 CHAR s[162];
475
476 sprintf(s,
477 GetPString(IDS_NOSUBDIRS2TEXT),
478 nm,
479 toupper(*pciParent->pszFileName),
480 (isremote) ? GetPString(IDS_NOSUBDIRS3TEXT) : NullStr);
481 Notify(s);
482 }
483 }
484 }
485 else if (toupper(*str) > 'B' && rc != ERROR_NO_MORE_FILES) {
486
487 CHAR s[CCHMAXPATH + 80];
488
489 sprintf(s, GetPString(IDS_SEARCHERRORTEXT), rc, str);
490 Notify(s);
491 }
492
493None:
494
495 DosError(FERR_DISABLEHARDERR);
496 return ret;
497}
498
499#pragma alloc_text(FLESH,Flesh,FleshEnv,Unflesh,Stubby)
Note: See TracBrowser for help on using the repository browser.