mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
Add option to dispose base streams
This commit is contained in:
parent
32996aed3c
commit
639e16cf98
8 changed files with 138 additions and 71 deletions
|
@ -29,7 +29,7 @@ namespace hactoolnet
|
||||||
|
|
||||||
using (var nax0 = Nax0.CreateFromPath(keyset, args[2], args[3]))
|
using (var nax0 = Nax0.CreateFromPath(keyset, args[2], args[3]))
|
||||||
{
|
{
|
||||||
var nca = new Nca(keyset, nax0.Stream);
|
var nca = new Nca(keyset, nax0.Stream, true);
|
||||||
|
|
||||||
using (var output = new FileStream(args[4], FileMode.Create))
|
using (var output = new FileStream(args[4], FileMode.Create))
|
||||||
using (var progress = new ProgressBar())
|
using (var progress = new ProgressBar())
|
||||||
|
@ -54,12 +54,15 @@ namespace hactoolnet
|
||||||
}
|
}
|
||||||
|
|
||||||
keyset.SetSdSeed(args[1].ToBytes());
|
keyset.SetSdSeed(args[1].ToBytes());
|
||||||
var sdfs = new SdFs(keyset, args[2]);
|
using (var sdfs = new SdFs(keyset, args[2]))
|
||||||
var ncas = sdfs.ReadAllNca();
|
|
||||||
|
|
||||||
foreach (Nca nca in ncas)
|
|
||||||
{
|
{
|
||||||
Console.WriteLine($"{nca.Header.TitleId:X16} {nca.Header.ContentType.ToString().PadRight(10, ' ')} {nca.Name}");
|
sdfs.OpenAllNcas();
|
||||||
|
|
||||||
|
foreach (Nca nca in sdfs.Ncas)
|
||||||
|
{
|
||||||
|
Console.WriteLine(
|
||||||
|
$"{nca.Header.TitleId:X16} {nca.Header.ContentType.ToString().PadRight(10, ' ')} {nca.Name}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,43 +70,48 @@ namespace hactoolnet
|
||||||
{
|
{
|
||||||
var keyset = ExternalKeys.ReadKeyFile(args[0]);
|
var keyset = ExternalKeys.ReadKeyFile(args[0]);
|
||||||
keyset.SetSdSeed(args[1].ToBytes());
|
keyset.SetSdSeed(args[1].ToBytes());
|
||||||
var sdfs = new SdFs(keyset, args[2]);
|
List<Nca> ncas;
|
||||||
var ncas = sdfs.ReadAllNca().ToArray();
|
using (var sdfs = new SdFs(keyset, args[2]))
|
||||||
|
|
||||||
var metadata = new List<Cnmt>();
|
|
||||||
|
|
||||||
using (var progress = new ProgressBar())
|
|
||||||
{
|
{
|
||||||
foreach (var nca in ncas.Where(x => x.Header.ContentType == ContentType.Meta))
|
sdfs.OpenAllNcas();
|
||||||
|
ncas = sdfs.Ncas;
|
||||||
|
|
||||||
|
var metadata = new List<Cnmt>();
|
||||||
|
|
||||||
|
using (var progress = new ProgressBar())
|
||||||
{
|
{
|
||||||
foreach (var section in nca.Sections.Where(x => x.Header.FsType == SectionFsType.Pfs0))
|
foreach (var nca in ncas.Where(x => x.Header.ContentType == ContentType.Meta))
|
||||||
{
|
{
|
||||||
var sect = nca.OpenSection(section.SectionNum);
|
foreach (var section in nca.Sections.Where(x => x.Header.FsType == SectionFsType.Pfs0))
|
||||||
var pfs0 = sect.Pfs0;
|
|
||||||
pfs0.Open(sect.Stream);
|
|
||||||
|
|
||||||
foreach (var entry in pfs0.Entries)
|
|
||||||
{
|
{
|
||||||
var path = Path.Combine("meta", entry.Name);
|
var sect = nca.OpenSection(section.SectionNum);
|
||||||
Directory.CreateDirectory(Path.GetDirectoryName(path));
|
var pfs0 = new Pfs0(sect);
|
||||||
var file = pfs0.GetFile(entry.Index);
|
|
||||||
|
|
||||||
metadata.Add(new Cnmt(new MemoryStream(file)));
|
foreach (var entry in pfs0.Entries)
|
||||||
File.WriteAllBytes(path, file);
|
{
|
||||||
|
var path = Path.Combine("meta", entry.Name);
|
||||||
|
Directory.CreateDirectory(Path.GetDirectoryName(path));
|
||||||
|
var file = pfs0.GetFile(entry.Index);
|
||||||
|
|
||||||
|
metadata.Add(new Cnmt(new MemoryStream(file)));
|
||||||
|
File.WriteAllBytes(path, file);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var meta in metadata.OrderBy(x => x.TitleId))
|
foreach (var meta in metadata.OrderBy(x => x.TitleId))
|
||||||
{
|
|
||||||
// progress.LogMessage($"{meta.TitleId:X16} v{meta.TitleVersion} {meta.Type}");
|
|
||||||
|
|
||||||
foreach (var content in meta.ContentEntries)
|
|
||||||
{
|
{
|
||||||
// Add an actual hexdump function
|
progress.LogMessage($"{meta.TitleId:X16} v{meta.TitleVersion} {meta.Type}");
|
||||||
// progress.LogMessage($" {BitConverter.ToString(content.NcaId).Replace("-", "")}.nca {content.Type}");
|
|
||||||
|
foreach (var content in meta.ContentEntries)
|
||||||
|
{
|
||||||
|
// Add an actual hexdump function
|
||||||
|
progress.LogMessage(
|
||||||
|
$" {BitConverter.ToString(content.NcaId).Replace("-", "")}.nca {content.Type}");
|
||||||
|
}
|
||||||
|
|
||||||
|
progress.LogMessage("");
|
||||||
}
|
}
|
||||||
//progress.LogMessage("");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ namespace libhac
|
||||||
|
|
||||||
stream.Position = 0x4000;
|
stream.Position = 0x4000;
|
||||||
var xts = XtsAes128.Create(Keys[0], Keys[1]);
|
var xts = XtsAes128.Create(Keys[0], Keys[1]);
|
||||||
Stream = new RandomAccessSectorStream(new XtsSectorStream(stream, xts, 0x4000, 0x4000));
|
Stream = new RandomAccessSectorStream(new XtsSectorStream(stream, xts, 0x4000, 0x4000), keepOpen);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ReadHeader(Stream stream)
|
private void ReadHeader(Stream stream)
|
||||||
|
|
|
@ -5,7 +5,7 @@ using libhac.XTSSharp;
|
||||||
|
|
||||||
namespace libhac
|
namespace libhac
|
||||||
{
|
{
|
||||||
public class Nca
|
public class Nca : IDisposable
|
||||||
{
|
{
|
||||||
public NcaHeader Header { get; private set; }
|
public NcaHeader Header { get; private set; }
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
|
@ -13,13 +13,16 @@ namespace libhac
|
||||||
public int CryptoType { get; private set; }
|
public int CryptoType { get; private set; }
|
||||||
public byte[][] DecryptedKeys { get; } = Util.CreateJaggedArray<byte[][]>(4, 0x10);
|
public byte[][] DecryptedKeys { get; } = Util.CreateJaggedArray<byte[][]>(4, 0x10);
|
||||||
public Stream Stream { get; private set; }
|
public Stream Stream { get; private set; }
|
||||||
|
private bool KeepOpen { get; }
|
||||||
|
|
||||||
public List<NcaSection> Sections = new List<NcaSection>();
|
public List<NcaSection> Sections = new List<NcaSection>();
|
||||||
|
|
||||||
public Nca(Keyset keyset, Stream stream)
|
public Nca(Keyset keyset, Stream stream, bool keepOpen)
|
||||||
{
|
{
|
||||||
|
stream.Position = 0;
|
||||||
|
KeepOpen = keepOpen;
|
||||||
Stream = stream;
|
Stream = stream;
|
||||||
ReadHeader(keyset, stream);
|
DecryptHeader(keyset, stream);
|
||||||
|
|
||||||
CryptoType = Math.Max(Header.CryptoType, Header.CryptoType2);
|
CryptoType = Math.Max(Header.CryptoType, Header.CryptoType2);
|
||||||
if (CryptoType > 0) CryptoType--;
|
if (CryptoType > 0) CryptoType--;
|
||||||
|
@ -33,25 +36,24 @@ namespace libhac
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
var section = ParseSection(keyset, stream, i);
|
var section = ParseSection(i);
|
||||||
if (section != null) Sections.Add(section);
|
if (section != null) Sections.Add(section);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public NcaSection OpenSection(int index)
|
public Stream OpenSection(int index)
|
||||||
{
|
{
|
||||||
if (index >= Sections.Count) throw new ArgumentOutOfRangeException(nameof(index));
|
if (index >= Sections.Count) throw new ArgumentOutOfRangeException(nameof(index));
|
||||||
var sect = Sections[index];
|
var sect = Sections[index];
|
||||||
|
|
||||||
sect.Stream = null;
|
|
||||||
long offset = sect.Offset;
|
long offset = sect.Offset;
|
||||||
long size = sect.Size;
|
long size = sect.Size;
|
||||||
|
|
||||||
switch (sect.Header.FsType)
|
switch (sect.Header.FsType)
|
||||||
{
|
{
|
||||||
case SectionFsType.Pfs0:
|
case SectionFsType.Pfs0:
|
||||||
offset = sect.Offset + sect.Pfs0.Superblock.Pfs0Offset;
|
offset = sect.Offset + sect.Pfs0.Pfs0Offset;
|
||||||
size = sect.Pfs0.Superblock.Pfs0Size;
|
size = sect.Pfs0.Pfs0Size;
|
||||||
break;
|
break;
|
||||||
case SectionFsType.Romfs:
|
case SectionFsType.Romfs:
|
||||||
break;
|
break;
|
||||||
|
@ -68,27 +70,28 @@ namespace libhac
|
||||||
case SectionCryptType.XTS:
|
case SectionCryptType.XTS:
|
||||||
break;
|
break;
|
||||||
case SectionCryptType.CTR:
|
case SectionCryptType.CTR:
|
||||||
sect.Stream = new RandomAccessSectorStream(new AesCtrStream(Stream, DecryptedKeys[2], offset, size, offset));
|
return new RandomAccessSectorStream(new AesCtrStream(Stream, DecryptedKeys[2], offset, size, offset), false);
|
||||||
break;
|
|
||||||
case SectionCryptType.BKTR:
|
case SectionCryptType.BKTR:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new ArgumentOutOfRangeException();
|
throw new ArgumentOutOfRangeException();
|
||||||
}
|
}
|
||||||
|
|
||||||
return sect;
|
return Stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ReadHeader(Keyset keyset, Stream stream)
|
private void DecryptHeader(Keyset keyset, Stream stream)
|
||||||
{
|
{
|
||||||
stream.Position = 0;
|
byte[] headerBytes = new byte[0xC00];
|
||||||
var xts = XtsAes128.Create(keyset.header_key);
|
var xts = XtsAes128.Create(keyset.header_key);
|
||||||
var headerDec = new RandomAccessSectorStream(new XtsSectorStream(stream, xts, 0x200));
|
using (var headerDec = new RandomAccessSectorStream(new XtsSectorStream(stream, xts, 0x200)))
|
||||||
var reader = new BinaryReader(headerDec);
|
{
|
||||||
|
headerDec.Read(headerBytes, 0, headerBytes.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
var reader = new BinaryReader(new MemoryStream(headerBytes));
|
||||||
|
|
||||||
Header = NcaHeader.Read(reader);
|
Header = NcaHeader.Read(reader);
|
||||||
|
|
||||||
headerDec.Close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DecryptKeyArea(Keyset keyset)
|
private void DecryptKeyArea(Keyset keyset)
|
||||||
|
@ -100,7 +103,7 @@ namespace libhac
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private NcaSection ParseSection(Keyset keyset, Stream stream, int index)
|
private NcaSection ParseSection(int index)
|
||||||
{
|
{
|
||||||
var entry = Header.SectionEntries[index];
|
var entry = Header.SectionEntries[index];
|
||||||
var header = Header.FsHeaders[index];
|
var header = Header.FsHeaders[index];
|
||||||
|
@ -116,11 +119,19 @@ namespace libhac
|
||||||
|
|
||||||
if (sect.Type == SectionType.Pfs0)
|
if (sect.Type == SectionType.Pfs0)
|
||||||
{
|
{
|
||||||
sect.Pfs0 = new Pfs0 { Superblock = header.Pfs0 };
|
sect.Pfs0 = header.Pfs0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return sect;
|
return sect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
if (!KeepOpen)
|
||||||
|
{
|
||||||
|
Stream?.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class NcaSection
|
public class NcaSection
|
||||||
|
@ -132,6 +143,6 @@ namespace libhac
|
||||||
public long Offset { get; set; }
|
public long Offset { get; set; }
|
||||||
public long Size { get; set; }
|
public long Size { get; set; }
|
||||||
|
|
||||||
public Pfs0 Pfs0 { get; set; }
|
public Pfs0Superblock Pfs0 { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,20 +5,19 @@ namespace libhac
|
||||||
{
|
{
|
||||||
public class Pfs0
|
public class Pfs0
|
||||||
{
|
{
|
||||||
public Pfs0Superblock Superblock { get; set; }
|
|
||||||
public Pfs0Header Header { get; set; }
|
public Pfs0Header Header { get; set; }
|
||||||
public int HeaderSize { get; set; }
|
public int HeaderSize { get; set; }
|
||||||
public Pfs0FileEntry[] Entries { get; set; }
|
public Pfs0FileEntry[] Entries { get; set; }
|
||||||
private Stream Stream { get; set; }
|
private Stream Stream { get; set; }
|
||||||
|
|
||||||
public void Open(Stream file)
|
public Pfs0(Stream stream)
|
||||||
{
|
{
|
||||||
byte[] headerBytes;
|
byte[] headerBytes;
|
||||||
using (var reader = new BinaryReader(file, Encoding.Default, true))
|
using (var reader = new BinaryReader(stream, Encoding.Default, true))
|
||||||
{
|
{
|
||||||
Header = new Pfs0Header(reader);
|
Header = new Pfs0Header(reader);
|
||||||
HeaderSize = (int)(16 + 24 * Header.NumFiles + Header.StringTableSize);
|
HeaderSize = (int)(16 + 24 * Header.NumFiles + Header.StringTableSize);
|
||||||
file.Position = 0;
|
stream.Position = 0;
|
||||||
headerBytes = reader.ReadBytes(HeaderSize);
|
headerBytes = reader.ReadBytes(HeaderSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,7 +39,7 @@ namespace libhac
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream = file;
|
Stream = stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] GetFile(int index)
|
public byte[] GetFile(int index)
|
||||||
|
|
|
@ -5,12 +5,14 @@ using System.Linq;
|
||||||
|
|
||||||
namespace libhac
|
namespace libhac
|
||||||
{
|
{
|
||||||
public class SdFs
|
public class SdFs : IDisposable
|
||||||
{
|
{
|
||||||
public Keyset Keyset { get; }
|
public Keyset Keyset { get; }
|
||||||
public string RootDir { get; }
|
public string RootDir { get; }
|
||||||
public string ContentsDir { get; }
|
public string ContentsDir { get; }
|
||||||
public string[] Files { get; }
|
public string[] Files { get; }
|
||||||
|
public List<Nca> Ncas { get; } = new List<Nca>();
|
||||||
|
private List<Nax0> Nax0s { get; } = new List<Nax0>();
|
||||||
|
|
||||||
public SdFs(Keyset keyset, string sdPath)
|
public SdFs(Keyset keyset, string sdPath)
|
||||||
{
|
{
|
||||||
|
@ -24,7 +26,7 @@ namespace libhac
|
||||||
Files = Directory.GetFiles(ContentsDir, "00", SearchOption.AllDirectories).Select(Path.GetDirectoryName).ToArray();
|
Files = Directory.GetFiles(ContentsDir, "00", SearchOption.AllDirectories).Select(Path.GetDirectoryName).ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<Nca> ReadAllNca()
|
public void OpenAllNcas()
|
||||||
{
|
{
|
||||||
foreach (var file in Files)
|
foreach (var file in Files)
|
||||||
{
|
{
|
||||||
|
@ -33,7 +35,8 @@ namespace libhac
|
||||||
{
|
{
|
||||||
var sdPath = "/" + Util.GetRelativePath(file, ContentsDir).Replace('\\', '/');
|
var sdPath = "/" + Util.GetRelativePath(file, ContentsDir).Replace('\\', '/');
|
||||||
var nax0 = Nax0.CreateFromPath(Keyset, file, sdPath);
|
var nax0 = Nax0.CreateFromPath(Keyset, file, sdPath);
|
||||||
nca = new Nca(Keyset, nax0.Stream);
|
Nax0s.Add(nax0);
|
||||||
|
nca = new Nca(Keyset, nax0.Stream, false);
|
||||||
nca.Name = Path.GetFileName(file);
|
nca.Name = Path.GetFileName(file);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
@ -41,9 +44,28 @@ namespace libhac
|
||||||
Console.WriteLine($"{ex.Message} {file}");
|
Console.WriteLine($"{ex.Message} {file}");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nca != null) yield return nca;
|
if (nca != null) Ncas.Add(nca);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DisposeNcas()
|
||||||
|
{
|
||||||
|
foreach (var nca in Ncas)
|
||||||
|
{
|
||||||
|
nca.Dispose();
|
||||||
|
}
|
||||||
|
Ncas.Clear();
|
||||||
|
|
||||||
|
foreach (var nax0 in Nax0s)
|
||||||
|
{
|
||||||
|
nax0.Dispose();
|
||||||
|
}
|
||||||
|
Nax0s.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
DisposeNcas();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@ namespace libhac.XTSSharp
|
||||||
private readonly byte[] _buffer;
|
private readonly byte[] _buffer;
|
||||||
private readonly int _bufferSize;
|
private readonly int _bufferSize;
|
||||||
private readonly SectorStream _s;
|
private readonly SectorStream _s;
|
||||||
private readonly bool _isStreamOwned;
|
private readonly bool _keepOpen;
|
||||||
private bool _bufferDirty;
|
private bool _bufferDirty;
|
||||||
private bool _bufferLoaded;
|
private bool _bufferLoaded;
|
||||||
private int _bufferPos;
|
private int _bufferPos;
|
||||||
|
@ -48,7 +48,7 @@ namespace libhac.XTSSharp
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="s">Base stream</param>
|
/// <param name="s">Base stream</param>
|
||||||
public RandomAccessSectorStream(SectorStream s)
|
public RandomAccessSectorStream(SectorStream s)
|
||||||
: this(s, false)
|
: this(s, true)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,11 +56,11 @@ namespace libhac.XTSSharp
|
||||||
/// Creates a new stream
|
/// Creates a new stream
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="s">Base stream</param>
|
/// <param name="s">Base stream</param>
|
||||||
/// <param name="isStreamOwned">Does this stream own the base stream? i.e. should it be automatically disposed?</param>
|
/// <param name="keepOpen">Should this stream leave the base stream open when disposed?</param>
|
||||||
public RandomAccessSectorStream(SectorStream s, bool isStreamOwned)
|
public RandomAccessSectorStream(SectorStream s, bool keepOpen)
|
||||||
{
|
{
|
||||||
_s = s;
|
_s = s;
|
||||||
_isStreamOwned = isStreamOwned;
|
_keepOpen = keepOpen;
|
||||||
_buffer = new byte[s.SectorSize];
|
_buffer = new byte[s.SectorSize];
|
||||||
_bufferSize = s.SectorSize;
|
_bufferSize = s.SectorSize;
|
||||||
}
|
}
|
||||||
|
@ -152,7 +152,7 @@ namespace libhac.XTSSharp
|
||||||
|
|
||||||
base.Dispose(disposing);
|
base.Dispose(disposing);
|
||||||
|
|
||||||
if (_isStreamOwned)
|
if (!_keepOpen)
|
||||||
_s.Dispose();
|
_s.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,7 @@ namespace libhac.XTSSharp
|
||||||
private readonly Stream _baseStream;
|
private readonly Stream _baseStream;
|
||||||
private readonly long _offset;
|
private readonly long _offset;
|
||||||
private ulong _currentSector;
|
private ulong _currentSector;
|
||||||
|
private bool _keepOpen;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new stream
|
/// Creates a new stream
|
||||||
|
@ -55,12 +56,28 @@ namespace libhac.XTSSharp
|
||||||
/// <param name="sectorSize">The size of the sectors to read/write</param>
|
/// <param name="sectorSize">The size of the sectors to read/write</param>
|
||||||
/// <param name="offset">Offset to start counting sectors</param>
|
/// <param name="offset">Offset to start counting sectors</param>
|
||||||
public SectorStream(Stream baseStream, int sectorSize, long offset)
|
public SectorStream(Stream baseStream, int sectorSize, long offset)
|
||||||
|
: this(baseStream, sectorSize, offset, false)
|
||||||
{
|
{
|
||||||
SectorSize = sectorSize;
|
SectorSize = sectorSize;
|
||||||
_baseStream = baseStream;
|
_baseStream = baseStream;
|
||||||
_offset = offset;
|
_offset = offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new stream
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="baseStream">The base stream to read/write from</param>
|
||||||
|
/// <param name="sectorSize">The size of the sectors to read/write</param>
|
||||||
|
/// <param name="offset">Offset to start counting sectors</param>
|
||||||
|
/// <param name="keepOpen">Should this stream leave the base stream open when disposed?</param>
|
||||||
|
public SectorStream(Stream baseStream, int sectorSize, long offset, bool keepOpen)
|
||||||
|
{
|
||||||
|
SectorSize = sectorSize;
|
||||||
|
_baseStream = baseStream;
|
||||||
|
_offset = offset;
|
||||||
|
_keepOpen = keepOpen;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The size of the sectors
|
/// The size of the sectors
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -229,5 +246,15 @@ namespace libhac.XTSSharp
|
||||||
_baseStream.Write(buffer, offset, count);
|
_baseStream.Write(buffer, offset, count);
|
||||||
_currentSector++;
|
_currentSector++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (!_keepOpen)
|
||||||
|
{
|
||||||
|
_baseStream.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -50,7 +50,7 @@ namespace libhac.XTSSharp
|
||||||
/// <param name="xts">Xts implementation to use</param>
|
/// <param name="xts">Xts implementation to use</param>
|
||||||
/// <param name="sectorSize">Sector size</param>
|
/// <param name="sectorSize">Sector size</param>
|
||||||
public XtsStream(Stream baseStream, Xts xts, int sectorSize)
|
public XtsStream(Stream baseStream, Xts xts, int sectorSize)
|
||||||
: base(new XtsSectorStream(baseStream, xts, sectorSize), true)
|
: base(new XtsSectorStream(baseStream, xts, sectorSize), false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ namespace libhac.XTSSharp
|
||||||
/// <param name="sectorSize">Sector size</param>
|
/// <param name="sectorSize">Sector size</param>
|
||||||
/// <param name="offset">Offset to start counting sectors</param>
|
/// <param name="offset">Offset to start counting sectors</param>
|
||||||
public XtsStream(Stream baseStream, Xts xts, int sectorSize, long offset)
|
public XtsStream(Stream baseStream, Xts xts, int sectorSize, long offset)
|
||||||
: base(new XtsSectorStream(baseStream, xts, sectorSize, offset), true)
|
: base(new XtsSectorStream(baseStream, xts, sectorSize, offset), false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue