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
Line 
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
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 "fm3str.h"
35#include "filldir.h" // FileAttrToString...
36#include "errutil.h" // Dos_Error...
37#include "strutil.h" // GetPString
38#include "flesh.h"
39#include "valid.h" // IsValidDir
40#include "misc.h" // LoadLibPath
41#include "fm3dll.h"
42
43#pragma data_seg(DATA1)
44
45static PSZ pszSrcFile = __FILE__;
46
47BOOL FleshEnv(HWND hwndCnr, PCNRITEM pciParent)
48{
49 PCNRITEM pciL;
50 DIRCNRDATA *dcd;
51 CHAR path[CCHMAXPATH + 12],
52 fullpath[CCHMAXPATH + 12], *env, *p, *pp, *var = NULL;
53
54 if (!pciParent || (INT) pciParent == -1 || !hwndCnr)
55 return FALSE;
56 dcd = (DIRCNRDATA *) WinQueryWindowPtr(hwndCnr, QWL_USER);
57 if (!dcd)
58 return FALSE;
59
60 strcpy(path, pciParent->pszFileName + 1);
61 if (stricmp(path, GetPString(IDS_ENVVARSTEXT) + 1))
62 UnFlesh(hwndCnr, pciParent);
63 if (*path) {
64 path[strlen(path) - 1] = 0;
65 if (!stricmp(path, "LIBPATH")) {
66 var = xmalloc(65536, pszSrcFile, __LINE__);
67 if (var)
68 LoadLibPath(var, 65536);
69 env = var;
70 }
71 else
72 env = getenv(path);
73 if (env && *env) {
74 p = env;
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) {
105
106 RECORDINSERT ri;
107
108 pciL = WinSendMsg(hwndCnr,
109 CM_ALLOCRECORD,
110 MPFROMLONG(EXTRA_RECORD_BYTES),
111 MPFROMLONG(1));
112 if (pciL) {
113 pciL->pszFileName = xstrdup(fullpath, pszSrcFile, __LINE__);
114 pciL->rc.pszIcon = pciL->pszFileName;
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;
123 pciL->pszDispAttr = FileAttrToString(pciL->attrFile);
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)))
133 FreeCnrItem(hwndCnr, pciL);
134 }
135 }
136 }
137 }
138 }
139 }
140 xfree(var, pszSrcFile, __LINE__);
141 pciL = (PCNRITEM) WinSendMsg(hwndCnr,
142 CM_QUERYRECORD,
143 MPFROMP(pciParent),
144 MPFROM2SHORT(CMA_FIRSTCHILD, CMA_ITEMORDER));
145 while (pciL && (INT) pciL != -1) {
146 pciL->flags |= (RECFLAGS_NODRAG | RECFLAGS_UNDERENV);
147 WinSendMsg(hwndCnr,
148 CM_INVALIDATERECORD, MPFROMP(&pciL), MPFROM2SHORT(1, 0));
149 pciL = WinSendMsg(hwndCnr,
150 CM_QUERYRECORD,
151 MPFROMP(pciL), MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
152 }
153 }
154 return TRUE;
155}
156
157BOOL Flesh(HWND hwndCnr, PCNRITEM pciParent)
158{
159 PCNRITEM pciL;
160 DIRCNRDATA *dcd;
161 BOOL includefiles = fFilesInTree;
162
163 if (!pciParent || (INT) pciParent == -1 || !hwndCnr)
164 return FALSE;
165 pciL = (PCNRITEM) WinSendMsg(hwndCnr,
166 CM_QUERYRECORD,
167 MPFROMP(pciParent),
168 MPFROM2SHORT(CMA_FIRSTCHILD, CMA_ITEMORDER));
169 if (!pciL || !*pciL->pszFileName) {
170 if (pciL && (INT) pciL != -1)
171 RemoveCnrItems(hwndCnr, pciL, 1, CMA_FREE);
172 dcd = INSTDATA(hwndCnr);
173 if (dcd && dcd->size != sizeof(DIRCNRDATA))
174 dcd = NULL;
175 if (driveflags[toupper(*pciParent->pszFileName) - 'A'] &
176 DRIVE_INCLUDEFILES)
177 includefiles = TRUE;
178 ProcessDirectory(hwndCnr,
179 pciParent,
180 pciParent->pszFileName,
181 includefiles, // filestoo
182 TRUE, // recurse
183 TRUE, // partial
184 NULL, // stop flag
185 dcd,
186 NULL, // total files
187 NULL); // total bytes
188 }
189 return TRUE;
190}
191
192BOOL UnFlesh(HWND hwndCnr, PCNRITEM pciParent)
193{
194 BOOL ret = FALSE;
195 PCNRITEM pciL;
196
197 if (!pciParent || !hwndCnr)
198 return FALSE;
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) {
205 ret = TRUE;
206 RemoveCnrItems(hwndCnr, pciL, 1, CMA_FREE);
207 }
208 else
209 break;
210 }
211 if (ret) {
212 WinSendMsg(hwndCnr,
213 CM_INVALIDATERECORD,
214 MPFROMP(&pciParent),
215 MPFROM2SHORT(1, CMA_ERASE | CMA_REPOSITION));
216 }
217 return ret;
218}
219
220#define DDEPTH 16
221
222BOOL Stubby(HWND hwndCnr, PCNRITEM pciParent)
223{
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
230 BOOL ret = FALSE;
231 FILEFINDBUF3 ffb[DDEPTH];
232 PFILEFINDBUF3 pffb;
233 HDIR hDir = HDIR_CREATE;
234 ULONG nm, ulM = 1, total = 0, fl = MUST_HAVE_DIRECTORY;
235 CHAR str[CCHMAXPATH];
236 register INT len;
237 APIRET rc, prc;
238 BOOL isadir = FALSE, isremote = FALSE, includefiles = fFilesInTree;
239 ULONG ddepth = 3;
240 static BOOL brokenlan = FALSE, isbroken = FALSE;
241
242 if (!pciParent || !*pciParent->pszFileName || !hwndCnr)
243 return FALSE;
244
245 len = strlen(pciParent->pszFileName);
246 memcpy(str, pciParent->pszFileName, len + 1);
247 if (str[len - 1] != '\\')
248 str[len++] = '\\';
249 str[len++] = '*';
250 str[len] = 0;
251
252 if (!isalpha(*str) || str[1] != ':' || str[2] != '\\')
253 MakeFullName(str);
254
255 if (!isalpha(*str) ||
256 str[1] != ':' ||
257 str[2] != '\\' || ((driveflags[toupper(*str) - 'A'] & DRIVE_IGNORE)))
258 return FALSE;
259
260 if (isalpha(*str) && driveflags[toupper(*str) - 'A'] & DRIVE_INCLUDEFILES)
261 includefiles = TRUE;
262
263 if (!isalpha(*str) ||
264 str[1] != ':' ||
265 str[2] != '\\' || ((driveflags[toupper(*str) - 'A'] & DRIVE_REMOTE)))
266 isremote = TRUE;
267
268 if (isremote) {
269 ddepth = 14;
270 if (fRemoteBug) {
271 if (brokenlan) {
272 ddepth = (ULONG) - 1;
273 ddepth--;
274 }
275 ulM = 1;
276 }
277 }
278 else if (isbroken)
279 ddepth = 14;
280
281 if (!isremote || !fRemoteBug)
282 ulM = (ddepth < 16) ? ddepth : 1;
283
284 nm = ulM;
285
286 DosError(FERR_DISABLEHARDERR);
287 if (includefiles)
288 fl = FILE_DIRECTORY;
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);
295 if (ulM == 1 && !rc) {
296 do {
297 pffb = &ffb[0];
298 if (!includefiles && !(pffb->attrFile & FILE_DIRECTORY) && !brokenlan) {
299 brokenlan = TRUE;
300 ddepth = (ULONG) - 1;
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));
312 NoBrokenNotify = 255;
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 }
326 }
327 if (*pffb->achName &&
328 (includefiles || (pffb->attrFile & FILE_DIRECTORY)) &&
329 // Skip . and ..
330 (pffb->achName[0] != '.' ||
331 (pffb->achName[1] &&
332 (pffb->achName[1] != '.' || pffb->achName[2])))) {
333 DosFindClose(hDir);
334 isadir = TRUE;
335 goto Interruptus;
336 }
337 nm = 1;
338 DosError(FERR_DISABLEHARDERR);
339 } while (++total < ddepth && !(rc = (DosFindNext(hDir,
340 &ffb,
341 sizeof(FILEFINDBUF3),
342 &nm))));
343 DosFindClose(hDir);
344 if (toupper(*pciParent->pszFileName) > 'B' &&
345 (*(pciParent->pszFileName + 1)) == ':' &&
346 (*(pciParent->pszFileName + 2)) == '\\' && !(*(pciParent->pszFileName + 3))) {
347
348 CHAR s[132];
349
350 sprintf(s,
351 GetPString(IDS_NOSUBDIRSTEXT),
352 total, toupper(*pciParent->pszFileName));
353 if (rc && rc != ERROR_NO_MORE_FILES)
354 sprintf(&s[strlen(s)], GetPString(IDS_SEARCHERRORTEXT), rc, str);
355 else if (ddepth < 16)
356 brokenlan = TRUE;
357 Notify(s);
358 }
359 goto None;
360 }
361
362 if (!rc) {
363 DosFindClose(hDir);
364 if (nm) {
365
366 register PBYTE fb = (PBYTE) & ffb[0];
367
368 for (len = 0; len < nm; len++) {
369 pffb = (PFILEFINDBUF3) fb;
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));
386 NoBrokenNotify = 255;
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)) &&
404 // Skip . and ..
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;
412 }
413
414 Interruptus:
415
416 if (isadir) {
417
418 PCNRITEM pci;
419
420 pci = WinSendMsg(hwndCnr,
421 CM_ALLOCRECORD,
422 MPFROMLONG(EXTRA_RECORD_BYTES), MPFROMLONG(1));
423 if (!pci) {
424 Win_Error(hwndCnr, HWND_DESKTOP, __FILE__, __LINE__,
425 GetPString(IDS_RECORDALLOCFAILEDTEXT));
426 }
427 else {
428 RECORDINSERT ri;
429 pci->pszFileName = NullStr;
430 pci->pszDisplayName = pci->pszFileName;
431 pci->rc.pszIcon = pci->pszDisplayName;
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))) {
441 DosSleep(50); //05 Aug 07 GKY 100
442 WinSetFocus(HWND_DESKTOP, hwndCnr);
443 if (WinIsWindow((HAB)0, hwndCnr)) {
444 if (!WinSendMsg(hwndCnr,
445 CM_INSERTRECORD, MPFROMP(pci), MPFROMP(&ri))) {
446 Win_Error(hwndCnr, HWND_DESKTOP, __FILE__, __LINE__,
447 GetPString(IDS_RECORDINSERTFAILEDTEXT));
448 FreeCnrItem(hwndCnr, pci);
449 }
450 else
451 ret = TRUE;
452 }
453 }
454 else
455 ret = TRUE;
456 }
457 }
458 else if (toupper(*str) > 'B' && str[1] == ':' && str[2] == '\\' &&
459 !str[3]) {
460
461 CHAR s[162];
462
463 sprintf(s,
464 GetPString(IDS_NOSUBDIRS2TEXT),
465 nm,
466 toupper(*pciParent->pszFileName),
467 (isremote) ? GetPString(IDS_NOSUBDIRS3TEXT) : NullStr);
468 Notify(s);
469 }
470 }
471 }
472 else if (toupper(*str) > 'B' && rc != ERROR_NO_MORE_FILES) {
473
474 CHAR s[CCHMAXPATH + 80];
475
476 sprintf(s, GetPString(IDS_SEARCHERRORTEXT), rc, str);
477 Notify(s);
478 }
479
480None:
481
482 DosError(FERR_DISABLEHARDERR);
483 return ret;
484}
485
486#pragma alloc_text(FLESH,Flesh,FleshEnv,Unflesh,Stubby)
Note: See TracBrowser for help on using the repository browser.