// Spludlow Software // Copyright © Samuel P. Ludlow 2020 All Rights Reserved // Distributed under the terms of the GNU General Public License version 3 // Distributed WITHOUT ANY WARRANTY; without implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE // https://www.spludlow.co.uk/LICENCE.TXT // The Spludlow logo is a registered trademark of Samuel P. Ludlow and may not be used without permission // v1.14 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.IO; using System.Data; namespace Spludlow.Io { public class DirectoryList { private static string[] AttributeNames; private static int[] AttributeValues; static DirectoryList() { AttributeNames = Enum.GetNames(typeof(FileAttributes)); AttributeValues = new int[AttributeNames.Length]; for (int index = 0; index < AttributeNames.Length; ++index) { FileAttributes attribute = (FileAttributes)Enum.Parse(typeof(FileAttributes), AttributeNames[index]); AttributeValues[index] = (int)attribute; } } public static DataSet List(string host, string directoryPath, bool recursive, bool directorySize) { return (DataSet)Spludlow.Call.Now(host, "Spludlow", "Spludlow.Io.DirectoryList", "List", new object[] { directoryPath, recursive, directorySize }, CallFlags.LargeResult); } public static DataSet List(string directoryPath, bool recursive, bool directorySize) { SysTables.FileSystemInfosDataTable table = new SysTables.FileSystemInfosDataTable(); DirectoryInfo directoryInfo = new DirectoryInfo(directoryPath); bool useRecursive = recursive; if (directorySize == true) useRecursive = true; ListDirectoryWork(table, directoryInfo, 0, useRecursive); if (directorySize == true) { AddDirectoryIds(table); DirectorySizes(table); if (recursive == false) { SysTables.FileSystemInfosDataTable tmpTable = new SysTables.FileSystemInfosDataTable(); foreach (DataRow row in table.Select("Depth = 1")) tmpTable.ImportRow(row); table = tmpTable; } } DataSet dataSet = new DataSet(); dataSet.Tables.Add(table); return dataSet; } private static void AddDirectoryIds(SysTables.FileSystemInfosDataTable table) { Dictionary directoryIds = new Dictionary(); foreach (SysTables.FileSystemInfosRow row in table.Rows) { if (row.Type == "D") { if (directoryIds.ContainsKey(row.Path) == false) directoryIds.Add(row.Path, directoryIds.Count + 1); row.DirectoryId = directoryIds[row.Path]; } string parentDirectory = Path.GetDirectoryName(row.Path); int parentDirectoryId = 0; if (parentDirectory != null && directoryIds.ContainsKey(parentDirectory) == true) parentDirectoryId = directoryIds[parentDirectory]; row.ParentDirectoryId = parentDirectoryId; } } private static void DirectorySizes(SysTables.FileSystemInfosDataTable table) { DataView directoryView = new DataView(table); directoryView.Sort = "Depth DESC, Path"; directoryView.RowFilter = "Type = 'D'"; foreach (DataRowView directoryRowView in directoryView) { DataRow directoryRow = directoryRowView.Row; ulong size = 0; foreach (DataRow parentRow in table.Select("ParentDirectoryId = " + (int)directoryRow["DirectoryId"])) //, "Path")) // Much slower with sort would need for checksums! { //if (readCheckSums == true) //{ // string fileSum = (string)fileRow["CheckSum"]; // if (fileSum.Length == 0) // throw new ApplicationException("Bad Checksum"); // sums.AppendLine(fileSum); //} size += (ulong)parentRow["Length"]; } //if (readCheckSums == true) // dirRow["CheckSum"] = Spludlow.CheckSum.ComputeText(sums.ToString()); directoryRow["Length"] = size; } } public static void ListDirectoryWork(SysTables.FileSystemInfosDataTable table, DirectoryInfo directoryInfo, int depth, bool recursive) { if (recursive == true || depth > 0) ListDirectoryAddRow(table, directoryInfo, depth); if (directoryInfo.Attributes.HasFlag(FileAttributes.System) == true && depth > 0) return; if (recursive == false && depth > 0) return; foreach (FileSystemInfo fsInfo in directoryInfo.GetFileSystemInfos()) { if (fsInfo is DirectoryInfo) ListDirectoryWork(table, (DirectoryInfo)fsInfo, depth + 1, recursive); else ListDirectoryAddRow(table, fsInfo, depth + 1); } } private static void ListDirectoryAddRow(SysTables.FileSystemInfosDataTable table, FileSystemInfo fsInfo, int depth) { SysTables.FileSystemInfosRow row = table.NewFileSystemInfosRow(); char fsType = fsInfo.GetType().Name[0]; if (fsType != 'F' && fsType != 'D') throw new ApplicationException("Unsupported FS type:\t" + fsInfo.GetType().Name); row.Type = fsType.ToString(); row.Path = fsInfo.FullName; row.Extension = fsInfo.Extension.ToLower(); if (fsType == 'F') { FileInfo fileInfo = (FileInfo)fsInfo; row.Length = (ulong)fileInfo.Length; } else { row.Length = 0; } row.Attributes = (int)fsInfo.Attributes; row.CreationTime = fsInfo.CreationTime; row.CreationTimeUtc = fsInfo.CreationTimeUtc; row.LastAccessTime = fsInfo.LastAccessTime; row.LastAccessTimeUtc = fsInfo.LastAccessTimeUtc; row.LastWriteTime = fsInfo.LastWriteTime; row.LastWriteTimeUtc = fsInfo.LastWriteTimeUtc; row.Depth = depth; for (int index = 0; index < AttributeNames.Length; ++index) { if ((row.Attributes & AttributeValues[index]) == 0) row[AttributeNames[index]] = false; else row[AttributeNames[index]] = true; } table.Rows.Add(row); } public static void ListFileAttributes() { DataTable table = Spludlow.Data.TextTable.ReadText(new string[] { "Value HexValue Name", "Int32 String String", }); foreach (string name in Enum.GetNames(typeof(FileAttributes))) { FileAttributes attribute = (FileAttributes)Enum.Parse(typeof(FileAttributes), name); table.Rows.Add((int)attribute, ((int)attribute).ToString("X8"), name); } Spludlow.Log.Report("FileAttributes", table); } public static DataSet ListDrives(string host) { return (DataSet)Spludlow.Call.Now(host, "Spludlow", "Spludlow.Io.DirectoryList", "ListDrives", CallFlags.LargeResult); } public static DataSet ListDrives() { SysTables.DriveInfosDataTable table = new SysTables.DriveInfosDataTable(); foreach (DriveInfo info in DriveInfo.GetDrives()) { if (info.IsReady == false) continue; SysTables.DriveInfosRow row = table.NewDriveInfosRow(); row.AvailableFreeSpace = info.AvailableFreeSpace; row.DriveFormat = info.DriveFormat; row.DriveType = info.DriveType.ToString(); row.IsReady = info.IsReady; row.Name = info.Name; row.TotalFreeSpace = info.TotalFreeSpace; row.TotalSize = info.TotalSize; row.VolumeLabel = info.VolumeLabel; row.RootDirectoryAttributes = (int)info.RootDirectory.Attributes; row.RootDirectoryFullName = info.RootDirectory.FullName; if (row.TotalSize > 0) { decimal usedPercent = 100 - ((100 / (decimal)row.TotalSize) * (decimal)row.TotalFreeSpace); row.UsedPercent = Decimal.Round(usedPercent, 2); } table.Rows.Add(row); } DataSet dataSet = new DataSet(); dataSet.Tables.Add(table); return dataSet; } } }