source: trunk/dll/flesh.c @ 751

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

Sync rest of code with CNRITEM mods
Sync code with ARCITEM mods
Get compare dialog working
Still some issues with status display
Still some issues with directory sizes tree display
Heap check diagnostic code mostly enabled

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