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