source: trunk/dll/flesh.c @ 739

Last change on this file since 739 was 739, checked in by Steven Levine, 13 years ago

More ticket #24 updates

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