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