mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
Use an enum instead of a bool for integrity checking levels
This commit is contained in:
parent
a64cbeca5b
commit
24e6434765
12 changed files with 100 additions and 71 deletions
|
@ -8,18 +8,18 @@ namespace LibHac
|
||||||
{
|
{
|
||||||
public Stream[] Levels { get; }
|
public Stream[] Levels { get; }
|
||||||
public Stream DataLevel { get; }
|
public Stream DataLevel { get; }
|
||||||
public bool EnableIntegrityChecks { get; }
|
public IntegrityCheckLevel IntegrityCheckLevel { get; }
|
||||||
|
|
||||||
public HierarchicalIntegrityVerificationStream(IntegrityVerificationInfo[] levelInfo, bool enableIntegrityChecks)
|
public HierarchicalIntegrityVerificationStream(IntegrityVerificationInfo[] levelInfo, IntegrityCheckLevel integrityCheckLevel)
|
||||||
{
|
{
|
||||||
Levels = new Stream[levelInfo.Length];
|
Levels = new Stream[levelInfo.Length];
|
||||||
EnableIntegrityChecks = enableIntegrityChecks;
|
IntegrityCheckLevel = integrityCheckLevel;
|
||||||
|
|
||||||
Levels[0] = levelInfo[0].Data;
|
Levels[0] = levelInfo[0].Data;
|
||||||
|
|
||||||
for (int i = 1; i < Levels.Length; i++)
|
for (int i = 1; i < Levels.Length; i++)
|
||||||
{
|
{
|
||||||
var levelData = new IntegrityVerificationStream(levelInfo[i], Levels[i - 1], enableIntegrityChecks);
|
var levelData = new IntegrityVerificationStream(levelInfo[i], Levels[i - 1], integrityCheckLevel);
|
||||||
|
|
||||||
Levels[i] = new RandomAccessSectorStream(levelData);
|
Levels[i] = new RandomAccessSectorStream(levelData);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ namespace LibHac
|
||||||
private const int DigestSize = 0x20;
|
private const int DigestSize = 0x20;
|
||||||
|
|
||||||
private Stream HashStream { get; }
|
private Stream HashStream { get; }
|
||||||
public bool EnableIntegrityChecks { get; }
|
public IntegrityCheckLevel IntegrityCheckLevel { get; }
|
||||||
|
|
||||||
private byte[] Salt { get; }
|
private byte[] Salt { get; }
|
||||||
private IntegrityStreamType Type { get; }
|
private IntegrityStreamType Type { get; }
|
||||||
|
@ -18,11 +18,11 @@ namespace LibHac
|
||||||
private readonly byte[] _hashBuffer = new byte[DigestSize];
|
private readonly byte[] _hashBuffer = new byte[DigestSize];
|
||||||
private readonly SHA256 _hash = SHA256.Create();
|
private readonly SHA256 _hash = SHA256.Create();
|
||||||
|
|
||||||
public IntegrityVerificationStream(IntegrityVerificationInfo info, Stream hashStream, bool enableIntegrityChecks)
|
public IntegrityVerificationStream(IntegrityVerificationInfo info, Stream hashStream, IntegrityCheckLevel integrityCheckLevel)
|
||||||
: base(info.Data, info.BlockSize)
|
: base(info.Data, info.BlockSize)
|
||||||
{
|
{
|
||||||
HashStream = hashStream;
|
HashStream = hashStream;
|
||||||
EnableIntegrityChecks = enableIntegrityChecks;
|
IntegrityCheckLevel = integrityCheckLevel;
|
||||||
Salt = info.Salt;
|
Salt = info.Salt;
|
||||||
Type = info.Type;
|
Type = info.Type;
|
||||||
}
|
}
|
||||||
|
@ -84,7 +84,7 @@ namespace LibHac
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!EnableIntegrityChecks) return bytesRead;
|
if (IntegrityCheckLevel == IntegrityCheckLevel.None) return bytesRead;
|
||||||
|
|
||||||
_hash.Initialize();
|
_hash.Initialize();
|
||||||
|
|
||||||
|
@ -139,4 +139,23 @@ namespace LibHac
|
||||||
RomFs,
|
RomFs,
|
||||||
PartitionFs
|
PartitionFs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents the level of integrity checks to be performed.
|
||||||
|
/// </summary>
|
||||||
|
public enum IntegrityCheckLevel
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// No integrity checks will be performed.
|
||||||
|
/// </summary>
|
||||||
|
None,
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
WarnOnInvalid,
|
||||||
|
/// <summary>
|
||||||
|
/// An <see cref="InvalidDataException"/> will be thrown if an integrity check fails.
|
||||||
|
/// </summary>
|
||||||
|
ErrorOnInvalid
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -140,7 +140,7 @@ namespace LibHac
|
||||||
false);
|
false);
|
||||||
if (BaseNca == null) return rawStream;
|
if (BaseNca == null) return rawStream;
|
||||||
|
|
||||||
Stream baseStream = BaseNca.OpenSection(ProgramPartitionType.Data, true, false);
|
Stream baseStream = BaseNca.OpenSection(ProgramPartitionType.Data, true, IntegrityCheckLevel.None);
|
||||||
if (baseStream == null) throw new InvalidDataException("Base NCA has no RomFS section");
|
if (baseStream == null) throw new InvalidDataException("Base NCA has no RomFS section");
|
||||||
|
|
||||||
return new Bktr(rawStream, baseStream, sect);
|
return new Bktr(rawStream, baseStream, sect);
|
||||||
|
@ -155,11 +155,11 @@ namespace LibHac
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="index">The index of the NCA section to open. Valid indexes are 0-3.</param>
|
/// <param name="index">The index of the NCA section to open. Valid indexes are 0-3.</param>
|
||||||
/// <param name="raw"><see langword="true"/> to open the raw section with hash metadata.</param>
|
/// <param name="raw"><see langword="true"/> to open the raw section with hash metadata.</param>
|
||||||
/// <param name="enableIntegrityChecks"><see langword="true"/> to enable data integrity checks when reading the section.
|
/// <param name="integrityCheckLevel">The level of integrity checks to be performed when reading the section.
|
||||||
/// Only applies if <paramref name="raw"/> is <see langword="false"/>.</param>
|
/// Always <see cref="IntegrityCheckLevel.None"/> if <paramref name="raw"/> is <see langword="false"/>.</param>
|
||||||
/// <returns>A <see cref="Stream"/> that provides access to the specified section. <see langword="null"/> if the section does not exist.</returns>
|
/// <returns>A <see cref="Stream"/> that provides access to the specified section. <see langword="null"/> if the section does not exist.</returns>
|
||||||
/// <exception cref="ArgumentOutOfRangeException">The specified <paramref name="index"/> is outside the valid range.</exception>
|
/// <exception cref="ArgumentOutOfRangeException">The specified <paramref name="index"/> is outside the valid range.</exception>
|
||||||
public Stream OpenSection(int index, bool raw, bool enableIntegrityChecks)
|
public Stream OpenSection(int index, bool raw, IntegrityCheckLevel integrityCheckLevel)
|
||||||
{
|
{
|
||||||
Stream rawStream = OpenRawSection(index);
|
Stream rawStream = OpenRawSection(index);
|
||||||
NcaSection sect = Sections[index];
|
NcaSection sect = Sections[index];
|
||||||
|
@ -173,9 +173,9 @@ namespace LibHac
|
||||||
switch (header.HashType)
|
switch (header.HashType)
|
||||||
{
|
{
|
||||||
case NcaHashType.Sha256:
|
case NcaHashType.Sha256:
|
||||||
return InitIvfcForPartitionfs(header.Sha256Info, new SharedStreamSource(rawStream), enableIntegrityChecks);
|
return InitIvfcForPartitionfs(header.Sha256Info, new SharedStreamSource(rawStream), integrityCheckLevel);
|
||||||
case NcaHashType.Ivfc:
|
case NcaHashType.Ivfc:
|
||||||
return InitIvfcForRomfs(header.IvfcInfo, new SharedStreamSource(rawStream), enableIntegrityChecks);
|
return InitIvfcForRomfs(header.IvfcInfo, new SharedStreamSource(rawStream), integrityCheckLevel);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new ArgumentOutOfRangeException();
|
throw new ArgumentOutOfRangeException();
|
||||||
|
@ -187,15 +187,15 @@ namespace LibHac
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="type">The type of section to open.</param>
|
/// <param name="type">The type of section to open.</param>
|
||||||
/// <param name="raw"><see langword="true"/> to open the raw section with hash metadata.</param>
|
/// <param name="raw"><see langword="true"/> to open the raw section with hash metadata.</param>
|
||||||
/// <param name="enableIntegrityChecks"><see langword="true"/> to enable data integrity checks when reading the section.
|
/// <param name="integrityCheckLevel">The level of integrity checks to be performed when reading the section.
|
||||||
/// Only applies if <paramref name="raw"/> is <see langword="false"/>.</param>
|
/// Always <see cref="IntegrityCheckLevel.None"/> if <paramref name="raw"/> is <see langword="false"/>.</param>
|
||||||
/// <returns>A <see cref="Stream"/> that provides access to the specified section. <see langword="null"/> if the section does not exist.</returns>
|
/// <returns>A <see cref="Stream"/> that provides access to the specified section. <see langword="null"/> if the section does not exist.</returns>
|
||||||
/// <exception cref="ArgumentOutOfRangeException">The specified <paramref name="type"/> is outside the valid range.</exception>
|
/// <exception cref="ArgumentOutOfRangeException">The specified <paramref name="type"/> is outside the valid range.</exception>
|
||||||
public Stream OpenSection(ProgramPartitionType type, bool raw, bool enableIntegrityChecks) =>
|
public Stream OpenSection(ProgramPartitionType type, bool raw, IntegrityCheckLevel integrityCheckLevel) =>
|
||||||
OpenSection((int)type, raw, enableIntegrityChecks);
|
OpenSection((int)type, raw, integrityCheckLevel);
|
||||||
|
|
||||||
private static HierarchicalIntegrityVerificationStream InitIvfcForRomfs(IvfcHeader ivfc,
|
private static HierarchicalIntegrityVerificationStream InitIvfcForRomfs(IvfcHeader ivfc,
|
||||||
SharedStreamSource romfsStreamSource, bool enableIntegrityChecks)
|
SharedStreamSource romfsStreamSource, IntegrityCheckLevel integrityCheckLevel)
|
||||||
{
|
{
|
||||||
var initInfo = new IntegrityVerificationInfo[ivfc.NumLevels];
|
var initInfo = new IntegrityVerificationInfo[ivfc.NumLevels];
|
||||||
|
|
||||||
|
@ -219,11 +219,11 @@ namespace LibHac
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return new HierarchicalIntegrityVerificationStream(initInfo, enableIntegrityChecks);
|
return new HierarchicalIntegrityVerificationStream(initInfo, integrityCheckLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Stream InitIvfcForPartitionfs(Sha256Info sb,
|
private static Stream InitIvfcForPartitionfs(Sha256Info sb,
|
||||||
SharedStreamSource pfsStreamSource, bool enableIntegrityChecks)
|
SharedStreamSource pfsStreamSource, IntegrityCheckLevel integrityCheckLevel)
|
||||||
{
|
{
|
||||||
SharedStream hashStream = pfsStreamSource.CreateStream(sb.HashTableOffset, sb.HashTableSize);
|
SharedStream hashStream = pfsStreamSource.CreateStream(sb.HashTableOffset, sb.HashTableSize);
|
||||||
SharedStream dataStream = pfsStreamSource.CreateStream(sb.DataOffset, sb.DataSize);
|
SharedStream dataStream = pfsStreamSource.CreateStream(sb.DataOffset, sb.DataSize);
|
||||||
|
@ -252,7 +252,7 @@ namespace LibHac
|
||||||
Type = IntegrityStreamType.PartitionFs
|
Type = IntegrityStreamType.PartitionFs
|
||||||
};
|
};
|
||||||
|
|
||||||
return new HierarchicalIntegrityVerificationStream(initInfo, enableIntegrityChecks);
|
return new HierarchicalIntegrityVerificationStream(initInfo, integrityCheckLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -376,7 +376,7 @@ namespace LibHac
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream stream = OpenSection(index, true, false);
|
Stream stream = OpenSection(index, true, IntegrityCheckLevel.None);
|
||||||
|
|
||||||
var hashTable = new byte[size];
|
var hashTable = new byte[size];
|
||||||
stream.Position = offset;
|
stream.Position = offset;
|
||||||
|
@ -385,25 +385,6 @@ namespace LibHac
|
||||||
sect.MasterHashValidity = Crypto.CheckMemoryHashTable(hashTable, expected, 0, hashTable.Length);
|
sect.MasterHashValidity = Crypto.CheckMemoryHashTable(hashTable, expected, 0, hashTable.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void VerifySection(int index, IProgressReport logger = null)
|
|
||||||
{
|
|
||||||
if (Sections[index] == null) throw new ArgumentOutOfRangeException(nameof(index));
|
|
||||||
|
|
||||||
NcaSection sect = Sections[index];
|
|
||||||
Stream stream = OpenSection(index, false, true);
|
|
||||||
logger?.LogMessage($"Verifying section {index}...");
|
|
||||||
|
|
||||||
switch (sect.Header.HashType)
|
|
||||||
{
|
|
||||||
case NcaHashType.Sha256:
|
|
||||||
break;
|
|
||||||
case NcaHashType.Ivfc:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new ArgumentOutOfRangeException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
if (!KeepOpen)
|
if (!KeepOpen)
|
||||||
|
@ -444,12 +425,12 @@ namespace LibHac
|
||||||
|
|
||||||
public static class NcaExtensions
|
public static class NcaExtensions
|
||||||
{
|
{
|
||||||
public static void ExportSection(this Nca nca, int index, string filename, bool raw = false, bool verify = false, IProgressReport logger = null)
|
public static void ExportSection(this Nca nca, int index, string filename, bool raw = false, IntegrityCheckLevel integrityCheckLevel = IntegrityCheckLevel.None, IProgressReport logger = null)
|
||||||
{
|
{
|
||||||
if (index < 0 || index > 3) throw new IndexOutOfRangeException();
|
if (index < 0 || index > 3) throw new IndexOutOfRangeException();
|
||||||
if (nca.Sections[index] == null) return;
|
if (nca.Sections[index] == null) return;
|
||||||
|
|
||||||
Stream section = nca.OpenSection(index, raw, verify);
|
Stream section = nca.OpenSection(index, raw, integrityCheckLevel);
|
||||||
string dir = Path.GetDirectoryName(filename);
|
string dir = Path.GetDirectoryName(filename);
|
||||||
if (!string.IsNullOrWhiteSpace(dir)) Directory.CreateDirectory(dir);
|
if (!string.IsNullOrWhiteSpace(dir)) Directory.CreateDirectory(dir);
|
||||||
|
|
||||||
|
@ -459,13 +440,13 @@ namespace LibHac
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ExtractSection(this Nca nca, int index, string outputDir, bool verify = false, IProgressReport logger = null)
|
public static void ExtractSection(this Nca nca, int index, string outputDir, IntegrityCheckLevel integrityCheckLevel = IntegrityCheckLevel.None, IProgressReport logger = null)
|
||||||
{
|
{
|
||||||
if (index < 0 || index > 3) throw new IndexOutOfRangeException();
|
if (index < 0 || index > 3) throw new IndexOutOfRangeException();
|
||||||
if (nca.Sections[index] == null) return;
|
if (nca.Sections[index] == null) return;
|
||||||
|
|
||||||
NcaSection section = nca.Sections[index];
|
NcaSection section = nca.Sections[index];
|
||||||
Stream stream = nca.OpenSection(index, false, verify);
|
Stream stream = nca.OpenSection(index, false, integrityCheckLevel);
|
||||||
|
|
||||||
switch (section.Type)
|
switch (section.Type)
|
||||||
{
|
{
|
||||||
|
@ -483,5 +464,31 @@ namespace LibHac
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void VerifySection(this Nca nca, int index, IProgressReport logger = null)
|
||||||
|
{
|
||||||
|
if (nca.Sections[index] == null) throw new ArgumentOutOfRangeException(nameof(index));
|
||||||
|
|
||||||
|
NcaSection sect = nca.Sections[index];
|
||||||
|
Stream stream = nca.OpenSection(index, false, IntegrityCheckLevel.WarnOnInvalid);
|
||||||
|
logger?.LogMessage($"Verifying section {index}...");
|
||||||
|
|
||||||
|
switch (sect.Header.HashType)
|
||||||
|
{
|
||||||
|
case NcaHashType.Sha256:
|
||||||
|
case NcaHashType.Ivfc:
|
||||||
|
if (stream is HierarchicalIntegrityVerificationStream ivfc)
|
||||||
|
{
|
||||||
|
for (int i = 1; i < ivfc.Levels.Length; i++)
|
||||||
|
{
|
||||||
|
logger?.LogMessage($" Verifying IVFC Level {i}...");
|
||||||
|
ivfc.Levels[i].CopyStream(Stream.Null, ivfc.Levels[i].Length, logger);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new ArgumentOutOfRangeException();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ namespace LibHac.Savefile
|
||||||
public DirectoryEntry[] Directories { get; private set; }
|
public DirectoryEntry[] Directories { get; private set; }
|
||||||
private Dictionary<string, FileEntry> FileDict { get; }
|
private Dictionary<string, FileEntry> FileDict { get; }
|
||||||
|
|
||||||
public Savefile(Keyset keyset, Stream file, bool enableIntegrityChecks)
|
public Savefile(Keyset keyset, Stream file, IntegrityCheckLevel integrityCheckLevel)
|
||||||
{
|
{
|
||||||
SavefileSource = new SharedStreamSource(file);
|
SavefileSource = new SharedStreamSource(file);
|
||||||
|
|
||||||
|
@ -106,7 +106,7 @@ namespace LibHac.Savefile
|
||||||
JournalStream = new JournalStream(journalData, journalMap, (int)Header.Journal.BlockSize);
|
JournalStream = new JournalStream(journalData, journalMap, (int)Header.Journal.BlockSize);
|
||||||
JournalStreamSource = new SharedStreamSource(JournalStream);
|
JournalStreamSource = new SharedStreamSource(JournalStream);
|
||||||
|
|
||||||
IvfcStream = InitIvfcStream(enableIntegrityChecks);
|
IvfcStream = InitIvfcStream(integrityCheckLevel);
|
||||||
IvfcStreamSource = new SharedStreamSource(IvfcStream);
|
IvfcStreamSource = new SharedStreamSource(IvfcStream);
|
||||||
|
|
||||||
ReadFileInfo();
|
ReadFileInfo();
|
||||||
|
@ -120,7 +120,7 @@ namespace LibHac.Savefile
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private HierarchicalIntegrityVerificationStream InitIvfcStream(bool enableIntegrityChecks)
|
private HierarchicalIntegrityVerificationStream InitIvfcStream(IntegrityCheckLevel integrityCheckLevel)
|
||||||
{
|
{
|
||||||
IvfcHeader ivfc = Header.Ivfc;
|
IvfcHeader ivfc = Header.Ivfc;
|
||||||
|
|
||||||
|
@ -151,7 +151,7 @@ namespace LibHac.Savefile
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return new HierarchicalIntegrityVerificationStream(initInfo, enableIntegrityChecks);
|
return new HierarchicalIntegrityVerificationStream(initInfo, integrityCheckLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Stream OpenFile(string filename)
|
public Stream OpenFile(string filename)
|
||||||
|
|
|
@ -126,7 +126,7 @@ namespace LibHac
|
||||||
|
|
||||||
string sdPath = "/" + Util.GetRelativePath(file, SaveDir).Replace('\\', '/');
|
string sdPath = "/" + Util.GetRelativePath(file, SaveDir).Replace('\\', '/');
|
||||||
var nax0 = new Nax0(Keyset, stream, sdPath, false);
|
var nax0 = new Nax0(Keyset, stream, sdPath, false);
|
||||||
save = new Savefile.Savefile(Keyset, nax0.Stream, false);
|
save = new Savefile.Savefile(Keyset, nax0.Stream, IntegrityCheckLevel.None);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
@ -147,7 +147,7 @@ namespace LibHac
|
||||||
var title = new Title();
|
var title = new Title();
|
||||||
|
|
||||||
// Meta contents always have 1 Partition FS section with 1 file in it
|
// Meta contents always have 1 Partition FS section with 1 file in it
|
||||||
Stream sect = nca.OpenSection(0, false, true);
|
Stream sect = nca.OpenSection(0, false, IntegrityCheckLevel.ErrorOnInvalid);
|
||||||
var pfs0 = new Pfs(sect);
|
var pfs0 = new Pfs(sect);
|
||||||
Stream file = pfs0.OpenFile(pfs0.Files[0]);
|
Stream file = pfs0.OpenFile(pfs0.Files[0]);
|
||||||
|
|
||||||
|
@ -187,7 +187,7 @@ namespace LibHac
|
||||||
{
|
{
|
||||||
foreach (Title title in Titles.Values.Where(x => x.ControlNca != null))
|
foreach (Title title in Titles.Values.Where(x => x.ControlNca != null))
|
||||||
{
|
{
|
||||||
var romfs = new Romfs(title.ControlNca.OpenSection(0, false, true));
|
var romfs = new Romfs(title.ControlNca.OpenSection(0, false, IntegrityCheckLevel.ErrorOnInvalid));
|
||||||
byte[] control = romfs.GetFile("/control.nacp");
|
byte[] control = romfs.GetFile("/control.nacp");
|
||||||
|
|
||||||
var reader = new BinaryReader(new MemoryStream(control));
|
var reader = new BinaryReader(new MemoryStream(control));
|
||||||
|
|
|
@ -102,7 +102,7 @@ namespace NandReader
|
||||||
private static List<Ticket> ReadTickets(Keyset keyset, Stream savefile)
|
private static List<Ticket> ReadTickets(Keyset keyset, Stream savefile)
|
||||||
{
|
{
|
||||||
var tickets = new List<Ticket>();
|
var tickets = new List<Ticket>();
|
||||||
var save = new Savefile(keyset, savefile, false);
|
var save = new Savefile(keyset, savefile, IntegrityCheckLevel.None);
|
||||||
var ticketList = new BinaryReader(save.OpenFile("/ticket_list.bin"));
|
var ticketList = new BinaryReader(save.OpenFile("/ticket_list.bin"));
|
||||||
var ticketFile = new BinaryReader(save.OpenFile("/ticket.bin"));
|
var ticketFile = new BinaryReader(save.OpenFile("/ticket.bin"));
|
||||||
|
|
||||||
|
|
|
@ -84,7 +84,7 @@ namespace NandReaderGui.ViewModel
|
||||||
private static List<Ticket> ReadTickets(Keyset keyset, Stream savefile)
|
private static List<Ticket> ReadTickets(Keyset keyset, Stream savefile)
|
||||||
{
|
{
|
||||||
var tickets = new List<Ticket>();
|
var tickets = new List<Ticket>();
|
||||||
var save = new Savefile(keyset, savefile, false);
|
var save = new Savefile(keyset, savefile, IntegrityCheckLevel.None);
|
||||||
var ticketList = new BinaryReader(save.OpenFile("/ticket_list.bin"));
|
var ticketList = new BinaryReader(save.OpenFile("/ticket_list.bin"));
|
||||||
var ticketFile = new BinaryReader(save.OpenFile("/ticket.bin"));
|
var ticketFile = new BinaryReader(save.OpenFile("/ticket.bin"));
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,9 @@ namespace hactoolnet
|
||||||
public bool ListRomFs;
|
public bool ListRomFs;
|
||||||
public bool SignSave;
|
public bool SignSave;
|
||||||
public ulong TitleId;
|
public ulong TitleId;
|
||||||
|
|
||||||
|
public IntegrityCheckLevel IntegrityLevel =>
|
||||||
|
EnableHash ? IntegrityCheckLevel.ErrorOnInvalid : IntegrityCheckLevel.None;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal enum FileType
|
internal enum FileType
|
||||||
|
|
|
@ -26,12 +26,12 @@ namespace hactoolnet
|
||||||
{
|
{
|
||||||
if (ctx.Options.SectionOut[i] != null)
|
if (ctx.Options.SectionOut[i] != null)
|
||||||
{
|
{
|
||||||
nca.ExportSection(i, ctx.Options.SectionOut[i], ctx.Options.Raw, ctx.Options.EnableHash, ctx.Logger);
|
nca.ExportSection(i, ctx.Options.SectionOut[i], ctx.Options.Raw, ctx.Options.IntegrityLevel, ctx.Logger);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx.Options.SectionOutDir[i] != null)
|
if (ctx.Options.SectionOutDir[i] != null)
|
||||||
{
|
{
|
||||||
nca.ExtractSection(i, ctx.Options.SectionOutDir[i], ctx.Options.EnableHash, ctx.Logger);
|
nca.ExtractSection(i, ctx.Options.SectionOutDir[i], ctx.Options.IntegrityLevel, ctx.Logger);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx.Options.Validate && nca.Sections[i] != null)
|
if (ctx.Options.Validate && nca.Sections[i] != null)
|
||||||
|
@ -42,7 +42,7 @@ namespace hactoolnet
|
||||||
|
|
||||||
if (ctx.Options.ListRomFs && nca.Sections[1] != null)
|
if (ctx.Options.ListRomFs && nca.Sections[1] != null)
|
||||||
{
|
{
|
||||||
var romfs = new Romfs(nca.OpenSection(1, false, ctx.Options.EnableHash));
|
var romfs = new Romfs(nca.OpenSection(1, false, ctx.Options.IntegrityLevel));
|
||||||
|
|
||||||
foreach (RomfsFile romfsFile in romfs.Files)
|
foreach (RomfsFile romfsFile in romfs.Files)
|
||||||
{
|
{
|
||||||
|
@ -68,12 +68,12 @@ namespace hactoolnet
|
||||||
|
|
||||||
if (ctx.Options.RomfsOut != null)
|
if (ctx.Options.RomfsOut != null)
|
||||||
{
|
{
|
||||||
nca.ExportSection(section.SectionNum, ctx.Options.RomfsOut, ctx.Options.Raw, ctx.Options.EnableHash, ctx.Logger);
|
nca.ExportSection(section.SectionNum, ctx.Options.RomfsOut, ctx.Options.Raw, ctx.Options.IntegrityLevel, ctx.Logger);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx.Options.RomfsOutDir != null)
|
if (ctx.Options.RomfsOutDir != null)
|
||||||
{
|
{
|
||||||
var romfs = new Romfs(nca.OpenSection(section.SectionNum, false, ctx.Options.EnableHash));
|
var romfs = new Romfs(nca.OpenSection(section.SectionNum, false, ctx.Options.IntegrityLevel));
|
||||||
romfs.Extract(ctx.Options.RomfsOutDir, ctx.Logger);
|
romfs.Extract(ctx.Options.RomfsOutDir, ctx.Logger);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -90,12 +90,12 @@ namespace hactoolnet
|
||||||
|
|
||||||
if (ctx.Options.ExefsOut != null)
|
if (ctx.Options.ExefsOut != null)
|
||||||
{
|
{
|
||||||
nca.ExportSection(section.SectionNum, ctx.Options.ExefsOut, ctx.Options.Raw, ctx.Options.EnableHash, ctx.Logger);
|
nca.ExportSection(section.SectionNum, ctx.Options.ExefsOut, ctx.Options.Raw, ctx.Options.IntegrityLevel, ctx.Logger);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx.Options.ExefsOutDir != null)
|
if (ctx.Options.ExefsOutDir != null)
|
||||||
{
|
{
|
||||||
nca.ExtractSection(section.SectionNum, ctx.Options.ExefsOutDir, ctx.Options.EnableHash, ctx.Logger);
|
nca.ExtractSection(section.SectionNum, ctx.Options.ExefsOutDir, ctx.Options.IntegrityLevel, ctx.Logger);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ namespace hactoolnet
|
||||||
{
|
{
|
||||||
using (var file = new FileStream(ctx.Options.InFile, FileMode.Open, FileAccess.ReadWrite))
|
using (var file = new FileStream(ctx.Options.InFile, FileMode.Open, FileAccess.ReadWrite))
|
||||||
{
|
{
|
||||||
var save = new Savefile(ctx.Keyset, file, ctx.Options.EnableHash);
|
var save = new Savefile(ctx.Keyset, file, ctx.Options.IntegrityLevel);
|
||||||
|
|
||||||
if (ctx.Options.OutDir != null)
|
if (ctx.Options.OutDir != null)
|
||||||
{
|
{
|
||||||
|
|
|
@ -55,12 +55,12 @@ namespace hactoolnet
|
||||||
|
|
||||||
if (ctx.Options.ExefsOutDir != null)
|
if (ctx.Options.ExefsOutDir != null)
|
||||||
{
|
{
|
||||||
title.MainNca.ExtractSection(section.SectionNum, ctx.Options.ExefsOutDir, ctx.Options.EnableHash, ctx.Logger);
|
title.MainNca.ExtractSection(section.SectionNum, ctx.Options.ExefsOutDir, ctx.Options.IntegrityLevel, ctx.Logger);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx.Options.ExefsOut != null)
|
if (ctx.Options.ExefsOut != null)
|
||||||
{
|
{
|
||||||
title.MainNca.ExportSection(section.SectionNum, ctx.Options.ExefsOut, ctx.Options.Raw, ctx.Options.EnableHash, ctx.Logger);
|
title.MainNca.ExportSection(section.SectionNum, ctx.Options.ExefsOut, ctx.Options.Raw, ctx.Options.IntegrityLevel, ctx.Logger);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,13 +95,13 @@ namespace hactoolnet
|
||||||
|
|
||||||
if (ctx.Options.RomfsOutDir != null)
|
if (ctx.Options.RomfsOutDir != null)
|
||||||
{
|
{
|
||||||
var romfs = new Romfs(title.MainNca.OpenSection(section.SectionNum, false, ctx.Options.EnableHash));
|
var romfs = new Romfs(title.MainNca.OpenSection(section.SectionNum, false, ctx.Options.IntegrityLevel));
|
||||||
romfs.Extract(ctx.Options.RomfsOutDir, ctx.Logger);
|
romfs.Extract(ctx.Options.RomfsOutDir, ctx.Logger);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx.Options.RomfsOut != null)
|
if (ctx.Options.RomfsOut != null)
|
||||||
{
|
{
|
||||||
title.MainNca.ExportSection(section.SectionNum, ctx.Options.RomfsOut, ctx.Options.Raw, ctx.Options.EnableHash, ctx.Logger);
|
title.MainNca.ExportSection(section.SectionNum, ctx.Options.RomfsOut, ctx.Options.Raw, ctx.Options.IntegrityLevel, ctx.Logger);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -79,12 +79,12 @@ namespace hactoolnet
|
||||||
|
|
||||||
if (ctx.Options.ExefsOutDir != null)
|
if (ctx.Options.ExefsOutDir != null)
|
||||||
{
|
{
|
||||||
mainNca.ExtractSection(exefsSection.SectionNum, ctx.Options.ExefsOutDir, ctx.Options.EnableHash, ctx.Logger);
|
mainNca.ExtractSection(exefsSection.SectionNum, ctx.Options.ExefsOutDir, ctx.Options.IntegrityLevel, ctx.Logger);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx.Options.ExefsOut != null)
|
if (ctx.Options.ExefsOut != null)
|
||||||
{
|
{
|
||||||
mainNca.ExportSection(exefsSection.SectionNum, ctx.Options.ExefsOut, ctx.Options.Raw, ctx.Options.EnableHash, ctx.Logger);
|
mainNca.ExportSection(exefsSection.SectionNum, ctx.Options.ExefsOut, ctx.Options.Raw, ctx.Options.IntegrityLevel, ctx.Logger);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,13 +108,13 @@ namespace hactoolnet
|
||||||
|
|
||||||
if (ctx.Options.RomfsOutDir != null)
|
if (ctx.Options.RomfsOutDir != null)
|
||||||
{
|
{
|
||||||
var romfs = new Romfs(mainNca.OpenSection(romfsSection.SectionNum, false, ctx.Options.EnableHash));
|
var romfs = new Romfs(mainNca.OpenSection(romfsSection.SectionNum, false, ctx.Options.IntegrityLevel));
|
||||||
romfs.Extract(ctx.Options.RomfsOutDir, ctx.Logger);
|
romfs.Extract(ctx.Options.RomfsOutDir, ctx.Logger);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx.Options.RomfsOut != null)
|
if (ctx.Options.RomfsOut != null)
|
||||||
{
|
{
|
||||||
mainNca.ExportSection(romfsSection.SectionNum, ctx.Options.RomfsOut, ctx.Options.Raw, ctx.Options.EnableHash, ctx.Logger);
|
mainNca.ExportSection(romfsSection.SectionNum, ctx.Options.RomfsOut, ctx.Options.Raw, ctx.Options.IntegrityLevel, ctx.Logger);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue