Subversion Repositories SvarDOS

Rev

Rev 2022 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2022 Rev 2023
Line 1... Line 1...
1
/****************************************************************************
1
/****************************************************************************
2
 
2
 
3
  TREE - Graphically displays the directory structure of a drive or path
3
  TREE - Graphically displays the directory structure of a drive or path
4
 
4
 
5
  Written to work with FreeDOS (and other DOS variants)
-
 
6
  Win32(c) console and DOS with LFN support.
-
 
7
 
-
 
8
****************************************************************************/
5
****************************************************************************/
9
 
6
 
10
#define VERSION "1.04"
7
#define VERSION "1.04"
11
 
8
 
12
/****************************************************************************
9
/****************************************************************************
Line 36... Line 33...
36
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
33
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
37
DEALINGS IN THE SOFTWARE.
34
DEALINGS IN THE SOFTWARE.
38
 
35
 
39
****************************************************************************/
36
****************************************************************************/
40
 
37
 
41
/**
-
 
42
 * Define the appropriate target here or within your compiler
-
 
43
 */
-
 
44
/* #define WIN32 */    /** Win32 console version **/
-
 
45
/* #define DOS */      /** DOS version           **/
-
 
46
/* #define UNIX */
-
 
47
 
-
 
48
 
38
 
49
/* Include files */
39
/* Include files */
50
#include <stdlib.h>
40
#include <stdlib.h>
51
#include <stdio.h>
41
#include <stdio.h>
52
#include <string.h>
42
#include <string.h>
Line 55... Line 45...
55
#include <limits.h>
45
#include <limits.h>
56
 
46
 
57
#include "stack.h"
47
#include "stack.h"
58
 
48
 
59
 
49
 
60
/* Platform (OS) specific definitions */
-
 
61
 
-
 
62
#ifdef WIN32       /* windows specific     */
-
 
63
 
-
 
64
#ifndef _WIN32_WINNT         /* NT 4.0 or higher features */
-
 
65
#define _WIN32_WINNT 0x0400
-
 
66
#endif
-
 
67
 
-
 
68
#include <windows.h>
-
 
69
#include <winbase.h>
-
 
70
 
-
 
71
/* converts from Ansi to OEM (IBM extended )    */
-
 
72
#define charToDisplayChar(x) CharToOemA((x), (x))
-
 
73
/* For wide character conversion, charToDisplayChar
-
 
74
   must be a function that provides its own buffer
-
 
75
   to CharToOemW and copies the results back into x
-
 
76
   as CharToOemA is inplace safe, but CharToOemW is not.
-
 
77
*/
-
 
78
 
-
 
79
/* These are defined in w32fDOS.h for DOS and enable /
-
 
80
   disable use of DOS extended int21h API for LFNs,
-
 
81
   on Windows we use it to force using short name when
-
 
82
   both a long and short name are available
-
 
83
   (note, LFNs may still be shown when no SFN exists)
-
 
84
*/
-
 
85
#define LFN_ENABLE 1
-
 
86
#define LFN_DISABLE 0
-
 
87
int LFN_Enable_Flag = LFN_ENABLE;
-
 
88
 
-
 
89
/* DOS compiler treats L"" as a char * */
-
 
90
#define UDOT L"."
-
 
91
#define UDOTDOT L".."
-
 
92
 
-
 
93
 
-
 
94
/* Stream display is only supported for Win32, specifically Windows NT */
-
 
95
#include "streams.c"
-
 
96
 
-
 
97
#else                   /* DOS specific         */
-
 
98
/* Win32 File compability stuff */
50
/* Win32 File compability stuff */
99
#include "w32fDOS.h"
51
#include "w32fDOS.h"
100
#include "wincon.h"
52
#include "wincon.h"
101
 
53
 
102
/* currently no mapping required */
54
/* currently no mapping required */
Line 104... Line 56...
104
 
56
 
105
/* DOS compiler treats L"" as a char * */
57
/* DOS compiler treats L"" as a char * */
106
const WORD UDOT[]    = { 0x2E, 0x00 };        //   L"."
58
const WORD UDOT[]    = { 0x2E, 0x00 };        //   L"."
107
const WORD UDOTDOT[] = { 0x2E, 0x2E, 0x00 };  //   L".."
59
const WORD UDOTDOT[] = { 0x2E, 0x2E, 0x00 };  //   L".."
108
 
60
 
109
#endif
-
 
110
 
61
 
111
 
62
 
112
/* Define getdrive so it returns current drive, 0=A,1=B,...           */
63
/* Define getdrive so it returns current drive, 0=A,1=B,...           */
113
#if defined _MSC_VER || defined __MSC /* MS Visual C/C++ 5 */
-
 
114
#define getdrive() (_getdrive() - 1)
-
 
115
#else /* #ifdef __BORLANDC__ || __TURBOC__ */
-
 
116
#define getdrive() getdisk()
64
#define getdrive() getdisk()
117
#endif
-
 
118
 
65
 
119
#include <conio.h>  /* for getch()   */
66
#include <conio.h>  /* for getch()   */
120
 
67
 
121
 
68
 
122
/* End Platform (OS) specific sections */
-
 
123
 
69
 
124
 
70
 
125
/* The default extended forms of the lines used. */
71
/* The default extended forms of the lines used. */
126
#define VERTBAR_STR  "\xB3   "                 /* |    */
72
#define VERTBAR_STR  "\xB3   "                 /* |    */
127
#define TBAR_HORZBAR_STR "\xC3\xC4\xC4\xC4"    /* +--- */
73
#define TBAR_HORZBAR_STR "\xC3\xC4\xC4\xC4"    /* +--- */
Line 1176... Line 1122...
1176
 
1122
 
1177
      if (dspSize)  /* file size */
1123
      if (dspSize)  /* file size */
1178
      {
1124
      {
1179
        if (entry.nFileSizeHigh)
1125
        if (entry.nFileSizeHigh)
1180
        {
1126
        {
1181
#ifdef WIN32  /* convert to a 64bit value, then round to nearest KB */
-
 
1182
          __int64 fsize = entry.nFileSizeHigh * ((__int64)ULONG_MAX + 1i64);
-
 
1183
          fsize = (fsize + entry.nFileSizeLow + 512i64) / 1024i64;
-
 
1184
          pprintf("%8I64uKB ", fsize);
-
 
1185
#else
-
 
1186
          pprintf("******** ");  /* error exceed max value we can display, > 4GB */
1127
          pprintf("******** ");  /* error exceed max value we can display, > 4GB */
1187
#endif
-
 
1188
        }
1128
        }
1189
        else
1129
        else
1190
        {
1130
        {
1191
          if (entry.nFileSizeLow < 1048576)  /* if less than a MB, display in bytes */
1131
          if (entry.nFileSizeLow < 1048576l)  /* if less than a MB, display in bytes */
1192
            pprintf("%10lu ", entry.nFileSizeLow);
1132
            pprintf("%10lu ", entry.nFileSizeLow);
1193
          else                               /* otherwise display in KB */
1133
          else                               /* otherwise display in KB */
1194
            pprintf("%8luKB ", entry.nFileSizeLow/1024UL);
1134
            pprintf("%8luKB ", entry.nFileSizeLow/1024UL);
1195
        }
1135
        }
1196
      }
1136
      }
Line 1212... Line 1152...
1212
      }
1152
      }
1213
 
1153
 
1214
      /* print filename */
1154
      /* print filename */
1215
      pprintf("%s\n", entry.cFileName);
1155
      pprintf("%s\n", entry.cFileName);
1216
 
1156
 
1217
#ifdef WIN32  /* streams are only available on NTFS systems with NT API */
-
 
1218
      if (dspStreams)
-
 
1219
      {
-
 
1220
        FILE_STREAM_INFORMATION *fsi;
-
 
1221
 
-
 
1222
        /* build full path to this filename */
-
 
1223
        strcpy(buffer, path);
-
 
1224
        strcat(buffer, entry.cFileName);
-
 
1225
 
-
 
1226
        /* try to get all streams associated with this file */
-
 
1227
        fsi = getFileStreamInfo(buffer);
-
 
1228
 
-
 
1229
        while (fsi != NULL)
-
 
1230
        {
-
 
1231
          /* check and ignore default $DATA stream */
-
 
1232
#if 1
-
 
1233
          if ((fsi->StreamNameLength != DefaultStreamNameLengthBytes) ||
-
 
1234
              (memcmp(fsi->StreamName, DefaultStreamName, DefaultStreamNameLengthBytes)!=0))
-
 
1235
#endif
-
 
1236
          {
-
 
1237
            /* print lead padding and spacing so fall under name */
-
 
1238
            pprintf("%s", padding);
-
 
1239
            if (dspAttr) pprintf("           ");
-
 
1240
            if (dspSize) pprintf("           ");
-
 
1241
            pprintf("  ");  /* extra spacing so slightly indented from filename */
-
 
1242
 
-
 
1243
            /* convert to UTF8 (really should convert to OEM or UTF8 as indicated) */
-
 
1244
            convertUTF16toUTF8(fsi->StreamName, buffer, MAXBUF);
-
 
1245
 
-
 
1246
            /* and display it */
-
 
1247
            pprintf("%s\n", buffer);
-
 
1248
          }
-
 
1249
 
-
 
1250
          /* either proceed to next entry or mark end */
-
 
1251
          if (fsi->NextEntryOffset)
-
 
1252
            fsi = (FILE_STREAM_INFORMATION *)(((byte *)fsi) + fsi->NextEntryOffset);
-
 
1253
          else
-
 
1254
            fsi = NULL;  /* end of available data */
-
 
1255
        }
-
 
1256
      }
-
 
1257
#endif /* WIN32 */
-
 
1258
 
-
 
1259
      filesShown++;
1157
      filesShown++;
1260
    }
1158
    }
1261
  } while(FindNextFile(dir, &entry) != 0);
1159
  } while(FindNextFile(dir, &entry) != 0);
1262
 
1160
 
1263
  if (filesShown)
1161
  if (filesShown)
Line 1638... Line 1536...
1638
  /* Changes %c in certain lines with proper option characters. */
1536
  /* Changes %c in certain lines with proper option characters. */
1639
  FixOptionText();
1537
  FixOptionText();
1640
}
1538
}
1641
 
1539
 
1642
 
1540
 
1643
/* Initialize function pointers for Win32 API functions not always available */
-
 
1644
void initFuncPtrs(void)
-
 
1645
{
-
 
1646
#ifdef WIN32
-
 
1647
  /* Attempt to get Unicode version of Win32 APIs
-
 
1648
   * Because they are in Kernel32, we assume it's always loaded
-
 
1649
   * and so don't need to use LoadLibrary/FreeLibrary to maintain a reference count.
-
 
1650
   */
-
 
1651
  HMODULE hKERNEL32 = GetModuleHandle("KERNEL32");
-
 
1652
  if (hKERNEL32 == NULL) printf("ERROR: unable to get KERNEL32 handle, %i\n", GetLastError());
-
 
1653
 
-
 
1654
  pFindFirstFileExA = (fFindFirstFileExA)GetProcAddress(hKERNEL32, "FindFirstFileExA");
-
 
1655
  if (pFindFirstFileExA == NULL)  printf("WARNING: unable to get FindFirstFileExA, %i\n", GetLastError());
-
 
1656
  if (pFindFirstFileExA == NULL) pFindFirstFileExA = myFindFirstFileExA;
-
 
1657
 
-
 
1658
  if (charSet == UNICODECHARS)
-
 
1659
  {
-
 
1660
    pFindFirstFileExW = (fFindFirstFileExW)GetProcAddress(hKERNEL32, "FindFirstFileExW");
-
 
1661
    if (pFindFirstFileExW == NULL)  printf("WARNING: unable to get FindFirstFileExW, %i\n", GetLastError());
-
 
1662
  }
-
 
1663
 
-
 
1664
  /* also for stream support; it uses NTDLL.DLL, which we also assume always loaded if available */
-
 
1665
  initStreamSupport();
-
 
1666
#endif
-
 
1667
}
-
 
1668
 
-
 
1669
int main(int argc, char *argv[])
1541
int main(int argc, char *argv[])
1670
{
1542
{
1671
  char serial[SERIALLEN]; /* volume serial #  0000:0000 */
1543
  char serial[SERIALLEN]; /* volume serial #  0000:0000 */
1672
  char volume[VOLLEN];    /* volume name (label), possibly none */
1544
  char volume[VOLLEN];    /* volume name (label), possibly none */
1673
 
1545
 
Line 1678... Line 1550...
1678
  parseArguments(argc, argv);
1550
  parseArguments(argc, argv);
1679
 
1551
 
1680
  /* Initialize screen size, may reset pause to NOPAUSE if redirected */
1552
  /* Initialize screen size, may reset pause to NOPAUSE if redirected */
1681
  getConsoleSize();
1553
  getConsoleSize();
1682
 
1554
 
1683
  /* Initialize function pointers for Win32 API functions not always available */
-
 
1684
  initFuncPtrs();
-
 
1685
 
-
 
1686
  /* Unicode mode only, Output BOM for UTF-8 signature */
1555
  /* Unicode mode only, Output BOM for UTF-8 signature */
1687
  if (charSet == UNICODECHARS)  pprintf("%s", UMARKER);
1556
  if (charSet == UNICODECHARS)  pprintf("%s", UMARKER);
1688
 
1557
 
1689
 
1558
 
1690
  /* Get Volume & Serial Number */
1559
  /* Get Volume & Serial Number */