diff --git a/LibHac.sln b/LibHac.sln index 59640480..1a9b8892 100644 --- a/LibHac.sln +++ b/LibHac.sln @@ -1,18 +1,12 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.27703.2026 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.29102.190 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LibHac", "src\LibHac\LibHac.csproj", "{FFCA6C31-D9D4-4ED8-A06D-0CC6B94422B8}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "hactoolnet", "src\hactoolnet\hactoolnet.csproj", "{B1633A64-125F-40A3-9E15-654B4DE5FD98}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LibHac.Nand", "src\LibHac.Nand\LibHac.Nand.csproj", "{AB503D24-F702-4E6E-B615-A9C7BDA218D1}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NandReader", "src\NandReader\NandReader.csproj", "{9889C467-284F-4061-B4DB-EC94051C29C0}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NandReaderGui", "src\NandReaderGui\NandReaderGui.csproj", "{3CBD38B0-6575-4768-8E94-A8AF2D2C9F43}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LibHac.Tests", "tests\LibHac.Tests\LibHac.Tests.csproj", "{679C89BD-5FDF-4CC2-9129-ABABD759035B}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "_build", "build\_build.csproj", "{C7150117-90B8-4083-8141-BBC35C9F44F6}" @@ -31,16 +25,6 @@ Global {B1633A64-125F-40A3-9E15-654B4DE5FD98}.Debug|Any CPU.Build.0 = Debug|Any CPU {B1633A64-125F-40A3-9E15-654B4DE5FD98}.Release|Any CPU.ActiveCfg = Release|Any CPU {B1633A64-125F-40A3-9E15-654B4DE5FD98}.Release|Any CPU.Build.0 = Release|Any CPU - {AB503D24-F702-4E6E-B615-A9C7BDA218D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {AB503D24-F702-4E6E-B615-A9C7BDA218D1}.Debug|Any CPU.Build.0 = Debug|Any CPU - {AB503D24-F702-4E6E-B615-A9C7BDA218D1}.Release|Any CPU.ActiveCfg = Release|Any CPU - {AB503D24-F702-4E6E-B615-A9C7BDA218D1}.Release|Any CPU.Build.0 = Release|Any CPU - {9889C467-284F-4061-B4DB-EC94051C29C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {9889C467-284F-4061-B4DB-EC94051C29C0}.Debug|Any CPU.Build.0 = Debug|Any CPU - {9889C467-284F-4061-B4DB-EC94051C29C0}.Release|Any CPU.ActiveCfg = Release|Any CPU - {9889C467-284F-4061-B4DB-EC94051C29C0}.Release|Any CPU.Build.0 = Release|Any CPU - {3CBD38B0-6575-4768-8E94-A8AF2D2C9F43}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {3CBD38B0-6575-4768-8E94-A8AF2D2C9F43}.Release|Any CPU.ActiveCfg = Release|Any CPU {679C89BD-5FDF-4CC2-9129-ABABD759035B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {679C89BD-5FDF-4CC2-9129-ABABD759035B}.Debug|Any CPU.Build.0 = Debug|Any CPU {679C89BD-5FDF-4CC2-9129-ABABD759035B}.Release|Any CPU.ActiveCfg = Release|Any CPU diff --git a/LibHac.sln.DotSettings b/LibHac.sln.DotSettings deleted file mode 100644 index 143267cd..00000000 --- a/LibHac.sln.DotSettings +++ /dev/null @@ -1,4 +0,0 @@ - - ExplicitlyExcluded - ExplicitlyExcluded - ExplicitlyExcluded \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/ApplePartitionMap/BlockZero.cs b/src/LibHac.Nand/DiscUtils.Core/ApplePartitionMap/BlockZero.cs deleted file mode 100644 index 1ed9c8e0..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/ApplePartitionMap/BlockZero.cs +++ /dev/null @@ -1,61 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using DiscUtils.Streams; - -namespace DiscUtils.ApplePartitionMap -{ - internal sealed class BlockZero : IByteArraySerializable - { - public uint BlockCount; - public ushort BlockSize; - public ushort DeviceId; - public ushort DeviceType; - public ushort DriverCount; - public uint DriverData; - public ushort Signature; - - public int Size - { - get { return 512; } - } - - public int ReadFrom(byte[] buffer, int offset) - { - Signature = EndianUtilities.ToUInt16BigEndian(buffer, offset + 0); - BlockSize = EndianUtilities.ToUInt16BigEndian(buffer, offset + 2); - BlockCount = EndianUtilities.ToUInt32BigEndian(buffer, offset + 4); - DeviceType = EndianUtilities.ToUInt16BigEndian(buffer, offset + 8); - DeviceId = EndianUtilities.ToUInt16BigEndian(buffer, offset + 10); - DriverData = EndianUtilities.ToUInt32BigEndian(buffer, offset + 12); - DriverCount = EndianUtilities.ToUInt16LittleEndian(buffer, offset + 16); - - return 512; - } - - public void WriteTo(byte[] buffer, int offset) - { - throw new NotImplementedException(); - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/ApplePartitionMap/PartitionMap.cs b/src/LibHac.Nand/DiscUtils.Core/ApplePartitionMap/PartitionMap.cs deleted file mode 100644 index fb62304e..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/ApplePartitionMap/PartitionMap.cs +++ /dev/null @@ -1,153 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.ObjectModel; -using System.IO; -using DiscUtils.Partitions; -using DiscUtils.Streams; - -namespace DiscUtils.ApplePartitionMap -{ - /// - /// Interprets Apple Partition Map structures that partition a disk. - /// - public sealed class PartitionMap : PartitionTable - { - private readonly PartitionMapEntry[] _partitions; - private readonly Stream _stream; - - /// - /// Initializes a new instance of the PartitionMap class. - /// - /// Stream containing the contents of a disk. - public PartitionMap(Stream stream) - { - _stream = stream; - - stream.Position = 0; - byte[] initialBytes = StreamUtilities.ReadExact(stream, 1024); - - BlockZero b0 = new BlockZero(); - b0.ReadFrom(initialBytes, 0); - - PartitionMapEntry initialPart = new PartitionMapEntry(_stream); - initialPart.ReadFrom(initialBytes, 512); - - byte[] partTableData = StreamUtilities.ReadExact(stream, (int)(initialPart.MapEntries - 1) * 512); - - _partitions = new PartitionMapEntry[initialPart.MapEntries - 1]; - for (uint i = 0; i < initialPart.MapEntries - 1; ++i) - { - _partitions[i] = new PartitionMapEntry(_stream); - _partitions[i].ReadFrom(partTableData, (int)(512 * i)); - } - } - - /// - /// Gets the GUID of the disk, always returns Guid.Empty. - /// - public override Guid DiskGuid - { - get { return Guid.Empty; } - } - - /// - /// Gets the partitions present on the disk. - /// - public override ReadOnlyCollection Partitions - { - get { return new ReadOnlyCollection(_partitions); } - } - - /// - /// Creates a new partition that encompasses the entire disk. - /// - /// The partition type. - /// Whether the partition is active (bootable). - /// The index of the partition. - /// The partition table must be empty before this method is called, - /// otherwise IOException is thrown. - public override int Create(WellKnownPartitionType type, bool active) - { - throw new NotImplementedException(); - } - - /// - /// Creates a new partition with a target size. - /// - /// The target size (in bytes). - /// The partition type. - /// Whether the partition is active (bootable). - /// The index of the new partition. - public override int Create(long size, WellKnownPartitionType type, bool active) - { - throw new NotImplementedException(); - } - - /// - /// Creates a new aligned partition that encompasses the entire disk. - /// - /// The partition type. - /// Whether the partition is active (bootable). - /// The alignment (in byte). - /// The index of the partition. - /// The partition table must be empty before this method is called, - /// otherwise IOException is thrown. - /// - /// Traditionally partitions were aligned to the physical structure of the underlying disk, - /// however with modern storage greater efficiency is acheived by aligning partitions on - /// large values that are a power of two. - /// - public override int CreateAligned(WellKnownPartitionType type, bool active, int alignment) - { - throw new NotImplementedException(); - } - - /// - /// Creates a new aligned partition with a target size. - /// - /// The target size (in bytes). - /// The partition type. - /// Whether the partition is active (bootable). - /// The alignment (in byte). - /// The index of the new partition. - /// - /// Traditionally partitions were aligned to the physical structure of the underlying disk, - /// however with modern storage greater efficiency is achieved by aligning partitions on - /// large values that are a power of two. - /// - public override int CreateAligned(long size, WellKnownPartitionType type, bool active, int alignment) - { - throw new NotImplementedException(); - } - - /// - /// Deletes a partition at a given index. - /// - /// The index of the partition. - public override void Delete(int index) - { - throw new NotImplementedException(); - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/ApplePartitionMap/PartitionMapEntry.cs b/src/LibHac.Nand/DiscUtils.Core/ApplePartitionMap/PartitionMapEntry.cs deleted file mode 100644 index 30e00b1d..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/ApplePartitionMap/PartitionMapEntry.cs +++ /dev/null @@ -1,112 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.IO; -using DiscUtils.Partitions; -using DiscUtils.Streams; - -namespace DiscUtils.ApplePartitionMap -{ - internal sealed class PartitionMapEntry : PartitionInfo, IByteArraySerializable - { - private readonly Stream _diskStream; - public uint BootBlock; - public uint BootBytes; - public uint Flags; - public uint LogicalBlocks; - public uint LogicalBlockStart; - public uint MapEntries; - public string Name; - public uint PhysicalBlocks; - public uint PhysicalBlockStart; - public ushort Signature; - public string Type; - - public PartitionMapEntry(Stream diskStream) - { - _diskStream = diskStream; - } - - public override byte BiosType - { - get { return 0xAF; } - } - - public override long FirstSector - { - get { return PhysicalBlockStart; } - } - - public override Guid GuidType - { - get { return Guid.Empty; } - } - - public override long LastSector - { - get { return PhysicalBlockStart + PhysicalBlocks - 1; } - } - - public override string TypeAsString - { - get { return Type; } - } - - internal override PhysicalVolumeType VolumeType - { - get { return PhysicalVolumeType.ApplePartition; } - } - - public int Size - { - get { return 512; } - } - - public int ReadFrom(byte[] buffer, int offset) - { - Signature = EndianUtilities.ToUInt16BigEndian(buffer, offset + 0); - MapEntries = EndianUtilities.ToUInt32BigEndian(buffer, offset + 4); - PhysicalBlockStart = EndianUtilities.ToUInt32BigEndian(buffer, offset + 8); - PhysicalBlocks = EndianUtilities.ToUInt32BigEndian(buffer, offset + 12); - Name = EndianUtilities.BytesToString(buffer, offset + 16, 32).TrimEnd('\0'); - Type = EndianUtilities.BytesToString(buffer, offset + 48, 32).TrimEnd('\0'); - LogicalBlockStart = EndianUtilities.ToUInt32BigEndian(buffer, offset + 80); - LogicalBlocks = EndianUtilities.ToUInt32BigEndian(buffer, offset + 84); - Flags = EndianUtilities.ToUInt32BigEndian(buffer, offset + 88); - BootBlock = EndianUtilities.ToUInt32BigEndian(buffer, offset + 92); - BootBytes = EndianUtilities.ToUInt32BigEndian(buffer, offset + 96); - - return 512; - } - - public void WriteTo(byte[] buffer, int offset) - { - throw new NotImplementedException(); - } - - public override SparseStream Open() - { - return new SubStream(_diskStream, PhysicalBlockStart * 512, PhysicalBlocks * 512); - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/ApplePartitionMap/PartitionMapFactory.cs b/src/LibHac.Nand/DiscUtils.Core/ApplePartitionMap/PartitionMapFactory.cs deleted file mode 100644 index d5971ce6..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/ApplePartitionMap/PartitionMapFactory.cs +++ /dev/null @@ -1,66 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System.IO; -using DiscUtils.Partitions; -using DiscUtils.Streams; - -namespace DiscUtils.ApplePartitionMap -{ - [PartitionTableFactory] - internal sealed class PartitionMapFactory : PartitionTableFactory - { - public override bool DetectIsPartitioned(Stream s) - { - if (s.Length < 1024) - { - return false; - } - - s.Position = 0; - - byte[] initialBytes = StreamUtilities.ReadExact(s, 1024); - - BlockZero b0 = new BlockZero(); - b0.ReadFrom(initialBytes, 0); - if (b0.Signature != 0x4552) - { - return false; - } - - PartitionMapEntry initialPart = new PartitionMapEntry(s); - initialPart.ReadFrom(initialBytes, 512); - - return initialPart.Signature == 0x504d; - } - - public override PartitionTable DetectPartitionTable(VirtualDisk disk) - { - if (!DetectIsPartitioned(disk.Content)) - { - return null; - } - - return new PartitionMap(disk.Content); - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Archives/FileRecord.cs b/src/LibHac.Nand/DiscUtils.Core/Archives/FileRecord.cs deleted file mode 100644 index f7178f8e..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Archives/FileRecord.cs +++ /dev/null @@ -1,38 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -namespace DiscUtils.Archives -{ - internal sealed class FileRecord - { - public long Length; - public string Name; - public long Start; - - public FileRecord(string name, long start, long length) - { - Name = name; - Start = start; - Length = length; - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Archives/TarFile.cs b/src/LibHac.Nand/DiscUtils.Core/Archives/TarFile.cs deleted file mode 100644 index e91a1f45..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Archives/TarFile.cs +++ /dev/null @@ -1,144 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; -using System.IO; -using DiscUtils.Streams; - -namespace DiscUtils.Archives -{ - /// - /// Minimal tar file format implementation. - /// - public sealed class TarFile - { - private readonly Dictionary _files; - private readonly Stream _fileStream; - - /// - /// Initializes a new instance of the TarFile class. - /// - /// The Tar file. - public TarFile(Stream fileStream) - { - _fileStream = fileStream; - _files = new Dictionary(); - - TarHeader hdr = new TarHeader(); - byte[] hdrBuf = StreamUtilities.ReadExact(_fileStream, TarHeader.Length); - hdr.ReadFrom(hdrBuf, 0); - while (hdr.FileLength != 0 || !string.IsNullOrEmpty(hdr.FileName)) - { - FileRecord record = new FileRecord(hdr.FileName, _fileStream.Position, hdr.FileLength); - _files.Add(record.Name, record); - _fileStream.Position += (hdr.FileLength + 511) / 512 * 512; - - hdrBuf = StreamUtilities.ReadExact(_fileStream, TarHeader.Length); - hdr.ReadFrom(hdrBuf, 0); - } - } - - /// - /// Tries to open a file contained in the archive, if it exists. - /// - /// The path to the file within the archive. - /// A stream containing the file contents, or null. - /// true if the file could be opened, else false. - public bool TryOpenFile(string path, out Stream stream) - { - if (_files.ContainsKey(path)) - { - FileRecord file = _files[path]; - stream = new SubStream(_fileStream, file.Start, file.Length); - return true; - } - - stream = null; - return false; - } - - /// - /// Open a file contained in the archive. - /// - /// The path to the file within the archive. - /// A stream containing the file contents. - /// Thrown if the file is not found. - public Stream OpenFile(string path) - { - if (_files.ContainsKey(path)) - { - FileRecord file = _files[path]; - return new SubStream(_fileStream, file.Start, file.Length); - } - - throw new FileNotFoundException("File is not in archive", path); - } - - /// - /// Determines if a given file exists in the archive. - /// - /// The file path to test. - /// true if the file is present, else false. - public bool FileExists(string path) - { - return _files.ContainsKey(path); - } - - /// - /// Determines if a given directory exists in the archive. - /// - /// The file path to test. - /// true if the directory is present, else false. - public bool DirExists(string path) - { - string searchStr = path; - searchStr = searchStr.Replace(@"\", "/"); - searchStr = searchStr.EndsWith(@"/", StringComparison.Ordinal) ? searchStr : searchStr + @"/"; - - foreach (string filePath in _files.Keys) - { - if (filePath.StartsWith(searchStr, StringComparison.Ordinal)) - { - return true; - } - } - - return false; - } - - internal IEnumerable GetFiles(string dir) - { - string searchStr = dir; - searchStr = searchStr.Replace(@"\", "/"); - searchStr = searchStr.EndsWith(@"/", StringComparison.Ordinal) ? searchStr : searchStr + @"/"; - - foreach (string filePath in _files.Keys) - { - if (filePath.StartsWith(searchStr, StringComparison.Ordinal)) - { - yield return _files[filePath]; - } - } - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Archives/TarFileBuilder.cs b/src/LibHac.Nand/DiscUtils.Core/Archives/TarFileBuilder.cs deleted file mode 100644 index 18838774..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Archives/TarFileBuilder.cs +++ /dev/null @@ -1,122 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; -using System.IO; -using DiscUtils.Streams; - -namespace DiscUtils.Archives -{ - /// - /// Builder to create UNIX Tar archive files. - /// - public sealed class TarFileBuilder : StreamBuilder - { - private readonly List _files; - - /// - /// Initializes a new instance of the class. - /// - public TarFileBuilder() - { - _files = new List(); - } - - /// - /// Add a file to the tar archive. - /// - /// The name of the file. - /// The file data. - public void AddFile(string name, byte[] buffer) - { - _files.Add(new UnixBuildFileRecord(name, buffer)); - } - - /// - /// Add a file to the tar archive. - /// - /// The name of the file. - /// The file data. - /// The access mode of the file. - /// The uid of the owner. - /// The gid of the owner. - /// The modification time for the file. - public void AddFile( - string name, byte[] buffer, UnixFilePermissions fileMode, int ownerId, int groupId, - DateTime modificationTime) - { - _files.Add(new UnixBuildFileRecord(name, buffer, fileMode, ownerId, groupId, modificationTime)); - } - - /// - /// Add a file to the tar archive. - /// - /// The name of the file. - /// The file data. - public void AddFile(string name, Stream stream) - { - _files.Add(new UnixBuildFileRecord(name, stream)); - } - - /// - /// Add a file to the tar archive. - /// - /// The name of the file. - /// The file data. - /// The access mode of the file. - /// The uid of the owner. - /// The gid of the owner. - /// The modification time for the file. - public void AddFile( - string name, Stream stream, UnixFilePermissions fileMode, int ownerId, int groupId, - DateTime modificationTime) - { - _files.Add(new UnixBuildFileRecord(name, stream, fileMode, ownerId, groupId, modificationTime)); - } - - protected override List FixExtents(out long totalLength) - { - List result = new List(_files.Count * 2 + 2); - long pos = 0; - - foreach (UnixBuildFileRecord file in _files) - { - BuilderExtent fileContentExtent = file.Fix(pos + TarHeader.Length); - - result.Add(new TarHeaderExtent( - pos, file.Name, fileContentExtent.Length, file.FileMode, file.OwnerId, file.GroupId, - file.ModificationTime)); - pos += TarHeader.Length; - - result.Add(fileContentExtent); - pos += MathUtilities.RoundUp(fileContentExtent.Length, 512); - } - - // Two empty 512-byte blocks at end of tar file. - result.Add(new BuilderBufferExtent(pos, new byte[1024])); - - totalLength = pos + 1024; - return result; - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Archives/TarHeader.cs b/src/LibHac.Nand/DiscUtils.Core/Archives/TarHeader.cs deleted file mode 100644 index 22ec87a9..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Archives/TarHeader.cs +++ /dev/null @@ -1,102 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using DiscUtils.Streams; - -namespace DiscUtils.Archives -{ - internal sealed class TarHeader - { - public const int Length = 512; - public long FileLength; - public UnixFilePermissions FileMode; - - public string FileName; - public int GroupId; - public DateTime ModificationTime; - public int OwnerId; - - public void ReadFrom(byte[] buffer, int offset) - { - FileName = ReadNullTerminatedString(buffer, offset + 0, 100); - FileMode = (UnixFilePermissions)OctalToLong(ReadNullTerminatedString(buffer, offset + 100, 8)); - OwnerId = (int)OctalToLong(ReadNullTerminatedString(buffer, offset + 108, 8)); - GroupId = (int)OctalToLong(ReadNullTerminatedString(buffer, offset + 116, 8)); - FileLength = OctalToLong(ReadNullTerminatedString(buffer, offset + 124, 12)); - ModificationTime = OctalToLong(ReadNullTerminatedString(buffer, offset + 136, 12)).FromUnixTimeSeconds().DateTime; - } - - public void WriteTo(byte[] buffer, int offset) - { - Array.Clear(buffer, offset, Length); - - EndianUtilities.StringToBytes(FileName, buffer, offset, 99); - EndianUtilities.StringToBytes(LongToOctal((long)FileMode, 7), buffer, offset + 100, 7); - EndianUtilities.StringToBytes(LongToOctal(OwnerId, 7), buffer, offset + 108, 7); - EndianUtilities.StringToBytes(LongToOctal(GroupId, 7), buffer, offset + 116, 7); - EndianUtilities.StringToBytes(LongToOctal(FileLength, 11), buffer, offset + 124, 11); - EndianUtilities.StringToBytes(LongToOctal(Convert.ToUInt32((new DateTimeOffset(ModificationTime)).ToUnixTimeSeconds()), 11), buffer, offset + 136, 11); - - // Checksum - EndianUtilities.StringToBytes(new string(' ', 8), buffer, offset + 148, 8); - long checkSum = 0; - for (int i = 0; i < 512; ++i) - { - checkSum += buffer[offset + i]; - } - - EndianUtilities.StringToBytes(LongToOctal(checkSum, 7), buffer, offset + 148, 7); - buffer[155] = 0; - } - - private static string ReadNullTerminatedString(byte[] buffer, int offset, int length) - { - return EndianUtilities.BytesToString(buffer, offset, length).TrimEnd('\0'); - } - - private static long OctalToLong(string value) - { - long result = 0; - - for (int i = 0; i < value.Length; ++i) - { - result = result * 8 + (value[i] - '0'); - } - - return result; - } - - private static string LongToOctal(long value, int length) - { - string result = string.Empty; - - while (value > 0) - { - result = (char)('0' + value % 8) + result; - value = value / 8; - } - - return new string('0', length - result.Length) + result; - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Archives/TarHeaderExtent.cs b/src/LibHac.Nand/DiscUtils.Core/Archives/TarHeaderExtent.cs deleted file mode 100644 index df089a24..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Archives/TarHeaderExtent.cs +++ /dev/null @@ -1,68 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using DiscUtils.Streams; - -namespace DiscUtils.Archives -{ - internal sealed class TarHeaderExtent : BuilderBufferExtent - { - private readonly long _fileLength; - private readonly string _fileName; - private readonly int _groupId; - private readonly UnixFilePermissions _mode; - private readonly DateTime _modificationTime; - private readonly int _ownerId; - - public TarHeaderExtent(long start, string fileName, long fileLength, UnixFilePermissions mode, int ownerId, - int groupId, DateTime modificationTime) - : base(start, 512) - { - _fileName = fileName; - _fileLength = fileLength; - _mode = mode; - _ownerId = ownerId; - _groupId = groupId; - _modificationTime = modificationTime; - } - - public TarHeaderExtent(long start, string fileName, long fileLength) - : this(start, fileName, fileLength, 0, 0, 0, DateTimeOffsetExtensions.UnixEpoch) {} - - protected override byte[] GetBuffer() - { - byte[] buffer = new byte[TarHeader.Length]; - - TarHeader header = new TarHeader(); - header.FileName = _fileName; - header.FileLength = _fileLength; - header.FileMode = _mode; - header.OwnerId = _ownerId; - header.GroupId = _groupId; - header.ModificationTime = _modificationTime; - header.WriteTo(buffer, 0); - - return buffer; - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Archives/UnixBuildFileRecord.cs b/src/LibHac.Nand/DiscUtils.Core/Archives/UnixBuildFileRecord.cs deleted file mode 100644 index fb1e3f4f..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Archives/UnixBuildFileRecord.cs +++ /dev/null @@ -1,75 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.IO; -using DiscUtils.Streams; - -namespace DiscUtils.Archives -{ - internal sealed class UnixBuildFileRecord - { - private readonly BuilderExtentSource _source; - - public UnixBuildFileRecord(string name, byte[] buffer) - : this(name, new BuilderBufferExtentSource(buffer), 0, 0, 0, DateTimeOffsetExtensions.UnixEpoch) {} - - public UnixBuildFileRecord(string name, Stream stream) - : this(name, new BuilderStreamExtentSource(stream), 0, 0, 0, DateTimeOffsetExtensions.UnixEpoch) {} - - public UnixBuildFileRecord( - string name, byte[] buffer, UnixFilePermissions fileMode, int ownerId, int groupId, - DateTime modificationTime) - : this(name, new BuilderBufferExtentSource(buffer), fileMode, ownerId, groupId, modificationTime) {} - - public UnixBuildFileRecord( - string name, Stream stream, UnixFilePermissions fileMode, int ownerId, int groupId, - DateTime modificationTime) - : this(name, new BuilderStreamExtentSource(stream), fileMode, ownerId, groupId, modificationTime) {} - - public UnixBuildFileRecord(string name, BuilderExtentSource fileSource, UnixFilePermissions fileMode, - int ownerId, int groupId, DateTime modificationTime) - { - Name = name; - _source = fileSource; - FileMode = fileMode; - OwnerId = ownerId; - GroupId = groupId; - ModificationTime = modificationTime; - } - - public UnixFilePermissions FileMode { get; } - - public int GroupId { get; } - - public DateTime ModificationTime { get; } - - public string Name { get; } - - public int OwnerId { get; } - - public BuilderExtent Fix(long pos) - { - return _source.Fix(pos); - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/ChsAddress.cs b/src/LibHac.Nand/DiscUtils.Core/ChsAddress.cs deleted file mode 100644 index 1bb74e13..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/ChsAddress.cs +++ /dev/null @@ -1,99 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -namespace DiscUtils -{ - /// - /// Class whose instances represent a CHS (Cylinder, Head, Sector) address on a disk. - /// - /// Instances of this class are immutable. - public sealed class ChsAddress - { - /// - /// The address of the first sector on any disk. - /// - public static readonly ChsAddress First = new ChsAddress(0, 0, 1); - - /// - /// Initializes a new instance of the ChsAddress class. - /// - /// The number of cylinders of the disk. - /// The number of heads (aka platters) of the disk. - /// The number of sectors per track/cylinder of the disk. - public ChsAddress(int cylinder, int head, int sector) - { - Cylinder = cylinder; - Head = head; - Sector = sector; - } - - /// - /// Gets the cylinder number (zero-based). - /// - public int Cylinder { get; } - - /// - /// Gets the head (zero-based). - /// - public int Head { get; } - - /// - /// Gets the sector number (one-based). - /// - public int Sector { get; } - - /// - /// Determines if this object is equivalent to another. - /// - /// The object to test against. - /// true if the is equivalent, else false. - public override bool Equals(object obj) - { - if (obj == null || obj.GetType() != GetType()) - { - return false; - } - - ChsAddress other = (ChsAddress)obj; - - return Cylinder == other.Cylinder && Head == other.Head && Sector == other.Sector; - } - - /// - /// Calculates the hash code for this object. - /// - /// The hash code. - public override int GetHashCode() - { - return Cylinder.GetHashCode() ^ Head.GetHashCode() ^ Sector.GetHashCode(); - } - - /// - /// Gets a string representation of this object, in the form (C/H/S). - /// - /// The string representation. - public override string ToString() - { - return "(" + Cylinder + "/" + Head + "/" + Sector + ")"; - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/ClusterMap.cs b/src/LibHac.Nand/DiscUtils.Core/ClusterMap.cs deleted file mode 100644 index 4cf55342..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/ClusterMap.cs +++ /dev/null @@ -1,75 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System.Collections.Generic; - -namespace DiscUtils -{ - /// - /// Class that identifies the role of each cluster in a file system. - /// - public sealed class ClusterMap - { - private readonly object[] _clusterToFileId; - private readonly ClusterRoles[] _clusterToRole; - private readonly Dictionary _fileIdToPaths; - - internal ClusterMap(ClusterRoles[] clusterToRole, object[] clusterToFileId, - Dictionary fileIdToPaths) - { - _clusterToRole = clusterToRole; - _clusterToFileId = clusterToFileId; - _fileIdToPaths = fileIdToPaths; - } - - /// - /// Gets the role of a cluster within the file system. - /// - /// The cluster to inspect. - /// The clusters role (or roles). - public ClusterRoles GetRole(long cluster) - { - if (_clusterToRole == null || _clusterToRole.Length < cluster) - { - return ClusterRoles.None; - } - return _clusterToRole[cluster]; - } - - /// - /// Converts a cluster to a list of file names. - /// - /// The cluster to inspect. - /// A list of paths that map to the cluster. - /// A list is returned because on file systems with the notion of - /// hard links, a cluster may correspond to multiple directory entries. - public string[] ClusterToPaths(long cluster) - { - if ((GetRole(cluster) & (ClusterRoles.DataFile | ClusterRoles.SystemFile)) != 0) - { - object fileId = _clusterToFileId[cluster]; - return _fileIdToPaths[fileId]; - } - return new string[0]; - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/ClusterRoles.cs b/src/LibHac.Nand/DiscUtils.Core/ClusterRoles.cs deleted file mode 100644 index 130a2902..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/ClusterRoles.cs +++ /dev/null @@ -1,50 +0,0 @@ -using System; - -namespace DiscUtils -{ - /// - /// Enumeration of possible cluster roles. - /// - /// A cluster may be in more than one role. - [Flags] - public enum ClusterRoles - { - /// - /// Unknown, or unspecified role. - /// - None = 0x00, - - /// - /// Cluster is free. - /// - Free = 0x01, - - /// - /// Cluster is in use by a normal file. - /// - DataFile = 0x02, - - /// - /// Cluster is in use by a system file. - /// - /// This isn't a file marked with the 'system' attribute, - /// rather files that form part of the file system namespace but also - /// form part of the file system meta-data. - SystemFile = 0x04, - - /// - /// Cluster is in use for meta-data. - /// - Metadata = 0x08, - - /// - /// Cluster contains the boot region. - /// - BootArea = 0x10, - - /// - /// Cluster is marked bad. - /// - Bad = 0x20 - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Compression/Adler32.cs b/src/LibHac.Nand/DiscUtils.Core/Compression/Adler32.cs deleted file mode 100644 index 630afc11..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Compression/Adler32.cs +++ /dev/null @@ -1,93 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; - -namespace DiscUtils.Compression -{ - /// - /// Implementation of the Adler-32 checksum algorithm. - /// - public class Adler32 - { - private uint _a; - private uint _b; - - /// - /// Initializes a new instance of the Adler32 class. - /// - public Adler32() - { - _a = 1; - } - - /// - /// Gets the checksum of all data processed so far. - /// - public int Value - { - get { return (int)(_b << 16 | _a); } - } - - /// - /// Provides data that should be checksummed. - /// - /// Buffer containing the data to checksum. - /// Offset of the first byte to checksum. - /// The number of bytes to checksum. - /// - /// Call this method repeatedly until all checksummed - /// data has been processed. - /// - public void Process(byte[] buffer, int offset, int count) - { - if (buffer == null) - { - throw new ArgumentNullException(nameof(buffer)); - } - - if (offset < 0 || offset > buffer.Length) - { - throw new ArgumentException("Offset outside of array bounds", nameof(offset)); - } - - if (count < 0 || offset + count > buffer.Length) - { - throw new ArgumentException("Array index out of bounds", nameof(count)); - } - - int processed = 0; - while (processed < count) - { - int innerEnd = Math.Min(count, processed + 2000); - while (processed < innerEnd) - { - _a += buffer[processed++]; - _b += _a; - } - - _a %= 65521; - _b %= 65521; - } - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Compression/BZip2BlockDecoder.cs b/src/LibHac.Nand/DiscUtils.Core/Compression/BZip2BlockDecoder.cs deleted file mode 100644 index 188a4a5f..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Compression/BZip2BlockDecoder.cs +++ /dev/null @@ -1,141 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -// -// Based on "libbzip2", Copyright (C) 1996-2007 Julian R Seward. -// - -using System.IO; - -namespace DiscUtils.Compression -{ - internal class BZip2BlockDecoder - { - private readonly InverseBurrowsWheeler _inverseBurrowsWheeler; - - public BZip2BlockDecoder(int blockSize) - { - _inverseBurrowsWheeler = new InverseBurrowsWheeler(blockSize); - } - - public uint Crc { get; private set; } - - public int Process(BitStream bitstream, byte[] outputBuffer, int outputBufferOffset) - { - Crc = 0; - for (int i = 0; i < 4; ++i) - { - Crc = (Crc << 8) | bitstream.Read(8); - } - - bool rand = bitstream.Read(1) != 0; - int origPtr = (int)bitstream.Read(24); - - int thisBlockSize = ReadBuffer(bitstream, outputBuffer, outputBufferOffset); - - _inverseBurrowsWheeler.OriginalIndex = origPtr; - _inverseBurrowsWheeler.Process(outputBuffer, outputBufferOffset, thisBlockSize, outputBuffer, - outputBufferOffset); - - if (rand) - { - BZip2Randomizer randomizer = new BZip2Randomizer(); - randomizer.Process(outputBuffer, outputBufferOffset, thisBlockSize, outputBuffer, outputBufferOffset); - } - - return thisBlockSize; - } - - private static int ReadBuffer(BitStream bitstream, byte[] buffer, int offset) - { - // The MTF state - int numInUse = 0; - MoveToFront moveFrontTransform = new MoveToFront(); - bool[] inUseGroups = new bool[16]; - for (int i = 0; i < 16; ++i) - { - inUseGroups[i] = bitstream.Read(1) != 0; - } - - for (int i = 0; i < 256; ++i) - { - if (inUseGroups[i / 16]) - { - if (bitstream.Read(1) != 0) - { - moveFrontTransform.Set(numInUse, (byte)i); - numInUse++; - } - } - } - - // Initialize 'virtual' Huffman tree from bitstream - BZip2CombinedHuffmanTrees huffmanTree = new BZip2CombinedHuffmanTrees(bitstream, numInUse + 2); - - // Main loop reading data - int readBytes = 0; - while (true) - { - uint symbol = huffmanTree.NextSymbol(); - - if (symbol < 2) - { - // RLE, with length stored in a binary-style format - uint runLength = 0; - int bitShift = 0; - while (symbol < 2) - { - runLength += (symbol + 1) << bitShift; - bitShift++; - - symbol = huffmanTree.NextSymbol(); - } - - byte b = moveFrontTransform.Head; - while (runLength > 0) - { - buffer[offset + readBytes] = b; - ++readBytes; - --runLength; - } - } - - if (symbol <= numInUse) - { - // Single byte - byte b = moveFrontTransform.GetAndMove((int)symbol - 1); - buffer[offset + readBytes] = b; - ++readBytes; - } - else if (symbol == numInUse + 1) - { - // End of block marker - return readBytes; - } - else - { - throw new InvalidDataException("Invalid symbol from Huffman table"); - } - } - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Compression/BZip2CombinedHuffmanTrees.cs b/src/LibHac.Nand/DiscUtils.Core/Compression/BZip2CombinedHuffmanTrees.cs deleted file mode 100644 index 4af22959..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Compression/BZip2CombinedHuffmanTrees.cs +++ /dev/null @@ -1,134 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -// -// Based on "libbzip2", Copyright (C) 1996-2007 Julian R Seward. -// - -using System.IO; - -namespace DiscUtils.Compression -{ - /// - /// Represents scheme used by BZip2 where multiple Huffman trees are used as a - /// virtual Huffman tree, with a logical selector every 50 bits in the bit stream. - /// - internal class BZip2CombinedHuffmanTrees - { - private HuffmanTree _activeTree; - private readonly BitStream _bitstream; - private int _nextSelector; - private byte[] _selectors; - private int _symbolsToNextSelector; - private HuffmanTree[] _trees; - - public BZip2CombinedHuffmanTrees(BitStream bitstream, int maxSymbols) - { - _bitstream = bitstream; - - Initialize(maxSymbols); - } - - public uint NextSymbol() - { - if (_symbolsToNextSelector == 0) - { - _symbolsToNextSelector = 50; - _activeTree = _trees[_selectors[_nextSelector]]; - _nextSelector++; - } - - _symbolsToNextSelector--; - - return _activeTree.NextSymbol(_bitstream); - } - - private void Initialize(int maxSymbols) - { - int numTrees = (int)_bitstream.Read(3); - if (numTrees < 2 || numTrees > 6) - { - throw new InvalidDataException("Invalid number of tables"); - } - - int numSelectors = (int)_bitstream.Read(15); - if (numSelectors < 1) - { - throw new InvalidDataException("Invalid number of selectors"); - } - - _selectors = new byte[numSelectors]; - MoveToFront mtf = new MoveToFront(numTrees, true); - for (int i = 0; i < numSelectors; ++i) - { - _selectors[i] = mtf.GetAndMove(CountSetBits(numTrees)); - } - - _trees = new HuffmanTree[numTrees]; - for (int t = 0; t < numTrees; ++t) - { - uint[] lengths = new uint[maxSymbols]; - - uint len = _bitstream.Read(5); - for (int i = 0; i < maxSymbols; ++i) - { - if (len < 1 || len > 20) - { - throw new InvalidDataException("Invalid length constructing Huffman tree"); - } - - while (_bitstream.Read(1) != 0) - { - len = _bitstream.Read(1) == 0 ? len + 1 : len - 1; - - if (len < 1 || len > 20) - { - throw new InvalidDataException("Invalid length constructing Huffman tree"); - } - } - - lengths[i] = len; - } - - _trees[t] = new HuffmanTree(lengths); - } - - _symbolsToNextSelector = 0; - _nextSelector = 0; - } - - private byte CountSetBits(int max) - { - byte val = 0; - while (_bitstream.Read(1) != 0) - { - val++; - if (val >= max) - { - throw new InvalidDataException("Exceeded max number of consecutive bits"); - } - } - - return val; - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Compression/BZip2DecoderStream.cs b/src/LibHac.Nand/DiscUtils.Core/Compression/BZip2DecoderStream.cs deleted file mode 100644 index 0d22745f..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Compression/BZip2DecoderStream.cs +++ /dev/null @@ -1,348 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -// -// Based on "libbzip2", Copyright (C) 1996-2007 Julian R Seward. -// - -using System; -using System.IO; -using DiscUtils.Internal; -using DiscUtils.Streams; - -namespace DiscUtils.Compression -{ - /// - /// Implementation of a BZip2 decoder. - /// - public sealed class BZip2DecoderStream : Stream - { - private readonly BitStream _bitstream; - - private readonly byte[] _blockBuffer; - private uint _blockCrc; - private readonly BZip2BlockDecoder _blockDecoder; - private Crc32 _calcBlockCrc; - private uint _calcCompoundCrc; - private uint _compoundCrc; - private Stream _compressedStream; - - private bool _eof; - private readonly Ownership _ownsCompressed; - private long _position; - private BZip2RleStream _rleStream; - - /// - /// Initializes a new instance of the BZip2DecoderStream class. - /// - /// The compressed input stream. - /// Whether ownership of stream passes to the new instance. - public BZip2DecoderStream(Stream stream, Ownership ownsStream) - { - _compressedStream = stream; - _ownsCompressed = ownsStream; - - _bitstream = new BigEndianBitStream(new BufferedStream(stream)); - - // The Magic BZh - byte[] magic = new byte[3]; - magic[0] = (byte)_bitstream.Read(8); - magic[1] = (byte)_bitstream.Read(8); - magic[2] = (byte)_bitstream.Read(8); - if (magic[0] != 0x42 || magic[1] != 0x5A || magic[2] != 0x68) - { - throw new InvalidDataException("Bad magic at start of stream"); - } - - // The size of the decompression blocks in multiples of 100,000 - int blockSize = (int)_bitstream.Read(8) - 0x30; - if (blockSize < 1 || blockSize > 9) - { - throw new InvalidDataException("Unexpected block size in header: " + blockSize); - } - - blockSize *= 100000; - - _rleStream = new BZip2RleStream(); - _blockDecoder = new BZip2BlockDecoder(blockSize); - _blockBuffer = new byte[blockSize]; - - if (ReadBlock() == 0) - { - _eof = true; - } - } - - /// - /// Gets an indication of whether read access is permitted. - /// - public override bool CanRead - { - get { return true; } - } - - /// - /// Gets an indication of whether seeking is permitted. - /// - public override bool CanSeek - { - get { return false; } - } - - /// - /// Gets an indication of whether write access is permitted. - /// - public override bool CanWrite - { - get { return false; } - } - - /// - /// Gets the length of the stream (the capacity of the underlying buffer). - /// - public override long Length - { - get { throw new NotSupportedException(); } - } - - /// - /// Gets and sets the current position within the stream. - /// - public override long Position - { - get { return _position; } - set { throw new NotSupportedException(); } - } - - /// - /// Flushes all data to the underlying storage. - /// - public override void Flush() - { - throw new NotSupportedException(); - } - - /// - /// Reads a number of bytes from the stream. - /// - /// The destination buffer. - /// The start offset within the destination buffer. - /// The number of bytes to read. - /// The number of bytes read. - public override int Read(byte[] buffer, int offset, int count) - { - if (buffer == null) - { - throw new ArgumentNullException(nameof(buffer)); - } - - if (buffer.Length < offset + count) - { - throw new ArgumentException("Buffer smaller than declared"); - } - - if (offset < 0) - { - throw new ArgumentException("Offset less than zero", nameof(offset)); - } - - if (count < 0) - { - throw new ArgumentException("Count less than zero", nameof(count)); - } - - if (_eof) - { - throw new IOException("Attempt to read beyond end of stream"); - } - - if (count == 0) - { - return 0; - } - - int numRead = _rleStream.Read(buffer, offset, count); - if (numRead == 0) - { - // If there was an existing block, check it's crc. - if (_calcBlockCrc != null) - { - if (_blockCrc != _calcBlockCrc.Value) - { - throw new InvalidDataException("Decompression failed - block CRC mismatch"); - } - - _calcCompoundCrc = ((_calcCompoundCrc << 1) | (_calcCompoundCrc >> 31)) ^ _blockCrc; - } - - // Read a new block (if any), if none - check the overall CRC before returning - if (ReadBlock() == 0) - { - _eof = true; - if (_calcCompoundCrc != _compoundCrc) - { - throw new InvalidDataException("Decompression failed - compound CRC"); - } - - return 0; - } - - numRead = _rleStream.Read(buffer, offset, count); - } - - _calcBlockCrc.Process(buffer, offset, numRead); - - // Pre-read next block, so a client that knows the decompressed length will still - // have the overall CRC calculated. - if (_rleStream.AtEof) - { - // If there was an existing block, check it's crc. - if (_calcBlockCrc != null) - { - if (_blockCrc != _calcBlockCrc.Value) - { - throw new InvalidDataException("Decompression failed - block CRC mismatch"); - } - } - - _calcCompoundCrc = ((_calcCompoundCrc << 1) | (_calcCompoundCrc >> 31)) ^ _blockCrc; - if (ReadBlock() == 0) - { - _eof = true; - if (_calcCompoundCrc != _compoundCrc) - { - throw new InvalidDataException("Decompression failed - compound CRC mismatch"); - } - - return numRead; - } - } - - _position += numRead; - return numRead; - } - - /// - /// Changes the current stream position. - /// - /// The origin-relative stream position. - /// The origin for the stream position. - /// The new stream position. - public override long Seek(long offset, SeekOrigin origin) - { - throw new NotSupportedException(); - } - - /// - /// Sets the length of the stream (the underlying buffer's capacity). - /// - /// The new length of the stream. - public override void SetLength(long value) - { - throw new NotSupportedException(); - } - - /// - /// Writes a buffer to the stream. - /// - /// The buffer to write. - /// The starting offset within buffer. - /// The number of bytes to write. - public override void Write(byte[] buffer, int offset, int count) - { - throw new NotSupportedException(); - } - - /// - /// Releases underlying resources. - /// - /// Whether this method is called from Dispose. - protected override void Dispose(bool disposing) - { - try - { - if (disposing) - { - if (_compressedStream != null && _ownsCompressed == Ownership.Dispose) - { - _compressedStream.Dispose(); - } - - _compressedStream = null; - - if (_rleStream != null) - { - _rleStream.Dispose(); - _rleStream = null; - } - } - } - finally - { - base.Dispose(disposing); - } - } - - private int ReadBlock() - { - ulong marker = ReadMarker(); - if (marker == 0x314159265359) - { - int blockSize = _blockDecoder.Process(_bitstream, _blockBuffer, 0); - _rleStream.Reset(_blockBuffer, 0, blockSize); - _blockCrc = _blockDecoder.Crc; - _calcBlockCrc = new Crc32BigEndian(Crc32Algorithm.Common); - return blockSize; - } - if (marker == 0x177245385090) - { - _compoundCrc = ReadUint(); - return 0; - } - throw new InvalidDataException("Found invalid marker in stream"); - } - - private uint ReadUint() - { - uint val = 0; - - for (int i = 0; i < 4; ++i) - { - val = (val << 8) | _bitstream.Read(8); - } - - return val; - } - - private ulong ReadMarker() - { - ulong marker = 0; - - for (int i = 0; i < 6; ++i) - { - marker = (marker << 8) | _bitstream.Read(8); - } - - return marker; - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Compression/BZip2Randomizer.cs b/src/LibHac.Nand/DiscUtils.Core/Compression/BZip2Randomizer.cs deleted file mode 100644 index 1d72dc7d..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Compression/BZip2Randomizer.cs +++ /dev/null @@ -1,124 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -// -// Based on "libbzip2", Copyright (C) 1996-2007 Julian R Seward. -// - -using System; - -namespace DiscUtils.Compression -{ - internal class BZip2Randomizer : DataBlockTransform - { - private static readonly int[] RandomVals = - { - 619, 720, 127, 481, 931, 816, 813, 233, 566, 247, - 985, 724, 205, 454, 863, 491, 741, 242, 949, 214, - 733, 859, 335, 708, 621, 574, 73, 654, 730, 472, - 419, 436, 278, 496, 867, 210, 399, 680, 480, 51, - 878, 465, 811, 169, 869, 675, 611, 697, 867, 561, - 862, 687, 507, 283, 482, 129, 807, 591, 733, 623, - 150, 238, 59, 379, 684, 877, 625, 169, 643, 105, - 170, 607, 520, 932, 727, 476, 693, 425, 174, 647, - 73, 122, 335, 530, 442, 853, 695, 249, 445, 515, - 909, 545, 703, 919, 874, 474, 882, 500, 594, 612, - 641, 801, 220, 162, 819, 984, 589, 513, 495, 799, - 161, 604, 958, 533, 221, 400, 386, 867, 600, 782, - 382, 596, 414, 171, 516, 375, 682, 485, 911, 276, - 98, 553, 163, 354, 666, 933, 424, 341, 533, 870, - 227, 730, 475, 186, 263, 647, 537, 686, 600, 224, - 469, 68, 770, 919, 190, 373, 294, 822, 808, 206, - 184, 943, 795, 384, 383, 461, 404, 758, 839, 887, - 715, 67, 618, 276, 204, 918, 873, 777, 604, 560, - 951, 160, 578, 722, 79, 804, 96, 409, 713, 940, - 652, 934, 970, 447, 318, 353, 859, 672, 112, 785, - 645, 863, 803, 350, 139, 93, 354, 99, 820, 908, - 609, 772, 154, 274, 580, 184, 79, 626, 630, 742, - 653, 282, 762, 623, 680, 81, 927, 626, 789, 125, - 411, 521, 938, 300, 821, 78, 343, 175, 128, 250, - 170, 774, 972, 275, 999, 639, 495, 78, 352, 126, - 857, 956, 358, 619, 580, 124, 737, 594, 701, 612, - 669, 112, 134, 694, 363, 992, 809, 743, 168, 974, - 944, 375, 748, 52, 600, 747, 642, 182, 862, 81, - 344, 805, 988, 739, 511, 655, 814, 334, 249, 515, - 897, 955, 664, 981, 649, 113, 974, 459, 893, 228, - 433, 837, 553, 268, 926, 240, 102, 654, 459, 51, - 686, 754, 806, 760, 493, 403, 415, 394, 687, 700, - 946, 670, 656, 610, 738, 392, 760, 799, 887, 653, - 978, 321, 576, 617, 626, 502, 894, 679, 243, 440, - 680, 879, 194, 572, 640, 724, 926, 56, 204, 700, - 707, 151, 457, 449, 797, 195, 791, 558, 945, 679, - 297, 59, 87, 824, 713, 663, 412, 693, 342, 606, - 134, 108, 571, 364, 631, 212, 174, 643, 304, 329, - 343, 97, 430, 751, 497, 314, 983, 374, 822, 928, - 140, 206, 73, 263, 980, 736, 876, 478, 430, 305, - 170, 514, 364, 692, 829, 82, 855, 953, 676, 246, - 369, 970, 294, 750, 807, 827, 150, 790, 288, 923, - 804, 378, 215, 828, 592, 281, 565, 555, 710, 82, - 896, 831, 547, 261, 524, 462, 293, 465, 502, 56, - 661, 821, 976, 991, 658, 869, 905, 758, 745, 193, - 768, 550, 608, 933, 378, 286, 215, 979, 792, 961, - 61, 688, 793, 644, 986, 403, 106, 366, 905, 644, - 372, 567, 466, 434, 645, 210, 389, 550, 919, 135, - 780, 773, 635, 389, 707, 100, 626, 958, 165, 504, - 920, 176, 193, 713, 857, 265, 203, 50, 668, 108, - 645, 990, 626, 197, 510, 357, 358, 850, 858, 364, - 936, 638 - }; - - protected override bool BuffersMustNotOverlap - { - get { return false; } - } - - protected override int DoProcess(byte[] input, int inputOffset, int inputCount, byte[] output, int outputOffset) - { - if (input != output || inputOffset != outputOffset) - { - Array.Copy(input, inputOffset, output, outputOffset, inputCount); - } - - int randIndex = 1; - int nextByte = RandomVals[0] - 2; - - while (nextByte < inputCount) - { - output[nextByte] ^= 1; - nextByte += RandomVals[randIndex++]; - randIndex &= 0x1FF; - } - - return inputCount; - } - - protected override int MaxOutputCount(int inputCount) - { - return inputCount; - } - - protected override int MinOutputCount(int inputCount) - { - return inputCount; - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Compression/BZip2RleStream.cs b/src/LibHac.Nand/DiscUtils.Core/Compression/BZip2RleStream.cs deleted file mode 100644 index a400bd3e..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Compression/BZip2RleStream.cs +++ /dev/null @@ -1,157 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -// -// Based on "libbzip2", Copyright (C) 1996-2007 Julian R Seward. -// - -using System; -using System.IO; - -namespace DiscUtils.Compression -{ - internal class BZip2RleStream : Stream - { - private byte[] _blockBuffer; - private int _blockOffset; - private int _blockRemaining; - private byte _lastByte; - - private int _numSame; - private long _position; - private int _runBytesOutstanding; - - public bool AtEof - { - get { return _runBytesOutstanding == 0 && _blockRemaining == 0; } - } - - public override bool CanRead - { - get { return true; } - } - - public override bool CanSeek - { - get { return false; } - } - - public override bool CanWrite - { - get { return false; } - } - - public override long Length - { - get { throw new NotSupportedException(); } - } - - public override long Position - { - get { return _position; } - set { throw new NotSupportedException(); } - } - - public void Reset(byte[] buffer, int offset, int count) - { - _position = 0; - _blockBuffer = buffer; - _blockOffset = offset; - _blockRemaining = count; - _numSame = -1; - _lastByte = 0; - _runBytesOutstanding = 0; - } - - public override void Flush() - { - throw new NotSupportedException(); - } - - public override int Read(byte[] buffer, int offset, int count) - { - int numRead = 0; - - while (numRead < count && _runBytesOutstanding > 0) - { - int runCount = Math.Min(_runBytesOutstanding, count); - for (int i = 0; i < runCount; ++i) - { - buffer[offset + numRead] = _lastByte; - } - - _runBytesOutstanding -= runCount; - numRead += runCount; - } - - while (numRead < count && _blockRemaining > 0) - { - byte b = _blockBuffer[_blockOffset]; - ++_blockOffset; - --_blockRemaining; - - if (_numSame == 4) - { - int runCount = Math.Min(b, count - numRead); - for (int i = 0; i < runCount; ++i) - { - buffer[offset + numRead] = _lastByte; - numRead++; - } - - _runBytesOutstanding = b - runCount; - _numSame = 0; - } - else - { - if (b != _lastByte || _numSame <= 0) - { - _lastByte = b; - _numSame = 0; - } - - buffer[offset + numRead] = b; - numRead++; - _numSame++; - } - } - - _position += numRead; - return numRead; - } - - public override long Seek(long offset, SeekOrigin origin) - { - throw new NotSupportedException(); - } - - public override void SetLength(long value) - { - throw new NotSupportedException(); - } - - public override void Write(byte[] buffer, int offset, int count) - { - throw new NotSupportedException(); - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Compression/BigEndianBitStream.cs b/src/LibHac.Nand/DiscUtils.Core/Compression/BigEndianBitStream.cs deleted file mode 100644 index 21c962ec..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Compression/BigEndianBitStream.cs +++ /dev/null @@ -1,94 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System.IO; - -namespace DiscUtils.Compression -{ - /// - /// Converts a byte stream into a bit stream. - /// - internal class BigEndianBitStream : BitStream - { - private uint _buffer; - private int _bufferAvailable; - private readonly Stream _byteStream; - - private readonly byte[] _readBuffer = new byte[2]; - - public BigEndianBitStream(Stream byteStream) - { - _byteStream = byteStream; - } - - public override int MaxReadAhead - { - get { return 16; } - } - - public override uint Read(int count) - { - if (count > 16) - { - uint result = Read(16) << (count - 16); - return result | Read(count - 16); - } - - EnsureBufferFilled(); - - _bufferAvailable -= count; - - uint mask = (uint)((1 << count) - 1); - - return (_buffer >> _bufferAvailable) & mask; - } - - public override uint Peek(int count) - { - EnsureBufferFilled(); - - uint mask = (uint)((1 << count) - 1); - - return (_buffer >> (_bufferAvailable - count)) & mask; - } - - public override void Consume(int count) - { - EnsureBufferFilled(); - - _bufferAvailable -= count; - } - - private void EnsureBufferFilled() - { - if (_bufferAvailable < 16) - { - _readBuffer[0] = 0; - _readBuffer[1] = 0; - _byteStream.Read(_readBuffer, 0, 2); - - _buffer = _buffer << 16 | (uint)(_readBuffer[0] << 8) | _readBuffer[1]; - _bufferAvailable += 16; - } - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Compression/BitStream.cs b/src/LibHac.Nand/DiscUtils.Core/Compression/BitStream.cs deleted file mode 100644 index 89b08342..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Compression/BitStream.cs +++ /dev/null @@ -1,60 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -namespace DiscUtils.Compression -{ - /// - /// Base class for bit streams. - /// - /// - /// The rules for conversion of a byte stream to a bit stream vary - /// between implementations. - /// - internal abstract class BitStream - { - /// - /// Gets the maximum number of bits that can be peeked on the stream. - /// - public abstract int MaxReadAhead { get; } - - /// - /// Reads bits from the stream. - /// - /// The number of bits to read. - /// The bits as a UInt32. - public abstract uint Read(int count); - - /// - /// Queries data from the stream. - /// - /// The number of bits to query. - /// The bits as a UInt32. - /// This method does not consume the bits (i.e. move the file pointer). - public abstract uint Peek(int count); - - /// - /// Consumes bits from the stream without returning them. - /// - /// The number of bits to consume. - public abstract void Consume(int count); - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Compression/BlockCompressor.cs b/src/LibHac.Nand/DiscUtils.Core/Compression/BlockCompressor.cs deleted file mode 100644 index 5bb1f39e..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Compression/BlockCompressor.cs +++ /dev/null @@ -1,64 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -namespace DiscUtils.Compression -{ - /// - /// Base class for block compression algorithms. - /// - public abstract class BlockCompressor - { - /// - /// Gets or sets the block size parameter to the algorithm. - /// - /// - /// Some algorithms may use this to control both compression and decompression, others may - /// only use it to control compression. Some may ignore it entirely. - /// - public int BlockSize { get; set; } - - /// - /// Compresses some data. - /// - /// The uncompressed input. - /// Offset of the input data in source. - /// The amount of uncompressed data. - /// The destination for the output compressed data. - /// Offset for the output data in compressed. - /// The maximum size of the compressed data on input, and the actual size on output. - /// Indication of success, or indication the data could not compress into the requested space. - public abstract CompressionResult Compress(byte[] source, int sourceOffset, int sourceLength, byte[] compressed, - int compressedOffset, ref int compressedLength); - - /// - /// Decompresses some data. - /// - /// The compressed input. - /// Offset of the input data in source. - /// The amount of compressed data. - /// The destination for the output decompressed data. - /// Offset for the output data in decompressed. - /// The amount of decompressed data. - public abstract int Decompress(byte[] source, int sourceOffset, int sourceLength, byte[] decompressed, - int decompressedOffset); - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Compression/CompressionResult.cs b/src/LibHac.Nand/DiscUtils.Core/Compression/CompressionResult.cs deleted file mode 100644 index ee1c1e74..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Compression/CompressionResult.cs +++ /dev/null @@ -1,50 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -namespace DiscUtils.Compression -{ - /// - /// Possible results of attempting to compress data. - /// - /// - /// A compression routine may return Compressed, even if the data - /// was 'all zeros' or increased in size. The AllZeros and Incompressible - /// values are for algorithms that include special detection for these cases. - /// - public enum CompressionResult - { - /// - /// The data compressed succesfully. - /// - Compressed, - - /// - /// The data was all-zero's. - /// - AllZeros, - - /// - /// The data was incompressible (could not fit into destination buffer). - /// - Incompressible - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Compression/DataBlockTransform.cs b/src/LibHac.Nand/DiscUtils.Core/Compression/DataBlockTransform.cs deleted file mode 100644 index 946dbbe7..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Compression/DataBlockTransform.cs +++ /dev/null @@ -1,70 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Globalization; - -namespace DiscUtils.Compression -{ - internal abstract class DataBlockTransform - { - protected abstract bool BuffersMustNotOverlap { get; } - - public int Process(byte[] input, int inputOffset, int inputCount, byte[] output, int outputOffset) - { - if (output.Length < outputOffset + (long)MinOutputCount(inputCount)) - { - throw new ArgumentException( - string.Format( - CultureInfo.InvariantCulture, - "Output buffer to small, must be at least {0} bytes may need to be {1} bytes", - MinOutputCount(inputCount), - MaxOutputCount(inputCount))); - } - - if (BuffersMustNotOverlap) - { - int maxOut = MaxOutputCount(inputCount); - - if (input == output - && (inputOffset + (long)inputCount > outputOffset) - && (inputOffset <= outputOffset + (long)maxOut)) - { - byte[] tempBuffer = new byte[maxOut]; - - int outCount = DoProcess(input, inputOffset, inputCount, tempBuffer, 0); - Array.Copy(tempBuffer, 0, output, outputOffset, outCount); - - return outCount; - } - } - - return DoProcess(input, inputOffset, inputCount, output, outputOffset); - } - - protected abstract int DoProcess(byte[] input, int inputOffset, int inputCount, byte[] output, int outputOffset); - - protected abstract int MaxOutputCount(int inputCount); - - protected abstract int MinOutputCount(int inputCount); - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Compression/HuffmanTree.cs b/src/LibHac.Nand/DiscUtils.Core/Compression/HuffmanTree.cs deleted file mode 100644 index e0fc50ba..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Compression/HuffmanTree.cs +++ /dev/null @@ -1,102 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -namespace DiscUtils.Compression -{ - /// - /// A canonical Huffman tree implementation. - /// - /// - /// A lookup table is created that will take any bit sequence (max tree depth in length), - /// indicating the output symbol. In WIM files, in practice, no chunk exceeds 32768 bytes - /// in length, so we often end up generating a bigger lookup table than the data it's - /// encoding. This makes for exceptionally fast symbol lookups O(1), but is inefficient - /// overall. - /// - internal sealed class HuffmanTree - { - private readonly uint[] _buffer; - private readonly int _numBits; // Max bits per symbol - private readonly int _numSymbols; // Max symbols - - public HuffmanTree(uint[] lengths) - { - Lengths = lengths; - _numSymbols = lengths.Length; - - uint maxLength = 0; - for (int i = 0; i < Lengths.Length; ++i) - { - if (Lengths[i] > maxLength) - { - maxLength = Lengths[i]; - } - } - - _numBits = (int)maxLength; - _buffer = new uint[1 << _numBits]; - - Build(); - } - - public uint[] Lengths { get; } - - public uint NextSymbol(BitStream bitStream) - { - uint symbol = _buffer[bitStream.Peek(_numBits)]; - - // We may have over-read, reset bitstream position - bitStream.Consume((int)Lengths[symbol]); - - return symbol; - } - - private void Build() - { - int position = 0; - - // For each bit-length... - for (int i = 1; i <= _numBits; ++i) - { - // Check each symbol - for (uint symbol = 0; symbol < _numSymbols; ++symbol) - { - if (Lengths[symbol] == i) - { - int numToFill = 1 << (_numBits - i); - for (int n = 0; n < numToFill; ++n) - { - _buffer[position + n] = symbol; - } - - position += numToFill; - } - } - } - - for (int i = position; i < _buffer.Length; ++i) - { - _buffer[i] = uint.MaxValue; - } - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Compression/InverseBurrowsWheeler.cs b/src/LibHac.Nand/DiscUtils.Core/Compression/InverseBurrowsWheeler.cs deleted file mode 100644 index f49804ac..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Compression/InverseBurrowsWheeler.cs +++ /dev/null @@ -1,97 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; - -namespace DiscUtils.Compression -{ - internal sealed class InverseBurrowsWheeler : DataBlockTransform - { - private readonly int[] _nextPos; - private readonly int[] _pointers; - - public InverseBurrowsWheeler(int bufferSize) - { - _pointers = new int[bufferSize]; - _nextPos = new int[256]; - } - - protected override bool BuffersMustNotOverlap - { - get { return true; } - } - - public int OriginalIndex { get; set; } - - protected override int DoProcess(byte[] input, int inputOffset, int inputCount, byte[] output, int outputOffset) - { - int outputCount = inputCount; - - // First find the frequency of each value - Array.Clear(_nextPos, 0, _nextPos.Length); - for (int i = inputOffset; i < inputOffset + inputCount; ++i) - { - _nextPos[input[i]]++; - } - - // We know they're 'sorted' in the first column, so now can figure - // out the position of the first instance of each. - int sum = 0; - for (int i = 0; i < 256; ++i) - { - int tempSum = sum; - sum += _nextPos[i]; - _nextPos[i] = tempSum; - } - - // For each value in the final column, put a pointer to to the - // 'next' character in the first (sorted) column. - for (int i = 0; i < inputCount; ++i) - { - _pointers[_nextPos[input[inputOffset + i]]++] = i; - } - - // The 'next' character after the end of the original string is the - // first character of the original string. - int focus = _pointers[OriginalIndex]; - - // We can now just walk the pointers to reconstruct the original string - for (int i = 0; i < outputCount; ++i) - { - output[outputOffset + i] = input[inputOffset + focus]; - focus = _pointers[focus]; - } - - return outputCount; - } - - protected override int MaxOutputCount(int inputCount) - { - return inputCount; - } - - protected override int MinOutputCount(int inputCount) - { - return inputCount; - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Compression/MoveToFront.cs b/src/LibHac.Nand/DiscUtils.Core/Compression/MoveToFront.cs deleted file mode 100644 index cf34bbd4..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Compression/MoveToFront.cs +++ /dev/null @@ -1,68 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -namespace DiscUtils.Compression -{ - internal class MoveToFront - { - private readonly byte[] _buffer; - - public MoveToFront() - : this(256, false) {} - - public MoveToFront(int size, bool autoInit) - { - _buffer = new byte[size]; - - if (autoInit) - { - for (byte i = 0; i < size; ++i) - { - _buffer[i] = i; - } - } - } - - public byte Head - { - get { return _buffer[0]; } - } - - public void Set(int pos, byte val) - { - _buffer[pos] = val; - } - - public byte GetAndMove(int pos) - { - byte val = _buffer[pos]; - - for (int i = pos; i > 0; --i) - { - _buffer[i] = _buffer[i - 1]; - } - - _buffer[0] = val; - return val; - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Compression/SizedDeflateStream.cs b/src/LibHac.Nand/DiscUtils.Core/Compression/SizedDeflateStream.cs deleted file mode 100644 index c367da5c..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Compression/SizedDeflateStream.cs +++ /dev/null @@ -1,64 +0,0 @@ -// -// Copyright (c) 2014, Quamotion -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.IO; -using System.IO.Compression; - -namespace DiscUtils.Compression -{ - internal class SizedDeflateStream : DeflateStream - { - private readonly int _length; - private int _position; - - public SizedDeflateStream(Stream stream, CompressionMode mode, bool leaveOpen, int length) - : base(stream, mode, leaveOpen) - { - _length = length; - } - - public override long Length - { - get { return _length; } - } - - public override long Position - { - get { return _position; } - set - { - if (value != Position) - { - throw new NotImplementedException(); - } - } - } - - public override int Read(byte[] array, int offset, int count) - { - int read = base.Read(array, offset, count); - _position += read; - return read; - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Compression/ZlibBuffer.cs b/src/LibHac.Nand/DiscUtils.Core/Compression/ZlibBuffer.cs deleted file mode 100644 index 451f757e..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Compression/ZlibBuffer.cs +++ /dev/null @@ -1,86 +0,0 @@ -// -// Copyright (c) 2014, Quamotion -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; -using System.IO; -using DiscUtils.Streams; -using Buffer=DiscUtils.Streams.Buffer; - -namespace DiscUtils.Compression -{ - internal class ZlibBuffer : Buffer - { - private Ownership _ownership; - private readonly Stream _stream; - private int position; - - public ZlibBuffer(Stream stream, Ownership ownership) - { - _stream = stream; - _ownership = ownership; - position = 0; - } - - public override bool CanRead - { - get { return _stream.CanRead; } - } - - public override bool CanWrite - { - get { return _stream.CanWrite; } - } - - public override long Capacity - { - get { return _stream.Length; } - } - - public override int Read(long pos, byte[] buffer, int offset, int count) - { - if (pos != position) - { - throw new NotSupportedException(); - } - - int read = _stream.Read(buffer, offset, count); - position += read; - return read; - } - - public override void Write(long pos, byte[] buffer, int offset, int count) - { - throw new NotImplementedException(); - } - - public override void SetCapacity(long value) - { - throw new NotImplementedException(); - } - - public override IEnumerable GetExtentsInRange(long start, long count) - { - yield return new StreamExtent(0, _stream.Length); - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Compression/ZlibStream.cs b/src/LibHac.Nand/DiscUtils.Core/Compression/ZlibStream.cs deleted file mode 100644 index c69a1716..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Compression/ZlibStream.cs +++ /dev/null @@ -1,240 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.IO; -using System.IO.Compression; -using DiscUtils.Streams; - -namespace DiscUtils.Compression -{ - /// - /// Implementation of the Zlib compression algorithm. - /// - /// Only decompression is currently implemented. - public class ZlibStream : Stream - { - private readonly Adler32 _adler32; - private readonly DeflateStream _deflateStream; - private readonly CompressionMode _mode; - private readonly Stream _stream; - - /// - /// Initializes a new instance of the ZlibStream class. - /// - /// The stream to compress of decompress. - /// Whether to compress or decompress. - /// Whether closing this stream should leave stream open. - public ZlibStream(Stream stream, CompressionMode mode, bool leaveOpen) - { - _stream = stream; - _mode = mode; - - if (mode == CompressionMode.Decompress) - { - // We just sanity check against expected header values... - byte[] headerBuffer = StreamUtilities.ReadExact(stream, 2); - ushort header = EndianUtilities.ToUInt16BigEndian(headerBuffer, 0); - - if (header % 31 != 0) - { - throw new IOException("Invalid Zlib header found"); - } - - if ((header & 0x0F00) != 8 << 8) - { - throw new NotSupportedException("Zlib compression not using DEFLATE algorithm"); - } - - if ((header & 0x0020) != 0) - { - throw new NotSupportedException("Zlib compression using preset dictionary"); - } - } - else - { - ushort header = - (8 << 8) // DEFLATE - | (7 << 12) // 32K window size - | 0x80; // Default algorithm - header |= (ushort)(31 - header % 31); - - byte[] headerBuffer = new byte[2]; - EndianUtilities.WriteBytesBigEndian(header, headerBuffer, 0); - stream.Write(headerBuffer, 0, 2); - } - - _deflateStream = new DeflateStream(stream, mode, leaveOpen); - _adler32 = new Adler32(); - } - - /// - /// Gets whether the stream can be read. - /// - public override bool CanRead - { - get { return _deflateStream.CanRead; } - } - - /// - /// Gets whether the stream pointer can be changed. - /// - public override bool CanSeek - { - get { return false; } - } - - /// - /// Gets whether the stream can be written to. - /// - public override bool CanWrite - { - get { return _deflateStream.CanWrite; } - } - - /// - /// Gets the length of the stream. - /// - public override long Length - { - get { throw new NotSupportedException(); } - } - - /// - /// Gets and sets the stream position. - /// - public override long Position - { - get { throw new NotSupportedException(); } - set { throw new NotSupportedException(); } - } - - /// - /// Closes the stream. - /// - protected override void Dispose(bool disposing) - { - if (_mode == CompressionMode.Decompress) - { - // Can only check Adler checksum on seekable streams. Since DeflateStream - // aggresively caches input, it normally has already consumed the footer. - if (_stream.CanSeek) - { - _stream.Seek(-4, SeekOrigin.End); - byte[] footerBuffer = StreamUtilities.ReadExact(_stream, 4); - if (EndianUtilities.ToInt32BigEndian(footerBuffer, 0) != _adler32.Value) - { - throw new InvalidDataException("Corrupt decompressed data detected"); - } - } - - _deflateStream.Dispose(); - } - else - { - _deflateStream.Dispose(); - - byte[] footerBuffer = new byte[4]; - EndianUtilities.WriteBytesBigEndian(_adler32.Value, footerBuffer, 0); - _stream.Write(footerBuffer, 0, 4); - } - - base.Dispose(disposing); - } - - /// - /// Flushes the stream. - /// - public override void Flush() - { - _deflateStream.Flush(); - } - - /// - /// Reads data from the stream. - /// - /// The buffer to populate. - /// The first byte to write. - /// The number of bytes requested. - /// The number of bytes read. - public override int Read(byte[] buffer, int offset, int count) - { - CheckParams(buffer, offset, count); - - int numRead = _deflateStream.Read(buffer, offset, count); - _adler32.Process(buffer, offset, numRead); - return numRead; - } - - /// - /// Seeks to a new position. - /// - /// Relative position to seek to. - /// The origin of the seek. - /// The new position. - public override long Seek(long offset, SeekOrigin origin) - { - throw new NotSupportedException(); - } - - /// - /// Changes the length of the stream. - /// - /// The new desired length of the stream. - public override void SetLength(long value) - { - throw new NotSupportedException(); - } - - /// - /// Writes data to the stream. - /// - /// Buffer containing the data to write. - /// Offset of the first byte to write. - /// Number of bytes to write. - public override void Write(byte[] buffer, int offset, int count) - { - CheckParams(buffer, offset, count); - - _adler32.Process(buffer, offset, count); - _deflateStream.Write(buffer, offset, count); - } - - private static void CheckParams(byte[] buffer, int offset, int count) - { - if (buffer == null) - { - throw new ArgumentNullException(nameof(buffer)); - } - - if (offset < 0 || offset > buffer.Length) - { - throw new ArgumentException("Offset outside of array bounds", nameof(offset)); - } - - if (count < 0 || offset + count > buffer.Length) - { - throw new ArgumentException("Array index out of bounds", nameof(count)); - } - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/CoreCompat/EncodingHelper.cs b/src/LibHac.Nand/DiscUtils.Core/CoreCompat/EncodingHelper.cs deleted file mode 100644 index 06fc146b..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/CoreCompat/EncodingHelper.cs +++ /dev/null @@ -1,23 +0,0 @@ -#if NETCORE -using System.Text; -#endif - -namespace DiscUtils.CoreCompat -{ - internal static class EncodingHelper - { - private static bool _registered; - - public static void RegisterEncodings() - { - if (_registered) - return; - - _registered = true; - -#if NETCORE - Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); -#endif - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/CoreCompat/ReflectionHelper.cs b/src/LibHac.Nand/DiscUtils.Core/CoreCompat/ReflectionHelper.cs deleted file mode 100644 index cf4534f4..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/CoreCompat/ReflectionHelper.cs +++ /dev/null @@ -1,91 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Reflection; -using System.Runtime.InteropServices; - -namespace DiscUtils.CoreCompat -{ - internal static class ReflectionHelper - { - public static bool IsEnum(Type type) - { -#if NETCORE - return type.GetTypeInfo().IsEnum; -#else - return type.IsEnum; -#endif - } - - public static Attribute GetCustomAttribute(PropertyInfo property, Type attributeType) - { -#if NETCORE - return property.GetCustomAttribute(attributeType); -#else - return Attribute.GetCustomAttribute(property, attributeType); -#endif - } - - public static Attribute GetCustomAttribute(PropertyInfo property, Type attributeType, bool inherit) - { -#if NETCORE - return property.GetCustomAttribute(attributeType, inherit); -#else - return Attribute.GetCustomAttribute(property, attributeType, inherit); -#endif - } - - public static Attribute GetCustomAttribute(FieldInfo field, Type attributeType) - { -#if NETCORE - return field.GetCustomAttribute(attributeType); -#else - return Attribute.GetCustomAttribute(field, attributeType); -#endif - } - - public static Attribute GetCustomAttribute(Type type, Type attributeType) - { -#if NETCORE - return type.GetTypeInfo().GetCustomAttribute(attributeType); -#else - return Attribute.GetCustomAttribute(type, attributeType); -#endif - } - - public static Attribute GetCustomAttribute(Type type, Type attributeType, bool inherit) - { -#if NETCORE - return type.GetTypeInfo().GetCustomAttribute(attributeType, inherit); -#else - return Attribute.GetCustomAttribute(type, attributeType); -#endif - } - - public static IEnumerable GetCustomAttributes(Type type, Type attributeType, bool inherit) - { -#if NETCORE - return type.GetTypeInfo().GetCustomAttributes(attributeType, inherit); -#else - return Attribute.GetCustomAttributes(type, attributeType); -#endif - } - - public static Assembly GetAssembly(Type type) - { -#if NETCORE - return type.GetTypeInfo().Assembly; -#else - return type.Assembly; -#endif - } - - public static int SizeOf() - { -#if NETCORE - return Marshal.SizeOf(); -#else - return Marshal.SizeOf(typeof(T)); -#endif - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/CoreCompat/StringExtensions.cs b/src/LibHac.Nand/DiscUtils.Core/CoreCompat/StringExtensions.cs deleted file mode 100644 index 76f9f1b3..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/CoreCompat/StringExtensions.cs +++ /dev/null @@ -1,15 +0,0 @@ -#if NETCORE -using System.Globalization; - -namespace DiscUtils.CoreCompat -{ - internal static class StringExtensions - { - public static string ToUpper(this string value, CultureInfo culture) - { - return value.ToUpper(); - } - } -} - -#endif \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/DiscDirectoryInfo.cs b/src/LibHac.Nand/DiscUtils.Core/DiscDirectoryInfo.cs deleted file mode 100644 index 0a198214..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/DiscDirectoryInfo.cs +++ /dev/null @@ -1,190 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System.IO; -using DiscUtils.Internal; - -namespace DiscUtils -{ - /// - /// Provides information about a directory on a disc. - /// - /// - /// This class allows navigation of the disc directory/file hierarchy. - /// - public sealed class DiscDirectoryInfo : DiscFileSystemInfo - { - /// - /// Initializes a new instance of the DiscDirectoryInfo class. - /// - /// The file system the directory info relates to. - /// The path within the file system of the directory. - internal DiscDirectoryInfo(DiscFileSystem fileSystem, string path) - : base(fileSystem, path) {} - - /// - /// Gets a value indicating whether the directory exists. - /// - public override bool Exists - { - get { return FileSystem.DirectoryExists(Path); } - } - - /// - /// Gets the full path of the directory. - /// - public override string FullName - { - get { return base.FullName + @"\"; } - } - - /// - /// Creates a directory. - /// - public void Create() - { - FileSystem.CreateDirectory(Path); - } - - /// - /// Deletes a directory, even if it's not empty. - /// - public override void Delete() - { - FileSystem.DeleteDirectory(Path, false); - } - - /// - /// Deletes a directory, with the caller choosing whether to recurse. - /// - /// true to delete all child node, false to fail if the directory is not empty. - public void Delete(bool recursive) - { - FileSystem.DeleteDirectory(Path, recursive); - } - - /// - /// Moves a directory and it's contents to a new path. - /// - /// The destination directory name. - public void MoveTo(string destinationDirName) - { - FileSystem.MoveDirectory(Path, destinationDirName); - } - - /// - /// Gets all child directories. - /// - /// An array of child directories. - public DiscDirectoryInfo[] GetDirectories() - { - return Utilities.Map(FileSystem.GetDirectories(Path), - p => new DiscDirectoryInfo(FileSystem, p)); - } - - /// - /// Gets all child directories matching a search pattern. - /// - /// The search pattern. - /// An array of child directories, or empty if none match. - /// The search pattern can include the wildcards * (matching 0 or more characters) - /// and ? (matching 1 character). - public DiscDirectoryInfo[] GetDirectories(string pattern) - { - return GetDirectories(pattern, SearchOption.TopDirectoryOnly); - } - - /// - /// Gets all descendant directories matching a search pattern. - /// - /// The search pattern. - /// Whether to search just this directory, or all children. - /// An array of descendant directories, or empty if none match. - /// The search pattern can include the wildcards * (matching 0 or more characters) - /// and ? (matching 1 character). The option parameter determines whether only immediate - /// children, or all children are returned. - public DiscDirectoryInfo[] GetDirectories(string pattern, SearchOption searchOption) - { - return Utilities.Map(FileSystem.GetDirectories(Path, pattern, searchOption), - p => new DiscDirectoryInfo(FileSystem, p)); - } - - /// - /// Gets all files. - /// - /// An array of files. - public DiscFileInfo[] GetFiles() - { - return Utilities.Map(FileSystem.GetFiles(Path), p => new DiscFileInfo(FileSystem, p)); - } - - /// - /// Gets all files matching a search pattern. - /// - /// The search pattern. - /// An array of files, or empty if none match. - /// The search pattern can include the wildcards * (matching 0 or more characters) - /// and ? (matching 1 character). - public DiscFileInfo[] GetFiles(string pattern) - { - return GetFiles(pattern, SearchOption.TopDirectoryOnly); - } - - /// - /// Gets all descendant files matching a search pattern. - /// - /// The search pattern. - /// Whether to search just this directory, or all children. - /// An array of descendant files, or empty if none match. - /// The search pattern can include the wildcards * (matching 0 or more characters) - /// and ? (matching 1 character). The option parameter determines whether only immediate - /// children, or all children are returned. - public DiscFileInfo[] GetFiles(string pattern, SearchOption searchOption) - { - return Utilities.Map(FileSystem.GetFiles(Path, pattern, searchOption), - p => new DiscFileInfo(FileSystem, p)); - } - - /// - /// Gets all files and directories in this directory. - /// - /// An array of files and directories. - public DiscFileSystemInfo[] GetFileSystemInfos() - { - return Utilities.Map(FileSystem.GetFileSystemEntries(Path), - p => new DiscFileSystemInfo(FileSystem, p)); - } - - /// - /// Gets all files and directories in this directory. - /// - /// The search pattern. - /// An array of files and directories. - /// The search pattern can include the wildcards * (matching 0 or more characters) - /// and ? (matching 1 character). - public DiscFileSystemInfo[] GetFileSystemInfos(string pattern) - { - return Utilities.Map(FileSystem.GetFileSystemEntries(Path, pattern), - p => new DiscFileSystemInfo(FileSystem, p)); - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/DiscFileInfo.cs b/src/LibHac.Nand/DiscUtils.Core/DiscFileInfo.cs deleted file mode 100644 index 14d88450..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/DiscFileInfo.cs +++ /dev/null @@ -1,200 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System.IO; - -namespace DiscUtils -{ - /// - /// Provides information about a file on a disc. - /// - public sealed class DiscFileInfo : DiscFileSystemInfo - { - internal DiscFileInfo(DiscFileSystem fileSystem, string path) - : base(fileSystem, path) {} - - /// - /// Gets an instance of the parent directory. - /// - public DiscDirectoryInfo Directory - { - get { return Parent; } - } - - /// - /// Gets a string representing the directory's full path. - /// - public string DirectoryName - { - get { return Directory.FullName; } - } - - /// - /// Gets a value indicating whether the file exists. - /// - public override bool Exists - { - get { return FileSystem.FileExists(Path); } - } - - /// - /// Gets or sets a value indicating whether the file is read-only. - /// - public bool IsReadOnly - { - get { return (Attributes & FileAttributes.ReadOnly) != 0; } - - set - { - if (value) - { - Attributes = Attributes | FileAttributes.ReadOnly; - } - else - { - Attributes = Attributes & ~FileAttributes.ReadOnly; - } - } - } - - /// - /// Gets the length of the current file in bytes. - /// - public long Length - { - get { return FileSystem.GetFileLength(Path); } - } - - /// - /// Deletes a file. - /// - public override void Delete() - { - FileSystem.DeleteFile(Path); - } - - /// - /// Creates a that appends text to the file represented by this . - /// - /// The newly created writer. - public StreamWriter AppendText() - { - return new StreamWriter(Open(FileMode.Append)); - } - - /// - /// Copies an existing file to a new file. - /// - /// The destination file. - public void CopyTo(string destinationFileName) - { - CopyTo(destinationFileName, false); - } - - /// - /// Copies an existing file to a new file, allowing overwriting of an existing file. - /// - /// The destination file. - /// Whether to permit over-writing of an existing file. - public void CopyTo(string destinationFileName, bool overwrite) - { - FileSystem.CopyFile(Path, destinationFileName, overwrite); - } - - /// - /// Creates a new file for reading and writing. - /// - /// The newly created stream. - public Stream Create() - { - return Open(FileMode.Create); - } - - /// - /// Creates a new that writes a new text file. - /// - /// A new stream writer that can write to the file contents. - public StreamWriter CreateText() - { - return new StreamWriter(Open(FileMode.Create)); - } - - /// - /// Moves a file to a new location. - /// - /// The new name of the file. - public void MoveTo(string destinationFileName) - { - FileSystem.MoveFile(Path, destinationFileName); - } - - /// - /// Opens the current file. - /// - /// The file mode for the created stream. - /// The newly created stream. - /// Read-only file systems only support FileMode.Open. - public Stream Open(FileMode mode) - { - return FileSystem.OpenFile(Path, mode); - } - - /// - /// Opens the current file. - /// - /// The file mode for the created stream. - /// The access permissions for the created stream. - /// The newly created stream. - /// Read-only file systems only support FileMode.Open and FileAccess.Read. - public Stream Open(FileMode mode, FileAccess access) - { - return FileSystem.OpenFile(Path, mode, access); - } - - /// - /// Opens an existing file for read-only access. - /// - /// The newly created stream. - public Stream OpenRead() - { - return Open(FileMode.Open, FileAccess.Read); - } - - /// - /// Opens an existing file for reading as UTF-8 text. - /// - /// The newly created reader. - public StreamReader OpenText() - { - return new StreamReader(OpenRead()); - } - - /// - /// Opens a file for writing. - /// - /// The newly created stream. - public Stream OpenWrite() - { - return Open(FileMode.Open, FileAccess.Write); - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/DiscFileLocator.cs b/src/LibHac.Nand/DiscUtils.Core/DiscFileLocator.cs deleted file mode 100644 index 24b41bb9..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/DiscFileLocator.cs +++ /dev/null @@ -1,93 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.IO; -using DiscUtils.Internal; - -namespace DiscUtils -{ - internal sealed class DiscFileLocator : FileLocator - { - private readonly string _basePath; - private readonly DiscFileSystem _fileSystem; - - public DiscFileLocator(DiscFileSystem fileSystem, string basePath) - { - _fileSystem = fileSystem; - _basePath = basePath; - } - - public override bool Exists(string fileName) - { - return _fileSystem.FileExists(Utilities.CombinePaths(_basePath, fileName)); - } - - protected override Stream OpenFile(string fileName, FileMode mode, FileAccess access, FileShare share) - { - return _fileSystem.OpenFile(Utilities.CombinePaths(_basePath, fileName), mode, access); - } - - public override FileLocator GetRelativeLocator(string path) - { - return new DiscFileLocator(_fileSystem, Utilities.CombinePaths(_basePath, path)); - } - - public override string GetFullPath(string path) - { - return Utilities.CombinePaths(_basePath, path); - } - - public override string GetDirectoryFromPath(string path) - { - return Utilities.GetDirectoryFromPath(path); - } - - public override string GetFileFromPath(string path) - { - return Utilities.GetFileFromPath(path); - } - - public override DateTime GetLastWriteTimeUtc(string path) - { - return _fileSystem.GetLastWriteTimeUtc(Utilities.CombinePaths(_basePath, path)); - } - - public override bool HasCommonRoot(FileLocator other) - { - DiscFileLocator otherDiscLocator = other as DiscFileLocator; - - if (otherDiscLocator == null) - { - return false; - } - - // Common root if the same file system instance. - return ReferenceEquals(otherDiscLocator._fileSystem, _fileSystem); - } - - public override string ResolveRelativePath(string path) - { - return Utilities.ResolveRelativePath(_basePath, path); - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/DiscFileSystem.cs b/src/LibHac.Nand/DiscUtils.Core/DiscFileSystem.cs deleted file mode 100644 index a617c6bc..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/DiscFileSystem.cs +++ /dev/null @@ -1,509 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.IO; -using DiscUtils.Streams; - -namespace DiscUtils -{ - /// - /// Provides the base class for all file systems. - /// - public abstract class DiscFileSystem : -#if !NETCORE - MarshalByRefObject, -#endif - IFileSystem, IDisposable - { - /// - /// Initializes a new instance of the DiscFileSystem class. - /// - protected DiscFileSystem() - { - Options = new DiscFileSystemOptions(); - } - - /// - /// Initializes a new instance of the DiscFileSystem class. - /// - /// The options instance to use for this file system instance. - protected DiscFileSystem(DiscFileSystemOptions defaultOptions) - { - Options = defaultOptions; - } - - /// - /// Finalizes an instance of the DiscFileSystem class. - /// - ~DiscFileSystem() - { - Dispose(false); - } - - /// - /// Gets the file system options, which can be modified. - /// - public virtual DiscFileSystemOptions Options { get; } - - /// - /// Gets a friendly description of the file system type. - /// - public abstract string FriendlyName { get; } - - /// - /// Gets a value indicating whether the file system is read-only or read-write. - /// - /// true if the file system is read-write. - public abstract bool CanWrite { get; } - - /// - /// Gets the root directory of the file system. - /// - public virtual DiscDirectoryInfo Root - { - get { return new DiscDirectoryInfo(this, string.Empty); } - } - - /// - /// Gets the volume label. - /// - public virtual string VolumeLabel - { - get { return string.Empty; } - } - - /// - /// Gets a value indicating whether the file system is thread-safe. - /// - public virtual bool IsThreadSafe - { - get { return false; } - } - - /// - /// Copies an existing file to a new file. - /// - /// The source file. - /// The destination file. - public virtual void CopyFile(string sourceFile, string destinationFile) - { - CopyFile(sourceFile, destinationFile, false); - } - - /// - /// Copies an existing file to a new file, allowing overwriting of an existing file. - /// - /// The source file. - /// The destination file. - /// Whether to permit over-writing of an existing file. - public abstract void CopyFile(string sourceFile, string destinationFile, bool overwrite); - - /// - /// Creates a directory. - /// - /// The path of the new directory. - public abstract void CreateDirectory(string path); - - /// - /// Deletes a directory. - /// - /// The path of the directory to delete. - public abstract void DeleteDirectory(string path); - - /// - /// Deletes a directory, optionally with all descendants. - /// - /// The path of the directory to delete. - /// Determines if the all descendants should be deleted. - public virtual void DeleteDirectory(string path, bool recursive) - { - if (recursive) - { - foreach (string dir in GetDirectories(path)) - { - DeleteDirectory(dir, true); - } - - foreach (string file in GetFiles(path)) - { - DeleteFile(file); - } - } - - DeleteDirectory(path); - } - - /// - /// Deletes a file. - /// - /// The path of the file to delete. - public abstract void DeleteFile(string path); - - /// - /// Indicates if a directory exists. - /// - /// The path to test. - /// true if the directory exists. - public abstract bool DirectoryExists(string path); - - /// - /// Indicates if a file exists. - /// - /// The path to test. - /// true if the file exists. - public abstract bool FileExists(string path); - - /// - /// Indicates if a file or directory exists. - /// - /// The path to test. - /// true if the file or directory exists. - public virtual bool Exists(string path) - { - return FileExists(path) || DirectoryExists(path); - } - - /// - /// Gets the names of subdirectories in a specified directory. - /// - /// The path to search. - /// Array of directories. - public virtual string[] GetDirectories(string path) - { - return GetDirectories(path, "*.*", SearchOption.TopDirectoryOnly); - } - - /// - /// Gets the names of subdirectories in a specified directory matching a specified - /// search pattern. - /// - /// The path to search. - /// The search string to match against. - /// Array of directories matching the search pattern. - public virtual string[] GetDirectories(string path, string searchPattern) - { - return GetDirectories(path, searchPattern, SearchOption.TopDirectoryOnly); - } - - /// - /// Gets the names of subdirectories in a specified directory matching a specified - /// search pattern, using a value to determine whether to search subdirectories. - /// - /// The path to search. - /// The search string to match against. - /// Indicates whether to search subdirectories. - /// Array of directories matching the search pattern. - public abstract string[] GetDirectories(string path, string searchPattern, SearchOption searchOption); - - /// - /// Gets the names of files in a specified directory. - /// - /// The path to search. - /// Array of files. - public virtual string[] GetFiles(string path) - { - return GetFiles(path, "*.*", SearchOption.TopDirectoryOnly); - } - - /// - /// Gets the names of files in a specified directory. - /// - /// The path to search. - /// The search string to match against. - /// Array of files matching the search pattern. - public virtual string[] GetFiles(string path, string searchPattern) - { - return GetFiles(path, searchPattern, SearchOption.TopDirectoryOnly); - } - - /// - /// Gets the names of files in a specified directory matching a specified - /// search pattern, using a value to determine whether to search subdirectories. - /// - /// The path to search. - /// The search string to match against. - /// Indicates whether to search subdirectories. - /// Array of files matching the search pattern. - public abstract string[] GetFiles(string path, string searchPattern, SearchOption searchOption); - - /// - /// Gets the names of all files and subdirectories in a specified directory. - /// - /// The path to search. - /// Array of files and subdirectories matching the search pattern. - public abstract string[] GetFileSystemEntries(string path); - - /// - /// Gets the names of files and subdirectories in a specified directory matching a specified - /// search pattern. - /// - /// The path to search. - /// The search string to match against. - /// Array of files and subdirectories matching the search pattern. - public abstract string[] GetFileSystemEntries(string path, string searchPattern); - - /// - /// Moves a directory. - /// - /// The directory to move. - /// The target directory name. - public abstract void MoveDirectory(string sourceDirectoryName, string destinationDirectoryName); - - /// - /// Moves a file. - /// - /// The file to move. - /// The target file name. - public virtual void MoveFile(string sourceName, string destinationName) - { - MoveFile(sourceName, destinationName, false); - } - - /// - /// Moves a file, allowing an existing file to be overwritten. - /// - /// The file to move. - /// The target file name. - /// Whether to permit a destination file to be overwritten. - public abstract void MoveFile(string sourceName, string destinationName, bool overwrite); - - /// - /// Opens the specified file. - /// - /// The full path of the file to open. - /// The file mode for the created stream. - /// The new stream. - public virtual SparseStream OpenFile(string path, FileMode mode) - { - return OpenFile(path, mode, FileAccess.ReadWrite); - } - - /// - /// Opens the specified file. - /// - /// The full path of the file to open. - /// The file mode for the created stream. - /// The access permissions for the created stream. - /// The new stream. - public abstract SparseStream OpenFile(string path, FileMode mode, FileAccess access); - - /// - /// Gets the attributes of a file or directory. - /// - /// The file or directory to inspect. - /// The attributes of the file or directory. - public abstract FileAttributes GetAttributes(string path); - - /// - /// Sets the attributes of a file or directory. - /// - /// The file or directory to change. - /// The new attributes of the file or directory. - public abstract void SetAttributes(string path, FileAttributes newValue); - - /// - /// Gets the creation time (in local time) of a file or directory. - /// - /// The path of the file or directory. - /// The creation time. - public virtual DateTime GetCreationTime(string path) - { - return GetCreationTimeUtc(path).ToLocalTime(); - } - - /// - /// Sets the creation time (in local time) of a file or directory. - /// - /// The path of the file or directory. - /// The new time to set. - public virtual void SetCreationTime(string path, DateTime newTime) - { - SetCreationTimeUtc(path, newTime.ToUniversalTime()); - } - - /// - /// Gets the creation time (in UTC) of a file or directory. - /// - /// The path of the file or directory. - /// The creation time. - public abstract DateTime GetCreationTimeUtc(string path); - - /// - /// Sets the creation time (in UTC) of a file or directory. - /// - /// The path of the file or directory. - /// The new time to set. - public abstract void SetCreationTimeUtc(string path, DateTime newTime); - - /// - /// Gets the last access time (in local time) of a file or directory. - /// - /// The path of the file or directory. - /// The last access time. - public virtual DateTime GetLastAccessTime(string path) - { - return GetLastAccessTimeUtc(path).ToLocalTime(); - } - - /// - /// Sets the last access time (in local time) of a file or directory. - /// - /// The path of the file or directory. - /// The new time to set. - public virtual void SetLastAccessTime(string path, DateTime newTime) - { - SetLastAccessTimeUtc(path, newTime.ToUniversalTime()); - } - - /// - /// Gets the last access time (in UTC) of a file or directory. - /// - /// The path of the file or directory. - /// The last access time. - public abstract DateTime GetLastAccessTimeUtc(string path); - - /// - /// Sets the last access time (in UTC) of a file or directory. - /// - /// The path of the file or directory. - /// The new time to set. - public abstract void SetLastAccessTimeUtc(string path, DateTime newTime); - - /// - /// Gets the last modification time (in local time) of a file or directory. - /// - /// The path of the file or directory. - /// The last write time. - public virtual DateTime GetLastWriteTime(string path) - { - return GetLastWriteTimeUtc(path).ToLocalTime(); - } - - /// - /// Sets the last modification time (in local time) of a file or directory. - /// - /// The path of the file or directory. - /// The new time to set. - public virtual void SetLastWriteTime(string path, DateTime newTime) - { - SetLastWriteTimeUtc(path, newTime.ToUniversalTime()); - } - - /// - /// Gets the last modification time (in UTC) of a file or directory. - /// - /// The path of the file or directory. - /// The last write time. - public abstract DateTime GetLastWriteTimeUtc(string path); - - /// - /// Sets the last modification time (in UTC) of a file or directory. - /// - /// The path of the file or directory. - /// The new time to set. - public abstract void SetLastWriteTimeUtc(string path, DateTime newTime); - - /// - /// Gets the length of a file. - /// - /// The path to the file. - /// The length in bytes. - public abstract long GetFileLength(string path); - - /// - /// Gets an object representing a possible file. - /// - /// The file path. - /// The representing object. - /// The file does not need to exist. - public virtual DiscFileInfo GetFileInfo(string path) - { - return new DiscFileInfo(this, path); - } - - /// - /// Gets an object representing a possible directory. - /// - /// The directory path. - /// The representing object. - /// The directory does not need to exist. - public virtual DiscDirectoryInfo GetDirectoryInfo(string path) - { - return new DiscDirectoryInfo(this, path); - } - - /// - /// Gets an object representing a possible file system object (file or directory). - /// - /// The file system path. - /// The representing object. - /// The file system object does not need to exist. - public virtual DiscFileSystemInfo GetFileSystemInfo(string path) - { - return new DiscFileSystemInfo(this, path); - } - - /// - /// Reads the boot code of the file system into a byte array. - /// - /// The boot code, or null if not available. - public virtual byte[] ReadBootCode() - { - return null; - } - - /// - /// Size of the Filesystem in bytes - /// - public abstract long Size { get; } - - /// - /// Used space of the Filesystem in bytes - /// - public abstract long UsedSpace { get; } - - /// - /// Available space of the Filesystem in bytes - /// - public abstract long AvailableSpace { get; } - - #region IDisposable Members - - /// - /// Disposes of this instance, releasing all resources. - /// - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - /// - /// Disposes of this instance. - /// - /// The value true if Disposing. - protected virtual void Dispose(bool disposing) {} - - #endregion - } -} diff --git a/src/LibHac.Nand/DiscUtils.Core/DiscFileSystemChecker.cs b/src/LibHac.Nand/DiscUtils.Core/DiscFileSystemChecker.cs deleted file mode 100644 index 426f0f0f..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/DiscFileSystemChecker.cs +++ /dev/null @@ -1,43 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System.IO; - -namespace DiscUtils -{ - /// - /// Base class for objects that validate file system integrity. - /// - /// Instances of this class do not offer the ability to fix/correct - /// file system issues, just to perform a limited number of checks on - /// integrity of the file system. - public abstract class DiscFileSystemChecker - { - /// - /// Checks the integrity of a file system held in a stream. - /// - /// A report on issues found. - /// The amount of detail to report. - /// true if the file system appears valid, else false. - public abstract bool Check(TextWriter reportOutput, ReportLevels levels); - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/DiscFileSystemInfo.cs b/src/LibHac.Nand/DiscUtils.Core/DiscFileSystemInfo.cs deleted file mode 100644 index d82e5c6e..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/DiscFileSystemInfo.cs +++ /dev/null @@ -1,219 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.IO; -using DiscUtils.Internal; - -namespace DiscUtils -{ - /// - /// Provides the base class for both and objects. - /// - public class DiscFileSystemInfo - { - internal DiscFileSystemInfo(DiscFileSystem fileSystem, string path) - { - if (path == null) - { - throw new ArgumentNullException(nameof(path)); - } - - FileSystem = fileSystem; - Path = path.Trim('\\'); - } - - /// - /// Gets or sets the of the current object. - /// - public virtual FileAttributes Attributes - { - get { return FileSystem.GetAttributes(Path); } - set { FileSystem.SetAttributes(Path, value); } - } - - /// - /// Gets or sets the creation time (in local time) of the current object. - /// - public virtual DateTime CreationTime - { - get { return CreationTimeUtc.ToLocalTime(); } - set { CreationTimeUtc = value.ToUniversalTime(); } - } - - /// - /// Gets or sets the creation time (in UTC) of the current object. - /// - public virtual DateTime CreationTimeUtc - { - get { return FileSystem.GetCreationTimeUtc(Path); } - set { FileSystem.SetCreationTimeUtc(Path, value); } - } - - /// - /// Gets a value indicating whether the file system object exists. - /// - public virtual bool Exists - { - get { return FileSystem.Exists(Path); } - } - - /// - /// Gets the extension part of the file or directory name. - /// - public virtual string Extension - { - get - { - string name = Name; - int sepIdx = name.LastIndexOf('.'); - if (sepIdx >= 0) - { - return name.Substring(sepIdx + 1); - } - - return string.Empty; - } - } - - /// - /// Gets the file system the referenced file or directory exists on. - /// - public DiscFileSystem FileSystem { get; } - - /// - /// Gets the full path of the file or directory. - /// - public virtual string FullName - { - get { return Path; } - } - - /// - /// Gets or sets the last time (in local time) the file or directory was accessed. - /// - /// Read-only file systems will never update this value, it will remain at a fixed value. - public virtual DateTime LastAccessTime - { - get { return LastAccessTimeUtc.ToLocalTime(); } - set { LastAccessTimeUtc = value.ToUniversalTime(); } - } - - /// - /// Gets or sets the last time (in UTC) the file or directory was accessed. - /// - /// Read-only file systems will never update this value, it will remain at a fixed value. - public virtual DateTime LastAccessTimeUtc - { - get { return FileSystem.GetLastAccessTimeUtc(Path); } - set { FileSystem.SetLastAccessTimeUtc(Path, value); } - } - - /// - /// Gets or sets the last time (in local time) the file or directory was written to. - /// - public virtual DateTime LastWriteTime - { - get { return LastWriteTimeUtc.ToLocalTime(); } - set { LastWriteTimeUtc = value.ToUniversalTime(); } - } - - /// - /// Gets or sets the last time (in UTC) the file or directory was written to. - /// - public virtual DateTime LastWriteTimeUtc - { - get { return FileSystem.GetLastWriteTimeUtc(Path); } - set { FileSystem.SetLastWriteTimeUtc(Path, value); } - } - - /// - /// Gets the name of the file or directory. - /// - public virtual string Name - { - get { return Utilities.GetFileFromPath(Path); } - } - - /// - /// Gets the of the directory containing the current object. - /// - public virtual DiscDirectoryInfo Parent - { - get - { - if (string.IsNullOrEmpty(Path)) - { - return null; - } - - return new DiscDirectoryInfo(FileSystem, Utilities.GetDirectoryFromPath(Path)); - } - } - - /// - /// Gets the path to the referenced file. - /// - protected string Path { get; } - - /// - /// Deletes a file or directory. - /// - public virtual void Delete() - { - if ((Attributes & FileAttributes.Directory) != 0) - { - FileSystem.DeleteDirectory(Path); - } - else - { - FileSystem.DeleteFile(Path); - } - } - - /// - /// Indicates if is equivalent to this object. - /// - /// The object to compare. - /// true if is equivalent, else false. - public override bool Equals(object obj) - { - DiscFileSystemInfo asInfo = obj as DiscFileSystemInfo; - if (obj == null) - { - return false; - } - - return string.Compare(Path, asInfo.Path, StringComparison.Ordinal) == 0 && - Equals(FileSystem, asInfo.FileSystem); - } - - /// - /// Gets the hash code for this object. - /// - /// The hash code. - public override int GetHashCode() - { - return Path.GetHashCode() ^ FileSystem.GetHashCode(); - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/DiscFileSystemOptions.cs b/src/LibHac.Nand/DiscUtils.Core/DiscFileSystemOptions.cs deleted file mode 100644 index b7aed0f4..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/DiscFileSystemOptions.cs +++ /dev/null @@ -1,41 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; - -namespace DiscUtils -{ - /// - /// Common file system options. - /// - /// Not all options are honoured by all file systems. - public class DiscFileSystemOptions - { - /// - /// Gets or sets the random number generator the file system should use. - /// - /// This option is normally null, which is fine for most purposes. - /// Use this option when you need to finely control the filesystem for - /// reproducibility of behaviour (for example in a test harness). - public Random RandomNumberGenerator { get; set; } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/DiskImageBuilder.cs b/src/LibHac.Nand/DiscUtils.Core/DiskImageBuilder.cs deleted file mode 100644 index 0cb23278..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/DiskImageBuilder.cs +++ /dev/null @@ -1,126 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; -using System.Globalization; -using DiscUtils.CoreCompat; -using DiscUtils.Internal; -using DiscUtils.Streams; - -namespace DiscUtils -{ - /// - /// Base class for all disk image builders. - /// - public abstract class DiskImageBuilder - { - private static Dictionary _typeMap; - - /// - /// Gets or sets the geometry of this disk, as reported by the BIOS, will be implied from the content stream if not set. - /// - public Geometry BiosGeometry { get; set; } - - /// - /// Gets or sets the content for this disk, implying the size of the disk. - /// - public SparseStream Content { get; set; } - - /// - /// Gets or sets the adapter type for created virtual disk, for file formats that encode this information. - /// - public virtual GenericDiskAdapterType GenericAdapterType { get; set; } - - /// - /// Gets or sets the geometry of this disk, will be implied from the content stream if not set. - /// - public Geometry Geometry { get; set; } - - /// - /// Gets a value indicating whether this file format preserves BIOS geometry information. - /// - public virtual bool PreservesBiosGeometry - { - get { return false; } - } - - private static Dictionary TypeMap - { - get - { - if (_typeMap == null) - { - InitializeMaps(); - } - - return _typeMap; - } - } - - /// - /// Gets an instance that constructs the specified type (and variant) of virtual disk image. - /// - /// The type of image to build (VHD, VMDK, etc). - /// The variant type (differencing/dynamic, fixed/static, etc). - /// The builder instance. - public static DiskImageBuilder GetBuilder(string type, string variant) - { - VirtualDiskFactory factory; - if (!TypeMap.TryGetValue(type, out factory)) - { - throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "Unknown disk type '{0}'", type), nameof(type)); - } - - return factory.GetImageBuilder(variant); - } - - /// - /// Initiates the construction of the disk image. - /// - /// The base name for the disk images. - /// A set of one or more logical files that constitute the - /// disk image. The first file is the 'primary' file that is normally attached to VMs. - /// The supplied baseName is the start of the file name, with no file - /// extension. The set of file specifications will indicate the actual name corresponding - /// to each logical file that comprises the disk image. For example, given a base name - /// 'foo', the files 'foo.vmdk' and 'foo-flat.vmdk' could be returned. - public abstract DiskImageFileSpecification[] Build(string baseName); - - private static void InitializeMaps() - { - Dictionary typeMap = new Dictionary(); - - foreach (Type type in ReflectionHelper.GetAssembly(typeof(VirtualDisk)).GetTypes()) - { - VirtualDiskFactoryAttribute attr = (VirtualDiskFactoryAttribute)ReflectionHelper.GetCustomAttribute(type, typeof(VirtualDiskFactoryAttribute), false); - if (attr != null) - { - VirtualDiskFactory factory = (VirtualDiskFactory)Activator.CreateInstance(type); - typeMap.Add(attr.Type, factory); - } - } - - _typeMap = typeMap; - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/DiskImageFileSpecification.cs b/src/LibHac.Nand/DiscUtils.Core/DiskImageFileSpecification.cs deleted file mode 100644 index 9e0d2f40..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/DiskImageFileSpecification.cs +++ /dev/null @@ -1,54 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using DiscUtils.Streams; - -namespace DiscUtils -{ - /// - /// Describes a particular file that is a constituent part of a virtual disk. - /// - public sealed class DiskImageFileSpecification - { - private readonly StreamBuilder _builder; - - internal DiskImageFileSpecification(string name, StreamBuilder builder) - { - Name = name; - _builder = builder; - } - - /// - /// Gets name of the file. - /// - public string Name { get; } - - /// - /// Gets the object that provides access to the file's content. - /// - /// A stream object that contains the file's content. - public SparseStream OpenStream() - { - return _builder.Build(); - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/FileLocator.cs b/src/LibHac.Nand/DiscUtils.Core/FileLocator.cs deleted file mode 100644 index 696d6f70..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/FileLocator.cs +++ /dev/null @@ -1,72 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.IO; -using DiscUtils.Internal; -using DiscUtils.Setup; - -namespace DiscUtils -{ - internal abstract class FileLocator - { - public abstract bool Exists(string fileName); - - public Stream Open(string fileName, FileMode mode, FileAccess access, FileShare share) - { - var args = new FileOpenEventArgs(fileName, mode, access, share, OpenFile); - SetupHelper.OnOpeningFile(this, args); - if (args.Result != null) - return args.Result; - return OpenFile(args.FileName, args.FileMode, args.FileAccess, args.FileShare); - } - - protected abstract Stream OpenFile(string fileName, FileMode mode, FileAccess access, FileShare share); - - public abstract FileLocator GetRelativeLocator(string path); - - public abstract string GetFullPath(string path); - - public abstract string GetDirectoryFromPath(string path); - - public abstract string GetFileFromPath(string path); - - public abstract DateTime GetLastWriteTimeUtc(string path); - - public abstract bool HasCommonRoot(FileLocator other); - - public abstract string ResolveRelativePath(string path); - - internal string MakeRelativePath(FileLocator fileLocator, string path) - { - if (!HasCommonRoot(fileLocator)) - { - return null; - } - - string ourFullPath = GetFullPath(string.Empty) + @"\"; - string otherFullPath = fileLocator.GetFullPath(path); - - return Utilities.MakeRelativePath(otherFullPath, ourFullPath); - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/FileSystemInfo.cs b/src/LibHac.Nand/DiscUtils.Core/FileSystemInfo.cs deleted file mode 100644 index 5a439ad3..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/FileSystemInfo.cs +++ /dev/null @@ -1,90 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System.IO; - -namespace DiscUtils -{ - /// - /// Base class holding information about a file system. - /// - /// - /// File system implementations derive from this class, to provide information about the file system. - /// - public abstract class FileSystemInfo - { - /// - /// Gets a one-line description of the file system. - /// - public abstract string Description { get; } - - /// - /// Gets the name of the file system. - /// - public abstract string Name { get; } - - /// - /// Opens a volume using the file system. - /// - /// The volume to access. - /// A file system instance. - public DiscFileSystem Open(VolumeInfo volume) - { - return Open(volume, null); - } - - /// - /// Opens a stream using the file system. - /// - /// The stream to access. - /// A file system instance. - public DiscFileSystem Open(Stream stream) - { - return Open(stream, null); - } - - /// - /// Opens a volume using the file system. - /// - /// The volume to access. - /// Parameters for the file system. - /// A file system instance. - public abstract DiscFileSystem Open(VolumeInfo volume, FileSystemParameters parameters); - - /// - /// Opens a stream using the file system. - /// - /// The stream to access. - /// Parameters for the file system. - /// A file system instance. - public abstract DiscFileSystem Open(Stream stream, FileSystemParameters parameters); - - /// - /// Gets the name of the file system. - /// - /// The file system name. - public override string ToString() - { - return Name; - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/FileSystemManager.cs b/src/LibHac.Nand/DiscUtils.Core/FileSystemManager.cs deleted file mode 100644 index 573e93a9..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/FileSystemManager.cs +++ /dev/null @@ -1,121 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; -using System.IO; -using System.Reflection; -using DiscUtils.CoreCompat; -using DiscUtils.Vfs; - -namespace DiscUtils -{ - /// - /// FileSystemManager determines which file systems are present on a volume. - /// - /// - /// The static detection methods detect default file systems. To plug in additional - /// file systems, create an instance of this class and call RegisterFileSystems. - /// - public static class FileSystemManager - { - private static readonly List _factories; - - /// - /// Initializes a new instance of the FileSystemManager class. - /// - static FileSystemManager() - { - _factories = new List(); - } - - /// - /// Registers new file systems with an instance of this class. - /// - /// The detector for the new file systems. - public static void RegisterFileSystems(VfsFileSystemFactory factory) - { - _factories.Add(factory); - } - - /// - /// Registers new file systems detected in an assembly. - /// - /// The assembly to inspect. - /// - /// To be detected, the VfsFileSystemFactory instances must be marked with the - /// VfsFileSystemFactoryAttribute> attribute. - /// - public static void RegisterFileSystems(Assembly assembly) - { - _factories.AddRange(DetectFactories(assembly)); - } - - /// - /// Detect which file systems are present on a volume. - /// - /// The volume to inspect. - /// The list of file systems detected. - public static FileSystemInfo[] DetectFileSystems(VolumeInfo volume) - { - using (Stream s = volume.Open()) - { - return DoDetect(s, volume); - } - } - - /// - /// Detect which file systems are present in a stream. - /// - /// The stream to inspect. - /// The list of file systems detected. - public static FileSystemInfo[] DetectFileSystems(Stream stream) - { - return DoDetect(stream, null); - } - - private static IEnumerable DetectFactories(Assembly assembly) - { - foreach (Type type in assembly.GetTypes()) - { - Attribute attrib = ReflectionHelper.GetCustomAttribute(type, typeof(VfsFileSystemFactoryAttribute), false); - if (attrib == null) - continue; - - yield return (VfsFileSystemFactory)Activator.CreateInstance(type); - } - } - - private static FileSystemInfo[] DoDetect(Stream stream, VolumeInfo volume) - { - BufferedStream detectStream = new BufferedStream(stream); - List detected = new List(); - - foreach (VfsFileSystemFactory factory in _factories) - { - detected.AddRange(factory.Detect(detectStream, volume)); - } - - return detected.ToArray(); - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/FileSystemParameters.cs b/src/LibHac.Nand/DiscUtils.Core/FileSystemParameters.cs deleted file mode 100644 index b0daee8f..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/FileSystemParameters.cs +++ /dev/null @@ -1,49 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System.Text; - -namespace DiscUtils -{ - /// - /// Class with generic file system parameters. - /// - /// Note - not all parameters apply to all types of file system. - public sealed class FileSystemParameters - { - /// - /// Gets or sets the character encoding for file names, or null for default. - /// - /// Some file systems, such as FAT, don't specify a particular character set for - /// file names. This parameter determines the character set that will be used for such - /// file systems. - public Encoding FileNameEncoding { get; set; } - - /// - /// Gets or sets the algorithm to convert file system time to UTC. - /// - /// Some file system, such as FAT, don't have a defined way to convert from file system - /// time (local time where the file system is authored) to UTC time. This parameter determines - /// the algorithm to use. - public TimeConverter TimeConverter { get; set; } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/FileTransport.cs b/src/LibHac.Nand/DiscUtils.Core/FileTransport.cs deleted file mode 100644 index d22a5eec..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/FileTransport.cs +++ /dev/null @@ -1,73 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Globalization; -using System.IO; -using DiscUtils.Internal; - -namespace DiscUtils -{ - [VirtualDiskTransport("file")] - internal sealed class FileTransport : VirtualDiskTransport - { - private string _extraInfo; - private string _path; - - public override bool IsRawDisk - { - get { return false; } - } - - public override void Connect(Uri uri, string username, string password) - { - _path = uri.LocalPath; - _extraInfo = uri.Fragment.TrimStart('#'); - - if (!Directory.Exists(Path.GetDirectoryName(_path))) - { - throw new FileNotFoundException( - string.Format(CultureInfo.InvariantCulture, "No such file '{0}'", uri.OriginalString), _path); - } - } - - public override VirtualDisk OpenDisk(FileAccess access) - { - throw new NotSupportedException(); - } - - public override FileLocator GetFileLocator() - { - return new LocalFileLocator(Path.GetDirectoryName(_path) + @"\"); - } - - public override string GetFileName() - { - return Path.GetFileName(_path); - } - - public override string GetExtraInfo() - { - return _extraInfo; - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/FloppyDiskType.cs b/src/LibHac.Nand/DiscUtils.Core/FloppyDiskType.cs deleted file mode 100644 index 708c847e..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/FloppyDiskType.cs +++ /dev/null @@ -1,45 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -namespace DiscUtils -{ - /// - /// The supported Floppy Disk logical formats. - /// - public enum FloppyDiskType - { - /// - /// 720KiB capacity disk. - /// - DoubleDensity = 0, - - /// - /// 1440KiB capacity disk. - /// - HighDensity = 1, - - /// - /// 2880KiB capacity disk. - /// - Extended = 2 - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/GenericDiskAdapterType.cs b/src/LibHac.Nand/DiscUtils.Core/GenericDiskAdapterType.cs deleted file mode 100644 index 7e3b2b4b..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/GenericDiskAdapterType.cs +++ /dev/null @@ -1,40 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -namespace DiscUtils -{ - /// - /// Well known hard disk adaptor types. - /// - public enum GenericDiskAdapterType - { - /// - /// IDE adaptor. - /// - Ide = 0, - - /// - /// SCSI adaptor. - /// - Scsi = 1 - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Geometry.cs b/src/LibHac.Nand/DiscUtils.Core/Geometry.cs deleted file mode 100644 index e23797f9..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Geometry.cs +++ /dev/null @@ -1,477 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Globalization; -using DiscUtils.Streams; - -namespace DiscUtils -{ - /// - /// Class whose instances represent disk geometries. - /// - /// Instances of this class are immutable. - public sealed class Geometry - { - /// - /// Initializes a new instance of the Geometry class. The default 512 bytes per sector is assumed. - /// - /// The number of cylinders of the disk. - /// The number of heads (aka platters) of the disk. - /// The number of sectors per track/cylinder of the disk. - public Geometry(int cylinders, int headsPerCylinder, int sectorsPerTrack) - { - Cylinders = cylinders; - HeadsPerCylinder = headsPerCylinder; - SectorsPerTrack = sectorsPerTrack; - BytesPerSector = 512; - } - - /// - /// Initializes a new instance of the Geometry class. - /// - /// The number of cylinders of the disk. - /// The number of heads (aka platters) of the disk. - /// The number of sectors per track/cylinder of the disk. - /// The number of bytes per sector of the disk. - public Geometry(int cylinders, int headsPerCylinder, int sectorsPerTrack, int bytesPerSector) - { - Cylinders = cylinders; - HeadsPerCylinder = headsPerCylinder; - SectorsPerTrack = sectorsPerTrack; - BytesPerSector = bytesPerSector; - } - - /// - /// Initializes a new instance of the Geometry class. - /// - /// The total capacity of the disk. - /// The number of heads (aka platters) of the disk. - /// The number of sectors per track/cylinder of the disk. - /// The number of bytes per sector of the disk. - public Geometry(long capacity, int headsPerCylinder, int sectorsPerTrack, int bytesPerSector) - { - Cylinders = (int)(capacity / (headsPerCylinder * (long)sectorsPerTrack * bytesPerSector)); - HeadsPerCylinder = headsPerCylinder; - SectorsPerTrack = sectorsPerTrack; - BytesPerSector = bytesPerSector; - } - - /// - /// Gets the number of bytes in each sector. - /// - public int BytesPerSector { get; } - - /// - /// Gets the total capacity of the disk (in bytes). - /// - public long Capacity - { - get { return TotalSectorsLong * BytesPerSector; } - } - - /// - /// Gets the number of cylinders. - /// - public int Cylinders { get; } - - /// - /// Gets the number of heads (aka platters). - /// - public int HeadsPerCylinder { get; } - - /// - /// Gets a value indicating whether the Geometry is representable both by the BIOS and by IDE. - /// - public bool IsBiosAndIdeSafe - { - get { return Cylinders <= 1024 && HeadsPerCylinder <= 16 && SectorsPerTrack <= 63; } - } - - /// - /// Gets a value indicating whether the Geometry is consistent with the values a BIOS can support. - /// - public bool IsBiosSafe - { - get { return Cylinders <= 1024 && HeadsPerCylinder <= 255 && SectorsPerTrack <= 63; } - } - - /// - /// Gets a value indicating whether the Geometry is consistent with the values IDE can represent. - /// - public bool IsIdeSafe - { - get { return Cylinders <= 65536 && HeadsPerCylinder <= 16 && SectorsPerTrack <= 255; } - } - - /// - /// Gets the address of the last sector on the disk. - /// - public ChsAddress LastSector - { - get { return new ChsAddress(Cylinders - 1, HeadsPerCylinder - 1, SectorsPerTrack); } - } - - /// - /// Gets a null geometry, which has 512-byte sectors but zero sectors, tracks or cylinders. - /// - public static Geometry Null - { - get { return new Geometry(0, 0, 0, 512); } - } - - /// - /// Gets the number of sectors per track. - /// - public int SectorsPerTrack { get; } - - /// - /// Gets the total size of the disk (in sectors). - /// - [Obsolete("Use TotalSectorsLong instead, to support very large disks.")] - public int TotalSectors - { - get { return Cylinders * HeadsPerCylinder * SectorsPerTrack; } - } - - /// - /// Gets the total size of the disk (in sectors). - /// - public long TotalSectorsLong - { - get { return Cylinders * (long)HeadsPerCylinder * SectorsPerTrack; } - } - - /// - /// Gets the 'Large' BIOS geometry for a disk, given it's physical geometry. - /// - /// The physical (aka IDE) geometry of the disk. - /// The geometry a BIOS using the 'Large' method for calculating disk geometry will indicate for the disk. - public static Geometry LargeBiosGeometry(Geometry ideGeometry) - { - int cylinders = ideGeometry.Cylinders; - int heads = ideGeometry.HeadsPerCylinder; - int sectors = ideGeometry.SectorsPerTrack; - - while (cylinders > 1024 && heads <= 127) - { - cylinders >>= 1; - heads <<= 1; - } - - return new Geometry(cylinders, heads, sectors); - } - - /// - /// Gets the 'LBA Assisted' BIOS geometry for a disk, given it's capacity. - /// - /// The capacity of the disk. - /// The geometry a BIOS using the 'LBA Assisted' method for calculating disk geometry will indicate for the disk. - public static Geometry LbaAssistedBiosGeometry(long capacity) - { - int heads; - if (capacity <= 504 * Sizes.OneMiB) - { - heads = 16; - } - else if (capacity <= 1008 * Sizes.OneMiB) - { - heads = 32; - } - else if (capacity <= 2016 * Sizes.OneMiB) - { - heads = 64; - } - else if (capacity <= 4032 * Sizes.OneMiB) - { - heads = 128; - } - else - { - heads = 255; - } - - int sectors = 63; - int cylinders = (int)Math.Min(1024, capacity / (sectors * (long)heads * Sizes.Sector)); - return new Geometry(cylinders, heads, sectors, Sizes.Sector); - } - - /// - /// Converts a geometry into one that is BIOS-safe, if not already. - /// - /// The geometry to make BIOS-safe. - /// The capacity of the disk. - /// The new geometry. - /// This method returns the LBA-Assisted geometry if the given geometry isn't BIOS-safe. - public static Geometry MakeBiosSafe(Geometry geometry, long capacity) - { - if (geometry == null) - { - return LbaAssistedBiosGeometry(capacity); - } - if (geometry.IsBiosSafe) - { - return geometry; - } - return LbaAssistedBiosGeometry(capacity); - } - - /// - /// Calculates a sensible disk geometry for a disk capacity using the VHD algorithm (errs under). - /// - /// The desired capacity of the disk. - /// The appropriate disk geometry. - /// The geometry returned tends to produce a disk with less capacity - /// than requested (an exact capacity is not always possible). The geometry returned is the IDE - /// (aka Physical) geometry of the disk, not necessarily the geometry used by the BIOS. - public static Geometry FromCapacity(long capacity) - { - return FromCapacity(capacity, Sizes.Sector); - } - - /// - /// Calculates a sensible disk geometry for a disk capacity using the VHD algorithm (errs under). - /// - /// The desired capacity of the disk. - /// The logical sector size of the disk. - /// The appropriate disk geometry. - /// The geometry returned tends to produce a disk with less capacity - /// than requested (an exact capacity is not always possible). The geometry returned is the IDE - /// (aka Physical) geometry of the disk, not necessarily the geometry used by the BIOS. - public static Geometry FromCapacity(long capacity, int sectorSize) - { - int totalSectors; - int cylinders; - int headsPerCylinder; - int sectorsPerTrack; - - // If more than ~128GB truncate at ~128GB - if (capacity > 65535 * (long)16 * 255 * sectorSize) - { - totalSectors = 65535 * 16 * 255; - } - else - { - totalSectors = (int)(capacity / sectorSize); - } - - // If more than ~32GB, break partition table compatibility. - // Partition table has max 63 sectors per track. Otherwise - // we're looking for a geometry that's valid for both BIOS - // and ATA. - if (totalSectors > 65535 * 16 * 63) - { - sectorsPerTrack = 255; - headsPerCylinder = 16; - } - else - { - sectorsPerTrack = 17; - int cylindersTimesHeads = totalSectors / sectorsPerTrack; - headsPerCylinder = (cylindersTimesHeads + 1023) / 1024; - - if (headsPerCylinder < 4) - { - headsPerCylinder = 4; - } - - // If we need more than 1023 cylinders, or 16 heads, try more sectors per track - if (cylindersTimesHeads >= headsPerCylinder * 1024U || headsPerCylinder > 16) - { - sectorsPerTrack = 31; - headsPerCylinder = 16; - cylindersTimesHeads = totalSectors / sectorsPerTrack; - } - - // We need 63 sectors per track to keep the cylinder count down - if (cylindersTimesHeads >= headsPerCylinder * 1024U) - { - sectorsPerTrack = 63; - headsPerCylinder = 16; - } - } - - cylinders = totalSectors / sectorsPerTrack / headsPerCylinder; - - return new Geometry(cylinders, headsPerCylinder, sectorsPerTrack, sectorSize); - } - - /// - /// Converts a CHS (Cylinder,Head,Sector) address to a LBA (Logical Block Address). - /// - /// The CHS address to convert. - /// The Logical Block Address (in sectors). - public long ToLogicalBlockAddress(ChsAddress chsAddress) - { - return ToLogicalBlockAddress(chsAddress.Cylinder, chsAddress.Head, chsAddress.Sector); - } - - /// - /// Converts a CHS (Cylinder,Head,Sector) address to a LBA (Logical Block Address). - /// - /// The cylinder of the address. - /// The head of the address. - /// The sector of the address. - /// The Logical Block Address (in sectors). - public long ToLogicalBlockAddress(int cylinder, int head, int sector) - { - if (cylinder < 0) - { - throw new ArgumentOutOfRangeException(nameof(cylinder), cylinder, "cylinder number is negative"); - } - - if (head >= HeadsPerCylinder) - { - throw new ArgumentOutOfRangeException(nameof(head), head, "head number is larger than disk geometry"); - } - - if (head < 0) - { - throw new ArgumentOutOfRangeException(nameof(head), head, "head number is negative"); - } - - if (sector > SectorsPerTrack) - { - throw new ArgumentOutOfRangeException(nameof(sector), sector, - "sector number is larger than disk geometry"); - } - - if (sector < 1) - { - throw new ArgumentOutOfRangeException(nameof(sector), sector, - "sector number is less than one (sectors are 1-based)"); - } - - return (cylinder * (long)HeadsPerCylinder + head) * SectorsPerTrack + sector - 1; - } - - /// - /// Converts a LBA (Logical Block Address) to a CHS (Cylinder, Head, Sector) address. - /// - /// The logical block address (in sectors). - /// The address in CHS form. - public ChsAddress ToChsAddress(long logicalBlockAddress) - { - if (logicalBlockAddress < 0) - { - throw new ArgumentOutOfRangeException(nameof(logicalBlockAddress), logicalBlockAddress, - "Logical Block Address is negative"); - } - - int cylinder = (int)(logicalBlockAddress / (HeadsPerCylinder * SectorsPerTrack)); - int temp = (int)(logicalBlockAddress % (HeadsPerCylinder * SectorsPerTrack)); - int head = temp / SectorsPerTrack; - int sector = temp % SectorsPerTrack + 1; - - return new ChsAddress(cylinder, head, sector); - } - - /// - /// Translates an IDE (aka Physical) geometry to a BIOS (aka Logical) geometry. - /// - /// The translation to perform. - /// The translated disk geometry. - public Geometry TranslateToBios(GeometryTranslation translation) - { - return TranslateToBios(0, translation); - } - - /// - /// Translates an IDE (aka Physical) geometry to a BIOS (aka Logical) geometry. - /// - /// The capacity of the disk, required if the geometry is an approximation on the actual disk size. - /// The translation to perform. - /// The translated disk geometry. - public Geometry TranslateToBios(long capacity, GeometryTranslation translation) - { - if (capacity <= 0) - { - capacity = TotalSectorsLong * 512L; - } - - switch (translation) - { - case GeometryTranslation.None: - return this; - - case GeometryTranslation.Auto: - if (IsBiosSafe) - { - return this; - } - return LbaAssistedBiosGeometry(capacity); - - case GeometryTranslation.Lba: - return LbaAssistedBiosGeometry(capacity); - - case GeometryTranslation.Large: - return LargeBiosGeometry(this); - - default: - throw new ArgumentException( - string.Format(CultureInfo.InvariantCulture, "Translation mode '{0}' not yet implemented", - translation), nameof(translation)); - } - } - - /// - /// Determines if this object is equivalent to another. - /// - /// The object to test against. - /// true if the is equivalent, else false. - public override bool Equals(object obj) - { - if (obj == null || obj.GetType() != GetType()) - { - return false; - } - - Geometry other = (Geometry)obj; - - return Cylinders == other.Cylinders && HeadsPerCylinder == other.HeadsPerCylinder - && SectorsPerTrack == other.SectorsPerTrack && BytesPerSector == other.BytesPerSector; - } - - /// - /// Calculates the hash code for this object. - /// - /// The hash code. - public override int GetHashCode() - { - return Cylinders.GetHashCode() ^ HeadsPerCylinder.GetHashCode() - ^ SectorsPerTrack.GetHashCode() ^ BytesPerSector.GetHashCode(); - } - - /// - /// Gets a string representation of this object, in the form (C/H/S). - /// - /// The string representation. - public override string ToString() - { - if (BytesPerSector == 512) - { - return "(" + Cylinders + "/" + HeadsPerCylinder + "/" + SectorsPerTrack + ")"; - } - return "(" + Cylinders + "/" + HeadsPerCylinder + "/" + SectorsPerTrack + ":" + BytesPerSector + ")"; - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/GeometryCalculation.cs b/src/LibHac.Nand/DiscUtils.Core/GeometryCalculation.cs deleted file mode 100644 index 6ce1c0a9..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/GeometryCalculation.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace DiscUtils -{ - /// - /// Delegate for calculating a disk geometry from a capacity. - /// - /// The disk capacity to convert. - /// The appropriate geometry for the disk. - public delegate Geometry GeometryCalculation(long capacity); -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/GeometryTranslation.cs b/src/LibHac.Nand/DiscUtils.Core/GeometryTranslation.cs deleted file mode 100644 index 9b795148..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/GeometryTranslation.cs +++ /dev/null @@ -1,50 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -namespace DiscUtils -{ - /// - /// Enumeration of standard BIOS disk geometry translation methods. - /// - public enum GeometryTranslation - { - /// - /// Apply no translation. - /// - None = 0, - - /// - /// Automatic, based on the physical geometry select the most appropriate translation. - /// - Auto = 1, - - /// - /// LBA assisted translation, based on just the disk capacity. - /// - Lba = 2, - - /// - /// Bit-shifting translation, based on the physical geometry of the disk. - /// - Large = 3 - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/IClusterBasedFileSystem.cs b/src/LibHac.Nand/DiscUtils.Core/IClusterBasedFileSystem.cs deleted file mode 100644 index 71a44279..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/IClusterBasedFileSystem.cs +++ /dev/null @@ -1,81 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using DiscUtils.Streams; - -namespace DiscUtils -{ - /// - /// Base class for all file systems based on a cluster model. - /// - public interface IClusterBasedFileSystem : IFileSystem - { - /// - /// Gets the size (in bytes) of each cluster. - /// - long ClusterSize { get; } - - /// - /// Gets the total number of clusters managed by the file system. - /// - long TotalClusters { get; } - - /// - /// Converts a cluster (index) into an absolute byte position in the underlying stream. - /// - /// The cluster to convert. - /// The corresponding absolute byte position. - long ClusterToOffset(long cluster); - - /// - /// Converts an absolute byte position in the underlying stream to a cluster (index). - /// - /// The byte position to convert. - /// The cluster containing the specified byte. - long OffsetToCluster(long offset); - - /// - /// Converts a file name to the list of clusters occupied by the file's data. - /// - /// The path to inspect. - /// The clusters. - /// Note that in some file systems, small files may not have dedicated - /// clusters. Only dedicated clusters will be returned. - Range[] PathToClusters(string path); - - /// - /// Converts a file name to the extents containing its data. - /// - /// The path to inspect. - /// The file extents, as absolute byte positions in the underlying stream. - /// Use this method with caution - not all file systems will store all bytes - /// directly in extents. Files may be compressed, sparse or encrypted. This method - /// merely indicates where file data is stored, not what's stored. - StreamExtent[] PathToExtents(string path); - - /// - /// Gets an object that can convert between clusters and files. - /// - /// The cluster map. - ClusterMap BuildClusterMap(); - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/IDiagnosticTraceable.cs b/src/LibHac.Nand/DiscUtils.Core/IDiagnosticTraceable.cs deleted file mode 100644 index 3911e8e0..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/IDiagnosticTraceable.cs +++ /dev/null @@ -1,39 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System.IO; - -namespace DiscUtils -{ - /// - /// Interface exposed by objects that can provide a structured trace of their content. - /// - public interface IDiagnosticTraceable - { - /// - /// Writes a diagnostic report about the state of the object to a writer. - /// - /// The writer to send the report to. - /// The prefix to place at the start of each line. - void Dump(TextWriter writer, string linePrefix); - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/IFileSystem.cs b/src/LibHac.Nand/DiscUtils.Core/IFileSystem.cs deleted file mode 100644 index 2a38fd13..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/IFileSystem.cs +++ /dev/null @@ -1,367 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.IO; -using DiscUtils.Streams; - -namespace DiscUtils -{ - /// - /// Common interface for all file systems. - /// - public interface IFileSystem - { - /// - /// Gets a value indicating whether the file system is read-only or read-write. - /// - /// true if the file system is read-write. - bool CanWrite { get; } - - /// - /// Gets a value indicating whether the file system is thread-safe. - /// - bool IsThreadSafe { get; } - - /// - /// Gets the root directory of the file system. - /// - DiscDirectoryInfo Root { get; } - - /// - /// Copies an existing file to a new file. - /// - /// The source file. - /// The destination file. - void CopyFile(string sourceFile, string destinationFile); - - /// - /// Copies an existing file to a new file, allowing overwriting of an existing file. - /// - /// The source file. - /// The destination file. - /// Whether to permit over-writing of an existing file. - void CopyFile(string sourceFile, string destinationFile, bool overwrite); - - /// - /// Creates a directory. - /// - /// The path of the new directory. - void CreateDirectory(string path); - - /// - /// Deletes a directory. - /// - /// The path of the directory to delete. - void DeleteDirectory(string path); - - /// - /// Deletes a directory, optionally with all descendants. - /// - /// The path of the directory to delete. - /// Determines if the all descendants should be deleted. - void DeleteDirectory(string path, bool recursive); - - /// - /// Deletes a file. - /// - /// The path of the file to delete. - void DeleteFile(string path); - - /// - /// Indicates if a directory exists. - /// - /// The path to test. - /// true if the directory exists. - bool DirectoryExists(string path); - - /// - /// Indicates if a file exists. - /// - /// The path to test. - /// true if the file exists. - bool FileExists(string path); - - /// - /// Indicates if a file or directory exists. - /// - /// The path to test. - /// true if the file or directory exists. - bool Exists(string path); - - /// - /// Gets the names of subdirectories in a specified directory. - /// - /// The path to search. - /// Array of directories. - string[] GetDirectories(string path); - - /// - /// Gets the names of subdirectories in a specified directory matching a specified - /// search pattern. - /// - /// The path to search. - /// The search string to match against. - /// Array of directories matching the search pattern. - string[] GetDirectories(string path, string searchPattern); - - /// - /// Gets the names of subdirectories in a specified directory matching a specified - /// search pattern, using a value to determine whether to search subdirectories. - /// - /// The path to search. - /// The search string to match against. - /// Indicates whether to search subdirectories. - /// Array of directories matching the search pattern. - string[] GetDirectories(string path, string searchPattern, SearchOption searchOption); - - /// - /// Gets the names of files in a specified directory. - /// - /// The path to search. - /// Array of files. - string[] GetFiles(string path); - - /// - /// Gets the names of files in a specified directory. - /// - /// The path to search. - /// The search string to match against. - /// Array of files matching the search pattern. - string[] GetFiles(string path, string searchPattern); - - /// - /// Gets the names of files in a specified directory matching a specified - /// search pattern, using a value to determine whether to search subdirectories. - /// - /// The path to search. - /// The search string to match against. - /// Indicates whether to search subdirectories. - /// Array of files matching the search pattern. - string[] GetFiles(string path, string searchPattern, SearchOption searchOption); - - /// - /// Gets the names of all files and subdirectories in a specified directory. - /// - /// The path to search. - /// Array of files and subdirectories matching the search pattern. - string[] GetFileSystemEntries(string path); - - /// - /// Gets the names of files and subdirectories in a specified directory matching a specified - /// search pattern. - /// - /// The path to search. - /// The search string to match against. - /// Array of files and subdirectories matching the search pattern. - string[] GetFileSystemEntries(string path, string searchPattern); - - /// - /// Moves a directory. - /// - /// The directory to move. - /// The target directory name. - void MoveDirectory(string sourceDirectoryName, string destinationDirectoryName); - - /// - /// Moves a file. - /// - /// The file to move. - /// The target file name. - void MoveFile(string sourceName, string destinationName); - - /// - /// Moves a file, allowing an existing file to be overwritten. - /// - /// The file to move. - /// The target file name. - /// Whether to permit a destination file to be overwritten. - void MoveFile(string sourceName, string destinationName, bool overwrite); - - /// - /// Opens the specified file. - /// - /// The full path of the file to open. - /// The file mode for the created stream. - /// The new stream. - SparseStream OpenFile(string path, FileMode mode); - - /// - /// Opens the specified file. - /// - /// The full path of the file to open. - /// The file mode for the created stream. - /// The access permissions for the created stream. - /// The new stream. - SparseStream OpenFile(string path, FileMode mode, FileAccess access); - - /// - /// Gets the attributes of a file or directory. - /// - /// The file or directory to inspect. - /// The attributes of the file or directory. - FileAttributes GetAttributes(string path); - - /// - /// Sets the attributes of a file or directory. - /// - /// The file or directory to change. - /// The new attributes of the file or directory. - void SetAttributes(string path, FileAttributes newValue); - - /// - /// Gets the creation time (in local time) of a file or directory. - /// - /// The path of the file or directory. - /// The creation time. - DateTime GetCreationTime(string path); - - /// - /// Sets the creation time (in local time) of a file or directory. - /// - /// The path of the file or directory. - /// The new time to set. - void SetCreationTime(string path, DateTime newTime); - - /// - /// Gets the creation time (in UTC) of a file or directory. - /// - /// The path of the file or directory. - /// The creation time. - DateTime GetCreationTimeUtc(string path); - - /// - /// Sets the creation time (in UTC) of a file or directory. - /// - /// The path of the file or directory. - /// The new time to set. - void SetCreationTimeUtc(string path, DateTime newTime); - - /// - /// Gets the last access time (in local time) of a file or directory. - /// - /// The path of the file or directory. - /// The last access time. - DateTime GetLastAccessTime(string path); - - /// - /// Sets the last access time (in local time) of a file or directory. - /// - /// The path of the file or directory. - /// The new time to set. - void SetLastAccessTime(string path, DateTime newTime); - - /// - /// Gets the last access time (in UTC) of a file or directory. - /// - /// The path of the file or directory. - /// The last access time. - DateTime GetLastAccessTimeUtc(string path); - - /// - /// Sets the last access time (in UTC) of a file or directory. - /// - /// The path of the file or directory. - /// The new time to set. - void SetLastAccessTimeUtc(string path, DateTime newTime); - - /// - /// Gets the last modification time (in local time) of a file or directory. - /// - /// The path of the file or directory. - /// The last write time. - DateTime GetLastWriteTime(string path); - - /// - /// Sets the last modification time (in local time) of a file or directory. - /// - /// The path of the file or directory. - /// The new time to set. - void SetLastWriteTime(string path, DateTime newTime); - - /// - /// Gets the last modification time (in UTC) of a file or directory. - /// - /// The path of the file or directory. - /// The last write time. - DateTime GetLastWriteTimeUtc(string path); - - /// - /// Sets the last modification time (in UTC) of a file or directory. - /// - /// The path of the file or directory. - /// The new time to set. - void SetLastWriteTimeUtc(string path, DateTime newTime); - - /// - /// Gets the length of a file. - /// - /// The path to the file. - /// The length in bytes. - long GetFileLength(string path); - - /// - /// Gets an object representing a possible file. - /// - /// The file path. - /// The representing object. - /// The file does not need to exist. - DiscFileInfo GetFileInfo(string path); - - /// - /// Gets an object representing a possible directory. - /// - /// The directory path. - /// The representing object. - /// The directory does not need to exist. - DiscDirectoryInfo GetDirectoryInfo(string path); - - /// - /// Gets an object representing a possible file system object (file or directory). - /// - /// The file system path. - /// The representing object. - /// The file system object does not need to exist. - DiscFileSystemInfo GetFileSystemInfo(string path); - - /// - /// Reads the boot code of the file system into a byte array. - /// - /// The boot code, or null if not available. - byte[] ReadBootCode(); - - /// - /// Size of the Filesystem in bytes - /// - long Size { get; } - - /// - /// Used space of the Filesystem in bytes - /// - long UsedSpace { get; } - - /// - /// Available space of the Filesystem in bytes - /// - long AvailableSpace { get; } - } -} diff --git a/src/LibHac.Nand/DiscUtils.Core/IUnixFileSystem.cs b/src/LibHac.Nand/DiscUtils.Core/IUnixFileSystem.cs deleted file mode 100644 index 9106c576..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/IUnixFileSystem.cs +++ /dev/null @@ -1,38 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -namespace DiscUtils -{ - /// - /// Provides the base class for all file systems that support Unix semantics. - /// - public interface IUnixFileSystem : IFileSystem - { - /// - /// Retrieves Unix-specific information about a file or directory. - /// - /// Path to the file or directory. - /// Information about the owner, group, permissions and type of the - /// file or directory. - UnixFileSystemInfo GetUnixFileInfo(string path); - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Internal/Crc32.cs b/src/LibHac.Nand/DiscUtils.Core/Internal/Crc32.cs deleted file mode 100644 index 9a24617b..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Internal/Crc32.cs +++ /dev/null @@ -1,43 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -namespace DiscUtils.Internal -{ - internal abstract class Crc32 - { - protected readonly uint[] Table; - protected uint _value; - - protected Crc32(uint[] table) - { - Table = table; - _value = 0xFFFFFFFF; - } - - public uint Value - { - get { return _value ^ 0xFFFFFFFF; } - } - - public abstract void Process(byte[] buffer, int offset, int count); - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Internal/Crc32Algorithm.cs b/src/LibHac.Nand/DiscUtils.Core/Internal/Crc32Algorithm.cs deleted file mode 100644 index decc6e0e..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Internal/Crc32Algorithm.cs +++ /dev/null @@ -1,47 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -namespace DiscUtils.Internal -{ - internal enum Crc32Algorithm - { - /// - /// Used in Ethernet, PKZIP, BZIP2, Gzip, PNG, etc. (aka CRC32). - /// - Common = 0, - - /// - /// Used in iSCSI, SCTP, Btrfs, Vhdx. (aka CRC32C). - /// - Castagnoli = 1, - - /// - /// Unknown usage. (aka CRC32K). - /// - Koopman = 2, - - /// - /// Used in AIXM. (aka CRC32Q). - /// - Aeronautical = 3 - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Internal/Crc32BigEndian.cs b/src/LibHac.Nand/DiscUtils.Core/Internal/Crc32BigEndian.cs deleted file mode 100644 index 6ffdc00a..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Internal/Crc32BigEndian.cs +++ /dev/null @@ -1,94 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -namespace DiscUtils.Internal -{ - /// - /// Calculates CRC32 of buffers. - /// - internal sealed class Crc32BigEndian : Crc32 - { - private static readonly uint[][] Tables; - - static Crc32BigEndian() - { - Tables = new uint[4][]; - - Tables[(int)Crc32Algorithm.Common] = CalcTable(0x04C11DB7); - Tables[(int)Crc32Algorithm.Castagnoli] = CalcTable(0x1EDC6F41); - Tables[(int)Crc32Algorithm.Koopman] = CalcTable(0x741B8CD7); - Tables[(int)Crc32Algorithm.Aeronautical] = CalcTable(0x814141AB); - } - - public Crc32BigEndian(Crc32Algorithm algorithm) - : base(Tables[(int)algorithm]) {} - - public static uint Compute(Crc32Algorithm algorithm, byte[] buffer, int offset, int count) - { - return Process(Tables[(int)algorithm], 0xFFFFFFFF, buffer, offset, count) ^ 0xFFFFFFFF; - } - - public override void Process(byte[] buffer, int offset, int count) - { - _value = Process(Table, _value, buffer, offset, count); - } - - private static uint[] CalcTable(uint polynomial) - { - uint[] table = new uint[256]; - - for (uint i = 0; i < 256; ++i) - { - uint crc = i << 24; - - for (int j = 8; j > 0; --j) - { - if ((crc & 0x80000000) != 0) - { - crc = (crc << 1) ^ polynomial; - } - else - { - crc <<= 1; - } - } - - table[i] = crc; - } - - return table; - } - - private static uint Process(uint[] table, uint accumulator, byte[] buffer, int offset, int count) - { - uint value = accumulator; - - for (int i = 0; i < count; ++i) - { - byte b = buffer[offset + i]; - value = table[(value >> 24) ^ b] ^ (value << 8); - } - - return value; - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Internal/Crc32LittleEndian.cs b/src/LibHac.Nand/DiscUtils.Core/Internal/Crc32LittleEndian.cs deleted file mode 100644 index b7eb0550..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Internal/Crc32LittleEndian.cs +++ /dev/null @@ -1,98 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -namespace DiscUtils.Internal -{ - /// - /// Calculates CRC32 of buffers. - /// - internal sealed class Crc32LittleEndian : Crc32 - { - private static readonly uint[][] Tables; - - static Crc32LittleEndian() - { - Tables = new uint[4][]; - - Tables[(int)Crc32Algorithm.Common] = CalcTable(0xEDB88320); - Tables[(int)Crc32Algorithm.Castagnoli] = CalcTable(0x82F63B78); - Tables[(int)Crc32Algorithm.Koopman] = CalcTable(0xEB31D82E); - Tables[(int)Crc32Algorithm.Aeronautical] = CalcTable(0xD5828281); - } - - public Crc32LittleEndian(Crc32Algorithm algorithm) - : base(Tables[(int)algorithm]) {} - - public static uint Compute(Crc32Algorithm algorithm, byte[] buffer, int offset, int count) - { - return Process(Tables[(int)algorithm], 0xFFFFFFFF, buffer, offset, count) ^ 0xFFFFFFFF; - } - - public override void Process(byte[] buffer, int offset, int count) - { - _value = Process(Table, _value, buffer, offset, count); - } - - private static uint[] CalcTable(uint polynomial) - { - uint[] table = new uint[256]; - - table[0] = 0; - for (uint i = 0; i <= 255; ++i) - { - uint crc = i; - - for (int j = 8; j > 0; --j) - { - if ((crc & 1) != 0) - { - crc = (crc >> 1) ^ polynomial; - } - else - { - crc >>= 1; - } - } - - table[i] = crc; - } - - return table; - } - - private static uint Process(uint[] table, uint accumulator, byte[] buffer, int offset, int count) - { - uint value = accumulator; - - for (int i = 0; i < count; ++i) - { - byte b = buffer[offset + i]; - - uint temp1 = (value >> 8) & 0x00FFFFFF; - uint temp2 = table[(value ^ b) & 0xFF]; - value = temp1 ^ temp2; - } - - return value; - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Internal/LocalFileLocator.cs b/src/LibHac.Nand/DiscUtils.Core/Internal/LocalFileLocator.cs deleted file mode 100644 index ba19cc3f..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Internal/LocalFileLocator.cs +++ /dev/null @@ -1,108 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.IO; - -namespace DiscUtils.Internal -{ - internal sealed class LocalFileLocator : FileLocator - { - private readonly string _dir; - - public LocalFileLocator(string dir) - { - _dir = dir; - } - - public override bool Exists(string fileName) - { - return File.Exists(Path.Combine(_dir, fileName)); - } - - protected override Stream OpenFile(string fileName, FileMode mode, FileAccess access, FileShare share) - { - return new FileStream(Path.Combine(_dir, fileName), mode, access, share); - } - - public override FileLocator GetRelativeLocator(string path) - { - return new LocalFileLocator(Path.Combine(_dir, path)); - } - - public override string GetFullPath(string path) - { - string combinedPath = Path.Combine(_dir, path); - if (string.IsNullOrEmpty(combinedPath)) - { -#if NETCORE - return Directory.GetCurrentDirectory(); -#else - return Environment.CurrentDirectory; -#endif - } - return Path.GetFullPath(combinedPath); - } - - public override string GetDirectoryFromPath(string path) - { - return Path.GetDirectoryName(path); - } - - public override string GetFileFromPath(string path) - { - return Path.GetFileName(path); - } - - public override DateTime GetLastWriteTimeUtc(string path) - { - return File.GetLastWriteTimeUtc(Path.Combine(_dir, path)); - } - - public override bool HasCommonRoot(FileLocator other) - { - LocalFileLocator otherLocal = other as LocalFileLocator; - if (otherLocal == null) - { - return false; - } - - // If the paths have drive specifiers, then common root depends on them having a common - // drive letter. - string otherDir = otherLocal._dir; - if (otherDir.Length >= 2 && _dir.Length >= 2) - { - if (otherDir[1] == ':' && _dir[1] == ':') - { - return char.ToUpperInvariant(otherDir[0]) == char.ToUpperInvariant(_dir[0]); - } - } - - return true; - } - - public override string ResolveRelativePath(string path) - { - return Utilities.ResolveRelativePath(_dir, path); - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Internal/LogicalVolumeFactory.cs b/src/LibHac.Nand/DiscUtils.Core/Internal/LogicalVolumeFactory.cs deleted file mode 100644 index acfdedc2..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Internal/LogicalVolumeFactory.cs +++ /dev/null @@ -1,33 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System.Collections.Generic; - -namespace DiscUtils.Internal -{ - internal abstract class LogicalVolumeFactory - { - public abstract bool HandlesPhysicalVolume(PhysicalVolumeInfo volume); - - public abstract void MapDisks(IEnumerable disks, Dictionary result); - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Internal/LogicalVolumeFactoryAttribute.cs b/src/LibHac.Nand/DiscUtils.Core/Internal/LogicalVolumeFactoryAttribute.cs deleted file mode 100644 index 59fc39c5..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Internal/LogicalVolumeFactoryAttribute.cs +++ /dev/null @@ -1,29 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; - -namespace DiscUtils.Internal -{ - [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] - internal sealed class LogicalVolumeFactoryAttribute : Attribute {} -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Internal/ObjectCache.cs b/src/LibHac.Nand/DiscUtils.Core/Internal/ObjectCache.cs deleted file mode 100644 index 17e39940..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Internal/ObjectCache.cs +++ /dev/null @@ -1,149 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; - -namespace DiscUtils.Internal -{ - /// - /// Caches objects. - /// - /// The type of the object key. - /// The type of the objects to cache. - /// - /// Can be use for two purposes - to ensure there is only one instance of a given object, - /// and to prevent the need to recreate objects that are expensive to create. - /// - internal class ObjectCache - { - private const int MostRecentListSize = 20; - private const int PruneGap = 500; - - private readonly Dictionary _entries; - private int _nextPruneCount; - private readonly List> _recent; - - public ObjectCache() - { - _entries = new Dictionary(); - _recent = new List>(); - } - - public V this[K key] - { - get - { - for (int i = 0; i < _recent.Count; ++i) - { - KeyValuePair recentEntry = _recent[i]; - if (recentEntry.Key.Equals(key)) - { - MakeMostRecent(i); - return recentEntry.Value; - } - } - - WeakReference wRef; - if (_entries.TryGetValue(key, out wRef)) - { - V val = (V)wRef.Target; - if (val != null) - { - MakeMostRecent(key, val); - } - - return val; - } - - return default(V); - } - - set - { - _entries[key] = new WeakReference(value); - MakeMostRecent(key, value); - PruneEntries(); - } - } - - internal void Remove(K key) - { - for (int i = 0; i < _recent.Count; ++i) - { - if (_recent[i].Key.Equals(key)) - { - _recent.RemoveAt(i); - break; - } - } - - _entries.Remove(key); - } - - private void PruneEntries() - { - _nextPruneCount++; - - if (_nextPruneCount > PruneGap) - { - List toPrune = new List(); - foreach (KeyValuePair entry in _entries) - { - if (!entry.Value.IsAlive) - { - toPrune.Add(entry.Key); - } - } - - foreach (K key in toPrune) - { - _entries.Remove(key); - } - - _nextPruneCount = 0; - } - } - - private void MakeMostRecent(int i) - { - if (i == 0) - { - return; - } - - KeyValuePair entry = _recent[i]; - _recent.RemoveAt(i); - _recent.Insert(0, entry); - } - - private void MakeMostRecent(K key, V val) - { - while (_recent.Count >= MostRecentListSize) - { - _recent.RemoveAt(_recent.Count - 1); - } - - _recent.Insert(0, new KeyValuePair(key, val)); - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Internal/Utilities.cs b/src/LibHac.Nand/DiscUtils.Core/Internal/Utilities.cs deleted file mode 100644 index fe97c3f0..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Internal/Utilities.cs +++ /dev/null @@ -1,467 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; -using System.IO; -using System.Text; -using System.Text.RegularExpressions; - -namespace DiscUtils.Internal -{ - internal static class Utilities - { - /// - /// Converts between two arrays. - /// - /// The type of the elements of the source array. - /// The type of the elements of the destination array. - /// The source array. - /// The function to map from source type to destination type. - /// The resultant array. - public static U[] Map(ICollection source, Func func) - { - U[] result = new U[source.Count]; - int i = 0; - - foreach (T sVal in source) - { - result[i++] = func(sVal); - } - - return result; - } - - /// - /// Converts between two arrays. - /// - /// The type of the elements of the source array. - /// The type of the elements of the destination array. - /// The source array. - /// The function to map from source type to destination type. - /// The resultant array. - public static U[] Map(IEnumerable source, Func func) - { - List result = new List(); - - foreach (T sVal in source) - { - result.Add(func(sVal)); - } - - return result.ToArray(); - } - - /// - /// Filters a collection into a new collection. - /// - /// The type of the new collection. - /// The type of the collection entries. - /// The collection to filter. - /// The predicate to select which entries are carried over. - /// The new collection, containing all entries where the predicate returns true. - public static C Filter(ICollection source, Func predicate) where C : ICollection, new() - { - C result = new C(); - foreach (T val in source) - { - if (predicate(val)) - { - result.Add(val); - } - } - - return result; - } - - /// - /// Indicates if two ranges overlap. - /// - /// The type of the ordinals. - /// The lowest ordinal of the first range (inclusive). - /// The highest ordinal of the first range (exclusive). - /// The lowest ordinal of the second range (inclusive). - /// The highest ordinal of the second range (exclusive). - /// true if the ranges overlap, else false. - public static bool RangesOverlap(T xFirst, T xLast, T yFirst, T yLast) where T : IComparable - { - return !((xLast.CompareTo(yFirst) <= 0) || (xFirst.CompareTo(yLast) >= 0)); - } - - #region Bit Twiddling - - public static bool IsAllZeros(byte[] buffer, int offset, int count) - { - int end = offset + count; - for (int i = offset; i < end; ++i) - { - if (buffer[i] != 0) - { - return false; - } - } - - return true; - } - - public static bool IsPowerOfTwo(uint val) - { - if (val == 0) - { - return false; - } - - while ((val & 1) != 1) - { - val >>= 1; - } - - return val == 1; - } - - public static bool IsPowerOfTwo(long val) - { - if (val == 0) - { - return false; - } - - while ((val & 1) != 1) - { - val >>= 1; - } - - return val == 1; - } - - public static bool AreEqual(byte[] a, byte[] b) - { - if (a.Length != b.Length) - { - return false; - } - - for (int i = 0; i < a.Length; ++i) - { - if (a[i] != b[i]) - { - return false; - } - } - - return true; - } - - public static ushort BitSwap(ushort value) - { - return (ushort)(((value & 0x00FF) << 8) | ((value & 0xFF00) >> 8)); - } - - public static uint BitSwap(uint value) - { - return ((value & 0xFF) << 24) | ((value & 0xFF00) << 8) | ((value & 0x00FF0000) >> 8) | - ((value & 0xFF000000) >> 24); - } - - public static ulong BitSwap(ulong value) - { - return ((ulong)BitSwap((uint)(value & 0xFFFFFFFF)) << 32) | BitSwap((uint)(value >> 32)); - } - - public static short BitSwap(short value) - { - return (short)BitSwap((ushort)value); - } - - public static int BitSwap(int value) - { - return (int)BitSwap((uint)value); - } - - public static long BitSwap(long value) - { - return (long)BitSwap((ulong)value); - } - - #endregion - - #region Path Manipulation - - /// - /// Extracts the directory part of a path. - /// - /// The path to process. - /// The directory part. - public static string GetDirectoryFromPath(string path) - { - string trimmed = path.TrimEnd('\\'); - - int index = trimmed.LastIndexOf('\\'); - if (index < 0) - { - return string.Empty; // No directory, just a file name - } - - return trimmed.Substring(0, index); - } - - /// - /// Extracts the file part of a path. - /// - /// The path to process. - /// The file part of the path. - public static string GetFileFromPath(string path) - { - string trimmed = path.Trim('\\'); - - int index = trimmed.LastIndexOf('\\'); - if (index < 0) - { - return trimmed; // No directory, just a file name - } - - return trimmed.Substring(index + 1); - } - - /// - /// Combines two paths. - /// - /// The first part of the path. - /// The second part of the path. - /// The combined path. - public static string CombinePaths(string a, string b) - { - if (string.IsNullOrEmpty(a) || (b.Length > 0 && b[0] == '\\')) - { - return b; - } - if (string.IsNullOrEmpty(b)) - { - return a; - } - return a.TrimEnd('\\') + '\\' + b.TrimStart('\\'); - } - - /// - /// Resolves a relative path into an absolute one. - /// - /// The base path to resolve from. - /// The relative path. - /// The absolute path. If no is specified - /// then relativePath is returned as-is. If - /// contains more '..' characters than the base path contains levels of - /// directory, the resultant string be the root drive followed by the file name. - /// If no the basePath starts with '\' (no drive specified) then the returned - /// path will also start with '\'. - /// For example: (\TEMP\Foo.txt, ..\..\Bar.txt) gives (\Bar.txt). - /// - public static string ResolveRelativePath(string basePath, string relativePath) - { - if (string.IsNullOrEmpty(basePath)) - { - return relativePath; - } - - if (!basePath.EndsWith(@"\")) - basePath = Path.GetDirectoryName(basePath); - - string merged = Path.GetFullPath(Path.Combine(basePath, relativePath)); - - if (basePath.StartsWith(@"\") && merged.Length > 2 && merged[1].Equals(':')) - { - return merged.Substring(2); - } - - return merged; - } - - public static string ResolvePath(string basePath, string path) - { - if (!path.StartsWith("\\", StringComparison.OrdinalIgnoreCase)) - { - return ResolveRelativePath(basePath, path); - } - return path; - } - - public static string MakeRelativePath(string path, string basePath) - { - List pathElements = - new List(path.Split(new[] { '\\' }, StringSplitOptions.RemoveEmptyEntries)); - List basePathElements = - new List(basePath.Split(new[] { '\\' }, StringSplitOptions.RemoveEmptyEntries)); - - if (!basePath.EndsWith("\\", StringComparison.Ordinal) && basePathElements.Count > 0) - { - basePathElements.RemoveAt(basePathElements.Count - 1); - } - - // Find first part of paths that don't match - int i = 0; - while (i < Math.Min(pathElements.Count - 1, basePathElements.Count)) - { - if (pathElements[i].ToUpperInvariant() != basePathElements[i].ToUpperInvariant()) - { - break; - } - - ++i; - } - - // For each remaining part of the base path, insert '..' - StringBuilder result = new StringBuilder(); - if (i == basePathElements.Count) - { - result.Append(@".\"); - } - else if (i < basePathElements.Count) - { - for (int j = 0; j < basePathElements.Count - i; ++j) - { - result.Append(@"..\"); - } - } - - // For each remaining part of the path, add the path element - for (int j = i; j < pathElements.Count - 1; ++j) - { - result.Append(pathElements[j]); - result.Append(@"\"); - } - - result.Append(pathElements[pathElements.Count - 1]); - - // If the target was a directory, put the terminator back - if (path.EndsWith(@"\", StringComparison.Ordinal)) - { - result.Append(@"\"); - } - - return result.ToString(); - } - - #endregion - - #region Filesystem Support - - /// - /// Indicates if a file name matches the 8.3 pattern. - /// - /// The name to test. - /// true if the name is 8.3, otherwise false. - public static bool Is8Dot3(string name) - { - if (name.Length > 12) - { - return false; - } - - string[] split = name.Split('.'); - - if (split.Length > 2 || split.Length < 1) - { - return false; - } - - if (split[0].Length > 8) - { - return false; - } - - foreach (char ch in split[0]) - { - if (!Is8Dot3Char(ch)) - { - return false; - } - } - - if (split.Length > 1) - { - if (split[1].Length > 3) - { - return false; - } - - foreach (char ch in split[1]) - { - if (!Is8Dot3Char(ch)) - { - return false; - } - } - } - - return true; - } - - public static bool Is8Dot3Char(char ch) - { - return (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9') || "_^$~!#%£-{}()@'`&".IndexOf(ch) != -1; - } - - /// - /// Converts a 'standard' wildcard file/path specification into a regular expression. - /// - /// The wildcard pattern to convert. - /// The resultant regular expression. - /// - /// The wildcard * (star) matches zero or more characters (including '.'), and ? - /// (question mark) matches precisely one character (except '.'). - /// - public static Regex ConvertWildcardsToRegEx(string pattern) - { - if (!pattern.Contains(".")) - { - pattern += "."; - } - - string query = "^" + Regex.Escape(pattern).Replace(@"\*", ".*").Replace(@"\?", "[^.]") + "$"; - return new Regex(query, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant); - } - - public static FileAttributes FileAttributesFromUnixFileType(UnixFileType fileType) - { - switch (fileType) - { - case UnixFileType.Fifo: - return FileAttributes.Device | FileAttributes.System; - case UnixFileType.Character: - return FileAttributes.Device | FileAttributes.System; - case UnixFileType.Directory: - return FileAttributes.Directory; - case UnixFileType.Block: - return FileAttributes.Device | FileAttributes.System; - case UnixFileType.Regular: - return FileAttributes.Normal; - case UnixFileType.Link: - return FileAttributes.ReparsePoint; - case UnixFileType.Socket: - return FileAttributes.Device | FileAttributes.System; - default: - return 0; - } - } - - #endregion - } -} diff --git a/src/LibHac.Nand/DiscUtils.Core/Internal/VirtualDiskFactory.cs b/src/LibHac.Nand/DiscUtils.Core/Internal/VirtualDiskFactory.cs deleted file mode 100644 index 814da9e2..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Internal/VirtualDiskFactory.cs +++ /dev/null @@ -1,56 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System.Collections.Generic; -using System.IO; - -namespace DiscUtils.Internal -{ - internal abstract class VirtualDiskFactory - { - public abstract string[] Variants { get; } - - public abstract VirtualDiskTypeInfo GetDiskTypeInformation(string variant); - - public abstract DiskImageBuilder GetImageBuilder(string variant); - - public abstract VirtualDisk CreateDisk(FileLocator locator, string variant, string path, - VirtualDiskParameters diskParameters); - - public abstract VirtualDisk OpenDisk(string path, FileAccess access); - - public abstract VirtualDisk OpenDisk(FileLocator locator, string path, FileAccess access); - - public virtual VirtualDisk OpenDisk(FileLocator locator, string path, string extraInfo, - Dictionary parameters, FileAccess access) - { - return OpenDisk(locator, path, access); - } - - public VirtualDisk OpenDisk(DiscFileSystem fileSystem, string path, FileAccess access) - { - return OpenDisk(new DiscFileLocator(fileSystem, @"\"), path, access); - } - - public abstract VirtualDiskLayer OpenDiskLayer(FileLocator locator, string path, FileAccess access); - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Internal/VirtualDiskFactoryAttribute.cs b/src/LibHac.Nand/DiscUtils.Core/Internal/VirtualDiskFactoryAttribute.cs deleted file mode 100644 index 3b56b03a..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Internal/VirtualDiskFactoryAttribute.cs +++ /dev/null @@ -1,40 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; - -namespace DiscUtils.Internal -{ - [AttributeUsage(AttributeTargets.Class)] - internal sealed class VirtualDiskFactoryAttribute : Attribute - { - public VirtualDiskFactoryAttribute(string type, string fileExtensions) - { - Type = type; - FileExtensions = fileExtensions.Replace(".", string.Empty).Split(','); - } - - public string[] FileExtensions { get; } - - public string Type { get; } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Internal/VirtualDiskTransport.cs b/src/LibHac.Nand/DiscUtils.Core/Internal/VirtualDiskTransport.cs deleted file mode 100644 index 2ad14275..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Internal/VirtualDiskTransport.cs +++ /dev/null @@ -1,50 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.IO; - -namespace DiscUtils.Internal -{ - internal abstract class VirtualDiskTransport : IDisposable - { - public abstract bool IsRawDisk { get; } - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - public abstract void Connect(Uri uri, string username, string password); - - public abstract VirtualDisk OpenDisk(FileAccess access); - - public abstract FileLocator GetFileLocator(); - - public abstract string GetFileName(); - - public abstract string GetExtraInfo(); - - protected virtual void Dispose(bool disposing) {} - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Internal/VirtualDiskTransportAttribute.cs b/src/LibHac.Nand/DiscUtils.Core/Internal/VirtualDiskTransportAttribute.cs deleted file mode 100644 index d42737df..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Internal/VirtualDiskTransportAttribute.cs +++ /dev/null @@ -1,37 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; - -namespace DiscUtils.Internal -{ - [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] - internal sealed class VirtualDiskTransportAttribute : Attribute - { - public VirtualDiskTransportAttribute(string scheme) - { - Scheme = scheme; - } - - public string Scheme { get; } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/InvalidFileSystemException.cs b/src/LibHac.Nand/DiscUtils.Core/InvalidFileSystemException.cs deleted file mode 100644 index 90b13fa8..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/InvalidFileSystemException.cs +++ /dev/null @@ -1,73 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.IO; - -#if !NETCORE -using System.Runtime.Serialization; -#endif - -namespace DiscUtils -{ - /// - /// Exception thrown when some invalid file system data is found, indicating probably corruption. - /// -#if !NETCORE - [Serializable] -#endif - public class InvalidFileSystemException : IOException - { - /// - /// Initializes a new instance of the InvalidFileSystemException class. - /// - public InvalidFileSystemException() {} - - /// - /// Initializes a new instance of the InvalidFileSystemException class. - /// - /// The exception message. - public InvalidFileSystemException(string message) - : base(message) {} - - /// - /// Initializes a new instance of the InvalidFileSystemException class. - /// - /// The exception message. - /// The inner exception. - public InvalidFileSystemException(string message, Exception innerException) - : base(message, innerException) {} - -#if !NETCORE - -/// -/// Initializes a new instance of the InvalidFileSystemException class. -/// -/// The serialization info. -/// The streaming context. - protected InvalidFileSystemException(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } -#endif - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/LogicalDiskManager/ComponentRecord.cs b/src/LibHac.Nand/DiscUtils.Core/LogicalDiskManager/ComponentRecord.cs deleted file mode 100644 index 99a8e5e3..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/LogicalDiskManager/ComponentRecord.cs +++ /dev/null @@ -1,64 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -namespace DiscUtils.LogicalDiskManager -{ - internal sealed class ComponentRecord : DatabaseRecord - { - public uint LinkId; // Identical on mirrors - public ExtentMergeType MergeType; // (02 Spanned, Simple, Mirrored) (01 on striped) - public ulong NumExtents; // Could be num disks - public string StatusString; - public long StripeSizeSectors; - public long StripeStride; // aka num partitions - public uint Unknown1; // Zero - public uint Unknown2; // Zero - public ulong Unknown3; // 00 .. 00 - public ulong Unknown4; // ?? - public ulong VolumeId; - - protected override void DoReadFrom(byte[] buffer, int offset) - { - base.DoReadFrom(buffer, offset); - - int pos = offset + 0x18; - - Id = ReadVarULong(buffer, ref pos); - Name = ReadVarString(buffer, ref pos); - StatusString = ReadVarString(buffer, ref pos); - MergeType = (ExtentMergeType)ReadByte(buffer, ref pos); - Unknown1 = ReadUInt(buffer, ref pos); // Zero - NumExtents = ReadVarULong(buffer, ref pos); - Unknown2 = ReadUInt(buffer, ref pos); - LinkId = ReadUInt(buffer, ref pos); - Unknown3 = ReadULong(buffer, ref pos); // Zero - VolumeId = ReadVarULong(buffer, ref pos); - Unknown4 = ReadVarULong(buffer, ref pos); // Zero - - if ((Flags & 0x1000) != 0) - { - StripeSizeSectors = ReadVarLong(buffer, ref pos); - StripeStride = ReadVarLong(buffer, ref pos); - } - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/LogicalDiskManager/Database.cs b/src/LibHac.Nand/DiscUtils.Core/LogicalDiskManager/Database.cs deleted file mode 100644 index 51459c26..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/LogicalDiskManager/Database.cs +++ /dev/null @@ -1,178 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; -using System.IO; -using DiscUtils.Streams; - -namespace DiscUtils.LogicalDiskManager -{ - internal class Database - { - private readonly Dictionary _records; - private readonly DatabaseHeader _vmdb; - - public Database(Stream stream) - { - long dbStart = stream.Position; - - byte[] buffer = new byte[Sizes.Sector]; - stream.Read(buffer, 0, buffer.Length); - _vmdb = new DatabaseHeader(); - _vmdb.ReadFrom(buffer, 0); - - stream.Position = dbStart + _vmdb.HeaderSize; - - buffer = StreamUtilities.ReadExact(stream, (int)(_vmdb.BlockSize * _vmdb.NumVBlks)); - - _records = new Dictionary(); - for (int i = 0; i < _vmdb.NumVBlks; ++i) - { - DatabaseRecord rec = DatabaseRecord.ReadFrom(buffer, (int)(i * _vmdb.BlockSize)); - if (rec != null) - { - _records.Add(rec.Id, rec); - } - } - } - - internal IEnumerable Disks - { - get - { - foreach (DatabaseRecord record in _records.Values) - { - if (record.RecordType == RecordType.Disk) - { - yield return (DiskRecord)record; - } - } - } - } - - internal IEnumerable Volumes - { - get - { - foreach (DatabaseRecord record in _records.Values) - { - if (record.RecordType == RecordType.Volume) - { - yield return (VolumeRecord)record; - } - } - } - } - - internal DiskGroupRecord GetDiskGroup(Guid guid) - { - foreach (DatabaseRecord record in _records.Values) - { - if (record.RecordType == RecordType.DiskGroup) - { - DiskGroupRecord dgRecord = (DiskGroupRecord)record; - if (new Guid(dgRecord.GroupGuidString) == guid || guid == Guid.Empty) - { - return dgRecord; - } - } - } - - return null; - } - - internal IEnumerable GetVolumeComponents(ulong volumeId) - { - foreach (DatabaseRecord record in _records.Values) - { - if (record.RecordType == RecordType.Component) - { - ComponentRecord cmpntRecord = (ComponentRecord)record; - if (cmpntRecord.VolumeId == volumeId) - { - yield return cmpntRecord; - } - } - } - } - - internal IEnumerable GetComponentExtents(ulong componentId) - { - foreach (DatabaseRecord record in _records.Values) - { - if (record.RecordType == RecordType.Extent) - { - ExtentRecord extentRecord = (ExtentRecord)record; - if (extentRecord.ComponentId == componentId) - { - yield return extentRecord; - } - } - } - } - - internal DiskRecord GetDisk(ulong diskId) - { - return (DiskRecord)_records[diskId]; - } - - internal VolumeRecord GetVolume(ulong volumeId) - { - return (VolumeRecord)_records[volumeId]; - } - - internal VolumeRecord GetVolume(Guid id) - { - return FindRecord(r => r.VolumeGuid == id, RecordType.Volume); - } - - internal IEnumerable GetVolumes() - { - foreach (DatabaseRecord record in _records.Values) - { - if (record.RecordType == RecordType.Volume) - { - yield return (VolumeRecord)record; - } - } - } - - internal T FindRecord(Predicate pred, RecordType typeId) - where T : DatabaseRecord - { - foreach (DatabaseRecord record in _records.Values) - { - if (record.RecordType == typeId) - { - T t = (T)record; - if (pred(t)) - { - return t; - } - } - } - - return null; - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/LogicalDiskManager/DatabaseHeader.cs b/src/LibHac.Nand/DiscUtils.Core/LogicalDiskManager/DatabaseHeader.cs deleted file mode 100644 index b9782732..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/LogicalDiskManager/DatabaseHeader.cs +++ /dev/null @@ -1,94 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using DiscUtils.Streams; - -namespace DiscUtils.LogicalDiskManager -{ - internal class DatabaseHeader - { - public uint BlockSize; // 00 00 00 80 - public long CommittedSequence; // 0xA - public string DiskGroupId; - public string GroupName; - public uint HeaderSize; // 00 00 02 00 - public uint NumVBlks; // 00 00 17 24 - public long PendingSequence; // 0xA - public string Signature; // VMDB - public DateTime Timestamp; - public ushort Unknown1; // 00 01 - public uint Unknown2; // 1 - public uint Unknown3; // 1 - public uint Unknown4; // 3 - public uint Unknown5; // 3 - public long Unknown6; // 0 - public long Unknown7; // 1 - public uint Unknown8; // 1 - public uint Unknown9; // 3 - public uint UnknownA; // 3 - public long UnknownB; // 0 - public uint UnknownC; // 0 - public ushort VersionDenom; // 00 0a - public ushort VersionNum; // 00 04 - - public void ReadFrom(byte[] buffer, int offset) - { - Signature = EndianUtilities.BytesToString(buffer, offset + 0x00, 4); - NumVBlks = EndianUtilities.ToUInt32BigEndian(buffer, offset + 0x04); - BlockSize = EndianUtilities.ToUInt32BigEndian(buffer, offset + 0x08); - HeaderSize = EndianUtilities.ToUInt32BigEndian(buffer, offset + 0x0C); - Unknown1 = EndianUtilities.ToUInt16BigEndian(buffer, offset + 0x10); - VersionNum = EndianUtilities.ToUInt16BigEndian(buffer, offset + 0x12); - VersionDenom = EndianUtilities.ToUInt16BigEndian(buffer, offset + 0x14); - GroupName = EndianUtilities.BytesToString(buffer, offset + 0x16, 31).Trim('\0'); - DiskGroupId = EndianUtilities.BytesToString(buffer, offset + 0x35, 0x40).Trim('\0'); - - // May be wrong way round... - CommittedSequence = EndianUtilities.ToInt64BigEndian(buffer, offset + 0x75); - PendingSequence = EndianUtilities.ToInt64BigEndian(buffer, offset + 0x7D); - - Unknown2 = EndianUtilities.ToUInt32BigEndian(buffer, offset + 0x85); - Unknown3 = EndianUtilities.ToUInt32BigEndian(buffer, offset + 0x89); - Unknown4 = EndianUtilities.ToUInt32BigEndian(buffer, offset + 0x8D); - Unknown5 = EndianUtilities.ToUInt32BigEndian(buffer, offset + 0x91); - Unknown6 = EndianUtilities.ToInt64BigEndian(buffer, offset + 0x95); - Unknown7 = EndianUtilities.ToInt64BigEndian(buffer, offset + 0x9D); - Unknown8 = EndianUtilities.ToUInt32BigEndian(buffer, offset + 0xA5); - Unknown9 = EndianUtilities.ToUInt32BigEndian(buffer, offset + 0xA9); - UnknownA = EndianUtilities.ToUInt32BigEndian(buffer, offset + 0xAD); - - UnknownB = EndianUtilities.ToInt64BigEndian(buffer, offset + 0xB1); - UnknownC = EndianUtilities.ToUInt32BigEndian(buffer, offset + 0xB9); - - Timestamp = DateTime.FromFileTimeUtc(EndianUtilities.ToInt64BigEndian(buffer, offset + 0xBD)); - } - - ////} - //// throw new NotImplementedException(); - //// // Add all byte values for ?? bytes - //// // Zero checksum bytes (0x08, 4) - ////{ - - ////private static int CalcChecksum() - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/LogicalDiskManager/DatabaseRecord.cs b/src/LibHac.Nand/DiscUtils.Core/LogicalDiskManager/DatabaseRecord.cs deleted file mode 100644 index 017947da..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/LogicalDiskManager/DatabaseRecord.cs +++ /dev/null @@ -1,154 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using DiscUtils.Streams; - -namespace DiscUtils.LogicalDiskManager -{ - internal abstract class DatabaseRecord - { - public uint Counter; - public uint DataLength; - public uint Flags; - - public ulong Id; - public uint Label; - public string Name; - public RecordType RecordType; - public string Signature; // VBLK - public uint Valid; - - public static DatabaseRecord ReadFrom(byte[] buffer, int offset) - { - DatabaseRecord result = null; - - if (EndianUtilities.ToInt32BigEndian(buffer, offset + 0xC) != 0) - { - switch ((RecordType)(buffer[offset + 0x13] & 0xF)) - { - case RecordType.Volume: - result = new VolumeRecord(); - break; - - case RecordType.Component: - result = new ComponentRecord(); - break; - - case RecordType.Extent: - result = new ExtentRecord(); - break; - - case RecordType.Disk: - result = new DiskRecord(); - break; - - case RecordType.DiskGroup: - result = new DiskGroupRecord(); - break; - - default: - throw new NotImplementedException("Unrecognized record type: " + buffer[offset + 0x13]); - } - - result.DoReadFrom(buffer, offset); - } - - return result; - } - - protected static ulong ReadVarULong(byte[] buffer, ref int offset) - { - int length = buffer[offset]; - - ulong result = 0; - for (int i = 0; i < length; ++i) - { - result = (result << 8) | buffer[offset + i + 1]; - } - - offset += length + 1; - - return result; - } - - protected static long ReadVarLong(byte[] buffer, ref int offset) - { - return (long)ReadVarULong(buffer, ref offset); - } - - protected static string ReadVarString(byte[] buffer, ref int offset) - { - int length = buffer[offset]; - - string result = EndianUtilities.BytesToString(buffer, offset + 1, length); - offset += length + 1; - return result; - } - - protected static byte ReadByte(byte[] buffer, ref int offset) - { - return buffer[offset++]; - } - - protected static uint ReadUInt(byte[] buffer, ref int offset) - { - offset += 4; - return EndianUtilities.ToUInt32BigEndian(buffer, offset - 4); - } - - protected static long ReadLong(byte[] buffer, ref int offset) - { - offset += 8; - return EndianUtilities.ToInt64BigEndian(buffer, offset - 8); - } - - protected static ulong ReadULong(byte[] buffer, ref int offset) - { - offset += 8; - return EndianUtilities.ToUInt64BigEndian(buffer, offset - 8); - } - - protected static string ReadString(byte[] buffer, int len, ref int offset) - { - offset += len; - return EndianUtilities.BytesToString(buffer, offset - len, len); - } - - protected static Guid ReadBinaryGuid(byte[] buffer, ref int offset) - { - offset += 16; - return EndianUtilities.ToGuidBigEndian(buffer, offset - 16); - } - - protected virtual void DoReadFrom(byte[] buffer, int offset) - { - Signature = EndianUtilities.BytesToString(buffer, offset + 0x00, 4); - Label = EndianUtilities.ToUInt32BigEndian(buffer, offset + 0x04); - Counter = EndianUtilities.ToUInt32BigEndian(buffer, offset + 0x08); - Valid = EndianUtilities.ToUInt32BigEndian(buffer, offset + 0x0C); - Flags = EndianUtilities.ToUInt32BigEndian(buffer, offset + 0x10); - RecordType = (RecordType)(Flags & 0xF); - DataLength = EndianUtilities.ToUInt32BigEndian(buffer, 0x14); - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/LogicalDiskManager/DiskGroupRecord.cs b/src/LibHac.Nand/DiscUtils.Core/LogicalDiskManager/DiskGroupRecord.cs deleted file mode 100644 index 6742ea2c..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/LogicalDiskManager/DiskGroupRecord.cs +++ /dev/null @@ -1,49 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -namespace DiscUtils.LogicalDiskManager -{ - internal sealed class DiskGroupRecord : DatabaseRecord - { - public string GroupGuidString; - public uint Unknown1; - - protected override void DoReadFrom(byte[] buffer, int offset) - { - base.DoReadFrom(buffer, offset); - - int pos = offset + 0x18; - - Id = ReadVarULong(buffer, ref pos); - Name = ReadVarString(buffer, ref pos); - if ((Flags & 0xF0) == 0x40) - { - GroupGuidString = ReadBinaryGuid(buffer, ref pos).ToString(); - } - else - { - GroupGuidString = ReadVarString(buffer, ref pos); - } - Unknown1 = ReadUInt(buffer, ref pos); - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/LogicalDiskManager/DiskRecord.cs b/src/LibHac.Nand/DiscUtils.Core/LogicalDiskManager/DiskRecord.cs deleted file mode 100644 index b3674a21..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/LogicalDiskManager/DiskRecord.cs +++ /dev/null @@ -1,47 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -namespace DiscUtils.LogicalDiskManager -{ - internal sealed class DiskRecord : DatabaseRecord - { - public string DiskGuidString; - - protected override void DoReadFrom(byte[] buffer, int offset) - { - base.DoReadFrom(buffer, offset); - - int pos = offset + 0x18; - - Id = ReadVarULong(buffer, ref pos); - Name = ReadVarString(buffer, ref pos); - if ((Flags & 0xF0) == 0x40) - { - DiskGuidString = ReadBinaryGuid(buffer, ref pos).ToString(); - } - else - { - DiskGuidString = ReadVarString(buffer, ref pos); - } - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/LogicalDiskManager/DynamicDisk.cs b/src/LibHac.Nand/DiscUtils.Core/LogicalDiskManager/DynamicDisk.cs deleted file mode 100644 index a6f453a8..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/LogicalDiskManager/DynamicDisk.cs +++ /dev/null @@ -1,144 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.IO; -using DiscUtils.Partitions; -using DiscUtils.Streams; - -namespace DiscUtils.LogicalDiskManager -{ - internal class DynamicDisk : IDiagnosticTraceable - { - private readonly VirtualDisk _disk; - private readonly PrivateHeader _header; - - internal DynamicDisk(VirtualDisk disk) - { - _disk = disk; - _header = GetPrivateHeader(_disk); - - TocBlock toc = GetTableOfContents(); - - long dbStart = _header.ConfigurationStartLba * 512 + toc.Item1Start * 512; - _disk.Content.Position = dbStart; - Database = new Database(_disk.Content); - } - - public SparseStream Content - { - get { return _disk.Content; } - } - - public Database Database { get; } - - public long DataOffset - { - get { return _header.DataStartLba; } - } - - public Guid GroupId - { - get { return string.IsNullOrEmpty(_header.DiskGroupId) ? Guid.Empty : new Guid(_header.DiskGroupId); } - } - - public Guid Id - { - get { return new Guid(_header.DiskId); } - } - - public void Dump(TextWriter writer, string linePrefix) - { - writer.WriteLine(linePrefix + "DISK (" + _header.DiskId + ")"); - writer.WriteLine(linePrefix + " Metadata Version: " + ((_header.Version >> 16) & 0xFFFF) + "." + - (_header.Version & 0xFFFF)); - writer.WriteLine(linePrefix + " Timestamp: " + _header.Timestamp); - writer.WriteLine(linePrefix + " Disk Id: " + _header.DiskId); - writer.WriteLine(linePrefix + " Host Id: " + _header.HostId); - writer.WriteLine(linePrefix + " Disk Group Id: " + _header.DiskGroupId); - writer.WriteLine(linePrefix + " Disk Group Name: " + _header.DiskGroupName); - writer.WriteLine(linePrefix + " Data Start: " + _header.DataStartLba + " (Sectors)"); - writer.WriteLine(linePrefix + " Data Size: " + _header.DataSizeLba + " (Sectors)"); - writer.WriteLine(linePrefix + " Configuration Start: " + _header.ConfigurationStartLba + " (Sectors)"); - writer.WriteLine(linePrefix + " Configuration Size: " + _header.ConfigurationSizeLba + " (Sectors)"); - writer.WriteLine(linePrefix + " TOC Size: " + _header.TocSizeLba + " (Sectors)"); - writer.WriteLine(linePrefix + " Next TOC: " + _header.NextTocLba + " (Sectors)"); - writer.WriteLine(linePrefix + " Number of Configs: " + _header.NumberOfConfigs); - writer.WriteLine(linePrefix + " Config Size: " + _header.ConfigurationSizeLba + " (Sectors)"); - writer.WriteLine(linePrefix + " Number of Logs: " + _header.NumberOfLogs); - writer.WriteLine(linePrefix + " Log Size: " + _header.LogSizeLba + " (Sectors)"); - } - - internal static PrivateHeader GetPrivateHeader(VirtualDisk disk) - { - if (disk.IsPartitioned) - { - long headerPos = 0; - PartitionTable pt = disk.Partitions; - if (pt is BiosPartitionTable) - { - headerPos = 0xc00; - } - else - { - foreach (PartitionInfo part in pt.Partitions) - { - if (part.GuidType == GuidPartitionTypes.WindowsLdmMetadata) - { - headerPos = part.LastSector * Sizes.Sector; - } - } - } - - if (headerPos != 0) - { - disk.Content.Position = headerPos; - byte[] buffer = new byte[Sizes.Sector]; - disk.Content.Read(buffer, 0, buffer.Length); - - PrivateHeader hdr = new PrivateHeader(); - hdr.ReadFrom(buffer, 0); - return hdr; - } - } - - return null; - } - - private TocBlock GetTableOfContents() - { - byte[] buffer = new byte[_header.TocSizeLba * 512]; - _disk.Content.Position = _header.ConfigurationStartLba * 512 + 1 * _header.TocSizeLba * 512; - - _disk.Content.Read(buffer, 0, buffer.Length); - TocBlock tocBlock = new TocBlock(); - tocBlock.ReadFrom(buffer, 0); - - if (tocBlock.Signature == "TOCBLOCK") - { - return tocBlock; - } - - return null; - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/LogicalDiskManager/DynamicDiskGroup.cs b/src/LibHac.Nand/DiscUtils.Core/LogicalDiskManager/DynamicDiskGroup.cs deleted file mode 100644 index 725714bd..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/LogicalDiskManager/DynamicDiskGroup.cs +++ /dev/null @@ -1,322 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; -using System.Globalization; -using System.IO; -using DiscUtils.Partitions; -using DiscUtils.Streams; - -namespace DiscUtils.LogicalDiskManager -{ - internal class DynamicDiskGroup : IDiagnosticTraceable - { - private readonly Database _database; - private readonly Dictionary _disks; - private readonly DiskGroupRecord _record; - - internal DynamicDiskGroup(VirtualDisk disk) - { - _disks = new Dictionary(); - - DynamicDisk dynDisk = new DynamicDisk(disk); - _database = dynDisk.Database; - _disks.Add(dynDisk.Id, dynDisk); - _record = dynDisk.Database.GetDiskGroup(dynDisk.GroupId); - } - - #region IDiagnosticTraceable Members - - public void Dump(TextWriter writer, string linePrefix) - { - writer.WriteLine(linePrefix + "DISK GROUP (" + _record.Name + ")"); - writer.WriteLine(linePrefix + " Name: " + _record.Name); - writer.WriteLine(linePrefix + " Flags: 0x" + - (_record.Flags & 0xFFF0).ToString("X4", CultureInfo.InvariantCulture)); - writer.WriteLine(linePrefix + " Database Id: " + _record.Id); - writer.WriteLine(linePrefix + " Guid: " + _record.GroupGuidString); - writer.WriteLine(); - - writer.WriteLine(linePrefix + " DISKS"); - foreach (DiskRecord disk in _database.Disks) - { - writer.WriteLine(linePrefix + " DISK (" + disk.Name + ")"); - writer.WriteLine(linePrefix + " Name: " + disk.Name); - writer.WriteLine(linePrefix + " Flags: 0x" + - (disk.Flags & 0xFFF0).ToString("X4", CultureInfo.InvariantCulture)); - writer.WriteLine(linePrefix + " Database Id: " + disk.Id); - writer.WriteLine(linePrefix + " Guid: " + disk.DiskGuidString); - - DynamicDisk dynDisk; - if (_disks.TryGetValue(new Guid(disk.DiskGuidString), out dynDisk)) - { - writer.WriteLine(linePrefix + " PRIVATE HEADER"); - dynDisk.Dump(writer, linePrefix + " "); - } - } - - writer.WriteLine(linePrefix + " VOLUMES"); - foreach (VolumeRecord vol in _database.Volumes) - { - writer.WriteLine(linePrefix + " VOLUME (" + vol.Name + ")"); - writer.WriteLine(linePrefix + " Name: " + vol.Name); - writer.WriteLine(linePrefix + " BIOS Type: " + - vol.BiosType.ToString("X2", CultureInfo.InvariantCulture) + " [" + - BiosPartitionTypes.ToString(vol.BiosType) + "]"); - writer.WriteLine(linePrefix + " Flags: 0x" + - (vol.Flags & 0xFFF0).ToString("X4", CultureInfo.InvariantCulture)); - writer.WriteLine(linePrefix + " Database Id: " + vol.Id); - writer.WriteLine(linePrefix + " Guid: " + vol.VolumeGuid); - writer.WriteLine(linePrefix + " State: " + vol.ActiveString); - writer.WriteLine(linePrefix + " Drive Hint: " + vol.MountHint); - writer.WriteLine(linePrefix + " Num Components: " + vol.ComponentCount); - writer.WriteLine(linePrefix + " Link Id: " + vol.PartitionComponentLink); - - writer.WriteLine(linePrefix + " COMPONENTS"); - foreach (ComponentRecord cmpnt in _database.GetVolumeComponents(vol.Id)) - { - writer.WriteLine(linePrefix + " COMPONENT (" + cmpnt.Name + ")"); - writer.WriteLine(linePrefix + " Name: " + cmpnt.Name); - writer.WriteLine(linePrefix + " Flags: 0x" + - (cmpnt.Flags & 0xFFF0).ToString("X4", CultureInfo.InvariantCulture)); - writer.WriteLine(linePrefix + " Database Id: " + cmpnt.Id); - writer.WriteLine(linePrefix + " State: " + cmpnt.StatusString); - writer.WriteLine(linePrefix + " Mode: " + cmpnt.MergeType); - writer.WriteLine(linePrefix + " Num Extents: " + cmpnt.NumExtents); - writer.WriteLine(linePrefix + " Link Id: " + cmpnt.LinkId); - writer.WriteLine(linePrefix + " Stripe Size: " + cmpnt.StripeSizeSectors + " (Sectors)"); - writer.WriteLine(linePrefix + " Stripe Stride: " + cmpnt.StripeStride); - - writer.WriteLine(linePrefix + " EXTENTS"); - foreach (ExtentRecord extent in _database.GetComponentExtents(cmpnt.Id)) - { - writer.WriteLine(linePrefix + " EXTENT (" + extent.Name + ")"); - writer.WriteLine(linePrefix + " Name: " + extent.Name); - writer.WriteLine(linePrefix + " Flags: 0x" + - (extent.Flags & 0xFFF0).ToString("X4", CultureInfo.InvariantCulture)); - writer.WriteLine(linePrefix + " Database Id: " + extent.Id); - writer.WriteLine(linePrefix + " Disk Offset: " + extent.DiskOffsetLba + - " (Sectors)"); - writer.WriteLine(linePrefix + " Volume Offset: " + extent.OffsetInVolumeLba + - " (Sectors)"); - writer.WriteLine(linePrefix + " Size: " + extent.SizeLba + " (Sectors)"); - writer.WriteLine(linePrefix + " Component Id: " + extent.ComponentId); - writer.WriteLine(linePrefix + " Disk Id: " + extent.DiskId); - writer.WriteLine(linePrefix + " Link Id: " + extent.PartitionComponentLink); - writer.WriteLine(linePrefix + " Interleave Order: " + extent.InterleaveOrder); - } - } - } - } - - #endregion - - public void Add(VirtualDisk disk) - { - DynamicDisk dynDisk = new DynamicDisk(disk); - _disks.Add(dynDisk.Id, dynDisk); - } - - internal DynamicVolume[] GetVolumes() - { - List vols = new List(); - foreach (VolumeRecord record in _database.GetVolumes()) - { - vols.Add(new DynamicVolume(this, record.VolumeGuid)); - } - - return vols.ToArray(); - } - - internal VolumeRecord GetVolume(Guid volume) - { - return _database.GetVolume(volume); - } - - internal LogicalVolumeStatus GetVolumeStatus(ulong volumeId) - { - return GetVolumeStatus(_database.GetVolume(volumeId)); - } - - internal SparseStream OpenVolume(ulong volumeId) - { - return OpenVolume(_database.GetVolume(volumeId)); - } - - private static int CompareExtentOffsets(ExtentRecord x, ExtentRecord y) - { - if (x.OffsetInVolumeLba > y.OffsetInVolumeLba) - { - return 1; - } - if (x.OffsetInVolumeLba < y.OffsetInVolumeLba) - { - return -1; - } - - return 0; - } - - private static int CompareExtentInterleaveOrder(ExtentRecord x, ExtentRecord y) - { - if (x.InterleaveOrder > y.InterleaveOrder) - { - return 1; - } - if (x.InterleaveOrder < y.InterleaveOrder) - { - return -1; - } - - return 0; - } - - private static LogicalVolumeStatus WorstOf(LogicalVolumeStatus x, LogicalVolumeStatus y) - { - return (LogicalVolumeStatus)Math.Max((int)x, (int)y); - } - - private LogicalVolumeStatus GetVolumeStatus(VolumeRecord volume) - { - int numFailed = 0; - ulong numOK = 0; - LogicalVolumeStatus worst = LogicalVolumeStatus.Healthy; - foreach (ComponentRecord cmpnt in _database.GetVolumeComponents(volume.Id)) - { - LogicalVolumeStatus cmpntStatus = GetComponentStatus(cmpnt); - worst = WorstOf(worst, cmpntStatus); - if (cmpntStatus == LogicalVolumeStatus.Failed) - { - numFailed++; - } - else - { - numOK++; - } - } - - if (numOK < 1) - { - return LogicalVolumeStatus.Failed; - } - if (numOK == volume.ComponentCount) - { - return worst; - } - return LogicalVolumeStatus.FailedRedundancy; - } - - private LogicalVolumeStatus GetComponentStatus(ComponentRecord cmpnt) - { - // NOTE: no support for RAID, so either valid or failed... - LogicalVolumeStatus status = LogicalVolumeStatus.Healthy; - - foreach (ExtentRecord extent in _database.GetComponentExtents(cmpnt.Id)) - { - DiskRecord disk = _database.GetDisk(extent.DiskId); - if (!_disks.ContainsKey(new Guid(disk.DiskGuidString))) - { - status = LogicalVolumeStatus.Failed; - break; - } - } - - return status; - } - - private SparseStream OpenExtent(ExtentRecord extent) - { - DiskRecord disk = _database.GetDisk(extent.DiskId); - - DynamicDisk diskObj = _disks[new Guid(disk.DiskGuidString)]; - - return new SubStream(diskObj.Content, Ownership.None, - (diskObj.DataOffset + extent.DiskOffsetLba) * Sizes.Sector, extent.SizeLba * Sizes.Sector); - } - - private SparseStream OpenComponent(ComponentRecord component) - { - if (component.MergeType == ExtentMergeType.Concatenated) - { - List extents = new List(_database.GetComponentExtents(component.Id)); - extents.Sort(CompareExtentOffsets); - - // Sanity Check... - long pos = 0; - foreach (ExtentRecord extent in extents) - { - if (extent.OffsetInVolumeLba != pos) - { - throw new IOException("Volume extents are non-contiguous"); - } - - pos += extent.SizeLba; - } - - List streams = new List(); - foreach (ExtentRecord extent in extents) - { - streams.Add(OpenExtent(extent)); - } - - return new ConcatStream(Ownership.Dispose, streams.ToArray()); - } - if (component.MergeType == ExtentMergeType.Interleaved) - { - List extents = new List(_database.GetComponentExtents(component.Id)); - extents.Sort(CompareExtentInterleaveOrder); - - List streams = new List(); - foreach (ExtentRecord extent in extents) - { - streams.Add(OpenExtent(extent)); - } - - return new StripedStream(component.StripeSizeSectors * Sizes.Sector, Ownership.Dispose, streams.ToArray()); - } - throw new NotImplementedException("Unknown component mode: " + component.MergeType); - } - - private SparseStream OpenVolume(VolumeRecord volume) - { - List cmpntStreams = new List(); - foreach (ComponentRecord component in _database.GetVolumeComponents(volume.Id)) - { - if (GetComponentStatus(component) == LogicalVolumeStatus.Healthy) - { - cmpntStreams.Add(OpenComponent(component)); - } - } - - if (cmpntStreams.Count < 1) - { - throw new IOException("Volume with no associated or healthy components"); - } - if (cmpntStreams.Count == 1) - { - return cmpntStreams[0]; - } - return new MirrorStream(Ownership.Dispose, cmpntStreams.ToArray()); - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/LogicalDiskManager/DynamicDiskManager.cs b/src/LibHac.Nand/DiscUtils.Core/LogicalDiskManager/DynamicDiskManager.cs deleted file mode 100644 index d2828eb1..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/LogicalDiskManager/DynamicDiskManager.cs +++ /dev/null @@ -1,153 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System.Collections.Generic; -using System.IO; -using DiscUtils.Partitions; - -namespace DiscUtils.LogicalDiskManager -{ - /// - /// A class that understands Windows LDM structures, mapping physical volumes to logical volumes. - /// - public class DynamicDiskManager : IDiagnosticTraceable - { - private readonly Dictionary _groups; - - /// - /// Initializes a new instance of the DynamicDiskManager class. - /// - /// The initial set of disks to manage. - public DynamicDiskManager(params VirtualDisk[] disks) - { - _groups = new Dictionary(); - - foreach (VirtualDisk disk in disks) - { - Add(disk); - } - } - - /// - /// Writes a diagnostic report about the state of the disk manager. - /// - /// The writer to send the report to. - /// The prefix to place at the start of each line. - public void Dump(TextWriter writer, string linePrefix) - { - writer.WriteLine(linePrefix + "DISK GROUPS"); - foreach (DynamicDiskGroup group in _groups.Values) - { - group.Dump(writer, linePrefix + " "); - } - } - - /// - /// Determines if a physical volume contains LDM data. - /// - /// The volume to inspect. - /// true if the physical volume contains LDM data, else false. - public static bool HandlesPhysicalVolume(PhysicalVolumeInfo volumeInfo) - { - PartitionInfo pi = volumeInfo.Partition; - if (pi != null) - { - return IsLdmPartition(pi); - } - - return false; - } - - /// - /// Determines if a disk is 'dynamic' (i.e. contains LDM volumes). - /// - /// The disk to inspect. - /// true if the disk contains LDM volumes, else false. - public static bool IsDynamicDisk(VirtualDisk disk) - { - if (disk.IsPartitioned) - { - foreach (PartitionInfo partition in disk.Partitions.Partitions) - { - if (IsLdmPartition(partition)) - { - return true; - } - } - } - - return false; - } - - /// - /// Adds a new disk to be managed. - /// - /// The disk to manage. - public void Add(VirtualDisk disk) - { - PrivateHeader header = DynamicDisk.GetPrivateHeader(disk); - - DynamicDiskGroup group; - if (_groups.TryGetValue(header.DiskGroupId, out group)) - { - group.Add(disk); - } - else - { - group = new DynamicDiskGroup(disk); - _groups.Add(header.DiskGroupId, group); - } - } - - /// - /// Gets the logical volumes held across the set of managed disks. - /// - /// An array of logical volumes. - public LogicalVolumeInfo[] GetLogicalVolumes() - { - List result = new List(); - foreach (DynamicDiskGroup group in _groups.Values) - { - foreach (DynamicVolume volume in group.GetVolumes()) - { - LogicalVolumeInfo lvi = new LogicalVolumeInfo( - volume.Identity, - null, - volume.Open, - volume.Length, - volume.BiosType, - volume.Status); - result.Add(lvi); - } - } - - return result.ToArray(); - } - - private static bool IsLdmPartition(PartitionInfo partition) - { - return partition.BiosType == BiosPartitionTypes.WindowsDynamicVolume - || partition.GuidType == GuidPartitionTypes.WindowsLdmMetadata - || partition.GuidType == GuidPartitionTypes.WindowsLdmData; - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/LogicalDiskManager/DynamicDiskManagerFactory.cs b/src/LibHac.Nand/DiscUtils.Core/LogicalDiskManager/DynamicDiskManagerFactory.cs deleted file mode 100644 index ed9afa29..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/LogicalDiskManager/DynamicDiskManagerFactory.cs +++ /dev/null @@ -1,54 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System.Collections.Generic; -using DiscUtils.Internal; - -namespace DiscUtils.LogicalDiskManager -{ - [LogicalVolumeFactory] - internal class DynamicDiskManagerFactory : LogicalVolumeFactory - { - public override bool HandlesPhysicalVolume(PhysicalVolumeInfo volume) - { - return DynamicDiskManager.HandlesPhysicalVolume(volume); - } - - public override void MapDisks(IEnumerable disks, Dictionary result) - { - DynamicDiskManager mgr = new DynamicDiskManager(); - - foreach (VirtualDisk disk in disks) - { - if (DynamicDiskManager.IsDynamicDisk(disk)) - { - mgr.Add(disk); - } - } - - foreach (LogicalVolumeInfo vol in mgr.GetLogicalVolumes()) - { - result.Add(vol.Identity, vol); - } - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/LogicalDiskManager/DynamicVolume.cs b/src/LibHac.Nand/DiscUtils.Core/LogicalDiskManager/DynamicVolume.cs deleted file mode 100644 index 146c67ff..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/LogicalDiskManager/DynamicVolume.cs +++ /dev/null @@ -1,70 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.IO; -using DiscUtils.Streams; - -namespace DiscUtils.LogicalDiskManager -{ - internal class DynamicVolume - { - private readonly DynamicDiskGroup _group; - - internal DynamicVolume(DynamicDiskGroup group, Guid volumeId) - { - _group = group; - Identity = volumeId; - } - - public byte BiosType - { - get { return Record.BiosType; } - } - - public Guid Identity { get; } - - public long Length - { - get { return Record.Size * Sizes.Sector; } - } - - private VolumeRecord Record - { - get { return _group.GetVolume(Identity); } - } - - public LogicalVolumeStatus Status - { - get { return _group.GetVolumeStatus(Record.Id); } - } - - public SparseStream Open() - { - if (Status == LogicalVolumeStatus.Failed) - { - throw new IOException("Attempt to open 'failed' volume"); - } - return _group.OpenVolume(Record.Id); - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/LogicalDiskManager/ExtentMergeType.cs b/src/LibHac.Nand/DiscUtils.Core/LogicalDiskManager/ExtentMergeType.cs deleted file mode 100644 index f10d9832..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/LogicalDiskManager/ExtentMergeType.cs +++ /dev/null @@ -1,31 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -namespace DiscUtils.LogicalDiskManager -{ - internal enum ExtentMergeType : byte - { - None = 0, - Interleaved = 1, - Concatenated = 2 - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/LogicalDiskManager/ExtentRecord.cs b/src/LibHac.Nand/DiscUtils.Core/LogicalDiskManager/ExtentRecord.cs deleted file mode 100644 index b612c3a4..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/LogicalDiskManager/ExtentRecord.cs +++ /dev/null @@ -1,60 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -namespace DiscUtils.LogicalDiskManager -{ - internal sealed class ExtentRecord : DatabaseRecord - { - public ulong ComponentId; - public ulong DiskId; - public long DiskOffsetLba; - public ulong InterleaveOrder; - public long OffsetInVolumeLba; - public uint PartitionComponentLink; - public long SizeLba; - public uint Unknown1; - public uint Unknown2; - - protected override void DoReadFrom(byte[] buffer, int offset) - { - base.DoReadFrom(buffer, offset); - - int pos = offset + 0x18; - - Id = ReadVarULong(buffer, ref pos); - Name = ReadVarString(buffer, ref pos); - Unknown1 = ReadUInt(buffer, ref pos); - Unknown2 = ReadUInt(buffer, ref pos); - PartitionComponentLink = ReadUInt(buffer, ref pos); - DiskOffsetLba = ReadLong(buffer, ref pos); - OffsetInVolumeLba = ReadLong(buffer, ref pos); - SizeLba = ReadVarLong(buffer, ref pos); - ComponentId = ReadVarULong(buffer, ref pos); - DiskId = ReadVarULong(buffer, ref pos); - - if ((Flags & 0x0800) != 0) - { - InterleaveOrder = ReadVarULong(buffer, ref pos); - } - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/LogicalDiskManager/PrivateHeader.cs b/src/LibHac.Nand/DiscUtils.Core/LogicalDiskManager/PrivateHeader.cs deleted file mode 100644 index fa6f3758..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/LogicalDiskManager/PrivateHeader.cs +++ /dev/null @@ -1,90 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using DiscUtils.Streams; - -namespace DiscUtils.LogicalDiskManager -{ - internal class PrivateHeader - { - public uint Checksum; // 00 00 2f 96 - public long ConfigSizeLba; - public long ConfigurationSizeLba; // 08 00 - public long ConfigurationStartLba; // 03 FF F8 00 - public long DataSizeLba; // 03 FF F7 C1 - public long DataStartLba; // 3F - public string DiskGroupId; // GUID string - public string DiskGroupName; // MAX_COMPUTER_NAME_LENGTH? - public string DiskId; // GUID string - public string HostId; // GUID string - public long LogSizeLba; - public long NextTocLba; - public long NumberOfConfigs; - public long NumberOfLogs; - public string Signature; // PRIVHEAD - public DateTime Timestamp; - public long TocSizeLba; - public long Unknown2; // Active TOC? 00 .. 00 01 - public long Unknown3; // 00 .. 07 ff // 1 sector less than 2MB - public long Unknown4; // 00 .. 07 40 - public uint Unknown5; // Sector Size? - public uint Version; // 2.12 - - public void ReadFrom(byte[] buffer, int offset) - { - Signature = EndianUtilities.BytesToString(buffer, offset + 0x00, 8); - Checksum = EndianUtilities.ToUInt32BigEndian(buffer, offset + 0x08); - Version = EndianUtilities.ToUInt32BigEndian(buffer, offset + 0x0C); - Timestamp = DateTime.FromFileTimeUtc(EndianUtilities.ToInt64BigEndian(buffer, offset + 0x10)); - Unknown2 = EndianUtilities.ToInt64BigEndian(buffer, offset + 0x18); - Unknown3 = EndianUtilities.ToInt64BigEndian(buffer, offset + 0x20); - Unknown4 = EndianUtilities.ToInt64BigEndian(buffer, offset + 0x28); - DiskId = EndianUtilities.BytesToString(buffer, offset + 0x30, 0x40).Trim('\0'); - HostId = EndianUtilities.BytesToString(buffer, offset + 0x70, 0x40).Trim('\0'); - DiskGroupId = EndianUtilities.BytesToString(buffer, offset + 0xB0, 0x40).Trim('\0'); - DiskGroupName = EndianUtilities.BytesToString(buffer, offset + 0xF0, 31).Trim('\0'); - Unknown5 = EndianUtilities.ToUInt32BigEndian(buffer, offset + 0x10F); - DataStartLba = EndianUtilities.ToInt64BigEndian(buffer, offset + 0x11B); - DataSizeLba = EndianUtilities.ToInt64BigEndian(buffer, offset + 0x123); - ConfigurationStartLba = EndianUtilities.ToInt64BigEndian(buffer, offset + 0x12B); - ConfigurationSizeLba = EndianUtilities.ToInt64BigEndian(buffer, offset + 0x133); - TocSizeLba = EndianUtilities.ToInt64BigEndian(buffer, offset + 0x13B); - NextTocLba = EndianUtilities.ToInt64BigEndian(buffer, offset + 0x143); - - // These two may be reversed - NumberOfConfigs = EndianUtilities.ToInt32BigEndian(buffer, offset + 0x14B); - NumberOfLogs = EndianUtilities.ToInt32BigEndian(buffer, offset + 0x14F); - - ConfigSizeLba = EndianUtilities.ToInt64BigEndian(buffer, offset + 0x153); - LogSizeLba = EndianUtilities.ToInt64BigEndian(buffer, offset + 0x15B); - } - - ////} - //// throw new NotImplementedException(); - //// // Add all byte values for 512 bytes - //// // Zero checksum bytes (0x08, 4) - ////{ - - ////private static int CalcChecksum() - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/LogicalDiskManager/RecordType.cs b/src/LibHac.Nand/DiscUtils.Core/LogicalDiskManager/RecordType.cs deleted file mode 100644 index b8d66cf8..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/LogicalDiskManager/RecordType.cs +++ /dev/null @@ -1,34 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -namespace DiscUtils.LogicalDiskManager -{ - internal enum RecordType : byte - { - None = 0, - Volume = 1, - Component = 2, - Extent = 3, - Disk = 4, - DiskGroup = 5 - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/LogicalDiskManager/TocBlock.cs b/src/LibHac.Nand/DiscUtils.Core/LogicalDiskManager/TocBlock.cs deleted file mode 100644 index 669b078d..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/LogicalDiskManager/TocBlock.cs +++ /dev/null @@ -1,72 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using DiscUtils.Streams; - -namespace DiscUtils.LogicalDiskManager -{ - internal class TocBlock - { - public uint Checksum; // 00 00 08 B6 - public long Item1Size; // Unit? - public long Item1Start; // Sector Offset from ConfigurationStart - public string Item1Str; // 'config', length 10 - public long Item2Size; // Unit? - public long Item2Start; // Sector Offset from ConfigurationStart - public string Item2Str; // 'log', length 10 - public long SequenceNumber; // 00 .. 01 - public string Signature; // TOCBLOCK - public long Unknown1; // 0 - public long Unknown2; // 00 - public uint Unknown3; // 00 06 00 01 (may be two values?) - public uint Unknown4; // 00 00 00 00 - public uint Unknown5; // 00 06 00 01 (may be two values?) - public uint Unknown6; // 00 00 00 00 - - public void ReadFrom(byte[] buffer, int offset) - { - Signature = EndianUtilities.BytesToString(buffer, offset + 0x00, 8); - Checksum = EndianUtilities.ToUInt32BigEndian(buffer, offset + 0x08); - SequenceNumber = EndianUtilities.ToInt64BigEndian(buffer, offset + 0x0C); - Unknown1 = EndianUtilities.ToInt64BigEndian(buffer, offset + 0x14); - Unknown2 = EndianUtilities.ToInt64BigEndian(buffer, offset + 0x1C); - Item1Str = EndianUtilities.BytesToString(buffer, offset + 0x24, 10).Trim('\0'); - Item1Start = EndianUtilities.ToInt64BigEndian(buffer, offset + 0x2E); - Item1Size = EndianUtilities.ToInt64BigEndian(buffer, offset + 0x36); - Unknown3 = EndianUtilities.ToUInt32BigEndian(buffer, offset + 0x3E); - Unknown4 = EndianUtilities.ToUInt32BigEndian(buffer, offset + 0x42); - Item2Str = EndianUtilities.BytesToString(buffer, offset + 0x46, 10).Trim('\0'); - Item2Start = EndianUtilities.ToInt64BigEndian(buffer, offset + 0x50); - Item2Size = EndianUtilities.ToInt64BigEndian(buffer, offset + 0x58); - Unknown5 = EndianUtilities.ToUInt32BigEndian(buffer, offset + 0x60); - Unknown6 = EndianUtilities.ToUInt32BigEndian(buffer, offset + 0x64); - } - - ////} - //// throw new NotImplementedException(); - //// // Add all byte values for ?? bytes - //// // Zero checksum bytes (0x08, 4) - ////{ - - ////private static int CalcChecksum() - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/LogicalDiskManager/VolumeRecord.cs b/src/LibHac.Nand/DiscUtils.Core/LogicalDiskManager/VolumeRecord.cs deleted file mode 100644 index 18385225..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/LogicalDiskManager/VolumeRecord.cs +++ /dev/null @@ -1,78 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using DiscUtils.Streams; - -namespace DiscUtils.LogicalDiskManager -{ - internal sealed class VolumeRecord : DatabaseRecord - { - public string ActiveString; - public byte BiosType; - public ulong ComponentCount; - public ulong DupCount; // ??Seen once after adding 'foreign disk', from broken mirror (identical links(P/V/C)) - public string GenString; - public string MountHint; - public string NumberString; // 8000000000000000 sometimes... - public uint PartitionComponentLink; - public long Size; - public ulong Unknown1; // Zero - public uint Unknown2; // Zero - public ulong UnknownA; // Zero - public ulong UnknownB; // 00 .. 03 - public uint UnknownC; // 00 00 00 11 - public uint UnknownD; // Zero - public Guid VolumeGuid; - - protected override void DoReadFrom(byte[] buffer, int offset) - { - base.DoReadFrom(buffer, offset); - - int pos = offset + 0x18; - - Id = ReadVarULong(buffer, ref pos); - Name = ReadVarString(buffer, ref pos); - GenString = ReadVarString(buffer, ref pos); - NumberString = ReadVarString(buffer, ref pos); - ActiveString = ReadString(buffer, 6, ref pos); - UnknownA = ReadVarULong(buffer, ref pos); - UnknownB = ReadULong(buffer, ref pos); - DupCount = ReadVarULong(buffer, ref pos); - UnknownC = ReadUInt(buffer, ref pos); - ComponentCount = ReadVarULong(buffer, ref pos); - UnknownD = ReadUInt(buffer, ref pos); - PartitionComponentLink = ReadUInt(buffer, ref pos); - Unknown1 = ReadULong(buffer, ref pos); - Size = ReadVarLong(buffer, ref pos); - Unknown2 = ReadUInt(buffer, ref pos); - BiosType = ReadByte(buffer, ref pos); - VolumeGuid = EndianUtilities.ToGuidBigEndian(buffer, pos); - pos += 16; - - if ((Flags & 0x0200) != 0) - { - MountHint = ReadVarString(buffer, ref pos); - } - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/LogicalVolumeInfo.cs b/src/LibHac.Nand/DiscUtils.Core/LogicalVolumeInfo.cs deleted file mode 100644 index 697a7168..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/LogicalVolumeInfo.cs +++ /dev/null @@ -1,120 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using DiscUtils.Streams; - -namespace DiscUtils -{ - /// - /// Information about a logical disk volume, which may be backed by one or more physical volumes. - /// - public sealed class LogicalVolumeInfo : VolumeInfo - { - private Guid _guid; - private readonly SparseStreamOpenDelegate _opener; - private readonly PhysicalVolumeInfo _physicalVol; - - internal LogicalVolumeInfo(Guid guid, PhysicalVolumeInfo physicalVolume, SparseStreamOpenDelegate opener, - long length, byte biosType, LogicalVolumeStatus status) - { - _guid = guid; - _physicalVol = physicalVolume; - _opener = opener; - Length = length; - BiosType = biosType; - Status = status; - } - - /// - /// Gets the disk geometry of the underlying storage medium (as used in BIOS calls), may be null. - /// - public override Geometry BiosGeometry - { - get { return _physicalVol == null ? Geometry.Null : _physicalVol.BiosGeometry; } - } - - /// - /// Gets the one-byte BIOS type for this volume, which indicates the content. - /// - public override byte BiosType { get; } - - /// - /// The stable identity for this logical volume. - /// - /// The stability of the identity depends the disk structure. - /// In some cases the identity may include a simple index, when no other information - /// is available. Best practice is to add disks to the Volume Manager in a stable - /// order, if the stability of this identity is paramount. - public override string Identity - { - get - { - if (_guid != Guid.Empty) - { - return "VLG" + _guid.ToString("B"); - } - return "VLP:" + _physicalVol.Identity; - } - } - - /// - /// Gets the length of the volume (in bytes). - /// - public override long Length { get; } - - /// - /// Gets the disk geometry of the underlying storage medium, if any (may be Geometry.Null). - /// - public override Geometry PhysicalGeometry - { - get { return _physicalVol == null ? Geometry.Null : _physicalVol.PhysicalGeometry; } - } - - /// - /// Gets the offset of this volume in the underlying storage medium, if any (may be Zero). - /// - public override long PhysicalStartSector - { - get { return _physicalVol == null ? 0 : _physicalVol.PhysicalStartSector; } - } - - /// - /// Gets the status of the logical volume, indicating volume health. - /// - public LogicalVolumeStatus Status { get; } - - /// - /// Gets the underlying physical volume info - /// - public PhysicalVolumeInfo PhysicalVolume { get { return _physicalVol; } } - - /// - /// Opens a stream with access to the content of the logical volume. - /// - /// The volume's content as a stream. - public override SparseStream Open() - { - return _opener(); - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/LogicalVolumeStatus.cs b/src/LibHac.Nand/DiscUtils.Core/LogicalVolumeStatus.cs deleted file mode 100644 index 368c759c..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/LogicalVolumeStatus.cs +++ /dev/null @@ -1,23 +0,0 @@ -namespace DiscUtils -{ - /// - /// Enumeration of the health status of a logical volume. - /// - public enum LogicalVolumeStatus - { - /// - /// The volume is healthy and fully functional. - /// - Healthy = 0, - - /// - /// The volume is completely accessible, but at degraded redundancy. - /// - FailedRedundancy = 1, - - /// - /// The volume is wholey, or partly, inaccessible. - /// - Failed = 2 - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/NativeFileSystem.cs b/src/LibHac.Nand/DiscUtils.Core/NativeFileSystem.cs deleted file mode 100644 index 4c9f9c9e..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/NativeFileSystem.cs +++ /dev/null @@ -1,804 +0,0 @@ -// -// DiscUtils Copyright (c) 2008-2011, Kenneth Bell -// -// Original NativeFileSystem contributed by bsobel: -// http://discutils.codeplex.com/workitem/5190 -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.IO; -using DiscUtils.Internal; -using DiscUtils.Streams; - -namespace DiscUtils -{ - /// - /// Provides an implementation for OS-mounted file systems. - /// - public class NativeFileSystem : DiscFileSystem - { - private readonly bool _readOnly; - - /// - /// Initializes a new instance of the NativeFileSystem class. - /// - /// The 'root' directory of the new instance. - /// Only permit 'read' activities. - public NativeFileSystem(string basePath, bool readOnly) - { - BasePath = basePath; - if (!BasePath.EndsWith(@"\", StringComparison.OrdinalIgnoreCase)) - { - BasePath += @"\"; - } - - _readOnly = readOnly; - } - - /// - /// Gets the base path used to create the file system. - /// - public string BasePath { get; } - - /// - /// Indicates whether the file system is read-only or read-write. - /// - /// true if the file system is read-write. - public override bool CanWrite - { - get { return !_readOnly; } - } - - /// - /// Provides a friendly description of the file system type. - /// - public override string FriendlyName - { - get { return "Native"; } - } - - /// - /// Gets a value indicating whether the file system is thread-safe. - /// - /// The Native File System is thread safe. - public override bool IsThreadSafe - { - get { return true; } - } - - /// - /// Gets the root directory of the file system. - /// - public override DiscDirectoryInfo Root - { - get { return new DiscDirectoryInfo(this, string.Empty); } - } - - /// - /// Gets the volume label. - /// - public override string VolumeLabel - { - get { return string.Empty; } - } - - /// - /// Copies an existing file to a new file. - /// - /// The source file. - /// The destination file. - public override void CopyFile(string sourceFile, string destinationFile) - { - CopyFile(sourceFile, destinationFile, true); - } - - /// - /// Copies an existing file to a new file, allowing overwriting of an existing file. - /// - /// The source file. - /// The destination file. - /// Whether to permit over-writing of an existing file. - public override void CopyFile(string sourceFile, string destinationFile, bool overwrite) - { - if (_readOnly) - { - throw new UnauthorizedAccessException(); - } - - if (sourceFile.StartsWith(@"\", StringComparison.OrdinalIgnoreCase)) - { - sourceFile = sourceFile.Substring(1); - } - - if (destinationFile.StartsWith(@"\", StringComparison.OrdinalIgnoreCase)) - { - destinationFile = destinationFile.Substring(1); - } - - File.Copy(Path.Combine(BasePath, sourceFile), Path.Combine(BasePath, destinationFile), true); - } - - /// - /// Creates a directory. - /// - /// The path of the new directory. - public override void CreateDirectory(string path) - { - if (_readOnly) - { - throw new UnauthorizedAccessException(); - } - - if (path.StartsWith(@"\", StringComparison.OrdinalIgnoreCase)) - { - path = path.Substring(1); - } - - Directory.CreateDirectory(Path.Combine(BasePath, path)); - } - - /// - /// Deletes a directory. - /// - /// The path of the directory to delete. - public override void DeleteDirectory(string path) - { - if (_readOnly) - { - throw new UnauthorizedAccessException(); - } - - if (path.StartsWith(@"\", StringComparison.OrdinalIgnoreCase)) - { - path = path.Substring(1); - } - - Directory.Delete(Path.Combine(BasePath, path)); - } - - /// - /// Deletes a directory, optionally with all descendants. - /// - /// The path of the directory to delete. - /// Determines if the all descendants should be deleted. - public override void DeleteDirectory(string path, bool recursive) - { - if (recursive) - { - foreach (string dir in GetDirectories(path)) - { - DeleteDirectory(dir, true); - } - - foreach (string file in GetFiles(path)) - { - DeleteFile(file); - } - } - - DeleteDirectory(path); - } - - /// - /// Deletes a file. - /// - /// The path of the file to delete. - public override void DeleteFile(string path) - { - if (_readOnly) - { - throw new UnauthorizedAccessException(); - } - - if (path.StartsWith(@"\", StringComparison.OrdinalIgnoreCase)) - { - path = path.Substring(1); - } - - File.Delete(Path.Combine(BasePath, path)); - } - - /// - /// Indicates if a directory exists. - /// - /// The path to test. - /// true if the directory exists. - public override bool DirectoryExists(string path) - { - if (path.StartsWith(@"\", StringComparison.OrdinalIgnoreCase)) - { - path = path.Substring(1); - } - - return Directory.Exists(Path.Combine(BasePath, path)); - } - - /// - /// Indicates if a file exists. - /// - /// The path to test. - /// true if the file exists. - public override bool FileExists(string path) - { - if (path.StartsWith(@"\", StringComparison.OrdinalIgnoreCase)) - { - path = path.Substring(1); - } - - return File.Exists(Path.Combine(BasePath, path)); - } - - /// - /// Indicates if a file or directory exists. - /// - /// The path to test. - /// true if the file or directory exists. - public override bool Exists(string path) - { - return FileExists(path) || DirectoryExists(path); - } - - /// - /// Gets the names of subdirectories in a specified directory. - /// - /// The path to search. - /// Array of directories. - public override string[] GetDirectories(string path) - { - return GetDirectories(path, "*.*", SearchOption.TopDirectoryOnly); - } - - /// - /// Gets the names of subdirectories in a specified directory matching a specified - /// search pattern. - /// - /// The path to search. - /// The search string to match against. - /// Array of directories matching the search pattern. - public override string[] GetDirectories(string path, string searchPattern) - { - return GetDirectories(path, searchPattern, SearchOption.TopDirectoryOnly); - } - - /// - /// Gets the names of subdirectories in a specified directory matching a specified - /// search pattern, using a value to determine whether to search subdirectories. - /// - /// The path to search. - /// The search string to match against. - /// Indicates whether to search subdirectories. - /// Array of directories matching the search pattern. - public override string[] GetDirectories(string path, string searchPattern, SearchOption searchOption) - { - if (path.StartsWith(@"\", StringComparison.OrdinalIgnoreCase)) - { - path = path.Substring(1); - } - - try - { - return CleanItems(Directory.GetDirectories(Path.Combine(BasePath, path), searchPattern, searchOption)); - } - catch (IOException) - { - return new string[0]; - } - catch (UnauthorizedAccessException) - { - return new string[0]; - } - } - - /// - /// Gets the names of files in a specified directory. - /// - /// The path to search. - /// Array of files. - public override string[] GetFiles(string path) - { - return GetFiles(path, "*.*", SearchOption.TopDirectoryOnly); - } - - /// - /// Gets the names of files in a specified directory. - /// - /// The path to search. - /// The search string to match against. - /// Array of files matching the search pattern. - public override string[] GetFiles(string path, string searchPattern) - { - return GetFiles(path, searchPattern, SearchOption.TopDirectoryOnly); - } - - /// - /// Gets the names of files in a specified directory matching a specified - /// search pattern, using a value to determine whether to search subdirectories. - /// - /// The path to search. - /// The search string to match against. - /// Indicates whether to search subdirectories. - /// Array of files matching the search pattern. - public override string[] GetFiles(string path, string searchPattern, SearchOption searchOption) - { - if (path.StartsWith(@"\", StringComparison.OrdinalIgnoreCase)) - { - path = path.Substring(1); - } - - try - { - return CleanItems(Directory.GetFiles(Path.Combine(BasePath, path), searchPattern, searchOption)); - } - catch (IOException) - { - return new string[0]; - } - catch (UnauthorizedAccessException) - { - return new string[0]; - } - } - - /// - /// Gets the names of all files and subdirectories in a specified directory. - /// - /// The path to search. - /// Array of files and subdirectories matching the search pattern. - public override string[] GetFileSystemEntries(string path) - { - return GetFileSystemEntries(path, "*.*"); - } - - /// - /// Gets the names of files and subdirectories in a specified directory matching a specified - /// search pattern. - /// - /// The path to search. - /// The search string to match against. - /// Array of files and subdirectories matching the search pattern. - public override string[] GetFileSystemEntries(string path, string searchPattern) - { - if (path.StartsWith(@"\", StringComparison.OrdinalIgnoreCase)) - { - path = path.Substring(1); - } - - try - { - return CleanItems(Directory.GetFileSystemEntries(Path.Combine(BasePath, path), searchPattern)); - } - catch (IOException) - { - return new string[0]; - } - catch (UnauthorizedAccessException) - { - return new string[0]; - } - } - - /// - /// Moves a directory. - /// - /// The directory to move. - /// The target directory name. - public override void MoveDirectory(string sourceDirectoryName, string destinationDirectoryName) - { - if (_readOnly) - { - throw new UnauthorizedAccessException(); - } - - if (sourceDirectoryName.StartsWith(@"\", StringComparison.OrdinalIgnoreCase)) - { - sourceDirectoryName = sourceDirectoryName.Substring(1); - } - - if (destinationDirectoryName.StartsWith(@"\", StringComparison.OrdinalIgnoreCase)) - { - destinationDirectoryName = destinationDirectoryName.Substring(1); - } - - Directory.Move(Path.Combine(BasePath, sourceDirectoryName), - Path.Combine(BasePath, destinationDirectoryName)); - } - - /// - /// Moves a file. - /// - /// The file to move. - /// The target file name. - public override void MoveFile(string sourceName, string destinationName) - { - MoveFile(sourceName, destinationName, false); - } - - /// - /// Moves a file, allowing an existing file to be overwritten. - /// - /// The file to move. - /// The target file name. - /// Whether to permit a destination file to be overwritten. - public override void MoveFile(string sourceName, string destinationName, bool overwrite) - { - if (_readOnly) - { - throw new UnauthorizedAccessException(); - } - - if (destinationName.StartsWith(@"\", StringComparison.OrdinalIgnoreCase)) - { - destinationName = destinationName.Substring(1); - } - - if (FileExists(Path.Combine(BasePath, destinationName))) - { - if (overwrite) - { - DeleteFile(Path.Combine(BasePath, destinationName)); - } - else - { - throw new IOException("File already exists"); - } - } - - if (sourceName.StartsWith(@"\", StringComparison.OrdinalIgnoreCase)) - { - sourceName = sourceName.Substring(1); - } - - File.Move(Path.Combine(BasePath, sourceName), Path.Combine(BasePath, destinationName)); - } - - /// - /// Opens the specified file. - /// - /// The full path of the file to open. - /// The file mode for the created stream. - /// The new stream. - public override SparseStream OpenFile(string path, FileMode mode) - { - return OpenFile(path, mode, FileAccess.ReadWrite); - } - - /// - /// Opens the specified file. - /// - /// The full path of the file to open. - /// The file mode for the created stream. - /// The access permissions for the created stream. - /// The new stream. - public override SparseStream OpenFile(string path, FileMode mode, FileAccess access) - { - if (_readOnly && access != FileAccess.Read) - { - throw new UnauthorizedAccessException(); - } - - if (path.StartsWith(@"\", StringComparison.OrdinalIgnoreCase)) - { - path = path.Substring(1); - } - - FileShare fileShare = FileShare.None; - if (access == FileAccess.Read) - { - fileShare = FileShare.Read; - } - - var locator = new LocalFileLocator(BasePath); - return SparseStream.FromStream(locator.Open(path, mode, access, fileShare), - Ownership.Dispose); - } - - /// - /// Gets the attributes of a file or directory. - /// - /// The file or directory to inspect. - /// The attributes of the file or directory. - public override FileAttributes GetAttributes(string path) - { - if (path.StartsWith(@"\", StringComparison.OrdinalIgnoreCase)) - { - path = path.Substring(1); - } - - return File.GetAttributes(Path.Combine(BasePath, path)); - } - - /// - /// Sets the attributes of a file or directory. - /// - /// The file or directory to change. - /// The new attributes of the file or directory. - public override void SetAttributes(string path, FileAttributes newValue) - { - if (_readOnly) - { - throw new UnauthorizedAccessException(); - } - - if (path.StartsWith(@"\", StringComparison.OrdinalIgnoreCase)) - { - path = path.Substring(1); - } - - File.SetAttributes(Path.Combine(BasePath, path), newValue); - } - - /// - /// Gets the creation time (in local time) of a file or directory. - /// - /// The path of the file or directory. - /// The creation time. - public override DateTime GetCreationTime(string path) - { - return GetCreationTimeUtc(path).ToLocalTime(); - } - - /// - /// Sets the creation time (in local time) of a file or directory. - /// - /// The path of the file or directory. - /// The new time to set. - public override void SetCreationTime(string path, DateTime newTime) - { - SetCreationTimeUtc(path, newTime.ToUniversalTime()); - } - - /// - /// Gets the creation time (in UTC) of a file or directory. - /// - /// The path of the file or directory. - /// The creation time. - public override DateTime GetCreationTimeUtc(string path) - { - if (path.StartsWith(@"\", StringComparison.OrdinalIgnoreCase)) - { - path = path.Substring(1); - } - - return File.GetCreationTimeUtc(Path.Combine(BasePath, path)); - } - - /// - /// Sets the creation time (in UTC) of a file or directory. - /// - /// The path of the file or directory. - /// The new time to set. - public override void SetCreationTimeUtc(string path, DateTime newTime) - { - if (_readOnly) - { - throw new UnauthorizedAccessException(); - } - - if (path.StartsWith(@"\", StringComparison.OrdinalIgnoreCase)) - { - path = path.Substring(1); - } - - File.SetCreationTimeUtc(Path.Combine(BasePath, path), newTime); - } - - /// - /// Gets the last access time (in local time) of a file or directory. - /// - /// The path of the file or directory. - /// The last access time. - public override DateTime GetLastAccessTime(string path) - { - return GetLastAccessTimeUtc(path).ToLocalTime(); - } - - /// - /// Sets the last access time (in local time) of a file or directory. - /// - /// The path of the file or directory. - /// The new time to set. - public override void SetLastAccessTime(string path, DateTime newTime) - { - SetLastAccessTimeUtc(path, newTime.ToUniversalTime()); - } - - /// - /// Gets the last access time (in UTC) of a file or directory. - /// - /// The path of the file or directory. - /// The last access time. - public override DateTime GetLastAccessTimeUtc(string path) - { - if (path.StartsWith(@"\", StringComparison.OrdinalIgnoreCase)) - { - path = path.Substring(1); - } - - return File.GetLastAccessTimeUtc(Path.Combine(BasePath, path)); - } - - /// - /// Sets the last access time (in UTC) of a file or directory. - /// - /// The path of the file or directory. - /// The new time to set. - public override void SetLastAccessTimeUtc(string path, DateTime newTime) - { - if (_readOnly) - { - throw new UnauthorizedAccessException(); - } - - if (path.StartsWith(@"\", StringComparison.OrdinalIgnoreCase)) - { - path = path.Substring(1); - } - - File.SetLastAccessTimeUtc(Path.Combine(BasePath, path), newTime); - } - - /// - /// Gets the last modification time (in local time) of a file or directory. - /// - /// The path of the file or directory. - /// The last write time. - public override DateTime GetLastWriteTime(string path) - { - return GetLastWriteTimeUtc(path).ToLocalTime(); - } - - /// - /// Sets the last modification time (in local time) of a file or directory. - /// - /// The path of the file or directory. - /// The new time to set. - public override void SetLastWriteTime(string path, DateTime newTime) - { - SetLastWriteTimeUtc(path, newTime.ToUniversalTime()); - } - - /// - /// Gets the last modification time (in UTC) of a file or directory. - /// - /// The path of the file or directory. - /// The last write time. - public override DateTime GetLastWriteTimeUtc(string path) - { - if (path.StartsWith(@"\", StringComparison.OrdinalIgnoreCase)) - { - path = path.Substring(1); - } - - return File.GetLastWriteTimeUtc(Path.Combine(BasePath, path)); - } - - /// - /// Sets the last modification time (in UTC) of a file or directory. - /// - /// The path of the file or directory. - /// The new time to set. - public override void SetLastWriteTimeUtc(string path, DateTime newTime) - { - if (_readOnly) - { - throw new UnauthorizedAccessException(); - } - - if (path.StartsWith(@"\", StringComparison.OrdinalIgnoreCase)) - { - path = path.Substring(1); - } - - File.SetLastWriteTimeUtc(Path.Combine(BasePath, path), newTime); - } - - /// - /// Gets the length of a file. - /// - /// The path to the file. - /// The length in bytes. - public override long GetFileLength(string path) - { - if (path.StartsWith(@"\", StringComparison.OrdinalIgnoreCase)) - { - path = path.Substring(1); - } - - return new FileInfo(Path.Combine(BasePath, path)).Length; - } - - /// - /// Gets an object representing a possible file. - /// - /// The file path. - /// The representing object. - /// The file does not need to exist. - public override DiscFileInfo GetFileInfo(string path) - { - return new DiscFileInfo(this, path); - } - - /// - /// Gets an object representing a possible directory. - /// - /// The directory path. - /// The representing object. - /// The directory does not need to exist. - public override DiscDirectoryInfo GetDirectoryInfo(string path) - { - return new DiscDirectoryInfo(this, path); - } - - /// - /// Gets an object representing a possible file system object (file or directory). - /// - /// The file system path. - /// The representing object. - /// The file system object does not need to exist. - public override DiscFileSystemInfo GetFileSystemInfo(string path) - { - return new DiscFileSystemInfo(this, path); - } - - /// - /// Size of the Filesystem in bytes - /// - public override long Size - { - get - { - DriveInfo info = new DriveInfo(BasePath); - return info.TotalSize; - } - } - - /// - /// Used space of the Filesystem in bytes - /// - public override long UsedSpace - { - get { return Size - AvailableSpace; } - } - - /// - /// Available space of the Filesystem in bytes - /// - public override long AvailableSpace - { - get - { - DriveInfo info = new DriveInfo(BasePath); - return info.AvailableFreeSpace; - } - } - - private string[] CleanItems(string[] dirtyItems) - { - string[] cleanList = new string[dirtyItems.Length]; - for (int x = 0; x < dirtyItems.Length; x++) - { - cleanList[x] = dirtyItems[x].Substring(BasePath.Length - 1); - } - - return cleanList; - } - } -} diff --git a/src/LibHac.Nand/DiscUtils.Core/Partitions/BiosExtendedPartitionTable.cs b/src/LibHac.Nand/DiscUtils.Core/Partitions/BiosExtendedPartitionTable.cs deleted file mode 100644 index d08ca872..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Partitions/BiosExtendedPartitionTable.cs +++ /dev/null @@ -1,119 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System.Collections.Generic; -using System.IO; -using DiscUtils.Streams; - -namespace DiscUtils.Partitions -{ - internal class BiosExtendedPartitionTable - { - private readonly Stream _disk; - private readonly uint _firstSector; - - public BiosExtendedPartitionTable(Stream disk, uint firstSector) - { - _disk = disk; - _firstSector = firstSector; - } - - public BiosPartitionRecord[] GetPartitions() - { - List result = new List(); - - uint partPos = _firstSector; - while (partPos != 0) - { - _disk.Position = (long)partPos * Sizes.Sector; - byte[] sector = StreamUtilities.ReadExact(_disk, Sizes.Sector); - if (sector[510] != 0x55 || sector[511] != 0xAA) - { - throw new IOException("Invalid extended partition sector"); - } - - uint nextPartPos = 0; - for (int offset = 0x1BE; offset <= 0x1EE; offset += 0x10) - { - BiosPartitionRecord thisPart = new BiosPartitionRecord(sector, offset, partPos, -1); - - if (thisPart.StartCylinder != 0 || thisPart.StartHead != 0 || thisPart.StartSector != 0 || - (thisPart.LBAStart != 0 && thisPart.LBALength != 0)) - { - if (thisPart.PartitionType != 0x05 && thisPart.PartitionType != 0x0F) - { - result.Add(thisPart); - } - else - { - nextPartPos = _firstSector + thisPart.LBAStart; - } - } - } - - partPos = nextPartPos; - } - - return result.ToArray(); - } - - /// - /// Gets all of the disk ranges containing partition table data. - /// - /// Set of stream extents, indicated as byte offset from the start of the disk. - public IEnumerable GetMetadataDiskExtents() - { - List extents = new List(); - - uint partPos = _firstSector; - while (partPos != 0) - { - extents.Add(new StreamExtent((long)partPos * Sizes.Sector, Sizes.Sector)); - - _disk.Position = (long)partPos * Sizes.Sector; - byte[] sector = StreamUtilities.ReadExact(_disk, Sizes.Sector); - if (sector[510] != 0x55 || sector[511] != 0xAA) - { - throw new IOException("Invalid extended partition sector"); - } - - uint nextPartPos = 0; - for (int offset = 0x1BE; offset <= 0x1EE; offset += 0x10) - { - BiosPartitionRecord thisPart = new BiosPartitionRecord(sector, offset, partPos, -1); - - if (thisPart.StartCylinder != 0 || thisPart.StartHead != 0 || thisPart.StartSector != 0) - { - if (thisPart.PartitionType == 0x05 || thisPart.PartitionType == 0x0F) - { - nextPartPos = _firstSector + thisPart.LBAStart; - } - } - } - - partPos = nextPartPos; - } - - return extents; - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Partitions/BiosPartitionInfo.cs b/src/LibHac.Nand/DiscUtils.Core/Partitions/BiosPartitionInfo.cs deleted file mode 100644 index ea7a4efb..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Partitions/BiosPartitionInfo.cs +++ /dev/null @@ -1,136 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using DiscUtils.Streams; - -namespace DiscUtils.Partitions -{ - /// - /// Provides access to partition records in a BIOS (MBR) partition table. - /// - public sealed class BiosPartitionInfo : PartitionInfo - { - private readonly BiosPartitionRecord _record; - private readonly BiosPartitionTable _table; - - internal BiosPartitionInfo(BiosPartitionTable table, BiosPartitionRecord record) - { - _table = table; - _record = record; - } - - /// - /// Gets the type of the partition. - /// - public override byte BiosType - { - get { return _record.PartitionType; } - } - - /// - /// Gets the end (inclusive) of the partition as a CHS address. - /// - public ChsAddress End - { - get { return new ChsAddress(_record.EndCylinder, _record.EndHead, _record.EndSector); } - } - - /// - /// Gets the first sector of the partion (relative to start of disk) as a Logical Block Address. - /// - public override long FirstSector - { - get { return _record.LBAStartAbsolute; } - } - - /// - /// Always returns .Empty. - /// - public override Guid GuidType - { - get { return Guid.Empty; } - } - - /// - /// Gets a value indicating whether this partition is active (bootable). - /// - public bool IsActive - { - get { return _record.Status != 0; } - } - - /// - /// Gets a value indicating whether the partition is a primary (rather than extended) partition. - /// - public bool IsPrimary - { - get { return PrimaryIndex >= 0; } - } - - /// - /// Gets the last sector of the partion (relative to start of disk) as a Logical Block Address (inclusive). - /// - public override long LastSector - { - get { return _record.LBAStartAbsolute + _record.LBALength - 1; } - } - - /// - /// Gets the index of the partition in the primary partition table, or -1 if not a primary partition. - /// - public int PrimaryIndex - { - get { return _record.Index; } - } - - /// - /// Gets the start of the partition as a CHS address. - /// - public ChsAddress Start - { - get { return new ChsAddress(_record.StartCylinder, _record.StartHead, _record.StartSector); } - } - - /// - /// Gets the type of the partition as a string. - /// - public override string TypeAsString - { - get { return _record.FriendlyPartitionType; } - } - - internal override PhysicalVolumeType VolumeType - { - get { return PhysicalVolumeType.BiosPartition; } - } - - /// - /// Opens a stream to access the content of the partition. - /// - /// The new stream. - public override SparseStream Open() - { - return _table.Open(_record); - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Partitions/BiosPartitionRecord.cs b/src/LibHac.Nand/DiscUtils.Core/Partitions/BiosPartitionRecord.cs deleted file mode 100644 index a76fafbf..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Partitions/BiosPartitionRecord.cs +++ /dev/null @@ -1,107 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using DiscUtils.Streams; - -namespace DiscUtils.Partitions -{ - internal class BiosPartitionRecord : IComparable - { - private readonly uint _lbaOffset; - - public BiosPartitionRecord() {} - - public BiosPartitionRecord(byte[] data, int offset, uint lbaOffset, int index) - { - _lbaOffset = lbaOffset; - - Status = data[offset]; - StartHead = data[offset + 1]; - StartSector = (byte)(data[offset + 2] & 0x3F); - StartCylinder = (ushort)(data[offset + 3] | ((data[offset + 2] & 0xC0) << 2)); - PartitionType = data[offset + 4]; - EndHead = data[offset + 5]; - EndSector = (byte)(data[offset + 6] & 0x3F); - EndCylinder = (ushort)(data[offset + 7] | ((data[offset + 6] & 0xC0) << 2)); - LBAStart = EndianUtilities.ToUInt32LittleEndian(data, offset + 8); - LBALength = EndianUtilities.ToUInt32LittleEndian(data, offset + 12); - Index = index; - } - - public ushort EndCylinder { get; set; } - - public byte EndHead { get; set; } - - public byte EndSector { get; set; } - - public string FriendlyPartitionType - { - get { return BiosPartitionTypes.ToString(PartitionType); } - } - - public int Index { get; } - - public bool IsValid - { - get { return EndHead != 0 || EndSector != 0 || EndCylinder != 0 || LBALength != 0; } - } - - public uint LBALength { get; set; } - - public uint LBAStart { get; set; } - - public uint LBAStartAbsolute - { - get { return LBAStart + _lbaOffset; } - } - - public byte PartitionType { get; set; } - - public ushort StartCylinder { get; set; } - - public byte StartHead { get; set; } - - public byte StartSector { get; set; } - - public byte Status { get; set; } - - public int CompareTo(BiosPartitionRecord other) - { - return LBAStartAbsolute.CompareTo(other.LBAStartAbsolute); - } - - internal void WriteTo(byte[] buffer, int offset) - { - buffer[offset] = Status; - buffer[offset + 1] = StartHead; - buffer[offset + 2] = (byte)((StartSector & 0x3F) | ((StartCylinder >> 2) & 0xC0)); - buffer[offset + 3] = (byte)StartCylinder; - buffer[offset + 4] = PartitionType; - buffer[offset + 5] = EndHead; - buffer[offset + 6] = (byte)((EndSector & 0x3F) | ((EndCylinder >> 2) & 0xC0)); - buffer[offset + 7] = (byte)EndCylinder; - EndianUtilities.WriteBytesLittleEndian(LBAStart, buffer, offset + 8); - EndianUtilities.WriteBytesLittleEndian(LBALength, buffer, offset + 12); - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Partitions/BiosPartitionTable.cs b/src/LibHac.Nand/DiscUtils.Core/Partitions/BiosPartitionTable.cs deleted file mode 100644 index 48682d5a..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Partitions/BiosPartitionTable.cs +++ /dev/null @@ -1,734 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Globalization; -using System.IO; -using DiscUtils.Internal; -using DiscUtils.Streams; - -namespace DiscUtils.Partitions -{ - /// - /// Represents a BIOS (MBR) Partition Table. - /// - public sealed class BiosPartitionTable : PartitionTable - { - private Stream _diskData; - private Geometry _diskGeometry; - - /// - /// Initializes a new instance of the BiosPartitionTable class. - /// - /// The disk containing the partition table. - public BiosPartitionTable(VirtualDisk disk) - { - Init(disk.Content, disk.BiosGeometry); - } - - /// - /// Initializes a new instance of the BiosPartitionTable class. - /// - /// The stream containing the disk data. - /// The geometry of the disk. - public BiosPartitionTable(Stream disk, Geometry diskGeometry) - { - Init(disk, diskGeometry); - } - - /// - /// Gets a collection of the partitions for storing Operating System file-systems. - /// - public ReadOnlyCollection BiosUserPartitions - { - get - { - List result = new List(); - foreach (BiosPartitionRecord r in GetAllRecords()) - { - if (r.IsValid) - { - result.Add(new BiosPartitionInfo(this, r)); - } - } - - return new ReadOnlyCollection(result); - } - } - - /// - /// Gets the GUID that uniquely identifies this disk, if supported (else returns null). - /// - public override Guid DiskGuid - { - get { return Guid.Empty; } - } - - /// - /// Gets a collection of the partitions for storing Operating System file-systems. - /// - public override ReadOnlyCollection Partitions - { - get - { - List result = new List(); - foreach (BiosPartitionRecord r in GetAllRecords()) - { - if (r.IsValid) - { - result.Add(new BiosPartitionInfo(this, r)); - } - } - - return new ReadOnlyCollection(result); - } - } - - /// - /// Makes a best guess at the geometry of a disk. - /// - /// String containing the disk image to detect the geometry from. - /// The detected geometry. - public static Geometry DetectGeometry(Stream disk) - { - if (disk.Length >= Sizes.Sector) - { - disk.Position = 0; - byte[] bootSector = StreamUtilities.ReadExact(disk, Sizes.Sector); - if (bootSector[510] == 0x55 && bootSector[511] == 0xAA) - { - byte maxHead = 0; - byte maxSector = 0; - foreach (BiosPartitionRecord record in ReadPrimaryRecords(bootSector)) - { - maxHead = Math.Max(maxHead, record.EndHead); - maxSector = Math.Max(maxSector, record.EndSector); - } - - if (maxHead > 0 && maxSector > 0) - { - int cylSize = (maxHead + 1) * maxSector * 512; - return new Geometry((int)MathUtilities.Ceil(disk.Length, cylSize), maxHead + 1, maxSector); - } - } - } - - return Geometry.FromCapacity(disk.Length); - } - - /// - /// Indicates if a stream contains a valid partition table. - /// - /// The stream to inspect. - /// true if the partition table is valid, else false. - public static bool IsValid(Stream disk) - { - if (disk.Length < Sizes.Sector) - { - return false; - } - - disk.Position = 0; - byte[] bootSector = StreamUtilities.ReadExact(disk, Sizes.Sector); - - // Check for the 'bootable sector' marker - if (bootSector[510] != 0x55 || bootSector[511] != 0xAA) - { - return false; - } - - List knownPartitions = new List(); - foreach (BiosPartitionRecord record in ReadPrimaryRecords(bootSector)) - { - // If the partition extends beyond the end of the disk, this is probably an invalid partition table - if (record.LBALength != 0xFFFFFFFF && - (record.LBAStart + (long)record.LBALength) * Sizes.Sector > disk.Length) - { - return false; - } - - if (record.LBALength > 0) - { - StreamExtent[] thisPartitionExtents = { new StreamExtent(record.LBAStart, record.LBALength) }; - - // If the partition intersects another partition, this is probably an invalid partition table - foreach (StreamExtent overlap in StreamExtent.Intersect(knownPartitions, thisPartitionExtents)) - { - return false; - } - - knownPartitions = new List(StreamExtent.Union(knownPartitions, thisPartitionExtents)); - } - } - - return true; - } - - /// - /// Creates a new partition table on a disk. - /// - /// The disk to initialize. - /// An object to access the newly created partition table. - public static BiosPartitionTable Initialize(VirtualDisk disk) - { - return Initialize(disk.Content, disk.BiosGeometry); - } - - /// - /// Creates a new partition table on a disk containing a single partition. - /// - /// The disk to initialize. - /// The partition type for the single partition. - /// An object to access the newly created partition table. - public static BiosPartitionTable Initialize(VirtualDisk disk, WellKnownPartitionType type) - { - BiosPartitionTable table = Initialize(disk.Content, disk.BiosGeometry); - table.Create(type, true); - return table; - } - - /// - /// Creates a new partition table on a disk. - /// - /// The stream containing the disk data. - /// The geometry of the disk. - /// An object to access the newly created partition table. - public static BiosPartitionTable Initialize(Stream disk, Geometry diskGeometry) - { - Stream data = disk; - - byte[] bootSector; - if (data.Length >= Sizes.Sector) - { - data.Position = 0; - bootSector = StreamUtilities.ReadExact(data, Sizes.Sector); - } - else - { - bootSector = new byte[Sizes.Sector]; - } - - // Wipe all four 16-byte partition table entries - Array.Clear(bootSector, 0x01BE, 16 * 4); - - // Marker bytes - bootSector[510] = 0x55; - bootSector[511] = 0xAA; - - data.Position = 0; - data.Write(bootSector, 0, bootSector.Length); - - return new BiosPartitionTable(disk, diskGeometry); - } - - /// - /// Creates a new partition that encompasses the entire disk. - /// - /// The partition type. - /// Whether the partition is active (bootable). - /// The index of the partition. - /// The partition table must be empty before this method is called, - /// otherwise IOException is thrown. - public override int Create(WellKnownPartitionType type, bool active) - { - Geometry allocationGeometry = new Geometry(_diskData.Length, _diskGeometry.HeadsPerCylinder, - _diskGeometry.SectorsPerTrack, _diskGeometry.BytesPerSector); - - ChsAddress start = new ChsAddress(0, 1, 1); - ChsAddress last = allocationGeometry.LastSector; - - long startLba = allocationGeometry.ToLogicalBlockAddress(start); - long lastLba = allocationGeometry.ToLogicalBlockAddress(last); - - return CreatePrimaryByCylinder(0, allocationGeometry.Cylinders - 1, - ConvertType(type, (lastLba - startLba) * Sizes.Sector), active); - } - - /// - /// Creates a new primary partition with a target size. - /// - /// The target size (in bytes). - /// The partition type. - /// Whether the partition is active (bootable). - /// The index of the new partition. - public override int Create(long size, WellKnownPartitionType type, bool active) - { - int cylinderCapacity = _diskGeometry.SectorsPerTrack * _diskGeometry.HeadsPerCylinder * - _diskGeometry.BytesPerSector; - int numCylinders = (int)(size / cylinderCapacity); - - int startCylinder = FindCylinderGap(numCylinders); - - return CreatePrimaryByCylinder(startCylinder, startCylinder + numCylinders - 1, ConvertType(type, size), - active); - } - - /// - /// Creates a new aligned partition that encompasses the entire disk. - /// - /// The partition type. - /// Whether the partition is active (bootable). - /// The alignment (in bytes). - /// The index of the partition. - /// The partition table must be empty before this method is called, - /// otherwise IOException is thrown. - /// - /// Traditionally partitions were aligned to the physical structure of the underlying disk, - /// however with modern storage greater efficiency is acheived by aligning partitions on - /// large values that are a power of two. - /// - public override int CreateAligned(WellKnownPartitionType type, bool active, int alignment) - { - Geometry allocationGeometry = new Geometry(_diskData.Length, _diskGeometry.HeadsPerCylinder, - _diskGeometry.SectorsPerTrack, _diskGeometry.BytesPerSector); - - ChsAddress start = new ChsAddress(0, 1, 1); - - long startLba = MathUtilities.RoundUp(allocationGeometry.ToLogicalBlockAddress(start), - alignment / _diskGeometry.BytesPerSector); - long lastLba = MathUtilities.RoundDown(_diskData.Length / _diskGeometry.BytesPerSector, - alignment / _diskGeometry.BytesPerSector); - - return CreatePrimaryBySector(startLba, lastLba - 1, - ConvertType(type, (lastLba - startLba) * _diskGeometry.BytesPerSector), active); - } - - /// - /// Creates a new aligned partition with a target size. - /// - /// The target size (in bytes). - /// The partition type. - /// Whether the partition is active (bootable). - /// The alignment (in bytes). - /// The index of the new partition. - /// - /// Traditionally partitions were aligned to the physical structure of the underlying disk, - /// however with modern storage greater efficiency is achieved by aligning partitions on - /// large values that are a power of two. - /// - public override int CreateAligned(long size, WellKnownPartitionType type, bool active, int alignment) - { - if (size < _diskGeometry.BytesPerSector) - { - throw new ArgumentOutOfRangeException(nameof(size), size, "size must be at least one sector"); - } - - if (alignment % _diskGeometry.BytesPerSector != 0) - { - throw new ArgumentException("Alignment is not a multiple of the sector size"); - } - - if (size % alignment != 0) - { - throw new ArgumentException("Size is not a multiple of the alignment"); - } - - long sectorLength = size / _diskGeometry.BytesPerSector; - long start = FindGap(size / _diskGeometry.BytesPerSector, alignment / _diskGeometry.BytesPerSector); - - return CreatePrimaryBySector(start, start + sectorLength - 1, - ConvertType(type, sectorLength * Sizes.Sector), active); - } - - /// - /// Deletes a partition at a given index. - /// - /// The index of the partition. - public override void Delete(int index) - { - WriteRecord(index, new BiosPartitionRecord()); - } - - /// - /// Creates a new Primary Partition that occupies whole cylinders, for best compatibility. - /// - /// The first cylinder to include in the partition (inclusive). - /// The last cylinder to include in the partition (inclusive). - /// The BIOS (MBR) type of the new partition. - /// Whether to mark the partition active (bootable). - /// The index of the new partition. - /// If the cylinder 0 is given, the first track will not be used, to reserve space - /// for the meta-data at the start of the disk. - public int CreatePrimaryByCylinder(int first, int last, byte type, bool markActive) - { - if (first < 0) - { - throw new ArgumentOutOfRangeException(nameof(first), first, "First cylinder must be Zero or greater"); - } - - if (last <= first) - { - throw new ArgumentException("Last cylinder must be greater than first"); - } - - long lbaStart = first == 0 - ? _diskGeometry.ToLogicalBlockAddress(0, 1, 1) - : _diskGeometry.ToLogicalBlockAddress(first, 0, 1); - long lbaLast = _diskGeometry.ToLogicalBlockAddress(last, _diskGeometry.HeadsPerCylinder - 1, - _diskGeometry.SectorsPerTrack); - - return CreatePrimaryBySector(lbaStart, lbaLast, type, markActive); - } - - /// - /// Creates a new Primary Partition, specified by Logical Block Addresses. - /// - /// The LBA address of the first sector (inclusive). - /// The LBA address of the last sector (inclusive). - /// The BIOS (MBR) type of the new partition. - /// Whether to mark the partition active (bootable). - /// The index of the new partition. - public int CreatePrimaryBySector(long first, long last, byte type, bool markActive) - { - if (first >= last) - { - throw new ArgumentException("The first sector in a partition must be before the last"); - } - - if ((last + 1) * _diskGeometry.BytesPerSector > _diskData.Length) - { - throw new ArgumentOutOfRangeException(nameof(last), last, - "The last sector extends beyond the end of the disk"); - } - - BiosPartitionRecord[] existing = GetPrimaryRecords(); - - BiosPartitionRecord newRecord = new BiosPartitionRecord(); - ChsAddress startAddr = _diskGeometry.ToChsAddress(first); - ChsAddress endAddr = _diskGeometry.ToChsAddress(last); - - // Because C/H/S addresses can max out at lower values than the LBA values, - // the special tuple (1023, 254, 63) is used. - if (startAddr.Cylinder > 1023) - { - startAddr = new ChsAddress(1023, 254, 63); - } - - if (endAddr.Cylinder > 1023) - { - endAddr = new ChsAddress(1023, 254, 63); - } - - newRecord.StartCylinder = (ushort)startAddr.Cylinder; - newRecord.StartHead = (byte)startAddr.Head; - newRecord.StartSector = (byte)startAddr.Sector; - newRecord.EndCylinder = (ushort)endAddr.Cylinder; - newRecord.EndHead = (byte)endAddr.Head; - newRecord.EndSector = (byte)endAddr.Sector; - newRecord.LBAStart = (uint)first; - newRecord.LBALength = (uint)(last - first + 1); - newRecord.PartitionType = type; - newRecord.Status = (byte)(markActive ? 0x80 : 0x00); - - // First check for overlap with existing partition... - foreach (BiosPartitionRecord r in existing) - { - if (Utilities.RangesOverlap((uint)first, (uint)last + 1, r.LBAStartAbsolute, - r.LBAStartAbsolute + r.LBALength)) - { - throw new IOException("New partition overlaps with existing partition"); - } - } - - // Now look for empty partition - for (int i = 0; i < 4; ++i) - { - if (!existing[i].IsValid) - { - WriteRecord(i, newRecord); - return i; - } - } - - throw new IOException("No primary partition slots available"); - } - - /// - /// Sets the active partition. - /// - /// The index of the primary partition to mark bootable, or -1 for none. - /// The supplied index is the index within the primary partition, see PrimaryIndex on BiosPartitionInfo. - public void SetActivePartition(int index) - { - List records = new List(GetPrimaryRecords()); - - for (int i = 0; i < records.Count; ++i) - { - records[i].Status = i == index ? (byte)0x80 : (byte)0x00; - WriteRecord(i, records[i]); - } - } - - /// - /// Gets all of the disk ranges containing partition table metadata. - /// - /// Set of stream extents, indicated as byte offset from the start of the disk. - public IEnumerable GetMetadataDiskExtents() - { - List extents = new List(); - - extents.Add(new StreamExtent(0, Sizes.Sector)); - - foreach (BiosPartitionRecord primaryRecord in GetPrimaryRecords()) - { - if (primaryRecord.IsValid) - { - if (IsExtendedPartition(primaryRecord)) - { - extents.AddRange( - new BiosExtendedPartitionTable(_diskData, primaryRecord.LBAStart).GetMetadataDiskExtents()); - } - } - } - - return extents; - } - - /// - /// Updates the CHS fields in partition records to reflect a new BIOS geometry. - /// - /// The disk's new BIOS geometry. - /// The partitions are not relocated to a cylinder boundary, just the CHS fields are updated on the - /// assumption the LBA fields are definitive. - public void UpdateBiosGeometry(Geometry geometry) - { - _diskData.Position = 0; - byte[] bootSector = StreamUtilities.ReadExact(_diskData, Sizes.Sector); - - BiosPartitionRecord[] records = ReadPrimaryRecords(bootSector); - for (int i = 0; i < records.Length; ++i) - { - BiosPartitionRecord record = records[i]; - if (record.IsValid) - { - ChsAddress newStartAddress = geometry.ToChsAddress(record.LBAStartAbsolute); - if (newStartAddress.Cylinder > 1023) - { - newStartAddress = new ChsAddress(1023, geometry.HeadsPerCylinder - 1, geometry.SectorsPerTrack); - } - - ChsAddress newEndAddress = geometry.ToChsAddress(record.LBAStartAbsolute + record.LBALength - 1); - if (newEndAddress.Cylinder > 1023) - { - newEndAddress = new ChsAddress(1023, geometry.HeadsPerCylinder - 1, geometry.SectorsPerTrack); - } - - record.StartCylinder = (ushort)newStartAddress.Cylinder; - record.StartHead = (byte)newStartAddress.Head; - record.StartSector = (byte)newStartAddress.Sector; - record.EndCylinder = (ushort)newEndAddress.Cylinder; - record.EndHead = (byte)newEndAddress.Head; - record.EndSector = (byte)newEndAddress.Sector; - - WriteRecord(i, record); - } - } - - _diskGeometry = geometry; - } - - internal SparseStream Open(BiosPartitionRecord record) - { - return new SubStream(_diskData, Ownership.None, - record.LBAStartAbsolute * _diskGeometry.BytesPerSector, - record.LBALength * _diskGeometry.BytesPerSector); - } - - private static BiosPartitionRecord[] ReadPrimaryRecords(byte[] bootSector) - { - BiosPartitionRecord[] records = new BiosPartitionRecord[4]; - for (int i = 0; i < 4; ++i) - { - records[i] = new BiosPartitionRecord(bootSector, 0x01BE + i * 0x10, 0, i); - } - - return records; - } - - private static bool IsExtendedPartition(BiosPartitionRecord r) - { - return r.PartitionType == BiosPartitionTypes.Extended || r.PartitionType == BiosPartitionTypes.ExtendedLba; - } - - private static byte ConvertType(WellKnownPartitionType type, long size) - { - switch (type) - { - case WellKnownPartitionType.WindowsFat: - if (size < 512 * Sizes.OneMiB) - { - return BiosPartitionTypes.Fat16; - } - if (size < 1023 * (long)254 * 63 * 512) - { - // Max BIOS size - return BiosPartitionTypes.Fat32; - } - return BiosPartitionTypes.Fat32Lba; - - case WellKnownPartitionType.WindowsNtfs: - return BiosPartitionTypes.Ntfs; - case WellKnownPartitionType.Linux: - return BiosPartitionTypes.LinuxNative; - case WellKnownPartitionType.LinuxSwap: - return BiosPartitionTypes.LinuxSwap; - case WellKnownPartitionType.LinuxLvm: - return BiosPartitionTypes.LinuxLvm; - default: - throw new ArgumentException( - string.Format(CultureInfo.InvariantCulture, "Unrecognized partition type: '{0}'", type), - nameof(type)); - } - } - - private BiosPartitionRecord[] GetAllRecords() - { - List newList = new List(); - - foreach (BiosPartitionRecord primaryRecord in GetPrimaryRecords()) - { - if (primaryRecord.IsValid) - { - if (IsExtendedPartition(primaryRecord)) - { - newList.AddRange(GetExtendedRecords(primaryRecord)); - } - else - { - newList.Add(primaryRecord); - } - } - } - - return newList.ToArray(); - } - - private BiosPartitionRecord[] GetPrimaryRecords() - { - _diskData.Position = 0; - byte[] bootSector = StreamUtilities.ReadExact(_diskData, Sizes.Sector); - - return ReadPrimaryRecords(bootSector); - } - - private BiosPartitionRecord[] GetExtendedRecords(BiosPartitionRecord r) - { - return new BiosExtendedPartitionTable(_diskData, r.LBAStart).GetPartitions(); - } - - private void WriteRecord(int i, BiosPartitionRecord newRecord) - { - _diskData.Position = 0; - byte[] bootSector = StreamUtilities.ReadExact(_diskData, Sizes.Sector); - newRecord.WriteTo(bootSector, 0x01BE + i * 16); - _diskData.Position = 0; - _diskData.Write(bootSector, 0, bootSector.Length); - } - - private int FindCylinderGap(int numCylinders) - { - List list = Utilities.Filter, BiosPartitionRecord>(GetPrimaryRecords(), - r => r.IsValid); - list.Sort(); - - int startCylinder = 0; - foreach (BiosPartitionRecord r in list) - { - int existingStart = r.StartCylinder; - int existingEnd = r.EndCylinder; - - // LBA can represent bigger disk locations than CHS, so assume the LBA to be definitive in the case where it - // appears the CHS address has been truncated. - if (r.LBAStart > _diskGeometry.ToLogicalBlockAddress(r.StartCylinder, r.StartHead, r.StartSector)) - { - existingStart = _diskGeometry.ToChsAddress((int)r.LBAStart).Cylinder; - } - - if (r.LBAStart + r.LBALength > - _diskGeometry.ToLogicalBlockAddress(r.EndCylinder, r.EndHead, r.EndSector)) - { - existingEnd = _diskGeometry.ToChsAddress((int)(r.LBAStart + r.LBALength)).Cylinder; - } - - if ( - !Utilities.RangesOverlap(startCylinder, startCylinder + numCylinders - 1, existingStart, existingEnd)) - { - break; - } - startCylinder = existingEnd + 1; - } - - return startCylinder; - } - - private long FindGap(long numSectors, long alignmentSectors) - { - List list = Utilities.Filter, BiosPartitionRecord>(GetPrimaryRecords(), - r => r.IsValid); - list.Sort(); - - long startSector = MathUtilities.RoundUp(_diskGeometry.ToLogicalBlockAddress(0, 1, 1), alignmentSectors); - - int idx = 0; - while (idx < list.Count) - { - BiosPartitionRecord entry = list[idx]; - while (idx < list.Count && startSector >= entry.LBAStartAbsolute + entry.LBALength) - { - idx++; - entry = list[idx]; - } - - if (Utilities.RangesOverlap(startSector, startSector + numSectors, entry.LBAStartAbsolute, - entry.LBAStartAbsolute + entry.LBALength)) - { - startSector = MathUtilities.RoundUp(entry.LBAStartAbsolute + entry.LBALength, alignmentSectors); - } - - idx++; - } - - if (_diskGeometry.TotalSectorsLong - startSector < numSectors) - { - throw new IOException(string.Format(CultureInfo.InvariantCulture, - "Unable to find free space of {0} sectors", numSectors)); - } - - return startSector; - } - - private void Init(Stream disk, Geometry diskGeometry) - { - _diskData = disk; - _diskGeometry = diskGeometry; - - _diskData.Position = 0; - byte[] bootSector = StreamUtilities.ReadExact(_diskData, Sizes.Sector); - if (bootSector[510] != 0x55 || bootSector[511] != 0xAA) - { - throw new IOException("Invalid boot sector - no magic number 0xAA55"); - } - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Partitions/BiosPartitionTypes.cs b/src/LibHac.Nand/DiscUtils.Core/Partitions/BiosPartitionTypes.cs deleted file mode 100644 index 114447b5..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Partitions/BiosPartitionTypes.cs +++ /dev/null @@ -1,197 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -namespace DiscUtils.Partitions -{ - /// - /// Convenient access to well-known BIOS (MBR) Partition Types. - /// - public static class BiosPartitionTypes - { - /// - /// Microsoft FAT12 (fewer than 32,680 sectors in the volume). - /// - public const byte Fat12 = 0x01; - - /// - /// Microsoft FAT16 (32,680–65,535 sectors or 16 MB–33 MB). - /// - public const byte Fat16Small = 0x04; - - /// - /// Extended Partition (contains other partitions). - /// - public const byte Extended = 0x05; - - /// - /// Microsoft BIGDOS FAT16 (33 MB–4 GB). - /// - public const byte Fat16 = 0x06; - - /// - /// Installable File System (NTFS). - /// - public const byte Ntfs = 0x07; - - /// - /// Microsoft FAT32. - /// - public const byte Fat32 = 0x0B; - - /// - /// Microsoft FAT32, accessed using Int13h BIOS LBA extensions. - /// - public const byte Fat32Lba = 0x0C; - - /// - /// Microsoft BIGDOS FAT16, accessed using Int13h BIOS LBA extensions. - /// - public const byte Fat16Lba = 0x0E; - - /// - /// Extended Partition (contains other partitions), accessed using Int13h BIOS LBA extensions. - /// - public const byte ExtendedLba = 0x0F; - - /// - /// Windows Logical Disk Manager dynamic volume. - /// - public const byte WindowsDynamicVolume = 0x42; - - /// - /// Linux Swap. - /// - public const byte LinuxSwap = 0x82; - - /// - /// Linux Native (ext2 and friends). - /// - public const byte LinuxNative = 0x83; - - /// - /// Linux Logical Volume Manager (LVM). - /// - public const byte LinuxLvm = 0x8E; - - /// - /// GUID Partition Table (GPT) protective partition, fills entire disk. - /// - public const byte GptProtective = 0xEE; - - /// - /// EFI System partition on an MBR disk. - /// - public const byte EfiSystem = 0xEF; - - /// - /// Provides a string representation of some known BIOS partition types. - /// - /// The partition type to represent as a string. - /// The string representation. - public static string ToString(byte type) - { - switch (type) - { - case 0x00: - return "Unused"; - case 0x01: - return "FAT12"; - case 0x02: - return "XENIX root"; - case 0x03: - return "XENIX /usr"; - case 0x04: - return "FAT16 (<32M)"; - case 0x05: - return "Extended (non-LBA)"; - case 0x06: - return "FAT16 (>32M)"; - case 0x07: - return "IFS (NTFS or HPFS)"; - case 0x0B: - return "FAT32 (non-LBA)"; - case 0x0C: - return "FAT32 (LBA)"; - case 0x0E: - return "FAT16 (LBA)"; - case 0x0F: - return "Extended (LBA)"; - case 0x11: - return "Hidden FAT12"; - case 0x12: - return "Vendor Config/Recovery/Diagnostics"; - case 0x14: - return "Hidden FAT16 (<32M)"; - case 0x16: - return "Hidden FAT16 (>32M)"; - case 0x17: - return "Hidden IFS (NTFS or HPFS)"; - case 0x1B: - return "Hidden FAT32 (non-LBA)"; - case 0x1C: - return "Hidden FAT32 (LBA)"; - case 0x1E: - return "Hidden FAT16 (LBA)"; - case 0x27: - return "Windows Recovery Environment"; - case 0x42: - return "Windows Dynamic Volume"; - case 0x80: - return "Minix v1.1 - v1.4a"; - case 0x81: - return "Minix / Early Linux"; - case 0x82: - return "Linux Swap"; - case 0x83: - return "Linux Native"; - case 0x84: - return "Hibernation"; - case 0x8E: - return "Linux LVM"; - case 0xA0: - return "Laptop Hibernation"; - case 0xA8: - return "Mac OS-X"; - case 0xAB: - return "Mac OS-X Boot"; - case 0xAF: - return "Mac OS-X HFS"; - case 0xC0: - return "NTFT"; - case 0xDE: - return "Dell OEM"; - case 0xEE: - return "GPT Protective"; - case 0xEF: - return "EFI"; - case 0xFB: - return "VMware File System"; - case 0xFC: - return "VMware Swap"; - case 0xFE: - return "IBM OEM"; - default: - return "Unknown"; - } - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Partitions/BiosPartitionedDiskBuilder.cs b/src/LibHac.Nand/DiscUtils.Core/Partitions/BiosPartitionedDiskBuilder.cs deleted file mode 100644 index 23eecbec..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Partitions/BiosPartitionedDiskBuilder.cs +++ /dev/null @@ -1,166 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; -using DiscUtils.Streams; - -namespace DiscUtils.Partitions -{ - /// - /// Builds a stream with the contents of a BIOS partitioned disk. - /// - /// - /// This class assembles a disk image dynamically in memory. The - /// constructed stream will read data from the partition content - /// streams only when a client of this class tries to read from - /// that partition. - /// - public class BiosPartitionedDiskBuilder : StreamBuilder - { - private Geometry _biosGeometry; - private readonly SparseMemoryStream _bootSectors; - private readonly long _capacity; - - private readonly Dictionary _partitionContents; - - /// - /// Initializes a new instance of the BiosPartitionedDiskBuilder class. - /// - /// The capacity of the disk (in bytes). - /// The BIOS geometry of the disk. - public BiosPartitionedDiskBuilder(long capacity, Geometry biosGeometry) - { - _capacity = capacity; - _biosGeometry = biosGeometry; - - _bootSectors = new SparseMemoryStream(); - _bootSectors.SetLength(capacity); - PartitionTable = BiosPartitionTable.Initialize(_bootSectors, _biosGeometry); - - _partitionContents = new Dictionary(); - } - - /// - /// Initializes a new instance of the BiosPartitionedDiskBuilder class. - /// - /// The capacity of the disk (in bytes). - /// The boot sector(s) of the disk. - /// The BIOS geometry of the disk. - [Obsolete("Use the variant that takes VirtualDisk, this method breaks for disks with extended partitions", false - )] - public BiosPartitionedDiskBuilder(long capacity, byte[] bootSectors, Geometry biosGeometry) - { - if (bootSectors == null) - { - throw new ArgumentNullException(nameof(bootSectors)); - } - - _capacity = capacity; - _biosGeometry = biosGeometry; - - _bootSectors = new SparseMemoryStream(); - _bootSectors.SetLength(capacity); - _bootSectors.Write(bootSectors, 0, bootSectors.Length); - PartitionTable = new BiosPartitionTable(_bootSectors, biosGeometry); - - _partitionContents = new Dictionary(); - } - - /// - /// Initializes a new instance of the BiosPartitionedDiskBuilder class by - /// cloning the partition structure of a source disk. - /// - /// The disk to clone. - public BiosPartitionedDiskBuilder(VirtualDisk sourceDisk) - { - if (sourceDisk == null) - { - throw new ArgumentNullException(nameof(sourceDisk)); - } - - _capacity = sourceDisk.Capacity; - _biosGeometry = sourceDisk.BiosGeometry; - - _bootSectors = new SparseMemoryStream(); - _bootSectors.SetLength(_capacity); - - foreach (StreamExtent extent in new BiosPartitionTable(sourceDisk).GetMetadataDiskExtents()) - { - sourceDisk.Content.Position = extent.Start; - byte[] buffer = StreamUtilities.ReadExact(sourceDisk.Content, (int)extent.Length); - _bootSectors.Position = extent.Start; - _bootSectors.Write(buffer, 0, buffer.Length); - } - - PartitionTable = new BiosPartitionTable(_bootSectors, _biosGeometry); - - _partitionContents = new Dictionary(); - } - - /// - /// Gets the partition table in the disk. - /// - public BiosPartitionTable PartitionTable { get; } - - /// - /// Sets a stream representing the content of a partition in the partition table. - /// - /// The index of the partition. - /// The stream with the contents of the partition. - public void SetPartitionContent(int index, SparseStream stream) - { - _partitionContents[index] = new BuilderSparseStreamExtent(PartitionTable[index].FirstSector * Sizes.Sector, - stream); - } - - /// - /// Updates the CHS fields in partition records to reflect a new BIOS geometry. - /// - /// The disk's new BIOS geometry. - /// The partitions are not relocated to a cylinder boundary, just the CHS fields are updated on the - /// assumption the LBA fields are definitive. - public void UpdateBiosGeometry(Geometry geometry) - { - PartitionTable.UpdateBiosGeometry(geometry); - _biosGeometry = geometry; - } - - protected override List FixExtents(out long totalLength) - { - totalLength = _capacity; - - List extents = new List(); - - foreach (StreamExtent extent in PartitionTable.GetMetadataDiskExtents()) - { - _bootSectors.Position = extent.Start; - byte[] buffer = StreamUtilities.ReadExact(_bootSectors, (int)extent.Length); - - extents.Add(new BuilderBufferExtent(extent.Start, buffer)); - } - - extents.AddRange(_partitionContents.Values); - return extents; - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Partitions/DefaultPartitionTableFactory.cs b/src/LibHac.Nand/DiscUtils.Core/Partitions/DefaultPartitionTableFactory.cs deleted file mode 100644 index ae8fb0f5..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Partitions/DefaultPartitionTableFactory.cs +++ /dev/null @@ -1,49 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System.IO; - -namespace DiscUtils.Partitions -{ - [PartitionTableFactory] - internal sealed class DefaultPartitionTableFactory : PartitionTableFactory - { - public override bool DetectIsPartitioned(Stream s) - { - return BiosPartitionTable.IsValid(s); - } - - public override PartitionTable DetectPartitionTable(VirtualDisk disk) - { - if (BiosPartitionTable.IsValid(disk.Content)) - { - BiosPartitionTable table = new BiosPartitionTable(disk); - if (table.Count == 1 && table[0].BiosType == BiosPartitionTypes.GptProtective) - { - return new GuidPartitionTable(disk); - } - return table; - } - return null; - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Partitions/GptEntry.cs b/src/LibHac.Nand/DiscUtils.Core/Partitions/GptEntry.cs deleted file mode 100644 index 918ebb5f..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Partitions/GptEntry.cs +++ /dev/null @@ -1,146 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Text; -using DiscUtils.Streams; - -namespace DiscUtils.Partitions -{ - internal class GptEntry : IComparable - { - public ulong Attributes; - public long FirstUsedLogicalBlock; - public Guid Identity; - public long LastUsedLogicalBlock; - public string Name; - public Guid PartitionType; - - public GptEntry() - { - PartitionType = Guid.Empty; - Identity = Guid.Empty; - Name = string.Empty; - } - - public string FriendlyPartitionType - { - get - { - switch (PartitionType.ToString().ToUpperInvariant()) - { - case "00000000-0000-0000-0000-000000000000": - return "Unused"; - case "024DEE41-33E7-11D3-9D69-0008C781F39F": - return "MBR Partition Scheme"; - case "C12A7328-F81F-11D2-BA4B-00A0C93EC93B": - return "EFI System"; - case "21686148-6449-6E6F-744E-656564454649": - return "BIOS Boot"; - case "E3C9E316-0B5C-4DB8-817D-F92DF00215AE": - return "Microsoft Reserved"; - case "EBD0A0A2-B9E5-4433-87C0-68B6B72699C7": - return "Windows Basic Data"; - case "5808C8AA-7E8F-42E0-85D2-E1E90434CFB3": - return "Windows Logical Disk Manager Metadata"; - case "AF9B60A0-1431-4F62-BC68-3311714A69AD": - return "Windows Logical Disk Manager Data"; - case "75894C1E-3AEB-11D3-B7C1-7B03A0000000": - return "HP-UX Data"; - case "E2A1E728-32E3-11D6-A682-7B03A0000000": - return "HP-UX Service"; - case "A19D880F-05FC-4D3B-A006-743F0F84911E": - return "Linux RAID"; - case "0657FD6D-A4AB-43C4-84E5-0933C84B4F4F": - return "Linux Swap"; - case "E6D6D379-F507-44C2-A23C-238F2A3DF928": - return "Linux Logical Volume Manager"; - case "83BD6B9D-7F41-11DC-BE0B-001560B84F0F": - return "FreeBSD Boot"; - case "516E7CB4-6ECF-11D6-8FF8-00022D09712B": - return "FreeBSD Data"; - case "516E7CB5-6ECF-11D6-8FF8-00022D09712B": - return "FreeBSD Swap"; - case "516E7CB6-6ECF-11D6-8FF8-00022D09712B": - return "FreeBSD Unix File System"; - case "516E7CB8-6ECF-11D6-8FF8-00022D09712B": - return "FreeBSD Vinum volume manager"; - case "516E7CBA-6ECF-11D6-8FF8-00022D09712B": - return "FreeBSD ZFS"; - case "48465300-0000-11AA-AA11-00306543ECAC": - return "Mac OS X HFS+"; - case "55465300-0000-11AA-AA11-00306543ECAC": - return "Mac OS X UFS"; - case "6A898CC3-1DD2-11B2-99A6-080020736631": - return "Mac OS X ZFS"; - case "52414944-0000-11AA-AA11-00306543ECAC": - return "Mac OS X RAID"; - case "52414944-5F4F-11AA-AA11-00306543ECAC": - return "Mac OS X RAID, Offline"; - case "426F6F74-0000-11AA-AA11-00306543ECAC": - return "Mac OS X Boot"; - case "4C616265-6C00-11AA-AA11-00306543ECAC": - return "Mac OS X Label"; - case "49F48D32-B10E-11DC-B99B-0019D1879648": - return "NetBSD Swap"; - case "49F48D5A-B10E-11DC-B99B-0019D1879648": - return "NetBSD Fast File System"; - case "49F48D82-B10E-11DC-B99B-0019D1879648": - return "NetBSD Log-Structed File System"; - case "49F48DAA-B10E-11DC-B99B-0019D1879648": - return "NetBSD RAID"; - case "2DB519C4-B10F-11DC-B99B-0019D1879648": - return "NetBSD Concatenated"; - case "2DB519EC-B10F-11DC-B99B-0019D1879648": - return "NetBSD Encrypted"; - default: - return "Unknown"; - } - } - } - - public int CompareTo(GptEntry other) - { - return FirstUsedLogicalBlock.CompareTo(other.FirstUsedLogicalBlock); - } - - public void ReadFrom(byte[] buffer, int offset) - { - PartitionType = EndianUtilities.ToGuidLittleEndian(buffer, offset + 0); - Identity = EndianUtilities.ToGuidLittleEndian(buffer, offset + 16); - FirstUsedLogicalBlock = EndianUtilities.ToInt64LittleEndian(buffer, offset + 32); - LastUsedLogicalBlock = EndianUtilities.ToInt64LittleEndian(buffer, offset + 40); - Attributes = EndianUtilities.ToUInt64LittleEndian(buffer, offset + 48); - Name = Encoding.Unicode.GetString(buffer, offset + 56, 72).TrimEnd('\0'); - } - - public void WriteTo(byte[] buffer, int offset) - { - EndianUtilities.WriteBytesLittleEndian(PartitionType, buffer, offset + 0); - EndianUtilities.WriteBytesLittleEndian(Identity, buffer, offset + 16); - EndianUtilities.WriteBytesLittleEndian(FirstUsedLogicalBlock, buffer, offset + 32); - EndianUtilities.WriteBytesLittleEndian(LastUsedLogicalBlock, buffer, offset + 40); - EndianUtilities.WriteBytesLittleEndian(Attributes, buffer, offset + 48); - Encoding.Unicode.GetBytes(Name + new string('\0', 36), 0, 36, buffer, offset + 56); - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Partitions/GptHeader.cs b/src/LibHac.Nand/DiscUtils.Core/Partitions/GptHeader.cs deleted file mode 100644 index 2153ba1e..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Partitions/GptHeader.cs +++ /dev/null @@ -1,146 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using DiscUtils.Internal; -using DiscUtils.Streams; - -namespace DiscUtils.Partitions -{ - internal class GptHeader - { - public const string GptSignature = "EFI PART"; - public long AlternateHeaderLba; - - public byte[] Buffer; - public uint Crc; - public Guid DiskGuid; - public uint EntriesCrc; - public long FirstUsable; - public long HeaderLba; - public int HeaderSize; - public long LastUsable; - public long PartitionEntriesLba; - public uint PartitionEntryCount; - public int PartitionEntrySize; - - public string Signature; - public uint Version; - - public GptHeader(int sectorSize) - { - Signature = GptSignature; - Version = 0x00010000; - HeaderSize = 92; - Buffer = new byte[sectorSize]; - } - - public GptHeader(GptHeader toCopy) - { - Signature = toCopy.Signature; - Version = toCopy.Version; - HeaderSize = toCopy.HeaderSize; - Crc = toCopy.Crc; - HeaderLba = toCopy.HeaderLba; - AlternateHeaderLba = toCopy.AlternateHeaderLba; - FirstUsable = toCopy.FirstUsable; - LastUsable = toCopy.LastUsable; - DiskGuid = toCopy.DiskGuid; - PartitionEntriesLba = toCopy.PartitionEntriesLba; - PartitionEntryCount = toCopy.PartitionEntryCount; - PartitionEntrySize = toCopy.PartitionEntrySize; - EntriesCrc = toCopy.EntriesCrc; - - Buffer = new byte[toCopy.Buffer.Length]; - Array.Copy(toCopy.Buffer, Buffer, Buffer.Length); - } - - public bool ReadFrom(byte[] buffer, int offset) - { - Signature = EndianUtilities.BytesToString(buffer, offset + 0, 8); - Version = EndianUtilities.ToUInt32LittleEndian(buffer, offset + 8); - HeaderSize = EndianUtilities.ToInt32LittleEndian(buffer, offset + 12); - Crc = EndianUtilities.ToUInt32LittleEndian(buffer, offset + 16); - HeaderLba = EndianUtilities.ToInt64LittleEndian(buffer, offset + 24); - AlternateHeaderLba = EndianUtilities.ToInt64LittleEndian(buffer, offset + 32); - FirstUsable = EndianUtilities.ToInt64LittleEndian(buffer, offset + 40); - LastUsable = EndianUtilities.ToInt64LittleEndian(buffer, offset + 48); - DiskGuid = EndianUtilities.ToGuidLittleEndian(buffer, offset + 56); - PartitionEntriesLba = EndianUtilities.ToInt64LittleEndian(buffer, offset + 72); - PartitionEntryCount = EndianUtilities.ToUInt32LittleEndian(buffer, offset + 80); - PartitionEntrySize = EndianUtilities.ToInt32LittleEndian(buffer, offset + 84); - EntriesCrc = EndianUtilities.ToUInt32LittleEndian(buffer, offset + 88); - - // In case the header has new fields unknown to us, store the entire header - // as a byte array - Buffer = new byte[HeaderSize]; - Array.Copy(buffer, offset, Buffer, 0, HeaderSize); - - // Reject obviously invalid data - if (Signature != GptSignature || HeaderSize == 0) - { - return false; - } - - return Crc == CalcCrc(buffer, offset, HeaderSize); - } - - public void WriteTo(byte[] buffer, int offset) - { - // First, copy the cached header to allow for unknown fields - Array.Copy(Buffer, 0, buffer, offset, Buffer.Length); - - // Next, write the fields - EndianUtilities.StringToBytes(Signature, buffer, offset + 0, 8); - EndianUtilities.WriteBytesLittleEndian(Version, buffer, offset + 8); - EndianUtilities.WriteBytesLittleEndian(HeaderSize, buffer, offset + 12); - EndianUtilities.WriteBytesLittleEndian((uint)0, buffer, offset + 16); - EndianUtilities.WriteBytesLittleEndian(HeaderLba, buffer, offset + 24); - EndianUtilities.WriteBytesLittleEndian(AlternateHeaderLba, buffer, offset + 32); - EndianUtilities.WriteBytesLittleEndian(FirstUsable, buffer, offset + 40); - EndianUtilities.WriteBytesLittleEndian(LastUsable, buffer, offset + 48); - EndianUtilities.WriteBytesLittleEndian(DiskGuid, buffer, offset + 56); - EndianUtilities.WriteBytesLittleEndian(PartitionEntriesLba, buffer, offset + 72); - EndianUtilities.WriteBytesLittleEndian(PartitionEntryCount, buffer, offset + 80); - EndianUtilities.WriteBytesLittleEndian(PartitionEntrySize, buffer, offset + 84); - EndianUtilities.WriteBytesLittleEndian(EntriesCrc, buffer, offset + 88); - - // Calculate & write the CRC - EndianUtilities.WriteBytesLittleEndian(CalcCrc(buffer, offset, HeaderSize), buffer, offset + 16); - - // Update the cached copy - re-allocate the buffer to allow for HeaderSize potentially having changed - Buffer = new byte[HeaderSize]; - Array.Copy(buffer, offset, Buffer, 0, HeaderSize); - } - - internal static uint CalcCrc(byte[] buffer, int offset, int count) - { - byte[] temp = new byte[count]; - Array.Copy(buffer, offset, temp, 0, count); - - // Reset CRC field - EndianUtilities.WriteBytesLittleEndian((uint)0, temp, 16); - - return Crc32LittleEndian.Compute(Crc32Algorithm.Common, temp, 0, count); - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Partitions/GuidPartitionInfo.cs b/src/LibHac.Nand/DiscUtils.Core/Partitions/GuidPartitionInfo.cs deleted file mode 100644 index 6669fe60..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Partitions/GuidPartitionInfo.cs +++ /dev/null @@ -1,120 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using DiscUtils.Streams; - -namespace DiscUtils.Partitions -{ - /// - /// Provides access to partition records in a GUID partition table. - /// - public sealed class GuidPartitionInfo : PartitionInfo - { - private readonly GptEntry _entry; - private readonly GuidPartitionTable _table; - - internal GuidPartitionInfo(GuidPartitionTable table, GptEntry entry) - { - _table = table; - _entry = entry; - } - - /// - /// Gets the attributes of the partition. - /// - public long Attributes - { - get { return (long)_entry.Attributes; } - } - - /// - /// Always returns Zero. - /// - public override byte BiosType - { - get { return 0; } - } - - /// - /// Gets the first sector of the partion (relative to start of disk) as a Logical Block Address. - /// - public override long FirstSector - { - get { return _entry.FirstUsedLogicalBlock; } - } - - /// - /// Gets the type of the partition, as a GUID. - /// - public override Guid GuidType - { - get { return _entry.PartitionType; } - } - - /// - /// Gets the unique identity of this specific partition. - /// - public Guid Identity - { - get { return _entry.Identity; } - } - - /// - /// Gets the last sector of the partion (relative to start of disk) as a Logical Block Address (inclusive). - /// - public override long LastSector - { - get { return _entry.LastUsedLogicalBlock; } - } - - /// - /// Gets the name of the partition. - /// - public string Name - { - get { return _entry.Name; } - } - - /// - /// Gets the type of the partition as a string. - /// - public override string TypeAsString - { - get { return _entry.FriendlyPartitionType; } - } - - internal override PhysicalVolumeType VolumeType - { - get { return PhysicalVolumeType.GptPartition; } - } - - /// - /// Opens a stream to access the content of the partition. - /// - /// The new stream. - public override SparseStream Open() - { - return _table.Open(_entry); - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Partitions/GuidPartitionTable.cs b/src/LibHac.Nand/DiscUtils.Core/Partitions/GuidPartitionTable.cs deleted file mode 100644 index e8abfb5d..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Partitions/GuidPartitionTable.cs +++ /dev/null @@ -1,657 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Globalization; -using System.IO; -using DiscUtils.Internal; -using DiscUtils.Streams; - -namespace DiscUtils.Partitions -{ - /// - /// Represents a GUID Partition Table. - /// - public sealed class GuidPartitionTable : PartitionTable - { - private Stream _diskData; - private Geometry _diskGeometry; - private byte[] _entryBuffer; - private GptHeader _primaryHeader; - private GptHeader _secondaryHeader; - - /// - /// Initializes a new instance of the GuidPartitionTable class. - /// - /// The disk containing the partition table. - public GuidPartitionTable(VirtualDisk disk) - { - Init(disk.Content, disk.Geometry); - } - - /// - /// Initializes a new instance of the GuidPartitionTable class. - /// - /// The stream containing the disk data. - /// The geometry of the disk. - public GuidPartitionTable(Stream disk, Geometry diskGeometry) - { - Init(disk, diskGeometry); - } - - /// - /// Gets the unique GPT identifier for this disk. - /// - public override Guid DiskGuid - { - get { return _primaryHeader.DiskGuid; } - } - - /// - /// Gets the first sector of the disk available to hold partitions. - /// - public long FirstUsableSector - { - get { return _primaryHeader.FirstUsable; } - } - - /// - /// Gets the last sector of the disk available to hold partitions. - /// - public long LastUsableSector - { - get { return _primaryHeader.LastUsable; } - } - - /// - /// Gets a collection of the partitions for storing Operating System file-systems. - /// - public override ReadOnlyCollection Partitions - { - get - { - return - new ReadOnlyCollection(Utilities.Map(GetAllEntries(), - e => new GuidPartitionInfo(this, e))); - } - } - - /// - /// Creates a new partition table on a disk. - /// - /// The disk to initialize. - /// An object to access the newly created partition table. - public static GuidPartitionTable Initialize(VirtualDisk disk) - { - return Initialize(disk.Content, disk.Geometry); - } - - /// - /// Creates a new partition table on a disk. - /// - /// The stream containing the disk data. - /// The geometry of the disk. - /// An object to access the newly created partition table. - public static GuidPartitionTable Initialize(Stream disk, Geometry diskGeometry) - { - // Create the protective MBR partition record. - BiosPartitionTable pt = BiosPartitionTable.Initialize(disk, diskGeometry); - pt.CreatePrimaryByCylinder(0, diskGeometry.Cylinders - 1, BiosPartitionTypes.GptProtective, false); - - // Create the GPT headers, and blank-out the entry areas - const int EntryCount = 128; - const int EntrySize = 128; - - int entrySectors = (EntryCount * EntrySize + diskGeometry.BytesPerSector - 1) / diskGeometry.BytesPerSector; - - byte[] entriesBuffer = new byte[EntryCount * EntrySize]; - - // Prepare primary header - GptHeader header = new GptHeader(diskGeometry.BytesPerSector); - header.HeaderLba = 1; - header.AlternateHeaderLba = disk.Length / diskGeometry.BytesPerSector - 1; - header.FirstUsable = header.HeaderLba + entrySectors + 1; - header.LastUsable = header.AlternateHeaderLba - entrySectors - 1; - header.DiskGuid = Guid.NewGuid(); - header.PartitionEntriesLba = 2; - header.PartitionEntryCount = EntryCount; - header.PartitionEntrySize = EntrySize; - header.EntriesCrc = CalcEntriesCrc(entriesBuffer); - - // Write the primary header - byte[] headerBuffer = new byte[diskGeometry.BytesPerSector]; - header.WriteTo(headerBuffer, 0); - disk.Position = header.HeaderLba * diskGeometry.BytesPerSector; - disk.Write(headerBuffer, 0, headerBuffer.Length); - - // Calc alternate header - header.HeaderLba = header.AlternateHeaderLba; - header.AlternateHeaderLba = 1; - header.PartitionEntriesLba = header.HeaderLba - entrySectors; - - // Write the alternate header - header.WriteTo(headerBuffer, 0); - disk.Position = header.HeaderLba * diskGeometry.BytesPerSector; - disk.Write(headerBuffer, 0, headerBuffer.Length); - - return new GuidPartitionTable(disk, diskGeometry); - } - - /// - /// Creates a new partition table on a disk containing a single partition. - /// - /// The disk to initialize. - /// The partition type for the single partition. - /// An object to access the newly created partition table. - public static GuidPartitionTable Initialize(VirtualDisk disk, WellKnownPartitionType type) - { - GuidPartitionTable pt = Initialize(disk); - pt.Create(type, true); - return pt; - } - - /// - /// Creates a new partition that encompasses the entire disk. - /// - /// The partition type. - /// Whether the partition is active (bootable). - /// The index of the partition. - /// The partition table must be empty before this method is called, - /// otherwise IOException is thrown. - public override int Create(WellKnownPartitionType type, bool active) - { - List allEntries = new List(GetAllEntries()); - - EstablishReservedPartition(allEntries); - - // Fill the rest of the disk with the requested partition - long start = FirstAvailableSector(allEntries); - long end = FindLastFreeSector(start, allEntries); - - return Create(start, end, GuidPartitionTypes.Convert(type), 0, "Data Partition"); - } - - /// - /// Creates a new primary partition with a target size. - /// - /// The target size (in bytes). - /// The partition type. - /// Whether the partition is active (bootable). - /// The index of the new partition. - public override int Create(long size, WellKnownPartitionType type, bool active) - { - if (size < _diskGeometry.BytesPerSector) - { - throw new ArgumentOutOfRangeException(nameof(size), size, "size must be at least one sector"); - } - - long sectorLength = size / _diskGeometry.BytesPerSector; - long start = FindGap(size / _diskGeometry.BytesPerSector, 1); - - return Create(start, start + sectorLength - 1, GuidPartitionTypes.Convert(type), 0, "Data Partition"); - } - - /// - /// Creates a new aligned partition that encompasses the entire disk. - /// - /// The partition type. - /// Whether the partition is active (bootable). - /// The alignment (in bytes). - /// The index of the partition. - /// The partition table must be empty before this method is called, - /// otherwise IOException is thrown. - /// - /// Traditionally partitions were aligned to the physical structure of the underlying disk, - /// however with modern storage greater efficiency is acheived by aligning partitions on - /// large values that are a power of two. - /// - public override int CreateAligned(WellKnownPartitionType type, bool active, int alignment) - { - if (alignment % _diskGeometry.BytesPerSector != 0) - { - throw new ArgumentException("Alignment is not a multiple of the sector size"); - } - - List allEntries = new List(GetAllEntries()); - - EstablishReservedPartition(allEntries); - - // Fill the rest of the disk with the requested partition - long start = MathUtilities.RoundUp(FirstAvailableSector(allEntries), alignment / _diskGeometry.BytesPerSector); - long end = MathUtilities.RoundDown(FindLastFreeSector(start, allEntries) + 1, - alignment / _diskGeometry.BytesPerSector); - - if (end <= start) - { - throw new IOException("No available space"); - } - - return Create(start, end - 1, GuidPartitionTypes.Convert(type), 0, "Data Partition"); - } - - /// - /// Creates a new aligned partition with a target size. - /// - /// The target size (in bytes). - /// The partition type. - /// Whether the partition is active (bootable). - /// The alignment (in bytes). - /// The index of the new partition. - /// - /// Traditionally partitions were aligned to the physical structure of the underlying disk, - /// however with modern storage greater efficiency is achieved by aligning partitions on - /// large values that are a power of two. - /// - public override int CreateAligned(long size, WellKnownPartitionType type, bool active, int alignment) - { - if (size < _diskGeometry.BytesPerSector) - { - throw new ArgumentOutOfRangeException(nameof(size), size, "size must be at least one sector"); - } - - if (alignment % _diskGeometry.BytesPerSector != 0) - { - throw new ArgumentException("Alignment is not a multiple of the sector size"); - } - - if (size % alignment != 0) - { - throw new ArgumentException("Size is not a multiple of the alignment"); - } - - long sectorLength = size / _diskGeometry.BytesPerSector; - long start = FindGap(size / _diskGeometry.BytesPerSector, alignment / _diskGeometry.BytesPerSector); - - return Create(start, start + sectorLength - 1, GuidPartitionTypes.Convert(type), 0, "Data Partition"); - } - - /// - /// Creates a new GUID partition on the disk. - /// - /// The first sector of the partition. - /// The last sector of the partition. - /// The partition type. - /// The partition attributes. - /// The name of the partition. - /// The index of the new partition. - /// No checking is performed on the parameters, the caller is - /// responsible for ensuring that the partition does not overlap other partitions. - public int Create(long startSector, long endSector, Guid type, long attributes, string name) - { - GptEntry newEntry = CreateEntry(startSector, endSector, type, attributes, name); - return GetEntryIndex(newEntry.Identity); - } - - /// - /// Deletes a partition at a given index. - /// - /// The index of the partition. - public override void Delete(int index) - { - int offset = GetPartitionOffset(index); - Array.Clear(_entryBuffer, offset, _primaryHeader.PartitionEntrySize); - Write(); - } - - internal SparseStream Open(GptEntry entry) - { - long start = entry.FirstUsedLogicalBlock * _diskGeometry.BytesPerSector; - long end = (entry.LastUsedLogicalBlock + 1) * _diskGeometry.BytesPerSector; - return new SubStream(_diskData, start, end - start); - } - - private static uint CalcEntriesCrc(byte[] buffer) - { - return Crc32LittleEndian.Compute(Crc32Algorithm.Common, buffer, 0, buffer.Length); - } - - private static int CountEntries(ICollection values, Func pred) - { - int count = 0; - - foreach (T val in values) - { - if (pred(val)) - { - ++count; - } - } - - return count; - } - - private void Init(Stream disk, Geometry diskGeometry) - { - BiosPartitionTable bpt; - try - { - bpt = new BiosPartitionTable(disk, diskGeometry); - } - catch (IOException ioe) - { - throw new IOException("Invalid GPT disk, protective MBR table not present or invalid", ioe); - } - - if (bpt.Count != 1 || bpt[0].BiosType != BiosPartitionTypes.GptProtective) - { - throw new IOException("Invalid GPT disk, protective MBR table is not valid"); - } - - _diskData = disk; - _diskGeometry = diskGeometry; - - disk.Position = diskGeometry.BytesPerSector; - byte[] sector = StreamUtilities.ReadExact(disk, diskGeometry.BytesPerSector); - - _primaryHeader = new GptHeader(diskGeometry.BytesPerSector); - if (!_primaryHeader.ReadFrom(sector, 0) || !ReadEntries(_primaryHeader)) - { - disk.Position = disk.Length - diskGeometry.BytesPerSector; - disk.Read(sector, 0, sector.Length); - _secondaryHeader = new GptHeader(diskGeometry.BytesPerSector); - if (!_secondaryHeader.ReadFrom(sector, 0) || !ReadEntries(_secondaryHeader)) - { - throw new IOException("No valid GUID Partition Table found"); - } - - // Generate from the primary table from the secondary one - _primaryHeader = new GptHeader(_secondaryHeader); - _primaryHeader.HeaderLba = _secondaryHeader.AlternateHeaderLba; - _primaryHeader.AlternateHeaderLba = _secondaryHeader.HeaderLba; - _primaryHeader.PartitionEntriesLba = 2; - - // If the disk is writeable, fix up the primary partition table based on the - // (valid) secondary table. - if (disk.CanWrite) - { - WritePrimaryHeader(); - } - } - - if (_secondaryHeader == null) - { - _secondaryHeader = new GptHeader(diskGeometry.BytesPerSector); - disk.Position = disk.Length - diskGeometry.BytesPerSector; - disk.Read(sector, 0, sector.Length); - if (!_secondaryHeader.ReadFrom(sector, 0) || !ReadEntries(_secondaryHeader)) - { - // Generate from the secondary table from the primary one - _secondaryHeader = new GptHeader(_primaryHeader); - _secondaryHeader.HeaderLba = _secondaryHeader.AlternateHeaderLba; - _secondaryHeader.AlternateHeaderLba = _secondaryHeader.HeaderLba; - _secondaryHeader.PartitionEntriesLba = _secondaryHeader.HeaderLba - - MathUtilities.RoundUp( - _secondaryHeader.PartitionEntryCount * - _secondaryHeader.PartitionEntrySize, - diskGeometry.BytesPerSector); - - // If the disk is writeable, fix up the secondary partition table based on the - // (valid) primary table. - if (disk.CanWrite) - { - WriteSecondaryHeader(); - } - } - } - } - - private void EstablishReservedPartition(List allEntries) - { - // If no MicrosoftReserved partition, and no Microsoft Data partitions, and the disk - // has a 'reasonable' size free, create a Microsoft Reserved partition. - if (CountEntries(allEntries, e => e.PartitionType == GuidPartitionTypes.MicrosoftReserved) == 0 - && CountEntries(allEntries, e => e.PartitionType == GuidPartitionTypes.WindowsBasicData) == 0 - && _diskGeometry.Capacity > 512 * 1024 * 1024) - { - long reservedStart = FirstAvailableSector(allEntries); - long reservedEnd = FindLastFreeSector(reservedStart, allEntries); - - if ((reservedEnd - reservedStart + 1) * _diskGeometry.BytesPerSector > 512 * 1024 * 1024) - { - long size = (_diskGeometry.Capacity < 16 * 1024L * 1024 * 1024 ? 32 : 128) * 1024 * 1024; - reservedEnd = reservedStart + size / _diskGeometry.BytesPerSector - 1; - - int reservedOffset = GetFreeEntryOffset(); - GptEntry newReservedEntry = new GptEntry(); - newReservedEntry.PartitionType = GuidPartitionTypes.MicrosoftReserved; - newReservedEntry.Identity = Guid.NewGuid(); - newReservedEntry.FirstUsedLogicalBlock = reservedStart; - newReservedEntry.LastUsedLogicalBlock = reservedEnd; - newReservedEntry.Attributes = 0; - newReservedEntry.Name = "Microsoft reserved partition"; - newReservedEntry.WriteTo(_entryBuffer, reservedOffset); - allEntries.Add(newReservedEntry); - } - } - } - - private GptEntry CreateEntry(long startSector, long endSector, Guid type, long attributes, string name) - { - if (endSector < startSector) - { - throw new ArgumentException("The end sector is before the start sector"); - } - - int offset = GetFreeEntryOffset(); - GptEntry newEntry = new GptEntry(); - newEntry.PartitionType = type; - newEntry.Identity = Guid.NewGuid(); - newEntry.FirstUsedLogicalBlock = startSector; - newEntry.LastUsedLogicalBlock = endSector; - newEntry.Attributes = (ulong)attributes; - newEntry.Name = name; - newEntry.WriteTo(_entryBuffer, offset); - - // Commit changes to disk - Write(); - - return newEntry; - } - - private long FindGap(long numSectors, long alignmentSectors) - { - List list = new List(GetAllEntries()); - list.Sort(); - - long startSector = MathUtilities.RoundUp(_primaryHeader.FirstUsable, alignmentSectors); - foreach (GptEntry entry in list) - { - if ( - !Utilities.RangesOverlap(startSector, startSector + numSectors - 1, entry.FirstUsedLogicalBlock, - entry.LastUsedLogicalBlock)) - { - break; - } - startSector = MathUtilities.RoundUp(entry.LastUsedLogicalBlock + 1, alignmentSectors); - } - - if (_diskGeometry.TotalSectorsLong - startSector < numSectors) - { - throw new IOException(string.Format(CultureInfo.InvariantCulture, - "Unable to find free space of {0} sectors", numSectors)); - } - - return startSector; - } - - private long FirstAvailableSector(List allEntries) - { - long start = _primaryHeader.FirstUsable; - - foreach (GptEntry entry in allEntries) - { - if (entry.LastUsedLogicalBlock >= start) - { - start = entry.LastUsedLogicalBlock + 1; - } - } - - return start; - } - - private long FindLastFreeSector(long start, List allEntries) - { - long end = _primaryHeader.LastUsable; - - foreach (GptEntry entry in allEntries) - { - if (entry.LastUsedLogicalBlock > start && entry.FirstUsedLogicalBlock <= end) - { - end = entry.FirstUsedLogicalBlock - 1; - } - } - - return end; - } - - private void Write() - { - WritePrimaryHeader(); - WriteSecondaryHeader(); - } - - private void WritePrimaryHeader() - { - byte[] buffer = new byte[_diskGeometry.BytesPerSector]; - _primaryHeader.EntriesCrc = CalcEntriesCrc(); - _primaryHeader.WriteTo(buffer, 0); - _diskData.Position = _diskGeometry.BytesPerSector; - _diskData.Write(buffer, 0, buffer.Length); - - _diskData.Position = 2 * _diskGeometry.BytesPerSector; - _diskData.Write(_entryBuffer, 0, _entryBuffer.Length); - } - - private void WriteSecondaryHeader() - { - byte[] buffer = new byte[_diskGeometry.BytesPerSector]; - _secondaryHeader.EntriesCrc = CalcEntriesCrc(); - _secondaryHeader.WriteTo(buffer, 0); - _diskData.Position = _diskData.Length - _diskGeometry.BytesPerSector; - _diskData.Write(buffer, 0, buffer.Length); - - _diskData.Position = _secondaryHeader.PartitionEntriesLba * _diskGeometry.BytesPerSector; - _diskData.Write(_entryBuffer, 0, _entryBuffer.Length); - } - - private bool ReadEntries(GptHeader header) - { - _diskData.Position = header.PartitionEntriesLba * _diskGeometry.BytesPerSector; - _entryBuffer = StreamUtilities.ReadExact(_diskData, (int)(header.PartitionEntrySize * header.PartitionEntryCount)); - if (header.EntriesCrc != CalcEntriesCrc()) - { - return false; - } - - return true; - } - - private uint CalcEntriesCrc() - { - return Crc32LittleEndian.Compute(Crc32Algorithm.Common, _entryBuffer, 0, _entryBuffer.Length); - } - - private IEnumerable GetAllEntries() - { - for (int i = 0; i < _primaryHeader.PartitionEntryCount; ++i) - { - GptEntry entry = new GptEntry(); - entry.ReadFrom(_entryBuffer, i * _primaryHeader.PartitionEntrySize); - if (entry.PartitionType != Guid.Empty) - { - yield return entry; - } - } - } - - private int GetPartitionOffset(int index) - { - bool found = false; - int entriesSoFar = 0; - int position = 0; - - while (!found && position < _primaryHeader.PartitionEntryCount) - { - GptEntry entry = new GptEntry(); - entry.ReadFrom(_entryBuffer, position * _primaryHeader.PartitionEntrySize); - if (entry.PartitionType != Guid.Empty) - { - if (index == entriesSoFar) - { - found = true; - break; - } - - entriesSoFar++; - } - - position++; - } - - if (found) - { - return position * _primaryHeader.PartitionEntrySize; - } - throw new IOException(string.Format(CultureInfo.InvariantCulture, "No such partition: {0}", index)); - } - - private int GetEntryIndex(Guid identity) - { - int index = 0; - - for (int i = 0; i < _primaryHeader.PartitionEntryCount; ++i) - { - GptEntry entry = new GptEntry(); - entry.ReadFrom(_entryBuffer, i * _primaryHeader.PartitionEntrySize); - - if (entry.Identity == identity) - { - return index; - } - if (entry.PartitionType != Guid.Empty) - { - index++; - } - } - - throw new IOException("No such partition"); - } - - private int GetFreeEntryOffset() - { - for (int i = 0; i < _primaryHeader.PartitionEntryCount; ++i) - { - GptEntry entry = new GptEntry(); - entry.ReadFrom(_entryBuffer, i * _primaryHeader.PartitionEntrySize); - - if (entry.PartitionType == Guid.Empty) - { - return i * _primaryHeader.PartitionEntrySize; - } - } - - throw new IOException("No free partition entries available"); - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Partitions/GuidPartitionTypes.cs b/src/LibHac.Nand/DiscUtils.Core/Partitions/GuidPartitionTypes.cs deleted file mode 100644 index d368c995..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Partitions/GuidPartitionTypes.cs +++ /dev/null @@ -1,94 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; - -namespace DiscUtils.Partitions -{ - /// - /// Convenient access to well known GPT partition types. - /// - public static class GuidPartitionTypes - { - /// - /// EFI system partition. - /// - public static readonly Guid EfiSystem = new Guid("C12A7328-F81F-11D2-BA4B-00A0C93EC93B"); - - /// - /// BIOS boot partition. - /// - public static readonly Guid BiosBoot = new Guid("21686148-6449-6E6F-744E-656564454649"); - - /// - /// Microsoft reserved partition. - /// - public static readonly Guid MicrosoftReserved = new Guid("E3C9E316-0B5C-4DB8-817D-F92DF00215AE"); - - /// - /// Windows basic data partition. - /// - public static readonly Guid WindowsBasicData = new Guid("EBD0A0A2-B9E5-4433-87C0-68B6B72699C7"); - - /// - /// Linux LVM partition. - /// - public static readonly Guid LinuxLvm = new Guid("E6D6D379-F507-44C2-A23C-238F2A3DF928"); - - /// - /// Linux swap partition. - /// - public static readonly Guid LinuxSwap = new Guid("0657FD6D-A4AB-43C4-84E5-0933C84B4F4F"); - - /// - /// Windows Logical Disk Manager metadata. - /// - public static readonly Guid WindowsLdmMetadata = new Guid("5808C8AA-7E8F-42E0-85D2-E1E90434CFB3"); - - /// - /// Windows Logical Disk Manager data. - /// - public static readonly Guid WindowsLdmData = new Guid("AF9B60A0-1431-4F62-BC68-3311714A69AD"); - - /// - /// Converts a well known partition type to a Guid. - /// - /// The value to convert. - /// The GUID value. - internal static Guid Convert(WellKnownPartitionType wellKnown) - { - switch (wellKnown) - { - case WellKnownPartitionType.Linux: - case WellKnownPartitionType.WindowsFat: - case WellKnownPartitionType.WindowsNtfs: - return WindowsBasicData; - case WellKnownPartitionType.LinuxLvm: - return LinuxLvm; - case WellKnownPartitionType.LinuxSwap: - return LinuxSwap; - default: - throw new ArgumentException("Unknown partition type"); - } - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Partitions/PartitionInfo.cs b/src/LibHac.Nand/DiscUtils.Core/Partitions/PartitionInfo.cs deleted file mode 100644 index 856d1aa0..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Partitions/PartitionInfo.cs +++ /dev/null @@ -1,93 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Globalization; -using DiscUtils.Streams; - -namespace DiscUtils.Partitions -{ - /// - /// Base class representing a disk partition. - /// - /// The purpose of this class is to provide a minimal view of a partition, - /// such that callers can access existing partitions without specific knowledge of - /// the partitioning system. - public abstract class PartitionInfo - { - /// - /// Gets the type of the partition, in legacy BIOS form, when available. - /// - /// Zero for GUID-style partitions. - public abstract byte BiosType { get; } - - /// - /// Gets the first sector of the partion (relative to start of disk) as a Logical Block Address. - /// - public abstract long FirstSector { get; } - - /// - /// Gets the type of the partition, as a GUID, when available. - /// - /// .Empty for MBR-style partitions. - public abstract Guid GuidType { get; } - - /// - /// Gets the last sector of the partion (relative to start of disk) as a Logical Block Address (inclusive). - /// - public abstract long LastSector { get; } - - /// - /// Gets the length of the partition in sectors. - /// - public virtual long SectorCount - { - get { return 1 + LastSector - FirstSector; } - } - - /// - /// Gets the partition type as a 'friendly' string. - /// - public abstract string TypeAsString { get; } - - /// - /// Gets the physical volume type for this type of partition. - /// - internal abstract PhysicalVolumeType VolumeType { get; } - - /// - /// Opens a stream that accesses the partition's contents. - /// - /// The new stream. - public abstract SparseStream Open(); - - /// - /// Gets a summary of the partition information as 'first - last (type)'. - /// - /// A string representation of the partition information. - public override string ToString() - { - return string.Format(CultureInfo.InvariantCulture, "0x{0:X} - 0x{1:X} ({2})", FirstSector, LastSector, - TypeAsString); - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Partitions/PartitionTable.cs b/src/LibHac.Nand/DiscUtils.Core/Partitions/PartitionTable.cs deleted file mode 100644 index a9b035ab..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Partitions/PartitionTable.cs +++ /dev/null @@ -1,211 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.IO; -using DiscUtils.CoreCompat; -using DiscUtils.Raw; -using DiscUtils.Streams; - -namespace DiscUtils.Partitions -{ - /// - /// Base class for classes which represent a disk partitioning scheme. - /// - /// After modifying the table, by creating or deleting a partition assume that any - /// previously stored partition indexes of higher value are no longer valid. Re-enumerate - /// the partitions to discover the next index-to-partition mapping. - public abstract class PartitionTable - { - private static List _factories; - - /// - /// Gets the number of User partitions on the disk. - /// - public int Count - { - get { return Partitions.Count; } - } - - /// - /// Gets the GUID that uniquely identifies this disk, if supported (else returns null). - /// - public abstract Guid DiskGuid { get; } - - private static List Factories - { - get - { - if (_factories == null) - { - List factories = new List(); - - foreach (Type type in ReflectionHelper.GetAssembly(typeof(VolumeManager)).GetTypes()) - { - foreach (PartitionTableFactoryAttribute attr in ReflectionHelper.GetCustomAttributes(type, typeof(PartitionTableFactoryAttribute), false)) - { - factories.Add((PartitionTableFactory)Activator.CreateInstance(type)); - } - } - - _factories = factories; - } - - return _factories; - } - } - - /// - /// Gets information about a particular User partition. - /// - /// The index of the partition. - /// Information about the partition. - public PartitionInfo this[int index] - { - get { return Partitions[index]; } - } - - /// - /// Gets the list of partitions that contain user data (i.e. non-system / empty). - /// - public abstract ReadOnlyCollection Partitions { get; } - - /// - /// Determines if a disk is partitioned with a known partitioning scheme. - /// - /// The content of the disk to check. - /// true if the disk is partitioned, else false. - public static bool IsPartitioned(Stream content) - { - foreach (PartitionTableFactory partTableFactory in Factories) - { - if (partTableFactory.DetectIsPartitioned(content)) - { - return true; - } - } - - return false; - } - - /// - /// Determines if a disk is partitioned with a known partitioning scheme. - /// - /// The disk to check. - /// true if the disk is partitioned, else false. - public static bool IsPartitioned(VirtualDisk disk) - { - return IsPartitioned(disk.Content); - } - - /// - /// Gets all of the partition tables found on a disk. - /// - /// The disk to inspect. - /// It is rare for a disk to have multiple partition tables, but theoretically - /// possible. - public static IList GetPartitionTables(VirtualDisk disk) - { - List tables = new List(); - - foreach (PartitionTableFactory factory in Factories) - { - PartitionTable table = factory.DetectPartitionTable(disk); - if (table != null) - { - tables.Add(table); - } - } - - return tables; - } - - /// - /// Gets all of the partition tables found on a disk. - /// - /// The content of the disk to inspect. - /// It is rare for a disk to have multiple partition tables, but theoretically - /// possible. - public static IList GetPartitionTables(Stream contentStream) - { - return GetPartitionTables(new Disk(contentStream, Ownership.None)); - } - - /// - /// Creates a new partition that encompasses the entire disk. - /// - /// The partition type. - /// Whether the partition is active (bootable). - /// The index of the partition. - /// The partition table must be empty before this method is called, - /// otherwise IOException is thrown. - public abstract int Create(WellKnownPartitionType type, bool active); - - /// - /// Creates a new partition with a target size. - /// - /// The target size (in bytes). - /// The partition type. - /// Whether the partition is active (bootable). - /// The index of the new partition. - public abstract int Create(long size, WellKnownPartitionType type, bool active); - - /// - /// Creates a new aligned partition that encompasses the entire disk. - /// - /// The partition type. - /// Whether the partition is active (bootable). - /// The alignment (in byte). - /// The index of the partition. - /// The partition table must be empty before this method is called, - /// otherwise IOException is thrown. - /// - /// Traditionally partitions were aligned to the physical structure of the underlying disk, - /// however with modern storage greater efficiency is acheived by aligning partitions on - /// large values that are a power of two. - /// - public abstract int CreateAligned(WellKnownPartitionType type, bool active, int alignment); - - /// - /// Creates a new aligned partition with a target size. - /// - /// The target size (in bytes). - /// The partition type. - /// Whether the partition is active (bootable). - /// The alignment (in byte). - /// The index of the new partition. - /// - /// Traditionally partitions were aligned to the physical structure of the underlying disk, - /// however with modern storage greater efficiency is achieved by aligning partitions on - /// large values that are a power of two. - /// - public abstract int CreateAligned(long size, WellKnownPartitionType type, bool active, int alignment); - - /// - /// Deletes a partition at a given index. - /// - /// The index of the partition. - public abstract void Delete(int index); - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Partitions/PartitionTableFactory.cs b/src/LibHac.Nand/DiscUtils.Core/Partitions/PartitionTableFactory.cs deleted file mode 100644 index 164b6a3e..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Partitions/PartitionTableFactory.cs +++ /dev/null @@ -1,33 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System.IO; - -namespace DiscUtils.Partitions -{ - internal abstract class PartitionTableFactory - { - public abstract bool DetectIsPartitioned(Stream s); - - public abstract PartitionTable DetectPartitionTable(VirtualDisk disk); - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Partitions/PartitionTableFactoryAttribute.cs b/src/LibHac.Nand/DiscUtils.Core/Partitions/PartitionTableFactoryAttribute.cs deleted file mode 100644 index e199c04e..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Partitions/PartitionTableFactoryAttribute.cs +++ /dev/null @@ -1,29 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; - -namespace DiscUtils.Partitions -{ - [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] - internal sealed class PartitionTableFactoryAttribute : Attribute {} -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Partitions/WellKnownPartitionType.cs b/src/LibHac.Nand/DiscUtils.Core/Partitions/WellKnownPartitionType.cs deleted file mode 100644 index 45a424e4..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Partitions/WellKnownPartitionType.cs +++ /dev/null @@ -1,55 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -namespace DiscUtils.Partitions -{ - /// - /// Enumeration of partition-table technology neutral partition types. - /// - public enum WellKnownPartitionType - { - /// - /// Windows FAT-based partition. - /// - WindowsFat = 0, - - /// - /// Windows NTFS-based partition. - /// - WindowsNtfs = 1, - - /// - /// Linux native file system. - /// - Linux = 2, - - /// - /// Linux swap. - /// - LinuxSwap = 3, - - /// - /// Linux Logical Volume Manager (LVM). - /// - LinuxLvm = 4 - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/PhysicalVolumeInfo.cs b/src/LibHac.Nand/DiscUtils.Core/PhysicalVolumeInfo.cs deleted file mode 100644 index 2b78fb00..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/PhysicalVolumeInfo.cs +++ /dev/null @@ -1,202 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Globalization; -using DiscUtils.Partitions; -using DiscUtils.Streams; - -namespace DiscUtils -{ - /// - /// Information about a physical disk volume, which may be a partition or an entire disk. - /// - public sealed class PhysicalVolumeInfo : VolumeInfo - { - private readonly VirtualDisk _disk; - private readonly string _diskId; - private readonly SparseStreamOpenDelegate _streamOpener; - - /// - /// Initializes a new instance of the PhysicalVolumeInfo class. - /// - /// The containing disk's identity. - /// The disk containing the partition. - /// Information about the partition. - /// Use this constructor to represent a (BIOS or GPT) partition. - internal PhysicalVolumeInfo( - string diskId, - VirtualDisk disk, - PartitionInfo partitionInfo) - { - _diskId = diskId; - _disk = disk; - _streamOpener = partitionInfo.Open; - VolumeType = partitionInfo.VolumeType; - Partition = partitionInfo; - } - - /// - /// Initializes a new instance of the PhysicalVolumeInfo class. - /// - /// The identity of the disk. - /// The disk itself. - /// Use this constructor to represent an entire disk as a single volume. - internal PhysicalVolumeInfo( - string diskId, - VirtualDisk disk) - { - _diskId = diskId; - _disk = disk; - _streamOpener = delegate { return new SubStream(disk.Content, Ownership.None, 0, disk.Capacity); }; - VolumeType = PhysicalVolumeType.EntireDisk; - } - - /// - /// Gets the disk geometry of the underlying storage medium (as used in BIOS calls), may be null. - /// - public override Geometry BiosGeometry - { - get { return _disk.BiosGeometry; } - } - - /// - /// Gets the one-byte BIOS type for this volume, which indicates the content. - /// - public override byte BiosType - { - get { return Partition == null ? (byte)0 : Partition.BiosType; } - } - - /// - /// Gets the unique identity of the disk containing the volume, if known. - /// - public Guid DiskIdentity - { - get { return VolumeType != PhysicalVolumeType.EntireDisk ? _disk.Partitions.DiskGuid : Guid.Empty; } - } - - /// - /// Gets the signature of the disk containing the volume (only valid for partition-type volumes). - /// - public int DiskSignature - { - get { return VolumeType != PhysicalVolumeType.EntireDisk ? _disk.Signature : 0; } - } - - /// - /// Gets the stable identity for this physical volume. - /// - /// The stability of the identity depends the disk structure. - /// In some cases the identity may include a simple index, when no other information - /// is available. Best practice is to add disks to the Volume Manager in a stable - /// order, if the stability of this identity is paramount. - public override string Identity - { - get - { - if (VolumeType == PhysicalVolumeType.GptPartition) - { - return "VPG" + PartitionIdentity.ToString("B"); - } - string partId; - switch (VolumeType) - { - case PhysicalVolumeType.EntireDisk: - partId = "PD"; - break; - case PhysicalVolumeType.BiosPartition: - case PhysicalVolumeType.ApplePartition: - partId = "PO" + - (Partition.FirstSector * _disk.SectorSize).ToString("X", - CultureInfo.InvariantCulture); - break; - default: - partId = "P*"; - break; - } - - return "VPD:" + _diskId + ":" + partId; - } - } - - /// - /// Gets the size of the volume, in bytes. - /// - public override long Length - { - get { return Partition == null ? _disk.Capacity : Partition.SectorCount * _disk.SectorSize; } - } - - /// - /// Gets the underlying partition (if any). - /// - public PartitionInfo Partition { get; } - - /// - /// Gets the unique identity of the physical partition, if known. - /// - public Guid PartitionIdentity - { - get - { - GuidPartitionInfo gpi = Partition as GuidPartitionInfo; - if (gpi != null) - { - return gpi.Identity; - } - - return Guid.Empty; - } - } - - /// - /// Gets the disk geometry of the underlying storage medium, if any (may be null). - /// - public override Geometry PhysicalGeometry - { - get { return _disk.Geometry; } - } - - /// - /// Gets the offset of this volume in the underlying storage medium, if any (may be Zero). - /// - public override long PhysicalStartSector - { - get { return VolumeType == PhysicalVolumeType.EntireDisk ? 0 : Partition.FirstSector; } - } - - /// - /// Gets the type of the volume. - /// - public PhysicalVolumeType VolumeType { get; } - - /// - /// Opens the volume, providing access to its contents. - /// - /// A stream that can be used to access the volume. - public override SparseStream Open() - { - return _streamOpener(); - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/PhysicalVolumeType.cs b/src/LibHac.Nand/DiscUtils.Core/PhysicalVolumeType.cs deleted file mode 100644 index 791c9cef..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/PhysicalVolumeType.cs +++ /dev/null @@ -1,33 +0,0 @@ -namespace DiscUtils -{ - /// - /// Enumeration of possible types of physical volume. - /// - public enum PhysicalVolumeType - { - /// - /// Unknown type. - /// - None, - - /// - /// Physical volume encompasses the entire disk. - /// - EntireDisk, - - /// - /// Physical volume is defined by a BIOS-style partition table. - /// - BiosPartition, - - /// - /// Physical volume is defined by a GUID partition table. - /// - GptPartition, - - /// - /// Physical volume is defined by an Apple partition map. - /// - ApplePartition - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Plist.cs b/src/LibHac.Nand/DiscUtils.Core/Plist.cs deleted file mode 100644 index e86c3e14..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Plist.cs +++ /dev/null @@ -1,208 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; -using System.Globalization; -using System.IO; -using System.Text; -using System.Xml; - -namespace DiscUtils -{ - internal static class Plist - { - internal static Dictionary Parse(Stream stream) - { - XmlDocument xmlDoc = new XmlDocument(); -#if !NETCORE - xmlDoc.XmlResolver = null; -#endif - - XmlReaderSettings settings = new XmlReaderSettings(); -#if !NET20 - // DTD processing is disabled on anything but .NET 2.0, so this must be set to - // Ignore. - // See https://msdn.microsoft.com/en-us/magazine/ee335713.aspx for additional information. - settings.DtdProcessing = DtdProcessing.Ignore; -#endif - - using (XmlReader reader = XmlReader.Create(stream, settings)) - { - xmlDoc.Load(reader); - } - - XmlElement root = xmlDoc.DocumentElement; - if (root.Name != "plist") - { - throw new InvalidDataException("XML document is not a plist"); - } - - return ParseDictionary(root.FirstChild); - } - - internal static void Write(Stream stream, Dictionary plist) - { - XmlDocument xmlDoc = new XmlDocument(); -#if !NETCORE - xmlDoc.XmlResolver = null; -#endif - - XmlDeclaration xmlDecl = xmlDoc.CreateXmlDeclaration("1.0", "UTF-8", null); - xmlDoc.AppendChild(xmlDecl); - -#if !NETCORE - XmlDocumentType xmlDocType = xmlDoc.CreateDocumentType("plist", "-//Apple//DTD PLIST 1.0//EN", "http://www.apple.com/DTDs/PropertyList-1.0.dtd", null); - xmlDoc.AppendChild(xmlDocType); -#endif - - XmlElement rootElement = xmlDoc.CreateElement("plist"); - rootElement.SetAttribute("Version", "1.0"); - xmlDoc.AppendChild(rootElement); - - xmlDoc.DocumentElement.SetAttribute("Version", "1.0"); - - rootElement.AppendChild(CreateNode(xmlDoc, plist)); - - XmlWriterSettings settings = new XmlWriterSettings(); - settings.Indent = true; - settings.Encoding = Encoding.UTF8; - - using (XmlWriter xw = XmlWriter.Create(stream, settings)) - { - xmlDoc.Save(xw); - } - } - - private static object ParseNode(XmlNode xmlNode) - { - switch (xmlNode.Name) - { - case "dict": - return ParseDictionary(xmlNode); - case "array": - return ParseArray(xmlNode); - case "string": - return ParseString(xmlNode); - case "data": - return ParseData(xmlNode); - case "integer": - return ParseInteger(xmlNode); - case "true": - return true; - case "false": - return false; - default: - throw new NotImplementedException(); - } - } - - private static XmlNode CreateNode(XmlDocument xmlDoc, object obj) - { - if (obj is Dictionary) - { - return CreateDictionary(xmlDoc, (Dictionary)obj); - } - if (obj is string) - { - XmlText text = xmlDoc.CreateTextNode((string)obj); - XmlElement node = xmlDoc.CreateElement("string"); - node.AppendChild(text); - return node; - } - throw new NotImplementedException(); - } - - private static XmlNode CreateDictionary(XmlDocument xmlDoc, Dictionary dict) - { - XmlElement dictNode = xmlDoc.CreateElement("dict"); - - foreach (KeyValuePair entry in dict) - { - XmlText text = xmlDoc.CreateTextNode(entry.Key); - XmlElement keyNode = xmlDoc.CreateElement("key"); - keyNode.AppendChild(text); - - dictNode.AppendChild(keyNode); - - XmlNode valueNode = CreateNode(xmlDoc, entry.Value); - dictNode.AppendChild(valueNode); - } - - return dictNode; - } - - private static Dictionary ParseDictionary(XmlNode xmlNode) - { - Dictionary result = new Dictionary(); - - XmlNode focusNode = xmlNode.FirstChild; - while (focusNode != null) - { - if (focusNode.Name != "key") - { - throw new InvalidDataException("Invalid plist, expected dictionary key"); - } - - string key = focusNode.InnerText; - - focusNode = focusNode.NextSibling; - - result.Add(key, ParseNode(focusNode)); - - focusNode = focusNode.NextSibling; - } - - return result; - } - - private static object ParseArray(XmlNode xmlNode) - { - List result = new List(); - - XmlNode focusNode = xmlNode.FirstChild; - while (focusNode != null) - { - result.Add(ParseNode(focusNode)); - focusNode = focusNode.NextSibling; - } - - return result; - } - - private static object ParseString(XmlNode xmlNode) - { - return xmlNode.InnerText; - } - - private static object ParseData(XmlNode xmlNode) - { - string base64 = xmlNode.InnerText; - return Convert.FromBase64String(base64); - } - - private static object ParseInteger(XmlNode xmlNode) - { - return int.Parse(xmlNode.InnerText, CultureInfo.InvariantCulture); - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Raw/Disk.cs b/src/LibHac.Nand/DiscUtils.Core/Raw/Disk.cs deleted file mode 100644 index beb6d603..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Raw/Disk.cs +++ /dev/null @@ -1,222 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; -using System.IO; -using DiscUtils.Internal; -using DiscUtils.Streams; - -namespace DiscUtils.Raw -{ - /// - /// Represents a raw disk image. - /// - /// This disk format is simply an uncompressed capture of all blocks on a disk. - public sealed class Disk : VirtualDisk - { - private DiskImageFile _file; - - /// - /// Initializes a new instance of the Disk class. - /// - /// The stream to read. - /// Indicates if the new instance should control the lifetime of the stream. - public Disk(Stream stream, Ownership ownsStream) - : this(stream, ownsStream, null) {} - - /// - /// Initializes a new instance of the Disk class. - /// - /// The stream to read. - /// Indicates if the new instance should control the lifetime of the stream. - /// The emulated geometry of the disk. - public Disk(Stream stream, Ownership ownsStream, Geometry geometry) - { - _file = new DiskImageFile(stream, ownsStream, geometry); - } - - /// - /// Initializes a new instance of the Disk class. - /// - /// The path to the disk image. - public Disk(string path) - :this(path, FileAccess.ReadWrite) {} - - /// - /// Initializes a new instance of the Disk class. - /// - /// The path to the disk image. - /// The access requested to the disk. - public Disk(string path, FileAccess access) - { - FileShare share = access == FileAccess.Read ? FileShare.Read : FileShare.None; - var locator = new LocalFileLocator(string.Empty); - _file = new DiskImageFile(locator.Open(path, FileMode.Open, access, share), Ownership.Dispose, null); - } - - /// - /// Initializes a new instance of the Disk class. - /// - /// The contents of the disk. - private Disk(DiskImageFile file) - { - _file = file; - } - - /// - /// Gets the capacity of the disk (in bytes). - /// - public override long Capacity - { - get { return _file.Capacity; } - } - - /// - /// Gets the content of the disk as a stream. - /// - /// Note the returned stream is not guaranteed to be at any particular position. The actual position - /// will depend on the last partition table/file system activity, since all access to the disk contents pass - /// through a single stream instance. Set the stream position before accessing the stream. - public override SparseStream Content - { - get { return _file.Content; } - } - - /// - /// Gets the type of disk represented by this object. - /// - public override VirtualDiskClass DiskClass - { - get { return _file.DiskType; } - } - - /// - /// Gets information about the type of disk. - /// - /// This property provides access to meta-data about the disk format, for example whether the - /// BIOS geometry is preserved in the disk file. - public override VirtualDiskTypeInfo DiskTypeInfo - { - get { return DiskFactory.MakeDiskTypeInfo(); } - } - - /// - /// Gets the geometry of the disk. - /// - public override Geometry Geometry - { - get { return _file.Geometry; } - } - - /// - /// Gets the layers that make up the disk. - /// - public override IEnumerable Layers - { - get { yield return _file; } - } - - /// - /// Initializes a stream as an unformatted disk. - /// - /// The stream to initialize. - /// Indicates if the new instance controls the lifetime of the stream. - /// The desired capacity of the new disk. - /// An object that accesses the stream as a disk. - public static Disk Initialize(Stream stream, Ownership ownsStream, long capacity) - { - return Initialize(stream, ownsStream, capacity, null); - } - - /// - /// Initializes a stream as an unformatted disk. - /// - /// The stream to initialize. - /// Indicates if the new instance controls the lifetime of the stream. - /// The desired capacity of the new disk. - /// The desired geometry of the new disk, or null for default. - /// An object that accesses the stream as a disk. - public static Disk Initialize(Stream stream, Ownership ownsStream, long capacity, Geometry geometry) - { - return new Disk(DiskImageFile.Initialize(stream, ownsStream, capacity, geometry)); - } - - /// - /// Initializes a stream as an unformatted floppy disk. - /// - /// The stream to initialize. - /// Indicates if the new instance controls the lifetime of the stream. - /// The type of floppy disk image to create. - /// An object that accesses the stream as a disk. - public static Disk Initialize(Stream stream, Ownership ownsStream, FloppyDiskType type) - { - return new Disk(DiskImageFile.Initialize(stream, ownsStream, type)); - } - - /// - /// Create a new differencing disk, possibly within an existing disk. - /// - /// The file system to create the disk on. - /// The path (or URI) for the disk to create. - /// The newly created disk. - public override VirtualDisk CreateDifferencingDisk(DiscFileSystem fileSystem, string path) - { - throw new NotSupportedException("Differencing disks not supported for raw disks"); - } - - /// - /// Create a new differencing disk. - /// - /// The path (or URI) for the disk to create. - /// The newly created disk. - public override VirtualDisk CreateDifferencingDisk(string path) - { - throw new NotSupportedException("Differencing disks not supported for raw disks"); - } - - /// - /// Disposes of underlying resources. - /// - /// Set to true if called within Dispose(), - /// else false. - protected override void Dispose(bool disposing) - { - try - { - if (disposing) - { - if (_file != null) - { - _file.Dispose(); - } - - _file = null; - } - } - finally - { - base.Dispose(disposing); - } - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Raw/DiskFactory.cs b/src/LibHac.Nand/DiscUtils.Core/Raw/DiskFactory.cs deleted file mode 100644 index 3157ff0c..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Raw/DiskFactory.cs +++ /dev/null @@ -1,84 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.IO; -using DiscUtils.Internal; -using DiscUtils.Streams; - -namespace DiscUtils.Raw -{ - [VirtualDiskFactory("RAW", ".img,.ima,.vfd,.flp,.bif")] - internal sealed class DiskFactory : VirtualDiskFactory - { - public override string[] Variants - { - get { return new string[] { }; } - } - - public override VirtualDiskTypeInfo GetDiskTypeInformation(string variant) - { - return MakeDiskTypeInfo(); - } - - public override DiskImageBuilder GetImageBuilder(string variant) - { - throw new NotSupportedException(); - } - - public override VirtualDisk CreateDisk(FileLocator locator, string variant, string path, - VirtualDiskParameters diskParameters) - { - return Disk.Initialize(locator.Open(path, FileMode.Create, FileAccess.ReadWrite, FileShare.None), - Ownership.Dispose, diskParameters.Capacity, diskParameters.Geometry); - } - - public override VirtualDisk OpenDisk(string path, FileAccess access) - { - return new Disk(path, access); - } - - public override VirtualDisk OpenDisk(FileLocator locator, string path, FileAccess access) - { - FileShare share = access == FileAccess.Read ? FileShare.Read : FileShare.None; - return new Disk(locator.Open(path, FileMode.Open, access, share), Ownership.Dispose); - } - - public override VirtualDiskLayer OpenDiskLayer(FileLocator locator, string path, FileAccess access) - { - return null; - } - - internal static VirtualDiskTypeInfo MakeDiskTypeInfo() - { - return new VirtualDiskTypeInfo - { - Name = "RAW", - Variant = string.Empty, - CanBeHardDisk = true, - DeterministicGeometry = true, - PreservesBiosGeometry = false, - CalcGeometry = c => Geometry.FromCapacity(c) - }; - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Raw/DiskImageFile.cs b/src/LibHac.Nand/DiscUtils.Core/Raw/DiskImageFile.cs deleted file mode 100644 index 221c3101..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Raw/DiskImageFile.cs +++ /dev/null @@ -1,246 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.IO; -using DiscUtils.Partitions; -using DiscUtils.Streams; - -namespace DiscUtils.Raw -{ - /// - /// Represents a single raw disk image file. - /// - public sealed class DiskImageFile : VirtualDiskLayer - { - private readonly Ownership _ownsContent; - - /// - /// Initializes a new instance of the DiskImageFile class. - /// - /// The stream to interpret. - public DiskImageFile(Stream stream) - : this(stream, Ownership.None, null) {} - - /// - /// Initializes a new instance of the DiskImageFile class. - /// - /// The stream to interpret. - /// Indicates if the new instance should control the lifetime of the stream. - /// The emulated geometry of the disk. - public DiskImageFile(Stream stream, Ownership ownsStream, Geometry geometry) - { - Content = stream as SparseStream; - _ownsContent = ownsStream; - - if (Content == null) - { - Content = SparseStream.FromStream(stream, ownsStream); - _ownsContent = Ownership.Dispose; - } - - Geometry = geometry ?? DetectGeometry(Content); - } - - internal override long Capacity - { - get { return Content.Length; } - } - - internal SparseStream Content { get; private set; } - - /// - /// Gets the type of disk represented by this object. - /// - public VirtualDiskClass DiskType - { - get { return DetectDiskType(Capacity); } - } - - /// - /// Gets the geometry of the file. - /// - public override Geometry Geometry { get; } - - /// - /// Gets a value indicating if the layer only stores meaningful sectors. - /// - public override bool IsSparse - { - get { return false; } - } - - /// - /// Gets a value indicating whether the file is a differencing disk. - /// - public override bool NeedsParent - { - get { return false; } - } - - internal override FileLocator RelativeFileLocator - { - get { return null; } - } - - /// - /// Initializes a stream as a raw disk image. - /// - /// The stream to initialize. - /// Indicates if the new instance controls the lifetime of the stream. - /// The desired capacity of the new disk. - /// The geometry of the new disk. - /// An object that accesses the stream as a raw disk image. - public static DiskImageFile Initialize(Stream stream, Ownership ownsStream, long capacity, Geometry geometry) - { - stream.SetLength(MathUtilities.RoundUp(capacity, Sizes.Sector)); - - // Wipe any pre-existing master boot record / BPB - stream.Position = 0; - stream.Write(new byte[Sizes.Sector], 0, Sizes.Sector); - stream.Position = 0; - - return new DiskImageFile(stream, ownsStream, geometry); - } - - /// - /// Initializes a stream as an unformatted floppy disk. - /// - /// The stream to initialize. - /// Indicates if the new instance controls the lifetime of the stream. - /// The type of floppy disk image to create. - /// An object that accesses the stream as a disk. - public static DiskImageFile Initialize(Stream stream, Ownership ownsStream, FloppyDiskType type) - { - return Initialize(stream, ownsStream, FloppyCapacity(type), null); - } - - /// - /// Gets the content of this layer. - /// - /// The parent stream (if any). - /// Controls ownership of the parent stream. - /// The content as a stream. - public override SparseStream OpenContent(SparseStream parent, Ownership ownsParent) - { - if (ownsParent == Ownership.Dispose && parent != null) - { - parent.Dispose(); - } - - return SparseStream.FromStream(Content, Ownership.None); - } - - /// - /// Gets the possible locations of the parent file (if any). - /// - /// Array of strings, empty if no parent. - public override string[] GetParentLocations() - { - return new string[0]; - } - - /// - /// Disposes of underlying resources. - /// - /// Set to true if called within Dispose(), - /// else false. - protected override void Dispose(bool disposing) - { - try - { - if (disposing) - { - if (_ownsContent == Ownership.Dispose && Content != null) - { - Content.Dispose(); - } - - Content = null; - } - } - finally - { - base.Dispose(disposing); - } - } - - /// - /// Calculates the best guess geometry of a disk. - /// - /// The disk to detect the geometry of. - /// The geometry of the disk. - private static Geometry DetectGeometry(Stream disk) - { - long capacity = disk.Length; - - // First, check for floppy disk capacities - these have well-defined geometries - if (capacity == Sizes.Sector * 1440) - { - return new Geometry(80, 2, 9); - } - if (capacity == Sizes.Sector * 2880) - { - return new Geometry(80, 2, 18); - } - if (capacity == Sizes.Sector * 5760) - { - return new Geometry(80, 2, 36); - } - - // Failing that, try to detect the geometry from any partition table. - // Note: this call falls back to guessing the geometry from the capacity - return BiosPartitionTable.DetectGeometry(disk); - } - - /// - /// Calculates the best guess disk type (i.e. floppy or hard disk). - /// - /// The capacity of the disk. - /// The disk type. - private static VirtualDiskClass DetectDiskType(long capacity) - { - if (capacity == Sizes.Sector * 1440 - || capacity == Sizes.Sector * 2880 - || capacity == Sizes.Sector * 5760) - { - return VirtualDiskClass.FloppyDisk; - } - return VirtualDiskClass.HardDisk; - } - - private static long FloppyCapacity(FloppyDiskType type) - { - switch (type) - { - case FloppyDiskType.DoubleDensity: - return Sizes.Sector * 1440; - case FloppyDiskType.HighDensity: - return Sizes.Sector * 2880; - case FloppyDiskType.Extended: - return Sizes.Sector * 5760; - default: - throw new ArgumentException("Invalid floppy disk type", nameof(type)); - } - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/ReadOnlyDiscFileSystem.cs b/src/LibHac.Nand/DiscUtils.Core/ReadOnlyDiscFileSystem.cs deleted file mode 100644 index ea6a7c0c..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/ReadOnlyDiscFileSystem.cs +++ /dev/null @@ -1,166 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.IO; -using DiscUtils.Streams; - -namespace DiscUtils -{ - /// - /// Base class for file systems that are by their nature read-only, causes NotSupportedException to be thrown - /// from all methods that are always invalid. - /// - public abstract class ReadOnlyDiscFileSystem : DiscFileSystem - { - /// - /// Initializes a new instance of the ReadOnlyDiscFileSystem class. - /// - protected ReadOnlyDiscFileSystem() {} - - /// - /// Initializes a new instance of the ReadOnlyDiscFileSystem class. - /// - /// The options instance to use for this file system instance. - protected ReadOnlyDiscFileSystem(DiscFileSystemOptions defaultOptions) - : base(defaultOptions) {} - - /// - /// Indicates whether the file system is read-only or read-write. - /// - /// Always false. - public override bool CanWrite - { - get { return false; } - } - - /// - /// Copies a file - not supported on read-only file systems. - /// - /// The source file. - /// The destination file. - /// Whether to permit over-writing of an existing file. - public override void CopyFile(string sourceFile, string destinationFile, bool overwrite) - { - throw new NotSupportedException(); - } - - /// - /// Creates a directory - not supported on read-only file systems. - /// - /// The path of the new directory. - public override void CreateDirectory(string path) - { - throw new NotSupportedException(); - } - - /// - /// Deletes a directory - not supported on read-only file systems. - /// - /// The path of the directory to delete. - public override void DeleteDirectory(string path) - { - throw new NotSupportedException(); - } - - /// - /// Deletes a file - not supported on read-only file systems. - /// - /// The path of the file to delete. - public override void DeleteFile(string path) - { - throw new NotSupportedException(); - } - - /// - /// Moves a directory - not supported on read-only file systems. - /// - /// The directory to move. - /// The target directory name. - public override void MoveDirectory(string sourceDirectoryName, string destinationDirectoryName) - { - throw new NotSupportedException(); - } - - /// - /// Moves a file - not supported on read-only file systems. - /// - /// The file to move. - /// The target file name. - /// Whether to allow an existing file to be overwritten. - public override void MoveFile(string sourceName, string destinationName, bool overwrite) - { - throw new NotSupportedException(); - } - - /// - /// Opens the specified file. - /// - /// The full path of the file to open. - /// The file mode for the created stream. - /// The new stream. - public override SparseStream OpenFile(string path, FileMode mode) - { - return OpenFile(path, mode, FileAccess.Read); - } - - /// - /// Sets the attributes of a file or directory - not supported on read-only file systems. - /// - /// The file or directory to change. - /// The new attributes of the file or directory. - public override void SetAttributes(string path, FileAttributes newValue) - { - throw new NotSupportedException(); - } - - /// - /// Sets the creation time (in UTC) of a file or directory - not supported on read-only file systems. - /// - /// The path of the file or directory. - /// The new time to set. - public override void SetCreationTimeUtc(string path, DateTime newTime) - { - throw new NotSupportedException(); - } - - /// - /// Sets the last access time (in UTC) of a file or directory - not supported on read-only file systems. - /// - /// The path of the file or directory. - /// The new time to set. - public override void SetLastAccessTimeUtc(string path, DateTime newTime) - { - throw new NotSupportedException(); - } - - /// - /// Sets the last modification time (in UTC) of a file or directory - not supported on read-only file systems. - /// - /// The path of the file or directory. - /// The new time to set. - public override void SetLastWriteTimeUtc(string path, DateTime newTime) - { - throw new NotSupportedException(); - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/ReparsePoint.cs b/src/LibHac.Nand/DiscUtils.Core/ReparsePoint.cs deleted file mode 100644 index 02161d35..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/ReparsePoint.cs +++ /dev/null @@ -1,51 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -namespace DiscUtils -{ - /// - /// Represents a Reparse Point, which can be associated with a file or directory. - /// - public sealed class ReparsePoint - { - /// - /// Initializes a new instance of the ReparsePoint class. - /// - /// The defined reparse point tag. - /// The reparse point's content. - public ReparsePoint(int tag, byte[] content) - { - Tag = tag; - Content = content; - } - - /// - /// Gets or sets the reparse point's content. - /// - public byte[] Content { get; set; } - - /// - /// Gets or sets the defined reparse point tag. - /// - public int Tag { get; set; } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/ReportLevels.cs b/src/LibHac.Nand/DiscUtils.Core/ReportLevels.cs deleted file mode 100644 index 7973866d..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/ReportLevels.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System; - -namespace DiscUtils -{ - /// - /// Flags for the amount of detail to include in a report. - /// - [Flags] - public enum ReportLevels - { - /// - /// Report no information. - /// - None = 0x00, - - /// - /// Report informational level items. - /// - Information = 0x01, - - /// - /// Report warning level items. - /// - Warnings = 0x02, - - /// - /// Report error level items. - /// - Errors = 0x04, - - /// - /// Report all items. - /// - All = 0x07 - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Setup/FileOpenEventArgs.cs b/src/LibHac.Nand/DiscUtils.Core/Setup/FileOpenEventArgs.cs deleted file mode 100644 index 79c4c0dc..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Setup/FileOpenEventArgs.cs +++ /dev/null @@ -1,83 +0,0 @@ -// -// Copyright (c) 2017, Bianco Veigel -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.IO; - -namespace DiscUtils.Setup -{ - internal delegate Stream FileOpenDelegate(string fileName, FileMode mode, FileAccess access, FileShare share); - - /// - /// Event arguments for opening a file - /// - public class FileOpenEventArgs:EventArgs - { - private FileOpenDelegate _opener; - - internal FileOpenEventArgs(string fileName, FileMode mode, FileAccess access, FileShare share, FileOpenDelegate opener) - { - FileName = fileName; - FileMode = mode; - FileAccess = access; - FileShare = share; - _opener = opener; - } - - /// - /// Gets or sets the filename to open - /// - public string FileName { get; set; } - - /// - /// Gets or sets the - /// - public FileMode FileMode { get; set; } - - /// - /// Gets or sets the - /// - public FileAccess FileAccess { get; set; } - - /// - /// Gets or sets the - /// - public FileShare FileShare { get; set; } - - /// - /// The resulting stream. - /// - /// - /// If this is set to a non null value, this stream is used instead of opening the supplied - /// - public Stream Result { get; set; } - - /// - /// returns the result from the builtin FileLocator - /// - /// - public Stream GetFileStream() - { - return _opener(FileName, FileMode, FileAccess, FileShare); - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Setup/SetupHelper.cs b/src/LibHac.Nand/DiscUtils.Core/Setup/SetupHelper.cs deleted file mode 100644 index 15e6abee..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Setup/SetupHelper.cs +++ /dev/null @@ -1,55 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Reflection; -using DiscUtils.CoreCompat; - -namespace DiscUtils.Setup -{ - /// - /// Helps setup new DiscUtils dependencies, when loaded into target programs - /// - public static class SetupHelper - { - private static readonly HashSet _alreadyLoaded; - - static SetupHelper() - { - _alreadyLoaded = new HashSet(); - - // Register the core DiscUtils lib - RegisterAssembly(ReflectionHelper.GetAssembly(typeof(SetupHelper))); - } - - /// - /// Registers the types provided by an assembly to all relevant DiscUtils managers - /// - /// - public static void RegisterAssembly(Assembly assembly) - { - lock (_alreadyLoaded) - { - if (!_alreadyLoaded.Add(assembly.FullName)) - return; - - FileSystemManager.RegisterFileSystems(assembly); - VirtualDiskManager.RegisterVirtualDiskTypes(assembly); - VolumeManager.RegisterLogicalVolumeFactory(assembly); - } - } - - /// - /// Allows intercepting any file open operation - /// - /// - /// Can be used to wrap the opened file for special use cases, - /// modify the parameters for opening files, validate file names - /// and many more. - /// - public static event EventHandler OpeningFile; - - internal static void OnOpeningFile(object sender, FileOpenEventArgs e) - { - OpeningFile?.Invoke(sender, e); - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/System/DateTimeOffsetExtensions.cs b/src/LibHac.Nand/DiscUtils.Core/System/DateTimeOffsetExtensions.cs deleted file mode 100644 index 568ef686..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/System/DateTimeOffsetExtensions.cs +++ /dev/null @@ -1,42 +0,0 @@ -namespace System -{ - /// - /// DateTimeOffset extension methods. - /// - public static class DateTimeOffsetExtensions - { - /// - /// The Epoch common to most (all?) Unix systems. - /// - public static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); - - /// - /// Converts the current Unix time to a DateTimeOffset. - /// - /// Seconds since UnixEpoch. - /// DateTimeOffset. - public static DateTimeOffset FromUnixTimeSeconds(this long seconds) - { -#if NETCORE - return DateTimeOffset.FromUnixTimeSeconds(seconds); -#else - DateTimeOffset dateTimeOffset = new DateTimeOffset(DateTimeOffsetExtensions.UnixEpoch); - dateTimeOffset = dateTimeOffset.AddSeconds(seconds); - return dateTimeOffset; -#endif - } - -#if !NETCORE - /// - /// Converts the current DateTimeOffset to Unix time. - /// - /// DateTimeOffset. - /// Seconds since UnixEpoch. - public static long ToUnixTimeSeconds(this DateTimeOffset dateTimeOffset) - { - long unixTimeStampInTicks = (dateTimeOffset.ToUniversalTime() - DateTimeOffsetExtensions.UnixEpoch).Ticks; - return unixTimeStampInTicks / TimeSpan.TicksPerSecond; - } -#endif - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/System/ExtensionAttribute.cs b/src/LibHac.Nand/DiscUtils.Core/System/ExtensionAttribute.cs deleted file mode 100644 index 6c25fdd7..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/System/ExtensionAttribute.cs +++ /dev/null @@ -1,11 +0,0 @@ -#if NET20 -namespace System.Runtime.CompilerServices -{ - /// - /// Indicates that a method is an extension method, or that a class or assembly contains - /// extension methods. - /// - [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method)] - public sealed class ExtensionAttribute : Attribute { } -} -#endif \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/System/HashSet.cs b/src/LibHac.Nand/DiscUtils.Core/System/HashSet.cs deleted file mode 100644 index b070d509..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/System/HashSet.cs +++ /dev/null @@ -1,125 +0,0 @@ -#if NET20 -using System.Collections.Generic; - -namespace System.Collections.Generic -{ - /// - /// Represents a set of values. - /// - /// The type of elements in the HashSet. - public class HashSet : ICollection - { - private Dictionary _innerDictionary; - - /// - /// Initializes a new instance of a HashSet - /// that is empty and uses the default equality comparer for the set type. - /// - public HashSet() - { - _innerDictionary = new Dictionary(); - } - - /// - /// Adds the specified element to a HashSet. - /// - /// The element to add to the set. - void ICollection.Add(T item) - { - AddInternal(item); - } - - private void AddInternal(T item) - { - _innerDictionary.Add(item, false); - } - - /// - /// Adds the specified element to a HashSet. - /// - /// The element to add to the set. - /// true if the element is added to the HashSet object; - /// false if the element is already present. - public bool Add(T item) - { - if (_innerDictionary.ContainsKey(item)) - return false; - - AddInternal(item); - return true; - } - - /// - /// Removes all elements from a HashSet. - /// - public void Clear() - { - _innerDictionary.Clear(); - _innerDictionary = new Dictionary(); - } - - /// - /// Determines whether a HashSet contains the specified element. - /// - /// The element to locate in the HashSet. - /// true if the HashSet contains the specified element; otherwise, false. - public bool Contains(T item) - { - return _innerDictionary.ContainsKey(item); - } - - /// - /// Copies the elements of a HashSet to an array, starting at the specified array index. - /// - /// The one-dimensional array that is the destination of the elements copied from - /// the HashSet. The array must have zero-based indexing - /// The zero-based index in array at which copying begins. - public void CopyTo(T[] array, int arrayIndex) - { - _innerDictionary.Keys.CopyTo(array, arrayIndex); - } - - /// - /// Gets the number of elements that are contained in a HashSet. - /// - public int Count - { - get { return _innerDictionary.Keys.Count; } - } - - /// - /// Gets a value indicating whether the HashSet is read-only. - /// This property is always false. - /// - public bool IsReadOnly - { - get { return false; } - } - - /// - /// Removes the specified element from a HashSet. - /// - /// The element to remove. - /// true if the element is successfully found and removed; otherwise, false. This - /// method returns false if item is not found in the HashSet - public bool Remove(T item) - { - return _innerDictionary.Remove(item); - } - - /// - /// Returns an enumerator that iterates through a HashSet. - /// - /// A HashSet.Enumerator object for the HashSet. - public IEnumerator GetEnumerator() - { - return _innerDictionary.Keys.GetEnumerator(); - } - - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - } -} -#endif \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/System/Tuple.cs b/src/LibHac.Nand/DiscUtils.Core/System/Tuple.cs deleted file mode 100644 index e1cf2705..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/System/Tuple.cs +++ /dev/null @@ -1,116 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - - -#if NET20 - -// ReSharper disable once CheckNamespace -namespace System -{ - internal class Tuple - { - public A Item1 { get; } - public B Item2 { get; } - - public Tuple(A item1, B item2) - { - Item1 = item1; - Item2 = item2; - } - - protected static bool Equals(V a, V b) - { - if (a == null && b == null) - return true; - - if (a == null) - return false; - - return a.Equals(b); - } - - public override bool Equals(object obj) - { - Tuple asType = obj as Tuple; - if (asType == null) - { - return false; - } - - return Equals(Item1, asType.Item1) && Equals(Item2, asType.Item2); - } - - public override int GetHashCode() - { - return ((Item1 == null) ? 0x14AB32BC : Item1.GetHashCode()) ^ ((Item2 == null) ? 0x65BC32DE : Item2.GetHashCode()); - } - } -} -#endif - -#if NET20 - -// ReSharper disable once CheckNamespace -namespace System -{ - internal class Tuple - { - public A Item1 { get; } - public B Item2 { get; } - public C Item3 { get; } - - public Tuple(A item1, B item2, C item3) - { - Item1 = item1; - Item2 = item2; - Item3 = item3; - } - - protected static bool Equals(V a, V b) - { - if (a == null && b == null) - return true; - - if (a == null) - return false; - - return a.Equals(b); - } - - public override bool Equals(object obj) - { - Tuple asType = obj as Tuple; - if (asType == null) - { - return false; - } - - return Equals(Item1, asType.Item1) && Equals(Item2, asType.Item2) && Equals(Item3, asType.Item3); - } - - public override int GetHashCode() - { - return ((Item1 == null) ? 0x14AB32BC : Item1.GetHashCode()) ^ ((Item2 == null) ? 0x65BC32DE : Item2.GetHashCode()) ^ ((Item3 == null) ? 0x2D4C25CF : Item3.GetHashCode()); - } - } -} -#endif \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/TimeConverter.cs b/src/LibHac.Nand/DiscUtils.Core/TimeConverter.cs deleted file mode 100644 index 1e8777df..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/TimeConverter.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; - -namespace DiscUtils -{ - /// - /// Converts a time to/from UTC. - /// - /// The time to convert. - /// true to convert FAT time to UTC, false to convert UTC to FAT time. - /// The converted time. - public delegate DateTime TimeConverter(DateTime time, bool toUtc); -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/UnixFilePermissions.cs b/src/LibHac.Nand/DiscUtils.Core/UnixFilePermissions.cs deleted file mode 100644 index d1088a7a..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/UnixFilePermissions.cs +++ /dev/null @@ -1,113 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; - -namespace DiscUtils -{ - /// - /// Standard Unix-style file system permissions. - /// - [Flags] - public enum UnixFilePermissions - { - /// - /// No permissions. - /// - None = 0, - - /// - /// Any user execute permission. - /// - OthersExecute = 0x001, - - /// - /// Any user write permission. - /// - OthersWrite = 0x002, - - /// - /// Any user read permission. - /// - OthersRead = 0x004, - - /// - /// Any user all permissions. - /// - OthersAll = OthersExecute | OthersWrite | OthersRead, - - /// - /// Group execute permission. - /// - GroupExecute = 0x008, - - /// - /// Group write permission. - /// - GroupWrite = 0x010, - - /// - /// Group read permission. - /// - GroupRead = 0x020, - - /// - /// Group all permissions. - /// - GroupAll = GroupExecute | GroupWrite | GroupRead, - - /// - /// Owner execute permission. - /// - OwnerExecute = 0x040, - - /// - /// Owner write permission. - /// - OwnerWrite = 0x080, - - /// - /// Owner read permission. - /// - OwnerRead = 0x100, - - /// - /// Owner all permissions. - /// - OwnerAll = OwnerExecute | OwnerWrite | OwnerRead, - - /// - /// Sticky bit (meaning ill-defined). - /// - Sticky = 0x200, - - /// - /// Set GUID on execute. - /// - SetGroupId = 0x400, - - /// - /// Set UID on execute. - /// - SetUserId = 0x800 - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/UnixFileSystemInfo.cs b/src/LibHac.Nand/DiscUtils.Core/UnixFileSystemInfo.cs deleted file mode 100644 index 30b9135e..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/UnixFileSystemInfo.cs +++ /dev/null @@ -1,65 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -namespace DiscUtils -{ - /// - /// Information about a file or directory common to most Unix systems. - /// - public sealed class UnixFileSystemInfo - { - /// - /// Gets or sets the device id of the referenced device (for character and block devices). - /// - public long DeviceId { get; set; } - - /// - /// Gets or sets the file's type. - /// - public UnixFileType FileType { get; set; } - - /// - /// Gets or sets the group that owns this file or directory. - /// - public int GroupId { get; set; } - - /// - /// Gets or sets the file's serial number (unique within file system). - /// - public long Inode { get; set; } - - /// - /// Gets or sets the number of hard links to this file. - /// - public int LinkCount { get; set; } - - /// - /// Gets or sets the file permissions (aka flags) for this file or directory. - /// - public UnixFilePermissions Permissions { get; set; } - - /// - /// Gets or sets the user that owns this file or directory. - /// - public int UserId { get; set; } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/UnixFileType.cs b/src/LibHac.Nand/DiscUtils.Core/UnixFileType.cs deleted file mode 100644 index 886c21ec..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/UnixFileType.cs +++ /dev/null @@ -1,70 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -namespace DiscUtils -{ - /// - /// Standard Unix-style file type. - /// - public enum UnixFileType - { - /// - /// No type specified. - /// - None = 0, - - /// - /// A FIFO / Named Pipe. - /// - Fifo = 0x1, - - /// - /// A character device. - /// - Character = 0x2, - - /// - /// A normal directory. - /// - Directory = 0x4, - - /// - /// A block device. - /// - Block = 0x6, - - /// - /// A regular file. - /// - Regular = 0x8, - - /// - /// A soft link. - /// - Link = 0xA, - - /// - /// A unix socket. - /// - Socket = 0xC - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Vfs/IVfsDirectory.cs b/src/LibHac.Nand/DiscUtils.Core/Vfs/IVfsDirectory.cs deleted file mode 100644 index 138efcd9..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Vfs/IVfsDirectory.cs +++ /dev/null @@ -1,60 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System.Collections.Generic; - -namespace DiscUtils.Vfs -{ - /// - /// Interface implemented by classes representing a directory. - /// - /// Concrete type representing directory entries. - /// Concrete type representing files. - public interface IVfsDirectory : IVfsFile - where TDirEntry : VfsDirEntry - where TFile : IVfsFile - { - /// - /// Gets all of the directory entries. - /// - ICollection AllEntries { get; } - - /// - /// Gets a self-reference, if available. - /// - TDirEntry Self { get; } - - /// - /// Gets a specific directory entry, by name. - /// - /// The name of the directory entry. - /// The directory entry, or null if not found. - TDirEntry GetEntryByName(string name); - - /// - /// Creates a new file. - /// - /// The name of the file (relative to this directory). - /// The newly created file. - TDirEntry CreateNewFile(string name); - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Vfs/IVfsFile.cs b/src/LibHac.Nand/DiscUtils.Core/Vfs/IVfsFile.cs deleted file mode 100644 index 0e71e25c..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Vfs/IVfsFile.cs +++ /dev/null @@ -1,69 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.IO; -using DiscUtils.Streams; - -namespace DiscUtils.Vfs -{ - /// - /// Interface implemented by a class representing a file. - /// - /// - /// File system implementations should have a class that implements this - /// interface. If the file system implementation is read-only, it is - /// acceptable to throw NotImplementedException from setters. - /// - public interface IVfsFile - { - /// - /// Gets or sets the last creation time in UTC. - /// - DateTime CreationTimeUtc { get; set; } - - /// - /// Gets or sets the file's attributes. - /// - FileAttributes FileAttributes { get; set; } - - /// - /// Gets a buffer to access the file's contents. - /// - IBuffer FileContent { get; } - - /// - /// Gets the length of the file. - /// - long FileLength { get; } - - /// - /// Gets or sets the last access time in UTC. - /// - DateTime LastAccessTimeUtc { get; set; } - - /// - /// Gets or sets the last write time in UTC. - /// - DateTime LastWriteTimeUtc { get; set; } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Vfs/IVfsFileWithStreams.cs b/src/LibHac.Nand/DiscUtils.Core/Vfs/IVfsFileWithStreams.cs deleted file mode 100644 index e29249ba..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Vfs/IVfsFileWithStreams.cs +++ /dev/null @@ -1,26 +0,0 @@ -using DiscUtils.Streams; - -namespace DiscUtils.Vfs -{ - /// - /// Interface implemented by classes representing files, in file systems that support multi-stream files. - /// - public interface IVfsFileWithStreams : IVfsFile - { - /// - /// Creates a new stream. - /// - /// The name of the stream. - /// An object representing the stream. - SparseStream CreateStream(string name); - - /// - /// Opens an existing stream. - /// - /// The name of the stream. - /// An object representing the stream. - /// The implementation must not implicitly create the stream if it doesn't already - /// exist. - SparseStream OpenExistingStream(string name); - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Vfs/IVfsSymlink.cs b/src/LibHac.Nand/DiscUtils.Core/Vfs/IVfsSymlink.cs deleted file mode 100644 index 94952c8f..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Vfs/IVfsSymlink.cs +++ /dev/null @@ -1,39 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -namespace DiscUtils.Vfs -{ - /// - /// Interface implemented by classes representing a directory. - /// - /// Concrete type representing directory entries. - /// Concrete type representing files. - public interface IVfsSymlink : IVfsFile - where TDirEntry : VfsDirEntry - where TFile : IVfsFile - { - /// - /// Gets the target path for this symlink. - /// - string TargetPath { get; } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Vfs/VfsContext.cs b/src/LibHac.Nand/DiscUtils.Core/Vfs/VfsContext.cs deleted file mode 100644 index 90cfc12f..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Vfs/VfsContext.cs +++ /dev/null @@ -1,29 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -namespace DiscUtils.Vfs -{ - /// - /// Base class for a context object that holds global state for file system implementations. - /// - public abstract class VfsContext {} -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Vfs/VfsDirEntry.cs b/src/LibHac.Nand/DiscUtils.Core/Vfs/VfsDirEntry.cs deleted file mode 100644 index 5536bf21..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Vfs/VfsDirEntry.cs +++ /dev/null @@ -1,128 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.IO; - -namespace DiscUtils.Vfs -{ - /// - /// Base class for directory entries in a file system. - /// - /// - /// File system implementations should have a class that derives from - /// this abstract class. If the file system implementation is read-only, - /// it is acceptable to throw NotImplementedException from methods - /// that attempt to modify the file system. - /// - public abstract class VfsDirEntry - { - /// - /// Gets the creation time of the file or directory. - /// - /// - /// May throw NotSupportedException if HasVfsTimeInfo is false. - /// - public abstract DateTime CreationTimeUtc { get; } - - /// - /// Gets the file attributes from the directory entry. - /// - /// - /// May throw NotSupportedException if HasVfsFileAttributes is false. - /// - public abstract FileAttributes FileAttributes { get; } - - /// - /// Gets the name of this directory entry. - /// - public abstract string FileName { get; } - - /// - /// Gets a value indicating whether this directory entry contains file attribute information. - /// - /// - /// Typically either always returns true or false. - /// - public abstract bool HasVfsFileAttributes { get; } - - /// - /// Gets a value indicating whether this directory entry contains time information. - /// - /// - /// Typically either always returns true or false. - /// - public abstract bool HasVfsTimeInfo { get; } - - /// - /// Gets a value indicating whether this directory entry represents a directory (rather than a file). - /// - public abstract bool IsDirectory { get; } - - /// - /// Gets a value indicating whether this directory entry represents a symlink (rather than a file or directory). - /// - public abstract bool IsSymlink { get; } - - /// - /// Gets the last access time of the file or directory. - /// - /// - /// May throw NotSupportedException if HasVfsTimeInfo is false. - /// - public abstract DateTime LastAccessTimeUtc { get; } - - /// - /// Gets the last write time of the file or directory. - /// - /// - /// May throw NotSupportedException if HasVfsTimeInfo is false. - /// - public abstract DateTime LastWriteTimeUtc { get; } - - /// - /// Gets a version of FileName that can be used in wildcard matches. - /// - /// - /// The returned name, must have an extension separator '.', and not have any optional version - /// information found in some files. The returned name is matched against a wildcard patterns - /// such as "*.*". - /// - public virtual string SearchName - { - get - { - string fileName = FileName; - if (fileName.IndexOf('.') == -1) - { - return fileName + "."; - } - return fileName; - } - } - - /// - /// Gets a unique id for the file or directory represented by this directory entry. - /// - public abstract long UniqueCacheId { get; } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Vfs/VfsFileSystem.cs b/src/LibHac.Nand/DiscUtils.Core/Vfs/VfsFileSystem.cs deleted file mode 100644 index e083309f..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Vfs/VfsFileSystem.cs +++ /dev/null @@ -1,749 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; -using System.Globalization; -using System.IO; -using System.Text.RegularExpressions; -using DiscUtils.Internal; -using DiscUtils.Streams; - -namespace DiscUtils.Vfs -{ - /// - /// Base class for VFS file systems. - /// - /// The concrete type representing directory entries. - /// The concrete type representing files. - /// The concrete type representing directories. - /// The concrete type holding global state. - public abstract class VfsFileSystem : DiscFileSystem - where TDirEntry : VfsDirEntry - where TFile : IVfsFile - where TDirectory : class, IVfsDirectory, TFile - where TContext : VfsContext - { - private readonly ObjectCache _fileCache; - - /// - /// Initializes a new instance of the VfsFileSystem class. - /// - /// The default file system options. - protected VfsFileSystem(DiscFileSystemOptions defaultOptions) - : base(defaultOptions) - { - _fileCache = new ObjectCache(); - } - - /// - /// Gets or sets the global shared state. - /// - protected TContext Context { get; set; } - - /// - /// Gets or sets the object representing the root directory. - /// - protected TDirectory RootDirectory { get; set; } - - /// - /// Gets the volume label. - /// - public abstract override string VolumeLabel { get; } - - /// - /// Copies a file - not supported on read-only file systems. - /// - /// The source file. - /// The destination file. - /// Whether to permit over-writing of an existing file. - public override void CopyFile(string sourceFile, string destinationFile, bool overwrite) - { - throw new NotImplementedException(); - } - - /// - /// Creates a directory - not supported on read-only file systems. - /// - /// The path of the new directory. - public override void CreateDirectory(string path) - { - throw new NotImplementedException(); - } - - /// - /// Deletes a directory - not supported on read-only file systems. - /// - /// The path of the directory to delete. - public override void DeleteDirectory(string path) - { - throw new NotImplementedException(); - } - - /// - /// Deletes a file - not supported on read-only file systems. - /// - /// The path of the file to delete. - public override void DeleteFile(string path) - { - throw new NotImplementedException(); - } - - /// - /// Indicates if a directory exists. - /// - /// The path to test. - /// true if the directory exists. - public override bool DirectoryExists(string path) - { - if (IsRoot(path)) - { - return true; - } - - TDirEntry dirEntry = GetDirectoryEntry(path); - - if (dirEntry != null) - { - return dirEntry.IsDirectory; - } - - return false; - } - - /// - /// Indicates if a file exists. - /// - /// The path to test. - /// true if the file exists. - public override bool FileExists(string path) - { - TDirEntry dirEntry = GetDirectoryEntry(path); - - if (dirEntry != null) - { - return !dirEntry.IsDirectory; - } - - return false; - } - - /// - /// Gets the names of subdirectories in a specified directory matching a specified - /// search pattern, using a value to determine whether to search subdirectories. - /// - /// The path to search. - /// The search string to match against. - /// Indicates whether to search subdirectories. - /// Array of directories matching the search pattern. - public override string[] GetDirectories(string path, string searchPattern, SearchOption searchOption) - { - Regex re = Utilities.ConvertWildcardsToRegEx(searchPattern); - - List dirs = new List(); - DoSearch(dirs, path, re, searchOption == SearchOption.AllDirectories, true, false); - return dirs.ToArray(); - } - - /// - /// Gets the names of files in a specified directory matching a specified - /// search pattern, using a value to determine whether to search subdirectories. - /// - /// The path to search. - /// The search string to match against. - /// Indicates whether to search subdirectories. - /// Array of files matching the search pattern. - public override string[] GetFiles(string path, string searchPattern, SearchOption searchOption) - { - Regex re = Utilities.ConvertWildcardsToRegEx(searchPattern); - - List results = new List(); - DoSearch(results, path, re, searchOption == SearchOption.AllDirectories, false, true); - return results.ToArray(); - } - - /// - /// Gets the names of all files and subdirectories in a specified directory. - /// - /// The path to search. - /// Array of files and subdirectories matching the search pattern. - public override string[] GetFileSystemEntries(string path) - { - string fullPath = path; - if (!fullPath.StartsWith(@"\", StringComparison.OrdinalIgnoreCase)) - { - fullPath = @"\" + fullPath; - } - - TDirectory parentDir = GetDirectory(fullPath); - return Utilities.Map(parentDir.AllEntries, - m => Utilities.CombinePaths(fullPath, FormatFileName(m.FileName))); - } - - /// - /// Gets the names of files and subdirectories in a specified directory matching a specified - /// search pattern. - /// - /// The path to search. - /// The search string to match against. - /// Array of files and subdirectories matching the search pattern. - public override string[] GetFileSystemEntries(string path, string searchPattern) - { - Regex re = Utilities.ConvertWildcardsToRegEx(searchPattern); - - TDirectory parentDir = GetDirectory(path); - - List result = new List(); - foreach (TDirEntry dirEntry in parentDir.AllEntries) - { - if (re.IsMatch(dirEntry.SearchName)) - { - result.Add(Utilities.CombinePaths(path, dirEntry.FileName)); - } - } - - return result.ToArray(); - } - - /// - /// Moves a directory. - /// - /// The directory to move. - /// The target directory name. - public override void MoveDirectory(string sourceDirectoryName, string destinationDirectoryName) - { - throw new NotImplementedException(); - } - - /// - /// Moves a file. - /// - /// The file to move. - /// The target file name. - /// Overwrite any existing file. - public override void MoveFile(string sourceName, string destinationName, bool overwrite) - { - throw new NotImplementedException(); - } - - /// - /// Opens the specified file. - /// - /// The full path of the file to open. - /// The file mode for the created stream. - /// The access permissions for the created stream. - /// The new stream. - public override SparseStream OpenFile(string path, FileMode mode, FileAccess access) - { - if (!CanWrite) - { - if (mode != FileMode.Open) - { - throw new NotSupportedException("Only existing files can be opened"); - } - - if (access != FileAccess.Read) - { - throw new NotSupportedException("Files cannot be opened for write"); - } - } - - string fileName = Utilities.GetFileFromPath(path); - string attributeName = null; - - int streamSepPos = fileName.IndexOf(':'); - if (streamSepPos >= 0) - { - attributeName = fileName.Substring(streamSepPos + 1); - } - - string dirName; - try - { - dirName = Utilities.GetDirectoryFromPath(path); - } - catch (ArgumentException) - { - throw new IOException("Invalid path: " + path); - } - - string entryPath = Utilities.CombinePaths(dirName, fileName); - TDirEntry entry = GetDirectoryEntry(entryPath); - if (entry == null) - { - if (mode == FileMode.Open) - { - throw new FileNotFoundException("No such file", path); - } - TDirectory parentDir = GetDirectory(Utilities.GetDirectoryFromPath(path)); - entry = parentDir.CreateNewFile(Utilities.GetFileFromPath(path)); - } - else if (mode == FileMode.CreateNew) - { - throw new IOException("File already exists"); - } - - if (entry.IsSymlink) - { - entry = ResolveSymlink(entry, entryPath); - } - - if (entry.IsDirectory) - { - throw new IOException("Attempt to open directory as a file"); - } - TFile file = GetFile(entry); - - SparseStream stream = null; - if (string.IsNullOrEmpty(attributeName)) - { - stream = new BufferStream(file.FileContent, access); - } - else - { - IVfsFileWithStreams fileStreams = file as IVfsFileWithStreams; - if (fileStreams != null) - { - stream = fileStreams.OpenExistingStream(attributeName); - if (stream == null) - { - if (mode == FileMode.Create || mode == FileMode.OpenOrCreate) - { - stream = fileStreams.CreateStream(attributeName); - } - else - { - throw new FileNotFoundException("No such attribute on file", path); - } - } - } - else - { - throw new NotSupportedException( - "Attempt to open a file stream on a file system that doesn't support them"); - } - } - - if (mode == FileMode.Create || mode == FileMode.Truncate) - { - stream.SetLength(0); - } - - return stream; - } - - /// - /// Gets the attributes of a file or directory. - /// - /// The file or directory to inspect. - /// The attributes of the file or directory. - public override FileAttributes GetAttributes(string path) - { - if (IsRoot(path)) - { - return RootDirectory.FileAttributes; - } - - TDirEntry dirEntry = GetDirectoryEntry(path); - if (dirEntry == null) - { - throw new FileNotFoundException("File not found", path); - } - - if (dirEntry.HasVfsFileAttributes) - { - return dirEntry.FileAttributes; - } - return GetFile(dirEntry).FileAttributes; - } - - /// - /// Sets the attributes of a file or directory. - /// - /// The file or directory to change. - /// The new attributes of the file or directory. - public override void SetAttributes(string path, FileAttributes newValue) - { - throw new NotImplementedException(); - } - - /// - /// Gets the creation time (in UTC) of a file or directory. - /// - /// The path of the file or directory. - /// The creation time. - public override DateTime GetCreationTimeUtc(string path) - { - if (IsRoot(path)) - { - return RootDirectory.CreationTimeUtc; - } - - TDirEntry dirEntry = GetDirectoryEntry(path); - if (dirEntry == null) - { - throw new FileNotFoundException("No such file or directory", path); - } - - if (dirEntry.HasVfsTimeInfo) - { - return dirEntry.CreationTimeUtc; - } - return GetFile(dirEntry).CreationTimeUtc; - } - - /// - /// Sets the creation time (in UTC) of a file or directory. - /// - /// The path of the file or directory. - /// The new time to set. - public override void SetCreationTimeUtc(string path, DateTime newTime) - { - throw new NotImplementedException(); - } - - /// - /// Gets the last access time (in UTC) of a file or directory. - /// - /// The path of the file or directory. - /// The last access time. - public override DateTime GetLastAccessTimeUtc(string path) - { - if (IsRoot(path)) - { - return RootDirectory.LastAccessTimeUtc; - } - - TDirEntry dirEntry = GetDirectoryEntry(path); - if (dirEntry == null) - { - throw new FileNotFoundException("No such file or directory", path); - } - - if (dirEntry.HasVfsTimeInfo) - { - return dirEntry.LastAccessTimeUtc; - } - return GetFile(dirEntry).LastAccessTimeUtc; - } - - /// - /// Sets the last access time (in UTC) of a file or directory. - /// - /// The path of the file or directory. - /// The new time to set. - public override void SetLastAccessTimeUtc(string path, DateTime newTime) - { - throw new NotImplementedException(); - } - - /// - /// Gets the last modification time (in UTC) of a file or directory. - /// - /// The path of the file or directory. - /// The last write time. - public override DateTime GetLastWriteTimeUtc(string path) - { - if (IsRoot(path)) - { - return RootDirectory.LastWriteTimeUtc; - } - - TDirEntry dirEntry = GetDirectoryEntry(path); - if (dirEntry == null) - { - throw new FileNotFoundException("No such file or directory", path); - } - - if (dirEntry.HasVfsTimeInfo) - { - return dirEntry.LastWriteTimeUtc; - } - return GetFile(dirEntry).LastWriteTimeUtc; - } - - /// - /// Sets the last modification time (in UTC) of a file or directory. - /// - /// The path of the file or directory. - /// The new time to set. - public override void SetLastWriteTimeUtc(string path, DateTime newTime) - { - throw new NotImplementedException(); - } - - /// - /// Gets the length of a file. - /// - /// The path to the file. - /// The length in bytes. - public override long GetFileLength(string path) - { - TFile file = GetFile(path); - if (file == null || (file.FileAttributes & FileAttributes.Directory) != 0) - { - throw new FileNotFoundException("No such file", path); - } - - return file.FileLength; - } - - internal TFile GetFile(TDirEntry dirEntry) - { - long cacheKey = dirEntry.UniqueCacheId; - - TFile file = _fileCache[cacheKey]; - if (file == null) - { - file = ConvertDirEntryToFile(dirEntry); - _fileCache[cacheKey] = file; - } - - return file; - } - - internal TDirectory GetDirectory(string path) - { - if (IsRoot(path)) - { - return RootDirectory; - } - - TDirEntry dirEntry = GetDirectoryEntry(path); - - if (dirEntry != null && dirEntry.IsSymlink) - { - dirEntry = ResolveSymlink(dirEntry, path); - } - - if (dirEntry == null || !dirEntry.IsDirectory) - { - throw new DirectoryNotFoundException("No such directory: " + path); - } - - return (TDirectory)GetFile(dirEntry); - } - - internal TDirEntry GetDirectoryEntry(string path) - { - return GetDirectoryEntry(RootDirectory, path); - } - - /// - /// Gets all directory entries in the specified directory and sub-directories. - /// - /// The path to inspect. - /// Delegate invoked for each directory entry. - protected void ForAllDirEntries(string path, DirEntryHandler handler) - { - TDirectory dir = null; - TDirEntry self = GetDirectoryEntry(path); - - if (self != null) - { - handler(path, self); - if (self.IsDirectory) - { - dir = GetFile(self) as TDirectory; - } - } - else - { - dir = GetFile(path) as TDirectory; - } - - if (dir != null) - { - foreach (TDirEntry subentry in dir.AllEntries) - { - ForAllDirEntries(Utilities.CombinePaths(path, subentry.FileName), handler); - } - } - } - - /// - /// Gets the file object for a given path. - /// - /// The path to query. - /// The file object corresponding to the path. - protected TFile GetFile(string path) - { - if (IsRoot(path)) - { - return RootDirectory; - } - if (path == null) - { - return default(TFile); - } - - TDirEntry dirEntry = GetDirectoryEntry(path); - if (dirEntry == null) - { - throw new FileNotFoundException("No such file or directory", path); - } - - return GetFile(dirEntry); - } - - /// - /// Converts a directory entry to an object representing a file. - /// - /// The directory entry to convert. - /// The corresponding file object. - protected abstract TFile ConvertDirEntryToFile(TDirEntry dirEntry); - - /// - /// Converts an internal directory entry name into an external one. - /// - /// The name to convert. - /// The external name. - /// - /// This method is called on a single path element (i.e. name contains no path - /// separators). - /// - protected virtual string FormatFileName(string name) - { - return name; - } - - private static bool IsRoot(string path) - { - return string.IsNullOrEmpty(path) || path == @"\"; - } - - private TDirEntry GetDirectoryEntry(TDirectory dir, string path) - { - string[] pathElements = path.Split(new[] { '\\' }, StringSplitOptions.RemoveEmptyEntries); - return GetDirectoryEntry(dir, pathElements, 0); - } - - private TDirEntry GetDirectoryEntry(TDirectory dir, string[] pathEntries, int pathOffset) - { - TDirEntry entry; - - if (pathEntries.Length == 0) - { - return dir.Self; - } - entry = dir.GetEntryByName(pathEntries[pathOffset]); - if (entry != null) - { - if (pathOffset == pathEntries.Length - 1) - { - return entry; - } - if (entry.IsDirectory) - { - return GetDirectoryEntry((TDirectory)ConvertDirEntryToFile(entry), pathEntries, pathOffset + 1); - } - throw new IOException(string.Format(CultureInfo.InvariantCulture, - "{0} is a file, not a directory", pathEntries[pathOffset])); - } - return null; - } - - private void DoSearch(List results, string path, Regex regex, bool subFolders, bool dirs, bool files) - { - TDirectory parentDir = GetDirectory(path); - if (parentDir == null) - { - throw new DirectoryNotFoundException(string.Format(CultureInfo.InvariantCulture, - "The directory '{0}' was not found", path)); - } - - string resultPrefixPath = path; - if (IsRoot(path)) - { - resultPrefixPath = @"\"; - } - - foreach (TDirEntry de in parentDir.AllEntries) - { - TDirEntry entry = de; - - if (entry.IsSymlink) - { - entry = ResolveSymlink(entry, path + "\\" + entry.FileName); - } - - bool isDir = entry.IsDirectory; - - if ((isDir && dirs) || (!isDir && files)) - { - if (regex.IsMatch(de.SearchName)) - { - results.Add(Utilities.CombinePaths(resultPrefixPath, FormatFileName(entry.FileName))); - } - } - - if (subFolders && isDir) - { - DoSearch(results, Utilities.CombinePaths(resultPrefixPath, FormatFileName(entry.FileName)), regex, - subFolders, dirs, files); - } - } - } - - private TDirEntry ResolveSymlink(TDirEntry entry, string path) - { - TDirEntry currentEntry = entry; - if (path.Length > 0 && path[0] != '\\') - { - path = '\\' + path; - } - string currentPath = path; - int resolvesLeft = 20; - while (currentEntry.IsSymlink && resolvesLeft > 0) - { - IVfsSymlink symlink = GetFile(currentEntry) as IVfsSymlink; - if (symlink == null) - { - throw new FileNotFoundException("Unable to resolve symlink", path); - } - - currentPath = Utilities.ResolvePath(currentPath.TrimEnd('\\'), symlink.TargetPath); - currentEntry = GetDirectoryEntry(currentPath); - if (currentEntry == null) - { - throw new FileNotFoundException("Unable to resolve symlink", path); - } - - --resolvesLeft; - } - - if (currentEntry.IsSymlink) - { - throw new FileNotFoundException("Unable to resolve symlink - too many links", path); - } - - return currentEntry; - } - - /// - /// Delegate for processing directory entries. - /// - /// Full path to the directory entry. - /// The directory entry itself. - protected delegate void DirEntryHandler(string path, TDirEntry dirEntry); - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Vfs/VfsFileSystemFacade.cs b/src/LibHac.Nand/DiscUtils.Core/Vfs/VfsFileSystemFacade.cs deleted file mode 100644 index 97887f80..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Vfs/VfsFileSystemFacade.cs +++ /dev/null @@ -1,567 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.IO; -using DiscUtils.Streams; - -namespace DiscUtils.Vfs -{ - /// - /// Base class for the public facade on a file system. - /// - /// - /// The derived class can extend the functionality available from a file system - /// beyond that defined by DiscFileSystem. - /// - public abstract class VfsFileSystemFacade : DiscFileSystem - { - private readonly DiscFileSystem _wrapped; - - /// - /// Initializes a new instance of the VfsFileSystemFacade class. - /// - /// The actual file system instance. - protected VfsFileSystemFacade(DiscFileSystem toWrap) - { - _wrapped = toWrap; - } - - /// - /// Indicates whether the file system is read-only or read-write. - /// - /// true if the file system is read-write. - public override bool CanWrite - { - get { return _wrapped.CanWrite; } - } - - /// - /// Gets a friendly name for the file system. - /// - public override string FriendlyName - { - get { return _wrapped.FriendlyName; } - } - - /// - /// Gets a value indicating whether the file system is thread-safe. - /// - public override bool IsThreadSafe - { - get { return _wrapped.IsThreadSafe; } - } - - /// - /// Gets the file system options, which can be modified. - /// - public override DiscFileSystemOptions Options - { - get { return _wrapped.Options; } - } - - /// - /// Gets the root directory of the file system. - /// - public override DiscDirectoryInfo Root - { - get { return new DiscDirectoryInfo(this, string.Empty); } - } - - /// - /// Gets the volume label. - /// - public override string VolumeLabel - { - get { return _wrapped.VolumeLabel; } - } - - /// - /// Copies an existing file to a new file. - /// - /// The source file. - /// The destination file. - public override void CopyFile(string sourceFile, string destinationFile) - { - _wrapped.CopyFile(sourceFile, destinationFile); - } - - /// - /// Copies an existing file to a new file. - /// - /// The source file. - /// The destination file. - /// Overwrite any existing file. - public override void CopyFile(string sourceFile, string destinationFile, bool overwrite) - { - _wrapped.CopyFile(sourceFile, destinationFile, overwrite); - } - - /// - /// Creates a directory. - /// - /// The path of the new directory. - public override void CreateDirectory(string path) - { - _wrapped.CreateDirectory(path); - } - - /// - /// Deletes a directory. - /// - /// The path of the directory to delete. - public override void DeleteDirectory(string path) - { - _wrapped.DeleteDirectory(path); - } - - /// - /// Deletes a directory, optionally with all descendants. - /// - /// The path of the directory to delete. - /// Determines if the all descendants should be deleted. - public override void DeleteDirectory(string path, bool recursive) - { - _wrapped.DeleteDirectory(path, recursive); - } - - /// - /// Deletes a file. - /// - /// The path of the file to delete. - public override void DeleteFile(string path) - { - _wrapped.DeleteFile(path); - } - - /// - /// Indicates if a directory exists. - /// - /// The path to test. - /// true if the directory exists. - public override bool DirectoryExists(string path) - { - return _wrapped.DirectoryExists(path); - } - - /// - /// Indicates if a file exists. - /// - /// The path to test. - /// true if the file exists. - public override bool FileExists(string path) - { - return _wrapped.FileExists(path); - } - - /// - /// Indicates if a file or directory exists. - /// - /// The path to test. - /// true if the file or directory exists. - public override bool Exists(string path) - { - return _wrapped.Exists(path); - } - - /// - /// Gets the names of subdirectories in a specified directory. - /// - /// The path to search. - /// Array of directories. - public override string[] GetDirectories(string path) - { - return _wrapped.GetDirectories(path); - } - - /// - /// Gets the names of subdirectories in a specified directory matching a specified - /// search pattern. - /// - /// The path to search. - /// The search string to match against. - /// Array of directories matching the search pattern. - public override string[] GetDirectories(string path, string searchPattern) - { - return _wrapped.GetDirectories(path, searchPattern); - } - - /// - /// Gets the names of subdirectories in a specified directory matching a specified - /// search pattern, using a value to determine whether to search subdirectories. - /// - /// The path to search. - /// The search string to match against. - /// Indicates whether to search subdirectories. - /// Array of directories matching the search pattern. - public override string[] GetDirectories(string path, string searchPattern, SearchOption searchOption) - { - return _wrapped.GetDirectories(path, searchPattern, searchOption); - } - - /// - /// Gets the names of files in a specified directory. - /// - /// The path to search. - /// Array of files. - public override string[] GetFiles(string path) - { - return _wrapped.GetFiles(path); - } - - /// - /// Gets the names of files in a specified directory. - /// - /// The path to search. - /// The search string to match against. - /// Array of files matching the search pattern. - public override string[] GetFiles(string path, string searchPattern) - { - return _wrapped.GetFiles(path, searchPattern); - } - - /// - /// Gets the names of files in a specified directory matching a specified - /// search pattern, using a value to determine whether to search subdirectories. - /// - /// The path to search. - /// The search string to match against. - /// Indicates whether to search subdirectories. - /// Array of files matching the search pattern. - public override string[] GetFiles(string path, string searchPattern, SearchOption searchOption) - { - return _wrapped.GetFiles(path, searchPattern, searchOption); - } - - /// - /// Gets the names of all files and subdirectories in a specified directory. - /// - /// The path to search. - /// Array of files and subdirectories matching the search pattern. - public override string[] GetFileSystemEntries(string path) - { - return _wrapped.GetFileSystemEntries(path); - } - - /// - /// Gets the names of files and subdirectories in a specified directory matching a specified - /// search pattern. - /// - /// The path to search. - /// The search string to match against. - /// Array of files and subdirectories matching the search pattern. - public override string[] GetFileSystemEntries(string path, string searchPattern) - { - return _wrapped.GetFileSystemEntries(path, searchPattern); - } - - /// - /// Moves a directory. - /// - /// The directory to move. - /// The target directory name. - public override void MoveDirectory(string sourceDirectoryName, string destinationDirectoryName) - { - _wrapped.MoveDirectory(sourceDirectoryName, destinationDirectoryName); - } - - /// - /// Moves a file. - /// - /// The file to move. - /// The target file name. - public override void MoveFile(string sourceName, string destinationName) - { - _wrapped.MoveFile(sourceName, destinationName); - } - - /// - /// Moves a file, allowing an existing file to be overwritten. - /// - /// The file to move. - /// The target file name. - /// Whether to permit a destination file to be overwritten. - public override void MoveFile(string sourceName, string destinationName, bool overwrite) - { - _wrapped.MoveFile(sourceName, destinationName, overwrite); - } - - /// - /// Opens the specified file. - /// - /// The full path of the file to open. - /// The file mode for the created stream. - /// The new stream. - public override SparseStream OpenFile(string path, FileMode mode) - { - return _wrapped.OpenFile(path, mode); - } - - /// - /// Opens the specified file. - /// - /// The full path of the file to open. - /// The file mode for the created stream. - /// The access permissions for the created stream. - /// The new stream. - public override SparseStream OpenFile(string path, FileMode mode, FileAccess access) - { - return _wrapped.OpenFile(path, mode, access); - } - - /// - /// Gets the attributes of a file or directory. - /// - /// The file or directory to inspect. - /// The attributes of the file or directory. - public override FileAttributes GetAttributes(string path) - { - return _wrapped.GetAttributes(path); - } - - /// - /// Sets the attributes of a file or directory. - /// - /// The file or directory to change. - /// The new attributes of the file or directory. - public override void SetAttributes(string path, FileAttributes newValue) - { - _wrapped.SetAttributes(path, newValue); - } - - /// - /// Gets the creation time (in local time) of a file or directory. - /// - /// The path of the file or directory. - /// The creation time. - public override DateTime GetCreationTime(string path) - { - return _wrapped.GetCreationTime(path); - } - - /// - /// Sets the creation time (in local time) of a file or directory. - /// - /// The path of the file or directory. - /// The new time to set. - public override void SetCreationTime(string path, DateTime newTime) - { - _wrapped.SetCreationTime(path, newTime); - } - - /// - /// Gets the creation time (in UTC) of a file or directory. - /// - /// The path of the file or directory. - /// The creation time. - public override DateTime GetCreationTimeUtc(string path) - { - return _wrapped.GetCreationTimeUtc(path); - } - - /// - /// Sets the creation time (in UTC) of a file or directory. - /// - /// The path of the file or directory. - /// The new time to set. - public override void SetCreationTimeUtc(string path, DateTime newTime) - { - _wrapped.SetCreationTimeUtc(path, newTime); - } - - /// - /// Gets the last access time (in local time) of a file or directory. - /// - /// The path of the file or directory. - /// The last access time. - public override DateTime GetLastAccessTime(string path) - { - return _wrapped.GetLastAccessTime(path); - } - - /// - /// Sets the last access time (in local time) of a file or directory. - /// - /// The path of the file or directory. - /// The new time to set. - public override void SetLastAccessTime(string path, DateTime newTime) - { - _wrapped.SetLastAccessTime(path, newTime); - } - - /// - /// Gets the last access time (in UTC) of a file or directory. - /// - /// The path of the file or directory. - /// The last access time. - public override DateTime GetLastAccessTimeUtc(string path) - { - return _wrapped.GetLastAccessTimeUtc(path); - } - - /// - /// Sets the last access time (in UTC) of a file or directory. - /// - /// The path of the file or directory. - /// The new time to set. - public override void SetLastAccessTimeUtc(string path, DateTime newTime) - { - _wrapped.SetLastAccessTimeUtc(path, newTime); - } - - /// - /// Gets the last modification time (in local time) of a file or directory. - /// - /// The path of the file or directory. - /// The last write time. - public override DateTime GetLastWriteTime(string path) - { - return _wrapped.GetLastWriteTime(path); - } - - /// - /// Sets the last modification time (in local time) of a file or directory. - /// - /// The path of the file or directory. - /// The new time to set. - public override void SetLastWriteTime(string path, DateTime newTime) - { - _wrapped.SetLastWriteTime(path, newTime); - } - - /// - /// Gets the last modification time (in UTC) of a file or directory. - /// - /// The path of the file or directory. - /// The last write time. - public override DateTime GetLastWriteTimeUtc(string path) - { - return _wrapped.GetLastWriteTimeUtc(path); - } - - /// - /// Sets the last modification time (in UTC) of a file or directory. - /// - /// The path of the file or directory. - /// The new time to set. - public override void SetLastWriteTimeUtc(string path, DateTime newTime) - { - _wrapped.SetLastWriteTimeUtc(path, newTime); - } - - /// - /// Gets the length of a file. - /// - /// The path to the file. - /// The length in bytes. - public override long GetFileLength(string path) - { - return _wrapped.GetFileLength(path); - } - - /// - /// Gets an object representing a possible file. - /// - /// The file path. - /// The representing object. - /// The file does not need to exist. - public override DiscFileInfo GetFileInfo(string path) - { - return new DiscFileInfo(this, path); - } - - /// - /// Gets an object representing a possible directory. - /// - /// The directory path. - /// The representing object. - /// The directory does not need to exist. - public override DiscDirectoryInfo GetDirectoryInfo(string path) - { - return new DiscDirectoryInfo(this, path); - } - - /// - /// Gets an object representing a possible file system object (file or directory). - /// - /// The file system path. - /// The representing object. - /// The file system object does not need to exist. - public override DiscFileSystemInfo GetFileSystemInfo(string path) - { - return new DiscFileSystemInfo(this, path); - } - - /// - /// Size of the Filesystem in bytes - /// - public override long Size - { - get { return _wrapped.Size; } - } - - /// - /// Used space of the Filesystem in bytes - /// - public override long UsedSpace - { - get { return _wrapped.UsedSpace; } - } - - /// - /// Available space of the Filesystem in bytes - /// - public override long AvailableSpace - { - get { return _wrapped.AvailableSpace; } - } - - /// - /// Provides access to the actual file system implementation. - /// - /// The concrete type representing directory entries. - /// The concrete type representing files. - /// The concrete type representing directories. - /// The concrete type holding global state. - /// The actual file system instance. - protected VfsFileSystem GetRealFileSystem - () - where TDirEntry : VfsDirEntry - where TFile : IVfsFile - where TDirectory : class, IVfsDirectory, TFile - where TContext : VfsContext - { - return (VfsFileSystem)_wrapped; - } - - /// - /// Provides access to the actual file system implementation. - /// - /// The concrete type of the actual file system. - /// The actual file system instance. - protected T GetRealFileSystem() - where T : DiscFileSystem - { - return (T)_wrapped; - } - } -} diff --git a/src/LibHac.Nand/DiscUtils.Core/Vfs/VfsFileSystemFactory.cs b/src/LibHac.Nand/DiscUtils.Core/Vfs/VfsFileSystemFactory.cs deleted file mode 100644 index 4c938800..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Vfs/VfsFileSystemFactory.cs +++ /dev/null @@ -1,63 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System.IO; - -namespace DiscUtils.Vfs -{ - /// - /// Base class for logic to detect file systems. - /// - public abstract class VfsFileSystemFactory - { - /// - /// Detects if a stream contains any known file systems. - /// - /// The stream to inspect. - /// A list of file systems (may be empty). - public FileSystemInfo[] Detect(Stream stream) - { - return Detect(stream, null); - } - - /// - /// Detects if a volume contains any known file systems. - /// - /// The volume to inspect. - /// A list of file systems (may be empty). - public FileSystemInfo[] Detect(VolumeInfo volume) - { - using (Stream stream = volume.Open()) - { - return Detect(stream, volume); - } - } - - /// - /// The logic for detecting file systems. - /// - /// The stream to inspect. - /// Optionally, information about the volume. - /// A list of file systems detected (may be empty). - public abstract FileSystemInfo[] Detect(Stream stream, VolumeInfo volumeInfo); - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Vfs/VfsFileSystemFactoryAttribute.cs b/src/LibHac.Nand/DiscUtils.Core/Vfs/VfsFileSystemFactoryAttribute.cs deleted file mode 100644 index aa370e06..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Vfs/VfsFileSystemFactoryAttribute.cs +++ /dev/null @@ -1,32 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; - -namespace DiscUtils.Vfs -{ - /// - /// Attribute identifying file system factory classes. - /// - [AttributeUsage(AttributeTargets.Class)] - public sealed class VfsFileSystemFactoryAttribute : Attribute {} -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Vfs/VfsFileSystemInfo.cs b/src/LibHac.Nand/DiscUtils.Core/Vfs/VfsFileSystemInfo.cs deleted file mode 100644 index 685f1d21..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Vfs/VfsFileSystemInfo.cs +++ /dev/null @@ -1,79 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System.IO; - -namespace DiscUtils.Vfs -{ - /// - /// Class holding information about a file system. - /// - public sealed class VfsFileSystemInfo : FileSystemInfo - { - private readonly VfsFileSystemOpener _openDelegate; - - /// - /// Initializes a new instance of the VfsFileSystemInfo class. - /// - /// The name of the file system. - /// A one-line description of the file system. - /// A delegate that can open streams as the indicated file system. - public VfsFileSystemInfo(string name, string description, VfsFileSystemOpener openDelegate) - { - Name = name; - Description = description; - _openDelegate = openDelegate; - } - - /// - /// Gets a one-line description of the file system. - /// - public override string Description { get; } - - /// - /// Gets the name of the file system. - /// - public override string Name { get; } - - /// - /// Opens a volume using the file system. - /// - /// The volume to access. - /// Parameters for the file system. - /// A file system instance. - public override DiscFileSystem Open(VolumeInfo volume, FileSystemParameters parameters) - { - return _openDelegate(volume.Open(), volume, parameters); - } - - /// - /// Opens a stream using the file system. - /// - /// The stream to access. - /// Parameters for the file system. - /// A file system instance. - public override DiscFileSystem Open(Stream stream, FileSystemParameters parameters) - { - return _openDelegate(stream, null, parameters); - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Vfs/VfsFileSystemOpener.cs b/src/LibHac.Nand/DiscUtils.Core/Vfs/VfsFileSystemOpener.cs deleted file mode 100644 index cbda9e87..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Vfs/VfsFileSystemOpener.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System.IO; - -namespace DiscUtils.Vfs -{ - /// - /// Delegate for instantiating a file system. - /// - /// The stream containing the file system. - /// Optional, information about the volume the file system is on. - /// Parameters for the file system. - /// A file system implementation. - public delegate DiscFileSystem VfsFileSystemOpener( - Stream stream, VolumeInfo volumeInfo, FileSystemParameters parameters); -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/Vfs/VfsReadOnlyFileSystem.cs b/src/LibHac.Nand/DiscUtils.Core/Vfs/VfsReadOnlyFileSystem.cs deleted file mode 100644 index c7528f65..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/Vfs/VfsReadOnlyFileSystem.cs +++ /dev/null @@ -1,169 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.IO; -using DiscUtils.Streams; - -namespace DiscUtils.Vfs -{ - /// - /// Base class for read-only file system implementations. - /// - /// The concrete type representing directory entries. - /// The concrete type representing files. - /// The concrete type representing directories. - /// The concrete type holding global state. - public abstract class VfsReadOnlyFileSystem : - VfsFileSystem - where TDirEntry : VfsDirEntry - where TFile : IVfsFile - where TDirectory : class, IVfsDirectory, TFile - where TContext : VfsContext - { - /// - /// Initializes a new instance of the VfsReadOnlyFileSystem class. - /// - /// The default file system options. - protected VfsReadOnlyFileSystem(DiscFileSystemOptions defaultOptions) - : base(defaultOptions) {} - - /// - /// Indicates whether the file system is read-only or read-write. - /// - /// Always false. - public override bool CanWrite - { - get { return false; } - } - - /// - /// Copies a file - not supported on read-only file systems. - /// - /// The source file. - /// The destination file. - /// Whether to permit over-writing of an existing file. - public override void CopyFile(string sourceFile, string destinationFile, bool overwrite) - { - throw new NotSupportedException(); - } - - /// - /// Creates a directory - not supported on read-only file systems. - /// - /// The path of the new directory. - public override void CreateDirectory(string path) - { - throw new NotSupportedException(); - } - - /// - /// Deletes a directory - not supported on read-only file systems. - /// - /// The path of the directory to delete. - public override void DeleteDirectory(string path) - { - throw new NotSupportedException(); - } - - /// - /// Deletes a file - not supported on read-only file systems. - /// - /// The path of the file to delete. - public override void DeleteFile(string path) - { - throw new NotSupportedException(); - } - - /// - /// Moves a directory - not supported on read-only file systems. - /// - /// The directory to move. - /// The target directory name. - public override void MoveDirectory(string sourceDirectoryName, string destinationDirectoryName) - { - throw new NotSupportedException(); - } - - /// - /// Moves a file - not supported on read-only file systems. - /// - /// The file to move. - /// The target file name. - /// Whether to allow an existing file to be overwritten. - public override void MoveFile(string sourceName, string destinationName, bool overwrite) - { - throw new NotSupportedException(); - } - - /// - /// Opens the specified file. - /// - /// The full path of the file to open. - /// The file mode for the created stream. - /// The new stream. - public override SparseStream OpenFile(string path, FileMode mode) - { - return OpenFile(path, mode, FileAccess.Read); - } - - /// - /// Sets the attributes of a file or directory - not supported on read-only file systems. - /// - /// The file or directory to change. - /// The new attributes of the file or directory. - public override void SetAttributes(string path, FileAttributes newValue) - { - throw new NotSupportedException(); - } - - /// - /// Sets the creation time (in UTC) of a file or directory - not supported on read-only file systems. - /// - /// The path of the file or directory. - /// The new time to set. - public override void SetCreationTimeUtc(string path, DateTime newTime) - { - throw new NotSupportedException(); - } - - /// - /// Sets the last access time (in UTC) of a file or directory - not supported on read-only file systems. - /// - /// The path of the file or directory. - /// The new time to set. - public override void SetLastAccessTimeUtc(string path, DateTime newTime) - { - throw new NotSupportedException(); - } - - /// - /// Sets the last modification time (in UTC) of a file or directory - not supported on read-only file systems. - /// - /// The path of the file or directory. - /// The new time to set. - public override void SetLastWriteTimeUtc(string path, DateTime newTime) - { - throw new NotSupportedException(); - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/VirtualDisk.cs b/src/LibHac.Nand/DiscUtils.Core/VirtualDisk.cs deleted file mode 100644 index d3c3239a..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/VirtualDisk.cs +++ /dev/null @@ -1,641 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; -using System.Globalization; -using System.IO; -using DiscUtils.Internal; -using DiscUtils.Partitions; -using DiscUtils.Streams; - -namespace DiscUtils -{ - /// - /// Base class representing virtual hard disks. - /// - public abstract class VirtualDisk : -#if !NETCORE - MarshalByRefObject, -#endif - IDisposable - { - private VirtualDiskTransport _transport; - - /// - /// Finalizes an instance of the VirtualDisk class. - /// - ~VirtualDisk() - { - Dispose(false); - } - - /// - /// Gets the set of disk formats supported as an array of file extensions. - /// - [Obsolete("Use VirtualDiskManager.SupportedDiskFormats")] - public static ICollection SupportedDiskFormats - { - get { return VirtualDiskManager.SupportedDiskFormats; } - } - - /// - /// Gets the set of disk types supported, as an array of identifiers. - /// - [Obsolete("Use VirtualDiskManager.SupportedDiskTypes")] - public static ICollection SupportedDiskTypes - { - get { return VirtualDiskManager.SupportedDiskTypes; } - } - - /// - /// Gets the geometry of the disk. - /// - public abstract Geometry Geometry { get; } - - /// - /// Gets the geometry of the disk as it is anticipated a hypervisor BIOS will represent it. - /// - public virtual Geometry BiosGeometry - { - get { return Geometry.MakeBiosSafe(Geometry, Capacity); } - } - - /// - /// Gets the type of disk represented by this object. - /// - public abstract VirtualDiskClass DiskClass { get; } - - /// - /// Gets the capacity of the disk (in bytes). - /// - public abstract long Capacity { get; } - - /// - /// Gets the size of the disk's logical blocks (aka sector size), in bytes. - /// - public virtual int BlockSize - { - get { return Sizes.Sector; } - } - - /// - /// Gets the logical sector size of the disk, in bytes. - /// - /// This is an alias for the BlockSize property. - public int SectorSize - { - get { return BlockSize; } - } - - /// - /// Gets the content of the disk as a stream. - /// - /// Note the returned stream is not guaranteed to be at any particular position. The actual position - /// will depend on the last partition table/file system activity, since all access to the disk contents pass - /// through a single stream instance. Set the stream position before accessing the stream. - public abstract SparseStream Content { get; } - - /// - /// Gets the layers that make up the disk. - /// - public abstract IEnumerable Layers { get; } - - /// - /// Gets or sets the Windows disk signature of the disk, which uniquely identifies the disk. - /// - public virtual int Signature - { - get { return EndianUtilities.ToInt32LittleEndian(GetMasterBootRecord(), 0x01B8); } - - set - { - byte[] mbr = GetMasterBootRecord(); - EndianUtilities.WriteBytesLittleEndian(value, mbr, 0x01B8); - SetMasterBootRecord(mbr); - } - } - - /// - /// Gets a value indicating whether the disk appears to have a valid partition table. - /// - /// There is no reliable way to determine whether a disk has a valid partition - /// table. The 'guess' consists of checking for basic indicators and looking for obviously - /// invalid data, such as overlapping partitions. - public virtual bool IsPartitioned - { - get { return PartitionTable.IsPartitioned(Content); } - } - - /// - /// Gets the object that interprets the partition structure. - /// - /// It is theoretically possible for a disk to contain two independent partition structures - a - /// BIOS/GPT one and an Apple one, for example. This method will return in order of preference, - /// a GUID partition table, a BIOS partition table, then in undefined preference one of any other partition - /// tables found. See PartitionTable.GetPartitionTables to gain access to all the discovered partition - /// tables on a disk. - public virtual PartitionTable Partitions - { - get - { - IList tables = PartitionTable.GetPartitionTables(this); - if (tables == null || tables.Count == 0) - { - return null; - } - if (tables.Count == 1) - { - return tables[0]; - } - PartitionTable best = null; - int bestScore = -1; - for (int i = 0; i < tables.Count; ++i) - { - int newScore = 0; - if (tables[i] is GuidPartitionTable) - { - newScore = 2; - } - else if (tables[i] is BiosPartitionTable) - { - newScore = 1; - } - - if (newScore > bestScore) - { - bestScore = newScore; - best = tables[i]; - } - } - - return best; - } - } - - /// - /// Gets the parameters of the disk. - /// - /// Most of the parameters are also available individually, such as DiskType and Capacity. - public virtual VirtualDiskParameters Parameters - { - get - { - return new VirtualDiskParameters - { - DiskType = DiskClass, - Capacity = Capacity, - Geometry = Geometry, - BiosGeometry = BiosGeometry, - AdapterType = GenericDiskAdapterType.Ide - }; - } - } - - /// - /// Gets information about the type of disk. - /// - /// This property provides access to meta-data about the disk format, for example whether the - /// BIOS geometry is preserved in the disk file. - public abstract VirtualDiskTypeInfo DiskTypeInfo { get; } - - /// - /// Gets the set of supported variants of a type of virtual disk. - /// - /// A type, as returned by . - /// A collection of identifiers, or empty if there is no variant concept for this type of disk. - public static ICollection GetSupportedDiskVariants(string type) - { - return VirtualDiskManager.TypeMap[type].Variants; - } - - /// - /// Gets information about disk type. - /// - /// The disk type, as returned by . - /// The variant of the disk type. - /// Information about the disk type. - public static VirtualDiskTypeInfo GetDiskType(string type, string variant) - { - return VirtualDiskManager.TypeMap[type].GetDiskTypeInformation(variant); - } - - /// - /// Create a new virtual disk, possibly within an existing disk. - /// - /// The file system to create the disk on. - /// The type of disk to create (see ). - /// The variant of the type to create (see ). - /// The path (or URI) for the disk to create. - /// The capacity of the new disk. - /// The geometry of the new disk (or null). - /// Untyped parameters controlling the creation process (TBD). - /// The newly created disk. - public static VirtualDisk CreateDisk(DiscFileSystem fileSystem, string type, string variant, string path, long capacity, Geometry geometry, Dictionary parameters) - { - VirtualDiskFactory factory = VirtualDiskManager.TypeMap[type]; - - VirtualDiskParameters diskParams = new VirtualDiskParameters - { - AdapterType = GenericDiskAdapterType.Scsi, - Capacity = capacity, - Geometry = geometry - }; - - if (parameters != null) - { - foreach (string key in parameters.Keys) - { - diskParams.ExtendedParameters[key] = parameters[key]; - } - } - - return factory.CreateDisk(new DiscFileLocator(fileSystem, Utilities.GetDirectoryFromPath(path)), variant.ToLowerInvariant(), Utilities.GetFileFromPath(path), diskParams); - } - - /// - /// Create a new virtual disk. - /// - /// The type of disk to create (see ). - /// The variant of the type to create (see ). - /// The path (or URI) for the disk to create. - /// The capacity of the new disk. - /// The geometry of the new disk (or null). - /// Untyped parameters controlling the creation process (TBD). - /// The newly created disk. - public static VirtualDisk CreateDisk(string type, string variant, string path, long capacity, Geometry geometry, Dictionary parameters) - { - return CreateDisk(type, variant, path, capacity, geometry, null, null, parameters); - } - - /// - /// Create a new virtual disk. - /// - /// The type of disk to create (see ). - /// The variant of the type to create (see ). - /// The path (or URI) for the disk to create. - /// The capacity of the new disk. - /// The geometry of the new disk (or null). - /// The user identity to use when accessing the path (or null). - /// The password to use when accessing the path (or null). - /// Untyped parameters controlling the creation process (TBD). - /// The newly created disk. - public static VirtualDisk CreateDisk(string type, string variant, string path, long capacity, Geometry geometry, string user, string password, Dictionary parameters) - { - VirtualDiskParameters diskParams = new VirtualDiskParameters - { - AdapterType = GenericDiskAdapterType.Scsi, - Capacity = capacity, - Geometry = geometry - }; - - if (parameters != null) - { - foreach (string key in parameters.Keys) - { - diskParams.ExtendedParameters[key] = parameters[key]; - } - } - - return CreateDisk(type, variant, path, diskParams, user, password); - } - - /// - /// Create a new virtual disk. - /// - /// The type of disk to create (see ). - /// The variant of the type to create (see ). - /// The path (or URI) for the disk to create. - /// Parameters controlling the capacity, geometry, etc of the new disk. - /// The user identity to use when accessing the path (or null). - /// The password to use when accessing the path (or null). - /// The newly created disk. - public static VirtualDisk CreateDisk(string type, string variant, string path, VirtualDiskParameters diskParameters, string user, string password) - { - Uri uri = PathToUri(path); - VirtualDisk result = null; - - Type transportType; - if (!VirtualDiskManager.DiskTransports.TryGetValue(uri.Scheme.ToUpperInvariant(), out transportType)) - { - throw new FileNotFoundException(string.Format(CultureInfo.InvariantCulture, "Unable to parse path '{0}'", path), path); - } - - VirtualDiskTransport transport = (VirtualDiskTransport)Activator.CreateInstance(transportType); - - try - { - transport.Connect(uri, user, password); - - if (transport.IsRawDisk) - { - result = transport.OpenDisk(FileAccess.ReadWrite); - } - else - { - VirtualDiskFactory factory = VirtualDiskManager.TypeMap[type]; - - result = factory.CreateDisk(transport.GetFileLocator(), variant.ToLowerInvariant(), Utilities.GetFileFromPath(path), diskParameters); - } - - if (result != null) - { - result._transport = transport; - transport = null; - } - - return result; - } - finally - { - if (transport != null) - { - transport.Dispose(); - } - } - } - - /// - /// Opens an existing virtual disk. - /// - /// The path of the virtual disk to open, can be a URI. - /// The desired access to the disk. - /// The Virtual Disk, or null if an unknown disk format. - public static VirtualDisk OpenDisk(string path, FileAccess access) - { - return OpenDisk(path, null, access, null, null); - } - - /// - /// Opens an existing virtual disk. - /// - /// The path of the virtual disk to open, can be a URI. - /// The desired access to the disk. - /// The user name to use for authentication (if necessary). - /// The password to use for authentication (if necessary). - /// The Virtual Disk, or null if an unknown disk format. - public static VirtualDisk OpenDisk(string path, FileAccess access, string user, string password) - { - return OpenDisk(path, null, access, user, password); - } - - /// - /// Opens an existing virtual disk. - /// - /// The path of the virtual disk to open, can be a URI. - /// Force the detected disk type (null to detect). - /// The desired access to the disk. - /// The user name to use for authentication (if necessary). - /// The password to use for authentication (if necessary). - /// The Virtual Disk, or null if an unknown disk format. - /// - /// The detected disk type can be forced by specifying a known disk type: - /// RAW, VHD, VMDK, etc. - /// - public static VirtualDisk OpenDisk(string path, string forceType, FileAccess access, string user, string password) - { - Uri uri = PathToUri(path); - VirtualDisk result = null; - - Type transportType; - if (!VirtualDiskManager.DiskTransports.TryGetValue(uri.Scheme.ToUpperInvariant(), out transportType)) - { - throw new FileNotFoundException(string.Format(CultureInfo.InvariantCulture, "Unable to parse path '{0}'", path), path); - } - - VirtualDiskTransport transport = (VirtualDiskTransport)Activator.CreateInstance(transportType); - - try - { - transport.Connect(uri, user, password); - - if (transport.IsRawDisk) - { - result = transport.OpenDisk(access); - } - else - { - bool foundFactory; - VirtualDiskFactory factory; - - if (!string.IsNullOrEmpty(forceType)) - { - foundFactory = VirtualDiskManager.TypeMap.TryGetValue(forceType, out factory); - } - else - { - string extension = Path.GetExtension(uri.AbsolutePath).ToUpperInvariant(); - if (extension.StartsWith(".", StringComparison.Ordinal)) - { - extension = extension.Substring(1); - } - - foundFactory = VirtualDiskManager.ExtensionMap.TryGetValue(extension, out factory); - } - - if (foundFactory) - { - result = factory.OpenDisk(transport.GetFileLocator(), transport.GetFileName(), access); - } - } - - if (result != null) - { - result._transport = transport; - transport = null; - } - - return result; - } - finally - { - if (transport != null) - { - transport.Dispose(); - } - } - } - - /// - /// Opens an existing virtual disk, possibly from within an existing disk. - /// - /// The file system to open the disk on. - /// The path of the virtual disk to open. - /// The desired access to the disk. - /// The Virtual Disk, or null if an unknown disk format. - public static VirtualDisk OpenDisk(DiscFileSystem fs, string path, FileAccess access) - { - if (fs == null) - { - return OpenDisk(path, access); - } - - string extension = Path.GetExtension(path).ToUpperInvariant(); - if (extension.StartsWith(".", StringComparison.Ordinal)) - { - extension = extension.Substring(1); - } - - VirtualDiskFactory factory; - if (VirtualDiskManager.ExtensionMap.TryGetValue(extension, out factory)) - { - return factory.OpenDisk(fs, path, access); - } - - return null; - } - - /// - /// Disposes of this instance, freeing underlying resources. - /// - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - /// - /// Reads the first sector of the disk, known as the Master Boot Record. - /// - /// The MBR as a byte array. - public virtual byte[] GetMasterBootRecord() - { - byte[] sector = new byte[Sizes.Sector]; - - long oldPos = Content.Position; - Content.Position = 0; - StreamUtilities.ReadExact(Content, sector, 0, Sizes.Sector); - Content.Position = oldPos; - - return sector; - } - - /// - /// Overwrites the first sector of the disk, known as the Master Boot Record. - /// - /// The master boot record, must be 512 bytes in length. - public virtual void SetMasterBootRecord(byte[] data) - { - if (data == null) - { - throw new ArgumentNullException(nameof(data)); - } - if (data.Length != Sizes.Sector) - { - throw new ArgumentException("The Master Boot Record must be exactly 512 bytes in length", nameof(data)); - } - - long oldPos = Content.Position; - Content.Position = 0; - Content.Write(data, 0, Sizes.Sector); - Content.Position = oldPos; - } - - /// - /// Create a new differencing disk, possibly within an existing disk. - /// - /// The file system to create the disk on. - /// The path (or URI) for the disk to create. - /// The newly created disk. - public abstract VirtualDisk CreateDifferencingDisk(DiscFileSystem fileSystem, string path); - - /// - /// Create a new differencing disk. - /// - /// The path (or URI) for the disk to create. - /// The newly created disk. - public abstract VirtualDisk CreateDifferencingDisk(string path); - - internal static VirtualDiskLayer OpenDiskLayer(FileLocator locator, string path, FileAccess access) - { - string extension = Path.GetExtension(path).ToUpperInvariant(); - if (extension.StartsWith(".", StringComparison.Ordinal)) - { - extension = extension.Substring(1); - } - - VirtualDiskFactory factory; - if (VirtualDiskManager.ExtensionMap.TryGetValue(extension, out factory)) - { - return factory.OpenDiskLayer(locator, path, access); - } - - return null; - } - - /// - /// Disposes of underlying resources. - /// - /// true if running inside Dispose(), indicating - /// graceful cleanup of all managed objects should be performed, or false - /// if running inside destructor. - protected virtual void Dispose(bool disposing) - { - if (disposing) - { - if (_transport != null) - { - _transport.Dispose(); - } - - _transport = null; - } - } - - private static Uri PathToUri(string path) - { - if (string.IsNullOrEmpty(path)) - { - throw new ArgumentException("Path must not be null or empty", nameof(path)); - } - - if (path.Contains("://")) - { - return new Uri(path); - } - - if (!Path.IsPathRooted(path)) - { - path = Path.GetFullPath(path); - } - - // Built-in Uri class does cope well with query params on file Uris, so do some - // parsing ourselves... - if (path.Length >= 1 && path[0] == '\\') - { - UriBuilder builder = new UriBuilder("file:" + path.Replace('\\', '/')); - return builder.Uri; - } - if (path.StartsWith("//", StringComparison.OrdinalIgnoreCase)) - { - UriBuilder builder = new UriBuilder("file:" + path); - return builder.Uri; - } - if (path.Length >= 2 && path[1] == ':') - { - UriBuilder builder = new UriBuilder("file:///" + path.Replace('\\', '/')); - return builder.Uri; - } - return new Uri(path); - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/VirtualDiskClass.cs b/src/LibHac.Nand/DiscUtils.Core/VirtualDiskClass.cs deleted file mode 100644 index 9c4d4ba6..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/VirtualDiskClass.cs +++ /dev/null @@ -1,50 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -namespace DiscUtils -{ - /// - /// Enumeration of different classes of disk. - /// - public enum VirtualDiskClass - { - /// - /// Unknown (or unspecified) type. - /// - None = 0, - - /// - /// Hard disk. - /// - HardDisk = 1, - - /// - /// Optical disk, such as CD or DVD. - /// - OpticalDisk = 2, - - /// - /// Floppy disk. - /// - FloppyDisk = 3 - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/VirtualDiskExtent.cs b/src/LibHac.Nand/DiscUtils.Core/VirtualDiskExtent.cs deleted file mode 100644 index 86eb3c1a..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/VirtualDiskExtent.cs +++ /dev/null @@ -1,78 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using DiscUtils.Streams; - -namespace DiscUtils -{ - /// - /// Base class represented a stored extent of a virtual disk. - /// - /// - /// Some file formats can divide a logical disk layer into multiple extents, stored in - /// different files. This class represents those extents. Normally, all virtual disks - /// have at least one extent. - /// - public abstract class VirtualDiskExtent : IDisposable - { - /// - /// Gets the capacity of the extent (in bytes). - /// - public abstract long Capacity { get; } - - /// - /// Gets a value indicating whether the extent only stores meaningful sectors. - /// - public abstract bool IsSparse { get; } - - /// - /// Gets the size of the extent (in bytes) on underlying storage. - /// - public abstract long StoredSize { get; } - - /// - /// Disposes of this instance, freeing underlying resources. - /// - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - /// - /// Gets the content of this extent. - /// - /// The parent stream (if any). - /// Controls ownership of the parent stream. - /// The content as a stream. - public abstract MappedStream OpenContent(SparseStream parent, Ownership ownsParent); - - /// - /// Disposes of underlying resources. - /// - /// true if running inside Dispose(), indicating - /// graceful cleanup of all managed objects should be performed, or false - /// if running inside destructor. - protected virtual void Dispose(bool disposing) {} - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/VirtualDiskLayer.cs b/src/LibHac.Nand/DiscUtils.Core/VirtualDiskLayer.cs deleted file mode 100644 index eb6eb7b2..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/VirtualDiskLayer.cs +++ /dev/null @@ -1,126 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; -using DiscUtils.Streams; - -namespace DiscUtils -{ - /// - /// Represents the base layer, or a differencing layer of a VirtualDisk. - /// - /// - /// VirtualDisks are composed of one or more layers - a base layer - /// which represents the entire disk (even if not all bytes are actually stored), - /// and a number of differencing layers that store the disk sectors that are - /// logically different to the base layer. - /// Disk Layers may not store all sectors. Any sectors that are not stored - /// are logically zero's (for base layers), or holes through to the layer underneath - /// (all other layers). - /// - public abstract class VirtualDiskLayer : IDisposable - { - /// - /// Gets the capacity of the disk (in bytes). - /// - internal abstract long Capacity { get; } - - /// - /// Gets and sets the logical extents that make up this layer. - /// - public virtual IList Extents - { - get { return new List(); } - } - - /// - /// Gets the full path to this disk layer, or empty string. - /// - public virtual string FullPath - { - get { return string.Empty; } - } - - /// - /// Gets the geometry of the virtual disk layer. - /// - public abstract Geometry Geometry { get; } - - /// - /// Gets a value indicating whether the layer only stores meaningful sectors. - /// - public abstract bool IsSparse { get; } - - /// - /// Gets a value indicating whether this is a differential disk. - /// - public abstract bool NeedsParent { get; } - - /// - /// Gets a FileLocator that can resolve relative paths, or null. - /// - /// - /// Typically used to locate parent disks. - /// - internal abstract FileLocator RelativeFileLocator { get; } - - /// - /// Disposes of this instance, freeing underlying resources. - /// - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - /// - /// Finalizes an instance of the VirtualDiskLayer class. - /// - ~VirtualDiskLayer() - { - Dispose(false); - } - - /// - /// Gets the content of this layer. - /// - /// The parent stream (if any). - /// Controls ownership of the parent stream. - /// The content as a stream. - public abstract SparseStream OpenContent(SparseStream parent, Ownership ownsParent); - - /// - /// Gets the possible locations of the parent file (if any). - /// - /// Array of strings, empty if no parent. - public abstract string[] GetParentLocations(); - - /// - /// Disposes of underlying resources. - /// - /// true if running inside Dispose(), indicating - /// graceful cleanup of all managed objects should be performed, or false - /// if running inside destructor. - protected virtual void Dispose(bool disposing) {} - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/VirtualDiskManager.cs b/src/LibHac.Nand/DiscUtils.Core/VirtualDiskManager.cs deleted file mode 100644 index d46226a8..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/VirtualDiskManager.cs +++ /dev/null @@ -1,70 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Reflection; -using DiscUtils.CoreCompat; -using DiscUtils.Internal; - -namespace DiscUtils -{ - /// - /// Helps discover and use VirtualDiskFactory's - /// - public static class VirtualDiskManager - { - static VirtualDiskManager() - { - ExtensionMap = new Dictionary(); - TypeMap = new Dictionary(); - DiskTransports = new Dictionary(); - } - - internal static Dictionary DiskTransports { get; } - internal static Dictionary ExtensionMap { get; } - - /// - /// Gets the set of disk formats supported as an array of file extensions. - /// - public static ICollection SupportedDiskFormats - { - get { return ExtensionMap.Keys; } - } - - /// - /// Gets the set of disk types supported, as an array of identifiers. - /// - public static ICollection SupportedDiskTypes - { - get { return TypeMap.Keys; } - } - - internal static Dictionary TypeMap { get; } - - /// - /// Locates VirtualDiskFactory factories attributed with VirtualDiskFactoryAttribute, and types marked with VirtualDiskTransportAttribute, that are able to work with Virtual Disk types. - /// - /// An assembly to scan - public static void RegisterVirtualDiskTypes(Assembly assembly) - { - foreach (Type type in assembly.GetTypes()) - { - VirtualDiskFactoryAttribute diskFactoryAttribute = (VirtualDiskFactoryAttribute)ReflectionHelper.GetCustomAttribute(type, typeof(VirtualDiskFactoryAttribute), false); - if (diskFactoryAttribute != null) - { - VirtualDiskFactory factory = (VirtualDiskFactory)Activator.CreateInstance(type); - TypeMap.Add(diskFactoryAttribute.Type, factory); - - foreach (string extension in diskFactoryAttribute.FileExtensions) - { - ExtensionMap.Add(extension.ToUpperInvariant(), factory); - } - } - - VirtualDiskTransportAttribute diskTransportAttribute = ReflectionHelper.GetCustomAttribute(type, typeof(VirtualDiskTransportAttribute), false) as VirtualDiskTransportAttribute; - if (diskTransportAttribute != null) - { - DiskTransports.Add(diskTransportAttribute.Scheme.ToUpperInvariant(), type); - } - } - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/VirtualDiskParameters.cs b/src/LibHac.Nand/DiscUtils.Core/VirtualDiskParameters.cs deleted file mode 100644 index 14b899c9..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/VirtualDiskParameters.cs +++ /dev/null @@ -1,65 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System.Collections.Generic; - -namespace DiscUtils -{ - /// - /// Common parameters for virtual disks. - /// - /// Not all attributes make sense for all kinds of disks, so some - /// may be null. Modifying instances of this class does not modify the - /// disk itself. - public sealed class VirtualDiskParameters - { - /// - /// Gets or sets the type of disk adapter. - /// - public GenericDiskAdapterType AdapterType { get; set; } - - /// - /// Gets or sets the logical (aka BIOS) geometry of the disk. - /// - public Geometry BiosGeometry { get; set; } - - /// - /// Gets or sets the disk capacity. - /// - public long Capacity { get; set; } - - /// - /// Gets or sets the type of disk (optical, hard disk, etc). - /// - public VirtualDiskClass DiskType { get; set; } - - /// - /// Gets a dictionary of extended parameters, that varies by disk type. - /// - public Dictionary ExtendedParameters { get; } = new Dictionary(); - - /// - /// Gets or sets the physical (aka IDE) geometry of the disk. - /// - public Geometry Geometry { get; set; } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/VirtualDiskTypeInfo.cs b/src/LibHac.Nand/DiscUtils.Core/VirtualDiskTypeInfo.cs deleted file mode 100644 index 7a7d3569..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/VirtualDiskTypeInfo.cs +++ /dev/null @@ -1,60 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -namespace DiscUtils -{ - /// - /// Information about a type of virtual disk. - /// - public sealed class VirtualDiskTypeInfo - { - /// - /// Gets or sets the algorithm for determining the geometry for a given disk capacity. - /// - public GeometryCalculation CalcGeometry { get; set; } - - /// - /// Gets or sets a value indicating whether this disk type can represent hard disks. - /// - public bool CanBeHardDisk { get; set; } - - /// - /// Gets or sets a value indicating whether this disk type requires a specific geometry for any given disk capacity. - /// - public bool DeterministicGeometry { get; set; } - - /// - /// Gets or sets the name of the virtual disk type. - /// - public string Name { get; set; } - - /// - /// Gets or sets a value indicating whether this disk type persists the BIOS geometry. - /// - public bool PreservesBiosGeometry { get; set; } - - /// - /// Gets or sets the variant of the virtual disk type. - /// - public string Variant { get; set; } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/VolumeInfo.cs b/src/LibHac.Nand/DiscUtils.Core/VolumeInfo.cs deleted file mode 100644 index 6b865544..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/VolumeInfo.cs +++ /dev/null @@ -1,80 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -#if !NETCORE -using System; -#endif -using DiscUtils.Streams; - -namespace DiscUtils -{ - /// - /// Base class that holds information about a disk volume. - /// - public abstract class VolumeInfo -#if !NETCORE - : MarshalByRefObject -#endif - { - internal VolumeInfo() {} - - /// - /// Gets the one-byte BIOS type for this volume, which indicates the content. - /// - public abstract byte BiosType { get; } - - /// - /// Gets the size of the volume, in bytes. - /// - public abstract long Length { get; } - - /// - /// Gets the stable volume identity. - /// - /// The stability of the identity depends the disk structure. - /// In some cases the identity may include a simple index, when no other information - /// is available. Best practice is to add disks to the Volume Manager in a stable - /// order, if the stability of this identity is paramount. - public abstract string Identity { get; } - - /// - /// Gets the disk geometry of the underlying storage medium, if any (may be null). - /// - public abstract Geometry PhysicalGeometry { get; } - - /// - /// Gets the disk geometry of the underlying storage medium (as used in BIOS calls), may be null. - /// - public abstract Geometry BiosGeometry { get; } - - /// - /// Gets the offset of this volume in the underlying storage medium, if any (may be Zero). - /// - public abstract long PhysicalStartSector { get; } - - /// - /// Opens the volume, providing access to it's contents. - /// - /// Stream that can access the volume's contents. - public abstract SparseStream Open(); - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/VolumeManager.cs b/src/LibHac.Nand/DiscUtils.Core/VolumeManager.cs deleted file mode 100644 index 0d59cf1c..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/VolumeManager.cs +++ /dev/null @@ -1,343 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; -using System.Globalization; -using System.IO; -using System.Reflection; -using DiscUtils.CoreCompat; -using DiscUtils.Internal; -using DiscUtils.Partitions; -using DiscUtils.Raw; -using DiscUtils.Streams; - -namespace DiscUtils -{ - /// - /// VolumeManager interprets partitions and other on-disk structures (possibly combining multiple disks). - /// - /// - /// Although file systems commonly are placed directly within partitions on a disk, in some - /// cases a logical volume manager / logical disk manager may be used, to combine disk regions in multiple - /// ways for data redundancy or other purposes. - /// - public sealed class VolumeManager -#if !NETCORE - : MarshalByRefObject -#endif - { - private static List s_logicalVolumeFactories; - private readonly List _disks; - private bool _needScan; - - private Dictionary _physicalVolumes; - private Dictionary _logicalVolumes; - private static readonly Assembly _coreAssembly = ReflectionHelper.GetAssembly(typeof(VolumeManager)); - - /// - /// Initializes a new instance of the VolumeManager class. - /// - public VolumeManager() - { - _disks = new List(); - _physicalVolumes = new Dictionary(); - _logicalVolumes = new Dictionary(); - } - - /// - /// Initializes a new instance of the VolumeManager class. - /// - /// The initial disk to add. - public VolumeManager(VirtualDisk initialDisk) - : this() - { - AddDisk(initialDisk); - } - - /// - /// Initializes a new instance of the VolumeManager class. - /// - /// Content of the initial disk to add. - public VolumeManager(Stream initialDiskContent) - : this() - { - AddDisk(initialDiskContent); - } - - private static List LogicalVolumeFactories - { - get - { - if (s_logicalVolumeFactories == null) - { - List factories = new List(); - factories.AddRange(GetLogicalVolumeFactories(_coreAssembly)); - s_logicalVolumeFactories = factories; - } - - return s_logicalVolumeFactories; - } - } - - private static IEnumerable GetLogicalVolumeFactories(Assembly assembly) - { - foreach (Type type in assembly.GetTypes()) - { - foreach (LogicalVolumeFactoryAttribute attr in ReflectionHelper.GetCustomAttributes(type, typeof(LogicalVolumeFactoryAttribute), false)) - { - yield return (LogicalVolumeFactory)Activator.CreateInstance(type); - } - } - } - - /// - /// Register new LogicalVolumeFactories detected in an assembly - /// - /// The assembly to inspect - public static void RegisterLogicalVolumeFactory(Assembly assembly) - { - if (assembly == _coreAssembly) return; - LogicalVolumeFactories.AddRange(GetLogicalVolumeFactories(assembly)); - } - - /// - /// Gets the physical volumes held on a disk. - /// - /// The contents of the disk to inspect. - /// An array of volumes. - /// - /// By preference, use the form of this method that takes a disk parameter. - /// If the disk isn't partitioned, this method returns the entire disk contents - /// as a single volume. - /// - public static PhysicalVolumeInfo[] GetPhysicalVolumes(Stream diskContent) - { - return GetPhysicalVolumes(new Disk(diskContent, Ownership.None)); - } - - /// - /// Gets the physical volumes held on a disk. - /// - /// The disk to inspect. - /// An array of volumes. - /// If the disk isn't partitioned, this method returns the entire disk contents - /// as a single volume. - public static PhysicalVolumeInfo[] GetPhysicalVolumes(VirtualDisk disk) - { - return new VolumeManager(disk).GetPhysicalVolumes(); - } - - /// - /// Adds a disk to the volume manager. - /// - /// The disk to add. - /// The GUID the volume manager will use to identify the disk. - public string AddDisk(VirtualDisk disk) - { - _needScan = true; - int ordinal = _disks.Count; - _disks.Add(disk); - return GetDiskId(ordinal); - } - - /// - /// Adds a disk to the volume manager. - /// - /// The contents of the disk to add. - /// The GUID the volume manager will use to identify the disk. - public string AddDisk(Stream content) - { - return AddDisk(new Disk(content, Ownership.None)); - } - - /// - /// Gets the physical volumes from all disks added to this volume manager. - /// - /// An array of physical volumes. - public PhysicalVolumeInfo[] GetPhysicalVolumes() - { - if (_needScan) - { - Scan(); - } - - return new List(_physicalVolumes.Values).ToArray(); - } - - /// - /// Gets the logical volumes from all disks added to this volume manager. - /// - /// An array of logical volumes. - public LogicalVolumeInfo[] GetLogicalVolumes() - { - if (_needScan) - { - Scan(); - } - - return new List(_logicalVolumes.Values).ToArray(); - } - - /// - /// Gets a particular volume, based on it's identity. - /// - /// The volume's identity. - /// The volume information for the volume, or returns null. - public VolumeInfo GetVolume(string identity) - { - if (_needScan) - { - Scan(); - } - - PhysicalVolumeInfo pvi; - if (_physicalVolumes.TryGetValue(identity, out pvi)) - { - return pvi; - } - - LogicalVolumeInfo lvi; - if (_logicalVolumes.TryGetValue(identity, out lvi)) - { - return lvi; - } - - return null; - } - - private static void MapPhysicalVolumes(IEnumerable physicalVols, Dictionary result) - { - foreach (PhysicalVolumeInfo physicalVol in physicalVols) - { - LogicalVolumeInfo lvi = new LogicalVolumeInfo( - physicalVol.PartitionIdentity, - physicalVol, - physicalVol.Open, - physicalVol.Length, - physicalVol.BiosType, - LogicalVolumeStatus.Healthy); - - result.Add(lvi.Identity, lvi); - } - } - - /// - /// Scans all of the disks for their physical and logical volumes. - /// - private void Scan() - { - Dictionary newPhysicalVolumes = ScanForPhysicalVolumes(); - Dictionary newLogicalVolumes = ScanForLogicalVolumes(newPhysicalVolumes.Values); - - _physicalVolumes = newPhysicalVolumes; - _logicalVolumes = newLogicalVolumes; - - _needScan = false; - } - - private Dictionary ScanForLogicalVolumes(IEnumerable physicalVols) - { - List unhandledPhysical = new List(); - Dictionary result = new Dictionary(); - - foreach (PhysicalVolumeInfo pvi in physicalVols) - { - bool handled = false; - foreach (LogicalVolumeFactory volFactory in LogicalVolumeFactories) - { - if (volFactory.HandlesPhysicalVolume(pvi)) - { - handled = true; - break; - } - } - - if (!handled) - { - unhandledPhysical.Add(pvi); - } - } - - MapPhysicalVolumes(unhandledPhysical, result); - - foreach (LogicalVolumeFactory volFactory in LogicalVolumeFactories) - { - volFactory.MapDisks(_disks, result); - } - - return result; - } - - private Dictionary ScanForPhysicalVolumes() - { - Dictionary result = new Dictionary(); - - // First scan physical volumes - for (int i = 0; i < _disks.Count; ++i) - { - VirtualDisk disk = _disks[i]; - string diskId = GetDiskId(i); - - if (PartitionTable.IsPartitioned(disk.Content)) - { - foreach (PartitionTable table in PartitionTable.GetPartitionTables(disk)) - { - foreach (PartitionInfo part in table.Partitions) - { - PhysicalVolumeInfo pvi = new PhysicalVolumeInfo(diskId, disk, part); - result.Add(pvi.Identity, pvi); - } - } - } - else - { - PhysicalVolumeInfo pvi = new PhysicalVolumeInfo(diskId, disk); - result.Add(pvi.Identity, pvi); - } - } - - return result; - } - - private string GetDiskId(int ordinal) - { - VirtualDisk disk = _disks[ordinal]; - if (disk.IsPartitioned) - { - Guid guid = disk.Partitions.DiskGuid; - if (guid != Guid.Empty) - { - return "DG" + guid.ToString("B"); - } - } - - int sig = disk.Signature; - if (sig != 0) - { - return "DS" + sig.ToString("X8", CultureInfo.InvariantCulture); - } - - return "DO" + ordinal; - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Core/WindowsFileInformation.cs b/src/LibHac.Nand/DiscUtils.Core/WindowsFileInformation.cs deleted file mode 100644 index 564d72f5..00000000 --- a/src/LibHac.Nand/DiscUtils.Core/WindowsFileInformation.cs +++ /dev/null @@ -1,58 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.IO; - -namespace DiscUtils -{ - /// - /// Common information for Windows files. - /// - public class WindowsFileInformation - { - /// - /// Gets or sets the last time the file was changed. - /// - public DateTime ChangeTime { get; set; } - - /// - /// Gets or sets the creation time of the file. - /// - public DateTime CreationTime { get; set; } - - /// - /// Gets or sets the file attributes. - /// - public FileAttributes FileAttributes { get; set; } - - /// - /// Gets or sets the last access time of the file. - /// - public DateTime LastAccessTime { get; set; } - - /// - /// Gets or sets the modification time of the file. - /// - public DateTime LastWriteTime { get; set; } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Fat/ClusterReader.cs b/src/LibHac.Nand/DiscUtils.Fat/ClusterReader.cs deleted file mode 100644 index 78310563..00000000 --- a/src/LibHac.Nand/DiscUtils.Fat/ClusterReader.cs +++ /dev/null @@ -1,95 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.IO; -using DiscUtils.Streams; - -namespace DiscUtils.Fat -{ - internal sealed class ClusterReader - { - private readonly int _bytesPerSector; - - /// - /// Pre-calculated value because of number of uses of this externally. - /// - private readonly int _clusterSize; - - private readonly int _firstDataSector; - private readonly int _sectorsPerCluster; - private readonly Stream _stream; - - public ClusterReader(Stream stream, int firstDataSector, int sectorsPerCluster, int bytesPerSector) - { - _stream = stream; - _firstDataSector = firstDataSector; - _sectorsPerCluster = sectorsPerCluster; - _bytesPerSector = bytesPerSector; - - _clusterSize = _sectorsPerCluster * _bytesPerSector; - } - - public int ClusterSize - { - get { return _clusterSize; } - } - - public void ReadCluster(uint cluster, byte[] buffer, int offset) - { - if (offset + ClusterSize > buffer.Length) - { - throw new ArgumentOutOfRangeException(nameof(offset), - "buffer is too small - cluster would overflow buffer"); - } - - uint firstSector = (uint)((cluster - 2) * _sectorsPerCluster + _firstDataSector); - - _stream.Position = firstSector * _bytesPerSector; - StreamUtilities.ReadExact(_stream, buffer, offset, _clusterSize); - } - - internal void WriteCluster(uint cluster, byte[] buffer, int offset) - { - if (offset + ClusterSize > buffer.Length) - { - throw new ArgumentOutOfRangeException(nameof(offset), - "buffer is too small - cluster would overflow buffer"); - } - - uint firstSector = (uint)((cluster - 2) * _sectorsPerCluster + _firstDataSector); - - _stream.Position = firstSector * _bytesPerSector; - - _stream.Write(buffer, offset, _clusterSize); - } - - internal void WipeCluster(uint cluster) - { - uint firstSector = (uint)((cluster - 2) * _sectorsPerCluster + _firstDataSector); - - _stream.Position = firstSector * _bytesPerSector; - - _stream.Write(new byte[_clusterSize], 0, _clusterSize); - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Fat/ClusterStream.cs b/src/LibHac.Nand/DiscUtils.Fat/ClusterStream.cs deleted file mode 100644 index 218e0d63..00000000 --- a/src/LibHac.Nand/DiscUtils.Fat/ClusterStream.cs +++ /dev/null @@ -1,452 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; -using System.IO; - -namespace DiscUtils.Fat -{ - internal class ClusterStream : Stream - { - private readonly FileAccess _access; - private readonly byte[] _clusterBuffer; - private readonly FileAllocationTable _fat; - - private readonly List _knownClusters; - private readonly ClusterReader _reader; - - private uint _currentCluster; - private uint _length; - private long _position; - - internal ClusterStream(FatFileSystem fileSystem, FileAccess access, uint firstCluster, uint length) - { - _access = access; - _reader = fileSystem.ClusterReader; - _fat = fileSystem.Fat; - _length = length; - - _knownClusters = new List(); - if (firstCluster != 0) - { - _knownClusters.Add(firstCluster); - } - else - { - _knownClusters.Add(FatBuffer.EndOfChain); - } - - if (_length == uint.MaxValue) - { - _length = DetectLength(); - } - - _currentCluster = uint.MaxValue; - _clusterBuffer = new byte[_reader.ClusterSize]; - } - - public override bool CanRead - { - get { return _access == FileAccess.Read || _access == FileAccess.ReadWrite; } - } - - public override bool CanSeek - { - get { return true; } - } - - public override bool CanWrite - { - get { return _access == FileAccess.ReadWrite || _access == FileAccess.Write; } - } - - public override long Length - { - get { return _length; } - } - - public override long Position - { - get { return _position; } - - set - { - if (value >= 0) - { - _position = value; - } - else - { - throw new ArgumentOutOfRangeException(nameof(value), "Attempt to move before beginning of stream"); - } - } - } - - public event FirstClusterChangedDelegate FirstClusterChanged; - - public override void Flush() {} - - public override int Read(byte[] buffer, int offset, int count) - { - if (!CanRead) - { - throw new IOException("Attempt to read from file not opened for read"); - } - - if (_position > _length) - { - return 0; - } - - if (count < 0) - { - throw new ArgumentOutOfRangeException(nameof(count), "Attempt to read negative number of bytes"); - } - - int target = count; - if (_length - _position < count) - { - target = (int)(_length - _position); - } - - if (!TryLoadCurrentCluster()) - { - if ((_position == _length || _position == DetectLength())) - { - return 0; - } - throw new IOException("Attempt to read beyond known clusters"); - } - - int numRead = 0; - while (numRead < target) - { - int clusterOffset = (int)(_position % _reader.ClusterSize); - int toCopy = Math.Min(_reader.ClusterSize - clusterOffset, target - numRead); - Array.Copy(_clusterBuffer, clusterOffset, buffer, offset + numRead, toCopy); - - // Remember how many we've read in total - numRead += toCopy; - - // Increment the position - _position += toCopy; - - // Abort if we've hit the end of the file - if (!TryLoadCurrentCluster()) - { - break; - } - } - - return numRead; - } - - public override long Seek(long offset, SeekOrigin origin) - { - long newPos = offset; - if (origin == SeekOrigin.Current) - { - newPos += _position; - } - else if (origin == SeekOrigin.End) - { - newPos += Length; - } - - _position = newPos; - return newPos; - } - - public override void SetLength(long value) - { - long desiredNumClusters = (value + _reader.ClusterSize - 1) / _reader.ClusterSize; - long actualNumClusters = (_length + _reader.ClusterSize - 1) / _reader.ClusterSize; - - if (desiredNumClusters < actualNumClusters) - { - uint cluster; - if (!TryGetClusterByPosition(value, out cluster)) - { - throw new IOException("Internal state corrupt - unable to find cluster"); - } - - uint firstToFree = _fat.GetNext(cluster); - _fat.SetEndOfChain(cluster); - _fat.FreeChain(firstToFree); - - while (_knownClusters.Count > desiredNumClusters) - { - _knownClusters.RemoveAt(_knownClusters.Count - 1); - } - - _knownClusters.Add(FatBuffer.EndOfChain); - - if (desiredNumClusters == 0) - { - FireFirstClusterAllocated(0); - } - } - else if (desiredNumClusters > actualNumClusters) - { - uint cluster; - while (!TryGetClusterByPosition(value, out cluster)) - { - cluster = ExtendChain(); - _reader.WipeCluster(cluster); - } - } - - if (_length != value) - { - _length = (uint)value; - if (_position > _length) - { - _position = _length; - } - } - } - - public override void Write(byte[] buffer, int offset, int count) - { - int bytesRemaining = count; - - if (!CanWrite) - { - throw new IOException("Attempting to write to file not opened for writing"); - } - - if (count < 0) - { - throw new ArgumentOutOfRangeException(nameof(count), count, - "Attempting to write negative number of bytes"); - } - - if (offset > buffer.Length || offset + count > buffer.Length) - { - throw new ArgumentException("Attempt to write bytes outside of the buffer"); - } - - // TODO: Free space check... - try - { - while (bytesRemaining > 0) - { - // Extend the stream until it encompasses _position - uint cluster; - while (!TryGetClusterByPosition(_position, out cluster)) - { - cluster = ExtendChain(); - _reader.WipeCluster(cluster); - } - - // Fill this cluster with as much data as we can (WriteToCluster preserves existing cluster - // data, if necessary) - int numWritten = WriteToCluster(cluster, (int)(_position % _reader.ClusterSize), buffer, offset, - bytesRemaining); - offset += numWritten; - bytesRemaining -= numWritten; - _position += numWritten; - } - - _length = (uint)Math.Max(_length, _position); - } - finally - { - _fat.Flush(); - } - } - - /// - /// Writes up to the next cluster boundary, making sure to preserve existing data in the cluster - /// that falls outside of the updated range. - /// - /// The cluster to write to. - /// The file position of the write (within the cluster). - /// The buffer with the new data. - /// Offset into buffer of the first byte to write. - /// The maximum number of bytes to write. - /// The number of bytes written - either count, or the number that fit up to - /// the cluster boundary. - private int WriteToCluster(uint cluster, int pos, byte[] buffer, int offset, int count) - { - if (pos == 0 && count >= _reader.ClusterSize) - { - _currentCluster = cluster; - Array.Copy(buffer, offset, _clusterBuffer, 0, _reader.ClusterSize); - - WriteCurrentCluster(); - - return _reader.ClusterSize; - } - - // Partial cluster, so need to read existing cluster data first - LoadCluster(cluster); - - int copyLength = Math.Min(count, _reader.ClusterSize - pos % _reader.ClusterSize); - Array.Copy(buffer, offset, _clusterBuffer, pos, copyLength); - - WriteCurrentCluster(); - - return copyLength; - } - - /// - /// Adds a new cluster to the end of the existing chain, by allocating a free cluster. - /// - /// The cluster allocated. - /// This method does not initialize the data in the cluster, the caller should - /// perform a write to ensure the cluster data is in known state. - private uint ExtendChain() - { - // Sanity check - make sure the final known cluster is the EOC marker - if (!_fat.IsEndOfChain(_knownClusters[_knownClusters.Count - 1])) - { - throw new IOException("Corrupt file system: final cluster isn't End-of-Chain"); - } - - uint cluster; - if (!_fat.TryGetFreeCluster(out cluster)) - { - throw new IOException("Out of disk space"); - } - - _fat.SetEndOfChain(cluster); - if (_knownClusters.Count == 1) - { - FireFirstClusterAllocated(cluster); - } - else - { - _fat.SetNext(_knownClusters[_knownClusters.Count - 2], cluster); - } - - _knownClusters[_knownClusters.Count - 1] = cluster; - _knownClusters.Add(_fat.GetNext(cluster)); - - return cluster; - } - - private void FireFirstClusterAllocated(uint cluster) - { - if (FirstClusterChanged != null) - { - FirstClusterChanged(cluster); - } - } - - private bool TryLoadCurrentCluster() - { - return TryLoadClusterByPosition(_position); - } - - private bool TryLoadClusterByPosition(long pos) - { - uint cluster; - if (!TryGetClusterByPosition(pos, out cluster)) - { - return false; - } - - // Read the cluster, it's different to the one currently loaded - if (cluster != _currentCluster) - { - _reader.ReadCluster(cluster, _clusterBuffer, 0); - _currentCluster = cluster; - } - - return true; - } - - private void LoadCluster(uint cluster) - { - // Read the cluster, it's different to the one currently loaded - if (cluster != _currentCluster) - { - _reader.ReadCluster(cluster, _clusterBuffer, 0); - _currentCluster = cluster; - } - } - - private void WriteCurrentCluster() - { - _reader.WriteCluster(_currentCluster, _clusterBuffer, 0); - } - - private bool TryGetClusterByPosition(long pos, out uint cluster) - { - int index = (int)(pos / _reader.ClusterSize); - - if (_knownClusters.Count <= index) - { - if (!TryPopulateKnownClusters(index)) - { - cluster = uint.MaxValue; - return false; - } - } - - // Chain is shorter than the current stream position - if (_knownClusters.Count <= index) - { - cluster = uint.MaxValue; - return false; - } - - cluster = _knownClusters[index]; - - // This is the 'special' End-of-chain cluster identifer, so the stream position - // is greater than the actual file length. - if (_fat.IsEndOfChain(cluster)) - { - return false; - } - - return true; - } - - private bool TryPopulateKnownClusters(int index) - { - uint lastKnown = _knownClusters[_knownClusters.Count - 1]; - while (!_fat.IsEndOfChain(lastKnown) && _knownClusters.Count <= index) - { - lastKnown = _fat.GetNext(lastKnown); - _knownClusters.Add(lastKnown); - } - - return _knownClusters.Count > index; - } - - private uint DetectLength() - { - while (!_fat.IsEndOfChain(_knownClusters[_knownClusters.Count - 1])) - { - if (!TryPopulateKnownClusters(_knownClusters.Count)) - { - throw new IOException("Corrupt file stream - unable to discover end of cluster chain"); - } - } - - return (uint)((_knownClusters.Count - 1) * (long)_reader.ClusterSize); - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Fat/Directory.cs b/src/LibHac.Nand/DiscUtils.Fat/Directory.cs deleted file mode 100644 index a7d45313..00000000 --- a/src/LibHac.Nand/DiscUtils.Fat/Directory.cs +++ /dev/null @@ -1,555 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; -using System.IO; -using System.Text; -using DiscUtils.Streams; - -namespace DiscUtils.Fat -{ - internal class Directory : IDisposable - { - private readonly Stream _dirStream; - private readonly Directory _parent; - private readonly long _parentId; - private long _endOfEntries; - - private Dictionary _entries; - private List _freeEntries; - private DirectoryEntry _parentEntry; - private long _parentEntryLocation; - - private DirectoryEntry _selfEntry; - private long _selfEntryLocation; - - /// - /// Initializes a new instance of the Directory class. Use this constructor to represent non-root directories. - /// - /// The parent directory. - /// The identity of the entry representing this directory in the parent. - internal Directory(Directory parent, long parentId) - { - FileSystem = parent.FileSystem; - _parent = parent; - _parentId = parentId; - - DirectoryEntry dirEntry = ParentsChildEntry; - _dirStream = new ClusterStream(FileSystem, FileAccess.ReadWrite, dirEntry.FirstCluster, uint.MaxValue); - - LoadEntries(); - } - - /// - /// Initializes a new instance of the Directory class. Use this constructor to represent the root directory. - /// - /// The file system. - /// The stream containing the directory info. - internal Directory(FatFileSystem fileSystem, Stream dirStream) - { - FileSystem = fileSystem; - _dirStream = dirStream; - - LoadEntries(); - } - - public DirectoryEntry[] Entries - { - get { return new List(_entries.Values).ToArray(); } - } - - public FatFileSystem FileSystem { get; } - - public bool IsEmpty - { - get { return _entries.Count == 0; } - } - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - public DirectoryEntry[] GetDirectories() - { - List dirs = new List(_entries.Count); - foreach (DirectoryEntry dirEntry in _entries.Values) - { - if ((dirEntry.Attributes & FatAttributes.Directory) != 0) - { - dirs.Add(dirEntry); - } - } - - return dirs.ToArray(); - } - - public DirectoryEntry[] GetFiles() - { - List files = new List(_entries.Count); - foreach (DirectoryEntry dirEntry in _entries.Values) - { - if ((dirEntry.Attributes & (FatAttributes.Directory | FatAttributes.VolumeId)) == 0) - { - files.Add(dirEntry); - } - } - - return files.ToArray(); - } - - public DirectoryEntry GetEntry(long id) - { - return id < 0 ? null : _entries[id]; - } - - public Directory GetChildDirectory(FileName name) - { - long id = FindEntry(name); - if (id < 0) - { - return null; - } - if ((_entries[id].Attributes & FatAttributes.Directory) == 0) - { - return null; - } - return FileSystem.GetDirectory(this, id); - } - - internal Directory CreateChildDirectory(FileName name) - { - long id = FindEntry(name); - if (id >= 0) - { - if ((_entries[id].Attributes & FatAttributes.Directory) == 0) - { - throw new IOException("A file exists with the same name"); - } - return FileSystem.GetDirectory(this, id); - } - try - { - uint firstCluster; - if (!FileSystem.Fat.TryGetFreeCluster(out firstCluster)) - { - throw new IOException("Failed to allocate first cluster for new directory"); - } - - FileSystem.Fat.SetEndOfChain(firstCluster); - - DirectoryEntry newEntry = new DirectoryEntry(FileSystem.FatOptions, name, FatAttributes.Directory, - FileSystem.FatVariant); - newEntry.FirstCluster = firstCluster; - newEntry.CreationTime = FileSystem.ConvertFromUtc(DateTime.UtcNow); - newEntry.LastWriteTime = newEntry.CreationTime; - - id = AddEntry(newEntry); - - PopulateNewChildDirectory(newEntry); - - // Rather than just creating a new instance, pull it through the fileSystem cache - // to ensure the cache model is preserved. - return FileSystem.GetDirectory(this, id); - } - finally - { - FileSystem.Fat.Flush(); - } - } - - internal void AttachChildDirectory(FileName name, Directory newChild) - { - long id = FindEntry(name); - if (id >= 0) - { - throw new IOException("Directory entry already exists"); - } - - DirectoryEntry newEntry = new DirectoryEntry(newChild.ParentsChildEntry); - newEntry.Name = name; - AddEntry(newEntry); - - DirectoryEntry newParentEntry = new DirectoryEntry(SelfEntry); - newParentEntry.Name = FileName.ParentEntryName; - newChild.ParentEntry = newParentEntry; - } - - internal long FindVolumeId() - { - foreach (long id in _entries.Keys) - { - DirectoryEntry focus = _entries[id]; - if ((focus.Attributes & FatAttributes.VolumeId) != 0) - { - return id; - } - } - - return -1; - } - - internal long FindEntry(FileName name) - { - foreach (long id in _entries.Keys) - { - DirectoryEntry focus = _entries[id]; - if (focus.Name == name && (focus.Attributes & FatAttributes.VolumeId) == 0) - { - return id; - } - } - - return -1; - } - - internal SparseStream OpenFile(FileName name, FileMode mode, FileAccess fileAccess) - { - if (mode == FileMode.Append || mode == FileMode.Truncate) - { - throw new NotImplementedException(); - } - - long fileId = FindEntry(name); - bool exists = fileId != -1; - - if (mode == FileMode.CreateNew && exists) - { - throw new IOException("File already exists"); - } - if (mode == FileMode.Open && !exists) - { - throw new FileNotFoundException("File not found", - name.GetDisplayName(FileSystem.FatOptions.FileNameEncoding)); - } - if ((mode == FileMode.Open || mode == FileMode.OpenOrCreate || mode == FileMode.Create) && exists) - { - SparseStream stream = new FatFileStream(FileSystem, this, fileId, fileAccess); - if (mode == FileMode.Create) - { - stream.SetLength(0); - } - - HandleAccessed(false); - - return stream; - } - if ((mode == FileMode.OpenOrCreate || mode == FileMode.CreateNew || mode == FileMode.Create) && !exists) - { - // Create new file - DirectoryEntry newEntry = new DirectoryEntry(FileSystem.FatOptions, name, FatAttributes.Archive, - FileSystem.FatVariant); - newEntry.FirstCluster = 0; // i.e. Zero-length - newEntry.CreationTime = FileSystem.ConvertFromUtc(DateTime.UtcNow); - newEntry.LastWriteTime = newEntry.CreationTime; - - fileId = AddEntry(newEntry); - - return new FatFileStream(FileSystem, this, fileId, fileAccess); - } - - // Should never get here... - throw new NotImplementedException(); - } - - internal long AddEntry(DirectoryEntry newEntry) - { - // Unlink an entry from the free list (or add to the end of the existing directory) - long pos; - if (_freeEntries.Count > 0) - { - pos = _freeEntries[0]; - _freeEntries.RemoveAt(0); - } - else - { - pos = _endOfEntries; - _endOfEntries += 32; - } - - // Put the new entry into it's slot - _dirStream.Position = pos; - newEntry.WriteTo(_dirStream); - - // Update internal structures to reflect new entry (as if read from disk) - _entries.Add(pos, newEntry); - - HandleAccessed(true); - - return pos; - } - - internal void DeleteEntry(long id, bool releaseContents) - { - if (id < 0) - { - throw new IOException("Attempt to delete unknown directory entry"); - } - - try - { - DirectoryEntry entry = _entries[id]; - - DirectoryEntry copy = new DirectoryEntry(entry); - copy.Name = entry.Name.Deleted(); - _dirStream.Position = id; - copy.WriteTo(_dirStream); - - if (releaseContents) - { - FileSystem.Fat.FreeChain(entry.FirstCluster); - } - - _entries.Remove(id); - _freeEntries.Add(id); - - HandleAccessed(true); - } - finally - { - FileSystem.Fat.Flush(); - } - } - - internal void UpdateEntry(long id, DirectoryEntry entry) - { - if (id < 0) - { - throw new IOException("Attempt to update unknown directory entry"); - } - - _dirStream.Position = id; - entry.WriteTo(_dirStream); - _entries[id] = entry; - } - - private void LoadEntries() - { - _entries = new Dictionary(); - _freeEntries = new List(); - - _selfEntryLocation = -1; - _parentEntryLocation = -1; - - Stack slotList = new Stack(); - bool errorDuringSlotDetection = false; - - while (_dirStream.Position < _dirStream.Length) - { - long streamPos = _dirStream.Position; - DirectoryEntry entry = new DirectoryEntry(FileSystem.FatOptions, _dirStream, FileSystem.FatVariant); - - if (entry.Attributes == - (FatAttributes.ReadOnly | FatAttributes.Hidden | FatAttributes.System | FatAttributes.VolumeId)) - { - // Long File Name entry - _dirStream.Position = streamPos; - try - { - slotList.Push(new Slot(_dirStream)); - } - catch - { - slotList.Clear(); - errorDuringSlotDetection = true; - } - // continue with the next element, since we don't want to empty the slot list in this case - continue; - - } - else if (entry.Name.IsDeleted()) - { - // E5 = Free Entry - _freeEntries.Add(streamPos); - } - else if (entry.Name == FileName.SelfEntryName) - { - _selfEntry = entry; - _selfEntryLocation = streamPos; - } - else if (entry.Name == FileName.ParentEntryName) - { - _parentEntry = entry; - _parentEntryLocation = streamPos; - } - else if (entry.Name.IsEndMarker()) - { - // Free Entry, no more entries available - _endOfEntries = streamPos; - break; - } - else - { - if (!errorDuringSlotDetection && slotList.Count > 0) - { - var checksum = entry.Name.ComputeChecksum(); - - bool validChecksum = true; - var sb = new StringBuilder(); - foreach (var slot in slotList) - { - if (slot.AliasChecksum != checksum) - { - validChecksum = false; - break; - } - sb.Append(slot.Name); - } - - if (validChecksum) - entry.Name.LongName = sb.ToString(); - } - - _entries.Add(streamPos, entry); - } - - slotList.Clear(); - errorDuringSlotDetection = false; - } - } - - private void HandleAccessed(bool forWrite) - { - if (FileSystem.CanWrite && _parent != null) - { - DateTime now = DateTime.Now; - DirectoryEntry entry = SelfEntry; - - DateTime oldAccessTime = entry.LastAccessTime; - DateTime oldWriteTime = entry.LastWriteTime; - - entry.LastAccessTime = now; - if (forWrite) - { - entry.LastWriteTime = now; - } - - if (entry.LastAccessTime != oldAccessTime || entry.LastWriteTime != oldWriteTime) - { - SelfEntry = entry; - - DirectoryEntry parentEntry = ParentsChildEntry; - parentEntry.LastAccessTime = entry.LastAccessTime; - parentEntry.LastWriteTime = entry.LastWriteTime; - ParentsChildEntry = parentEntry; - } - } - } - - private void PopulateNewChildDirectory(DirectoryEntry newEntry) - { - // Populate new directory with initial (special) entries. First one is easy, just change the name! - using ( - ClusterStream stream = new ClusterStream(FileSystem, FileAccess.Write, newEntry.FirstCluster, - uint.MaxValue)) - { - // First is the self-referencing entry... - DirectoryEntry selfEntry = new DirectoryEntry(newEntry); - selfEntry.Name = FileName.SelfEntryName; - selfEntry.WriteTo(stream); - - // Second is a clone of our self entry (i.e. parent) - though dates are odd... - DirectoryEntry parentEntry = new DirectoryEntry(SelfEntry); - parentEntry.Name = FileName.ParentEntryName; - parentEntry.CreationTime = newEntry.CreationTime; - parentEntry.LastWriteTime = newEntry.LastWriteTime; - parentEntry.WriteTo(stream); - } - } - - private void Dispose(bool disposing) - { - if (disposing) - { - _dirStream.Dispose(); - } - } - - #region Convenient accessors for special entries - - internal DirectoryEntry ParentsChildEntry - { - get - { - if (_parent == null) - { - return new DirectoryEntry(FileSystem.FatOptions, FileName.ParentEntryName, FatAttributes.Directory, - FileSystem.FatVariant); - } - return _parent.GetEntry(_parentId); - } - - set - { - if (_parent != null) - { - _parent.UpdateEntry(_parentId, value); - } - } - } - - internal DirectoryEntry SelfEntry - { - get - { - if (_parent == null) - { - // If we're the root directory, simulate the parent entry with a dummy record - return new DirectoryEntry(FileSystem.FatOptions, FileName.Null, FatAttributes.Directory, - FileSystem.FatVariant); - } - return _selfEntry; - } - - set - { - if (_selfEntryLocation >= 0) - { - _dirStream.Position = _selfEntryLocation; - value.WriteTo(_dirStream); - _selfEntry = value; - } - } - } - - internal DirectoryEntry ParentEntry - { - get { return _parentEntry; } - - set - { - if (_parentEntryLocation < 0) - { - throw new IOException("No parent entry on disk to update"); - } - - _dirStream.Position = _parentEntryLocation; - value.WriteTo(_dirStream); - _parentEntry = value; - } - } - - #endregion - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Fat/DirectoryEntry.cs b/src/LibHac.Nand/DiscUtils.Fat/DirectoryEntry.cs deleted file mode 100644 index 47e7b1c3..00000000 --- a/src/LibHac.Nand/DiscUtils.Fat/DirectoryEntry.cs +++ /dev/null @@ -1,211 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.IO; -using System.Text; -using DiscUtils.Streams; - -namespace DiscUtils.Fat -{ - internal class DirectoryEntry - { - private readonly FatType _fatVariant; - private readonly FatFileSystemOptions _options; - private byte _attr; - private ushort _creationDate; - private ushort _creationTime; - private byte _creationTimeTenth; - private uint _fileSize; - private ushort _firstClusterHi; - private ushort _firstClusterLo; - private ushort _lastAccessDate; - private ushort _lastWriteDate; - private ushort _lastWriteTime; - - internal DirectoryEntry(FatFileSystemOptions options, Stream stream, FatType fatVariant) - { - _options = options; - _fatVariant = fatVariant; - byte[] buffer = StreamUtilities.ReadExact(stream, 32); - Load(buffer, 0, options.FileNameEncoding); - } - - internal DirectoryEntry(FatFileSystemOptions options, FileName name, FatAttributes attrs, FatType fatVariant) - { - _options = options; - _fatVariant = fatVariant; - Name = name; - _attr = (byte)attrs; - } - - internal DirectoryEntry(DirectoryEntry toCopy) - { - _options = toCopy._options; - _fatVariant = toCopy._fatVariant; - Name = toCopy.Name; - _attr = toCopy._attr; - _creationTimeTenth = toCopy._creationTimeTenth; - _creationTime = toCopy._creationTime; - _creationDate = toCopy._creationDate; - _lastAccessDate = toCopy._lastAccessDate; - _firstClusterHi = toCopy._firstClusterHi; - _lastWriteTime = toCopy._lastWriteTime; - _firstClusterLo = toCopy._firstClusterLo; - _fileSize = toCopy._fileSize; - } - - public FatAttributes Attributes - { - get { return (FatAttributes)_attr; } - set { _attr = (byte)value; } - } - - public DateTime CreationTime - { - get { return FileTimeToDateTime(_creationDate, _creationTime, _creationTimeTenth); } - set { DateTimeToFileTime(value, out _creationDate, out _creationTime, out _creationTimeTenth); } - } - - public int FileSize - { - get { return (int)_fileSize; } - set { _fileSize = (uint)value; } - } - - public uint FirstCluster - { - get - { - if (_fatVariant == FatType.Fat32) - { - return (uint)(_firstClusterHi << 16) | _firstClusterLo; - } - return _firstClusterLo; - } - - set - { - if (_fatVariant == FatType.Fat32) - { - _firstClusterHi = (ushort)((value >> 16) & 0xFFFF); - } - - _firstClusterLo = (ushort)(value & 0xFFFF); - } - } - - public DateTime LastAccessTime - { - get { return FileTimeToDateTime(_lastAccessDate, 0, 0); } - set { DateTimeToFileTime(value, out _lastAccessDate); } - } - - public DateTime LastWriteTime - { - get { return FileTimeToDateTime(_lastWriteDate, _lastWriteTime, 0); } - set { DateTimeToFileTime(value, out _lastWriteDate, out _lastWriteTime); } - } - - public FileName Name { get; set; } - - internal void WriteTo(Stream stream) - { - byte[] buffer = new byte[32]; - - Name.GetBytes(buffer, 0); - buffer[11] = _attr; - buffer[13] = _creationTimeTenth; - EndianUtilities.WriteBytesLittleEndian(_creationTime, buffer, 14); - EndianUtilities.WriteBytesLittleEndian(_creationDate, buffer, 16); - EndianUtilities.WriteBytesLittleEndian(_lastAccessDate, buffer, 18); - EndianUtilities.WriteBytesLittleEndian(_firstClusterHi, buffer, 20); - EndianUtilities.WriteBytesLittleEndian(_lastWriteTime, buffer, 22); - EndianUtilities.WriteBytesLittleEndian(_lastWriteDate, buffer, 24); - EndianUtilities.WriteBytesLittleEndian(_firstClusterLo, buffer, 26); - EndianUtilities.WriteBytesLittleEndian(_fileSize, buffer, 28); - - stream.Write(buffer, 0, buffer.Length); - } - - private static DateTime FileTimeToDateTime(ushort date, ushort time, byte tenths) - { - if (date == 0 || date == 0xFFFF) - { - // Return Epoch - this is an invalid date - return FatFileSystem.Epoch; - } - - int year = 1980 + ((date & 0xFE00) >> 9); - int month = (date & 0x01E0) >> 5; - int day = date & 0x001F; - int hour = (time & 0xF800) >> 11; - int minute = (time & 0x07E0) >> 5; - int second = (time & 0x001F) * 2 + tenths / 100; - int millis = tenths % 100 * 10; - - return new DateTime(year, month, day, hour, minute, second, millis); - } - - private static void DateTimeToFileTime(DateTime value, out ushort date) - { - byte tenths; - ushort time; - DateTimeToFileTime(value, out date, out time, out tenths); - } - - private static void DateTimeToFileTime(DateTime value, out ushort date, out ushort time) - { - byte tenths; - DateTimeToFileTime(value, out date, out time, out tenths); - } - - private static void DateTimeToFileTime(DateTime value, out ushort date, out ushort time, out byte tenths) - { - if (value.Year < 1980) - { - value = FatFileSystem.Epoch; - } - - date = - (ushort)((((value.Year - 1980) << 9) & 0xFE00) | ((value.Month << 5) & 0x01E0) | (value.Day & 0x001F)); - time = - (ushort)(((value.Hour << 11) & 0xF800) | ((value.Minute << 5) & 0x07E0) | ((value.Second / 2) & 0x001F)); - tenths = (byte)(value.Second % 2 * 100 + value.Millisecond / 10); - } - - private void Load(byte[] data, int offset, Encoding encoding) - { - Name = new FileName(data, offset, encoding); - _attr = data[offset + 11]; - _creationTimeTenth = data[offset + 13]; - _creationTime = EndianUtilities.ToUInt16LittleEndian(data, offset + 14); - _creationDate = EndianUtilities.ToUInt16LittleEndian(data, offset + 16); - _lastAccessDate = EndianUtilities.ToUInt16LittleEndian(data, offset + 18); - _firstClusterHi = EndianUtilities.ToUInt16LittleEndian(data, offset + 20); - _lastWriteTime = EndianUtilities.ToUInt16LittleEndian(data, offset + 22); - _lastWriteDate = EndianUtilities.ToUInt16LittleEndian(data, offset + 24); - _firstClusterLo = EndianUtilities.ToUInt16LittleEndian(data, offset + 26); - _fileSize = EndianUtilities.ToUInt32LittleEndian(data, offset + 28); - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Fat/FatAttributes.cs b/src/LibHac.Nand/DiscUtils.Fat/FatAttributes.cs deleted file mode 100644 index 1651b402..00000000 --- a/src/LibHac.Nand/DiscUtils.Fat/FatAttributes.cs +++ /dev/null @@ -1,37 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; - -namespace DiscUtils.Fat -{ - [Flags] - internal enum FatAttributes : byte - { - ReadOnly = 0x01, - Hidden = 0x02, - System = 0x04, - VolumeId = 0x08, - Directory = 0x10, - Archive = 0x20 - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Fat/FatBuffer.cs b/src/LibHac.Nand/DiscUtils.Fat/FatBuffer.cs deleted file mode 100644 index 63dbddb2..00000000 --- a/src/LibHac.Nand/DiscUtils.Fat/FatBuffer.cs +++ /dev/null @@ -1,267 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; -using System.IO; -using DiscUtils.Streams; - -namespace DiscUtils.Fat -{ - internal class FatBuffer - { - /// - /// The End-of-chain marker to WRITE (SetNext). Don't use this value to test for end of chain. - /// - /// - /// The actual end-of-chain marker bits on disk vary by FAT type, and can end ...F8 through ...FF. - /// - public const uint EndOfChain = 0xFFFFFFFF; - - /// - /// The Bad-Cluster marker to WRITE (SetNext). Don't use this value to test for bad clusters. - /// - /// - /// The actual bad-cluster marker bits on disk vary by FAT type. - /// - public const uint BadCluster = 0xFFFFFFF7; - - /// - /// The Free-Cluster marker to WRITE (SetNext). Don't use this value to test for free clusters. - /// - /// - /// The actual free-cluster marker bits on disk vary by FAT type. - /// - public const uint FreeCluster = 0; - - private const uint DirtyRegionSize = 512; - private readonly byte[] _buffer; - private readonly Dictionary _dirtySectors; - - private readonly FatType _type; - private uint _nextFreeCandidate; - - public FatBuffer(FatType type, byte[] buffer) - { - _type = type; - _buffer = buffer; - _dirtySectors = new Dictionary(); - } - - internal int NumEntries - { - get - { - switch (_type) - { - case FatType.Fat12: - return _buffer.Length / 3 * 2; - case FatType.Fat16: - return _buffer.Length / 2; - default: // FAT32 - return _buffer.Length / 4; - } - } - } - - internal int Size - { - get { return _buffer.Length; } - } - - internal bool IsFree(uint val) - { - return val == 0; - } - - internal bool IsEndOfChain(uint val) - { - switch (_type) - { - case FatType.Fat12: - return (val & 0x0FFF) >= 0x0FF8; - case FatType.Fat16: - return (val & 0xFFFF) >= 0xFFF8; - case FatType.Fat32: - return (val & 0x0FFFFFF8) >= 0x0FFFFFF8; - default: - throw new ArgumentException("Unknown FAT type"); - } - } - - internal bool IsBadCluster(uint val) - { - switch (_type) - { - case FatType.Fat12: - return (val & 0x0FFF) == 0x0FF7; - case FatType.Fat16: - return (val & 0xFFFF) == 0xFFF7; - case FatType.Fat32: - return (val & 0x0FFFFFF8) == 0x0FFFFFF7; - default: - throw new ArgumentException("Unknown FAT type"); - } - } - - internal uint GetNext(uint cluster) - { - if (_type == FatType.Fat16) - { - return EndianUtilities.ToUInt16LittleEndian(_buffer, (int)(cluster * 2)); - } - if (_type == FatType.Fat32) - { - return EndianUtilities.ToUInt32LittleEndian(_buffer, (int)(cluster * 4)) & 0x0FFFFFFF; - } - - // FAT12 - if ((cluster & 1) != 0) - { - return - (uint)((EndianUtilities.ToUInt16LittleEndian(_buffer, (int)(cluster + cluster / 2)) >> 4) & 0x0FFF); - } - return (uint)(EndianUtilities.ToUInt16LittleEndian(_buffer, (int)(cluster + cluster / 2)) & 0x0FFF); - } - - internal void SetEndOfChain(uint cluster) - { - SetNext(cluster, EndOfChain); - } - - internal void SetBadCluster(uint cluster) - { - SetNext(cluster, BadCluster); - } - - internal void SetFree(uint cluster) - { - if (cluster < _nextFreeCandidate) - { - _nextFreeCandidate = cluster; - } - - SetNext(cluster, FreeCluster); - } - - internal void SetNext(uint cluster, uint next) - { - if (_type == FatType.Fat16) - { - MarkDirty(cluster * 2); - EndianUtilities.WriteBytesLittleEndian((ushort)next, _buffer, (int)(cluster * 2)); - } - else if (_type == FatType.Fat32) - { - MarkDirty(cluster * 4); - uint oldVal = EndianUtilities.ToUInt32LittleEndian(_buffer, (int)(cluster * 4)); - uint newVal = (oldVal & 0xF0000000) | (next & 0x0FFFFFFF); - EndianUtilities.WriteBytesLittleEndian(newVal, _buffer, (int)(cluster * 4)); - } - else - { - uint offset = cluster + cluster / 2; - MarkDirty(offset); - MarkDirty(offset + 1); // On alternate sector boundaries, cluster info crosses two sectors - - ushort maskedOldVal; - if ((cluster & 1) != 0) - { - next = next << 4; - maskedOldVal = (ushort)(EndianUtilities.ToUInt16LittleEndian(_buffer, (int)offset) & 0x000F); - } - else - { - next = next & 0x0FFF; - maskedOldVal = (ushort)(EndianUtilities.ToUInt16LittleEndian(_buffer, (int)offset) & 0xF000); - } - - ushort newVal = (ushort)(maskedOldVal | next); - - EndianUtilities.WriteBytesLittleEndian(newVal, _buffer, (int)offset); - } - } - - internal bool TryGetFreeCluster(out uint cluster) - { - // Simple scan - don't hold a free list... - uint numEntries = (uint)NumEntries; - for (uint i = 0; i < numEntries; i++) - { - uint candidate = (i + _nextFreeCandidate) % numEntries; - if (IsFree(GetNext(candidate))) - { - cluster = candidate; - _nextFreeCandidate = candidate + 1; - return true; - } - } - - cluster = 0; - return false; - } - - internal void FreeChain(uint head) - { - foreach (uint cluster in GetChain(head)) - { - SetFree(cluster); - } - } - - internal List GetChain(uint head) - { - List result = new List(); - - if (head != 0) - { - uint focus = head; - while (!IsEndOfChain(focus)) - { - result.Add(focus); - focus = GetNext(focus); - } - } - - return result; - } - - internal void MarkDirty(uint offset) - { - _dirtySectors[offset / DirtyRegionSize] = offset / DirtyRegionSize; - } - - internal void WriteDirtyRegions(Stream stream, long position) - { - foreach (uint val in _dirtySectors.Values) - { - stream.Position = position + val * DirtyRegionSize; - stream.Write(_buffer, (int)(val * DirtyRegionSize), (int)DirtyRegionSize); - } - } - - internal void ClearDirtyRegions() - { - _dirtySectors.Clear(); - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Fat/FatFileStream.cs b/src/LibHac.Nand/DiscUtils.Fat/FatFileStream.cs deleted file mode 100644 index 5f1183bb..00000000 --- a/src/LibHac.Nand/DiscUtils.Fat/FatFileStream.cs +++ /dev/null @@ -1,138 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; -using System.IO; -using DiscUtils.Streams; - -namespace DiscUtils.Fat -{ - internal class FatFileStream : SparseStream - { - private readonly Directory _dir; - private readonly long _dirId; - private readonly ClusterStream _stream; - - private bool didWrite; - - public FatFileStream(FatFileSystem fileSystem, Directory dir, long fileId, FileAccess access) - { - _dir = dir; - _dirId = fileId; - - DirectoryEntry dirEntry = _dir.GetEntry(_dirId); - _stream = new ClusterStream(fileSystem, access, dirEntry.FirstCluster, (uint)dirEntry.FileSize); - _stream.FirstClusterChanged += FirstClusterAllocatedHandler; - } - - public override bool CanRead - { - get { return _stream.CanRead; } - } - - public override bool CanSeek - { - get { return _stream.CanSeek; } - } - - public override bool CanWrite - { - get { return _stream.CanWrite; } - } - - public override IEnumerable Extents - { - get { return new[] { new StreamExtent(0, Length) }; } - } - - public override long Length - { - get { return _stream.Length; } - } - - public override long Position - { - get { return _stream.Position; } - set { _stream.Position = value; } - } - - protected override void Dispose(bool disposing) - { - if (_dir.FileSystem.CanWrite) - { - try - { - DateTime now = _dir.FileSystem.ConvertFromUtc(DateTime.UtcNow); - - DirectoryEntry dirEntry = _dir.GetEntry(_dirId); - dirEntry.LastAccessTime = now; - if (didWrite) - { - dirEntry.FileSize = (int)_stream.Length; - dirEntry.LastWriteTime = now; - } - - _dir.UpdateEntry(_dirId, dirEntry); - } - finally - { - base.Dispose(disposing); - } - } - } - - public override void SetLength(long value) - { - didWrite = true; - _stream.SetLength(value); - } - - public override void Write(byte[] buffer, int offset, int count) - { - didWrite = true; - _stream.Write(buffer, offset, count); - } - - public override void Flush() - { - _stream.Flush(); - } - - public override int Read(byte[] buffer, int offset, int count) - { - return _stream.Read(buffer, offset, count); - } - - public override long Seek(long offset, SeekOrigin origin) - { - return _stream.Seek(offset, origin); - } - - private void FirstClusterAllocatedHandler(uint cluster) - { - DirectoryEntry dirEntry = _dir.GetEntry(_dirId); - dirEntry.FirstCluster = cluster; - _dir.UpdateEntry(_dirId, dirEntry); - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Fat/FatFileSystem.cs b/src/LibHac.Nand/DiscUtils.Fat/FatFileSystem.cs deleted file mode 100644 index 8e624e52..00000000 --- a/src/LibHac.Nand/DiscUtils.Fat/FatFileSystem.cs +++ /dev/null @@ -1,1942 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; -using System.Globalization; -using System.IO; -using System.Text; -using System.Text.RegularExpressions; -using DiscUtils.Internal; -using DiscUtils.Streams; - -namespace DiscUtils.Fat -{ - /// - /// Class for accessing FAT file systems. - /// - public sealed class FatFileSystem : DiscFileSystem - { - /// - /// The Epoch for FAT file systems (1st Jan, 1980). - /// - public static readonly DateTime Epoch = new DateTime(1980, 1, 1); - - private readonly Dictionary _dirCache; - private readonly Ownership _ownsData; - - private readonly TimeConverter _timeConverter; - private byte[] _bootSector; - private ushort _bpbBkBootSec; - - private ushort _bpbBytesPerSec; - private ushort _bpbExtFlags; - private ushort _bpbFATSz16; - - private uint _bpbFATSz32; - private ushort _bpbFSInfo; - private ushort _bpbFSVer; - private uint _bpbHiddSec; - private ushort _bpbNumHeads; - private uint _bpbRootClus; - private ushort _bpbRootEntCnt; - private ushort _bpbRsvdSecCnt; - private ushort _bpbSecPerTrk; - private ushort _bpbTotSec16; - private uint _bpbTotSec32; - - private byte _bsBootSig; - private uint _bsVolId; - private string _bsVolLab; - private Stream _data; - private Directory _rootDir; - - /// - /// Initializes a new instance of the FatFileSystem class. - /// - /// The stream containing the file system. - /// - /// Local time is the effective timezone of the new instance. - /// - public FatFileSystem(Stream data) - : base(new FatFileSystemOptions()) - { - _dirCache = new Dictionary(); - _timeConverter = DefaultTimeConverter; - Initialize(data); - } - - /// - /// Initializes a new instance of the FatFileSystem class. - /// - /// The stream containing the file system. - /// Indicates if the new instance should take ownership - /// of . - /// - /// Local time is the effective timezone of the new instance. - /// - public FatFileSystem(Stream data, Ownership ownsData) - : base(new FatFileSystemOptions()) - { - _dirCache = new Dictionary(); - _timeConverter = DefaultTimeConverter; - Initialize(data); - _ownsData = ownsData; - } - - /// - /// Initializes a new instance of the FatFileSystem class. - /// - /// The stream containing the file system. - /// A delegate to convert to/from the file system's timezone. - public FatFileSystem(Stream data, TimeConverter timeConverter) - : base(new FatFileSystemOptions()) - { - _dirCache = new Dictionary(); - _timeConverter = timeConverter; - Initialize(data); - } - - /// - /// Initializes a new instance of the FatFileSystem class. - /// - /// The stream containing the file system. - /// Indicates if the new instance should take ownership - /// of . - /// A delegate to convert to/from the file system's timezone. - public FatFileSystem(Stream data, Ownership ownsData, TimeConverter timeConverter) - : base(new FatFileSystemOptions()) - { - _dirCache = new Dictionary(); - _timeConverter = timeConverter; - Initialize(data); - _ownsData = ownsData; - } - - /// - /// Initializes a new instance of the FatFileSystem class. - /// - /// The stream containing the file system. - /// Indicates if the new instance should take ownership - /// of . - /// The parameters for the file system. - public FatFileSystem(Stream data, Ownership ownsData, FileSystemParameters parameters) - : base(new FatFileSystemOptions(parameters)) - { - _dirCache = new Dictionary(); - - if (parameters != null && parameters.TimeConverter != null) - { - _timeConverter = parameters.TimeConverter; - } - else - { - _timeConverter = DefaultTimeConverter; - } - - Initialize(data); - _ownsData = ownsData; - } - - /// - /// Gets the active FAT (zero-based index). - /// - public byte ActiveFat - { - get { return (byte)((_bpbExtFlags & 0x08) != 0 ? _bpbExtFlags & 0x7 : 0); } - } - - /// - /// Gets the Sector location of the backup boot sector (FAT32 only). - /// - public int BackupBootSector - { - get { return _bpbBkBootSec; } - } - - /// - /// Gets the BIOS drive number for BIOS Int 13h calls. - /// - public byte BiosDriveNumber { get; private set; } - - /// - /// Gets the number of bytes per sector (as stored in the file-system meta data). - /// - public int BytesPerSector - { - get { return _bpbBytesPerSec; } - } - - /// - /// Indicates if this file system is read-only or read-write. - /// - /// . - public override bool CanWrite - { - get { return _data.CanWrite; } - } - - internal ClusterReader ClusterReader { get; private set; } - - /// - /// Gets a value indicating whether the VolumeId, VolumeLabel and FileSystemType fields are valid. - /// - public bool ExtendedBootSignaturePresent - { - get { return _bsBootSig == 0x29; } - } - - internal FileAllocationTable Fat { get; private set; } - - /// - /// Gets the number of FATs present. - /// - public byte FatCount { get; private set; } - - /// - /// Gets the FAT file system options, which can be modified. - /// - public FatFileSystemOptions FatOptions - { - get { return (FatFileSystemOptions)Options; } - } - - /// - /// Gets the size of a single FAT, in sectors. - /// - public long FatSize - { - get { return _bpbFATSz16 != 0 ? _bpbFATSz16 : _bpbFATSz32; } - } - - /// - /// Gets the FAT variant of the file system. - /// - public FatType FatVariant { get; private set; } - - /// - /// Gets the (informational only) file system type recorded in the meta-data. - /// - public string FileSystemType { get; private set; } - - /// - /// Gets the friendly name for the file system, including FAT variant. - /// - public override string FriendlyName - { - get - { - switch (FatVariant) - { - case FatType.Fat12: - return "Microsoft FAT12"; - case FatType.Fat16: - return "Microsoft FAT16"; - case FatType.Fat32: - return "Microsoft FAT32"; - default: - return "Unknown FAT"; - } - } - } - - /// - /// Gets the sector location of the FSINFO structure (FAT32 only). - /// - public int FSInfoSector - { - get { return _bpbFSInfo; } - } - - /// - /// Gets the number of logical heads. - /// - public int Heads - { - get { return _bpbNumHeads; } - } - - /// - /// Gets the number of hidden sectors, hiding partition tables, etc. - /// - public long HiddenSectors - { - get { return _bpbHiddSec; } - } - - /// - /// Gets the maximum number of root directory entries (on FAT variants that have a limit). - /// - public int MaxRootDirectoryEntries - { - get { return _bpbRootEntCnt; } - } - - /// - /// Gets the Media marker byte, which indicates fixed or removable media. - /// - public byte Media { get; private set; } - - /// - /// Gets a value indicating whether FAT changes are mirrored to all copies of the FAT. - /// - public bool MirrorFat - { - get { return (_bpbExtFlags & 0x08) == 0; } - } - - /// - /// Gets the OEM name from the file system. - /// - public string OemName { get; private set; } - - /// - /// Gets the number of reserved sectors at the start of the disk. - /// - public int ReservedSectorCount - { - get { return _bpbRsvdSecCnt; } - } - - /// - /// Gets the cluster number of the first cluster of the root directory (FAT32 only). - /// - public long RootDirectoryCluster - { - get { return _bpbRootClus; } - } - - /// - /// Gets the number of contiguous sectors that make up one cluster. - /// - public byte SectorsPerCluster { get; private set; } - - /// - /// Gets the number of sectors per logical track. - /// - public int SectorsPerTrack - { - get { return _bpbSecPerTrk; } - } - - /// - /// Gets the total number of sectors on the disk. - /// - public long TotalSectors - { - get { return _bpbTotSec16 != 0 ? _bpbTotSec16 : _bpbTotSec32; } - } - - /// - /// Gets the file-system version (usually 0). - /// - public int Version - { - get { return _bpbFSVer; } - } - - /// - /// Gets the volume serial number. - /// - public int VolumeId - { - get { return (int)_bsVolId; } - } - - /// - /// Gets the volume label. - /// - public override string VolumeLabel - { - get - { - long volId = _rootDir.FindVolumeId(); - if (volId < 0) - { - return _bsVolLab; - } - return _rootDir.GetEntry(volId).Name.GetRawName(FatOptions.FileNameEncoding); - } - } - - /// - /// Detects if a stream contains a FAT file system. - /// - /// The stream to inspect. - /// true if the stream appears to be a FAT file system, else false. - public static bool Detect(Stream stream) - { - if (stream.Length < 512) - { - return false; - } - - stream.Position = 0; - byte[] bytes = StreamUtilities.ReadExact(stream, 512); - ushort bpbBytesPerSec = EndianUtilities.ToUInt16LittleEndian(bytes, 11); - if (bpbBytesPerSec != 512) - { - return false; - } - - byte bpbNumFATs = bytes[16]; - if (bpbNumFATs == 0 || bpbNumFATs > 2) - { - return false; - } - - ushort bpbTotSec16 = EndianUtilities.ToUInt16LittleEndian(bytes, 19); - uint bpbTotSec32 = EndianUtilities.ToUInt32LittleEndian(bytes, 32); - - if (!((bpbTotSec16 == 0) ^ (bpbTotSec32 == 0))) - { - return false; - } - - uint totalSectors = bpbTotSec16 + bpbTotSec32; - return totalSectors * (long)bpbBytesPerSec <= stream.Length; - } - - /// - /// Opens a file for reading and/or writing. - /// - /// The full path to the file. - /// The file mode. - /// The desired access. - /// The stream to the opened file. - public override SparseStream OpenFile(string path, FileMode mode, FileAccess access) - { - Directory parent; - long entryId; - try - { - entryId = GetDirectoryEntry(_rootDir, path, out parent); - } - catch (ArgumentException) - { - throw new IOException("Invalid path: " + path); - } - - if (parent == null) - { - throw new FileNotFoundException("Could not locate file", path); - } - - if (entryId < 0) - { - return parent.OpenFile(FileName.FromPath(path, FatOptions.FileNameEncoding), mode, access); - } - - DirectoryEntry dirEntry = parent.GetEntry(entryId); - - if ((dirEntry.Attributes & FatAttributes.Directory) != 0) - { - throw new IOException("Attempt to open directory as a file"); - } - return parent.OpenFile(dirEntry.Name, mode, access); - } - - /// - /// Gets the attributes of a file or directory. - /// - /// The file or directory to inspect. - /// The attributes of the file or directory. - public override FileAttributes GetAttributes(string path) - { - // Simulate a root directory entry - doesn't really exist though - if (IsRootPath(path)) - { - return FileAttributes.Directory; - } - - DirectoryEntry dirEntry = GetDirectoryEntry(path); - if (dirEntry == null) - { - throw new FileNotFoundException("No such file", path); - } - - // Luckily, FAT and .NET FileAttributes match, bit-for-bit - return (FileAttributes)dirEntry.Attributes; - } - - /// - /// Sets the attributes of a file or directory. - /// - /// The file or directory to change. - /// The new attributes of the file or directory. - public override void SetAttributes(string path, FileAttributes newValue) - { - if (IsRootPath(path)) - { - if (newValue != FileAttributes.Directory) - { - throw new NotSupportedException("The attributes of the root directory cannot be modified"); - } - - return; - } - - Directory parent; - long id = GetDirectoryEntry(path, out parent); - DirectoryEntry dirEntry = parent.GetEntry(id); - - FatAttributes newFatAttr = (FatAttributes)newValue; - - if ((newFatAttr & FatAttributes.Directory) != (dirEntry.Attributes & FatAttributes.Directory)) - { - throw new ArgumentException("Attempted to change the directory attribute"); - } - - dirEntry.Attributes = newFatAttr; - parent.UpdateEntry(id, dirEntry); - - // For directories, need to update their 'self' entry also - if ((dirEntry.Attributes & FatAttributes.Directory) != 0) - { - Directory dir = GetDirectory(path); - dirEntry = dir.SelfEntry; - dirEntry.Attributes = newFatAttr; - dir.SelfEntry = dirEntry; - } - } - - /// - /// Gets the creation time (in local time) of a file or directory. - /// - /// The path of the file or directory. - /// The creation time. - public override DateTime GetCreationTime(string path) - { - if (IsRootPath(path)) - { - return Epoch; - } - - return GetDirectoryEntry(path).CreationTime; - } - - /// - /// Sets the creation time (in local time) of a file or directory. - /// - /// The path of the file or directory. - /// The new time to set. - public override void SetCreationTime(string path, DateTime newTime) - { - if (IsRootPath(path)) - { - if (newTime != Epoch) - { - throw new NotSupportedException("The creation time of the root directory cannot be modified"); - } - - return; - } - - UpdateDirEntry(path, e => { e.CreationTime = newTime; }); - } - - /// - /// Gets the creation time (in UTC) of a file or directory. - /// - /// The path of the file or directory. - /// The creation time. - public override DateTime GetCreationTimeUtc(string path) - { - if (IsRootPath(path)) - { - return ConvertToUtc(Epoch); - } - - return ConvertToUtc(GetDirectoryEntry(path).CreationTime); - } - - /// - /// Sets the creation time (in UTC) of a file or directory. - /// - /// The path of the file or directory. - /// The new time to set. - public override void SetCreationTimeUtc(string path, DateTime newTime) - { - if (IsRootPath(path)) - { - if (ConvertFromUtc(newTime) != Epoch) - { - throw new NotSupportedException("The last write time of the root directory cannot be modified"); - } - - return; - } - - UpdateDirEntry(path, e => { e.CreationTime = ConvertFromUtc(newTime); }); - } - - /// - /// Gets the last access time (in local time) of a file or directory. - /// - /// The path of the file or directory. - /// The time the file or directory was last accessed. - public override DateTime GetLastAccessTime(string path) - { - if (IsRootPath(path)) - { - return Epoch; - } - - return GetDirectoryEntry(path).LastAccessTime; - } - - /// - /// Sets the last access time (in local time) of a file or directory. - /// - /// The path of the file or directory. - /// The new time to set. - public override void SetLastAccessTime(string path, DateTime newTime) - { - if (IsRootPath(path)) - { - if (newTime != Epoch) - { - throw new NotSupportedException("The last access time of the root directory cannot be modified"); - } - - return; - } - - UpdateDirEntry(path, e => { e.LastAccessTime = newTime; }); - } - - /// - /// Gets the last access time (in UTC) of a file or directory. - /// - /// The path of the file or directory. - /// The time the file or directory was last accessed. - public override DateTime GetLastAccessTimeUtc(string path) - { - if (IsRootPath(path)) - { - return ConvertToUtc(Epoch); - } - - return ConvertToUtc(GetDirectoryEntry(path).LastAccessTime); - } - - /// - /// Sets the last access time (in UTC) of a file or directory. - /// - /// The path of the file or directory. - /// The new time to set. - public override void SetLastAccessTimeUtc(string path, DateTime newTime) - { - if (IsRootPath(path)) - { - if (ConvertFromUtc(newTime) != Epoch) - { - throw new NotSupportedException("The last write time of the root directory cannot be modified"); - } - - return; - } - - UpdateDirEntry(path, e => { e.LastAccessTime = ConvertFromUtc(newTime); }); - } - - /// - /// Gets the last modification time (in local time) of a file or directory. - /// - /// The path of the file or directory. - /// The time the file or directory was last modified. - public override DateTime GetLastWriteTime(string path) - { - if (IsRootPath(path)) - { - return Epoch; - } - - return GetDirectoryEntry(path).LastWriteTime; - } - - /// - /// Sets the last modification time (in local time) of a file or directory. - /// - /// The path of the file or directory. - /// The new time to set. - public override void SetLastWriteTime(string path, DateTime newTime) - { - if (IsRootPath(path)) - { - if (newTime != Epoch) - { - throw new NotSupportedException("The last write time of the root directory cannot be modified"); - } - - return; - } - - UpdateDirEntry(path, e => { e.LastWriteTime = newTime; }); - } - - /// - /// Gets the last modification time (in UTC) of a file or directory. - /// - /// The path of the file or directory. - /// The time the file or directory was last modified. - public override DateTime GetLastWriteTimeUtc(string path) - { - if (IsRootPath(path)) - { - return ConvertToUtc(Epoch); - } - - return ConvertToUtc(GetDirectoryEntry(path).LastWriteTime); - } - - /// - /// Sets the last modification time (in UTC) of a file or directory. - /// - /// The path of the file or directory. - /// The new time to set. - public override void SetLastWriteTimeUtc(string path, DateTime newTime) - { - if (IsRootPath(path)) - { - if (ConvertFromUtc(newTime) != Epoch) - { - throw new NotSupportedException("The last write time of the root directory cannot be modified"); - } - - return; - } - - UpdateDirEntry(path, e => { e.LastWriteTime = ConvertFromUtc(newTime); }); - } - - /// - /// Gets the length of a file. - /// - /// The path to the file. - /// The length in bytes. - public override long GetFileLength(string path) - { - return GetDirectoryEntry(path).FileSize; - } - - /// - /// Copies an existing file to a new file, allowing overwriting of an existing file. - /// - /// The source file. - /// The destination file. - /// Whether to permit over-writing of an existing file. - public override void CopyFile(string sourceFile, string destinationFile, bool overwrite) - { - Directory sourceDir; - long sourceEntryId = GetDirectoryEntry(sourceFile, out sourceDir); - - if (sourceDir == null || sourceEntryId < 0) - { - throw new FileNotFoundException(string.Format(CultureInfo.InvariantCulture, - "The source file '{0}' was not found", sourceFile)); - } - - DirectoryEntry sourceEntry = sourceDir.GetEntry(sourceEntryId); - - if ((sourceEntry.Attributes & FatAttributes.Directory) != 0) - { - throw new IOException("The source file is a directory"); - } - - DirectoryEntry newEntry = new DirectoryEntry(sourceEntry); - newEntry.Name = FileName.FromPath(destinationFile, FatOptions.FileNameEncoding); - newEntry.FirstCluster = 0; - - Directory destDir; - long destEntryId = GetDirectoryEntry(destinationFile, out destDir); - - if (destDir == null) - { - throw new DirectoryNotFoundException(string.Format(CultureInfo.InvariantCulture, - "The destination directory for '{0}' was not found", destinationFile)); - } - - // If the destination is a directory, use the old file name to construct a full path. - if (destEntryId >= 0) - { - DirectoryEntry destEntry = destDir.GetEntry(destEntryId); - if ((destEntry.Attributes & FatAttributes.Directory) != 0) - { - newEntry.Name = FileName.FromPath(sourceFile, FatOptions.FileNameEncoding); - destinationFile = Utilities.CombinePaths(destinationFile, Utilities.GetFileFromPath(sourceFile)); - - destEntryId = GetDirectoryEntry(destinationFile, out destDir); - } - } - - // If there's an existing entry... - if (destEntryId >= 0) - { - DirectoryEntry destEntry = destDir.GetEntry(destEntryId); - - if ((destEntry.Attributes & FatAttributes.Directory) != 0) - { - throw new IOException("Destination file is an existing directory"); - } - - if (!overwrite) - { - throw new IOException("Destination file already exists"); - } - - // Remove the old file - destDir.DeleteEntry(destEntryId, true); - } - - // Add the new file's entry - destEntryId = destDir.AddEntry(newEntry); - - // Copy the contents... - using (Stream sourceStream = new FatFileStream(this, sourceDir, sourceEntryId, FileAccess.Read), - destStream = new FatFileStream(this, destDir, destEntryId, FileAccess.Write)) - { - StreamUtilities.PumpStreams(sourceStream, destStream); - } - } - - /// - /// Creates a directory. - /// - /// The directory to create. - public override void CreateDirectory(string path) - { - string[] pathElements = path.Split(new[] { '\\' }, StringSplitOptions.RemoveEmptyEntries); - - Directory focusDir = _rootDir; - - for (int i = 0; i < pathElements.Length; ++i) - { - FileName name; - try - { - name = new FileName(pathElements[i], FatOptions.FileNameEncoding, false); - } - catch (ArgumentException ae) - { - throw new IOException("Invalid path", ae); - } - - Directory child = focusDir.GetChildDirectory(name); - if (child == null) - { - child = focusDir.CreateChildDirectory(name); - } - - focusDir = child; - } - } - - /// - /// Deletes a directory, optionally with all descendants. - /// - /// The path of the directory to delete. - public override void DeleteDirectory(string path) - { - Directory dir = GetDirectory(path); - if (dir == null) - { - throw new DirectoryNotFoundException(string.Format(CultureInfo.InvariantCulture, - "No such directory: {0}", path)); - } - - if (!dir.IsEmpty) - { - throw new IOException("Unable to delete non-empty directory"); - } - - Directory parent; - long id = GetDirectoryEntry(path, out parent); - if (parent == null && id == 0) - { - throw new IOException("Unable to delete root directory"); - } - if (parent != null && id >= 0) - { - DirectoryEntry deadEntry = parent.GetEntry(id); - parent.DeleteEntry(id, true); - ForgetDirectory(deadEntry); - } - else - { - throw new DirectoryNotFoundException("No such directory: " + path); - } - } - - /// - /// Deletes a file. - /// - /// The path of the file to delete. - public override void DeleteFile(string path) - { - Directory parent; - long id = GetDirectoryEntry(path, out parent); - if (parent == null || id < 0) - { - throw new FileNotFoundException("No such file", path); - } - - DirectoryEntry entry = parent.GetEntry(id); - if (entry == null || (entry.Attributes & FatAttributes.Directory) != 0) - { - throw new FileNotFoundException("No such file", path); - } - - parent.DeleteEntry(id, true); - } - - /// - /// Indicates if a directory exists. - /// - /// The path to test. - /// true if the directory exists. - public override bool DirectoryExists(string path) - { - // Special case - root directory - if (string.IsNullOrEmpty(path)) - { - return true; - } - DirectoryEntry dirEntry = GetDirectoryEntry(path); - return dirEntry != null && (dirEntry.Attributes & FatAttributes.Directory) != 0; - } - - /// - /// Indicates if a file exists. - /// - /// The path to test. - /// true if the file exists. - public override bool FileExists(string path) - { - // Special case - root directory - if (string.IsNullOrEmpty(path)) - { - return true; - } - DirectoryEntry dirEntry = GetDirectoryEntry(path); - return dirEntry != null && (dirEntry.Attributes & FatAttributes.Directory) == 0; - } - - /// - /// Indicates if a file or directory exists. - /// - /// The path to test. - /// true if the file or directory exists. - public override bool Exists(string path) - { - // Special case - root directory - if (string.IsNullOrEmpty(path)) - { - return true; - } - return GetDirectoryEntry(path) != null; - } - - /// - /// Gets the names of subdirectories in a specified directory. - /// - /// The path to search. - /// Array of directories. - public override string[] GetDirectories(string path) - { - Directory dir = GetDirectory(path); - if (dir == null) - { - throw new DirectoryNotFoundException(string.Format(CultureInfo.InvariantCulture, - "The directory '{0}' was not found", path)); - } - - DirectoryEntry[] entries = dir.GetDirectories(); - List dirs = new List(entries.Length); - foreach (DirectoryEntry dirEntry in entries) - { - dirs.Add(Utilities.CombinePaths(path, dirEntry.Name.GetDisplayName(FatOptions.FileNameEncoding))); - } - - return dirs.ToArray(); - } - - /// - /// Gets the names of subdirectories in a specified directory matching a specified - /// search pattern, using a value to determine whether to search subdirectories. - /// - /// The path to search. - /// The search string to match against. - /// Indicates whether to search subdirectories. - /// Array of directories matching the search pattern. - public override string[] GetDirectories(string path, string searchPattern, SearchOption searchOption) - { - Regex re = Utilities.ConvertWildcardsToRegEx(searchPattern); - - List dirs = new List(); - DoSearch(dirs, path, re, searchOption == SearchOption.AllDirectories, true, false); - return dirs.ToArray(); - } - - /// - /// Gets the names of files in a specified directory. - /// - /// The path to search. - /// Array of files. - public override string[] GetFiles(string path) - { - Directory dir = GetDirectory(path); - DirectoryEntry[] entries = dir.GetFiles(); - - List files = new List(entries.Length); - foreach (DirectoryEntry dirEntry in entries) - { - files.Add(Utilities.CombinePaths(path, dirEntry.Name.GetDisplayName(FatOptions.FileNameEncoding))); - } - - return files.ToArray(); - } - - /// - /// Gets the names of files in a specified directory matching a specified - /// search pattern, using a value to determine whether to search subdirectories. - /// - /// The path to search. - /// The search string to match against. - /// Indicates whether to search subdirectories. - /// Array of files matching the search pattern. - public override string[] GetFiles(string path, string searchPattern, SearchOption searchOption) - { - Regex re = Utilities.ConvertWildcardsToRegEx(searchPattern); - - List results = new List(); - DoSearch(results, path, re, searchOption == SearchOption.AllDirectories, false, true); - return results.ToArray(); - } - - /// - /// Gets the names of all files and subdirectories in a specified directory. - /// - /// The path to search. - /// Array of files and subdirectories matching the search pattern. - public override string[] GetFileSystemEntries(string path) - { - Directory dir = GetDirectory(path); - DirectoryEntry[] entries = dir.Entries; - - List result = new List(entries.Length); - foreach (DirectoryEntry dirEntry in entries) - { - result.Add(Utilities.CombinePaths(path, dirEntry.Name.GetDisplayName(FatOptions.FileNameEncoding))); - } - - return result.ToArray(); - } - - /// - /// Gets the names of files and subdirectories in a specified directory matching a specified - /// search pattern. - /// - /// The path to search. - /// The search string to match against. - /// Array of files and subdirectories matching the search pattern. - public override string[] GetFileSystemEntries(string path, string searchPattern) - { - Regex re = Utilities.ConvertWildcardsToRegEx(searchPattern); - - Directory dir = GetDirectory(path); - DirectoryEntry[] entries = dir.Entries; - - List result = new List(entries.Length); - foreach (DirectoryEntry dirEntry in entries) - { - if (re.IsMatch(dirEntry.Name.GetSearchName(FatOptions.FileNameEncoding))) - { - result.Add(Utilities.CombinePaths(path, dirEntry.Name.GetDisplayName(FatOptions.FileNameEncoding))); - } - } - - return result.ToArray(); - } - - /// - /// Moves a directory. - /// - /// The directory to move. - /// The target directory name. - public override void MoveDirectory(string sourceDirectoryName, string destinationDirectoryName) - { - if (string.IsNullOrEmpty(destinationDirectoryName)) - { - if (destinationDirectoryName == null) - { - throw new ArgumentNullException(nameof(destinationDirectoryName)); - } - throw new ArgumentException("Invalid destination name (empty string)"); - } - - Directory destParent; - long destId = GetDirectoryEntry(destinationDirectoryName, out destParent); - if (destParent == null) - { - throw new DirectoryNotFoundException("Target directory doesn't exist"); - } - if (destId >= 0) - { - throw new IOException("Target directory already exists"); - } - - Directory sourceParent; - long sourceId = GetDirectoryEntry(sourceDirectoryName, out sourceParent); - if (sourceParent == null || sourceId < 0) - { - throw new IOException("Source directory doesn't exist"); - } - - destParent.AttachChildDirectory(FileName.FromPath(destinationDirectoryName, FatOptions.FileNameEncoding), - GetDirectory(sourceDirectoryName)); - sourceParent.DeleteEntry(sourceId, false); - } - - /// - /// Moves a file, allowing an existing file to be overwritten. - /// - /// The file to move. - /// The target file name. - /// Whether to permit a destination file to be overwritten. - public override void MoveFile(string sourceName, string destinationName, bool overwrite) - { - Directory sourceDir; - long sourceEntryId = GetDirectoryEntry(sourceName, out sourceDir); - - if (sourceDir == null || sourceEntryId < 0) - { - throw new FileNotFoundException(string.Format(CultureInfo.InvariantCulture, - "The source file '{0}' was not found", sourceName)); - } - - DirectoryEntry sourceEntry = sourceDir.GetEntry(sourceEntryId); - - if ((sourceEntry.Attributes & FatAttributes.Directory) != 0) - { - throw new IOException("The source file is a directory"); - } - - DirectoryEntry newEntry = new DirectoryEntry(sourceEntry); - newEntry.Name = FileName.FromPath(destinationName, FatOptions.FileNameEncoding); - - Directory destDir; - long destEntryId = GetDirectoryEntry(destinationName, out destDir); - - if (destDir == null) - { - throw new DirectoryNotFoundException(string.Format(CultureInfo.InvariantCulture, - "The destination directory for '{0}' was not found", destinationName)); - } - - // If the destination is a directory, use the old file name to construct a full path. - if (destEntryId >= 0) - { - DirectoryEntry destEntry = destDir.GetEntry(destEntryId); - if ((destEntry.Attributes & FatAttributes.Directory) != 0) - { - newEntry.Name = FileName.FromPath(sourceName, FatOptions.FileNameEncoding); - destinationName = Utilities.CombinePaths(destinationName, Utilities.GetFileFromPath(sourceName)); - - destEntryId = GetDirectoryEntry(destinationName, out destDir); - } - } - - // If there's an existing entry... - if (destEntryId >= 0) - { - DirectoryEntry destEntry = destDir.GetEntry(destEntryId); - - if ((destEntry.Attributes & FatAttributes.Directory) != 0) - { - throw new IOException("Destination file is an existing directory"); - } - - if (!overwrite) - { - throw new IOException("Destination file already exists"); - } - - // Remove the old file - destDir.DeleteEntry(destEntryId, true); - } - - // Add the new file's entry and remove the old link to the file's contents - destDir.AddEntry(newEntry); - sourceDir.DeleteEntry(sourceEntryId, false); - } - - internal DateTime ConvertToUtc(DateTime dateTime) - { - return _timeConverter(dateTime, true); - } - - internal DateTime ConvertFromUtc(DateTime dateTime) - { - return _timeConverter(dateTime, false); - } - - internal Directory GetDirectory(string path) - { - Directory parent; - - if (string.IsNullOrEmpty(path) || path == "\\") - { - return _rootDir; - } - - long id = GetDirectoryEntry(_rootDir, path, out parent); - if (id >= 0) - { - return GetDirectory(parent, id); - } - return null; - } - - internal Directory GetDirectory(Directory parent, long parentId) - { - if (parent == null) - { - return _rootDir; - } - - DirectoryEntry dirEntry = parent.GetEntry(parentId); - if ((dirEntry.Attributes & FatAttributes.Directory) == 0) - { - throw new DirectoryNotFoundException(); - } - - // If we have this one cached, return it - Directory result; - if (_dirCache.TryGetValue(dirEntry.FirstCluster, out result)) - { - return result; - } - - // Not cached - create a new one. - result = new Directory(parent, parentId); - _dirCache[dirEntry.FirstCluster] = result; - return result; - } - - internal void ForgetDirectory(DirectoryEntry entry) - { - uint index = entry.FirstCluster; - if (index != 0 && _dirCache.ContainsKey(index)) - { - Directory dir = _dirCache[index]; - _dirCache.Remove(index); - dir.Dispose(); - } - } - - internal DirectoryEntry GetDirectoryEntry(string path) - { - Directory parent; - - long id = GetDirectoryEntry(_rootDir, path, out parent); - if (parent == null || id < 0) - { - return null; - } - - return parent.GetEntry(id); - } - - internal long GetDirectoryEntry(string path, out Directory parent) - { - return GetDirectoryEntry(_rootDir, path, out parent); - } - - /// - /// Disposes of this instance. - /// - /// The value true if Disposing. - protected override void Dispose(bool disposing) - { - try - { - if (disposing) - { - foreach (Directory dir in _dirCache.Values) - { - dir.Dispose(); - } - - _rootDir.Dispose(); - - if (_ownsData == Ownership.Dispose) - { - _data.Dispose(); - _data = null; - } - } - } - finally - { - base.Dispose(disposing); - } - } - - /// - /// Writes a FAT12/FAT16 BPB. - /// - /// The buffer to fill. - /// The total capacity of the disk (in sectors). - /// The number of bits in each FAT entry. - /// The maximum number of root directory entries. - /// The number of hidden sectors before this file system (i.e. partition offset). - /// The number of reserved sectors before the FAT. - /// The number of sectors per cluster. - /// The geometry of the disk containing the Fat file system. - /// Indicates if the disk is a removable media (a floppy disk). - /// The disk's volume Id. - /// The disk's label (or null). - private static void WriteBPB( - byte[] bootSector, - uint sectors, - FatType fatType, - ushort maxRootEntries, - uint hiddenSectors, - ushort reservedSectors, - byte sectorsPerCluster, - Geometry diskGeometry, - bool isFloppy, - uint volId, - string label) - { - uint fatSectors = CalcFatSize(sectors, fatType, sectorsPerCluster); - - bootSector[0] = 0xEB; - bootSector[1] = 0x3C; - bootSector[2] = 0x90; - - // OEM Name - EndianUtilities.StringToBytes("DISCUTIL", bootSector, 3, 8); - - // Bytes Per Sector (512) - bootSector[11] = 0; - bootSector[12] = 2; - - // Sectors Per Cluster - bootSector[13] = sectorsPerCluster; - - // Reserved Sector Count - EndianUtilities.WriteBytesLittleEndian(reservedSectors, bootSector, 14); - - // Number of FATs - bootSector[16] = 2; - - // Number of Entries in the root directory - EndianUtilities.WriteBytesLittleEndian(maxRootEntries, bootSector, 17); - - // Total number of sectors (small) - EndianUtilities.WriteBytesLittleEndian((ushort)(sectors < 0x10000 ? sectors : 0), bootSector, 19); - - // Media - bootSector[21] = (byte)(isFloppy ? 0xF0 : 0xF8); - - // FAT size (FAT12/FAT16) - EndianUtilities.WriteBytesLittleEndian((ushort)(fatType < FatType.Fat32 ? fatSectors : 0), bootSector, 22); - - // Sectors Per Track - EndianUtilities.WriteBytesLittleEndian((ushort)diskGeometry.SectorsPerTrack, bootSector, 24); - - // Heads Per Cylinder - EndianUtilities.WriteBytesLittleEndian((ushort)diskGeometry.HeadsPerCylinder, bootSector, 26); - - // Hidden Sectors - EndianUtilities.WriteBytesLittleEndian(hiddenSectors, bootSector, 28); - - // Total number of sectors (large) - EndianUtilities.WriteBytesLittleEndian(sectors >= 0x10000 ? sectors : 0, bootSector, 32); - - if (fatType < FatType.Fat32) - { - WriteBS(bootSector, 36, isFloppy, volId, label, fatType); - } - else - { - // FAT size (FAT32) - EndianUtilities.WriteBytesLittleEndian(fatSectors, bootSector, 36); - - // Ext flags: 0x80 = FAT 1 (i.e. Zero) active, mirroring - bootSector[40] = 0x00; - bootSector[41] = 0x00; - - // Filesystem version (0.0) - bootSector[42] = 0; - bootSector[43] = 0; - - // First cluster of the root directory, always 2 since we don't do bad sectors... - EndianUtilities.WriteBytesLittleEndian((uint)2, bootSector, 44); - - // Sector number of FSINFO - EndianUtilities.WriteBytesLittleEndian((uint)1, bootSector, 48); - - // Sector number of the Backup Boot Sector - EndianUtilities.WriteBytesLittleEndian((uint)6, bootSector, 50); - - // Reserved area - must be set to 0 - Array.Clear(bootSector, 52, 12); - - WriteBS(bootSector, 64, isFloppy, volId, label, fatType); - } - - bootSector[510] = 0x55; - bootSector[511] = 0xAA; - } - - private static uint CalcFatSize(uint sectors, FatType fatType, byte sectorsPerCluster) - { - uint numClusters = sectors / sectorsPerCluster; - uint fatBytes = numClusters * (ushort)fatType / 8; - return (fatBytes + Sizes.Sector - 1) / Sizes.Sector; - } - - private static void WriteBS(byte[] bootSector, int offset, bool isFloppy, uint volId, string label, - FatType fatType) - { - if (string.IsNullOrEmpty(label)) - { - label = "NO NAME "; - } - - string fsType = "FAT32 "; - if (fatType == FatType.Fat12) - { - fsType = "FAT12 "; - } - else if (fatType == FatType.Fat16) - { - fsType = "FAT16 "; - } - - // Drive Number (for BIOS) - bootSector[offset + 0] = (byte)(isFloppy ? 0x00 : 0x80); - - // Reserved - bootSector[offset + 1] = 0; - - // Boot Signature (indicates next 3 fields present) - bootSector[offset + 2] = 0x29; - - // Volume Id - EndianUtilities.WriteBytesLittleEndian(volId, bootSector, offset + 3); - - // Volume Label - EndianUtilities.StringToBytes(label + " ", bootSector, offset + 7, 11); - - // File System Type - EndianUtilities.StringToBytes(fsType, bootSector, offset + 18, 8); - } - - private static FatType DetectFATType(byte[] bpb) - { - uint bpbBytesPerSec = EndianUtilities.ToUInt16LittleEndian(bpb, 11); - uint bpbRootEntCnt = EndianUtilities.ToUInt16LittleEndian(bpb, 17); - uint bpbFATSz16 = EndianUtilities.ToUInt16LittleEndian(bpb, 22); - uint bpbFATSz32 = EndianUtilities.ToUInt32LittleEndian(bpb, 36); - uint bpbTotSec16 = EndianUtilities.ToUInt16LittleEndian(bpb, 19); - uint bpbTotSec32 = EndianUtilities.ToUInt32LittleEndian(bpb, 32); - uint bpbResvdSecCnt = EndianUtilities.ToUInt16LittleEndian(bpb, 14); - uint bpbNumFATs = bpb[16]; - uint bpbSecPerClus = bpb[13]; - - uint rootDirSectors = (bpbRootEntCnt * 32 + bpbBytesPerSec - 1) / bpbBytesPerSec; - uint fatSz = bpbFATSz16 != 0 ? bpbFATSz16 : bpbFATSz32; - uint totalSec = bpbTotSec16 != 0 ? bpbTotSec16 : bpbTotSec32; - - uint dataSec = totalSec - (bpbResvdSecCnt + bpbNumFATs * fatSz + rootDirSectors); - uint countOfClusters = dataSec / bpbSecPerClus; - - if (countOfClusters < 4085) - { - return FatType.Fat12; - } - if (countOfClusters < 65525) - { - return FatType.Fat16; - } - return FatType.Fat32; - } - - private static bool IsRootPath(string path) - { - return string.IsNullOrEmpty(path) || path == @"\"; - } - - private static DateTime DefaultTimeConverter(DateTime time, bool toUtc) - { - return toUtc ? time.ToUniversalTime() : time.ToLocalTime(); - } - - private void Initialize(Stream data) - { - _data = data; - _data.Position = 0; - _bootSector = StreamUtilities.ReadSector(_data); - - FatVariant = DetectFATType(_bootSector); - - ReadBPB(); - - LoadFAT(); - - LoadClusterReader(); - - LoadRootDirectory(); - } - - private void LoadClusterReader() - { - int rootDirSectors = (_bpbRootEntCnt * 32 + (_bpbBytesPerSec - 1)) / _bpbBytesPerSec; - int firstDataSector = (int)(_bpbRsvdSecCnt + FatCount * FatSize + rootDirSectors); - ClusterReader = new ClusterReader(_data, firstDataSector, SectorsPerCluster, _bpbBytesPerSec); - } - - private void LoadRootDirectory() - { - Stream fatStream; - if (FatVariant != FatType.Fat32) - { - fatStream = new SubStream(_data, (_bpbRsvdSecCnt + FatCount * _bpbFATSz16) * _bpbBytesPerSec, - _bpbRootEntCnt * 32); - } - else - { - fatStream = new ClusterStream(this, FileAccess.ReadWrite, _bpbRootClus, uint.MaxValue); - } - - _rootDir = new Directory(this, fatStream); - } - - private void LoadFAT() - { - Fat = new FileAllocationTable(FatVariant, _data, _bpbRsvdSecCnt, (uint)FatSize, FatCount, ActiveFat); - } - - private void ReadBPB() - { - OemName = Encoding.ASCII.GetString(_bootSector, 3, 8).TrimEnd('\0'); - _bpbBytesPerSec = EndianUtilities.ToUInt16LittleEndian(_bootSector, 11); - SectorsPerCluster = _bootSector[13]; - _bpbRsvdSecCnt = EndianUtilities.ToUInt16LittleEndian(_bootSector, 14); - FatCount = _bootSector[16]; - _bpbRootEntCnt = EndianUtilities.ToUInt16LittleEndian(_bootSector, 17); - _bpbTotSec16 = EndianUtilities.ToUInt16LittleEndian(_bootSector, 19); - Media = _bootSector[21]; - _bpbFATSz16 = EndianUtilities.ToUInt16LittleEndian(_bootSector, 22); - _bpbSecPerTrk = EndianUtilities.ToUInt16LittleEndian(_bootSector, 24); - _bpbNumHeads = EndianUtilities.ToUInt16LittleEndian(_bootSector, 26); - _bpbHiddSec = EndianUtilities.ToUInt32LittleEndian(_bootSector, 28); - _bpbTotSec32 = EndianUtilities.ToUInt32LittleEndian(_bootSector, 32); - - if (FatVariant != FatType.Fat32) - { - ReadBS(36); - } - else - { - _bpbFATSz32 = EndianUtilities.ToUInt32LittleEndian(_bootSector, 36); - _bpbExtFlags = EndianUtilities.ToUInt16LittleEndian(_bootSector, 40); - _bpbFSVer = EndianUtilities.ToUInt16LittleEndian(_bootSector, 42); - _bpbRootClus = EndianUtilities.ToUInt32LittleEndian(_bootSector, 44); - _bpbFSInfo = EndianUtilities.ToUInt16LittleEndian(_bootSector, 48); - _bpbBkBootSec = EndianUtilities.ToUInt16LittleEndian(_bootSector, 50); - ReadBS(64); - } - } - - private void ReadBS(int offset) - { - BiosDriveNumber = _bootSector[offset]; - _bsBootSig = _bootSector[offset + 2]; - _bsVolId = EndianUtilities.ToUInt32LittleEndian(_bootSector, offset + 3); - _bsVolLab = Encoding.ASCII.GetString(_bootSector, offset + 7, 11); - FileSystemType = Encoding.ASCII.GetString(_bootSector, offset + 18, 8); - } - - private long GetDirectoryEntry(Directory dir, string path, out Directory parent) - { - string[] pathElements = path.Split(new[] { '\\' }, StringSplitOptions.RemoveEmptyEntries); - return GetDirectoryEntry(dir, pathElements, 0, out parent); - } - - private long GetDirectoryEntry(Directory dir, string[] pathEntries, int pathOffset, out Directory parent) - { - long entryId; - - if (pathEntries.Length == 0) - { - // Looking for root directory, simulate the directory entry in its parent... - parent = null; - return 0; - } - entryId = dir.FindEntry(new FileName(pathEntries[pathOffset], FatOptions.FileNameEncoding, true)); - if (entryId >= 0) - { - if (pathOffset == pathEntries.Length - 1) - { - parent = dir; - return entryId; - } - return GetDirectoryEntry(GetDirectory(dir, entryId), pathEntries, pathOffset + 1, out parent); - } - if (pathOffset == pathEntries.Length - 1) - { - parent = dir; - return -1; - } - parent = null; - return -1; - } - - private void DoSearch(List results, string path, Regex regex, bool subFolders, bool dirs, bool files) - { - Directory dir = GetDirectory(path); - if (dir == null) - { - throw new DirectoryNotFoundException(string.Format(CultureInfo.InvariantCulture, - "The directory '{0}' was not found", path)); - } - - DirectoryEntry[] entries = dir.Entries; - - foreach (DirectoryEntry de in entries) - { - bool isDir = (de.Attributes & FatAttributes.Directory) != 0; - - if ((isDir && dirs) || (!isDir && files)) - { - if (regex.IsMatch(de.Name.GetSearchName(FatOptions.FileNameEncoding))) - { - results.Add(Utilities.CombinePaths(path, de.Name.GetDisplayName(FatOptions.FileNameEncoding))); - } - } - - if (subFolders && isDir) - { - DoSearch(results, Utilities.CombinePaths(path, de.Name.GetDisplayName(FatOptions.FileNameEncoding)), - regex, subFolders, dirs, files); - } - } - } - - private void UpdateDirEntry(string path, EntryUpdateAction action) - { - Directory parent; - long id = GetDirectoryEntry(path, out parent); - DirectoryEntry entry = parent.GetEntry(id); - action(entry); - parent.UpdateEntry(id, entry); - - if ((entry.Attributes & FatAttributes.Directory) != 0) - { - Directory dir = GetDirectory(path); - DirectoryEntry selfEntry = dir.SelfEntry; - action(selfEntry); - dir.SelfEntry = selfEntry; - } - } - - /// - /// Size of the Filesystem in bytes - /// - public override long Size { get { return ((TotalSectors - ReservedSectorCount - (FatSize * FatCount))*BytesPerSector); } } - - /// - /// Used space of the Filesystem in bytes - /// - public override long UsedSpace - { - get - { - uint usedCluster = 0; - for (uint i = 2; i < Fat.NumEntries; i++) - { - var fatValue = Fat.GetNext(i); - if (!Fat.IsFree(fatValue)) - { - usedCluster++; - } - } - return (usedCluster *SectorsPerCluster*BytesPerSector); - } - } - - /// - /// Available space of the Filesystem in bytes - /// - public override long AvailableSpace { get { return Size - UsedSpace; } } - - private delegate void EntryUpdateAction(DirectoryEntry entry); - -#region Disk Formatting - - /// - /// Creates a formatted floppy disk image in a stream. - /// - /// The stream to write the blank image to. - /// The type of floppy to create. - /// The volume label for the floppy (or null). - /// An object that provides access to the newly created floppy disk image. - public static FatFileSystem FormatFloppy(Stream stream, FloppyDiskType type, string label) - { - long pos = stream.Position; - - long ticks = DateTime.UtcNow.Ticks; - uint volId = (uint)((ticks & 0xFFFF) | (ticks >> 32)); - - // Write the BIOS Parameter Block (BPB) - a single sector - byte[] bpb = new byte[512]; - uint sectors; - if (type == FloppyDiskType.DoubleDensity) - { - sectors = 1440; - WriteBPB(bpb, sectors, FatType.Fat12, 224, 0, 1, 1, new Geometry(80, 2, 9), true, volId, label); - } - else if (type == FloppyDiskType.HighDensity) - { - sectors = 2880; - WriteBPB(bpb, sectors, FatType.Fat12, 224, 0, 1, 1, new Geometry(80, 2, 18), true, volId, label); - } - else if (type == FloppyDiskType.Extended) - { - sectors = 5760; - WriteBPB(bpb, sectors, FatType.Fat12, 224, 0, 1, 1, new Geometry(80, 2, 36), true, volId, label); - } - else - { - throw new ArgumentException("Unrecognised Floppy Disk type", nameof(type)); - } - - stream.Write(bpb, 0, bpb.Length); - - // Write both FAT copies - uint fatSize = CalcFatSize(sectors, FatType.Fat12, 1); - byte[] fat = new byte[fatSize * Sizes.Sector]; - FatBuffer fatBuffer = new FatBuffer(FatType.Fat12, fat); - fatBuffer.SetNext(0, 0xFFFFFFF0); - fatBuffer.SetEndOfChain(1); - stream.Write(fat, 0, fat.Length); - stream.Write(fat, 0, fat.Length); - - // Write the (empty) root directory - uint rootDirSectors = (224 * 32 + Sizes.Sector - 1) / Sizes.Sector; - byte[] rootDir = new byte[rootDirSectors * Sizes.Sector]; - stream.Write(rootDir, 0, rootDir.Length); - - // Write a single byte at the end of the disk to ensure the stream is at least as big - // as needed for this disk image. - stream.Position = pos + sectors * Sizes.Sector - 1; - stream.WriteByte(0); - - // Give the caller access to the new file system - stream.Position = pos; - return new FatFileSystem(stream); - } - - /// - /// Formats a virtual hard disk partition. - /// - /// The disk containing the partition. - /// The index of the partition on the disk. - /// The volume label for the partition (or null). - /// An object that provides access to the newly created partition file system. - public static FatFileSystem FormatPartition(VirtualDisk disk, int partitionIndex, string label) - { - using (Stream partitionStream = disk.Partitions[partitionIndex].Open()) - { - return FormatPartition( - partitionStream, - label, - disk.Geometry, - (int)disk.Partitions[partitionIndex].FirstSector, - (int)(1 + disk.Partitions[partitionIndex].LastSector - disk.Partitions[partitionIndex].FirstSector), - 0); - } - } - - /// - /// Creates a formatted hard disk partition in a stream. - /// - /// The stream to write the new file system to. - /// The volume label for the partition (or null). - /// The geometry of the disk containing the partition. - /// The starting sector number of this partition (hide's sectors in other partitions). - /// The number of sectors in this partition. - /// The number of reserved sectors at the start of the partition. - /// An object that provides access to the newly created partition file system. - public static FatFileSystem FormatPartition( - Stream stream, - string label, - Geometry diskGeometry, - int firstSector, - int sectorCount, - short reservedSectors) - { - long pos = stream.Position; - - long ticks = DateTime.UtcNow.Ticks; - uint volId = (uint)((ticks & 0xFFFF) | (ticks >> 32)); - - byte sectorsPerCluster; - FatType fatType; - ushort maxRootEntries; - - /* - * Write the BIOS Parameter Block (BPB) - a single sector - */ - - byte[] bpb = new byte[512]; - if (sectorCount <= 8400) - { - throw new ArgumentException("Requested size is too small for a partition"); - } - if (sectorCount < 1024 * 1024) - { - fatType = FatType.Fat16; - maxRootEntries = 512; - if (sectorCount <= 32680) - { - sectorsPerCluster = 2; - } - else if (sectorCount <= 262144) - { - sectorsPerCluster = 4; - } - else if (sectorCount <= 524288) - { - sectorsPerCluster = 8; - } - else - { - sectorsPerCluster = 16; - } - - if (reservedSectors < 1) - { - reservedSectors = 1; - } - } - else - { - fatType = FatType.Fat32; - maxRootEntries = 0; - if (sectorCount <= 532480) - { - sectorsPerCluster = 1; - } - else if (sectorCount <= 16777216) - { - sectorsPerCluster = 8; - } - else if (sectorCount <= 33554432) - { - sectorsPerCluster = 16; - } - else if (sectorCount <= 67108864) - { - sectorsPerCluster = 32; - } - else - { - sectorsPerCluster = 64; - } - - if (reservedSectors < 32) - { - reservedSectors = 32; - } - } - - WriteBPB(bpb, (uint)sectorCount, fatType, maxRootEntries, (uint)firstSector, (ushort)reservedSectors, - sectorsPerCluster, diskGeometry, false, volId, label); - stream.Write(bpb, 0, bpb.Length); - - /* - * Skip the reserved sectors - */ - - stream.Position = pos + (ushort)reservedSectors * Sizes.Sector; - - /* - * Write both FAT copies - */ - - byte[] fat = new byte[CalcFatSize((uint)sectorCount, fatType, sectorsPerCluster) * Sizes.Sector]; - FatBuffer fatBuffer = new FatBuffer(fatType, fat); - fatBuffer.SetNext(0, 0xFFFFFFF8); - fatBuffer.SetEndOfChain(1); - if (fatType >= FatType.Fat32) - { - // Mark cluster 2 as End-of-chain (i.e. root directory - // is a single cluster in length) - fatBuffer.SetEndOfChain(2); - } - - stream.Write(fat, 0, fat.Length); - stream.Write(fat, 0, fat.Length); - - /* - * Write the (empty) root directory - */ - - uint rootDirSectors; - if (fatType < FatType.Fat32) - { - rootDirSectors = (uint)((maxRootEntries * 32 + Sizes.Sector - 1) / Sizes.Sector); - } - else - { - rootDirSectors = sectorsPerCluster; - } - - byte[] rootDir = new byte[rootDirSectors * Sizes.Sector]; - stream.Write(rootDir, 0, rootDir.Length); - - /* - * Make sure the stream is at least as large as the partition requires. - */ - - if (stream.Length < pos + sectorCount * Sizes.Sector) - { - stream.SetLength(pos + sectorCount * Sizes.Sector); - } - - /* - * Give the caller access to the new file system - */ - - stream.Position = pos; - return new FatFileSystem(stream); - } - -#endregion - } -} diff --git a/src/LibHac.Nand/DiscUtils.Fat/FatFileSystemOptions.cs b/src/LibHac.Nand/DiscUtils.Fat/FatFileSystemOptions.cs deleted file mode 100644 index 0e6f6563..00000000 --- a/src/LibHac.Nand/DiscUtils.Fat/FatFileSystemOptions.cs +++ /dev/null @@ -1,79 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Text; -using DiscUtils.CoreCompat; - -namespace DiscUtils.Fat -{ - /// - /// FAT file system options. - /// - public sealed class FatFileSystemOptions : DiscFileSystemOptions - { - private Encoding _encoding; - - static FatFileSystemOptions() - { - EncodingHelper.RegisterEncodings(); - } - - internal FatFileSystemOptions() - { - // Code page 437 isn't built-in to .NET Core. Hopefully the Switch doesn't use non-ASCII names. - // FileNameEncoding = Encoding.GetEncoding(437); - FileNameEncoding = Encoding.ASCII; - } - - internal FatFileSystemOptions(FileSystemParameters parameters) - { - if (parameters != null && parameters.FileNameEncoding != null) - { - FileNameEncoding = parameters.FileNameEncoding; - } - else - { - // FileNameEncoding = Encoding.GetEncoding(437); - FileNameEncoding = Encoding.ASCII; - } - } - - /// - /// Gets or sets the character encoding used for file names. - /// - public Encoding FileNameEncoding - { - get { return _encoding; } - - set - { - if (!value.IsSingleByte) - { - throw new ArgumentException(value.EncodingName + " is not a single byte encoding"); - } - - _encoding = value; - } - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Fat/FatType.cs b/src/LibHac.Nand/DiscUtils.Fat/FatType.cs deleted file mode 100644 index c85fb96f..00000000 --- a/src/LibHac.Nand/DiscUtils.Fat/FatType.cs +++ /dev/null @@ -1,50 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -namespace DiscUtils.Fat -{ - /// - /// Enumeration of known FAT types. - /// - public enum FatType - { - /// - /// Represents no known FAT type. - /// - None = 0, - - /// - /// Represents a 12-bit FAT. - /// - Fat12 = 12, - - /// - /// Represents a 16-bit FAT. - /// - Fat16 = 16, - - /// - /// Represents a 32-bit FAT. - /// - Fat32 = 32 - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Fat/FileAllocationTable.cs b/src/LibHac.Nand/DiscUtils.Fat/FileAllocationTable.cs deleted file mode 100644 index fdfd55e6..00000000 --- a/src/LibHac.Nand/DiscUtils.Fat/FileAllocationTable.cs +++ /dev/null @@ -1,106 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System.IO; -using DiscUtils.Streams; - -namespace DiscUtils.Fat -{ - internal class FileAllocationTable - { - private readonly FatBuffer _buffer; - private readonly ushort _firstFatSector; - private readonly byte _numFats; - private readonly Stream _stream; - - public FileAllocationTable(FatType type, Stream stream, ushort firstFatSector, uint fatSize, byte numFats, - byte activeFat) - { - _stream = stream; - _firstFatSector = firstFatSector; - _numFats = numFats; - - _stream.Position = (firstFatSector + fatSize * activeFat) * Sizes.Sector; - _buffer = new FatBuffer(type, StreamUtilities.ReadExact(_stream, (int)(fatSize * Sizes.Sector))); - } - - internal bool IsFree(uint val) - { - return _buffer.IsFree(val); - } - - internal bool IsEndOfChain(uint val) - { - return _buffer.IsEndOfChain(val); - } - - internal bool IsBadCluster(uint val) - { - return _buffer.IsBadCluster(val); - } - - internal uint GetNext(uint cluster) - { - return _buffer.GetNext(cluster); - } - - internal void SetEndOfChain(uint cluster) - { - _buffer.SetEndOfChain(cluster); - } - - internal void SetBadCluster(uint cluster) - { - _buffer.SetBadCluster(cluster); - } - - internal void SetNext(uint cluster, uint next) - { - _buffer.SetNext(cluster, next); - } - - internal void Flush() - { - for (int i = 0; i < _numFats; ++i) - { - _buffer.WriteDirtyRegions(_stream, _firstFatSector * Sizes.Sector + _buffer.Size * i); - } - - _buffer.ClearDirtyRegions(); - } - - internal bool TryGetFreeCluster(out uint cluster) - { - return _buffer.TryGetFreeCluster(out cluster); - } - - internal void FreeChain(uint head) - { - _buffer.FreeChain(head); - } - - internal int NumEntries - { - get { return _buffer.NumEntries; } - } - } -} diff --git a/src/LibHac.Nand/DiscUtils.Fat/FileName.cs b/src/LibHac.Nand/DiscUtils.Fat/FileName.cs deleted file mode 100644 index 4a46f844..00000000 --- a/src/LibHac.Nand/DiscUtils.Fat/FileName.cs +++ /dev/null @@ -1,258 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Text; -using DiscUtils.Internal; - -namespace DiscUtils.Fat -{ - internal sealed class FileName : IEquatable - { - private const byte SpaceByte = 0x20; - - public static readonly FileName SelfEntryName = - new FileName(new byte[] { 0x2E, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 }, 0); - - public static readonly FileName ParentEntryName = - new FileName(new byte[] { 0x2E, 0x2E, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 }, 0); - - public static readonly FileName Null = - new FileName(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0); - - private static readonly byte[] InvalidBytes = { 0x22, 0x2A, 0x2B, 0x2C, 0x2E, 0x2F, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x5B, 0x5C, 0x5D, 0x7C }; - - private readonly byte[] _raw; - - public FileName(byte[] data, int offset) - { - _raw = new byte[11]; - Array.Copy(data, offset, _raw, 0, 11); - } - - /// - /// Constructs the long name using the given data and encoding - /// - public FileName(byte[] data, int offset, Encoding encoding) - : this(data, offset) - { - LongName = GetDisplayName(encoding); - } - - public FileName(string name, Encoding encoding, bool useLongName) - { - _raw = new byte[11]; - byte[] bytes = encoding.GetBytes(name.ToUpperInvariant()); - - if (useLongName) - { - LongName = name; - } - - int nameIdx = 0; - int rawIdx = 0; - while (nameIdx < bytes.Length && bytes[nameIdx] != '.' && rawIdx < _raw.Length) - { - byte b = bytes[nameIdx++]; - if (b < 0x20 || Contains(InvalidBytes, b)) - { - throw new ArgumentException("Invalid character in file name '" + (char)b + "'", nameof(name)); - } - - _raw[rawIdx++] = b; - } - - if (rawIdx > 8) - { - if(!useLongName) - throw new ArgumentException("File name too long '" + name + "'", nameof(name)); - } - if (rawIdx == 0) - { - throw new ArgumentException("File name too short '" + name + "'", nameof(name)); - } - - while (rawIdx < 8) - { - _raw[rawIdx++] = SpaceByte; - } - - if (nameIdx < bytes.Length && bytes[nameIdx] == '.') - { - ++nameIdx; - } - - while (nameIdx < bytes.Length && rawIdx < _raw.Length) - { - byte b = bytes[nameIdx++]; - if (b < 0x20 || Contains(InvalidBytes, b)) - { - throw new ArgumentException("Invalid character in file extension '" + (char)b + "'", nameof(name)); - } - - _raw[rawIdx++] = b; - } - - while (rawIdx < 11) - { - _raw[rawIdx++] = SpaceByte; - } - - if (nameIdx != bytes.Length && !useLongName) - { - throw new ArgumentException("File extension too long '" + name + "'", nameof(name)); - } - } - - /// - /// Long name to be displayed to the user - /// - public string LongName { get; set; } - - public bool Equals(FileName other) - { - if (other is null) - { - return false; - } - if (!string.IsNullOrEmpty(LongName) && !string.IsNullOrEmpty(other.LongName)) - return LongName.Equals(other.LongName, StringComparison.InvariantCultureIgnoreCase); - - return CompareRawNames(this, other) == 0; - } - - public static FileName FromPath(string path, Encoding encoding) - { - return new FileName(Utilities.GetFileFromPath(path), encoding, true); - } - - public static bool operator ==(FileName a, FileName b) - { - if (a is null) - return b is null; - return a.Equals(b); - } - - public static bool operator !=(FileName a, FileName b) - { - return !(a == b); - } - - public string GetDisplayName(Encoding encoding) - { - if (!string.IsNullOrEmpty(LongName)) - return LongName; - return GetSearchName(encoding).TrimEnd('.'); - } - - public string GetSearchName(Encoding encoding) - { - if (!string.IsNullOrEmpty(LongName)) - return LongName; - return encoding.GetString(_raw, 0, 8).TrimEnd() + "." + encoding.GetString(_raw, 8, 3).TrimEnd(); - } - - public string GetRawName(Encoding encoding) - { - return encoding.GetString(_raw, 0, 11).TrimEnd(); - } - - public FileName Deleted() - { - byte[] data = new byte[11]; - Array.Copy(_raw, data, 11); - data[0] = 0xE5; - - return new FileName(data, 0); - } - - public bool IsDeleted() - { - return _raw[0] == 0xE5; - } - - public bool IsEndMarker() - { - return _raw[0] == 0x00; - } - - public void GetBytes(byte[] data, int offset) - { - Array.Copy(_raw, 0, data, offset, 11); - } - - public override bool Equals(object other) - { - return Equals(other as FileName); - } - - public override int GetHashCode() - { - int val = 0x1A8D3C4E; - - for (int i = 0; i < 11; ++i) - { - val = (val << 2) ^ _raw[i]; - } - - return val; - } - - public byte ComputeChecksum() - { - byte checksum = 0; - - for (var i = 0; i < 11; ++i) - { - checksum = (byte)((((checksum & 1) << 7) | ((checksum & 0xfe) >> 1)) + _raw[i]); - } - - return checksum; - } - - private static int CompareRawNames(FileName a, FileName b) - { - for (int i = 0; i < 11; ++i) - { - if (a._raw[i] != b._raw[i]) - { - return a._raw[i] - b._raw[i]; - } - } - - return 0; - } - - private static bool Contains(byte[] array, byte val) - { - foreach (byte b in array) - { - if (b == val) - { - return true; - } - } - - return false; - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Fat/FileSystemFactory.cs b/src/LibHac.Nand/DiscUtils.Fat/FileSystemFactory.cs deleted file mode 100644 index 25982f7d..00000000 --- a/src/LibHac.Nand/DiscUtils.Fat/FileSystemFactory.cs +++ /dev/null @@ -1,47 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System.IO; -using DiscUtils.Vfs; -using DiscUtils.Streams; - -namespace DiscUtils.Fat -{ - [VfsFileSystemFactory] - internal class FileSystemFactory : VfsFileSystemFactory - { - public override FileSystemInfo[] Detect(Stream stream, VolumeInfo volume) - { - if (FatFileSystem.Detect(stream)) - { - return new FileSystemInfo[] { new VfsFileSystemInfo("FAT", "Microsoft FAT", Open) }; - } - - return new FileSystemInfo[0]; - } - - private DiscFileSystem Open(Stream stream, VolumeInfo volumeInfo, FileSystemParameters parameters) - { - return new FatFileSystem(stream, Ownership.None, parameters); - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Fat/FirstClusterChangedDelegate.cs b/src/LibHac.Nand/DiscUtils.Fat/FirstClusterChangedDelegate.cs deleted file mode 100644 index 5a160b90..00000000 --- a/src/LibHac.Nand/DiscUtils.Fat/FirstClusterChangedDelegate.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace DiscUtils.Fat -{ - internal delegate void FirstClusterChangedDelegate(uint cluster); -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Fat/Slot.cs b/src/LibHac.Nand/DiscUtils.Fat/Slot.cs deleted file mode 100644 index b2915b91..00000000 --- a/src/LibHac.Nand/DiscUtils.Fat/Slot.cs +++ /dev/null @@ -1,76 +0,0 @@ -// -// Copyright (c) 2018, DiscUtils -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.IO; -using System.Text; -using DiscUtils.Streams; - -namespace DiscUtils.Fat -{ - // More information here: https://www.kernel.org/doc/Documentation/filesystems/vfat.txt - internal class Slot - { - internal Slot(Stream stream) - { - byte[] buffer = StreamUtilities.ReadExact(stream, 32); - Load(buffer, 0); - } - - internal string Name { get; private set; } - - internal byte AliasChecksum { get; private set; } - - private void Load(byte[] data, int offset) - { - byte[] buffer = new byte[12]; - Array.Copy(data, offset + 1, buffer, 0, 10); - Name = Encoding.Unicode.GetString(buffer, 0, 10); - - var attr = (FatAttributes)data[offset + 11]; - if (attr != (FatAttributes.ReadOnly | FatAttributes.Hidden | FatAttributes.System | FatAttributes.VolumeId)) - throw new Exception($"Invalid value '{attr}' for attribute byte"); - - var reserved = data[offset + 12]; - if (reserved != 0) - throw new Exception($"Reserved byte value '{reserved}' should always be 0"); - - AliasChecksum = data[offset + 13]; - - Array.Copy(data, offset + 14, buffer, 0, 12); - Name += Encoding.Unicode.GetString(buffer); - - var startingCluster = EndianUtilities.ToUInt16LittleEndian(data, offset + 26); - if (startingCluster != 0) - throw new Exception($"Starting cluster value {startingCluster} should always be 0"); - - Array.Copy(data, offset + 28, buffer, 0, 4); - Name += Encoding.Unicode.GetString(buffer, 0, 4); - - // StringComparison.Ordinal to force IndexOf to not ignore the null character - // ref: https://github.com/dotnet/coreclr/issues/14066 - var index = Name.IndexOf("\0", StringComparison.Ordinal); - if (index > -1) - Name = Name.Substring(0, index); - } - } -} diff --git a/src/LibHac.Nand/DiscUtils.Streams/AligningStream.cs b/src/LibHac.Nand/DiscUtils.Streams/AligningStream.cs deleted file mode 100644 index e3a37f68..00000000 --- a/src/LibHac.Nand/DiscUtils.Streams/AligningStream.cs +++ /dev/null @@ -1,180 +0,0 @@ -// -// Copyright (c) 2008-2012, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.IO; - -namespace DiscUtils.Streams -{ - /// - /// Aligns I/O to a given block size. - /// - /// Uses the read-modify-write pattern to align I/O. - public sealed class AligningStream : WrappingMappedStream - { - private readonly byte[] _alignmentBuffer; - private readonly int _blockSize; - private long _position; - - public AligningStream(SparseStream toWrap, Ownership ownership, int blockSize) - : base(toWrap, ownership, null) - { - _blockSize = blockSize; - _alignmentBuffer = new byte[blockSize]; - } - - public override long Position - { - get { return _position; } - set { _position = value; } - } - - public override int Read(byte[] buffer, int offset, int count) - { - int startOffset = (int)(_position % _blockSize); - if (startOffset == 0 && (count % _blockSize == 0 || _position + count == Length)) - { - // Aligned read - pass through to underlying stream. - WrappedStream.Position = _position; - int numRead = WrappedStream.Read(buffer, offset, count); - _position += numRead; - return numRead; - } - - long startPos = MathUtilities.RoundDown(_position, _blockSize); - long endPos = MathUtilities.RoundUp(_position + count, _blockSize); - - if (endPos - startPos > int.MaxValue) - { - throw new IOException("Oversized read, after alignment"); - } - - byte[] tempBuffer = new byte[endPos - startPos]; - - WrappedStream.Position = startPos; - int read = WrappedStream.Read(tempBuffer, 0, tempBuffer.Length); - int available = Math.Min(count, read - startOffset); - - Array.Copy(tempBuffer, startOffset, buffer, offset, available); - - _position += available; - return available; - } - - public override long Seek(long offset, SeekOrigin origin) - { - long effectiveOffset = offset; - if (origin == SeekOrigin.Current) - { - effectiveOffset += _position; - } - else if (origin == SeekOrigin.End) - { - effectiveOffset += Length; - } - - if (effectiveOffset < 0) - { - throw new IOException("Attempt to move before beginning of stream"); - } - _position = effectiveOffset; - return _position; - } - - public override void Clear(int count) - { - DoOperation( - (s, opOffset, opCount) => { s.Clear(opCount); }, - (buffer, offset, opOffset, opCount) => { Array.Clear(buffer, offset, opCount); }, - count); - } - - public override void Write(byte[] buffer, int offset, int count) - { - DoOperation( - (s, opOffset, opCount) => { s.Write(buffer, offset + opOffset, opCount); }, - (tempBuffer, tempOffset, opOffset, opCount) => { Array.Copy(buffer, offset + opOffset, tempBuffer, tempOffset, opCount); }, - count); - } - - private void DoOperation(ModifyStream modifyStream, ModifyBuffer modifyBuffer, int count) - { - int startOffset = (int)(_position % _blockSize); - if (startOffset == 0 && (count % _blockSize == 0 || _position + count == Length)) - { - WrappedStream.Position = _position; - modifyStream(WrappedStream, 0, count); - _position += count; - return; - } - - long unalignedEnd = _position + count; - long alignedPos = MathUtilities.RoundDown(_position, _blockSize); - - if (startOffset != 0) - { - WrappedStream.Position = alignedPos; - WrappedStream.Read(_alignmentBuffer, 0, _blockSize); - - modifyBuffer(_alignmentBuffer, startOffset, 0, Math.Min(count, _blockSize - startOffset)); - - WrappedStream.Position = alignedPos; - WrappedStream.Write(_alignmentBuffer, 0, _blockSize); - } - - alignedPos = MathUtilities.RoundUp(_position, _blockSize); - if (alignedPos >= unalignedEnd) - { - _position = unalignedEnd; - return; - } - - int passthroughLength = (int)MathUtilities.RoundDown(_position + count - alignedPos, _blockSize); - if (passthroughLength > 0) - { - WrappedStream.Position = alignedPos; - modifyStream(WrappedStream, (int)(alignedPos - _position), passthroughLength); - } - - alignedPos += passthroughLength; - if (alignedPos >= unalignedEnd) - { - _position = unalignedEnd; - return; - } - - WrappedStream.Position = alignedPos; - WrappedStream.Read(_alignmentBuffer, 0, _blockSize); - - modifyBuffer(_alignmentBuffer, 0, (int)(alignedPos - _position), (int)Math.Min(count - (alignedPos - _position), unalignedEnd - alignedPos)); - - WrappedStream.Position = alignedPos; - WrappedStream.Write(_alignmentBuffer, 0, _blockSize); - - _position = unalignedEnd; - } - - private delegate void ModifyStream(SparseStream stream, int opOffset, int count); - - private delegate void ModifyBuffer(byte[] buffer, int offset, int opOffset, int count); - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Streams/Block/Block.cs b/src/LibHac.Nand/DiscUtils.Streams/Block/Block.cs deleted file mode 100644 index df2383ba..00000000 --- a/src/LibHac.Nand/DiscUtils.Streams/Block/Block.cs +++ /dev/null @@ -1,38 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -namespace DiscUtils.Streams -{ - public class Block - { - public int Available { get; set; } - - public byte[] Data { get; set; } - - public long Position { get; set; } - - public bool Equals(Block other) - { - return Position == other.Position; - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Streams/Block/BlockCache.cs b/src/LibHac.Nand/DiscUtils.Streams/Block/BlockCache.cs deleted file mode 100644 index 596def4b..00000000 --- a/src/LibHac.Nand/DiscUtils.Streams/Block/BlockCache.cs +++ /dev/null @@ -1,132 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System.Collections.Generic; - -namespace DiscUtils.Streams -{ - public class BlockCache - where T : Block, new() - { - private readonly Dictionary _blocks; - private int _blocksCreated; - private readonly int _blockSize; - - private readonly List _freeBlocks; - private readonly LinkedList _lru; - private readonly int _totalBlocks; - - public BlockCache(int blockSize, int blockCount) - { - _blockSize = blockSize; - _totalBlocks = blockCount; - - _blocks = new Dictionary(); - _lru = new LinkedList(); - _freeBlocks = new List(_totalBlocks); - - FreeBlockCount = _totalBlocks; - } - - public int FreeBlockCount { get; private set; } - - public bool ContainsBlock(long position) - { - return _blocks.ContainsKey(position); - } - - public bool TryGetBlock(long position, out T block) - { - if (_blocks.TryGetValue(position, out block)) - { - _lru.Remove(block); - _lru.AddFirst(block); - return true; - } - - return false; - } - - public T GetBlock(long position) - { - T result; - - if (TryGetBlock(position, out result)) - { - return result; - } - - result = GetFreeBlock(); - result.Position = position; - result.Available = -1; - StoreBlock(result); - - return result; - } - - public void ReleaseBlock(long position) - { - T block; - if (_blocks.TryGetValue(position, out block)) - { - _blocks.Remove(position); - _lru.Remove(block); - _freeBlocks.Add(block); - FreeBlockCount++; - } - } - - private void StoreBlock(T block) - { - _blocks[block.Position] = block; - _lru.AddFirst(block); - } - - private T GetFreeBlock() - { - T block; - - if (_freeBlocks.Count > 0) - { - int idx = _freeBlocks.Count - 1; - block = _freeBlocks[idx]; - _freeBlocks.RemoveAt(idx); - FreeBlockCount--; - } - else if (_blocksCreated < _totalBlocks) - { - block = new T(); - block.Data = new byte[_blockSize]; - _blocksCreated++; - FreeBlockCount--; - } - else - { - block = _lru.Last.Value; - _lru.RemoveLast(); - _blocks.Remove(block.Position); - } - - return block; - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Streams/Block/BlockCacheSettings.cs b/src/LibHac.Nand/DiscUtils.Streams/Block/BlockCacheSettings.cs deleted file mode 100644 index 7c444ef9..00000000 --- a/src/LibHac.Nand/DiscUtils.Streams/Block/BlockCacheSettings.cs +++ /dev/null @@ -1,77 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -namespace DiscUtils.Streams -{ - /// - /// Settings controlling BlockCache instances. - /// - public sealed class BlockCacheSettings - { - /// - /// Initializes a new instance of the BlockCacheSettings class. - /// - public BlockCacheSettings() - { - BlockSize = (int)(4 * Sizes.OneKiB); - ReadCacheSize = 4 * Sizes.OneMiB; - LargeReadSize = 64 * Sizes.OneKiB; - OptimumReadSize = (int)(64 * Sizes.OneKiB); - } - - /// - /// Initializes a new instance of the BlockCacheSettings class. - /// - /// The cache settings. - internal BlockCacheSettings(BlockCacheSettings settings) - { - BlockSize = settings.BlockSize; - ReadCacheSize = settings.ReadCacheSize; - LargeReadSize = settings.LargeReadSize; - OptimumReadSize = settings.OptimumReadSize; - } - - /// - /// Gets or sets the size (in bytes) of each cached block. - /// - public int BlockSize { get; set; } - - /// - /// Gets or sets the maximum read size that will be cached. - /// - /// Large reads are not cached, on the assumption they will not - /// be repeated. This setting controls what is considered 'large'. - /// Any read that is more than this many bytes will not be cached. - public long LargeReadSize { get; set; } - - /// - /// Gets or sets the optimum size of a read to the wrapped stream. - /// - /// This value must be a multiple of BlockSize. - public int OptimumReadSize { get; set; } - - /// - /// Gets or sets the size (in bytes) of the read cache. - /// - public long ReadCacheSize { get; set; } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Streams/Block/BlockCacheStatistics.cs b/src/LibHac.Nand/DiscUtils.Streams/Block/BlockCacheStatistics.cs deleted file mode 100644 index 7d460a2a..00000000 --- a/src/LibHac.Nand/DiscUtils.Streams/Block/BlockCacheStatistics.cs +++ /dev/null @@ -1,79 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -namespace DiscUtils.Streams -{ - /// - /// Statistical information about the effectiveness of a BlockCache instance. - /// - public sealed class BlockCacheStatistics - { - /// - /// Gets the number of free blocks in the read cache. - /// - public int FreeReadBlocks { get; internal set; } - - /// - /// Gets the number of requested 'large' reads, as defined by the LargeReadSize setting. - /// - public long LargeReadsIn { get; internal set; } - - /// - /// Gets the number of times a read request was serviced (in part or whole) from the cache. - /// - public long ReadCacheHits { get; internal set; } - - /// - /// Gets the number of time a read request was serviced (in part or whole) from the wrapped stream. - /// - public long ReadCacheMisses { get; internal set; } - - /// - /// Gets the total number of requested reads. - /// - public long TotalReadsIn { get; internal set; } - - /// - /// Gets the total number of reads passed on by the cache. - /// - public long TotalReadsOut { get; internal set; } - - /// - /// Gets the total number of requested writes. - /// - public long TotalWritesIn { get; internal set; } - - /// - /// Gets the number of requested unaligned reads. - /// - /// Unaligned reads are reads where the read doesn't start on a multiple of - /// the block size. - public long UnalignedReadsIn { get; internal set; } - - /// - /// Gets the number of requested unaligned writes. - /// - /// Unaligned writes are writes where the write doesn't start on a multiple of - /// the block size. - public long UnalignedWritesIn { get; internal set; } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Streams/Block/BlockCacheStream.cs b/src/LibHac.Nand/DiscUtils.Streams/Block/BlockCacheStream.cs deleted file mode 100644 index 15c30054..00000000 --- a/src/LibHac.Nand/DiscUtils.Streams/Block/BlockCacheStream.cs +++ /dev/null @@ -1,461 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; -using System.IO; - -namespace DiscUtils.Streams -{ - /// - /// A stream implementing a block-oriented read cache. - /// - public sealed class BlockCacheStream : SparseStream - { - private bool _atEof; - private readonly int _blocksInReadBuffer; - - private readonly BlockCache _cache; - private readonly Ownership _ownWrapped; - - private long _position; - private readonly byte[] _readBuffer; - private readonly BlockCacheSettings _settings; - private readonly BlockCacheStatistics _stats; - private SparseStream _wrappedStream; - - /// - /// Initializes a new instance of the BlockCacheStream class. - /// - /// The stream to wrap. - /// Whether to assume ownership of toWrap. - public BlockCacheStream(SparseStream toWrap, Ownership ownership) - : this(toWrap, ownership, new BlockCacheSettings()) {} - - /// - /// Initializes a new instance of the BlockCacheStream class. - /// - /// The stream to wrap. - /// Whether to assume ownership of toWrap. - /// The cache settings. - public BlockCacheStream(SparseStream toWrap, Ownership ownership, BlockCacheSettings settings) - { - if (!toWrap.CanRead) - { - throw new ArgumentException("The wrapped stream does not support reading", nameof(toWrap)); - } - - if (!toWrap.CanSeek) - { - throw new ArgumentException("The wrapped stream does not support seeking", nameof(toWrap)); - } - - _wrappedStream = toWrap; - _ownWrapped = ownership; - _settings = new BlockCacheSettings(settings); - - if (_settings.OptimumReadSize % _settings.BlockSize != 0) - { - throw new ArgumentException("Invalid settings, OptimumReadSize must be a multiple of BlockSize", - nameof(settings)); - } - - _readBuffer = new byte[_settings.OptimumReadSize]; - _blocksInReadBuffer = _settings.OptimumReadSize / _settings.BlockSize; - - int totalBlocks = (int)(_settings.ReadCacheSize / _settings.BlockSize); - - _cache = new BlockCache(_settings.BlockSize, totalBlocks); - _stats = new BlockCacheStatistics(); - _stats.FreeReadBlocks = totalBlocks; - } - - /// - /// Gets an indication as to whether the stream can be read. - /// - public override bool CanRead - { - get { return true; } - } - - /// - /// Gets an indication as to whether the stream position can be changed. - /// - public override bool CanSeek - { - get { return true; } - } - - /// - /// Gets an indication as to whether the stream can be written to. - /// - public override bool CanWrite - { - get { return _wrappedStream.CanWrite; } - } - - /// - /// Gets the parts of the stream that are stored. - /// - /// This may be an empty enumeration if all bytes are zero. - public override IEnumerable Extents - { - get - { - CheckDisposed(); - return _wrappedStream.Extents; - } - } - - /// - /// Gets the length of the stream. - /// - public override long Length - { - get - { - CheckDisposed(); - return _wrappedStream.Length; - } - } - - /// - /// Gets and sets the current stream position. - /// - public override long Position - { - get - { - CheckDisposed(); - return _position; - } - - set - { - CheckDisposed(); - _position = value; - } - } - - /// - /// Gets the performance statistics for this instance. - /// - public BlockCacheStatistics Statistics - { - get - { - _stats.FreeReadBlocks = _cache.FreeBlockCount; - return _stats; - } - } - - /// - /// Gets the parts of a stream that are stored, within a specified range. - /// - /// The offset of the first byte of interest. - /// The number of bytes of interest. - /// An enumeration of stream extents, indicating stored bytes. - public override IEnumerable GetExtentsInRange(long start, long count) - { - CheckDisposed(); - return _wrappedStream.GetExtentsInRange(start, count); - } - - /// - /// Reads data from the stream. - /// - /// The buffer to fill. - /// The buffer offset to start from. - /// The number of bytes to read. - /// The number of bytes read. - public override int Read(byte[] buffer, int offset, int count) - { - CheckDisposed(); - - if (_position >= Length) - { - if (_atEof) - { - throw new IOException("Attempt to read beyond end of stream"); - } - _atEof = true; - return 0; - } - - _stats.TotalReadsIn++; - - if (count > _settings.LargeReadSize) - { - _stats.LargeReadsIn++; - _stats.TotalReadsOut++; - _wrappedStream.Position = _position; - int numRead = _wrappedStream.Read(buffer, offset, count); - _position = _wrappedStream.Position; - - if (_position >= Length) - { - _atEof = true; - } - - return numRead; - } - - int totalBytesRead = 0; - bool servicedFromCache = false; - bool servicedOutsideCache = false; - int blockSize = _settings.BlockSize; - - long firstBlock = _position / blockSize; - int offsetInNextBlock = (int)(_position % blockSize); - long endBlock = MathUtilities.Ceil(Math.Min(_position + count, Length), blockSize); - int numBlocks = (int)(endBlock - firstBlock); - - if (offsetInNextBlock != 0) - { - _stats.UnalignedReadsIn++; - } - - int blocksRead = 0; - while (blocksRead < numBlocks) - { - Block block; - - // Read from the cache as much as possible - while (blocksRead < numBlocks && _cache.TryGetBlock(firstBlock + blocksRead, out block)) - { - int bytesToRead = Math.Min(count - totalBytesRead, block.Available - offsetInNextBlock); - - Array.Copy(block.Data, offsetInNextBlock, buffer, offset + totalBytesRead, bytesToRead); - offsetInNextBlock = 0; - totalBytesRead += bytesToRead; - _position += bytesToRead; - blocksRead++; - - servicedFromCache = true; - } - - // Now handle a sequence of (one or more) blocks that are not cached - if (blocksRead < numBlocks && !_cache.ContainsBlock(firstBlock + blocksRead)) - { - servicedOutsideCache = true; - - // Figure out how many blocks to read from the wrapped stream - int blocksToRead = 0; - while (blocksRead + blocksToRead < numBlocks - && blocksToRead < _blocksInReadBuffer - && !_cache.ContainsBlock(firstBlock + blocksRead + blocksToRead)) - { - ++blocksToRead; - } - - // Allow for the end of the stream not being block-aligned - long readPosition = (firstBlock + blocksRead) * blockSize; - int bytesRead = (int)Math.Min(blocksToRead * (long)blockSize, Length - readPosition); - - // Do the read - _stats.TotalReadsOut++; - _wrappedStream.Position = readPosition; - StreamUtilities.ReadExact(_wrappedStream, _readBuffer, 0, bytesRead); - - // Cache the read blocks - for (int i = 0; i < blocksToRead; ++i) - { - int copyBytes = Math.Min(blockSize, bytesRead - i * blockSize); - block = _cache.GetBlock(firstBlock + blocksRead + i); - Array.Copy(_readBuffer, i * blockSize, block.Data, 0, copyBytes); - block.Available = copyBytes; - - if (copyBytes < blockSize) - { - Array.Clear(_readBuffer, i * blockSize + copyBytes, blockSize - copyBytes); - } - } - - blocksRead += blocksToRead; - - // Propogate the data onto the caller - int bytesToCopy = Math.Min(count - totalBytesRead, bytesRead - offsetInNextBlock); - Array.Copy(_readBuffer, offsetInNextBlock, buffer, offset + totalBytesRead, bytesToCopy); - totalBytesRead += bytesToCopy; - _position += bytesToCopy; - offsetInNextBlock = 0; - } - } - - if (_position >= Length && totalBytesRead == 0) - { - _atEof = true; - } - - if (servicedFromCache) - { - _stats.ReadCacheHits++; - } - - if (servicedOutsideCache) - { - _stats.ReadCacheMisses++; - } - - return totalBytesRead; - } - - /// - /// Flushes the stream. - /// - public override void Flush() - { - CheckDisposed(); - _wrappedStream.Flush(); - } - - /// - /// Moves the stream position. - /// - /// The origin-relative location. - /// The base location. - /// The new absolute stream position. - public override long Seek(long offset, SeekOrigin origin) - { - CheckDisposed(); - - long effectiveOffset = offset; - if (origin == SeekOrigin.Current) - { - effectiveOffset += _position; - } - else if (origin == SeekOrigin.End) - { - effectiveOffset += Length; - } - - _atEof = false; - - if (effectiveOffset < 0) - { - throw new IOException("Attempt to move before beginning of disk"); - } - _position = effectiveOffset; - return _position; - } - - /// - /// Sets the length of the stream. - /// - /// The new length. - public override void SetLength(long value) - { - CheckDisposed(); - _wrappedStream.SetLength(value); - } - - /// - /// Writes data to the stream at the current location. - /// - /// The data to write. - /// The first byte to write from buffer. - /// The number of bytes to write. - public override void Write(byte[] buffer, int offset, int count) - { - CheckDisposed(); - - _stats.TotalWritesIn++; - - int blockSize = _settings.BlockSize; - long firstBlock = _position / blockSize; - long endBlock = MathUtilities.Ceil(Math.Min(_position + count, Length), blockSize); - int numBlocks = (int)(endBlock - firstBlock); - - try - { - _wrappedStream.Position = _position; - _wrappedStream.Write(buffer, offset, count); - } - catch - { - InvalidateBlocks(firstBlock, numBlocks); - throw; - } - - int offsetInNextBlock = (int)(_position % blockSize); - if (offsetInNextBlock != 0) - { - _stats.UnalignedWritesIn++; - } - - // For each block touched, if it's cached, update it - int bytesProcessed = 0; - for (int i = 0; i < numBlocks; ++i) - { - int bufferPos = offset + bytesProcessed; - int bytesThisBlock = Math.Min(count - bytesProcessed, blockSize - offsetInNextBlock); - - Block block; - if (_cache.TryGetBlock(firstBlock + i, out block)) - { - Array.Copy(buffer, bufferPos, block.Data, offsetInNextBlock, bytesThisBlock); - block.Available = Math.Max(block.Available, offsetInNextBlock + bytesThisBlock); - } - - offsetInNextBlock = 0; - bytesProcessed += bytesThisBlock; - } - - _position += count; - } - - /// - /// Disposes of this instance, freeing up associated resources. - /// - /// true if invoked from Dispose, else false. - protected override void Dispose(bool disposing) - { - if (disposing) - { - if (_wrappedStream != null && _ownWrapped == Ownership.Dispose) - { - _wrappedStream.Dispose(); - } - - _wrappedStream = null; - } - - base.Dispose(disposing); - } - - private void CheckDisposed() - { - if (_wrappedStream == null) - { - throw new ObjectDisposedException("BlockCacheStream"); - } - } - - private void InvalidateBlocks(long firstBlock, int numBlocks) - { - for (long i = firstBlock; i < firstBlock + numBlocks; ++i) - { - _cache.ReleaseBlock(i); - } - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Streams/Buffer/Buffer.cs b/src/LibHac.Nand/DiscUtils.Streams/Buffer/Buffer.cs deleted file mode 100644 index 7c84cb13..00000000 --- a/src/LibHac.Nand/DiscUtils.Streams/Buffer/Buffer.cs +++ /dev/null @@ -1,122 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System.Collections.Generic; - -#if !NETCORE - using System; -#endif - -namespace DiscUtils.Streams -{ - /// - /// Abstract base class for implementations of IBuffer. - /// - public abstract class Buffer : -#if !NETCORE - MarshalByRefObject, -#endif - IBuffer - { - /// - /// Gets a value indicating whether this buffer can be read. - /// - public abstract bool CanRead { get; } - - /// - /// Gets a value indicating whether this buffer can be modified. - /// - public abstract bool CanWrite { get; } - - /// - /// Gets the current capacity of the buffer, in bytes. - /// - public abstract long Capacity { get; } - - /// - /// Gets the parts of the stream that are stored. - /// - /// This may be an empty enumeration if all bytes are zero. - public virtual IEnumerable Extents - { - get { return GetExtentsInRange(0, Capacity); } - } - - /// - /// Reads from the buffer into a byte array. - /// - /// The offset within the buffer to start reading. - /// The destination byte array. - /// The start offset within the destination buffer. - /// The number of bytes to read. - /// The actual number of bytes read. - public abstract int Read(long pos, byte[] buffer, int offset, int count); - - /// - /// Writes a byte array into the buffer. - /// - /// The start offset within the buffer. - /// The source byte array. - /// The start offset within the source byte array. - /// The number of bytes to write. - public abstract void Write(long pos, byte[] buffer, int offset, int count); - - /// - /// Clears bytes from the buffer. - /// - /// The start offset within the buffer. - /// The number of bytes to clear. - /// - /// Logically equivalent to writing count null/zero bytes to the buffer, some - /// implementations determine that some (or all) of the range indicated is not actually - /// stored. There is no direct, automatic, correspondence to clearing bytes and them - /// not being represented as an 'extent' - for example, the implementation of the underlying - /// stream may not permit fine-grained extent storage. - /// It is always safe to call this method to 'zero-out' a section of a buffer, regardless of - /// the underlying buffer implementation. - /// - public virtual void Clear(long pos, int count) - { - Write(pos, new byte[count], 0, count); - } - - /// - /// Flushes all data to the underlying storage. - /// - /// The default behaviour, implemented by this class, is to take no action. - public virtual void Flush() {} - - /// - /// Sets the capacity of the buffer, truncating if appropriate. - /// - /// The desired capacity of the buffer. - public abstract void SetCapacity(long value); - - /// - /// Gets the parts of a buffer that are stored, within a specified range. - /// - /// The offset of the first byte of interest. - /// The number of bytes of interest. - /// An enumeration of stream extents, indicating stored bytes. - public abstract IEnumerable GetExtentsInRange(long start, long count); - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Streams/Buffer/BufferStream.cs b/src/LibHac.Nand/DiscUtils.Streams/Buffer/BufferStream.cs deleted file mode 100644 index 57aa4f57..00000000 --- a/src/LibHac.Nand/DiscUtils.Streams/Buffer/BufferStream.cs +++ /dev/null @@ -1,213 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System.Collections.Generic; -using System.IO; - -namespace DiscUtils.Streams -{ - /// - /// Converts a Buffer into a Stream. - /// - public class BufferStream : SparseStream - { - private readonly FileAccess _access; - private readonly IBuffer _buffer; - - private long _position; - - /// - /// Initializes a new instance of the BufferStream class. - /// - /// The buffer to use. - /// The access permitted to clients. - public BufferStream(IBuffer buffer, FileAccess access) - { - _buffer = buffer; - _access = access; - } - - /// - /// Gets an indication of whether read access is permitted. - /// - public override bool CanRead - { - get { return _access != FileAccess.Write; } - } - - /// - /// Gets an indication of whether seeking is permitted. - /// - public override bool CanSeek - { - get { return true; } - } - - /// - /// Gets an indication of whether write access is permitted. - /// - public override bool CanWrite - { - get { return _access != FileAccess.Read; } - } - - /// - /// Gets the stored extents within the sparse stream. - /// - public override IEnumerable Extents - { - get { return _buffer.Extents; } - } - - /// - /// Gets the length of the stream (the capacity of the underlying buffer). - /// - public override long Length - { - get { return _buffer.Capacity; } - } - - /// - /// Gets and sets the current position within the stream. - /// - public override long Position - { - get { return _position; } - set { _position = value; } - } - - /// - /// Flushes all data to the underlying storage. - /// - public override void Flush() {} - - /// - /// Reads a number of bytes from the stream. - /// - /// The destination buffer. - /// The start offset within the destination buffer. - /// The number of bytes to read. - /// The number of bytes read. - public override int Read(byte[] buffer, int offset, int count) - { - if (!CanRead) - { - throw new IOException("Attempt to read from write-only stream"); - } - - StreamUtilities.AssertBufferParameters(buffer, offset, count); - - int numRead = _buffer.Read(_position, buffer, offset, count); - _position += numRead; - return numRead; - } - - /// - /// Changes the current stream position. - /// - /// The origin-relative stream position. - /// The origin for the stream position. - /// The new stream position. - public override long Seek(long offset, SeekOrigin origin) - { - long effectiveOffset = offset; - if (origin == SeekOrigin.Current) - { - effectiveOffset += _position; - } - else if (origin == SeekOrigin.End) - { - effectiveOffset += _buffer.Capacity; - } - - if (effectiveOffset < 0) - { - throw new IOException("Attempt to move before beginning of disk"); - } - _position = effectiveOffset; - return _position; - } - - /// - /// Sets the length of the stream (the underlying buffer's capacity). - /// - /// The new length of the stream. - public override void SetLength(long value) - { - _buffer.SetCapacity(value); - } - - /// - /// Writes a buffer to the stream. - /// - /// The buffer to write. - /// The starting offset within buffer. - /// The number of bytes to write. - public override void Write(byte[] buffer, int offset, int count) - { - if (!CanWrite) - { - throw new IOException("Attempt to write to read-only stream"); - } - - StreamUtilities.AssertBufferParameters(buffer, offset, count); - - _buffer.Write(_position, buffer, offset, count); - _position += count; - } - - /// - /// Clears bytes from the stream. - /// - /// The number of bytes (from the current position) to clear. - /// - /// Logically equivalent to writing count null/zero bytes to the stream, some - /// implementations determine that some (or all) of the range indicated is not actually - /// stored. There is no direct, automatic, correspondence to clearing bytes and them - /// not being represented as an 'extent' - for example, the implementation of the underlying - /// stream may not permit fine-grained extent storage. - /// It is always safe to call this method to 'zero-out' a section of a stream, regardless of - /// the underlying stream implementation. - /// - public override void Clear(int count) - { - if (!CanWrite) - { - throw new IOException("Attempt to erase bytes in a read-only stream"); - } - - _buffer.Clear(_position, count); - _position += count; - } - - /// - /// Gets the parts of a stream that are stored, within a specified range. - /// - /// The offset of the first byte of interest. - /// The number of bytes of interest. - /// An enumeration of stream extents, indicating stored bytes. - public override IEnumerable GetExtentsInRange(long start, long count) - { - return _buffer.GetExtentsInRange(start, count); - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Streams/Buffer/IBuffer.cs b/src/LibHac.Nand/DiscUtils.Streams/Buffer/IBuffer.cs deleted file mode 100644 index 7b9ad11f..00000000 --- a/src/LibHac.Nand/DiscUtils.Streams/Buffer/IBuffer.cs +++ /dev/null @@ -1,112 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System.Collections.Generic; - -namespace DiscUtils.Streams -{ - /// - /// Interface shared by all buffers. - /// - /// - /// Buffers are very similar to streams, except the buffer has no notion of - /// 'current position'. All I/O operations instead specify the position, as - /// needed. Buffers also support sparse behaviour. - /// - public interface IBuffer - { - /// - /// Gets a value indicating whether this buffer can be read. - /// - bool CanRead { get; } - - /// - /// Gets a value indicating whether this buffer can be modified. - /// - bool CanWrite { get; } - - /// - /// Gets the current capacity of the buffer, in bytes. - /// - long Capacity { get; } - - /// - /// Gets the parts of the buffer that are stored. - /// - /// This may be an empty enumeration if all bytes are zero. - IEnumerable Extents { get; } - - /// - /// Reads from the buffer into a byte array. - /// - /// The offset within the buffer to start reading. - /// The destination byte array. - /// The start offset within the destination buffer. - /// The number of bytes to read. - /// The actual number of bytes read. - int Read(long pos, byte[] buffer, int offset, int count); - - /// - /// Writes a byte array into the buffer. - /// - /// The start offset within the buffer. - /// The source byte array. - /// The start offset within the source byte array. - /// The number of bytes to write. - void Write(long pos, byte[] buffer, int offset, int count); - - /// - /// Clears bytes from the buffer. - /// - /// The start offset within the buffer. - /// The number of bytes to clear. - /// - /// Logically equivalent to writing count null/zero bytes to the buffer, some - /// implementations determine that some (or all) of the range indicated is not actually - /// stored. There is no direct, automatic, correspondence to clearing bytes and them - /// not being represented as an 'extent' - for example, the implementation of the underlying - /// stream may not permit fine-grained extent storage. - /// It is always safe to call this method to 'zero-out' a section of a buffer, regardless of - /// the underlying buffer implementation. - /// - void Clear(long pos, int count); - - /// - /// Flushes all data to the underlying storage. - /// - void Flush(); - - /// - /// Sets the capacity of the buffer, truncating if appropriate. - /// - /// The desired capacity of the buffer. - void SetCapacity(long value); - - /// - /// Gets the parts of a buffer that are stored, within a specified range. - /// - /// The offset of the first byte of interest. - /// The number of bytes of interest. - /// An enumeration of stream extents, indicating stored bytes. - IEnumerable GetExtentsInRange(long start, long count); - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Streams/Buffer/IMappedBuffer.cs b/src/LibHac.Nand/DiscUtils.Streams/Buffer/IMappedBuffer.cs deleted file mode 100644 index 9ef95d91..00000000 --- a/src/LibHac.Nand/DiscUtils.Streams/Buffer/IMappedBuffer.cs +++ /dev/null @@ -1,29 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -namespace DiscUtils.Streams -{ - public interface IMappedBuffer : IBuffer - { - long MapPosition(long position); - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Streams/Buffer/SubBuffer.cs b/src/LibHac.Nand/DiscUtils.Streams/Buffer/SubBuffer.cs deleted file mode 100644 index a1631de2..00000000 --- a/src/LibHac.Nand/DiscUtils.Streams/Buffer/SubBuffer.cs +++ /dev/null @@ -1,173 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; - -namespace DiscUtils.Streams -{ - /// - /// Class representing a portion of an existing buffer. - /// - public class SubBuffer : Buffer - { - private readonly long _first; - private readonly long _length; - - private readonly IBuffer _parent; - - /// - /// Initializes a new instance of the SubBuffer class. - /// - /// The parent buffer. - /// The first byte in represented by this sub-buffer. - /// The number of bytes of represented by this sub-buffer. - public SubBuffer(IBuffer parent, long first, long length) - { - _parent = parent; - _first = first; - _length = length; - - if (_first + _length > _parent.Capacity) - { - throw new ArgumentException("Substream extends beyond end of parent stream"); - } - } - - /// - /// Can this buffer be read. - /// - public override bool CanRead - { - get { return _parent.CanRead; } - } - - /// - /// Can this buffer be modified. - /// - public override bool CanWrite - { - get { return _parent.CanWrite; } - } - - /// - /// Gets the current capacity of the buffer, in bytes. - /// - public override long Capacity - { - get { return _length; } - } - - /// - /// Gets the parts of the buffer that are stored. - /// - /// This may be an empty enumeration if all bytes are zero. - public override IEnumerable Extents - { - get { return OffsetExtents(_parent.GetExtentsInRange(_first, _length)); } - } - - /// - /// Flushes all data to the underlying storage. - /// - public override void Flush() - { - _parent.Flush(); - } - - /// - /// Reads from the buffer into a byte array. - /// - /// The offset within the buffer to start reading. - /// The destination byte array. - /// The start offset within the destination buffer. - /// The number of bytes to read. - /// The actual number of bytes read. - public override int Read(long pos, byte[] buffer, int offset, int count) - { - if (count < 0) - { - throw new ArgumentOutOfRangeException(nameof(count), "Attempt to read negative bytes"); - } - - if (pos >= _length) - { - return 0; - } - - return _parent.Read(pos + _first, buffer, offset, - (int)Math.Min(count, Math.Min(_length - pos, int.MaxValue))); - } - - /// - /// Writes a byte array into the buffer. - /// - /// The start offset within the buffer. - /// The source byte array. - /// The start offset within the source byte array. - /// The number of bytes to write. - public override void Write(long pos, byte[] buffer, int offset, int count) - { - if (count < 0) - { - throw new ArgumentOutOfRangeException(nameof(count), "Attempt to write negative bytes"); - } - - if (pos + count > _length) - { - throw new ArgumentOutOfRangeException(nameof(count), "Attempt to write beyond end of substream"); - } - - _parent.Write(pos + _first, buffer, offset, count); - } - - /// - /// Sets the capacity of the buffer, truncating if appropriate. - /// - /// The desired capacity of the buffer. - public override void SetCapacity(long value) - { - throw new NotSupportedException("Attempt to change length of a subbuffer"); - } - - /// - /// Gets the parts of a buffer that are stored, within a specified range. - /// - /// The offset of the first byte of interest. - /// The number of bytes of interest. - /// An enumeration of stream extents, indicating stored bytes. - public override IEnumerable GetExtentsInRange(long start, long count) - { - long absStart = _first + start; - long absEnd = Math.Min(absStart + count, _first + _length); - return OffsetExtents(_parent.GetExtentsInRange(absStart, absEnd - absStart)); - } - - private IEnumerable OffsetExtents(IEnumerable src) - { - foreach (StreamExtent e in src) - { - yield return new StreamExtent(e.Start - _first, e.Length); - } - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Streams/Builder/BuilderBufferExtent.cs b/src/LibHac.Nand/DiscUtils.Streams/Builder/BuilderBufferExtent.cs deleted file mode 100644 index 8f5dac25..00000000 --- a/src/LibHac.Nand/DiscUtils.Streams/Builder/BuilderBufferExtent.cs +++ /dev/null @@ -1,73 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; - -namespace DiscUtils.Streams -{ - public class BuilderBufferExtent : BuilderExtent - { - private byte[] _buffer; - private readonly bool _fixedBuffer; - - public BuilderBufferExtent(long start, long length) - : base(start, length) {} - - public BuilderBufferExtent(long start, byte[] buffer) - : base(start, buffer.Length) - { - _fixedBuffer = true; - _buffer = buffer; - } - - public override void Dispose() {} - - public override void PrepareForRead() - { - if (!_fixedBuffer) - { - _buffer = GetBuffer(); - } - } - - public override int Read(long diskOffset, byte[] block, int offset, int count) - { - int startOffset = (int)(diskOffset - Start); - int numBytes = (int)Math.Min(Length - startOffset, count); - Array.Copy(_buffer, startOffset, block, offset, numBytes); - return numBytes; - } - - public override void DisposeReadState() - { - if (!_fixedBuffer) - { - _buffer = null; - } - } - - protected virtual byte[] GetBuffer() - { - throw new NotSupportedException("Derived class should implement"); - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Streams/Builder/BuilderBufferExtentSource.cs b/src/LibHac.Nand/DiscUtils.Streams/Builder/BuilderBufferExtentSource.cs deleted file mode 100644 index de6a7a1a..00000000 --- a/src/LibHac.Nand/DiscUtils.Streams/Builder/BuilderBufferExtentSource.cs +++ /dev/null @@ -1,39 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -namespace DiscUtils.Streams -{ - public class BuilderBufferExtentSource : BuilderExtentSource - { - private readonly byte[] _buffer; - - public BuilderBufferExtentSource(byte[] buffer) - { - _buffer = buffer; - } - - public override BuilderExtent Fix(long pos) - { - return new BuilderBufferExtent(pos, _buffer); - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Streams/Builder/BuilderBytesExtent.cs b/src/LibHac.Nand/DiscUtils.Streams/Builder/BuilderBytesExtent.cs deleted file mode 100644 index 8b36659a..00000000 --- a/src/LibHac.Nand/DiscUtils.Streams/Builder/BuilderBytesExtent.cs +++ /dev/null @@ -1,56 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; - -namespace DiscUtils.Streams -{ - public class BuilderBytesExtent : BuilderExtent - { - protected byte[] _data; - - public BuilderBytesExtent(long start, byte[] data) - : base(start, data.Length) - { - _data = data; - } - - protected BuilderBytesExtent(long start, long length) - : base(start, length) {} - - public override void Dispose() {} - - public override void PrepareForRead() {} - - public override int Read(long diskOffset, byte[] block, int offset, int count) - { - int start = (int)Math.Min(diskOffset - Start, _data.Length); - int numRead = Math.Min(count, _data.Length - start); - - Array.Copy(_data, start, block, offset, numRead); - - return numRead; - } - - public override void DisposeReadState() {} - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Streams/Builder/BuilderExtent.cs b/src/LibHac.Nand/DiscUtils.Streams/Builder/BuilderExtent.cs deleted file mode 100644 index d93a62d0..00000000 --- a/src/LibHac.Nand/DiscUtils.Streams/Builder/BuilderExtent.cs +++ /dev/null @@ -1,57 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; - -namespace DiscUtils.Streams -{ - public abstract class BuilderExtent : IDisposable - { - public BuilderExtent(long start, long length) - { - Start = start; - Length = length; - } - - public long Length { get; } - - public long Start { get; } - - /// - /// Gets the parts of the stream that are stored. - /// - /// This may be an empty enumeration if all bytes are zero. - public virtual IEnumerable StreamExtents - { - get { return new[] { new StreamExtent(Start, Length) }; } - } - - public abstract void Dispose(); - - public abstract void PrepareForRead(); - - public abstract int Read(long diskOffset, byte[] block, int offset, int count); - - public abstract void DisposeReadState(); - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Streams/Builder/BuilderExtentSource.cs b/src/LibHac.Nand/DiscUtils.Streams/Builder/BuilderExtentSource.cs deleted file mode 100644 index 58e11bcc..00000000 --- a/src/LibHac.Nand/DiscUtils.Streams/Builder/BuilderExtentSource.cs +++ /dev/null @@ -1,29 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -namespace DiscUtils.Streams -{ - public abstract class BuilderExtentSource - { - public abstract BuilderExtent Fix(long pos); - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Streams/Builder/BuilderSparseStreamExtent.cs b/src/LibHac.Nand/DiscUtils.Streams/Builder/BuilderSparseStreamExtent.cs deleted file mode 100644 index ff5dc523..00000000 --- a/src/LibHac.Nand/DiscUtils.Streams/Builder/BuilderSparseStreamExtent.cs +++ /dev/null @@ -1,66 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System.Collections.Generic; - -namespace DiscUtils.Streams -{ - public class BuilderSparseStreamExtent : BuilderExtent - { - private readonly Ownership _ownership; - private SparseStream _stream; - - public BuilderSparseStreamExtent(long start, SparseStream stream) - : this(start, stream, Ownership.None) {} - - public BuilderSparseStreamExtent(long start, SparseStream stream, Ownership ownership) - : base(start, stream.Length) - { - _stream = stream; - _ownership = ownership; - } - - public override IEnumerable StreamExtents - { - get { return StreamExtent.Offset(_stream.Extents, Start); } - } - - public override void Dispose() - { - if (_stream != null && _ownership == Ownership.Dispose) - { - _stream.Dispose(); - _stream = null; - } - } - - public override void PrepareForRead() {} - - public override int Read(long diskOffset, byte[] block, int offset, int count) - { - _stream.Position = diskOffset - Start; - return _stream.Read(block, offset, count); - } - - public override void DisposeReadState() {} - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Streams/Builder/BuilderStreamExtent.cs b/src/LibHac.Nand/DiscUtils.Streams/Builder/BuilderStreamExtent.cs deleted file mode 100644 index 0f53c1f6..00000000 --- a/src/LibHac.Nand/DiscUtils.Streams/Builder/BuilderStreamExtent.cs +++ /dev/null @@ -1,61 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System.IO; - -namespace DiscUtils.Streams -{ - public class BuilderStreamExtent : BuilderExtent - { - private readonly Ownership _ownership; - private Stream _source; - - public BuilderStreamExtent(long start, Stream source) - : this(start, source, Ownership.None) {} - - public BuilderStreamExtent(long start, Stream source, Ownership ownership) - : base(start, source.Length) - { - _source = source; - _ownership = ownership; - } - - public override void Dispose() - { - if (_source != null && _ownership == Ownership.Dispose) - { - _source.Dispose(); - _source = null; - } - } - - public override void PrepareForRead() {} - - public override int Read(long diskOffset, byte[] block, int offset, int count) - { - _source.Position = diskOffset - Start; - return _source.Read(block, offset, count); - } - - public override void DisposeReadState() {} - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Streams/Builder/BuilderStreamExtentSource.cs b/src/LibHac.Nand/DiscUtils.Streams/Builder/BuilderStreamExtentSource.cs deleted file mode 100644 index 27c481dc..00000000 --- a/src/LibHac.Nand/DiscUtils.Streams/Builder/BuilderStreamExtentSource.cs +++ /dev/null @@ -1,41 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System.IO; - -namespace DiscUtils.Streams -{ - public class BuilderStreamExtentSource : BuilderExtentSource - { - private readonly Stream _stream; - - public BuilderStreamExtentSource(Stream stream) - { - _stream = stream; - } - - public override BuilderExtent Fix(long pos) - { - return new BuilderStreamExtent(pos, _stream); - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Streams/Builder/PassthroughStreamBuilder.cs b/src/LibHac.Nand/DiscUtils.Streams/Builder/PassthroughStreamBuilder.cs deleted file mode 100644 index 241b774c..00000000 --- a/src/LibHac.Nand/DiscUtils.Streams/Builder/PassthroughStreamBuilder.cs +++ /dev/null @@ -1,46 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System.Collections.Generic; -using System.IO; - -namespace DiscUtils.Streams -{ - public class PassthroughStreamBuilder : StreamBuilder - { - private readonly Stream _stream; - - public PassthroughStreamBuilder(Stream stream) - { - _stream = stream; - } - - protected override List FixExtents(out long totalLength) - { - _stream.Position = 0; - List result = new List(); - result.Add(new BuilderStreamExtent(0, _stream)); - totalLength = _stream.Length; - return result; - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Streams/Builder/StreamBuilder.cs b/src/LibHac.Nand/DiscUtils.Streams/Builder/StreamBuilder.cs deleted file mode 100644 index 38c14693..00000000 --- a/src/LibHac.Nand/DiscUtils.Streams/Builder/StreamBuilder.cs +++ /dev/null @@ -1,76 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System.Collections.Generic; -using System.IO; - -namespace DiscUtils.Streams -{ - /// - /// Base class for objects that can dynamically construct a stream. - /// - public abstract class StreamBuilder - { - /// - /// Builds a new stream. - /// - /// The stream created by the StreamBuilder instance. - public virtual SparseStream Build() - { - long totalLength; - List extents = FixExtents(out totalLength); - return new BuiltStream(totalLength, extents); - } - - /// - /// Writes the stream contents to an existing stream. - /// - /// The stream to write to. - public void Build(Stream output) - { - using (Stream src = Build()) - { - byte[] buffer = new byte[64 * 1024]; - int numRead = src.Read(buffer, 0, buffer.Length); - while (numRead != 0) - { - output.Write(buffer, 0, numRead); - numRead = src.Read(buffer, 0, buffer.Length); - } - } - } - - /// - /// Writes the stream contents to a file. - /// - /// The file to write to. - public void Build(string outputFile) - { - using (FileStream destStream = new FileStream(outputFile, FileMode.Create, FileAccess.Write)) - { - Build(destStream); - } - } - - protected abstract List FixExtents(out long totalLength); - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Streams/BuiltStream.cs b/src/LibHac.Nand/DiscUtils.Streams/BuiltStream.cs deleted file mode 100644 index 19d01a02..00000000 --- a/src/LibHac.Nand/DiscUtils.Streams/BuiltStream.cs +++ /dev/null @@ -1,325 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; -using System.IO; - -namespace DiscUtils.Streams -{ - public class BuiltStream : SparseStream - { - private Stream _baseStream; - - private BuilderExtent _currentExtent; - private readonly List _extents; - private readonly long _length; - private long _position; - - public BuiltStream(long length, List extents) - { - _baseStream = new ZeroStream(length); - _length = length; - _extents = extents; - - // Make sure the extents are sorted, so binary searches will work. - _extents.Sort(new ExtentStartComparer()); - } - - public override bool CanRead - { - get { return true; } - } - - public override bool CanSeek - { - get { return true; } - } - - public override bool CanWrite - { - get { return false; } - } - - public override IEnumerable Extents - { - get - { - foreach (BuilderExtent extent in _extents) - { - foreach (StreamExtent streamExtent in extent.StreamExtents) - { - yield return streamExtent; - } - } - } - } - - public override long Length - { - get { return _length; } - } - - public override long Position - { - get { return _position; } - set { _position = value; } - } - - public override void Flush() {} - - public override int Read(byte[] buffer, int offset, int count) - { - if (_position >= _length) - { - return 0; - } - if (_position + count > _length) - { - count = (int)(_length - _position); - } - - int totalRead = 0; - while (totalRead < count && _position < _length) - { - // If current region is outside the area of interest, clean it up - if (_currentExtent != null && - (_position < _currentExtent.Start || _position >= _currentExtent.Start + _currentExtent.Length)) - { - _currentExtent.DisposeReadState(); - _currentExtent = null; - } - - // If we need to find a new region, look for it - if (_currentExtent == null) - { - using (SearchExtent searchExtent = new SearchExtent(_position)) - { - int idx = _extents.BinarySearch(searchExtent, new ExtentRangeComparer()); - if (idx >= 0) - { - BuilderExtent extent = _extents[idx]; - extent.PrepareForRead(); - _currentExtent = extent; - } - } - } - - int numRead = 0; - - // If the block is outside any known extent, defer to base stream. - if (_currentExtent == null) - { - _baseStream.Position = _position; - BuilderExtent nextExtent = FindNext(_position); - if (nextExtent != null) - { - numRead = _baseStream.Read(buffer, offset + totalRead, - (int)Math.Min(count - totalRead, nextExtent.Start - _position)); - } - else - { - numRead = _baseStream.Read(buffer, offset + totalRead, count - totalRead); - } - } - else - { - numRead = _currentExtent.Read(_position, buffer, offset + totalRead, count - totalRead); - } - - _position += numRead; - totalRead += numRead; - if (numRead == 0) - break; - } - - return totalRead; - } - - public override long Seek(long offset, SeekOrigin origin) - { - long newPos = offset; - if (origin == SeekOrigin.Current) - { - newPos += _position; - } - else if (origin == SeekOrigin.End) - { - newPos += _length; - } - - _position = newPos; - return newPos; - } - - public override void SetLength(long value) - { - throw new NotSupportedException(); - } - - public override void Write(byte[] buffer, int offset, int count) - { - throw new NotSupportedException(); - } - - protected override void Dispose(bool disposing) - { - try - { - if (disposing) - { - if (_currentExtent != null) - { - _currentExtent.DisposeReadState(); - _currentExtent = null; - } - - if (_baseStream != null) - { - _baseStream.Dispose(); - _baseStream = null; - } - } - } - finally - { - base.Dispose(disposing); - } - } - - private BuilderExtent FindNext(long pos) - { - int min = 0; - int max = _extents.Count - 1; - - if (_extents.Count == 0 || _extents[_extents.Count - 1].Start + _extents[_extents.Count - 1].Length <= pos) - { - return null; - } - - while (true) - { - if (min >= max) - { - return _extents[min]; - } - - int mid = (max + min) / 2; - if (_extents[mid].Start < pos) - { - min = mid + 1; - } - else if (_extents[mid].Start > pos) - { - max = mid; - } - else - { - return _extents[mid]; - } - } - } - - private class SearchExtent : BuilderExtent - { - public SearchExtent(long pos) - : base(pos, 1) {} - - public override void Dispose() {} - - public override void PrepareForRead() - { - // Not valid to use this 'dummy' extent for actual construction - throw new NotSupportedException(); - } - - public override int Read(long diskOffset, byte[] block, int offset, int count) - { - // Not valid to use this 'dummy' extent for actual construction - throw new NotSupportedException(); - } - - public override void DisposeReadState() - { - // Not valid to use this 'dummy' extent for actual construction - throw new NotSupportedException(); - } - } - - private class ExtentRangeComparer : IComparer - { - public int Compare(BuilderExtent x, BuilderExtent y) - { - if (x == null) - { - throw new ArgumentNullException(nameof(x)); - } - - if (y == null) - { - throw new ArgumentNullException(nameof(y)); - } - - if (x.Start + x.Length <= y.Start) - { - // x < y, with no intersection - return -1; - } - if (x.Start >= y.Start + y.Length) - { - // x > y, with no intersection - return 1; - } - - // x intersects y - return 0; - } - } - - private class ExtentStartComparer : IComparer - { - public int Compare(BuilderExtent x, BuilderExtent y) - { - if (x == null) - { - throw new ArgumentNullException(nameof(x)); - } - - if (y == null) - { - throw new ArgumentNullException(nameof(y)); - } - - long val = x.Start - y.Start; - if (val < 0) - { - return -1; - } - if (val > 0) - { - return 1; - } - return 0; - } - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Streams/CircularStream.cs b/src/LibHac.Nand/DiscUtils.Streams/CircularStream.cs deleted file mode 100644 index c222e9a1..00000000 --- a/src/LibHac.Nand/DiscUtils.Streams/CircularStream.cs +++ /dev/null @@ -1,74 +0,0 @@ -// -// Copyright (c) 2008-2013, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; - -namespace DiscUtils.Streams -{ - /// - /// Represents a stream that is circular, so reads and writes off the end of the stream wrap. - /// - public sealed class CircularStream : WrappingStream - { - public CircularStream(SparseStream toWrap, Ownership ownership) - : base(toWrap, ownership) {} - - public override int Read(byte[] buffer, int offset, int count) - { - WrapPosition(); - - int read = base.Read(buffer, offset, (int)Math.Min(Length - Position, count)); - - WrapPosition(); - - return read; - } - - public override void Write(byte[] buffer, int offset, int count) - { - WrapPosition(); - - int totalWritten = 0; - while (totalWritten < count) - { - int toWrite = (int)Math.Min(count - totalWritten, Length - Position); - - base.Write(buffer, offset + totalWritten, toWrite); - - WrapPosition(); - - totalWritten += toWrite; - } - } - - private void WrapPosition() - { - long pos = Position; - long length = Length; - - if (pos >= length) - { - Position = pos % length; - } - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Streams/ConcatStream.cs b/src/LibHac.Nand/DiscUtils.Streams/ConcatStream.cs deleted file mode 100644 index 38341bb8..00000000 --- a/src/LibHac.Nand/DiscUtils.Streams/ConcatStream.cs +++ /dev/null @@ -1,286 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; -using System.Globalization; -using System.IO; - -namespace DiscUtils.Streams -{ - /// - /// The concatenation of multiple streams (read-only, for now). - /// - public class ConcatStream : SparseStream - { - private readonly bool _canWrite; - private readonly Ownership _ownsStreams; - - private long _position; - private SparseStream[] _streams; - - public ConcatStream(Ownership ownsStreams, params SparseStream[] streams) - { - _ownsStreams = ownsStreams; - _streams = streams; - - // Only allow writes if all streams can be written - _canWrite = true; - foreach (SparseStream stream in streams) - { - if (!stream.CanWrite) - { - _canWrite = false; - } - } - } - - public override bool CanRead - { - get - { - CheckDisposed(); - return true; - } - } - - public override bool CanSeek - { - get - { - CheckDisposed(); - return true; - } - } - - public override bool CanWrite - { - get - { - CheckDisposed(); - return _canWrite; - } - } - - public override IEnumerable Extents - { - get - { - CheckDisposed(); - List extents = new List(); - - long pos = 0; - for (int i = 0; i < _streams.Length; ++i) - { - foreach (StreamExtent extent in _streams[i].Extents) - { - extents.Add(new StreamExtent(extent.Start + pos, extent.Length)); - } - - pos += _streams[i].Length; - } - - return extents; - } - } - - public override long Length - { - get - { - CheckDisposed(); - long length = 0; - for (int i = 0; i < _streams.Length; ++i) - { - length += _streams[i].Length; - } - - return length; - } - } - - public override long Position - { - get - { - CheckDisposed(); - return _position; - } - - set - { - CheckDisposed(); - _position = value; - } - } - - public override void Flush() - { - CheckDisposed(); - for (int i = 0; i < _streams.Length; ++i) - { - _streams[i].Flush(); - } - } - - public override int Read(byte[] buffer, int offset, int count) - { - CheckDisposed(); - - int totalRead = 0; - int numRead = 0; - - do - { - long activeStreamStartPos; - int activeStream = GetActiveStream(out activeStreamStartPos); - - _streams[activeStream].Position = _position - activeStreamStartPos; - - numRead = _streams[activeStream].Read(buffer, offset + totalRead, count - totalRead); - - totalRead += numRead; - _position += numRead; - } while (numRead != 0); - - return totalRead; - } - - public override long Seek(long offset, SeekOrigin origin) - { - CheckDisposed(); - - long effectiveOffset = offset; - if (origin == SeekOrigin.Current) - { - effectiveOffset += _position; - } - else if (origin == SeekOrigin.End) - { - effectiveOffset += Length; - } - - if (effectiveOffset < 0) - { - throw new IOException("Attempt to move before beginning of disk"); - } - Position = effectiveOffset; - return Position; - } - - public override void SetLength(long value) - { - CheckDisposed(); - - long lastStreamOffset; - int lastStream = GetStream(Length, out lastStreamOffset); - if (value < lastStreamOffset) - { - throw new IOException(string.Format(CultureInfo.InvariantCulture, - "Unable to reduce stream length to less than {0}", lastStreamOffset)); - } - - _streams[lastStream].SetLength(value - lastStreamOffset); - } - - public override void Write(byte[] buffer, int offset, int count) - { - CheckDisposed(); - - int totalWritten = 0; - while (totalWritten != count) - { - // Offset of the stream = streamOffset - long streamOffset; - int streamIdx = GetActiveStream(out streamOffset); - - // Offset within the stream = streamPos - long streamPos = _position - streamOffset; - _streams[streamIdx].Position = streamPos; - - // Write (limited to the stream's length), except for final stream - that may be - // extendable - int numToWrite; - if (streamIdx == _streams.Length - 1) - { - numToWrite = count - totalWritten; - } - else - { - numToWrite = (int)Math.Min(count - totalWritten, _streams[streamIdx].Length - streamPos); - } - - _streams[streamIdx].Write(buffer, offset + totalWritten, numToWrite); - - totalWritten += numToWrite; - _position += numToWrite; - } - } - - protected override void Dispose(bool disposing) - { - try - { - if (disposing && _ownsStreams == Ownership.Dispose && _streams != null) - { - foreach (SparseStream stream in _streams) - { - stream.Dispose(); - } - - _streams = null; - } - } - finally - { - base.Dispose(disposing); - } - } - - private int GetActiveStream(out long startPos) - { - return GetStream(_position, out startPos); - } - - private int GetStream(long targetPos, out long streamStartPos) - { - // Find the stream that _position is within - streamStartPos = 0; - int focusStream = 0; - while (focusStream < _streams.Length - 1 && streamStartPos + _streams[focusStream].Length <= targetPos) - { - streamStartPos += _streams[focusStream].Length; - focusStream++; - } - - return focusStream; - } - - private void CheckDisposed() - { - if (_streams == null) - { - throw new ObjectDisposedException("ConcatStream"); - } - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Streams/IByteArraySerializable.cs b/src/LibHac.Nand/DiscUtils.Streams/IByteArraySerializable.cs deleted file mode 100644 index 91f79769..00000000 --- a/src/LibHac.Nand/DiscUtils.Streams/IByteArraySerializable.cs +++ /dev/null @@ -1,50 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -namespace DiscUtils.Streams -{ - /// - /// Common interface for reading structures to/from byte arrays. - /// - public interface IByteArraySerializable - { - /// - /// Gets the total number of bytes the structure occupies. - /// - int Size { get; } - - /// - /// Reads the structure from a byte array. - /// - /// The buffer to read from. - /// The buffer offset to start reading from. - /// The number of bytes read. - int ReadFrom(byte[] buffer, int offset); - - /// - /// Writes a structure to a byte array. - /// - /// The buffer to write to. - /// The buffer offset to start writing at. - void WriteTo(byte[] buffer, int offset); - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Streams/LengthWrappingStream.cs b/src/LibHac.Nand/DiscUtils.Streams/LengthWrappingStream.cs deleted file mode 100644 index c9cccf85..00000000 --- a/src/LibHac.Nand/DiscUtils.Streams/LengthWrappingStream.cs +++ /dev/null @@ -1,47 +0,0 @@ -// -// Copyright (c) 2017, Bianco Veigel -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -namespace DiscUtils.Streams -{ - /// - /// Represents a stream with a specified length - /// - /// - /// since the wrapped stream may not support - /// there is no validation of the specified length - /// - public class LengthWrappingStream : WrappingStream - { - private readonly long _length; - - public LengthWrappingStream(SparseStream toWrap, long length, Ownership ownership) - : base(toWrap, ownership) - { - _length = length; - } - - public override long Length - { - get { return _length; } - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Streams/MappedStream.cs b/src/LibHac.Nand/DiscUtils.Streams/MappedStream.cs deleted file mode 100644 index d4d11ac7..00000000 --- a/src/LibHac.Nand/DiscUtils.Streams/MappedStream.cs +++ /dev/null @@ -1,83 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System.Collections.Generic; -using System.IO; - -namespace DiscUtils.Streams -{ - /// - /// Base class for streams that are essentially a mapping onto a parent stream. - /// - /// - /// This class provides access to the mapping underlying the stream, enabling - /// callers to convert a byte range in this stream into one or more ranges in - /// the parent stream. - /// - public abstract class MappedStream : SparseStream - { - /// - /// Converts any stream into a non-linear stream. - /// - /// The stream to convert. - /// true to have the new stream dispose the wrapped - /// stream when it is disposed. - /// A sparse stream. - /// The wrapped stream is assumed to be a linear stream (such that any byte range - /// maps directly onto the parent stream). - public new static MappedStream FromStream(Stream stream, Ownership takeOwnership) - { - return new WrappingMappedStream(stream, takeOwnership, null); - } - - /// - /// Converts any stream into a non-linear stream. - /// - /// The stream to convert. - /// true to have the new stream dispose the wrapped - /// stream when it is disposed. - /// The set of extents actually stored in stream. - /// A sparse stream. - /// The wrapped stream is assumed to be a linear stream (such that any byte range - /// maps directly onto the parent stream). - public new static MappedStream FromStream(Stream stream, Ownership takeOwnership, - IEnumerable extents) - { - return new WrappingMappedStream(stream, takeOwnership, extents); - } - - /// - /// Maps a logical range down to storage locations. - /// - /// The first logical range to map. - /// The length of the range to map. - /// One or more stream extents specifying the storage locations that correspond - /// to the identified logical extent range. - /// - /// As far as possible, the stream extents are returned in logical disk order - - /// however, due to the nature of non-linear streams, not all of the range may actually - /// be stored, or some or all of the range may be compressed - thus reading the - /// returned stream extents is not equivalent to reading the logical disk range. - /// - public abstract IEnumerable MapContent(long start, long length); - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Streams/MirrorStream.cs b/src/LibHac.Nand/DiscUtils.Streams/MirrorStream.cs deleted file mode 100644 index bf98fb4f..00000000 --- a/src/LibHac.Nand/DiscUtils.Streams/MirrorStream.cs +++ /dev/null @@ -1,170 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; -using System.IO; - -namespace DiscUtils.Streams -{ - public class MirrorStream : SparseStream - { - private readonly bool _canRead; - private readonly bool _canSeek; - private readonly bool _canWrite; - private readonly long _length; - private readonly Ownership _ownsWrapped; - private List _wrapped; - - public MirrorStream(Ownership ownsWrapped, params SparseStream[] wrapped) - { - _wrapped = new List(wrapped); - _ownsWrapped = ownsWrapped; - - _canRead = _wrapped[0].CanRead; - _canWrite = _wrapped[0].CanWrite; - _canSeek = _wrapped[0].CanSeek; - _length = _wrapped[0].Length; - - foreach (SparseStream stream in _wrapped) - { - if (stream.CanRead != _canRead || stream.CanWrite != _canWrite || stream.CanSeek != _canSeek) - { - throw new ArgumentException("All mirrored streams must have the same read/write/seek permissions", - nameof(wrapped)); - } - - if (stream.Length != _length) - { - throw new ArgumentException("All mirrored streams must have the same length", nameof(wrapped)); - } - } - } - - public override bool CanRead - { - get { return _canRead; } - } - - public override bool CanSeek - { - get { return _canSeek; } - } - - public override bool CanWrite - { - get { return _canWrite; } - } - - public override IEnumerable Extents - { - get { return _wrapped[0].Extents; } - } - - public override long Length - { - get { return _length; } - } - - public override long Position - { - get { return _wrapped[0].Position; } - - set { _wrapped[0].Position = value; } - } - - public override void Flush() - { - _wrapped[0].Flush(); - } - - public override int Read(byte[] buffer, int offset, int count) - { - return _wrapped[0].Read(buffer, offset, count); - } - - public override long Seek(long offset, SeekOrigin origin) - { - return _wrapped[0].Seek(offset, origin); - } - - public override void SetLength(long value) - { - if (value != _length) - { - throw new InvalidOperationException("Changing the stream length is not permitted for mirrored streams"); - } - } - - public override void Clear(int count) - { - long pos = _wrapped[0].Position; - - if (pos + count > _length) - { - throw new IOException("Attempt to clear beyond end of mirrored stream"); - } - - foreach (SparseStream stream in _wrapped) - { - stream.Position = pos; - stream.Clear(count); - } - } - - public override void Write(byte[] buffer, int offset, int count) - { - long pos = _wrapped[0].Position; - - if (pos + count > _length) - { - throw new IOException("Attempt to write beyond end of mirrored stream"); - } - - foreach (SparseStream stream in _wrapped) - { - stream.Position = pos; - stream.Write(buffer, offset, count); - } - } - - protected override void Dispose(bool disposing) - { - try - { - if (disposing && _ownsWrapped == Ownership.Dispose && _wrapped != null) - { - foreach (SparseStream stream in _wrapped) - { - stream.Dispose(); - } - - _wrapped = null; - } - } - finally - { - base.Dispose(disposing); - } - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Streams/PositionWrappingStream.cs b/src/LibHac.Nand/DiscUtils.Streams/PositionWrappingStream.cs deleted file mode 100644 index 8bf40a1f..00000000 --- a/src/LibHac.Nand/DiscUtils.Streams/PositionWrappingStream.cs +++ /dev/null @@ -1,102 +0,0 @@ -// -// Copyright (c) 2017, Bianco Veigel -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.IO; - -namespace DiscUtils.Streams -{ - /// - /// Stream wrapper to allow forward only seeking on not seekable streams - /// - public class PositionWrappingStream : WrappingStream - { - public PositionWrappingStream(SparseStream toWrap, long currentPosition, Ownership ownership) - : base(toWrap, ownership) - { - _position = currentPosition; - } - - private long _position; - public override long Position - { - get { return _position; } - set - { - if (_position == value) - return; - Seek(value, SeekOrigin.Begin); - } - } - - public override long Seek(long offset, SeekOrigin origin) - { - if (base.CanSeek) - { - return base.Seek(offset, SeekOrigin.Current); - } - switch (origin) - { - case SeekOrigin.Begin: - offset = offset - _position; - break; - case SeekOrigin.Current: - offset = offset + _position; - break; - case SeekOrigin.End: - offset = Length - offset; - break; - default: - throw new ArgumentOutOfRangeException(nameof(origin), origin, null); - } - if (offset == 0) - return _position; - if (offset < 0) - throw new NotSupportedException("backward seeking is not supported"); - var buffer = new byte[Sizes.OneKiB]; - while (offset > 0) - { - var read = base.Read(buffer, 0, (int)Math.Min(buffer.Length, offset)); - offset -= read; - } - return _position; - } - - public override bool CanSeek - { - get { return true; } - } - - public override int Read(byte[] buffer, int offset, int count) - { - var read = base.Read(buffer, offset, count); - _position += read; - return read; - } - - public override void Write(byte[] buffer, int offset, int count) - { - base.Write(buffer, offset, count); - _position += count; - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Streams/PumpProgressEventArgs.cs b/src/LibHac.Nand/DiscUtils.Streams/PumpProgressEventArgs.cs deleted file mode 100644 index 31eaa757..00000000 --- a/src/LibHac.Nand/DiscUtils.Streams/PumpProgressEventArgs.cs +++ /dev/null @@ -1,52 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; - -namespace DiscUtils.Streams -{ - /// - /// Event arguments indicating progress on pumping a stream. - /// - public class PumpProgressEventArgs : EventArgs - { - /// - /// Gets or sets the number of bytes read from InputStream. - /// - public long BytesRead { get; set; } - - /// - /// Gets or sets the number of bytes written to OutputStream. - /// - public long BytesWritten { get; set; } - - /// - /// Gets or sets the absolute position in OutputStream. - /// - public long DestinationPosition { get; set; } - - /// - /// Gets or sets the absolute position in InputStream. - /// - public long SourcePosition { get; set; } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Streams/ReaderWriter/BigEndianDataReader.cs b/src/LibHac.Nand/DiscUtils.Streams/ReaderWriter/BigEndianDataReader.cs deleted file mode 100644 index 177152e5..00000000 --- a/src/LibHac.Nand/DiscUtils.Streams/ReaderWriter/BigEndianDataReader.cs +++ /dev/null @@ -1,63 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.IO; - -namespace DiscUtils.Streams -{ - public class BigEndianDataReader : DataReader - { - public BigEndianDataReader(Stream stream) - : base(stream) {} - - public override ushort ReadUInt16() - { - ReadToBuffer(sizeof(UInt16)); - return EndianUtilities.ToUInt16BigEndian(_buffer, 0); - } - - public override int ReadInt32() - { - ReadToBuffer(sizeof(Int32)); - return EndianUtilities.ToInt32BigEndian(_buffer, 0); - } - - public override uint ReadUInt32() - { - ReadToBuffer(sizeof(UInt32)); - return EndianUtilities.ToUInt32BigEndian(_buffer, 0); - } - - public override long ReadInt64() - { - ReadToBuffer(sizeof(Int64)); - return EndianUtilities.ToInt64BigEndian(_buffer, 0); - } - - public override ulong ReadUInt64() - { - ReadToBuffer(sizeof(UInt64)); - return EndianUtilities.ToUInt64BigEndian(_buffer, 0); - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Streams/ReaderWriter/BigEndianDataWriter.cs b/src/LibHac.Nand/DiscUtils.Streams/ReaderWriter/BigEndianDataWriter.cs deleted file mode 100644 index ceae6bc4..00000000 --- a/src/LibHac.Nand/DiscUtils.Streams/ReaderWriter/BigEndianDataWriter.cs +++ /dev/null @@ -1,68 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.IO; - -namespace DiscUtils.Streams -{ - public class BigEndianDataWriter : DataWriter - { - public BigEndianDataWriter(Stream stream) - : base(stream) {} - - public override void Write(ushort value) - { - EnsureBuffer(); - EndianUtilities.WriteBytesBigEndian(value, _buffer, 0); - FlushBuffer(sizeof(UInt16)); - } - - public override void Write(int value) - { - EnsureBuffer(); - EndianUtilities.WriteBytesBigEndian(value, _buffer, 0); - FlushBuffer(sizeof(Int32)); - } - - public override void Write(uint value) - { - EnsureBuffer(); - EndianUtilities.WriteBytesBigEndian(value, _buffer, 0); - FlushBuffer(sizeof(UInt32)); - } - - public override void Write(long value) - { - EnsureBuffer(); - EndianUtilities.WriteBytesBigEndian(value, _buffer, 0); - FlushBuffer(sizeof(Int64)); - } - - public override void Write(ulong value) - { - EnsureBuffer(); - EndianUtilities.WriteBytesBigEndian(value, _buffer, 0); - FlushBuffer(sizeof(UInt64)); - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Streams/ReaderWriter/DataReader.cs b/src/LibHac.Nand/DiscUtils.Streams/ReaderWriter/DataReader.cs deleted file mode 100644 index 0e2a96c3..00000000 --- a/src/LibHac.Nand/DiscUtils.Streams/ReaderWriter/DataReader.cs +++ /dev/null @@ -1,84 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.IO; - -namespace DiscUtils.Streams -{ - /// - /// Base class for reading binary data from a stream. - /// - public abstract class DataReader - { - private const int _bufferSize = sizeof(UInt64); - - protected readonly Stream _stream; - - protected byte[] _buffer; - - public DataReader(Stream stream) - { - _stream = stream; - } - - public long Length - { - get { return _stream.Length; } - } - - public long Position - { - get { return _stream.Position; } - } - - public void Skip(int bytes) - { - ReadBytes(bytes); - } - - public abstract ushort ReadUInt16(); - - public abstract int ReadInt32(); - - public abstract uint ReadUInt32(); - - public abstract long ReadInt64(); - - public abstract ulong ReadUInt64(); - - public virtual byte[] ReadBytes(int count) - { - return StreamUtilities.ReadExact(_stream, count); - } - - protected void ReadToBuffer(int count) - { - if (_buffer == null) - { - _buffer = new byte[_bufferSize]; - } - - StreamUtilities.ReadExact(_stream, _buffer, 0, count); - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Streams/ReaderWriter/DataWriter.cs b/src/LibHac.Nand/DiscUtils.Streams/ReaderWriter/DataWriter.cs deleted file mode 100644 index f2622acb..00000000 --- a/src/LibHac.Nand/DiscUtils.Streams/ReaderWriter/DataWriter.cs +++ /dev/null @@ -1,79 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.IO; - -namespace DiscUtils.Streams -{ - public abstract class DataWriter - { - private const int _bufferSize = sizeof(UInt64); - - protected readonly Stream _stream; - - protected byte[] _buffer; - - public DataWriter(Stream stream) - { - _stream = stream; - } - - public abstract void Write(ushort value); - - public abstract void Write(int value); - - public abstract void Write(uint value); - - public abstract void Write(long value); - - public abstract void Write(ulong value); - - public virtual void WriteBytes(byte[] value, int offset, int count) - { - _stream.Write(value, offset, count); - } - - public virtual void WriteBytes(byte[] value) - { - _stream.Write(value, 0, value.Length); - } - - public virtual void Flush() - { - _stream.Flush(); - } - - protected void EnsureBuffer() - { - if (_buffer == null) - { - _buffer = new byte[_bufferSize]; - } - } - - protected void FlushBuffer(int count) - { - _stream.Write(_buffer, 0, count); - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Streams/ReaderWriter/LittleEndianDataReader.cs b/src/LibHac.Nand/DiscUtils.Streams/ReaderWriter/LittleEndianDataReader.cs deleted file mode 100644 index ad7ee984..00000000 --- a/src/LibHac.Nand/DiscUtils.Streams/ReaderWriter/LittleEndianDataReader.cs +++ /dev/null @@ -1,66 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.IO; - -namespace DiscUtils.Streams -{ - /// - /// Class for reading little-endian data from a stream. - /// - public class LittleEndianDataReader : DataReader - { - public LittleEndianDataReader(Stream stream) - : base(stream) {} - - public override ushort ReadUInt16() - { - ReadToBuffer(sizeof(UInt16)); - return EndianUtilities.ToUInt16LittleEndian(_buffer, 0); - } - - public override int ReadInt32() - { - ReadToBuffer(sizeof(Int32)); - return EndianUtilities.ToInt32LittleEndian(_buffer, 0); - } - - public override uint ReadUInt32() - { - ReadToBuffer(sizeof(UInt32)); - return EndianUtilities.ToUInt32LittleEndian(_buffer, 0); - } - - public override long ReadInt64() - { - ReadToBuffer(sizeof(Int64)); - return EndianUtilities.ToInt64LittleEndian(_buffer, 0); - } - - public override ulong ReadUInt64() - { - ReadToBuffer(sizeof(UInt64)); - return EndianUtilities.ToUInt64LittleEndian(_buffer, 0); - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Streams/SnapshotStream.cs b/src/LibHac.Nand/DiscUtils.Streams/SnapshotStream.cs deleted file mode 100644 index d27b5058..00000000 --- a/src/LibHac.Nand/DiscUtils.Streams/SnapshotStream.cs +++ /dev/null @@ -1,410 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; -using System.IO; - -namespace DiscUtils.Streams -{ - /// - /// A wrapper stream that enables you to take a snapshot, pushing changes into a side buffer. - /// - /// Once a snapshot is taken, you can discard subsequent changes or merge them back - /// into the wrapped stream. - public sealed class SnapshotStream : SparseStream - { - private Stream _baseStream; - - private readonly Ownership _baseStreamOwnership; - - /// - /// Records which byte ranges in diffStream hold changes. - /// - /// Can't use _diffStream's own tracking because that's based on it's - /// internal block size, not on the _actual_ bytes stored. - private List _diffExtents; - - /// - /// Captures changes to the base stream (when enabled). - /// - private SparseMemoryStream _diffStream; - - /// - /// Indicates that no writes should be permitted. - /// - private bool _frozen; - - private long _position; - - /// - /// The saved stream position (if the diffStream is active). - /// - private long _savedPosition; - - /// - /// Initializes a new instance of the SnapshotStream class. - /// - /// The stream to wrap. - /// Indicates if this stream should control the lifetime of baseStream. - public SnapshotStream(Stream baseStream, Ownership owns) - { - _baseStream = baseStream; - _baseStreamOwnership = owns; - _diffExtents = new List(); - } - - /// - /// Gets an indication as to whether the stream can be read. - /// - public override bool CanRead - { - get { return _baseStream.CanRead; } - } - - /// - /// Gets an indication as to whether the stream position can be changed. - /// - public override bool CanSeek - { - get { return _baseStream.CanSeek; } - } - - /// - /// Gets an indication as to whether the stream can be written to. - /// - /// This property is orthogonal to Freezing/Thawing, it's - /// perfectly possible for a stream to be frozen and this method - /// return true. - public override bool CanWrite - { - get { return _diffStream != null ? true : _baseStream.CanWrite; } - } - - /// - /// Returns an enumeration over the parts of the stream that contain real data. - /// - public override IEnumerable Extents - { - get - { - SparseStream sparseBase = _baseStream as SparseStream; - if (sparseBase == null) - { - return new[] { new StreamExtent(0, Length) }; - } - return StreamExtent.Union(sparseBase.Extents, _diffExtents); - } - } - - /// - /// Gets the length of the stream. - /// - public override long Length - { - get - { - if (_diffStream != null) - { - return _diffStream.Length; - } - return _baseStream.Length; - } - } - - /// - /// Gets and sets the current stream position. - /// - public override long Position - { - get { return _position; } - - set { _position = value; } - } - - /// - /// Prevents any write operations to the stream. - /// - /// Useful to prevent changes whilst inspecting the stream. - public void Freeze() - { - _frozen = true; - } - - /// - /// Re-permits write operations to the stream. - /// - public void Thaw() - { - _frozen = false; - } - - /// - /// Takes a snapshot of the current stream contents. - /// - public void Snapshot() - { - if (_diffStream != null) - { - throw new InvalidOperationException("Already have a snapshot"); - } - - _savedPosition = _position; - - _diffExtents = new List(); - _diffStream = new SparseMemoryStream(); - _diffStream.SetLength(_baseStream.Length); - } - - /// - /// Reverts to a previous snapshot, discarding any changes made to the stream. - /// - public void RevertToSnapshot() - { - if (_diffStream == null) - { - throw new InvalidOperationException("No snapshot"); - } - - _diffStream = null; - _diffExtents = null; - - _position = _savedPosition; - } - - /// - /// Discards the snapshot any changes made after the snapshot was taken are kept. - /// - public void ForgetSnapshot() - { - if (_diffStream == null) - { - throw new InvalidOperationException("No snapshot"); - } - - byte[] buffer = new byte[8192]; - - foreach (StreamExtent extent in _diffExtents) - { - _diffStream.Position = extent.Start; - _baseStream.Position = extent.Start; - - int totalRead = 0; - while (totalRead < extent.Length) - { - int toRead = (int)Math.Min(extent.Length - totalRead, buffer.Length); - - int read = _diffStream.Read(buffer, 0, toRead); - _baseStream.Write(buffer, 0, read); - - totalRead += read; - } - } - - _diffStream = null; - _diffExtents = null; - } - - /// - /// Flushes the stream. - /// - public override void Flush() - { - CheckFrozen(); - - _baseStream.Flush(); - } - - /// - /// Reads data from the stream. - /// - /// The buffer to fill. - /// The buffer offset to start from. - /// The number of bytes to read. - /// The number of bytes read. - public override int Read(byte[] buffer, int offset, int count) - { - int numRead; - - if (_diffStream == null) - { - _baseStream.Position = _position; - numRead = _baseStream.Read(buffer, offset, count); - } - else - { - if (_position > _diffStream.Length) - { - throw new IOException("Attempt to read beyond end of file"); - } - - int toRead = (int)Math.Min(count, _diffStream.Length - _position); - - // If the read is within the base stream's range, then touch it first to get the - // (potentially) stale data. - if (_position < _baseStream.Length) - { - int baseToRead = (int)Math.Min(toRead, _baseStream.Length - _position); - _baseStream.Position = _position; - - int totalBaseRead = 0; - while (totalBaseRead < baseToRead) - { - totalBaseRead += _baseStream.Read(buffer, offset + totalBaseRead, baseToRead - totalBaseRead); - } - } - - // Now overlay any data from the overlay stream (if any) - IEnumerable overlayExtents = StreamExtent.Intersect(_diffExtents, - new StreamExtent(_position, toRead)); - foreach (StreamExtent extent in overlayExtents) - { - _diffStream.Position = extent.Start; - int overlayNumRead = 0; - while (overlayNumRead < extent.Length) - { - overlayNumRead += _diffStream.Read( - buffer, - (int)(offset + (extent.Start - _position) + overlayNumRead), - (int)(extent.Length - overlayNumRead)); - } - } - - numRead = toRead; - } - - _position += numRead; - - return numRead; - } - - /// - /// Moves the stream position. - /// - /// The origin-relative location. - /// The base location. - /// The new absolute stream position. - public override long Seek(long offset, SeekOrigin origin) - { - CheckFrozen(); - - long effectiveOffset = offset; - if (origin == SeekOrigin.Current) - { - effectiveOffset += _position; - } - else if (origin == SeekOrigin.End) - { - effectiveOffset += Length; - } - - if (effectiveOffset < 0) - { - throw new IOException("Attempt to move before beginning of disk"); - } - _position = effectiveOffset; - return _position; - } - - /// - /// Sets the length of the stream. - /// - /// The new length. - public override void SetLength(long value) - { - CheckFrozen(); - - if (_diffStream != null) - { - _diffStream.SetLength(value); - } - else - { - _baseStream.SetLength(value); - } - } - - /// - /// Writes data to the stream at the current location. - /// - /// The data to write. - /// The first byte to write from buffer. - /// The number of bytes to write. - public override void Write(byte[] buffer, int offset, int count) - { - CheckFrozen(); - - if (_diffStream != null) - { - _diffStream.Position = _position; - _diffStream.Write(buffer, offset, count); - - // Beware of Linq's delayed model - force execution now by placing into a list. - // Without this, large execution chains can build up (v. slow) and potential for stack overflow. - _diffExtents = - new List(StreamExtent.Union(_diffExtents, new StreamExtent(_position, count))); - - _position += count; - } - else - { - _baseStream.Position = _position; - _baseStream.Write(buffer, offset, count); - _position += count; - } - } - - /// - /// Disposes of this instance. - /// - /// true if called from Dispose(), else false. - protected override void Dispose(bool disposing) - { - if (disposing) - { - if (_baseStreamOwnership == Ownership.Dispose && _baseStream != null) - { - _baseStream.Dispose(); - } - - _baseStream = null; - - if (_diffStream != null) - { - _diffStream.Dispose(); - } - - _diffStream = null; - } - - base.Dispose(disposing); - } - - private void CheckFrozen() - { - if (_frozen) - { - throw new InvalidOperationException("The stream is frozen"); - } - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Streams/SparseMemoryBuffer.cs b/src/LibHac.Nand/DiscUtils.Streams/SparseMemoryBuffer.cs deleted file mode 100644 index 32dd78fd..00000000 --- a/src/LibHac.Nand/DiscUtils.Streams/SparseMemoryBuffer.cs +++ /dev/null @@ -1,252 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; - -namespace DiscUtils.Streams -{ - /// - /// A sparse in-memory buffer. - /// - /// This class is useful for storing large sparse buffers in memory, unused - /// chunks of the buffer are not stored (assumed to be zero). - public sealed class SparseMemoryBuffer : Buffer - { - private readonly Dictionary _buffers; - - private long _capacity; - - /// - /// Initializes a new instance of the SparseMemoryBuffer class. - /// - /// The size of each allocation chunk. - public SparseMemoryBuffer(int chunkSize) - { - ChunkSize = chunkSize; - _buffers = new Dictionary(); - } - - /// - /// Gets the (sorted) list of allocated chunks, as chunk indexes. - /// - /// An enumeration of chunk indexes. - /// This method returns chunks as an index rather than absolute stream position. - /// For example, if ChunkSize is 16KB, and the first 32KB of the buffer is actually stored, - /// this method will return 0 and 1. This indicates the first and second chunks are stored. - public IEnumerable AllocatedChunks - { - get - { - List keys = new List(_buffers.Keys); - keys.Sort(); - return keys; - } - } - - /// - /// Indicates this stream can be read (always true). - /// - public override bool CanRead - { - get { return true; } - } - - /// - /// Indicates this stream can be written (always true). - /// - public override bool CanWrite - { - get { return true; } - } - - /// - /// Gets the current capacity of the sparse buffer (number of logical bytes stored). - /// - public override long Capacity - { - get { return _capacity; } - } - - /// - /// Gets the size of each allocation chunk. - /// - public int ChunkSize { get; } - - /// - /// Accesses this memory buffer as an infinite byte array. - /// - /// The buffer position to read. - /// The byte stored at this position (or Zero if not explicitly stored). - public byte this[long pos] - { - get - { - byte[] buffer = new byte[1]; - if (Read(pos, buffer, 0, 1) != 0) - { - return buffer[0]; - } - return 0; - } - - set - { - byte[] buffer = new byte[1]; - buffer[0] = value; - Write(pos, buffer, 0, 1); - } - } - - /// - /// Reads a section of the sparse buffer into a byte array. - /// - /// The offset within the sparse buffer to start reading. - /// The destination byte array. - /// The start offset within the destination buffer. - /// The number of bytes to read. - /// The actual number of bytes read. - public override int Read(long pos, byte[] buffer, int offset, int count) - { - int totalRead = 0; - - while (count > 0 && pos < _capacity) - { - int chunk = (int)(pos / ChunkSize); - int chunkOffset = (int)(pos % ChunkSize); - int numToRead = (int)Math.Min(Math.Min(ChunkSize - chunkOffset, _capacity - pos), count); - - if (!_buffers.TryGetValue(chunk, out byte[] chunkBuffer)) - { - Array.Clear(buffer, offset, numToRead); - } - else - { - Array.Copy(chunkBuffer, chunkOffset, buffer, offset, numToRead); - } - - totalRead += numToRead; - offset += numToRead; - count -= numToRead; - pos += numToRead; - } - - return totalRead; - } - - /// - /// Writes a byte array into the sparse buffer. - /// - /// The start offset within the sparse buffer. - /// The source byte array. - /// The start offset within the source byte array. - /// The number of bytes to write. - public override void Write(long pos, byte[] buffer, int offset, int count) - { - while (count > 0) - { - int chunk = (int)(pos / ChunkSize); - int chunkOffset = (int)(pos % ChunkSize); - int numToWrite = Math.Min(ChunkSize - chunkOffset, count); - - if (!_buffers.TryGetValue(chunk, out byte[] chunkBuffer)) - { - chunkBuffer = new byte[ChunkSize]; - _buffers[chunk] = chunkBuffer; - } - - Array.Copy(buffer, offset, chunkBuffer, chunkOffset, numToWrite); - - offset += numToWrite; - count -= numToWrite; - pos += numToWrite; - } - - _capacity = Math.Max(_capacity, pos); - } - - /// - /// Clears bytes from the buffer. - /// - /// The start offset within the buffer. - /// The number of bytes to clear. - public override void Clear(long pos, int count) - { - while (count > 0) - { - int chunk = (int)(pos / ChunkSize); - int chunkOffset = (int)(pos % ChunkSize); - int numToClear = Math.Min(ChunkSize - chunkOffset, count); - - if (_buffers.TryGetValue(chunk, out byte[] chunkBuffer)) - { - if (chunkOffset == 0 && numToClear == ChunkSize) - { - _buffers.Remove(chunk); - } - else - { - Array.Clear(chunkBuffer, chunkOffset, numToClear); - } - } - - count -= numToClear; - pos += numToClear; - } - - _capacity = Math.Max(_capacity, pos); - } - - /// - /// Sets the capacity of the sparse buffer, truncating if appropriate. - /// - /// The desired capacity of the buffer. - /// This method does not allocate any chunks, it merely records the logical - /// capacity of the sparse buffer. Writes beyond the specified capacity will increase - /// the capacity. - public override void SetCapacity(long value) - { - _capacity = value; - } - - /// - /// Gets the parts of a buffer that are stored, within a specified range. - /// - /// The offset of the first byte of interest. - /// The number of bytes of interest. - /// An enumeration of stream extents, indicating stored bytes. - public override IEnumerable GetExtentsInRange(long start, long count) - { - long end = start + count; - foreach (int chunk in AllocatedChunks) - { - long chunkStart = chunk * (long)ChunkSize; - long chunkEnd = chunkStart + ChunkSize; - if (chunkEnd > start && chunkStart < end) - { - long extentStart = Math.Max(start, chunkStart); - yield return new StreamExtent(extentStart, Math.Min(chunkEnd, end) - extentStart); - } - } - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Streams/SparseMemoryStream.cs b/src/LibHac.Nand/DiscUtils.Streams/SparseMemoryStream.cs deleted file mode 100644 index 2c914468..00000000 --- a/src/LibHac.Nand/DiscUtils.Streams/SparseMemoryStream.cs +++ /dev/null @@ -1,47 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System.IO; - -namespace DiscUtils.Streams -{ - /// - /// Provides a sparse equivalent to MemoryStream. - /// - public sealed class SparseMemoryStream : BufferStream - { - /// - /// Initializes a new instance of the SparseMemoryStream class. - /// - /// The created instance permits read and write access. - public SparseMemoryStream() - : base(new SparseMemoryBuffer(16 * 1024), FileAccess.ReadWrite) {} - - /// - /// Initializes a new instance of the SparseMemoryStream class. - /// - /// The buffer to use. - /// The access permitted to clients. - public SparseMemoryStream(SparseMemoryBuffer buffer, FileAccess access) - : base(buffer, access) {} - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Streams/SparseStream.cs b/src/LibHac.Nand/DiscUtils.Streams/SparseStream.cs deleted file mode 100644 index b302aef1..00000000 --- a/src/LibHac.Nand/DiscUtils.Streams/SparseStream.cs +++ /dev/null @@ -1,324 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; -using System.IO; - -namespace DiscUtils.Streams -{ - /// - /// Represents a sparse stream. - /// - /// A sparse stream is a logically contiguous stream where some parts of the stream - /// aren't stored. The unstored parts are implicitly zero-byte ranges. - public abstract class SparseStream : Stream - { - /// - /// Gets the parts of the stream that are stored. - /// - /// This may be an empty enumeration if all bytes are zero. - public abstract IEnumerable Extents { get; } - - /// - /// Converts any stream into a sparse stream. - /// - /// The stream to convert. - /// true to have the new stream dispose the wrapped - /// stream when it is disposed. - /// A sparse stream. - /// The returned stream has the entire wrapped stream as a - /// single extent. - public static SparseStream FromStream(Stream stream, Ownership takeOwnership) - { - return new SparseWrapperStream(stream, takeOwnership, null); - } - - /// - /// Converts any stream into a sparse stream. - /// - /// The stream to convert. - /// true to have the new stream dispose the wrapped - /// stream when it is disposed. - /// The set of extents actually stored in stream. - /// A sparse stream. - /// The returned stream has the entire wrapped stream as a - /// single extent. - public static SparseStream FromStream(Stream stream, Ownership takeOwnership, IEnumerable extents) - { - return new SparseWrapperStream(stream, takeOwnership, extents); - } - - /// - /// Efficiently pumps data from a sparse stream to another stream. - /// - /// The sparse stream to pump from. - /// The stream to pump to. - /// must support seeking. - public static void Pump(Stream inStream, Stream outStream) - { - Pump(inStream, outStream, Sizes.Sector); - } - - /// - /// Efficiently pumps data from a sparse stream to another stream. - /// - /// The stream to pump from. - /// The stream to pump to. - /// The smallest sequence of zero bytes that will be skipped when writing to . - /// must support seeking. - public static void Pump(Stream inStream, Stream outStream, int chunkSize) - { - StreamPump pump = new StreamPump(inStream, outStream, chunkSize); - pump.Run(); - } - - /// - /// Wraps a sparse stream in a read-only wrapper, preventing modification. - /// - /// The stream to make read-only. - /// Whether to transfer responsibility for calling Dispose on toWrap. - /// The read-only stream. - public static SparseStream ReadOnly(SparseStream toWrap, Ownership ownership) - { - return new SparseReadOnlyWrapperStream(toWrap, ownership); - } - - /// - /// Clears bytes from the stream. - /// - /// The number of bytes (from the current position) to clear. - /// - /// Logically equivalent to writing count null/zero bytes to the stream, some - /// implementations determine that some (or all) of the range indicated is not actually - /// stored. There is no direct, automatic, correspondence to clearing bytes and them - /// not being represented as an 'extent' - for example, the implementation of the underlying - /// stream may not permit fine-grained extent storage. - /// It is always safe to call this method to 'zero-out' a section of a stream, regardless of - /// the underlying stream implementation. - /// - public virtual void Clear(int count) - { - Write(new byte[count], 0, count); - } - - /// - /// Gets the parts of a stream that are stored, within a specified range. - /// - /// The offset of the first byte of interest. - /// The number of bytes of interest. - /// An enumeration of stream extents, indicating stored bytes. - public virtual IEnumerable GetExtentsInRange(long start, long count) - { - return StreamExtent.Intersect(Extents, new[] { new StreamExtent(start, count) }); - } - - private class SparseReadOnlyWrapperStream : SparseStream - { - private readonly Ownership _ownsWrapped; - private SparseStream _wrapped; - - public SparseReadOnlyWrapperStream(SparseStream wrapped, Ownership ownsWrapped) - { - _wrapped = wrapped; - _ownsWrapped = ownsWrapped; - } - - public override bool CanRead - { - get { return _wrapped.CanRead; } - } - - public override bool CanSeek - { - get { return _wrapped.CanSeek; } - } - - public override bool CanWrite - { - get { return false; } - } - - public override IEnumerable Extents - { - get { return _wrapped.Extents; } - } - - public override long Length - { - get { return _wrapped.Length; } - } - - public override long Position - { - get { return _wrapped.Position; } - - set { _wrapped.Position = value; } - } - - public override void Flush() {} - - public override int Read(byte[] buffer, int offset, int count) - { - return _wrapped.Read(buffer, offset, count); - } - - public override long Seek(long offset, SeekOrigin origin) - { - return _wrapped.Seek(offset, origin); - } - - public override void SetLength(long value) - { - throw new InvalidOperationException("Attempt to change length of read-only stream"); - } - - public override void Write(byte[] buffer, int offset, int count) - { - throw new InvalidOperationException("Attempt to write to read-only stream"); - } - - protected override void Dispose(bool disposing) - { - try - { - if (disposing && _ownsWrapped == Ownership.Dispose && _wrapped != null) - { - _wrapped.Dispose(); - _wrapped = null; - } - } - finally - { - base.Dispose(disposing); - } - } - } - - private class SparseWrapperStream : SparseStream - { - private readonly List _extents; - private readonly Ownership _ownsWrapped; - private Stream _wrapped; - - public SparseWrapperStream(Stream wrapped, Ownership ownsWrapped, IEnumerable extents) - { - _wrapped = wrapped; - _ownsWrapped = ownsWrapped; - if (extents != null) - { - _extents = new List(extents); - } - } - - public override bool CanRead - { - get { return _wrapped.CanRead; } - } - - public override bool CanSeek - { - get { return _wrapped.CanSeek; } - } - - public override bool CanWrite - { - get { return _wrapped.CanWrite; } - } - - public override IEnumerable Extents - { - get - { - if (_extents != null) - { - return _extents; - } - SparseStream wrappedAsSparse = _wrapped as SparseStream; - if (wrappedAsSparse != null) - { - return wrappedAsSparse.Extents; - } - return new[] { new StreamExtent(0, _wrapped.Length) }; - } - } - - public override long Length - { - get { return _wrapped.Length; } - } - - public override long Position - { - get { return _wrapped.Position; } - - set { _wrapped.Position = value; } - } - - public override void Flush() - { - _wrapped.Flush(); - } - - public override int Read(byte[] buffer, int offset, int count) - { - return _wrapped.Read(buffer, offset, count); - } - - public override long Seek(long offset, SeekOrigin origin) - { - return _wrapped.Seek(offset, origin); - } - - public override void SetLength(long value) - { - _wrapped.SetLength(value); - } - - public override void Write(byte[] buffer, int offset, int count) - { - if (_extents != null) - { - throw new InvalidOperationException("Attempt to write to stream with explicit extents"); - } - - _wrapped.Write(buffer, offset, count); - } - - protected override void Dispose(bool disposing) - { - try - { - if (disposing && _ownsWrapped == Ownership.Dispose && _wrapped != null) - { - _wrapped.Dispose(); - _wrapped = null; - } - } - finally - { - base.Dispose(disposing); - } - } - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Streams/SparseStreamOpenDelegate.cs b/src/LibHac.Nand/DiscUtils.Streams/SparseStreamOpenDelegate.cs deleted file mode 100644 index 14062589..00000000 --- a/src/LibHac.Nand/DiscUtils.Streams/SparseStreamOpenDelegate.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace DiscUtils.Streams -{ - public delegate SparseStream SparseStreamOpenDelegate(); -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Streams/StreamBuffer.cs b/src/LibHac.Nand/DiscUtils.Streams/StreamBuffer.cs deleted file mode 100644 index d65685f1..00000000 --- a/src/LibHac.Nand/DiscUtils.Streams/StreamBuffer.cs +++ /dev/null @@ -1,164 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; -using System.IO; - -namespace DiscUtils.Streams -{ - /// - /// Converts a Stream into an IBuffer instance. - /// - public sealed class StreamBuffer : Buffer, IDisposable - { - private readonly Ownership _ownership; - private SparseStream _stream; - - /// - /// Initializes a new instance of the StreamBuffer class. - /// - /// The stream to wrap. - /// Whether to dispose stream, when this object is disposed. - public StreamBuffer(Stream stream, Ownership ownership) - { - if (stream == null) - { - throw new ArgumentNullException(nameof(stream)); - } - - _stream = stream as SparseStream; - if (_stream == null) - { - _stream = SparseStream.FromStream(stream, ownership); - _ownership = Ownership.Dispose; - } - else - { - _ownership = ownership; - } - } - - /// - /// Can this buffer be read. - /// - public override bool CanRead - { - get { return _stream.CanRead; } - } - - /// - /// Can this buffer be written. - /// - public override bool CanWrite - { - get { return _stream.CanWrite; } - } - - /// - /// Gets the current capacity of the buffer, in bytes. - /// - public override long Capacity - { - get { return _stream.Length; } - } - - /// - /// Gets the parts of the stream that are stored. - /// - /// This may be an empty enumeration if all bytes are zero. - public override IEnumerable Extents - { - get { return _stream.Extents; } - } - - /// - /// Disposes of this instance. - /// - public void Dispose() - { - if (_ownership == Ownership.Dispose) - { - if (_stream != null) - { - _stream.Dispose(); - _stream = null; - } - } - } - - /// - /// Reads from the buffer into a byte array. - /// - /// The offset within the buffer to start reading. - /// The destination byte array. - /// The start offset within the destination buffer. - /// The number of bytes to read. - /// The actual number of bytes read. - public override int Read(long pos, byte[] buffer, int offset, int count) - { - _stream.Position = pos; - return _stream.Read(buffer, offset, count); - } - - /// - /// Writes a byte array into the buffer. - /// - /// The start offset within the buffer. - /// The source byte array. - /// The start offset within the source byte array. - /// The number of bytes to write. - public override void Write(long pos, byte[] buffer, int offset, int count) - { - _stream.Position = pos; - _stream.Write(buffer, offset, count); - } - - /// - /// Flushes all data to the underlying storage. - /// - public override void Flush() - { - _stream.Flush(); - } - - /// - /// Sets the capacity of the buffer, truncating if appropriate. - /// - /// The desired capacity of the buffer. - public override void SetCapacity(long value) - { - _stream.SetLength(value); - } - - /// - /// Gets the parts of a buffer that are stored, within a specified range. - /// - /// The offset of the first byte of interest. - /// The number of bytes of interest. - /// An enumeration of stream extents, indicating stored bytes. - public override IEnumerable GetExtentsInRange(long start, long count) - { - return _stream.GetExtentsInRange(start, count); - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Streams/StreamExtent.cs b/src/LibHac.Nand/DiscUtils.Streams/StreamExtent.cs deleted file mode 100644 index a00de5ea..00000000 --- a/src/LibHac.Nand/DiscUtils.Streams/StreamExtent.cs +++ /dev/null @@ -1,493 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; - -namespace DiscUtils.Streams -{ - /// - /// Represents a range of bytes in a stream. - /// - /// This is normally used to represent regions of a SparseStream that - /// are actually stored in the underlying storage medium (rather than implied - /// zero bytes). Extents are stored as a zero-based byte offset (from the - /// beginning of the stream), and a byte length. - public sealed class StreamExtent : IEquatable, IComparable - { - /// - /// Initializes a new instance of the StreamExtent class. - /// - /// The start of the extent. - /// The length of the extent. - public StreamExtent(long start, long length) - { - Start = start; - Length = length; - } - - /// - /// Gets the start of the extent (in bytes). - /// - public long Length { get; } - - /// - /// Gets the start of the extent (in bytes). - /// - public long Start { get; } - - /// - /// Compares this stream extent to another. - /// - /// The extent to compare. - /// Value greater than zero if this extent starts after - /// other, zero if they start at the same position, else - /// a value less than zero. - public int CompareTo(StreamExtent other) - { - if (Start > other.Start) - { - return 1; - } - if (Start == other.Start) - { - return 0; - } - return -1; - } - - /// - /// Indicates if this StreamExtent is equal to another. - /// - /// The extent to compare. - /// true if the extents are equal, else false. - public bool Equals(StreamExtent other) - { - if (other == null) - { - return false; - } - return Start == other.Start && Length == other.Length; - } - - /// - /// Calculates the union of a list of extents with another extent. - /// - /// The list of extents. - /// The other extent. - /// The union of the extents. - public static IEnumerable Union(IEnumerable extents, StreamExtent other) - { - List otherList = new List(); - otherList.Add(other); - return Union(extents, otherList); - } - - /// - /// Calculates the union of the extents of multiple streams. - /// - /// The stream extents. - /// The union of the extents from multiple streams. - /// A typical use of this method is to calculate the combined set of - /// stored extents from a number of overlayed sparse streams. - public static IEnumerable Union(params IEnumerable[] streams) - { - long extentStart = long.MaxValue; - long extentEnd = 0; - - // Initialize enumerations and find first stored byte position - IEnumerator[] enums = new IEnumerator[streams.Length]; - bool[] streamsValid = new bool[streams.Length]; - int validStreamsRemaining = 0; - for (int i = 0; i < streams.Length; ++i) - { - enums[i] = streams[i].GetEnumerator(); - streamsValid[i] = enums[i].MoveNext(); - if (streamsValid[i]) - { - ++validStreamsRemaining; - if (enums[i].Current.Start < extentStart) - { - extentStart = enums[i].Current.Start; - extentEnd = enums[i].Current.Start + enums[i].Current.Length; - } - } - } - - while (validStreamsRemaining > 0) - { - // Find the end of this extent - bool foundIntersection; - do - { - foundIntersection = false; - validStreamsRemaining = 0; - for (int i = 0; i < streams.Length; ++i) - { - while (streamsValid[i] && enums[i].Current.Start + enums[i].Current.Length <= extentEnd) - { - streamsValid[i] = enums[i].MoveNext(); - } - - if (streamsValid[i]) - { - ++validStreamsRemaining; - } - - if (streamsValid[i] && enums[i].Current.Start <= extentEnd) - { - extentEnd = enums[i].Current.Start + enums[i].Current.Length; - foundIntersection = true; - streamsValid[i] = enums[i].MoveNext(); - } - } - } while (foundIntersection && validStreamsRemaining > 0); - - // Return the discovered extent - yield return new StreamExtent(extentStart, extentEnd - extentStart); - - // Find the next extent start point - extentStart = long.MaxValue; - validStreamsRemaining = 0; - for (int i = 0; i < streams.Length; ++i) - { - if (streamsValid[i]) - { - ++validStreamsRemaining; - if (enums[i].Current.Start < extentStart) - { - extentStart = enums[i].Current.Start; - extentEnd = enums[i].Current.Start + enums[i].Current.Length; - } - } - } - } - } - - /// - /// Calculates the intersection of the extents of a stream with another extent. - /// - /// The stream extents. - /// The extent to intersect. - /// The intersection of the extents. - public static IEnumerable Intersect(IEnumerable extents, StreamExtent other) - { - List otherList = new List(1); - otherList.Add(other); - return Intersect(extents, otherList); - } - - /// - /// Calculates the intersection of the extents of multiple streams. - /// - /// The stream extents. - /// The intersection of the extents from multiple streams. - /// A typical use of this method is to calculate the extents in a - /// region of a stream.. - public static IEnumerable Intersect(params IEnumerable[] streams) - { - long extentStart = long.MinValue; - long extentEnd = long.MaxValue; - - IEnumerator[] enums = new IEnumerator[streams.Length]; - for (int i = 0; i < streams.Length; ++i) - { - enums[i] = streams[i].GetEnumerator(); - if (!enums[i].MoveNext()) - { - // Gone past end of one stream (in practice was empty), so no intersections - yield break; - } - } - - int overlapsFound = 0; - while (true) - { - // We keep cycling round the streams, until we get streams.Length continuous overlaps - for (int i = 0; i < streams.Length; ++i) - { - // Move stream on past all extents that are earlier than our candidate start point - while (enums[i].Current.Length == 0 - || enums[i].Current.Start + enums[i].Current.Length <= extentStart) - { - if (!enums[i].MoveNext()) - { - // Gone past end of this stream, no more intersections possible - yield break; - } - } - - // If this stream has an extent that spans over the candidate start point - if (enums[i].Current.Start <= extentStart) - { - extentEnd = Math.Min(extentEnd, enums[i].Current.Start + enums[i].Current.Length); - overlapsFound++; - } - else - { - extentStart = enums[i].Current.Start; - extentEnd = extentStart + enums[i].Current.Length; - overlapsFound = 1; - } - - // We've just done a complete loop of all streams, they overlapped this start position - // and we've cut the extent's end down to the shortest run. - if (overlapsFound == streams.Length) - { - yield return new StreamExtent(extentStart, extentEnd - extentStart); - extentStart = extentEnd; - extentEnd = long.MaxValue; - overlapsFound = 0; - } - } - } - } - - /// - /// Calculates the subtraction of the extents of a stream by another extent. - /// - /// The stream extents. - /// The extent to subtract. - /// The subtraction of other from extents. - public static IEnumerable Subtract(IEnumerable extents, StreamExtent other) - { - return Subtract(extents, new[] { other }); - } - - /// - /// Calculates the subtraction of the extents of a stream by another stream. - /// - /// The stream extents to subtract from. - /// The stream extents to subtract. - /// The subtraction of the extents of b from a. - public static IEnumerable Subtract(IEnumerable a, IEnumerable b) - { - return Intersect(a, Invert(b)); - } - - /// - /// Calculates the inverse of the extents of a stream. - /// - /// The stream extents to inverse. - /// The inverted extents. - /// - /// This method assumes a logical stream addressable from 0 to long.MaxValue, and is undefined - /// should any stream extent start at less than 0. To constrain the extents to a specific range, use the - /// Intersect method. - /// - public static IEnumerable Invert(IEnumerable extents) - { - StreamExtent last = new StreamExtent(0, 0); - foreach (StreamExtent extent in extents) - { - // Skip over any 'noise' - if (extent.Length == 0) - { - continue; - } - - long lastEnd = last.Start + last.Length; - if (lastEnd < extent.Start) - { - yield return new StreamExtent(lastEnd, extent.Start - lastEnd); - } - - last = extent; - } - - long finalEnd = last.Start + last.Length; - if (finalEnd < long.MaxValue) - { - yield return new StreamExtent(finalEnd, long.MaxValue - finalEnd); - } - } - - /// - /// Offsets the extents of a stream. - /// - /// The stream extents. - /// The amount to offset the extents by. - /// The stream extents, offset by delta. - public static IEnumerable Offset(IEnumerable stream, long delta) - { - foreach (StreamExtent extent in stream) - { - yield return new StreamExtent(extent.Start + delta, extent.Length); - } - } - - /// - /// Returns the number of blocks containing stream data. - /// - /// The stream extents. - /// The size of each block. - /// The number of blocks containing stream data. - /// This method logically divides the stream into blocks of a specified - /// size, then indicates how many of those blocks contain actual stream data. - public static long BlockCount(IEnumerable stream, long blockSize) - { - long totalBlocks = 0; - long lastBlock = -1; - - foreach (StreamExtent extent in stream) - { - if (extent.Length > 0) - { - long extentStartBlock = extent.Start / blockSize; - long extentNextBlock = MathUtilities.Ceil(extent.Start + extent.Length, blockSize); - - long extentNumBlocks = extentNextBlock - extentStartBlock; - if (extentStartBlock == lastBlock) - { - extentNumBlocks--; - } - - lastBlock = extentNextBlock - 1; - - totalBlocks += extentNumBlocks; - } - } - - return totalBlocks; - } - - /// - /// Returns all of the blocks containing stream data. - /// - /// The stream extents. - /// The size of each block. - /// Ranges of blocks, as block indexes. - /// This method logically divides the stream into blocks of a specified - /// size, then indicates ranges of blocks that contain stream data. - public static IEnumerable> Blocks(IEnumerable stream, long blockSize) - { - long? rangeStart = null; - long rangeLength = 0; - - foreach (StreamExtent extent in stream) - { - if (extent.Length > 0) - { - long extentStartBlock = extent.Start / blockSize; - long extentNextBlock = MathUtilities.Ceil(extent.Start + extent.Length, blockSize); - - if (rangeStart != null && extentStartBlock > rangeStart + rangeLength) - { - // This extent is non-contiguous (in terms of blocks), so write out the last range and start new - yield return new Range((long)rangeStart, rangeLength); - rangeStart = extentStartBlock; - } - else if (rangeStart == null) - { - // First extent, so start first range - rangeStart = extentStartBlock; - } - - // Set the length of the current range, based on the end of this extent - rangeLength = extentNextBlock - (long)rangeStart; - } - } - - // Final range (if any ranges at all) hasn't been returned yet, so do that now - if (rangeStart != null) - { - yield return new Range((long)rangeStart, rangeLength); - } - } - - /// - /// The equality operator. - /// - /// The first extent to compare. - /// The second extent to compare. - /// Whether the two extents are equal. - public static bool operator ==(StreamExtent a, StreamExtent b) - { - if (ReferenceEquals(a, null)) - { - return ReferenceEquals(b, null); - } - return a.Equals(b); - } - - /// - /// The inequality operator. - /// - /// The first extent to compare. - /// The second extent to compare. - /// Whether the two extents are different. - public static bool operator !=(StreamExtent a, StreamExtent b) - { - return !(a == b); - } - - /// - /// The less-than operator. - /// - /// The first extent to compare. - /// The second extent to compare. - /// Whether a is less than b. - public static bool operator <(StreamExtent a, StreamExtent b) - { - return a.CompareTo(b) < 0; - } - - /// - /// The greater-than operator. - /// - /// The first extent to compare. - /// The second extent to compare. - /// Whether a is greater than b. - public static bool operator >(StreamExtent a, StreamExtent b) - { - return a.CompareTo(b) > 0; - } - - /// - /// Returns a string representation of the extent as [start:+length]. - /// - /// The string representation. - public override string ToString() - { - return "[" + Start + ":+" + Length + "]"; - } - - /// - /// Indicates if this stream extent is equal to another object. - /// - /// The object to test. - /// true if obj is equivalent, else false. - public override bool Equals(object obj) - { - return Equals(obj as StreamExtent); - } - - /// - /// Gets a hash code for this extent. - /// - /// The extent's hash code. - public override int GetHashCode() - { - return Start.GetHashCode() ^ Length.GetHashCode(); - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Streams/StreamPump.cs b/src/LibHac.Nand/DiscUtils.Streams/StreamPump.cs deleted file mode 100644 index 1b91eb8f..00000000 --- a/src/LibHac.Nand/DiscUtils.Streams/StreamPump.cs +++ /dev/null @@ -1,270 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.IO; - -namespace DiscUtils.Streams -{ - /// - /// Utility class for pumping the contents of one stream into another. - /// - /// - /// This class is aware of sparse streams, and will avoid copying data that is not - /// valid in the source stream. This functionality should normally only be used - /// when the destination stream is known not to contain any existing data. - /// - public sealed class StreamPump - { - /// - /// Initializes a new instance of the StreamPump class. - /// - public StreamPump() - { - SparseChunkSize = 512; - BufferSize = (int)(512 * Sizes.OneKiB); - SparseCopy = true; - } - - /// - /// Initializes a new instance of the StreamPump class. - /// - /// The stream to read from. - /// The stream to write to. - /// The size of each sparse chunk. - public StreamPump(Stream inStream, Stream outStream, int sparseChunkSize) - { - InputStream = inStream; - OutputStream = outStream; - SparseChunkSize = sparseChunkSize; - BufferSize = (int)(512 * Sizes.OneKiB); - SparseCopy = true; - } - - /// - /// Gets or sets the amount of data to read at a time from InputStream. - /// - public int BufferSize { get; set; } - - /// - /// Gets the number of bytes read from InputStream. - /// - public long BytesRead { get; private set; } - - /// - /// Gets the number of bytes written to OutputStream. - /// - public long BytesWritten { get; private set; } - - /// - /// Gets or sets the stream that will be read from. - /// - public Stream InputStream { get; set; } - - /// - /// Gets or sets the stream that will be written to. - /// - public Stream OutputStream { get; set; } - - /// - /// Gets or sets, for sparse transfers, the size of each chunk. - /// - /// - /// A chunk is transfered if any byte in the chunk is valid, otherwise it is not. - /// This value should normally be set to reflect the underlying storage granularity - /// of OutputStream. - /// - public int SparseChunkSize { get; set; } - - /// - /// Gets or sets a value indicating whether to enable the sparse copy behaviour (default true). - /// - public bool SparseCopy { get; set; } - - /// - /// Event raised periodically through the pump operation. - /// - /// - /// This event is signalled synchronously, so to avoid slowing the pumping activity - /// implementations should return quickly. - /// - public event EventHandler ProgressEvent; - - /// - /// Performs the pump activity, blocking until complete. - /// - public void Run() - { - if (InputStream == null) - { - throw new InvalidOperationException("Input stream is null"); - } - - if (OutputStream == null) - { - throw new InvalidOperationException("Output stream is null"); - } - - if (!OutputStream.CanSeek) - { - throw new InvalidOperationException("Output stream does not support seek operations"); - } - - if (SparseChunkSize <= 1) - { - throw new InvalidOperationException("Chunk size is invalid"); - } - - if (SparseCopy) - { - RunSparse(); - } - else - { - RunNonSparse(); - } - } - - private static bool IsAllZeros(byte[] buffer, int offset, int count) - { - for (int j = 0; j < count; j++) - { - if (buffer[offset + j] != 0) - { - return false; - } - } - - return true; - } - - private void RunNonSparse() - { - byte[] copyBuffer = new byte[BufferSize]; - - InputStream.Position = 0; - OutputStream.Position = 0; - - int numRead = InputStream.Read(copyBuffer, 0, copyBuffer.Length); - while (numRead > 0) - { - BytesRead += numRead; - - OutputStream.Write(copyBuffer, 0, numRead); - BytesWritten += numRead; - - RaiseProgressEvent(); - - numRead = InputStream.Read(copyBuffer, 0, copyBuffer.Length); - } - } - - private void RunSparse() - { - SparseStream inStream = InputStream as SparseStream; - if (inStream == null) - { - inStream = SparseStream.FromStream(InputStream, Ownership.None); - } - - if (BufferSize > SparseChunkSize && BufferSize % SparseChunkSize != 0) - { - throw new InvalidOperationException("Buffer size is not a multiple of the sparse chunk size"); - } - - byte[] copyBuffer = new byte[Math.Max(BufferSize, SparseChunkSize)]; - - BytesRead = 0; - BytesWritten = 0; - - foreach (StreamExtent extent in inStream.Extents) - { - inStream.Position = extent.Start; - - long extentOffset = 0; - while (extentOffset < extent.Length) - { - int numRead = (int)Math.Min(copyBuffer.Length, extent.Length - extentOffset); - StreamUtilities.ReadExact(inStream, copyBuffer, 0, numRead); - BytesRead += numRead; - - int copyBufferOffset = 0; - for (int i = 0; i < numRead; i += SparseChunkSize) - { - if (IsAllZeros(copyBuffer, i, Math.Min(SparseChunkSize, numRead - i))) - { - if (copyBufferOffset < i) - { - OutputStream.Position = extent.Start + extentOffset + copyBufferOffset; - OutputStream.Write(copyBuffer, copyBufferOffset, i - copyBufferOffset); - BytesWritten += i - copyBufferOffset; - } - - copyBufferOffset = i + SparseChunkSize; - } - } - - if (copyBufferOffset < numRead) - { - OutputStream.Position = extent.Start + extentOffset + copyBufferOffset; - OutputStream.Write(copyBuffer, copyBufferOffset, numRead - copyBufferOffset); - BytesWritten += numRead - copyBufferOffset; - } - - extentOffset += numRead; - - RaiseProgressEvent(); - } - } - - // Ensure the output stream is at least as long as the input stream. This uses - // read/write, rather than SetLength, to avoid failing on streams that can't be - // explicitly resized. Side-effect of this, is that if outStream is an NTFS - // file stream, then actual clusters will be allocated out to at least the - // length of the input stream. - if (OutputStream.Length < inStream.Length) - { - inStream.Position = inStream.Length - 1; - int b = inStream.ReadByte(); - if (b >= 0) - { - OutputStream.Position = inStream.Length - 1; - OutputStream.WriteByte((byte)b); - } - } - } - - private void RaiseProgressEvent() - { - // Raise the event by using the () operator. - if (ProgressEvent != null) - { - PumpProgressEventArgs args = new PumpProgressEventArgs(); - args.BytesRead = BytesRead; - args.BytesWritten = BytesWritten; - args.SourcePosition = InputStream.Position; - args.DestinationPosition = OutputStream.Position; - ProgressEvent(this, args); - } - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Streams/StripedStream.cs b/src/LibHac.Nand/DiscUtils.Streams/StripedStream.cs deleted file mode 100644 index cff0f8fd..00000000 --- a/src/LibHac.Nand/DiscUtils.Streams/StripedStream.cs +++ /dev/null @@ -1,221 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; -using System.IO; - -namespace DiscUtils.Streams -{ - public class StripedStream : SparseStream - { - private readonly bool _canRead; - private readonly bool _canWrite; - private readonly long _length; - private readonly Ownership _ownsWrapped; - - private long _position; - private readonly long _stripeSize; - private List _wrapped; - - public StripedStream(long stripeSize, Ownership ownsWrapped, params SparseStream[] wrapped) - { - _wrapped = new List(wrapped); - _stripeSize = stripeSize; - _ownsWrapped = ownsWrapped; - - _canRead = _wrapped[0].CanRead; - _canWrite = _wrapped[0].CanWrite; - long subStreamLength = _wrapped[0].Length; - - foreach (SparseStream stream in _wrapped) - { - if (stream.CanRead != _canRead || stream.CanWrite != _canWrite) - { - throw new ArgumentException("All striped streams must have the same read/write permissions", - nameof(wrapped)); - } - - if (stream.Length != subStreamLength) - { - throw new ArgumentException("All striped streams must have the same length", nameof(wrapped)); - } - } - - _length = subStreamLength * wrapped.Length; - } - - public override bool CanRead - { - get { return _canRead; } - } - - public override bool CanSeek - { - get { return true; } - } - - public override bool CanWrite - { - get { return _canWrite; } - } - - public override IEnumerable Extents - { - get - { - // Temporary, indicate there are no 'unstored' extents. - // Consider combining extent information from all wrapped streams in future. - yield return new StreamExtent(0, _length); - } - } - - public override long Length - { - get { return _length; } - } - - public override long Position - { - get { return _position; } - - set { _position = value; } - } - - public override void Flush() - { - foreach (SparseStream stream in _wrapped) - { - stream.Flush(); - } - } - - public override int Read(byte[] buffer, int offset, int count) - { - if (!CanRead) - { - throw new InvalidOperationException("Attempt to read to non-readable stream"); - } - - int maxToRead = (int)Math.Min(_length - _position, count); - - int totalRead = 0; - while (totalRead < maxToRead) - { - long stripe = _position / _stripeSize; - long stripeOffset = _position % _stripeSize; - int stripeToRead = (int)Math.Min(maxToRead - totalRead, _stripeSize - stripeOffset); - - int streamIdx = (int)(stripe % _wrapped.Count); - long streamStripe = stripe / _wrapped.Count; - - Stream targetStream = _wrapped[streamIdx]; - targetStream.Position = streamStripe * _stripeSize + stripeOffset; - - int numRead = targetStream.Read(buffer, offset + totalRead, stripeToRead); - _position += numRead; - totalRead += numRead; - } - - return totalRead; - } - - public override long Seek(long offset, SeekOrigin origin) - { - long effectiveOffset = offset; - if (origin == SeekOrigin.Current) - { - effectiveOffset += _position; - } - else if (origin == SeekOrigin.End) - { - effectiveOffset += _length; - } - - if (effectiveOffset < 0) - { - throw new IOException("Attempt to move before beginning of stream"); - } - _position = effectiveOffset; - return _position; - } - - public override void SetLength(long value) - { - if (value != _length) - { - throw new InvalidOperationException("Changing the stream length is not permitted for striped streams"); - } - } - - public override void Write(byte[] buffer, int offset, int count) - { - if (!CanWrite) - { - throw new InvalidOperationException("Attempt to write to read-only stream"); - } - - if (_position + count > _length) - { - throw new IOException("Attempt to write beyond end of stream"); - } - - int totalWritten = 0; - while (totalWritten < count) - { - long stripe = _position / _stripeSize; - long stripeOffset = _position % _stripeSize; - int stripeToWrite = (int)Math.Min(count - totalWritten, _stripeSize - stripeOffset); - - int streamIdx = (int)(stripe % _wrapped.Count); - long streamStripe = stripe / _wrapped.Count; - - Stream targetStream = _wrapped[streamIdx]; - targetStream.Position = streamStripe * _stripeSize + stripeOffset; - targetStream.Write(buffer, offset + totalWritten, stripeToWrite); - - _position += stripeToWrite; - totalWritten += stripeToWrite; - } - } - - protected override void Dispose(bool disposing) - { - try - { - if (disposing && _ownsWrapped == Ownership.Dispose && _wrapped != null) - { - foreach (SparseStream stream in _wrapped) - { - stream.Dispose(); - } - - _wrapped = null; - } - } - finally - { - base.Dispose(disposing); - } - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Streams/SubStream.cs b/src/LibHac.Nand/DiscUtils.Streams/SubStream.cs deleted file mode 100644 index 58dce20e..00000000 --- a/src/LibHac.Nand/DiscUtils.Streams/SubStream.cs +++ /dev/null @@ -1,212 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; -using System.IO; - -namespace DiscUtils.Streams -{ - public class SubStream : MappedStream - { - private readonly long _first; - private readonly long _length; - private readonly Ownership _ownsParent; - - private readonly Stream _parent; - private long _position; - - public SubStream(Stream parent, long first, long length) - { - _parent = parent; - _first = first; - _length = length; - _ownsParent = Ownership.None; - - if (_first + _length > _parent.Length) - { - throw new ArgumentException("Substream extends beyond end of parent stream"); - } - } - - public SubStream(Stream parent, Ownership ownsParent, long first, long length) - { - _parent = parent; - _ownsParent = ownsParent; - _first = first; - _length = length; - - if (_first + _length > _parent.Length) - { - throw new ArgumentException("Substream extends beyond end of parent stream"); - } - } - - public override bool CanRead - { - get { return _parent.CanRead; } - } - - public override bool CanSeek - { - get { return _parent.CanSeek; } - } - - public override bool CanWrite - { - get { return _parent.CanWrite; } - } - - public override IEnumerable Extents - { - get - { - SparseStream parentAsSparse = _parent as SparseStream; - if (parentAsSparse != null) - { - return OffsetExtents(parentAsSparse.GetExtentsInRange(_first, _length)); - } - return new[] { new StreamExtent(0, _length) }; - } - } - - public override long Length - { - get { return _length; } - } - - public override long Position - { - get { return _position; } - - set - { - if (value <= _length) - { - _position = value; - } - else - { - throw new ArgumentOutOfRangeException(nameof(value), "Attempt to move beyond end of stream"); - } - } - } - - public override IEnumerable MapContent(long start, long length) - { - return new[] { new StreamExtent(start + _first, length) }; - } - - public override void Flush() - { - _parent.Flush(); - } - - public override int Read(byte[] buffer, int offset, int count) - { - if (count < 0) - { - throw new ArgumentOutOfRangeException(nameof(count), "Attempt to read negative bytes"); - } - - if (_position > _length) - { - return 0; - } - - _parent.Position = _first + _position; - int numRead = _parent.Read(buffer, offset, - (int)Math.Min(count, Math.Min(_length - _position, int.MaxValue))); - _position += numRead; - return numRead; - } - - public override long Seek(long offset, SeekOrigin origin) - { - long absNewPos = offset; - if (origin == SeekOrigin.Current) - { - absNewPos += _position; - } - else if (origin == SeekOrigin.End) - { - absNewPos += _length; - } - - if (absNewPos < 0) - { - throw new ArgumentOutOfRangeException(nameof(offset), "Attempt to move before start of stream"); - } - - _position = absNewPos; - return _position; - } - - public override void SetLength(long value) - { - throw new NotSupportedException("Attempt to change length of a substream"); - } - - public override void Write(byte[] buffer, int offset, int count) - { - if (count < 0) - { - throw new ArgumentOutOfRangeException(nameof(count), "Attempt to write negative bytes"); - } - - if (_position + count > _length) - { - throw new ArgumentOutOfRangeException(nameof(count), "Attempt to write beyond end of substream"); - } - - _parent.Position = _first + _position; - _parent.Write(buffer, offset, count); - _position += count; - } - - protected override void Dispose(bool disposing) - { - try - { - if (disposing) - { - if (_ownsParent == Ownership.Dispose) - { - _parent.Dispose(); - } - } - } - finally - { - base.Dispose(disposing); - } - } - - private IEnumerable OffsetExtents(IEnumerable src) - { - foreach (StreamExtent e in src) - { - yield return new StreamExtent(e.Start - _first, e.Length); - } - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Streams/System/Func.cs b/src/LibHac.Nand/DiscUtils.Streams/System/Func.cs deleted file mode 100644 index 0a7ac0bc..00000000 --- a/src/LibHac.Nand/DiscUtils.Streams/System/Func.cs +++ /dev/null @@ -1,7 +0,0 @@ - -#if NET20 -namespace System -{ - public delegate TResult Func(T arg); -} -#endif \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Streams/ThreadSafeStream.cs b/src/LibHac.Nand/DiscUtils.Streams/ThreadSafeStream.cs deleted file mode 100644 index b860135c..00000000 --- a/src/LibHac.Nand/DiscUtils.Streams/ThreadSafeStream.cs +++ /dev/null @@ -1,336 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; -using System.IO; - -namespace DiscUtils.Streams -{ - /// - /// Provides a thread-safe wrapping around a sparse stream. - /// - /// - /// Streams are inherently not thread-safe (because read/write is not atomic w.r.t. Position). - /// This method enables multiple 'views' of a stream to be created (each with their own Position), and ensures - /// only a single operation is executing on the wrapped stream at any time. - /// This example shows the pattern of use: - /// - /// - /// SparseStream baseStream = ...; - /// ThreadSafeStream tss = new ThreadSafeStream(baseStream); - /// for(int i = 0; i < 10; ++i) - /// { - /// SparseStream streamForThread = tss.OpenView(); - /// } - /// - /// - /// This results in 11 streams that can be used in different streams - tss and ten 'views' created from tss. - /// Note, the stream length cannot be changed. - /// - public class ThreadSafeStream : SparseStream - { - private CommonState _common; - private readonly bool _ownsCommon; - private long _position; - - /// - /// Initializes a new instance of the ThreadSafeStream class. - /// - /// The stream to wrap. - /// Do not directly modify toWrap after wrapping it, unless the thread-safe views - /// will no longer be used. - public ThreadSafeStream(SparseStream toWrap) - : this(toWrap, Ownership.None) {} - - /// - /// Initializes a new instance of the ThreadSafeStream class. - /// - /// The stream to wrap. - /// Whether to transfer ownership of toWrap to the new instance. - /// Do not directly modify toWrap after wrapping it, unless the thread-safe views - /// will no longer be used. - public ThreadSafeStream(SparseStream toWrap, Ownership ownership) - { - if (!toWrap.CanSeek) - { - throw new ArgumentException("Wrapped stream must support seeking", nameof(toWrap)); - } - - _common = new CommonState - { - WrappedStream = toWrap, - WrappedStreamOwnership = ownership - }; - _ownsCommon = true; - } - - private ThreadSafeStream(ThreadSafeStream toClone) - { - _common = toClone._common; - if (_common == null) - { - throw new ObjectDisposedException("toClone"); - } - } - - /// - /// Gets a value indicating if this stream supports reads. - /// - public override bool CanRead - { - get - { - lock (_common) - { - return Wrapped.CanRead; - } - } - } - - /// - /// Gets a value indicating if this stream supports seeking (always true). - /// - public override bool CanSeek - { - get { return true; } - } - - /// - /// Gets a value indicating if this stream supports writes (currently, always false). - /// - public override bool CanWrite - { - get - { - lock (_common) - { - return Wrapped.CanWrite; - } - } - } - - /// - /// Gets the parts of the stream that are stored. - /// - /// This may be an empty enumeration if all bytes are zero. - public override IEnumerable Extents - { - get - { - lock (_common) - { - return Wrapped.Extents; - } - } - } - - /// - /// Gets the length of the stream. - /// - public override long Length - { - get - { - lock (_common) - { - return Wrapped.Length; - } - } - } - - /// - /// Gets the current stream position - each 'view' has it's own Position. - /// - public override long Position - { - get { return _position; } - - set { _position = value; } - } - - private SparseStream Wrapped - { - get - { - SparseStream wrapped = _common.WrappedStream; - if (wrapped == null) - { - throw new ObjectDisposedException("ThreadSafeStream"); - } - - return wrapped; - } - } - - /// - /// Opens a new thread-safe view on the stream. - /// - /// The new view. - public SparseStream OpenView() - { - return new ThreadSafeStream(this); - } - - /// - /// Gets the parts of a stream that are stored, within a specified range. - /// - /// The offset of the first byte of interest. - /// The number of bytes of interest. - /// An enumeration of stream extents, indicating stored bytes. - public override IEnumerable GetExtentsInRange(long start, long count) - { - lock (_common) - { - return Wrapped.GetExtentsInRange(start, count); - } - } - - /// - /// Causes the stream to flush all changes. - /// - public override void Flush() - { - lock (_common) - { - Wrapped.Flush(); - } - } - - /// - /// Reads data from the stream. - /// - /// The buffer to fill. - /// The first byte in buffer to fill. - /// The requested number of bytes to read. - /// The actual number of bytes read. - public override int Read(byte[] buffer, int offset, int count) - { - lock (_common) - { - SparseStream wrapped = Wrapped; - wrapped.Position = _position; - int numRead = wrapped.Read(buffer, offset, count); - _position += numRead; - return numRead; - } - } - - /// - /// Changes the current stream position (each view has it's own Position). - /// - /// The relative location to move to. - /// The origin of the location. - /// The new location as an absolute position. - public override long Seek(long offset, SeekOrigin origin) - { - long effectiveOffset = offset; - if (origin == SeekOrigin.Current) - { - effectiveOffset += _position; - } - else if (origin == SeekOrigin.End) - { - effectiveOffset += Length; - } - - if (effectiveOffset < 0) - { - throw new IOException("Attempt to move before beginning of disk"); - } - _position = effectiveOffset; - return _position; - } - - /// - /// Sets the length of the stream (not supported). - /// - /// The new length. - public override void SetLength(long value) - { - throw new NotSupportedException(); - } - - /// - /// Writes data to the stream (not currently supported). - /// - /// The data to write. - /// The first byte to write. - /// The number of bytes to write. - public override void Write(byte[] buffer, int offset, int count) - { - lock (_common) - { - SparseStream wrapped = Wrapped; - - if (_position + count > wrapped.Length) - { - throw new IOException("Attempt to extend stream"); - } - - wrapped.Position = _position; - wrapped.Write(buffer, offset, count); - _position += count; - } - } - - /// - /// Disposes of this instance, invalidating any remaining views. - /// - /// true if disposing, lese false. - protected override void Dispose(bool disposing) - { - if (disposing) - { - if (_ownsCommon && _common != null) - { - lock (_common) - { - if (_common.WrappedStreamOwnership == Ownership.Dispose) - { - _common.WrappedStream.Dispose(); - } - - _common.Dispose(); - } - } - } - - _common = null; - } - - private sealed class CommonState : IDisposable - { - public SparseStream WrappedStream; - public Ownership WrappedStreamOwnership; - - #region IDisposable Members - - public void Dispose() - { - WrappedStream = null; - } - - #endregion - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Streams/Util/BitCounter.cs b/src/LibHac.Nand/DiscUtils.Streams/Util/BitCounter.cs deleted file mode 100644 index 1d4ae362..00000000 --- a/src/LibHac.Nand/DiscUtils.Streams/Util/BitCounter.cs +++ /dev/null @@ -1,80 +0,0 @@ -// -// Copyright (c) 2017, Bianco Veigel -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; - -namespace DiscUtils.Streams -{ - /// - /// Helper to count the number of bits set in a byte or byte[] - /// - public static class BitCounter - { - private static readonly byte[] _lookupTable; - - static BitCounter() - { - _lookupTable = new byte[256]; - for (int i = 0; i < 256; i++) - { - byte bitCount = 0; - var value = i; - while (value != 0) - { - bitCount++; - value &= (byte)(value - 1); - } - _lookupTable[i] = bitCount; - } - } - - /// - /// count the number of bits set in - /// - /// the number of bits set in - public static byte Count(byte value) - { - return _lookupTable[value]; - } - - /// - /// count the number of bits set in each entry of - /// - /// the to process - /// the values offset to start from - /// the number of bytes to count - /// - public static long Count(byte[] values, int offset, int count) - { - var end = offset + count; - if (end > values.Length) - throw new ArgumentOutOfRangeException(nameof(count), "can't count after end of values"); - var result = 0L; - for (int i = offset; i < end; i++) - { - var value = values[i]; - result += _lookupTable[value]; - } - return result; - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Streams/Util/EndianUtilities.cs b/src/LibHac.Nand/DiscUtils.Streams/Util/EndianUtilities.cs deleted file mode 100644 index 47454931..00000000 --- a/src/LibHac.Nand/DiscUtils.Streams/Util/EndianUtilities.cs +++ /dev/null @@ -1,306 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; - -namespace DiscUtils.Streams -{ - public static class EndianUtilities - { - #region Bit Twiddling - - public static void WriteBytesLittleEndian(ushort val, byte[] buffer, int offset) - { - buffer[offset] = (byte)(val & 0xFF); - buffer[offset + 1] = (byte)((val >> 8) & 0xFF); - } - - public static void WriteBytesLittleEndian(uint val, byte[] buffer, int offset) - { - buffer[offset] = (byte)(val & 0xFF); - buffer[offset + 1] = (byte)((val >> 8) & 0xFF); - buffer[offset + 2] = (byte)((val >> 16) & 0xFF); - buffer[offset + 3] = (byte)((val >> 24) & 0xFF); - } - - public static void WriteBytesLittleEndian(ulong val, byte[] buffer, int offset) - { - buffer[offset] = (byte)(val & 0xFF); - buffer[offset + 1] = (byte)((val >> 8) & 0xFF); - buffer[offset + 2] = (byte)((val >> 16) & 0xFF); - buffer[offset + 3] = (byte)((val >> 24) & 0xFF); - buffer[offset + 4] = (byte)((val >> 32) & 0xFF); - buffer[offset + 5] = (byte)((val >> 40) & 0xFF); - buffer[offset + 6] = (byte)((val >> 48) & 0xFF); - buffer[offset + 7] = (byte)((val >> 56) & 0xFF); - } - - public static void WriteBytesLittleEndian(short val, byte[] buffer, int offset) - { - WriteBytesLittleEndian((ushort)val, buffer, offset); - } - - public static void WriteBytesLittleEndian(int val, byte[] buffer, int offset) - { - WriteBytesLittleEndian((uint)val, buffer, offset); - } - - public static void WriteBytesLittleEndian(long val, byte[] buffer, int offset) - { - WriteBytesLittleEndian((ulong)val, buffer, offset); - } - - public static void WriteBytesLittleEndian(Guid val, byte[] buffer, int offset) - { - byte[] le = val.ToByteArray(); - Array.Copy(le, 0, buffer, offset, 16); - } - - public static void WriteBytesBigEndian(ushort val, byte[] buffer, int offset) - { - buffer[offset] = (byte)(val >> 8); - buffer[offset + 1] = (byte)(val & 0xFF); - } - - public static void WriteBytesBigEndian(uint val, byte[] buffer, int offset) - { - buffer[offset] = (byte)((val >> 24) & 0xFF); - buffer[offset + 1] = (byte)((val >> 16) & 0xFF); - buffer[offset + 2] = (byte)((val >> 8) & 0xFF); - buffer[offset + 3] = (byte)(val & 0xFF); - } - - public static void WriteBytesBigEndian(ulong val, byte[] buffer, int offset) - { - buffer[offset] = (byte)((val >> 56) & 0xFF); - buffer[offset + 1] = (byte)((val >> 48) & 0xFF); - buffer[offset + 2] = (byte)((val >> 40) & 0xFF); - buffer[offset + 3] = (byte)((val >> 32) & 0xFF); - buffer[offset + 4] = (byte)((val >> 24) & 0xFF); - buffer[offset + 5] = (byte)((val >> 16) & 0xFF); - buffer[offset + 6] = (byte)((val >> 8) & 0xFF); - buffer[offset + 7] = (byte)(val & 0xFF); - } - - public static void WriteBytesBigEndian(short val, byte[] buffer, int offset) - { - WriteBytesBigEndian((ushort)val, buffer, offset); - } - - public static void WriteBytesBigEndian(int val, byte[] buffer, int offset) - { - WriteBytesBigEndian((uint)val, buffer, offset); - } - - public static void WriteBytesBigEndian(long val, byte[] buffer, int offset) - { - WriteBytesBigEndian((ulong)val, buffer, offset); - } - - public static void WriteBytesBigEndian(Guid val, byte[] buffer, int offset) - { - byte[] le = val.ToByteArray(); - WriteBytesBigEndian(ToUInt32LittleEndian(le, 0), buffer, offset + 0); - WriteBytesBigEndian(ToUInt16LittleEndian(le, 4), buffer, offset + 4); - WriteBytesBigEndian(ToUInt16LittleEndian(le, 6), buffer, offset + 6); - Array.Copy(le, 8, buffer, offset + 8, 8); - } - - public static ushort ToUInt16LittleEndian(byte[] buffer, int offset) - { - return (ushort)(((buffer[offset + 1] << 8) & 0xFF00) | ((buffer[offset + 0] << 0) & 0x00FF)); - } - - public static uint ToUInt32LittleEndian(byte[] buffer, int offset) - { - return (uint)(((buffer[offset + 3] << 24) & 0xFF000000U) | ((buffer[offset + 2] << 16) & 0x00FF0000U) - | ((buffer[offset + 1] << 8) & 0x0000FF00U) | ((buffer[offset + 0] << 0) & 0x000000FFU)); - } - - public static ulong ToUInt64LittleEndian(byte[] buffer, int offset) - { - return ((ulong)ToUInt32LittleEndian(buffer, offset + 4) << 32) | ToUInt32LittleEndian(buffer, offset + 0); - } - - public static short ToInt16LittleEndian(byte[] buffer, int offset) - { - return (short)ToUInt16LittleEndian(buffer, offset); - } - - public static int ToInt32LittleEndian(byte[] buffer, int offset) - { - return (int)ToUInt32LittleEndian(buffer, offset); - } - - public static long ToInt64LittleEndian(byte[] buffer, int offset) - { - return (long)ToUInt64LittleEndian(buffer, offset); - } - - public static ushort ToUInt16BigEndian(byte[] buffer, int offset) - { - return (ushort)(((buffer[offset] << 8) & 0xFF00) | ((buffer[offset + 1] << 0) & 0x00FF)); - } - - public static uint ToUInt32BigEndian(byte[] buffer, int offset) - { - uint val = (uint)(((buffer[offset + 0] << 24) & 0xFF000000U) | ((buffer[offset + 1] << 16) & 0x00FF0000U) - | ((buffer[offset + 2] << 8) & 0x0000FF00U) | ((buffer[offset + 3] << 0) & 0x000000FFU)); - return val; - } - - public static ulong ToUInt64BigEndian(byte[] buffer, int offset) - { - return ((ulong)ToUInt32BigEndian(buffer, offset + 0) << 32) | ToUInt32BigEndian(buffer, offset + 4); - } - - public static short ToInt16BigEndian(byte[] buffer, int offset) - { - return (short)ToUInt16BigEndian(buffer, offset); - } - - public static int ToInt32BigEndian(byte[] buffer, int offset) - { - return (int)ToUInt32BigEndian(buffer, offset); - } - - public static long ToInt64BigEndian(byte[] buffer, int offset) - { - return (long)ToUInt64BigEndian(buffer, offset); - } - - public static Guid ToGuidLittleEndian(byte[] buffer, int offset) - { - byte[] temp = new byte[16]; - Array.Copy(buffer, offset, temp, 0, 16); - return new Guid(temp); - } - - public static Guid ToGuidBigEndian(byte[] buffer, int offset) - { - return new Guid( - ToUInt32BigEndian(buffer, offset + 0), - ToUInt16BigEndian(buffer, offset + 4), - ToUInt16BigEndian(buffer, offset + 6), - buffer[offset + 8], - buffer[offset + 9], - buffer[offset + 10], - buffer[offset + 11], - buffer[offset + 12], - buffer[offset + 13], - buffer[offset + 14], - buffer[offset + 15]); - } - - public static byte[] ToByteArray(byte[] buffer, int offset, int length) - { - byte[] result = new byte[length]; - Array.Copy(buffer, offset, result, 0, length); - return result; - } - - public static T ToStruct(byte[] buffer, int offset) - where T : IByteArraySerializable, new() - { - T result = new T(); - result.ReadFrom(buffer, offset); - return result; - } - - /// - /// Primitive conversion from Unicode to ASCII that preserves special characters. - /// - /// The string to convert. - /// The buffer to fill. - /// The start of the string in the buffer. - /// The number of characters to convert. - /// The built-in ASCIIEncoding converts characters of codepoint > 127 to ?, - /// this preserves those code points by removing the top 16 bits of each character. - public static void StringToBytes(string value, byte[] dest, int offset, int count) - { - char[] chars = value.ToCharArray(0, Math.Min(value.Length, count)); - - int i = 0; - while (i < chars.Length && i < count) - { - dest[i + offset] = (byte)chars[i]; - ++i; - } - - while (i < count) - { - dest[i + offset] = 0; - ++i; - } - } - - /// - /// Primitive conversion from ASCII to Unicode that preserves special characters. - /// - /// The data to convert. - /// The first byte to convert. - /// The number of bytes to convert. - /// The string. - /// The built-in ASCIIEncoding converts characters of codepoint > 127 to ?, - /// this preserves those code points. - public static string BytesToString(byte[] data, int offset, int count) - { - char[] result = new char[count]; - - for (int i = 0; i < count; ++i) - { - result[i] = (char)data[i + offset]; - } - - return new string(result); - } - - /// - /// Primitive conversion from ASCII to Unicode that stops at a null-terminator. - /// - /// The data to convert. - /// The first byte to convert. - /// The number of bytes to convert. - /// The string. - /// The built-in ASCIIEncoding converts characters of codepoint > 127 to ?, - /// this preserves those code points. - public static string BytesToZString(byte[] data, int offset, int count) - { - char[] result = new char[count]; - - for (int i = 0; i < count; ++i) - { - byte ch = data[i + offset]; - if (ch == 0) - { - return new string(result, 0, i); - } - - result[i] = (char)ch; - } - - return new string(result); - } - - #endregion - } -} diff --git a/src/LibHac.Nand/DiscUtils.Streams/Util/MathUtilities.cs b/src/LibHac.Nand/DiscUtils.Streams/Util/MathUtilities.cs deleted file mode 100644 index ef732105..00000000 --- a/src/LibHac.Nand/DiscUtils.Streams/Util/MathUtilities.cs +++ /dev/null @@ -1,137 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; - -namespace DiscUtils.Streams -{ - public static class MathUtilities - { - /// - /// Round up a value to a multiple of a unit size. - /// - /// The value to round up. - /// The unit (the returned value will be a multiple of this number). - /// The rounded-up value. - public static long RoundUp(long value, long unit) - { - return (value + (unit - 1)) / unit * unit; - } - - /// - /// Round up a value to a multiple of a unit size. - /// - /// The value to round up. - /// The unit (the returned value will be a multiple of this number). - /// The rounded-up value. - public static int RoundUp(int value, int unit) - { - return (value + (unit - 1)) / unit * unit; - } - - /// - /// Round down a value to a multiple of a unit size. - /// - /// The value to round down. - /// The unit (the returned value will be a multiple of this number). - /// The rounded-down value. - public static long RoundDown(long value, long unit) - { - return value / unit * unit; - } - - /// - /// Calculates the CEIL function. - /// - /// The value to divide. - /// The value to divide by. - /// The value of CEIL(numerator/denominator). - public static int Ceil(int numerator, int denominator) - { - return (numerator + (denominator - 1)) / denominator; - } - - /// - /// Calculates the CEIL function. - /// - /// The value to divide. - /// The value to divide by. - /// The value of CEIL(numerator/denominator). - public static uint Ceil(uint numerator, uint denominator) - { - return (numerator + (denominator - 1)) / denominator; - } - - /// - /// Calculates the CEIL function. - /// - /// The value to divide. - /// The value to divide by. - /// The value of CEIL(numerator/denominator). - public static long Ceil(long numerator, long denominator) - { - return (numerator + (denominator - 1)) / denominator; - } - - public static int Log2(uint val) - { - if (val == 0) - { - throw new ArgumentException("Cannot calculate log of Zero", nameof(val)); - } - - int result = 0; - while ((val & 1) != 1) - { - val >>= 1; - ++result; - } - - if (val == 1) - { - return result; - } - throw new ArgumentException("Input is not a power of Two", nameof(val)); - } - - public static int Log2(int val) - { - if (val == 0) - { - throw new ArgumentException("Cannot calculate log of Zero", nameof(val)); - } - - int result = 0; - while ((val & 1) != 1) - { - val >>= 1; - ++result; - } - - if (val == 1) - { - return result; - } - throw new ArgumentException("Input is not a power of Two", nameof(val)); - } - } -} diff --git a/src/LibHac.Nand/DiscUtils.Streams/Util/Numbers.cs b/src/LibHac.Nand/DiscUtils.Streams/Util/Numbers.cs deleted file mode 100644 index 764ec2f4..00000000 --- a/src/LibHac.Nand/DiscUtils.Streams/Util/Numbers.cs +++ /dev/null @@ -1,228 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; - -namespace DiscUtils.Streams -{ - internal static class Numbers - where T : struct, IComparable, IEquatable - { - public delegate bool ComparisonFn(T a, T b); - - public delegate T ConvertIntFn(int a); - - public delegate T ConvertLongFn(long a); - - public delegate T DualParamFn(T a, T b); - - public delegate T NoParamFn(); - - public static readonly T Zero = default(T); - public static readonly T One = GetOne(); - public static readonly DualParamFn Add = GetAdd(); - public static readonly DualParamFn Subtract = GetSubtract(); - public static readonly DualParamFn Multiply = GetMultiply(); - public static readonly DualParamFn Divide = GetDivide(); - public static readonly DualParamFn RoundUp = GetRoundUp(); - public static readonly DualParamFn RoundDown = GetRoundDown(); - public static readonly DualParamFn Ceil = GetCeil(); - public static readonly ConvertLongFn ConvertLong = GetConvertLong(); - public static readonly ConvertIntFn ConvertInt = GetConvertInt(); - - public static bool GreaterThan(T a, T b) - { - return a.CompareTo(b) > 0; - } - - public static bool GreaterThanOrEqual(T a, T b) - { - return a.CompareTo(b) >= 0; - } - - public static bool LessThan(T a, T b) - { - return a.CompareTo(b) < 0; - } - - public static bool LessThanOrEqual(T a, T b) - { - return a.CompareTo(b) <= 0; - } - - public static bool Equal(T a, T b) - { - return a.CompareTo(b) == 0; - } - - public static bool NotEqual(T a, T b) - { - return a.CompareTo(b) != 0; - } - - private static T GetOne() - { - if (typeof(T) == typeof(long)) - { - return ((NoParamFn)(object)new LongNoParamFn(() => { return 1; }))(); - } - if (typeof(T) == typeof(int)) - { - return ((NoParamFn)(object)new IntNoParamFn(() => { return 1; }))(); - } - throw new NotSupportedException(); - } - - private static ConvertLongFn GetConvertLong() - { - if (typeof(T) == typeof(long)) - { - return (ConvertLongFn)(object)new LongConvertLongFn(x => { return x; }); - } - if (typeof(T) == typeof(int)) - { - return (ConvertLongFn)(object)new IntConvertLongFn(x => { return (int)x; }); - } - throw new NotSupportedException(); - } - - private static ConvertIntFn GetConvertInt() - { - if (typeof(T) == typeof(long)) - { - return (ConvertIntFn)(object)new LongConvertIntFn(x => { return x; }); - } - if (typeof(T) == typeof(int)) - { - return (ConvertIntFn)(object)new IntConvertIntFn(x => { return x; }); - } - throw new NotSupportedException(); - } - - private static DualParamFn GetAdd() - { - if (typeof(T) == typeof(long)) - { - return (DualParamFn)(object)new LongDualParamFn((a, b) => { return a + b; }); - } - if (typeof(T) == typeof(int)) - { - return (DualParamFn)(object)new IntDualParamFn((a, b) => { return a + b; }); - } - throw new NotSupportedException(); - } - - private static DualParamFn GetSubtract() - { - if (typeof(T) == typeof(long)) - { - return (DualParamFn)(object)new LongDualParamFn((a, b) => { return a - b; }); - } - if (typeof(T) == typeof(int)) - { - return (DualParamFn)(object)new IntDualParamFn((a, b) => { return a - b; }); - } - throw new NotSupportedException(); - } - - private static DualParamFn GetMultiply() - { - if (typeof(T) == typeof(long)) - { - return (DualParamFn)(object)new LongDualParamFn((a, b) => { return a * b; }); - } - if (typeof(T) == typeof(int)) - { - return (DualParamFn)(object)new IntDualParamFn((a, b) => { return a * b; }); - } - throw new NotSupportedException(); - } - - private static DualParamFn GetDivide() - { - if (typeof(T) == typeof(long)) - { - return (DualParamFn)(object)new LongDualParamFn((a, b) => { return a / b; }); - } - if (typeof(T) == typeof(int)) - { - return (DualParamFn)(object)new IntDualParamFn((a, b) => { return a / b; }); - } - throw new NotSupportedException(); - } - - private static DualParamFn GetRoundUp() - { - if (typeof(T) == typeof(long)) - { - return (DualParamFn)(object)new LongDualParamFn((a, b) => { return (a + b - 1) / b * b; }); - } - if (typeof(T) == typeof(int)) - { - return (DualParamFn)(object)new IntDualParamFn((a, b) => { return (a + b - 1) / b * b; }); - } - throw new NotSupportedException(); - } - - private static DualParamFn GetRoundDown() - { - if (typeof(T) == typeof(long)) - { - return (DualParamFn)(object)new LongDualParamFn((a, b) => { return a / b * b; }); - } - if (typeof(T) == typeof(int)) - { - return (DualParamFn)(object)new IntDualParamFn((a, b) => { return a / b * b; }); - } - throw new NotSupportedException(); - } - - private static DualParamFn GetCeil() - { - if (typeof(T) == typeof(long)) - { - return (DualParamFn)(object)new LongDualParamFn((a, b) => { return (a + b - 1) / b; }); - } - if (typeof(T) == typeof(int)) - { - return (DualParamFn)(object)new IntDualParamFn((a, b) => { return (a + b - 1) / b; }); - } - throw new NotSupportedException(); - } - - private delegate long LongNoParamFn(); - - private delegate long LongDualParamFn(long a, long b); - - private delegate long LongConvertLongFn(long x); - - private delegate long LongConvertIntFn(int x); - - private delegate int IntNoParamFn(); - - private delegate int IntDualParamFn(int a, int b); - - private delegate int IntConvertLongFn(long x); - - private delegate int IntConvertIntFn(int x); - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Streams/Util/Ownership.cs b/src/LibHac.Nand/DiscUtils.Streams/Util/Ownership.cs deleted file mode 100644 index 856e50ae..00000000 --- a/src/LibHac.Nand/DiscUtils.Streams/Util/Ownership.cs +++ /dev/null @@ -1,40 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -namespace DiscUtils.Streams -{ - /// - /// Enumeration used to indicate transfer of disposable objects. - /// - public enum Ownership - { - /// - /// Indicates there is no transfer of ownership. - /// - None, - - /// - /// Indicates ownership of the stream is transfered, the owner should dispose of the stream when appropriate. - /// - Dispose - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Streams/Util/Range.cs b/src/LibHac.Nand/DiscUtils.Streams/Util/Range.cs deleted file mode 100644 index a892650b..00000000 --- a/src/LibHac.Nand/DiscUtils.Streams/Util/Range.cs +++ /dev/null @@ -1,131 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; - -namespace DiscUtils.Streams -{ - /// - /// Represents a range of values. - /// - /// The type of the offset element. - /// The type of the size element. - public class Range : IEquatable> - where TOffset : IEquatable - where TCount : IEquatable - { - /// - /// Initializes a new instance of the Range class. - /// - /// The offset (i.e. start) of the range. - /// The size of the range. - public Range(TOffset offset, TCount count) - { - Offset = offset; - Count = count; - } - - /// - /// Gets the size of the range. - /// - public TCount Count { get; } - - /// - /// Gets the offset (i.e. start) of the range. - /// - public TOffset Offset { get; } - - #region IEquatable> Members - - /// - /// Compares this range to another. - /// - /// The range to compare. - /// true if the ranges are equivalent, else false. - public bool Equals(Range other) - { - if (other == null) - { - return false; - } - - return Offset.Equals(other.Offset) && Count.Equals(other.Count); - } - - #endregion - - /// - /// Merges sets of ranges into chunks. - /// - /// The ranges to merge. - /// The size of each chunk. - /// Ranges combined into larger chunks. - /// The type of the offset and count in the ranges. - public static IEnumerable> Chunked(IEnumerable> ranges, T chunkSize) - where T : struct, IEquatable, IComparable - { - T? chunkStart = Numbers.Zero; - T chunkLength = Numbers.Zero; - - foreach (Range range in ranges) - { - if (Numbers.NotEqual(range.Count, Numbers.Zero)) - { - T rangeStart = Numbers.RoundDown(range.Offset, chunkSize); - T rangeNext = Numbers.RoundUp(Numbers.Add(range.Offset, range.Count), chunkSize); - - if (chunkStart.HasValue && - Numbers.GreaterThan(rangeStart, Numbers.Add(chunkStart.Value, chunkLength))) - { - // This extent is non-contiguous (in terms of blocks), so write out the last range and start new - yield return new Range(chunkStart.Value, chunkLength); - chunkStart = rangeStart; - } - else if (!chunkStart.HasValue) - { - // First extent, so start first range - chunkStart = rangeStart; - } - - // Set the length of the current range, based on the end of this extent - chunkLength = Numbers.Subtract(rangeNext, chunkStart.Value); - } - } - - // Final range (if any ranges at all) hasn't been returned yet, so do that now - if (chunkStart.HasValue) - { - yield return new Range(chunkStart.Value, chunkLength); - } - } - - /// - /// Returns a string representation of the extent as [start:+length]. - /// - /// The string representation. - public override string ToString() - { - return "[" + Offset + ":+" + Count + "]"; - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Streams/Util/Sizes.cs b/src/LibHac.Nand/DiscUtils.Streams/Util/Sizes.cs deleted file mode 100644 index 847239af..00000000 --- a/src/LibHac.Nand/DiscUtils.Streams/Util/Sizes.cs +++ /dev/null @@ -1,33 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -namespace DiscUtils.Streams -{ - public static class Sizes - { - public const long OneKiB = 1024; - public const long OneMiB = 1024 * OneKiB; - public const long OneGiB = 1024 * OneMiB; - - public const int Sector = 512; - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Streams/Util/StreamUtilities.cs b/src/LibHac.Nand/DiscUtils.Streams/Util/StreamUtilities.cs deleted file mode 100644 index f9220128..00000000 --- a/src/LibHac.Nand/DiscUtils.Streams/Util/StreamUtilities.cs +++ /dev/null @@ -1,288 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.IO; - -namespace DiscUtils.Streams -{ - public static class StreamUtilities - { - /// - /// Validates standard buffer, offset, count parameters to a method. - /// - /// The byte array to read from / write to. - /// The starting offset in buffer. - /// The number of bytes to read / write. - public static void AssertBufferParameters(byte[] buffer, int offset, int count) - { - if (buffer == null) - { - throw new ArgumentNullException(nameof(buffer)); - } - - if (offset < 0) - { - throw new ArgumentOutOfRangeException(nameof(offset), offset, "Offset is negative"); - } - - if (count < 0) - { - throw new ArgumentOutOfRangeException(nameof(count), count, "Count is negative"); - } - - if (buffer.Length < offset + count) - { - throw new ArgumentException("buffer is too small", nameof(buffer)); - } - } - - #region Stream Manipulation - - /// - /// Read bytes until buffer filled or throw EndOfStreamException. - /// - /// The stream to read. - /// The buffer to populate. - /// Offset in the buffer to start. - /// The number of bytes to read. - public static void ReadExact(Stream stream, byte[] buffer, int offset, int count) - { - int originalCount = count; - - while (count > 0) - { - int numRead = stream.Read(buffer, offset, count); - - if (numRead == 0) - { - throw new EndOfStreamException("Unable to complete read of " + originalCount + " bytes"); - } - - offset += numRead; - count -= numRead; - } - } - - /// - /// Read bytes until buffer filled or throw EndOfStreamException. - /// - /// The stream to read. - /// The number of bytes to read. - /// The data read from the stream. - public static byte[] ReadExact(Stream stream, int count) - { - byte[] buffer = new byte[count]; - - ReadExact(stream, buffer, 0, count); - - return buffer; - } - - /// - /// Read bytes until buffer filled or throw EndOfStreamException. - /// - /// The stream to read. - /// The position in buffer to read from. - /// The buffer to populate. - /// Offset in the buffer to start. - /// The number of bytes to read. - public static void ReadExact(IBuffer buffer, long pos, byte[] data, int offset, int count) - { - int originalCount = count; - - while (count > 0) - { - int numRead = buffer.Read(pos, data, offset, count); - - if (numRead == 0) - { - throw new EndOfStreamException("Unable to complete read of " + originalCount + " bytes"); - } - - pos += numRead; - offset += numRead; - count -= numRead; - } - } - - /// - /// Read bytes until buffer filled or throw EndOfStreamException. - /// - /// The buffer to read. - /// The position in buffer to read from. - /// The number of bytes to read. - /// The data read from the stream. - public static byte[] ReadExact(IBuffer buffer, long pos, int count) - { - byte[] result = new byte[count]; - - ReadExact(buffer, pos, result, 0, count); - - return result; - } - - /// - /// Read bytes until buffer filled or EOF. - /// - /// The stream to read. - /// The buffer to populate. - /// Offset in the buffer to start. - /// The number of bytes to read. - /// The number of bytes actually read. - public static int ReadMaximum(Stream stream, byte[] buffer, int offset, int count) - { - int totalRead = 0; - - while (count > 0) - { - int numRead = stream.Read(buffer, offset, count); - - if (numRead == 0) - { - return totalRead; - } - - offset += numRead; - count -= numRead; - totalRead += numRead; - } - - return totalRead; - } - - /// - /// Read bytes until buffer filled or EOF. - /// - /// The stream to read. - /// The position in buffer to read from. - /// The buffer to populate. - /// Offset in the buffer to start. - /// The number of bytes to read. - /// The number of bytes actually read. - public static int ReadMaximum(IBuffer buffer, long pos, byte[] data, int offset, int count) - { - int totalRead = 0; - - while (count > 0) - { - int numRead = buffer.Read(pos, data, offset, count); - - if (numRead == 0) - { - return totalRead; - } - - pos += numRead; - offset += numRead; - count -= numRead; - totalRead += numRead; - } - - return totalRead; - } - - /// - /// Read bytes until buffer filled or throw EndOfStreamException. - /// - /// The buffer to read. - /// The data read from the stream. - public static byte[] ReadAll(IBuffer buffer) - { - return ReadExact(buffer, 0, (int)buffer.Capacity); - } - - /// - /// Reads a disk sector (512 bytes). - /// - /// The stream to read. - /// The sector data as a byte array. - public static byte[] ReadSector(Stream stream) - { - return ReadExact(stream, Sizes.Sector); - } - - /// - /// Reads a structure from a stream. - /// - /// The type of the structure. - /// The stream to read. - /// The structure. - public static T ReadStruct(Stream stream) - where T : IByteArraySerializable, new() - { - T result = new T(); - byte[] buffer = ReadExact(stream, result.Size); - result.ReadFrom(buffer, 0); - return result; - } - - /// - /// Reads a structure from a stream. - /// - /// The type of the structure. - /// The stream to read. - /// The number of bytes to read. - /// The structure. - public static T ReadStruct(Stream stream, int length) - where T : IByteArraySerializable, new() - { - T result = new T(); - byte[] buffer = ReadExact(stream, length); - result.ReadFrom(buffer, 0); - return result; - } - - /// - /// Writes a structure to a stream. - /// - /// The type of the structure. - /// The stream to write to. - /// The structure to write. - public static void WriteStruct(Stream stream, T obj) - where T : IByteArraySerializable - { - byte[] buffer = new byte[obj.Size]; - obj.WriteTo(buffer, 0); - stream.Write(buffer, 0, buffer.Length); - } - - /// - /// Copies the contents of one stream to another. - /// - /// The stream to copy from. - /// The destination stream. - /// Copying starts at the current stream positions. - public static void PumpStreams(Stream source, Stream dest) - { - byte[] buffer = new byte[8192]; - int numRead; - - while ((numRead = source.Read(buffer, 0, buffer.Length)) > 0) - { - dest.Write(buffer, 0, numRead); - } - } - - #endregion - } -} diff --git a/src/LibHac.Nand/DiscUtils.Streams/WrappingMappedStream.cs b/src/LibHac.Nand/DiscUtils.Streams/WrappingMappedStream.cs deleted file mode 100644 index 6a1d6558..00000000 --- a/src/LibHac.Nand/DiscUtils.Streams/WrappingMappedStream.cs +++ /dev/null @@ -1,165 +0,0 @@ -// -// Copyright (c) 2008-2012, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System.Collections.Generic; -using System.IO; - -namespace DiscUtils.Streams -{ - /// - /// Base class for streams that wrap another stream. - /// - /// The type of stream to wrap. - /// - /// Provides the default implementation of methods & properties, so - /// wrapping streams need only override the methods they need to intercept. - /// - public class WrappingMappedStream : MappedStream - where T : Stream - { - private readonly List _extents; - private readonly Ownership _ownership; - - public WrappingMappedStream(T toWrap, Ownership ownership, IEnumerable extents) - { - WrappedStream = toWrap; - _ownership = ownership; - if (extents != null) - { - _extents = new List(extents); - } - } - - public override bool CanRead - { - get { return WrappedStream.CanRead; } - } - - public override bool CanSeek - { - get { return WrappedStream.CanSeek; } - } - - public override bool CanWrite - { - get { return WrappedStream.CanWrite; } - } - - public override IEnumerable Extents - { - get - { - if (_extents != null) - { - return _extents; - } - SparseStream sparse = WrappedStream as SparseStream; - if (sparse != null) - { - return sparse.Extents; - } - return new[] { new StreamExtent(0, WrappedStream.Length) }; - } - } - - public override long Length - { - get { return WrappedStream.Length; } - } - - public override long Position - { - get { return WrappedStream.Position; } - set { WrappedStream.Position = value; } - } - - protected T WrappedStream { get; private set; } - - public override IEnumerable MapContent(long start, long length) - { - MappedStream mapped = WrappedStream as MappedStream; - if (mapped != null) - { - return mapped.MapContent(start, length); - } - return new[] { new StreamExtent(start, length) }; - } - - public override void Flush() - { - WrappedStream.Flush(); - } - - public override int Read(byte[] buffer, int offset, int count) - { - return WrappedStream.Read(buffer, offset, count); - } - - public override long Seek(long offset, SeekOrigin origin) - { - return WrappedStream.Seek(offset, origin); - } - - public override void SetLength(long value) - { - WrappedStream.SetLength(value); - } - - public override void Clear(int count) - { - SparseStream sparse = WrappedStream as SparseStream; - if (sparse != null) - { - sparse.Clear(count); - } - else - { - base.Clear(count); - } - } - - public override void Write(byte[] buffer, int offset, int count) - { - WrappedStream.Write(buffer, offset, count); - } - - protected override void Dispose(bool disposing) - { - try - { - if (disposing) - { - if (WrappedStream != null && _ownership == Ownership.Dispose) - { - WrappedStream.Dispose(); - } - - WrappedStream = null; - } - } - finally - { - base.Dispose(disposing); - } - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Streams/WrappingStream.cs b/src/LibHac.Nand/DiscUtils.Streams/WrappingStream.cs deleted file mode 100644 index 0c803786..00000000 --- a/src/LibHac.Nand/DiscUtils.Streams/WrappingStream.cs +++ /dev/null @@ -1,127 +0,0 @@ -// -// Copyright (c) 2008-2012, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System.Collections.Generic; -using System.IO; - -namespace DiscUtils.Streams -{ - /// - /// Base class for streams that wrap another stream. - /// - /// - /// Provides the default implementation of methods & properties, so - /// wrapping streams need only override the methods they need to intercept. - /// - public class WrappingStream : SparseStream - { - private readonly Ownership _ownership; - private SparseStream _wrapped; - - public WrappingStream(SparseStream toWrap, Ownership ownership) - { - _wrapped = toWrap; - _ownership = ownership; - } - - public override bool CanRead - { - get { return _wrapped.CanRead; } - } - - public override bool CanSeek - { - get { return _wrapped.CanSeek; } - } - - public override bool CanWrite - { - get { return _wrapped.CanWrite; } - } - - public override IEnumerable Extents - { - get { return _wrapped.Extents; } - } - - public override long Length - { - get { return _wrapped.Length; } - } - - public override long Position - { - get { return _wrapped.Position; } - set { _wrapped.Position = value; } - } - - public override void Flush() - { - _wrapped.Flush(); - } - - public override int Read(byte[] buffer, int offset, int count) - { - return _wrapped.Read(buffer, offset, count); - } - - public override long Seek(long offset, SeekOrigin origin) - { - return _wrapped.Seek(offset, origin); - } - - public override void SetLength(long value) - { - _wrapped.SetLength(value); - } - - public override void Clear(int count) - { - _wrapped.Clear(count); - } - - public override void Write(byte[] buffer, int offset, int count) - { - _wrapped.Write(buffer, offset, count); - } - - protected override void Dispose(bool disposing) - { - try - { - if (disposing) - { - if (_wrapped != null && _ownership == Ownership.Dispose) - { - _wrapped.Dispose(); - } - - _wrapped = null; - } - } - finally - { - base.Dispose(disposing); - } - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/DiscUtils.Streams/ZeroStream.cs b/src/LibHac.Nand/DiscUtils.Streams/ZeroStream.cs deleted file mode 100644 index 8e60d0ca..00000000 --- a/src/LibHac.Nand/DiscUtils.Streams/ZeroStream.cs +++ /dev/null @@ -1,144 +0,0 @@ -// -// Copyright (c) 2008-2011, Kenneth Bell -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; -using System.IO; - -namespace DiscUtils.Streams -{ - /// - /// A stream that returns Zero's. - /// - public class ZeroStream : MappedStream - { - private bool _atEof; - private readonly long _length; - private long _position; - - public ZeroStream(long length) - { - _length = length; - } - - public override bool CanRead - { - get { return true; } - } - - public override bool CanSeek - { - get { return true; } - } - - public override bool CanWrite - { - get { return false; } - } - - public override IEnumerable Extents - { - // The stream is entirely sparse - get { return new List(0); } - } - - public override long Length - { - get { return _length; } - } - - public override long Position - { - get { return _position; } - - set - { - _position = value; - _atEof = false; - } - } - - public override IEnumerable MapContent(long start, long length) - { - return new StreamExtent[0]; - } - - public override void Flush() {} - - public override int Read(byte[] buffer, int offset, int count) - { - if (_position > _length) - { - _atEof = true; - throw new IOException("Attempt to read beyond end of stream"); - } - - if (_position == _length) - { - if (_atEof) - { - throw new IOException("Attempt to read beyond end of stream"); - } - _atEof = true; - return 0; - } - - int numToClear = (int)Math.Min(count, _length - _position); - Array.Clear(buffer, offset, numToClear); - _position += numToClear; - - return numToClear; - } - - public override long Seek(long offset, SeekOrigin origin) - { - long effectiveOffset = offset; - if (origin == SeekOrigin.Current) - { - effectiveOffset += _position; - } - else if (origin == SeekOrigin.End) - { - effectiveOffset += _length; - } - - _atEof = false; - - if (effectiveOffset < 0) - { - throw new IOException("Attempt to move before beginning of stream"); - } - _position = effectiveOffset; - return _position; - } - - public override void SetLength(long value) - { - throw new NotSupportedException(); - } - - public override void Write(byte[] buffer, int offset, int count) - { - throw new NotSupportedException(); - } - } -} \ No newline at end of file diff --git a/src/LibHac.Nand/FatFileSystemDirectory.cs b/src/LibHac.Nand/FatFileSystemDirectory.cs deleted file mode 100644 index add712c0..00000000 --- a/src/LibHac.Nand/FatFileSystemDirectory.cs +++ /dev/null @@ -1,69 +0,0 @@ -using System.Collections.Generic; -using System.IO; -using System.Runtime.CompilerServices; -using DiscUtils; -using LibHac.Fs; - -using DirectoryEntry = LibHac.Fs.DirectoryEntry; -using IFileSystem = LibHac.Fs.IFileSystem; - -namespace LibHac.Nand -{ - public class FatFileSystemDirectory : IDirectory - { - public IFileSystem ParentFileSystem { get; } - public string FullPath { get; } - public OpenDirectoryMode Mode { get; } - private DiscDirectoryInfo DirInfo { get; } - - public FatFileSystemDirectory(FatFileSystemProvider fs, string path, OpenDirectoryMode mode) - { - ParentFileSystem = fs; - FullPath = path; - Mode = mode; - - path = FatFileSystemProvider.ToDiscUtilsPath(PathTools.Normalize(path)); - - DirInfo = fs.Fs.GetDirectoryInfo(path); - } - - public IEnumerable Read() - { - foreach (DiscFileSystemInfo entry in DirInfo.GetFileSystemInfos()) - { - bool isDir = (entry.Attributes & FileAttributes.Directory) != 0; - - if (!CanReturnEntry(isDir, Mode)) continue; - - DirectoryEntryType type = isDir ? DirectoryEntryType.Directory : DirectoryEntryType.File; - long length = isDir ? 0 : entry.FileSystem.GetFileLength(entry.FullName); - - yield return new DirectoryEntry(entry.Name, PathTools.Combine(FullPath, entry.Name), type, length) - { - Attributes = entry.Attributes.ToNxAttributes() - }; - } - } - - public int GetEntryCount() - { - int count = 0; - - foreach (DiscFileSystemInfo entry in DirInfo.GetFileSystemInfos()) - { - bool isDir = (entry.Attributes & FileAttributes.Directory) != 0; - - if (CanReturnEntry(isDir, Mode)) count++; - } - - return count; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static bool CanReturnEntry(bool isDir, OpenDirectoryMode mode) - { - return isDir && (mode & OpenDirectoryMode.Directories) != 0 || - !isDir && (mode & OpenDirectoryMode.Files) != 0; - } - } -} diff --git a/src/LibHac.Nand/FatFileSystemProvider.cs b/src/LibHac.Nand/FatFileSystemProvider.cs deleted file mode 100644 index 81383955..00000000 --- a/src/LibHac.Nand/FatFileSystemProvider.cs +++ /dev/null @@ -1,144 +0,0 @@ -using System; -using System.IO; -using DiscUtils.Fat; -using LibHac.Fs; - -namespace LibHac.Nand -{ - public class FatFileSystemProvider : IAttributeFileSystem - { - public FatFileSystem Fs { get; } - - public FatFileSystemProvider(FatFileSystem fileSystem) - { - Fs = fileSystem; - } - - public void DeleteDirectory(string path) - { - path = ToDiscUtilsPath(PathTools.Normalize(path)); - Fs.DeleteDirectory(path); - } - - public void DeleteDirectoryRecursively(string path) - { - path = ToDiscUtilsPath(PathTools.Normalize(path)); - - Fs.DeleteDirectory(path, true); - } - - public void CleanDirectoryRecursively(string path) - { - path = ToDiscUtilsPath(PathTools.Normalize(path)); - - foreach (string file in Fs.GetFiles(path)) - { - Fs.DeleteFile(file); - } - - foreach (string file in Fs.GetDirectories(path)) - { - Fs.DeleteDirectory(file, true); - } - } - - public void DeleteFile(string path) - { - path = ToDiscUtilsPath(PathTools.Normalize(path)); - Fs.DeleteFile(path); - } - - public IDirectory OpenDirectory(string path, OpenDirectoryMode mode) - { - path = PathTools.Normalize(path); - - return new FatFileSystemDirectory(this, path, mode); - } - - public IFile OpenFile(string path, OpenMode mode) - { - path = ToDiscUtilsPath(PathTools.Normalize(path)); - - Stream stream = Fs.OpenFile(path, FileMode.Open, GetFileAccess(mode)); - return stream.AsIFile(mode); - } - - public DirectoryEntryType GetEntryType(string path) - { - path = PathTools.Normalize(path); - string discUtilsPath = ToDiscUtilsPath(path); - - if (Fs.FileExists(discUtilsPath)) return DirectoryEntryType.File; - if (Fs.DirectoryExists(discUtilsPath)) return DirectoryEntryType.Directory; - - return DirectoryEntryType.NotFound; - } - - public NxFileAttributes GetFileAttributes(string path) - { - path = ToDiscUtilsPath(PathTools.Normalize(path)); - - return Fs.GetAttributes(path).ToNxAttributes(); - } - - public void SetFileAttributes(string path, NxFileAttributes attributes) - { - path = ToDiscUtilsPath(PathTools.Normalize(path)); - - FileAttributes attributesOld = File.GetAttributes(path); - FileAttributes attributesNew = attributesOld.ApplyNxAttributes(attributes); - - Fs.SetAttributes(path, attributesNew); - } - - public long GetFileSize(string path) - { - path = ToDiscUtilsPath(PathTools.Normalize(path)); - - return Fs.GetFileInfo(path).Length; - } - - public FileTimeStampRaw GetFileTimeStampRaw(string path) - { - path = PathTools.Normalize(path); - string localPath = ToDiscUtilsPath(path); - - FileTimeStampRaw timeStamp = default; - - timeStamp.Created = new DateTimeOffset(Fs.GetCreationTime(localPath)).ToUnixTimeSeconds(); - timeStamp.Accessed = new DateTimeOffset(Fs.GetLastAccessTime(localPath)).ToUnixTimeSeconds(); - timeStamp.Modified = new DateTimeOffset(Fs.GetLastWriteTime(localPath)).ToUnixTimeSeconds(); - - 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(); - public void CreateFile(string path, long size, CreateFileOptions options) => throw new NotSupportedException(); - 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, ReadOnlySpan inBuffer, string path, QueryId queryId) => throw new NotSupportedException(); - - private static FileAccess GetFileAccess(OpenMode mode) - { - // FileAccess and OpenMode have the same flags - return (FileAccess)(mode & OpenMode.ReadWrite); - } - - internal static string ToDiscUtilsPath(string path) - { - return path.Replace("/", @"\"); - } - } -} diff --git a/src/LibHac.Nand/LibHac.Nand.csproj b/src/LibHac.Nand/LibHac.Nand.csproj deleted file mode 100644 index 80b4ddab..00000000 --- a/src/LibHac.Nand/LibHac.Nand.csproj +++ /dev/null @@ -1,12 +0,0 @@ - - - - netcoreapp2.1;net46 - 7.3 - - - - - - - diff --git a/src/LibHac.Nand/Nand.cs b/src/LibHac.Nand/Nand.cs deleted file mode 100644 index 6366934b..00000000 --- a/src/LibHac.Nand/Nand.cs +++ /dev/null @@ -1,92 +0,0 @@ -using System.IO; -using System.Linq; -using DiscUtils; -using DiscUtils.Fat; -using DiscUtils.Partitions; -using DiscUtils.Streams; -using LibHac.Fs; - -namespace LibHac.Nand -{ - public class Nand - { - private GuidPartitionInfo ProdInfo { get; } - private GuidPartitionInfo ProdInfoF { get; } - private GuidPartitionInfo[] Package2 { get; } - private GuidPartitionInfo Safe { get; } - private GuidPartitionInfo System { get; } - private GuidPartitionInfo User { get; } - public Keyset Keyset { get; } - - public FileAccess Access { get; } - - public Nand(Stream stream, Keyset keyset, FileAccess access = FileAccess.Read) - { - var disc = new GuidPartitionTable(stream, Geometry.Null); - GuidPartitionInfo[] partitions = disc.Partitions.Select(x => (GuidPartitionInfo)x).ToArray(); - ProdInfo = partitions.FirstOrDefault(x => x.Name == "PRODINFO"); - ProdInfoF = partitions.FirstOrDefault(x => x.Name == "PRODINFOF"); - Package2 = new[] - { - partitions.FirstOrDefault(x => x.Name == "BCPKG2-1-Normal-Main"), - partitions.FirstOrDefault(x => x.Name == "BCPKG2-2-Normal-Sub"), - partitions.FirstOrDefault(x => x.Name == "BCPKG2-3-SafeMode-Main"), - partitions.FirstOrDefault(x => x.Name == "BCPKG2-4-SafeMode-Sub"), - partitions.FirstOrDefault(x => x.Name == "BCPKG2-5-Repair-Main"), - partitions.FirstOrDefault(x => x.Name == "BCPKG2-6-Repair-Sub") - }; - Safe = partitions.FirstOrDefault(x => x.Name == "SAFE"); - System = partitions.FirstOrDefault(x => x.Name == "SYSTEM"); - User = partitions.FirstOrDefault(x => x.Name == "USER"); - Keyset = keyset; - Access = access; - } - - public Stream OpenProdInfo() - { - IStorage encStorage = ProdInfo.Open().AsStorage(); - var decStorage = new CachedStorage(new Aes128XtsStorage(encStorage, Keyset.BisKeys[0], 0x4000, true), 0x4000, 4, true); - return decStorage.AsStream(Access); - } - - public FatFileSystemProvider OpenProdInfoF() - { - IStorage encStorage = ProdInfoF.Open().AsStorage(); - var decStorage = new CachedStorage(new Aes128XtsStorage(encStorage, Keyset.BisKeys[0], 0x4000, true), 0x4000, 4, true); - var fat = new FatFileSystem(decStorage.AsStream(Access), Ownership.None); - return new FatFileSystemProvider(fat); - } - - public IStorage OpenPackage2(int index) - { - IStorage storage = Package2[index].Open().AsStorage(); - if (Access == FileAccess.Read) - return storage.AsReadOnly(); - return storage; - } - - public FatFileSystemProvider OpenSafePartition() - { - IStorage encStorage = Safe.Open().AsStorage(); - var decStorage = new CachedStorage(new Aes128XtsStorage(encStorage, Keyset.BisKeys[1], 0x4000, true), 0x4000, 4, true); - var fat = new FatFileSystem(decStorage.AsStream(Access), Ownership.None); - return new FatFileSystemProvider(fat); - } - - public FatFileSystemProvider OpenSystemPartition() - { - IStorage encStorage = System.Open().AsStorage(); - var decStorage = new CachedStorage(new Aes128XtsStorage(encStorage, Keyset.BisKeys[2], 0x4000, true), 0x4000, 4, true); - var fat = new FatFileSystem(decStorage.AsStream(Access), Ownership.None); - return new FatFileSystemProvider(fat); - } - - public FatFileSystemProvider OpenUserPartition() - { - IStorage encStorage = User.Open().AsStorage(); - var decStorage = new CachedStorage(new Aes128XtsStorage(encStorage, Keyset.BisKeys[3], 0x4000, true), 0x4000, 4, true); - var fat = new FatFileSystem(decStorage.AsStream(Access), Ownership.None); - return new FatFileSystemProvider(fat); - } - } -} \ No newline at end of file diff --git a/src/NandReader/NandReader.csproj b/src/NandReader/NandReader.csproj deleted file mode 100644 index 952d8def..00000000 --- a/src/NandReader/NandReader.csproj +++ /dev/null @@ -1,12 +0,0 @@ - - - - Exe - netcoreapp2.1;net46 - - - - - - - diff --git a/src/NandReader/Program.cs b/src/NandReader/Program.cs deleted file mode 100644 index ec6cbdf1..00000000 --- a/src/NandReader/Program.cs +++ /dev/null @@ -1,152 +0,0 @@ -// ReSharper disable UnusedVariable UnusedMember.Local -using System; -using System.Collections.Generic; -using System.IO; -using LibHac; -using LibHac.Fs; -using LibHac.Fs.Save; -using LibHac.Nand; - -namespace NandReader -{ - public static class Program - { - public static void Main(string[] args) - { - if (args.Length != 1) - { - Console.WriteLine("Usage: NandReader raw_nand_dump_file"); - return; - } - ReadSwitchFs(args[0]); - } - - private static void GetTitleKeys(string nandFile) - { - using (var logger = new ProgressBar()) - using (var stream = new FileStream(nandFile, FileMode.Open, FileAccess.Read)) - { - Keyset keyset = OpenKeyset(); - var nand = new Nand(stream, keyset); - Stream prodinfo = nand.OpenProdInfo(); - var calibration = new Calibration(prodinfo); - - keyset.EticketExtKeyRsa = Crypto.DecryptRsaKey(calibration.EticketExtKeyRsa, keyset.EticketRsaKek); - Ticket[] tickets = GetTickets(keyset, nand, logger); - - foreach (Ticket ticket in tickets) - { - byte[] key = ticket.GetTitleKey(keyset); - logger.LogMessage($"{ticket.RightsId.ToHexString()},{key.ToHexString()}"); - } - } - } - - private static void ReadSwitchFs(string nandFile) - { - using (var logger = new ProgressBar()) - using (var stream = new FileStream(nandFile, FileMode.Open, FileAccess.Read)) - { - Keyset keyset = OpenKeyset(); - var nand = new Nand(stream, keyset); - FatFileSystemProvider user = nand.OpenSystemPartition(); - SwitchFs sdfs = SwitchFs.OpenNandPartition(keyset, user); - } - } - - private static void ReadCalibration(string nandFile) - { - using (var logger = new ProgressBar()) - using (var stream = new FileStream(nandFile, FileMode.Open, FileAccess.Read)) - { - Keyset keyset = OpenKeyset(); - var nand = new Nand(stream, keyset); - Stream prodinfo = nand.OpenProdInfo(); - var calibration = new Calibration(prodinfo); - } - } - - private static void DumpTickets(string nandFile) - { - using (var logger = new ProgressBar()) - using (var stream = new FileStream(nandFile, FileMode.Open, FileAccess.Read)) - { - Keyset keyset = OpenKeyset(); - var nand = new Nand(stream, keyset); - Ticket[] tickets = GetTickets(keyset, nand, logger); - - Directory.CreateDirectory("tickets"); - foreach (Ticket ticket in tickets) - { - string filename = Path.Combine("tickets", $"{ticket.RightsId.ToHexString()}.tik"); - File.WriteAllBytes(filename, ticket.File); - } - } - } - - private static Ticket[] GetTickets(Keyset keyset, Nand nand, IProgressReport logger = null) - { - var tickets = new List(); - FatFileSystemProvider system = nand.OpenSystemPartition(); - - IFile saveE1File = system.OpenFile("/save/80000000000000E1", OpenMode.Read); - tickets.AddRange(ReadTickets(keyset, saveE1File.AsStream())); - - IFile saveE2 = system.OpenFile("/save/80000000000000E2", OpenMode.Read); - tickets.AddRange(ReadTickets(keyset, saveE2.AsStream())); - - logger?.LogMessage($"Found {tickets.Count} tickets"); - - return tickets.ToArray(); - } - - private static List ReadTickets(Keyset keyset, Stream savefile) - { - var tickets = new List(); - var save = new SaveDataFileSystem(keyset, savefile.AsStorage(), IntegrityCheckLevel.None, true); - var ticketList = new BinaryReader(save.OpenFile("/ticket_list.bin", OpenMode.Read).AsStream()); - var ticketFile = new BinaryReader(save.OpenFile("/ticket.bin", OpenMode.Read).AsStream()); - - ulong titleId = ticketList.ReadUInt64(); - while (titleId != ulong.MaxValue) - { - ticketList.BaseStream.Position += 0x18; - long start = ticketFile.BaseStream.Position; - tickets.Add(new Ticket(ticketFile)); - ticketFile.BaseStream.Position = start + 0x400; - titleId = ticketList.ReadUInt64(); - } - - return tickets; - } - - private static Keyset OpenKeyset() - { - string home = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); - string homeKeyFile = Path.Combine(home, ".switch", "prod.keys"); - string homeTitleKeyFile = Path.Combine(home, ".switch", "title.keys"); - string homeConsoleKeyFile = Path.Combine(home, ".switch", "console.keys"); - string keyFile = null; - string titleKeyFile = null; - string consoleKeyFile = null; - - if (File.Exists(homeKeyFile)) - { - keyFile = homeKeyFile; - } - - if (File.Exists(homeTitleKeyFile)) - { - titleKeyFile = homeTitleKeyFile; - } - - if (File.Exists(homeConsoleKeyFile)) - { - consoleKeyFile = homeConsoleKeyFile; - } - - return ExternalKeys.ReadKeyFile(keyFile, titleKeyFile, consoleKeyFile); - } - } -} - diff --git a/src/NandReaderGui/App.config b/src/NandReaderGui/App.config deleted file mode 100644 index 8324aa6f..00000000 --- a/src/NandReaderGui/App.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/src/NandReaderGui/App.xaml b/src/NandReaderGui/App.xaml deleted file mode 100644 index bd2febe2..00000000 --- a/src/NandReaderGui/App.xaml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - diff --git a/src/NandReaderGui/App.xaml.cs b/src/NandReaderGui/App.xaml.cs deleted file mode 100644 index 7ddcbb21..00000000 --- a/src/NandReaderGui/App.xaml.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace NandReaderGui -{ - /// - /// Interaction logic for App.xaml - /// - public partial class App - { - } -} diff --git a/src/NandReaderGui/DeviceStream.cs b/src/NandReaderGui/DeviceStream.cs deleted file mode 100644 index 9b3c68c3..00000000 --- a/src/NandReaderGui/DeviceStream.cs +++ /dev/null @@ -1,157 +0,0 @@ -using System; -using System.IO; -using System.Runtime.InteropServices; -using Microsoft.Win32.SafeHandles; - -namespace NandReaderGui -{ - public class DeviceStream : Stream - { - public const short FileAttributeNormal = 0x80; - public const short InvalidHandleValue = -1; - public const uint GenericRead = 0x80000000; - public const uint GenericWrite = 0x40000000; - public const uint CreateNew = 1; - public const uint CreateAlways = 2; - public const uint OpenExisting = 3; - - // Use interop to call the CreateFile function. - // For more information about CreateFile, - // see the unmanaged MSDN reference library. - [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] - private static extern IntPtr CreateFile(string lpFileName, uint dwDesiredAccess, - uint dwShareMode, IntPtr lpSecurityAttributes, uint dwCreationDisposition, - uint dwFlagsAndAttributes, IntPtr hTemplateFile); - - [DllImport("kernel32.dll", SetLastError = true)] - private static extern bool ReadFile( - IntPtr hFile, // handle to file - byte[] lpBuffer, // data buffer - int nNumberOfBytesToRead, // number of bytes to read - ref int lpNumberOfBytesRead, // number of bytes read - IntPtr lpOverlapped - // - // ref OVERLAPPED lpOverlapped // overlapped buffer - ); - - private SafeFileHandle _handleValue; - private FileStream _fs; - - public DeviceStream(string device, long length) - { - Load(device); - Length = length; - } - - private void Load(string path) - { - if (string.IsNullOrEmpty(path)) - { - throw new ArgumentNullException("path"); - } - - // Try to open the file. - IntPtr ptr = CreateFile(path, GenericRead, 0, IntPtr.Zero, OpenExisting, 0, IntPtr.Zero); - - _handleValue = new SafeFileHandle(ptr, true); - _fs = new FileStream(_handleValue, FileAccess.Read); - - // If the handle is invalid, - // get the last Win32 error - // and throw a Win32Exception. - if (_handleValue.IsInvalid) - { - Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); - } - } - - public override bool CanRead { get; } = true; - - public override bool CanSeek => true; - - public override bool CanWrite => false; - - public override void Flush() { } - - public override long Length { get; } - - public override long Position - { - get => _fs.Position; - set => _fs.Position = value; - } - - public override int Read(byte[] buffer, int offset, int count) - { - int bytesRead = 0; - var bufBytes = new byte[count]; - if (!ReadFile(_handleValue.DangerousGetHandle(), bufBytes, count, ref bytesRead, IntPtr.Zero)) - { - Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); - } - for (int i = 0; i < bytesRead; i++) - { - buffer[offset + i] = bufBytes[i]; - } - return bytesRead; - } - - public override int ReadByte() - { - int bytesRead = 0; - var lpBuffer = new byte[1]; - if (!ReadFile( - _handleValue.DangerousGetHandle(), // handle to file - lpBuffer, // data buffer - 1, // number of bytes to read - ref bytesRead, // number of bytes read - IntPtr.Zero - )) - { Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); } - return lpBuffer[0]; - } - - public override long Seek(long offset, SeekOrigin origin) => _fs.Seek(offset, origin); - - public override void SetLength(long value) - { - throw new NotSupportedException(); - } - - public override void Write(byte[] buffer, int offset, int count) - { - throw new NotSupportedException(); - } - - public override void Close() - { - _handleValue.Close(); - _handleValue.Dispose(); - _handleValue = null; - base.Close(); - } - - private bool _disposed; - - protected override void Dispose(bool disposing) - { - // Check to see if Dispose has already been called. - if (!_disposed) - { - if (disposing) - { - if (_handleValue != null) - { - _fs.Dispose(); - _handleValue.Close(); - _handleValue.Dispose(); - _handleValue = null; - } - } - // Note disposing has been done. - _disposed = true; - base.Dispose(disposing); - } - } - } -} diff --git a/src/NandReaderGui/FodyWeavers.xml b/src/NandReaderGui/FodyWeavers.xml deleted file mode 100644 index 43fc6a63..00000000 --- a/src/NandReaderGui/FodyWeavers.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/NandReaderGui/MainWindow.xaml b/src/NandReaderGui/MainWindow.xaml deleted file mode 100644 index f6e9046f..00000000 --- a/src/NandReaderGui/MainWindow.xaml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - diff --git a/src/NandReaderGui/MainWindow.xaml.cs b/src/NandReaderGui/MainWindow.xaml.cs deleted file mode 100644 index b0a88d70..00000000 --- a/src/NandReaderGui/MainWindow.xaml.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace NandReaderGui -{ - /// - /// Interaction logic for MainWindow.xaml - /// - public partial class MainWindow - { - public MainWindow() - { - InitializeComponent(); - } - } -} diff --git a/src/NandReaderGui/NandReaderGui.csproj b/src/NandReaderGui/NandReaderGui.csproj deleted file mode 100644 index a487398f..00000000 --- a/src/NandReaderGui/NandReaderGui.csproj +++ /dev/null @@ -1,126 +0,0 @@ - - - - - Debug - AnyCPU - {3CBD38B0-6575-4768-8E94-A8AF2D2C9F43} - WinExe - NandReaderGui - NandReaderGui - v4.6 - 512 - {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - 4 - true - - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - - - - - - - - - 4.0 - - - - - - - - MSBuild:Compile - Designer - - - - - - Nand.xaml - - - MSBuild:Compile - Designer - - - App.xaml - Code - - - MainWindow.xaml - Code - - - Designer - MSBuild:Compile - - - - - Code - - - True - True - Resources.resx - - - True - Settings.settings - True - - - ResXFileCodeGenerator - Resources.Designer.cs - - - SettingsSingleFileGenerator - Settings.Designer.cs - - - - - - - - 3.1.0 - - - 5.4.1 - - - - - {ab503d24-f702-4e6e-b615-a9c7bda218d1} - LibHac.Nand - - - {ffca6c31-d9d4-4ed8-a06d-0cc6b94422b8} - LibHac - - - - \ No newline at end of file diff --git a/src/NandReaderGui/Properties/AssemblyInfo.cs b/src/NandReaderGui/Properties/AssemblyInfo.cs deleted file mode 100644 index 867f8690..00000000 --- a/src/NandReaderGui/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,53 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; -using System.Windows; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("RawNandReader")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("RawNandReader")] -[assembly: AssemblyCopyright("Copyright © 2018")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -//In order to begin building localizable applications, set -//CultureYouAreCodingWith in your .csproj file -//inside a . For example, if you are using US english -//in your source files, set the to en-US. Then uncomment -//the NeutralResourceLanguage attribute below. Update the "en-US" in -//the line below to match the UICulture setting in the project file. - -//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] - - -[assembly: ThemeInfo( - ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located - //(used if a resource is not found in the page, - // or application resource dictionaries) - ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located - //(used if a resource is not found in the page, - // app, or any theme specific resource dictionaries) -)] - - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/src/NandReaderGui/Properties/Resources.Designer.cs b/src/NandReaderGui/Properties/Resources.Designer.cs deleted file mode 100644 index 6396e556..00000000 --- a/src/NandReaderGui/Properties/Resources.Designer.cs +++ /dev/null @@ -1,63 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace NandReaderGui.Properties { - using System; - - - /// - /// A strongly-typed resource class, for looking up localized strings, etc. - /// - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Resources { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Resources() { - } - - /// - /// Returns the cached ResourceManager instance used by this class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("NandReaderGui.Properties.Resources", typeof(Resources).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - } -} diff --git a/src/NandReaderGui/Properties/Resources.resx b/src/NandReaderGui/Properties/Resources.resx deleted file mode 100644 index af7dbebb..00000000 --- a/src/NandReaderGui/Properties/Resources.resx +++ /dev/null @@ -1,117 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/src/NandReaderGui/Properties/Settings.Designer.cs b/src/NandReaderGui/Properties/Settings.Designer.cs deleted file mode 100644 index 974adc6a..00000000 --- a/src/NandReaderGui/Properties/Settings.Designer.cs +++ /dev/null @@ -1,26 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace NandReaderGui.Properties { - - - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.7.0.0")] - internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { - - private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); - - public static Settings Default { - get { - return defaultInstance; - } - } - } -} diff --git a/src/NandReaderGui/Properties/Settings.settings b/src/NandReaderGui/Properties/Settings.settings deleted file mode 100644 index 033d7a5e..00000000 --- a/src/NandReaderGui/Properties/Settings.settings +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/src/NandReaderGui/View/Nand.xaml b/src/NandReaderGui/View/Nand.xaml deleted file mode 100644 index 5f8881d3..00000000 --- a/src/NandReaderGui/View/Nand.xaml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - diff --git a/src/NandReaderGui/View/Nand.xaml.cs b/src/NandReaderGui/View/Nand.xaml.cs deleted file mode 100644 index 469a1aa9..00000000 --- a/src/NandReaderGui/View/Nand.xaml.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace NandReaderGui.View -{ - /// - /// Interaction logic for Nand.xaml - /// - public partial class Nand - { - public Nand() - { - InitializeComponent(); - } - } -} diff --git a/src/NandReaderGui/ViewModel/NandViewModel.cs b/src/NandReaderGui/ViewModel/NandViewModel.cs deleted file mode 100644 index 8a9d9a7d..00000000 --- a/src/NandReaderGui/ViewModel/NandViewModel.cs +++ /dev/null @@ -1,145 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Management; -using System.Windows.Input; -using GalaSoft.MvvmLight; -using GalaSoft.MvvmLight.Command; -using LibHac; -using LibHac.Fs; -using LibHac.Fs.Save; -using LibHac.Nand; - -namespace NandReaderGui.ViewModel -{ - public class NandViewModel : ViewModelBase - { - public List Disks { get; } = new List(); - public ICommand OpenCommand { get; set; } - public DiskInfo SelectedDisk { get; set; } - - public NandViewModel() - { - OpenCommand = new RelayCommand(Open); - - var query = new WqlObjectQuery("SELECT * FROM Win32_DiskDrive"); - using (var searcher = new ManagementObjectSearcher(query)) - { - foreach (ManagementBaseObject drive in searcher.Get()) - { - if (drive.GetPropertyValue("Size") == null) continue; - var info = new DiskInfo(); - info.PhysicalName = (string)drive.GetPropertyValue("Name"); - info.Name = (string)drive.GetPropertyValue("Caption"); - info.Model = (string)drive.GetPropertyValue("Model"); - //todo Why is Windows returning small sizes? https://stackoverflow.com/questions/15051660 - info.Length = (long)((ulong)drive.GetPropertyValue("Size")); - info.SectorSize = (int)((uint)drive.GetPropertyValue("BytesPerSector")); - info.DisplaySize = Util.GetBytesReadable((long)((ulong)drive.GetPropertyValue("Size"))); - - Disks.Add(info); - } - } - } - - public void Open() - { - DiskInfo disk = SelectedDisk; - var storage = new CachedStorage(new DeviceStream(disk.PhysicalName, disk.Length).AsStorage(), disk.SectorSize * 100, 4, true); - Stream stream = storage.AsStream(FileAccess.Read); - - Keyset keyset = OpenKeyset(); - var nand = new Nand(stream, keyset); - - Stream prodinfo = nand.OpenProdInfo(); - var calibration = new Calibration(prodinfo); - - keyset.EticketExtKeyRsa = Crypto.DecryptRsaKey(calibration.EticketExtKeyRsa, keyset.EticketRsaKek); - Ticket[] tickets = GetTickets(keyset, nand); - - using (var outStream = new StreamWriter("titlekeys.txt")) - { - foreach (Ticket ticket in tickets) - { - byte[] key = ticket.GetTitleKey(keyset); - outStream.WriteLine($"{ticket.RightsId.ToHexString()},{key.ToHexString()}"); - } - } - } - - private static Ticket[] GetTickets(Keyset keyset, Nand nand, IProgressReport logger = null) - { - var tickets = new List(); - FatFileSystemProvider system = nand.OpenSystemPartition(); - - IFile saveE1File = system.OpenFile("/save/80000000000000E1", OpenMode.Read); - tickets.AddRange(ReadTickets(keyset, saveE1File.AsStream())); - - IFile saveE2 = system.OpenFile("/save/80000000000000E2", OpenMode.Read); - tickets.AddRange(ReadTickets(keyset, saveE2.AsStream())); - - logger?.LogMessage($"Found {tickets.Count} tickets"); - - return tickets.ToArray(); - } - - private static List ReadTickets(Keyset keyset, Stream savefile) - { - var tickets = new List(); - var save = new SaveDataFileSystem(keyset, savefile.AsStorage(), IntegrityCheckLevel.None, true); - var ticketList = new BinaryReader(save.OpenFile("/ticket_list.bin", OpenMode.Read).AsStream()); - var ticketFile = new BinaryReader(save.OpenFile("/ticket.bin", OpenMode.Read).AsStream()); - - ulong titleId = ticketList.ReadUInt64(); - while (titleId != ulong.MaxValue) - { - ticketList.BaseStream.Position += 0x18; - long start = ticketFile.BaseStream.Position; - tickets.Add(new Ticket(ticketFile)); - ticketFile.BaseStream.Position = start + 0x400; - titleId = ticketList.ReadUInt64(); - } - - return tickets; - } - - private static Keyset OpenKeyset() - { - string home = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); - string homeKeyFile = Path.Combine(home, ".switch", "prod.keys"); - string homeTitleKeyFile = Path.Combine(home, ".switch", "title.keys"); - string homeConsoleKeyFile = Path.Combine(home, ".switch", "console.keys"); - string keyFile = null; - string titleKeyFile = null; - string consoleKeyFile = null; - - if (File.Exists(homeKeyFile)) - { - keyFile = homeKeyFile; - } - - if (File.Exists(homeTitleKeyFile)) - { - titleKeyFile = homeTitleKeyFile; - } - - if (File.Exists(homeConsoleKeyFile)) - { - consoleKeyFile = homeConsoleKeyFile; - } - - return ExternalKeys.ReadKeyFile(keyFile, titleKeyFile, consoleKeyFile); - } - } - - public class DiskInfo - { - public string PhysicalName { get; set; } - public string Name { get; set; } - public string Model { get; set; } - public long Length { get; set; } - public int SectorSize { get; set; } - public string DisplaySize { get; set; } - public string Display => $"{Name} ({DisplaySize})"; - } -} diff --git a/src/NandReaderGui/ViewModel/ViewModelLocator.cs b/src/NandReaderGui/ViewModel/ViewModelLocator.cs deleted file mode 100644 index e4266ff8..00000000 --- a/src/NandReaderGui/ViewModel/ViewModelLocator.cs +++ /dev/null @@ -1,48 +0,0 @@ -/* - In App.xaml: - - - - - In the View: - DataContext="{Binding Source={StaticResource Locator}, Path=ViewModelName}" -*/ - -using CommonServiceLocator; -using GalaSoft.MvvmLight.Ioc; - -namespace NandReaderGui.ViewModel -{ - /// - /// This class contains static references to all the view models in the - /// application and provides an entry point for the bindings. - /// - /// See http://www.mvvmlight.net - /// - /// - public class ViewModelLocator - { - static ViewModelLocator() - { - ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default); - - SimpleIoc.Default.Register(); - } - - /// - /// Gets the Main property. - /// - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", - "CA1822:MarkMembersAsStatic", - Justification = "This non-static member is needed for data binding purposes.")] - public NandViewModel Main => ServiceLocator.Current.GetInstance(); - - /// - /// Cleans up all the resources. - /// - public static void Cleanup() - { - } - } -} \ No newline at end of file