source: trunk/dll/flesh.c@ 515

Last change on this file since 515 was 515, checked in by root, 19 years ago

Stubby - correct . and .. detect

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