source: trunk/dll/flesh.c@ 1036

Last change on this file since 1036 was 1009, checked in by Steven Levine, 17 years ago

Add xfree xstrdup Fortify support
Add MT capable Fortify scope logic

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