source: trunk/dll/flesh.c@ 1194

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

Ticket 187: Draft 2: Move remaining function declarations

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