Make sure storage conversion extensions are in place

This commit is contained in:
Alex Barney 2019-01-21 18:12:07 -06:00
parent 8e151c4a1c
commit 1d07a98d1e
13 changed files with 57 additions and 21 deletions

View file

@ -31,7 +31,7 @@ namespace LibHac.IO
throw new ArgumentException("NAX0 key derivation failed."); throw new ArgumentException("NAX0 key derivation failed.");
} }
IStorage encStorage = new FileStorage(BaseFile).Slice(HeaderLength, Header.Size); IStorage encStorage = BaseFile.AsStorage().Slice(HeaderLength, Header.Size);
BaseStorage = new CachedStorage(new Aes128XtsStorage(encStorage, Header.DecryptedKey1, Header.DecryptedKey2, BlockSize, true), 4, true); BaseStorage = new CachedStorage(new Aes128XtsStorage(encStorage, Header.DecryptedKey1, Header.DecryptedKey2, BlockSize, true), 4, true);
} }

View file

@ -23,7 +23,7 @@ namespace LibHac.IO
if (Delta.Length < 0x40) throw new InvalidDataException("Delta file is too small."); if (Delta.Length < 0x40) throw new InvalidDataException("Delta file is too small.");
Header = new DeltaFragmentHeader(new StorageFile(delta, OpenMode.Read)); Header = new DeltaFragmentHeader(delta.AsFile(OpenMode.Read));
if (Header.Magic != Ndv0Magic) throw new InvalidDataException("NDV0 magic value is missing."); if (Header.Magic != Ndv0Magic) throw new InvalidDataException("NDV0 magic value is missing.");
@ -67,7 +67,7 @@ namespace LibHac.IO
private void ParseDeltaStructure() private void ParseDeltaStructure()
{ {
var reader = new FileReader(new StorageFile(Delta, OpenMode.Read)); var reader = new FileReader(Delta.AsFile(OpenMode.Read));
reader.Position = Header.FragmentHeaderSize; reader.Position = Header.FragmentHeaderSize;

View file

@ -119,6 +119,7 @@ namespace LibHac.IO
} }
} }
public static IStorage AsStorage(this IFile file) => new FileStorage(file);
public static Stream AsStream(this IFile file) => new NxFileStream(file, true); public static Stream AsStream(this IFile file) => new NxFileStream(file, true);
public static Stream AsStream(this IFile file, bool keepOpen) => new NxFileStream(file, keepOpen); public static Stream AsStream(this IFile file, bool keepOpen) => new NxFileStream(file, keepOpen);

34
src/LibHac/IO/NullFile.cs Normal file
View file

@ -0,0 +1,34 @@
using System;
namespace LibHac.IO
{
public class NullFile : FileBase
{
public NullFile() { }
public NullFile(long length) => Length = length;
private long Length { get; }
public override int Read(Span<byte> destination, long offset)
{
int toRead = ValidateReadParamsAndGetSize(destination, offset);
destination.Slice(0, toRead).Clear();
return toRead;
}
public override void Write(ReadOnlySpan<byte> source, long offset)
{
}
public override void Flush()
{
}
public override long GetSize() => Length;
public override void SetSize(long size)
{
throw new NotSupportedException();
}
}
}

View file

@ -104,8 +104,7 @@ namespace LibHac.IO.Save
if (file.BlockIndex < 0) if (file.BlockIndex < 0)
{ {
// todo return new NullFile();
return new StorageFile(new MemoryStorage(new byte[0]), OpenMode.ReadWrite);
} }
AllocationTableStorage storage = OpenFatBlock(file.BlockIndex, file.FileSize); AllocationTableStorage storage = OpenFatBlock(file.BlockIndex, file.FileSize);

View file

@ -40,6 +40,8 @@ namespace LibHac.IO
public static Stream AsStream(this IStorage storage, FileAccess access) => new StorageStream(storage, access, true); public static Stream AsStream(this IStorage storage, FileAccess access) => new StorageStream(storage, access, true);
public static Stream AsStream(this IStorage storage, FileAccess access, bool keepOpen) => new StorageStream(storage, access, keepOpen); public static Stream AsStream(this IStorage storage, FileAccess access, bool keepOpen) => new StorageStream(storage, access, keepOpen);
public static IFile AsFile(this IStorage storage, OpenMode mode) => new StorageFile(storage, mode);
public static void CopyTo(this IStorage input, IStorage output, IProgressReport progress = null) public static void CopyTo(this IStorage input, IStorage output, IProgressReport progress = null)
{ {
const int bufferSize = 81920; const int bufferSize = 81920;

View file

@ -232,7 +232,8 @@ namespace LibHac
// Set the master hash // Set the master hash
initInfo[0] = new IntegrityVerificationInfo initInfo[0] = new IntegrityVerificationInfo
{ {
Data = new StreamStorage(new MemoryStream(sb.MasterHash), true), // todo Get hash directly from header
Data = new MemoryStorage(sb.MasterHash),
BlockSize = 0, BlockSize = 0,
Type = IntegrityStorageType.PartitionFs Type = IntegrityStorageType.PartitionFs
@ -301,7 +302,7 @@ namespace LibHac
if (!pfs.FileExists("main.npdm")) return; if (!pfs.FileExists("main.npdm")) return;
var npdmStorage = new FileStorage(pfs.OpenFile("main.npdm", OpenMode.Read)); IStorage npdmStorage = pfs.OpenFile("main.npdm", OpenMode.Read).AsStorage();
Npdm = new Npdm.NpdmBinary(npdmStorage.AsStream(), Keyset); Npdm = new Npdm.NpdmBinary(npdmStorage.AsStream(), Keyset);

View file

@ -67,7 +67,7 @@ namespace LibHac
Nca nca = null; Nca nca = null;
try try
{ {
var storage = new FileStorage(ContentFs.OpenFile(fileEntry.FullPath, OpenMode.Read)); IStorage storage = ContentFs.OpenFile(fileEntry.FullPath, OpenMode.Read).AsStorage();
nca = new Nca(Keyset, storage, false); nca = new Nca(Keyset, storage, false);
@ -106,7 +106,7 @@ namespace LibHac
try try
{ {
IFile file = SaveFs.OpenFile(fileEntry.FullPath, OpenMode.Read); IFile file = SaveFs.OpenFile(fileEntry.FullPath, OpenMode.Read);
save = new SaveDataFileSystem(Keyset, new FileStorage(file), IntegrityCheckLevel.None, true); save = new SaveDataFileSystem(Keyset, file.AsStorage(), IntegrityCheckLevel.None, true);
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -131,7 +131,7 @@ namespace LibHac
var pfs0 = new PartitionFileSystem(sect); var pfs0 = new PartitionFileSystem(sect);
IFile file = pfs0.OpenFile(pfs0.Files[0], OpenMode.Read); IFile file = pfs0.OpenFile(pfs0.Files[0], OpenMode.Read);
var metadata = new Cnmt(new FileStorage(file).AsStream()); var metadata = new Cnmt(file.AsStream());
title.Id = metadata.TitleId; title.Id = metadata.TitleId;
title.Version = metadata.TitleVersion; title.Version = metadata.TitleVersion;
title.Metadata = metadata; title.Metadata = metadata;
@ -168,7 +168,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 RomFsFileSystem(title.ControlNca.OpenSection(0, false, IntegrityCheckLevel.ErrorOnInvalid, true)); var romfs = new RomFsFileSystem(title.ControlNca.OpenSection(0, false, IntegrityCheckLevel.ErrorOnInvalid, true));
IStorage control = new FileStorage(romfs.OpenFile("control.nacp", OpenMode.Read)); IFile control = romfs.OpenFile("control.nacp", OpenMode.Read);
title.Control = new Nacp(control.AsStream()); title.Control = new Nacp(control.AsStream());

View file

@ -40,7 +40,7 @@ namespace LibHac
{ {
IFile partitionFile = RootPartition.OpenFile(file, OpenMode.Read); IFile partitionFile = RootPartition.OpenFile(file, OpenMode.Read);
var partition = new XciPartition(new FileStorage(partitionFile)) var partition = new XciPartition(partitionFile.AsStorage())
{ {
Name = file.Name, Name = file.Name,
Offset = Header.PartitionFsHeaderAddress + RootPartition.HeaderSize + file.Offset, Offset = Header.PartitionFsHeaderAddress + RootPartition.HeaderSize + file.Offset,

View file

@ -15,9 +15,8 @@ namespace hactoolnet
public static void Process(Context ctx) public static void Process(Context ctx)
{ {
using (var deltaFile = new StreamStorage(new FileStream(ctx.Options.InFile, FileMode.Open, FileAccess.Read), false)) using (IStorage deltaFile = new FileStream(ctx.Options.InFile, FileMode.Open, FileAccess.Read).AsStorage(false))
{ {
IStorage deltaStorage = deltaFile; IStorage deltaStorage = deltaFile;
Span<byte> magic = stackalloc byte[4]; Span<byte> magic = stackalloc byte[4];
deltaFile.Read(magic, 0); deltaFile.Read(magic, 0);
@ -34,7 +33,7 @@ namespace hactoolnet
throw new FileNotFoundException("Specified NCA does not contain a delta fragment"); throw new FileNotFoundException("Specified NCA does not contain a delta fragment");
} }
deltaStorage = new FileStorage(fs.OpenFile(FragmentFileName, OpenMode.Read)); deltaStorage = fs.OpenFile(FragmentFileName, OpenMode.Read).AsStorage();
} }
catch (InvalidDataException) { } // Ignore non-NCA3 files catch (InvalidDataException) { } // Ignore non-NCA3 files
} }
@ -43,7 +42,7 @@ namespace hactoolnet
if (ctx.Options.BaseFile != null) if (ctx.Options.BaseFile != null)
{ {
using (var baseFile = new StreamStorage(new FileStream(ctx.Options.BaseFile, FileMode.Open, FileAccess.Read), false)) using (IStorage baseFile = new FileStream(ctx.Options.BaseFile, FileMode.Open, FileAccess.Read).AsStorage(false))
{ {
delta.SetBaseStorage(baseFile); delta.SetBaseStorage(baseFile);

View file

@ -11,7 +11,7 @@ namespace hactoolnet
{ {
public static void Process(Context ctx) public static void Process(Context ctx)
{ {
using (var file = new StreamStorage(new FileStream(ctx.Options.InFile, FileMode.Open, FileAccess.Read), false)) using (IStorage file = new FileStream(ctx.Options.InFile, FileMode.Open, FileAccess.Read).AsStorage(false))
{ {
var nca = new Nca(ctx.Keyset, file, false); var nca = new Nca(ctx.Keyset, file, false);
nca.ValidateMasterHashes(); nca.ValidateMasterHashes();
@ -19,7 +19,7 @@ namespace hactoolnet
if (ctx.Options.BaseNca != null) if (ctx.Options.BaseNca != null)
{ {
var baseFile = new StreamStorage(new FileStream(ctx.Options.BaseNca, FileMode.Open, FileAccess.Read), false); IStorage baseFile = new FileStream(ctx.Options.BaseNca, FileMode.Open, FileAccess.Read).AsStorage(false);
var baseNca = new Nca(ctx.Keyset, baseFile, false); var baseNca = new Nca(ctx.Keyset, baseFile, false);
nca.SetBaseNca(baseNca); nca.SetBaseNca(baseNca);
} }

View file

@ -99,7 +99,7 @@ namespace hactoolnet
string destFilename = ctx.Options.ReplaceFileDest; string destFilename = ctx.Options.ReplaceFileDest;
if (!destFilename.StartsWith("/")) destFilename = '/' + destFilename; if (!destFilename.StartsWith("/")) destFilename = '/' + destFilename;
using (IFile inFile = new StorageFile(new FileStream(ctx.Options.ReplaceFileSource, FileMode.Open, FileAccess.Read).AsStorage(false), OpenMode.ReadWrite)) using (IFile inFile = new FileStream(ctx.Options.ReplaceFileSource, FileMode.Open, FileAccess.Read).AsIFile(OpenMode.ReadWrite))
{ {
using (IFile outFile = save.OpenFile(destFilename, OpenMode.ReadWrite)) using (IFile outFile = save.OpenFile(destFilename, OpenMode.ReadWrite))
{ {

View file

@ -53,7 +53,7 @@ namespace hactoolnet
foreach (PartitionFileEntry sub in root.Files) foreach (PartitionFileEntry sub in root.Files)
{ {
var subPfs = new PartitionFileSystem(new FileStorage(root.OpenFile(sub, OpenMode.Read))); var subPfs = new PartitionFileSystem(root.OpenFile(sub, OpenMode.Read).AsStorage());
string subDir = Path.Combine(ctx.Options.OutDir, sub.Name); string subDir = Path.Combine(ctx.Options.OutDir, sub.Name);
subPfs.Extract(subDir, ctx.Logger); subPfs.Extract(subDir, ctx.Logger);
@ -133,7 +133,7 @@ namespace hactoolnet
foreach (PartitionFileEntry fileEntry in xci.SecurePartition.Files.Where(x => x.Name.EndsWith(".nca"))) foreach (PartitionFileEntry fileEntry in xci.SecurePartition.Files.Where(x => x.Name.EndsWith(".nca")))
{ {
IStorage ncaStorage = new FileStorage(xci.SecurePartition.OpenFile(fileEntry, OpenMode.Read)); IStorage ncaStorage = xci.SecurePartition.OpenFile(fileEntry, OpenMode.Read).AsStorage();
var nca = new Nca(ctx.Keyset, ncaStorage, true); var nca = new Nca(ctx.Keyset, ncaStorage, true);
if (nca.Header.ContentType == ContentType.Program) if (nca.Header.ContentType == ContentType.Program)