From f1e839a64af039645396e88013f5127cc897688c Mon Sep 17 00:00:00 2001 From: Alex Barney Date: Tue, 7 May 2019 21:42:54 -0500 Subject: [PATCH] Add GetFreeSpaceSize and GetTotalSpaceSize --- src/LibHac.Nand/FatFileSystemProvider.cs | 12 +++++++++++- src/LibHac/IO/AesXtsFileSystem.cs | 10 ++++++++++ src/LibHac/IO/ConcatenationFileSystem.cs | 10 ++++++++++ src/LibHac/IO/IFileSystem.cs | 4 ++-- src/LibHac/IO/LayeredFileSystem.cs | 2 ++ src/LibHac/IO/LocalFileSystem.cs | 10 ++++++++++ src/LibHac/IO/PartitionFileSystem.cs | 2 ++ src/LibHac/IO/RomFs/RomFsFileSystem.cs | 2 ++ src/LibHac/IO/Save/AllocationTable.cs | 9 +++++++++ src/LibHac/IO/Save/SaveDataFileSystem.cs | 10 ++++++++++ src/LibHac/IO/Save/SaveDataFileSystemCore.cs | 11 +++++++++++ src/LibHac/IO/SubdirectoryFileSystem.cs | 14 ++++++++++++++ src/hactoolnet/ProcessSave.cs | 3 +++ 13 files changed, 96 insertions(+), 3 deletions(-) diff --git a/src/LibHac.Nand/FatFileSystemProvider.cs b/src/LibHac.Nand/FatFileSystemProvider.cs index b16baa15..6a994e21 100644 --- a/src/LibHac.Nand/FatFileSystemProvider.cs +++ b/src/LibHac.Nand/FatFileSystemProvider.cs @@ -106,6 +106,16 @@ namespace LibHac.Nand return timeStamp; } + public long GetFreeSpaceSize(string path) + { + return Fs.AvailableSpace; + } + + public long GetTotalSpaceSize(string path) + { + return Fs.Size; + } + public void Commit() { } public void CreateDirectory(string path) => throw new NotSupportedException(); @@ -113,7 +123,7 @@ namespace LibHac.Nand public void RenameDirectory(string srcPath, string dstPath) => throw new NotSupportedException(); public void RenameFile(string srcPath, string dstPath) => throw new NotSupportedException(); public void QueryEntry(Span outBuffer, Span inBuffer, string path, QueryId queryId) => throw new NotSupportedException(); - + private static FileAccess GetFileAccess(OpenMode mode) { // FileAccess and OpenMode have the same flags diff --git a/src/LibHac/IO/AesXtsFileSystem.cs b/src/LibHac/IO/AesXtsFileSystem.cs index c9c7bce3..837cb502 100644 --- a/src/LibHac/IO/AesXtsFileSystem.cs +++ b/src/LibHac/IO/AesXtsFileSystem.cs @@ -184,6 +184,16 @@ namespace LibHac.IO return BaseFileSystem.GetFileTimeStampRaw(path); } + public long GetFreeSpaceSize(string path) + { + return BaseFileSystem.GetFreeSpaceSize(path); + } + + public long GetTotalSpaceSize(string path) + { + return BaseFileSystem.GetTotalSpaceSize(path); + } + public void Commit() { BaseFileSystem.Commit(); diff --git a/src/LibHac/IO/ConcatenationFileSystem.cs b/src/LibHac/IO/ConcatenationFileSystem.cs index f62bd54f..a36d0cea 100644 --- a/src/LibHac/IO/ConcatenationFileSystem.cs +++ b/src/LibHac/IO/ConcatenationFileSystem.cs @@ -198,6 +198,16 @@ namespace LibHac.IO return BaseFileSystem.GetEntryType(path); } + public long GetFreeSpaceSize(string path) + { + return BaseFileSystem.GetFreeSpaceSize(path); + } + + public long GetTotalSpaceSize(string path) + { + return BaseFileSystem.GetTotalSpaceSize(path); + } + public FileTimeStampRaw GetFileTimeStampRaw(string path) { return BaseFileSystem.GetFileTimeStampRaw(path); diff --git a/src/LibHac/IO/IFileSystem.cs b/src/LibHac/IO/IFileSystem.cs index d597baf8..762a7236 100644 --- a/src/LibHac/IO/IFileSystem.cs +++ b/src/LibHac/IO/IFileSystem.cs @@ -105,9 +105,9 @@ namespace LibHac.IO /// The specified path does not exist. DirectoryEntryType GetEntryType(string path); - //long GetFreeSpaceSize(string path); + long GetFreeSpaceSize(string path); - //long GetTotalSpaceSize(string path); + long GetTotalSpaceSize(string path); FileTimeStampRaw GetFileTimeStampRaw(string path); diff --git a/src/LibHac/IO/LayeredFileSystem.cs b/src/LibHac/IO/LayeredFileSystem.cs index daece15f..5972fbc3 100644 --- a/src/LibHac/IO/LayeredFileSystem.cs +++ b/src/LibHac/IO/LayeredFileSystem.cs @@ -136,5 +136,7 @@ namespace LibHac.IO public void DeleteFile(string path) => throw new NotSupportedException(); public void RenameDirectory(string srcPath, string dstPath) => throw new NotSupportedException(); public void RenameFile(string srcPath, string dstPath) => throw new NotSupportedException(); + public long GetFreeSpaceSize(string path) => throw new NotSupportedException(); + public long GetTotalSpaceSize(string path) => throw new NotSupportedException(); } } diff --git a/src/LibHac/IO/LocalFileSystem.cs b/src/LibHac/IO/LocalFileSystem.cs index 3db52ec6..679b5ae2 100644 --- a/src/LibHac/IO/LocalFileSystem.cs +++ b/src/LibHac/IO/LocalFileSystem.cs @@ -174,6 +174,16 @@ namespace LibHac.IO return timeStamp; } + public long GetFreeSpaceSize(string path) + { + return new DriveInfo(BasePath).AvailableFreeSpace; + } + + public long GetTotalSpaceSize(string path) + { + return new DriveInfo(BasePath).TotalSize; + } + public void Commit() { } public void QueryEntry(Span outBuffer, Span inBuffer, string path, QueryId queryId) => throw new NotSupportedException(); diff --git a/src/LibHac/IO/PartitionFileSystem.cs b/src/LibHac/IO/PartitionFileSystem.cs index bf1c29e2..291b8fdf 100644 --- a/src/LibHac/IO/PartitionFileSystem.cs +++ b/src/LibHac/IO/PartitionFileSystem.cs @@ -81,6 +81,8 @@ namespace LibHac.IO public void DeleteFile(string path) => throw new NotSupportedException(); public void RenameDirectory(string srcPath, string dstPath) => throw new NotSupportedException(); public void RenameFile(string srcPath, string dstPath) => throw new NotSupportedException(); + public long GetFreeSpaceSize(string path) => throw new NotSupportedException(); + public long GetTotalSpaceSize(string path) => throw new NotSupportedException(); public FileTimeStampRaw GetFileTimeStampRaw(string path) => throw new NotSupportedException(); public void Commit() { } public void QueryEntry(Span outBuffer, Span inBuffer, string path, QueryId queryId) => throw new NotSupportedException(); diff --git a/src/LibHac/IO/RomFs/RomFsFileSystem.cs b/src/LibHac/IO/RomFs/RomFsFileSystem.cs index ecc9981e..b7953dac 100644 --- a/src/LibHac/IO/RomFs/RomFsFileSystem.cs +++ b/src/LibHac/IO/RomFs/RomFsFileSystem.cs @@ -89,6 +89,8 @@ namespace LibHac.IO.RomFs public void DeleteFile(string path) => throw new NotSupportedException(); public void RenameDirectory(string srcPath, string dstPath) => throw new NotSupportedException(); public void RenameFile(string srcPath, string dstPath) => throw new NotSupportedException(); + public long GetFreeSpaceSize(string path) => throw new NotSupportedException(); + public long GetTotalSpaceSize(string path) => throw new NotSupportedException(); public FileTimeStampRaw GetFileTimeStampRaw(string path) => throw new NotSupportedException(); public void QueryEntry(Span outBuffer, Span inBuffer, string path, QueryId queryId) => throw new NotSupportedException(); } diff --git a/src/LibHac/IO/Save/AllocationTable.cs b/src/LibHac/IO/Save/AllocationTable.cs index b12797cf..e986dadf 100644 --- a/src/LibHac/IO/Save/AllocationTable.cs +++ b/src/LibHac/IO/Save/AllocationTable.cs @@ -272,6 +272,15 @@ namespace LibHac.IO.Save WriteEntry(segAIndex, segA); } + public int GetFreeListLength() + { + int freeListStart = GetFreeListBlockIndex(); + + if (freeListStart == -1) return 0; + + return GetListLength(freeListStart); + } + public int GetListLength(int blockIndex) { int index = blockIndex; diff --git a/src/LibHac/IO/Save/SaveDataFileSystem.cs b/src/LibHac/IO/Save/SaveDataFileSystem.cs index d1207656..62873021 100644 --- a/src/LibHac/IO/Save/SaveDataFileSystem.cs +++ b/src/LibHac/IO/Save/SaveDataFileSystem.cs @@ -190,6 +190,16 @@ namespace LibHac.IO.Save return SaveDataFileSystemCore.GetEntryType(path); } + public long GetFreeSpaceSize(string path) + { + return SaveDataFileSystemCore.GetFreeSpaceSize(path); + } + + public long GetTotalSpaceSize(string path) + { + return SaveDataFileSystemCore.GetTotalSpaceSize(path); + } + public void Commit() { Commit(Keyset); diff --git a/src/LibHac/IO/Save/SaveDataFileSystemCore.cs b/src/LibHac/IO/Save/SaveDataFileSystemCore.cs index 72488ef2..b2514232 100644 --- a/src/LibHac/IO/Save/SaveDataFileSystemCore.cs +++ b/src/LibHac/IO/Save/SaveDataFileSystemCore.cs @@ -126,6 +126,17 @@ namespace LibHac.IO.Save throw new FileNotFoundException(path); } + public long GetFreeSpaceSize(string path) + { + int freeBlockCount = AllocationTable.GetFreeListLength(); + return Header.BlockSize * freeBlockCount; + } + + public long GetTotalSpaceSize(string path) + { + return Header.BlockSize * Header.BlockCount; + } + public void Commit() { diff --git a/src/LibHac/IO/SubdirectoryFileSystem.cs b/src/LibHac/IO/SubdirectoryFileSystem.cs index 1b0a2434..9eb8ec19 100644 --- a/src/LibHac/IO/SubdirectoryFileSystem.cs +++ b/src/LibHac/IO/SubdirectoryFileSystem.cs @@ -105,6 +105,20 @@ namespace LibHac.IO ParentFileSystem.Commit(); } + public long GetFreeSpaceSize(string path) + { + path = PathTools.Normalize(path); + + return ParentFileSystem.GetFreeSpaceSize(ResolveFullPath(path)); + } + + public long GetTotalSpaceSize(string path) + { + path = PathTools.Normalize(path); + + return ParentFileSystem.GetTotalSpaceSize(ResolveFullPath(path)); + } + public FileTimeStampRaw GetFileTimeStampRaw(string path) { path = PathTools.Normalize(path); diff --git a/src/hactoolnet/ProcessSave.cs b/src/hactoolnet/ProcessSave.cs index a72d8632..d111def5 100644 --- a/src/hactoolnet/ProcessSave.cs +++ b/src/hactoolnet/ProcessSave.cs @@ -269,6 +269,8 @@ namespace hactoolnet var sb = new StringBuilder(); sb.AppendLine(); + long freeSpace = save.GetFreeSpaceSize(""); + sb.AppendLine("Savefile:"); PrintItem(sb, colLen, $"CMAC Signature{save.Header.SignatureValidity.GetValidityString()}:", save.Header.Cmac); PrintItem(sb, colLen, "Title ID:", $"{save.Header.ExtraData.TitleId:x16}"); @@ -279,6 +281,7 @@ namespace hactoolnet PrintItem(sb, colLen, "Timestamp:", $"{DateTimeOffset.FromUnixTimeSeconds(save.Header.ExtraData.Timestamp):yyyy-MM-dd HH:mm:ss} UTC"); PrintItem(sb, colLen, "Save Data Size:", $"0x{save.Header.ExtraData.DataSize:x16} ({Util.GetBytesReadable(save.Header.ExtraData.DataSize)})"); PrintItem(sb, colLen, "Journal Size:", $"0x{save.Header.ExtraData.JournalSize:x16} ({Util.GetBytesReadable(save.Header.ExtraData.JournalSize)})"); + PrintItem(sb, colLen, "Free Space:", $"0x{freeSpace:x16} ({Util.GetBytesReadable(freeSpace)})"); PrintItem(sb, colLen, $"Header Hash{save.Header.HeaderHashValidity.GetValidityString()}:", save.Header.Layout.Hash); PrintItem(sb, colLen, "Number of Files:", save.EnumerateEntries().Count(x => x.Type == DirectoryEntryType.File));