mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
3d50085e22
*Create an IStorage interface and Storage abstract class to use instead of Stream * Improve AES-XTS performance by ~16x * Double AES-CTR performance: 800 MB/s -> 1600 MB/s on a 6700K * Add AES-XTS tests * Add AES benchmark and AES-CTR writing * Add support for a hashed FAT in save files * Add option to export decrypted NCA * Allow opening decrypted package1 and package2 * Make sure romfs disposal can cascade all the way down * Validate NCA, NPDM and package2 signatures
69 lines
2.5 KiB
C#
69 lines
2.5 KiB
C#
using System;
|
|
using System.Text;
|
|
using LibHac;
|
|
using LibHac.IO;
|
|
|
|
namespace hactoolnet
|
|
{
|
|
internal static class Print
|
|
{
|
|
public static void PrintItem(StringBuilder sb, int colLen, string prefix, object data)
|
|
{
|
|
if (data is byte[] byteData)
|
|
{
|
|
sb.MemDump(prefix.PadRight(colLen), byteData);
|
|
}
|
|
else
|
|
{
|
|
sb.AppendLine(prefix.PadRight(colLen) + data);
|
|
}
|
|
}
|
|
|
|
public static string GetValidityString(this Validity validity)
|
|
{
|
|
switch (validity)
|
|
{
|
|
case Validity.Invalid: return " (FAIL)";
|
|
case Validity.Valid: return " (GOOD)";
|
|
default: return string.Empty;
|
|
}
|
|
}
|
|
|
|
public static void PrintIvfcHash(StringBuilder sb, int colLen, int indentSize, IvfcHeader ivfcInfo, IntegrityStorageType type)
|
|
{
|
|
string prefix = new string(' ', indentSize);
|
|
string prefix2 = new string(' ', indentSize + 4);
|
|
|
|
if (type == IntegrityStorageType.RomFs)
|
|
PrintItem(sb, colLen, $"{prefix}Master Hash{ivfcInfo.LevelHeaders[0].HashValidity.GetValidityString()}:", ivfcInfo.MasterHash);
|
|
|
|
PrintItem(sb, colLen, $"{prefix}Magic:", ivfcInfo.Magic);
|
|
PrintItem(sb, colLen, $"{prefix}Version:", ivfcInfo.Version);
|
|
|
|
if (type == IntegrityStorageType.Save)
|
|
PrintItem(sb, colLen, $"{prefix}Salt Seed:", ivfcInfo.SaltSource);
|
|
|
|
int levelCount = Math.Max(ivfcInfo.NumLevels - 1, 0);
|
|
if (type == IntegrityStorageType.Save) levelCount = 4;
|
|
|
|
int offsetLen = type == IntegrityStorageType.Save ? 16 : 12;
|
|
|
|
for (int i = 0; i < levelCount; i++)
|
|
{
|
|
IvfcLevelHeader level = ivfcInfo.LevelHeaders[i];
|
|
long hashOffset = 0;
|
|
|
|
if (i != 0)
|
|
{
|
|
hashOffset = ivfcInfo.LevelHeaders[i - 1].Offset;
|
|
}
|
|
|
|
sb.AppendLine($"{prefix}Level {i}{level.HashValidity.GetValidityString()}:");
|
|
PrintItem(sb, colLen, $"{prefix2}Data Offset:", $"0x{level.Offset.ToString($"x{offsetLen}")}");
|
|
PrintItem(sb, colLen, $"{prefix2}Data Size:", $"0x{level.Size.ToString($"x{offsetLen}")}");
|
|
PrintItem(sb, colLen, $"{prefix2}Hash Offset:", $"0x{hashOffset.ToString($"x{offsetLen}")}");
|
|
PrintItem(sb, colLen, $"{prefix2}Hash BlockSize:", $"0x{1 << level.BlockSizePower:x8}");
|
|
}
|
|
}
|
|
}
|
|
}
|