ReactOS  0.4.12-dev-14-gd0c8636
tree.c File Reference
#include <stdio.h>
#include <stdlib.h>
#include <windef.h>
#include <winbase.h>
#include <conutils.h>
#include "resource.h"
Include dependency graph for tree.c:

Go to the source code of this file.

Macros

#define STR_MAX   2048
 

Functions

: GetDirectoryStructure
Parameters
strPathMust specify folder name
widthspecifies drawing distance for correct formatting of tree structure being drawn on console screen
prevLinespecifies the previous line written on console, is used for correct formatting
Returns
void
static VOID GetDirectoryStructure (PWSTR strPath, UINT width, PCWSTR prevLine)
 
: HasSubFolder
Parameters
strPathMust specify folder name
Returns
true if folder has sub-folders, else will return false
static BOOL HasSubFolder (PCWSTR strPath1)
 
: DrawTree
Parameters
strPathMust specify folder name
arrFoldermust be a list of folder names to be drawn in tree format
widthspecifies drawing distance for correct formatting of tree structure being drawn on console screen used internally for adding spaces
prevLineused internally for formatting reasons
Returns
void
static VOID DrawTree (PCWSTR strPath, const WIN32_FIND_DATAW *arrFolder, const size_t szArr, UINT width, PCWSTR prevLine, BOOL drawfolder)
 
: main

standard main functionality as required by C/C++ for application startup

Returns
error /success value
int wmain (int argc, WCHAR *argv[])
 

Variables

BOOL bShowFiles = FALSE
 
BOOL bUseAscii = FALSE
 

Macro Definition Documentation

◆ STR_MAX

#define STR_MAX   2048

Definition at line 18 of file tree.c.

Referenced by DrawTree(), GetDirectoryStructure(), and HasSubFolder().

Function Documentation

◆ DrawTree()

static VOID DrawTree ( PCWSTR  strPath,
const WIN32_FIND_DATAW arrFolder,
const size_t  szArr,
UINT  width,
PCWSTR  prevLine,
BOOL  drawfolder 
)
static

Definition at line 88 of file tree.c.

Referenced by GetDirectoryStructure().

94 {
95  BOOL bHasSubFolder = HasSubFolder(strPath);
96  UINT i = 0;
97 
98  /* This will format the spaces required for correct formatting */
99  for (i = 0; i < szArr; ++i)
100  {
101  PWSTR consoleOut = (PWSTR)malloc(STR_MAX * sizeof(WCHAR));
102  UINT j = 0;
103  static WCHAR str[STR_MAX];
104 
105  /* As we do not seem to have the _s functions properly set up, use the non-secure version for now */
106  //wcscpy_s(consoleOut, STR_MAX, L"");
107  //wcscpy_s(str, STR_MAX, L"");
108  wcscpy(consoleOut, L"");
109  wcscpy(str, L"");
110 
111  for (j = 0; j < width - 1; ++j)
112  {
113  /* If the previous line has '├' or '│' then the current line will
114  add '│' to continue the connecting line */
115  if (prevLine[j] == L'\x251C' || prevLine[j] == L'\x2502' ||
116  prevLine[j] == L'+' || prevLine[j] == L'|')
117  {
118  if (!bUseAscii)
119  {
120  wcscat(consoleOut, L"\x2502");
121  }
122  else
123  {
124  wcscat(consoleOut, L"|");
125  }
126  }
127  else
128  {
129  wcscat(consoleOut, L" ");
130  }
131  }
132 
133  if (szArr - 1 != i)
134  {
135  if (drawfolder)
136  {
137  /* Add '├───Folder name' (\xC3\xC4\xC4\xC4 or \x251C\x2500\x2500\x2500) */
138  if (bUseAscii)
139  swprintf(str, L"+---%s", arrFolder[i].cFileName);
140  else
141  swprintf(str, L"\x251C\x2500\x2500\x2500%s", arrFolder[i].cFileName);
142  }
143  else
144  {
145  if (bHasSubFolder)
146  {
147  /* Add '│ FileName' (\xB3 or \x2502) */
148  // This line is added to connect the below-folder sub-structure
149  if (bUseAscii)
150  swprintf(str, L"| %s", arrFolder[i].cFileName);
151  else
152  swprintf(str, L"\x2502 %s", arrFolder[i].cFileName);
153  }
154  else
155  {
156  /* Add ' FileName' */
157  swprintf(str, L" %s", arrFolder[i].cFileName);
158  }
159  }
160  }
161  else
162  {
163  if (drawfolder)
164  {
165  /* '└───Folder name' (\xC0\xC4\xC4\xC4 or \x2514\x2500\x2500\x2500) */
166  if (bUseAscii)
167  swprintf(str, L"\\---%s", arrFolder[i].cFileName);
168  else
169  swprintf(str, L"\x2514\x2500\x2500\x2500%s", arrFolder[i].cFileName);
170  }
171  else
172  {
173  if (bHasSubFolder)
174  {
175  /* '│ FileName' (\xB3 or \x2502) */
176  if (bUseAscii)
177  swprintf(str, L"| %s", arrFolder[i].cFileName);
178  else
179  swprintf(str, L"\x2502 %s", arrFolder[i].cFileName);
180  }
181  else
182  {
183  /* ' FileName' */
184  swprintf(str, L" %s", arrFolder[i].cFileName);
185  }
186  }
187  }
188 
189  wcscat(consoleOut, str);
190  ConPrintf(StdOut, L"%s\n", consoleOut);
191 
192  if (drawfolder)
193  {
194  PWSTR str = (PWSTR)malloc(STR_MAX * sizeof(WCHAR));
195  ZeroMemory(str, STR_MAX * sizeof(WCHAR));
196 
197  wcscat(str, strPath);
198  wcscat(str, L"\\");
199  wcscat(str, arrFolder[i].cFileName);
200  GetDirectoryStructure(str, width + 4, consoleOut);
201 
202  free(str);
203  }
204  free(consoleOut);
205  }
206 }
GLint GLint GLsizei width
Definition: gl.h:1546
GLenum GLclampf GLint GLenum GLuint GLenum GLenum GLsizei GLenum const GLvoid GLfloat GLfloat GLfloat GLfloat GLclampd GLint GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean GLboolean GLboolean GLboolean GLint GLenum GLsizei const GLvoid GLenum GLint GLenum GLint GLint GLsizei GLint GLenum GLint GLint GLint GLint GLsizei GLenum GLsizei const GLuint GLboolean GLenum GLenum GLint GLsizei GLenum GLsizei GLenum const GLvoid GLboolean const GLboolean GLenum const GLdouble const GLfloat const GLdouble const GLfloat GLenum GLint GLint GLint GLint GLint GLint j
Definition: glfuncs.h:98
__wchar_t WCHAR
Definition: xmlstorage.h:180
uint16_t * PWSTR
Definition: typedefs.h:54
#define free
Definition: debug_ros.c:5
BOOL bUseAscii
Definition: tree.c:26
#define ZeroMemory
Definition: winbase.h:1635
GLenum GLclampf GLint i
Definition: glfuncs.h:14
INT __cdecl ConPrintf(IN PCON_STREAM Stream, IN LPWSTR szStr,...)
Definition: outstream.c:520
static VOID GetDirectoryStructure(PWSTR strPath, UINT width, PCWSTR prevLine)
Definition: tree.c:223
const WCHAR * str
unsigned int BOOL
Definition: ntddk_ex.h:94
#define swprintf(buf, format,...)
Definition: sprintf.c:56
unsigned int UINT
Definition: ndis.h:50
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
static const WCHAR L[]
Definition: oid.c:1087
static BOOL HasSubFolder(PCWSTR strPath1)
Definition: tree.c:37
_CRTIMP wchar_t *__cdecl wcscat(_Inout_updates_z_(_String_length_(_Dest)+_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
#define StdOut
Definition: stream.h:76
#define malloc
Definition: debug_ros.c:4
#define STR_MAX
Definition: tree.c:18

◆ GetDirectoryStructure()

static VOID GetDirectoryStructure ( PWSTR  strPath,
UINT  width,
PCWSTR  prevLine 
)
static

Definition at line 223 of file tree.c.

Referenced by DrawTree(), and wmain().

224 {
225  WIN32_FIND_DATAW FindFileData;
226  HANDLE hFind = NULL;
227  //DWORD err = 0;
228  /* Fill up with names of all sub-folders */
229  WIN32_FIND_DATAW *arrFolder = NULL;
230  UINT arrFoldersz = 0;
231  /* Fill up with names of all sub-folders */
232  WIN32_FIND_DATAW *arrFile = NULL;
233  UINT arrFilesz = 0;
234 
235  ZeroMemory(&FindFileData, sizeof(FindFileData));
236 
237  {
238  static WCHAR tmp[STR_MAX] = L"";
239  ZeroMemory(tmp, sizeof(tmp));
240  wcscat(tmp, strPath);
241  wcscat(tmp, L"\\*.*");
242  hFind = FindFirstFileW(tmp, &FindFileData);
243  //err = GetLastError();
244  }
245 
246  if (hFind == INVALID_HANDLE_VALUE)
247  return;
248 
249  do
250  {
251  if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
252  {
253  if (wcscmp(FindFileData.cFileName, L".") == 0 ||
254  wcscmp(FindFileData.cFileName, L"..") == 0)
255  continue;
256 
257  ++arrFoldersz;
258  arrFolder = (WIN32_FIND_DATAW*)realloc(arrFolder, arrFoldersz * sizeof(FindFileData));
259 
260  if (arrFolder == NULL)
261  exit(-1);
262 
263  arrFolder[arrFoldersz - 1] = FindFileData;
264 
265  }
266  else
267  {
268  ++arrFilesz;
269  arrFile = (WIN32_FIND_DATAW*)realloc(arrFile, arrFilesz * sizeof(FindFileData));
270 
271  if(arrFile == NULL)
272  exit(-1);
273 
274  arrFile[arrFilesz - 1] = FindFileData;
275  }
276  }
277  while (FindNextFileW(hFind, &FindFileData));
278 
279  FindClose(hFind);
280 
281  if (bShowFiles)
282  {
283  /* Will free(arrFile) */
284  DrawTree(strPath, arrFile, arrFilesz, width, prevLine, FALSE);
285  }
286 
287  /* Will free(arrFile) */
288  DrawTree(strPath, arrFolder, arrFoldersz, width, prevLine, TRUE);
289 
290  free(arrFolder);
291  free(arrFile);
292 }
#define realloc
Definition: debug_ros.c:6
BOOL WINAPI FindNextFileW(IN HANDLE hFindFile, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:382
GLint GLint GLsizei width
Definition: gl.h:1546
#define TRUE
Definition: types.h:120
__wchar_t WCHAR
Definition: xmlstorage.h:180
static VOID DrawTree(PCWSTR strPath, const WIN32_FIND_DATAW *arrFolder, const size_t szArr, UINT width, PCWSTR prevLine, BOOL drawfolder)
Definition: tree.c:88
#define free
Definition: debug_ros.c:5
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
#define ZeroMemory
Definition: winbase.h:1635
smooth NULL
Definition: ftsmooth.c:416
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
unsigned int UINT
Definition: ndis.h:50
static const WCHAR L[]
Definition: oid.c:1087
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
_CRTIMP wchar_t *__cdecl wcscat(_Inout_updates_z_(_String_length_(_Dest)+_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
void exit(int exitcode)
Definition: _exit.c:33
BOOL bShowFiles
Definition: tree.c:23
#define STR_MAX
Definition: tree.c:18
HANDLE WINAPI FindFirstFileW(IN LPCWSTR lpFileName, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:320
BOOL WINAPI FindClose(HANDLE hFindFile)
Definition: find.c:502

◆ HasSubFolder()

static BOOL HasSubFolder ( PCWSTR  strPath1)
static

Definition at line 37 of file tree.c.

Referenced by DrawTree().

38 {
39  BOOL ret = FALSE;
40  WIN32_FIND_DATAW FindFileData;
41  HANDLE hFind = NULL;
42  static WCHAR strPath[STR_MAX] = L"";
43  ZeroMemory(strPath, sizeof(strPath));
44 
45  wcscat(strPath, strPath1);
46  wcscat(strPath, L"\\*.");
47 
48  hFind = FindFirstFileW(strPath, &FindFileData);
49  do
50  {
51  if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
52  {
53  if (wcscmp(FindFileData.cFileName, L".") == 0 ||
54  wcscmp(FindFileData.cFileName, L"..") == 0 )
55  {
56  continue;
57  }
58 
59  ret = TRUE; // Sub-folder found
60  break;
61  }
62  }
63  while (FindNextFileW(hFind, &FindFileData));
64 
65  FindClose(hFind);
66  return ret;
67 }
BOOL WINAPI FindNextFileW(IN HANDLE hFindFile, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:382
#define TRUE
Definition: types.h:120
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define ZeroMemory
Definition: winbase.h:1635
smooth NULL
Definition: ftsmooth.c:416
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
unsigned int BOOL
Definition: ntddk_ex.h:94
int ret
static const WCHAR L[]
Definition: oid.c:1087
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
_CRTIMP wchar_t *__cdecl wcscat(_Inout_updates_z_(_String_length_(_Dest)+_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
#define STR_MAX
Definition: tree.c:18
HANDLE WINAPI FindFirstFileW(IN LPCWSTR lpFileName, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:320
BOOL WINAPI FindClose(HANDLE hFindFile)
Definition: find.c:502

◆ wmain()

int wmain ( int  argc,
WCHAR argv[] 
)

Definition at line 301 of file tree.c.

302 {
303  DWORD dwSerial = 0;
304  WCHAR t = 0;
305  PWSTR strPath = NULL;
306  DWORD sz = 0;
307  //PWSTR context = NULL;
308  PWSTR driveLetter = NULL;
309 
310  int i;
311 
312  /* Initialize the Console Standard Streams */
314 
315  /* Parse the command line */
316  for (i = 1; i < argc; ++i)
317  {
318  if (argv[i][0] == L'-' || argv[i][0] == L'/')
319  {
320  switch (towlower(argv[i][1]))
321  {
322  case L'?':
323  /* Print help and exit after */
325  return 0;
326 
327  case L'f':
328  bShowFiles = TRUE;
329  break;
330 
331  case L'a':
332  bUseAscii = TRUE;
333  break;
334 
335  default:
336  break;
337  }
338  }
339  else
340  {
341  /* This must be path to some folder */
342 
343  /* Set the current directory for this executable */
345  if (b == FALSE)
346  {
348  return 1;
349  }
350  }
351  }
352 
354 
355  GetVolumeInformationW(NULL, NULL, 0, &dwSerial, NULL, NULL, NULL, 0);
356  ConResPrintf(StdOut, IDS_VOL_SERIAL, dwSerial >> 16, dwSerial & 0xffff);
357 
358  /* get the buffer size */
359  sz = GetCurrentDirectoryW(1, &t);
360  /* must not return before calling delete[] */
361  strPath = (PWSTR)malloc(sz * sizeof(WCHAR));
362 
363  /* get the current directory */
364  GetCurrentDirectoryW(sz, strPath);
365 
366  /* get the drive letter , must not return before calling delete[] */
367  driveLetter = (PWSTR)malloc(sz * sizeof(WCHAR));
368 
369  /* As we do not seem to have the _s functions properly set up, use the non-secure version for now */
370  //wcscpy_s(driveLetter,sz,strPath);
371  //wcstok_s(driveLetter,L":", &context); //parse for the drive letter
372  wcscpy(driveLetter, strPath);
373  wcstok(driveLetter, L":");
374 
375  ConPrintf(StdOut, L"%s:.\n", driveLetter);
376 
377  free(driveLetter);
378 
379  /* get the sub-directories within this current folder */
380  GetDirectoryStructure(strPath, 1, L" ");
381 
382  free(strPath);
383  ConPuts(StdOut, L"\n");
384 
385  return 0;
386 }
static int argc
Definition: ServiceArgs.c:12
#define TRUE
Definition: types.h:120
__wchar_t WCHAR
Definition: xmlstorage.h:180
uint16_t * PWSTR
Definition: typedefs.h:54
#define free
Definition: debug_ros.c:5
#define GetCurrentDirectoryW(x, y)
Definition: compat.h:413
_Check_return_ _CRTIMP wchar_t *__cdecl wcstok(_Inout_opt_z_ wchar_t *_Str, _In_z_ const wchar_t *_Delim)
GLdouble GLdouble t
Definition: gl.h:2047
#define IDS_NO_SUBDIRECTORIES
Definition: resource.h:4
BOOL bUseAscii
Definition: tree.c:26
#define IDS_USAGE
Definition: resource.h:3
static char ** argv
Definition: ServiceArgs.c:11
GLenum GLclampf GLint i
Definition: glfuncs.h:14
#define ConInitStdStreams()
Definition: stream.h:122
INT __cdecl ConPrintf(IN PCON_STREAM Stream, IN LPWSTR szStr,...)
Definition: outstream.c:520
static VOID GetDirectoryStructure(PWSTR strPath, UINT width, PCWSTR prevLine)
Definition: tree.c:223
smooth NULL
Definition: ftsmooth.c:416
#define IDS_FOLDER_PATH
Definition: resource.h:5
INT __cdecl ConResPrintf(IN PCON_STREAM Stream, IN UINT uID,...)
Definition: outstream.c:781
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
#define IDS_VOL_SERIAL
Definition: resource.h:6
INT ConResPuts(IN PCON_STREAM Stream, IN UINT uID)
Definition: outstream.c:610
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
static const WCHAR L[]
Definition: oid.c:1087
BOOL WINAPI GetVolumeInformationW(IN LPCWSTR lpRootPathName, IN LPWSTR lpVolumeNameBuffer, IN DWORD nVolumeNameSize, OUT LPDWORD lpVolumeSerialNumber OPTIONAL, OUT LPDWORD lpMaximumComponentLength OPTIONAL, OUT LPDWORD lpFileSystemFlags OPTIONAL, OUT LPWSTR lpFileSystemNameBuffer OPTIONAL, IN DWORD nFileSystemNameSize)
Definition: volume.c:226
BOOL WINAPI SetCurrentDirectoryW(IN LPCWSTR lpPathName)
Definition: path.c:2248
INT ConPuts(IN PCON_STREAM Stream, IN LPWSTR szStr)
Definition: outstream.c:427
#define StdOut
Definition: stream.h:76
#define towlower(c)
Definition: wctype.h:97
#define malloc
Definition: debug_ros.c:4
BOOL bShowFiles
Definition: tree.c:23

Variable Documentation

◆ bShowFiles

BOOL bShowFiles = FALSE

Definition at line 23 of file tree.c.

Referenced by GetDirectoryStructure(), and wmain().

◆ bUseAscii

BOOL bUseAscii = FALSE

Definition at line 26 of file tree.c.

Referenced by DrawTree(), and wmain().