From 85260e1fa75d49ac10e70fa64b1fedbfdc835a28 Mon Sep 17 00:00:00 2001 From: Ziliang Guo Date: Sun, 14 Dec 2014 00:00:54 +0000 Subject: [PATCH] [TREE] Implement directory tree commandline utility. Code by Asif Bahrainwala. Cleanup by Ziliang Guo. CORE-8529 svn path=/trunk/; revision=65631 --- .../base/applications/cmdutils/CMakeLists.txt | 1 + .../applications/cmdutils/tree/CMakeLists.txt | 5 + .../base/applications/cmdutils/tree/tree.c | 332 ++++++++++++++++++ 3 files changed, 338 insertions(+) create mode 100644 reactos/base/applications/cmdutils/tree/CMakeLists.txt create mode 100644 reactos/base/applications/cmdutils/tree/tree.c diff --git a/reactos/base/applications/cmdutils/CMakeLists.txt b/reactos/base/applications/cmdutils/CMakeLists.txt index 15f4f240997..f0214905aca 100644 --- a/reactos/base/applications/cmdutils/CMakeLists.txt +++ b/reactos/base/applications/cmdutils/CMakeLists.txt @@ -11,6 +11,7 @@ add_subdirectory(more) add_subdirectory(reg) add_subdirectory(sort) add_subdirectory(taskkill) +add_subdirectory(tree) add_subdirectory(wmic) add_subdirectory(wscript) add_subdirectory(xcopy) diff --git a/reactos/base/applications/cmdutils/tree/CMakeLists.txt b/reactos/base/applications/cmdutils/tree/CMakeLists.txt new file mode 100644 index 00000000000..78f33c34d0d --- /dev/null +++ b/reactos/base/applications/cmdutils/tree/CMakeLists.txt @@ -0,0 +1,5 @@ + +add_executable(tree tree.c) +set_module_type(tree win32cui UNICODE) +add_importlibs(tree msvcrt kernel32 user32) +add_cd_file(TARGET tree DESTINATION reactos/system32 FOR all) diff --git a/reactos/base/applications/cmdutils/tree/tree.c b/reactos/base/applications/cmdutils/tree/tree.c new file mode 100644 index 00000000000..a422a9ed310 --- /dev/null +++ b/reactos/base/applications/cmdutils/tree/tree.c @@ -0,0 +1,332 @@ +/* + * PROJECT: ReactOS + * LICENSE: GNU GPLv2 only as published by the Free Software Foundation + * PURPOSE: Implements tree.com functionality similar to Windows + * PROGRAMMERS: Asif Bahrainwala (asif_bahrainwala@hotmail.com) + */ + +// Tree.cpp : Defines the entry point for the console application. +// +#include +#include + +#define STR_MAX 2048 + +const wchar_t *HELP = L"\nGraphically displays the folder structure of a drive or path. \n\nTREE [drive:][path] [/F] [/A]\n\n /F Display the names of the files in each folder.\n\n\n"; +const wchar_t *INVALID = L"No subfolders exist"; + +static void DrawTree(const wchar_t* strPath, const WIN32_FIND_DATA *arrFolder, const size_t szArr, UINT width, const wchar_t *prevLine, BOOL drawfolder); +static void GetDirectoryStructure(wchar_t* strPath, UINT width, const wchar_t* prevLine); + +BOOL bShowFiles = FALSE; //if this flag is set to true, files will also be listed + +/** +* @name: HasSubFolder +* +* @param strPath +* Must specify folder name +* +* @return +* true if folder has sub folders, else will return false +*/ +static BOOL HasSubFolder(const wchar_t *strPath1) +{ + BOOL ret = FALSE; + WIN32_FIND_DATA FindFileData; + HANDLE hFind = NULL; + static wchar_t strPath[STR_MAX]= L""; + ZeroMemory(strPath, sizeof(strPath)); + + wcscat(strPath,strPath1); + wcscat(strPath,L"\\*."); + + hFind=FindFirstFile(strPath, &FindFileData); + do + { + if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + if(wcscmp(FindFileData.cFileName, L".")==0 || + wcscmp(FindFileData.cFileName, L"..")==0 ) + { + continue; + } + + ret=TRUE; //found subfolder + break; + } + } + while(FindNextFile(hFind, &FindFileData)); + + FindClose(hFind); + return ret; +} + +/** + * @name: DrawTree + * + * @param strPath + * Must specify folder name + * + * @param arrFolder + * must be a list of folder names to be drawn in tree format + * + * @param width + * specifies drawing distance for correct formatting of tree structure being drawn on console screen + * used internally for adding spaces + * + * @param prevLine + * used internally for formatting reasons + * + * @return + * void + */ +static void DrawTree(const wchar_t* strPath, const WIN32_FIND_DATA *arrFolder, const size_t szArr, UINT width, const wchar_t *prevLine, BOOL drawfolder) +{ + BOOL bHasSubFolder = HasSubFolder(strPath); + UINT i = 0; + + //this will format the spaces required for correct formatting + for(i = 0; i < szArr; ++i) + { + wchar_t *consoleOut = (wchar_t*)malloc(sizeof(wchar_t) * STR_MAX); + UINT j=0; + static wchar_t str[STR_MAX]; + + // As we do not seem to have the _s functions properly set up, use the non-secure version for now + //wcscpy_s(consoleOut, STR_MAX, L""); + //wcscpy_s(str, STR_MAX, L""); + wcscpy(consoleOut, L""); + wcscpy(str, L""); + + for(j=0;j> 16, dwSerial & 0xffff); + + sz = GetCurrentDirectory(1, &t); //get the buffer size + strPath = (wchar_t*)malloc(sizeof(wchar_t) * sz); //must not return before calling delete[] + + GetCurrentDirectory(sz, strPath); //get the current directory + + + driveLetter = (wchar_t*)malloc(sizeof(wchar_t) * sz); //get the drive letter , must not return before calling delete[] + + // As we do not seem to have the _s functions properly set up, use the non-secure version for now + //wcscpy_s(driveLetter,sz,strPath); + //wcstok_s(driveLetter,L":", &context); //parse for the drive letter + wcscpy(driveLetter,strPath); + wcstok(driveLetter, L":"); + + wprintf(L"%s:.\n",driveLetter); + + free(driveLetter); + + GetDirectoryStructure(strPath, 1, L" "); //get the sub directories within this current folder + + free(strPath); + wprintf(L"\n"); + + return 0; +}