diff --git a/DiscImageChef.Filters/AppleDouble.cs b/DiscImageChef.Filters/AppleDouble.cs index d0326e4ff..48405edce 100644 --- a/DiscImageChef.Filters/AppleDouble.cs +++ b/DiscImageChef.Filters/AppleDouble.cs @@ -38,117 +38,35 @@ using System.Runtime.InteropServices; namespace DiscImageChef.Filters { /// - /// Decodes AppleDouble files + /// Decodes AppleDouble files /// public class AppleDouble : Filter { - enum AppleDoubleEntryID : uint - { - Invalid = 0, - DataFork = 1, - ResourceFork = 2, - RealName = 3, - Comment = 4, - Icon = 5, - ColorIcon = 6, - FileInfo = 7, - FileDates = 8, - FinderInfo = 9, - MacFileInfo = 10, - ProDOSFileInfo = 11, - DOSFileInfo = 12, - ShortName = 13, - AFPFileInfo = 14, - DirectoryID = 15 - } - - [StructLayout(LayoutKind.Sequential, Pack = 1)] - struct AppleDoubleHeader - { - public uint magic; - public uint version; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] homeFilesystem; - public ushort entries; - } - - [StructLayout(LayoutKind.Sequential, Pack = 1)] - struct AppleDoubleEntry - { - public uint id; - public uint offset; - public uint length; - } - - [StructLayout(LayoutKind.Sequential, Pack = 1)] - struct AppleDoubleFileDates - { - public uint creationDate; - public uint modificationDate; - public uint backupDate; - public uint accessDate; - } - - [StructLayout(LayoutKind.Sequential, Pack = 1)] - struct AppleDoubleMacFileInfo - { - public uint creationDate; - public uint modificationDate; - public uint backupDate; - public uint accessDate; - } - - [StructLayout(LayoutKind.Sequential, Pack = 1)] - struct AppleDoubleUNIXFileInfo - { - public uint creationDate; - public uint accessDate; - public uint modificationDate; - } - - [StructLayout(LayoutKind.Sequential, Pack = 1)] - struct AppleDoubleDOSFileInfo - { - public ushort modificationDate; - public ushort modificationTime; - public ushort attributes; - } - - [StructLayout(LayoutKind.Sequential, Pack = 1)] - struct AppleDoubleProDOSFileInfo - { - public uint creationDate; - public uint modificationDate; - public uint backupDate; - public ushort access; - public ushort fileType; - public uint auxType; - } - const uint AppleDoubleMagic = 0x00051607; const uint AppleDoubleVersion = 0x00010000; const uint AppleDoubleVersion2 = 0x00020000; + readonly byte[] DOSHome = + {0x4D, 0x53, 0x2D, 0x44, 0x4F, 0x53, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20}; readonly byte[] MacintoshHome = {0x4D, 0x61, 0x63, 0x69, 0x6E, 0x74, 0x6F, 0x73, 0x68, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20}; + readonly byte[] OSXHome = + {0x4D, 0x61, 0x63, 0x20, 0x4F, 0x53, 0x20, 0x58, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20}; readonly byte[] ProDOSHome = {0x50, 0x72, 0x6F, 0x44, 0x4F, 0x53, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20}; - readonly byte[] DOSHome = - {0x4D, 0x53, 0x2D, 0x44, 0x4F, 0x53, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20}; readonly byte[] UNIXHome = {0x55, 0x6E, 0x69, 0x78, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20}; readonly byte[] VMXHome = {0x56, 0x41, 0x58, 0x20, 0x56, 0x4D, 0x53, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20}; - readonly byte[] OSXHome = - {0x4D, 0x61, 0x63, 0x20, 0x4F, 0x53, 0x20, 0x58, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20}; + string basePath; + DateTime creationTime; AppleDoubleEntry dataFork; - AppleDoubleEntry rsrcFork; - bool opened; - string basePath; + AppleDoubleHeader header; string headerPath; DateTime lastWriteTime; - DateTime creationTime; - AppleDoubleHeader header; + bool opened; + AppleDoubleEntry rsrcFork; public AppleDouble() { @@ -263,7 +181,8 @@ namespace DiscImageChef.Filters UNIXAppleDouble = Path.Combine(parentFolder, "%" + filename); DOSAppleDouble = Path.Combine(parentFolder, filenameNoExt + ".ADF"); DOSAppleDoubleLower = Path.Combine(parentFolder, filenameNoExt + ".adf"); - NetatalkAppleDouble = Path.Combine(parentFolder, ".AppleDouble", filename ?? throw new InvalidOperationException()); + NetatalkAppleDouble = Path.Combine(parentFolder, ".AppleDouble", + filename ?? throw new InvalidOperationException()); DAVEAppleDouble = Path.Combine(parentFolder, "resource.frk", filename); OSXAppleDouble = Path.Combine(parentFolder, "._" + filename); UnArAppleDouble = Path.Combine(parentFolder, filename + ".rsrc"); @@ -431,7 +350,8 @@ namespace DiscImageChef.Filters UNIXAppleDouble = Path.Combine(parentFolder, "%" + filename); DOSAppleDouble = Path.Combine(parentFolder, filenameNoExt + ".ADF"); DOSAppleDoubleLower = Path.Combine(parentFolder, filenameNoExt + ".adf"); - NetatalkAppleDouble = Path.Combine(parentFolder, ".AppleDouble", filename ?? throw new InvalidOperationException()); + NetatalkAppleDouble = Path.Combine(parentFolder, ".AppleDouble", + filename ?? throw new InvalidOperationException()); DAVEAppleDouble = Path.Combine(parentFolder, "resource.frk", filename); OSXAppleDouble = Path.Combine(parentFolder, "._" + filename); UnArAppleDouble = Path.Combine(parentFolder, filename + ".rsrc"); @@ -646,5 +566,87 @@ namespace DiscImageChef.Filters opened = true; basePath = path; } + + enum AppleDoubleEntryID : uint + { + Invalid = 0, + DataFork = 1, + ResourceFork = 2, + RealName = 3, + Comment = 4, + Icon = 5, + ColorIcon = 6, + FileInfo = 7, + FileDates = 8, + FinderInfo = 9, + MacFileInfo = 10, + ProDOSFileInfo = 11, + DOSFileInfo = 12, + ShortName = 13, + AFPFileInfo = 14, + DirectoryID = 15 + } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + struct AppleDoubleHeader + { + public uint magic; + public uint version; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] homeFilesystem; + public ushort entries; + } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + struct AppleDoubleEntry + { + public uint id; + public uint offset; + public uint length; + } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + struct AppleDoubleFileDates + { + public uint creationDate; + public uint modificationDate; + public uint backupDate; + public uint accessDate; + } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + struct AppleDoubleMacFileInfo + { + public uint creationDate; + public uint modificationDate; + public uint backupDate; + public uint accessDate; + } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + struct AppleDoubleUNIXFileInfo + { + public uint creationDate; + public uint accessDate; + public uint modificationDate; + } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + struct AppleDoubleDOSFileInfo + { + public ushort modificationDate; + public ushort modificationTime; + public ushort attributes; + } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + struct AppleDoubleProDOSFileInfo + { + public uint creationDate; + public uint modificationDate; + public uint backupDate; + public ushort access; + public ushort fileType; + public uint auxType; + } } } \ No newline at end of file diff --git a/DiscImageChef.Filters/AppleSingle.cs b/DiscImageChef.Filters/AppleSingle.cs index c0302b193..622d331d8 100644 --- a/DiscImageChef.Filters/AppleSingle.cs +++ b/DiscImageChef.Filters/AppleSingle.cs @@ -38,118 +38,36 @@ using System.Runtime.InteropServices; namespace DiscImageChef.Filters { /// - /// Decodes AppleSingle files + /// Decodes AppleSingle files /// public class AppleSingle : Filter { - enum AppleSingleEntryID : uint - { - Invalid = 0, - DataFork = 1, - ResourceFork = 2, - RealName = 3, - Comment = 4, - Icon = 5, - ColorIcon = 6, - FileInfo = 7, - FileDates = 8, - FinderInfo = 9, - MacFileInfo = 10, - ProDOSFileInfo = 11, - DOSFileInfo = 12, - ShortName = 13, - AFPFileInfo = 14, - DirectoryID = 15 - } - - [StructLayout(LayoutKind.Sequential, Pack = 1)] - struct AppleSingleHeader - { - public uint magic; - public uint version; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] homeFilesystem; - public ushort entries; - } - - [StructLayout(LayoutKind.Sequential, Pack = 1)] - struct AppleSingleEntry - { - public uint id; - public uint offset; - public uint length; - } - - [StructLayout(LayoutKind.Sequential, Pack = 1)] - struct AppleSingleFileDates - { - public uint creationDate; - public uint modificationDate; - public uint backupDate; - public uint accessDate; - } - - [StructLayout(LayoutKind.Sequential, Pack = 1)] - struct AppleSingleMacFileInfo - { - public uint creationDate; - public uint modificationDate; - public uint backupDate; - public uint accessDate; - } - - [StructLayout(LayoutKind.Sequential, Pack = 1)] - struct AppleSingleUNIXFileInfo - { - public uint creationDate; - public uint accessDate; - public uint modificationDate; - } - - [StructLayout(LayoutKind.Sequential, Pack = 1)] - struct AppleSingleDOSFileInfo - { - public ushort modificationDate; - public ushort modificationTime; - public ushort attributes; - } - - [StructLayout(LayoutKind.Sequential, Pack = 1)] - struct AppleSingleProDOSFileInfo - { - public uint creationDate; - public uint modificationDate; - public uint backupDate; - public ushort access; - public ushort fileType; - public uint auxType; - } - const uint AppleSingleMagic = 0x00051600; const uint AppleSingleVersion = 0x00010000; const uint AppleSingleVersion2 = 0x00020000; + readonly byte[] DOSHome = + {0x4D, 0x53, 0x2D, 0x44, 0x4F, 0x53, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20}; readonly byte[] MacintoshHome = {0x4D, 0x61, 0x63, 0x69, 0x6E, 0x74, 0x6F, 0x73, 0x68, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20}; + readonly byte[] OSXHome = + {0x4D, 0x61, 0x63, 0x20, 0x4F, 0x53, 0x20, 0x58, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20}; readonly byte[] ProDOSHome = {0x50, 0x72, 0x6F, 0x44, 0x4F, 0x53, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20}; - readonly byte[] DOSHome = - {0x4D, 0x53, 0x2D, 0x44, 0x4F, 0x53, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20}; readonly byte[] UNIXHome = {0x55, 0x6E, 0x69, 0x78, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20}; readonly byte[] VMSHome = {0x56, 0x41, 0x58, 0x20, 0x56, 0x4D, 0x53, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20}; - readonly byte[] OSXHome = - {0x4D, 0x61, 0x63, 0x20, 0x4F, 0x53, 0x20, 0x58, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20}; + string basePath; + byte[] bytes; + DateTime creationTime; AppleSingleEntry dataFork; - AppleSingleEntry rsrcFork; - byte[] bytes; - Stream stream; - bool isBytes, isStream, isPath, opened; - string basePath; - DateTime lastWriteTime; - DateTime creationTime; AppleSingleHeader header; + bool isBytes, isStream, isPath, opened; + DateTime lastWriteTime; + AppleSingleEntry rsrcFork; + Stream stream; public AppleSingle() { @@ -519,5 +437,87 @@ namespace DiscImageChef.Filters isPath = true; basePath = path; } + + enum AppleSingleEntryID : uint + { + Invalid = 0, + DataFork = 1, + ResourceFork = 2, + RealName = 3, + Comment = 4, + Icon = 5, + ColorIcon = 6, + FileInfo = 7, + FileDates = 8, + FinderInfo = 9, + MacFileInfo = 10, + ProDOSFileInfo = 11, + DOSFileInfo = 12, + ShortName = 13, + AFPFileInfo = 14, + DirectoryID = 15 + } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + struct AppleSingleHeader + { + public uint magic; + public uint version; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] homeFilesystem; + public ushort entries; + } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + struct AppleSingleEntry + { + public uint id; + public uint offset; + public uint length; + } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + struct AppleSingleFileDates + { + public uint creationDate; + public uint modificationDate; + public uint backupDate; + public uint accessDate; + } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + struct AppleSingleMacFileInfo + { + public uint creationDate; + public uint modificationDate; + public uint backupDate; + public uint accessDate; + } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + struct AppleSingleUNIXFileInfo + { + public uint creationDate; + public uint accessDate; + public uint modificationDate; + } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + struct AppleSingleDOSFileInfo + { + public ushort modificationDate; + public ushort modificationTime; + public ushort attributes; + } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + struct AppleSingleProDOSFileInfo + { + public uint creationDate; + public uint modificationDate; + public uint backupDate; + public ushort access; + public ushort fileType; + public uint auxType; + } } } \ No newline at end of file diff --git a/DiscImageChef.Filters/BZip2.cs b/DiscImageChef.Filters/BZip2.cs index f35e23664..a14d6d50c 100644 --- a/DiscImageChef.Filters/BZip2.cs +++ b/DiscImageChef.Filters/BZip2.cs @@ -38,17 +38,17 @@ using SharpCompress.Compressors.BZip2; namespace DiscImageChef.Filters { /// - /// Decompress bz2 files while reading + /// Decompress bz2 files while reading /// public class BZip2 : Filter { - Stream dataStream; string basePath; - DateTime lastWriteTime; DateTime creationTime; - bool opened; + Stream dataStream; long decompressedSize; Stream innerStream; + DateTime lastWriteTime; + bool opened; public BZip2() { @@ -96,7 +96,8 @@ namespace DiscImageChef.Filters if(buffer.Length <= 512) return true; - return buffer[buffer.Length - 512] != 0x6B || buffer[buffer.Length - 511] != 0x6F || buffer[buffer.Length - 510] != 0x6C || buffer[buffer.Length - 509] != 0x79; + return buffer[buffer.Length - 512] != 0x6B || buffer[buffer.Length - 511] != 0x6F || + buffer[buffer.Length - 510] != 0x6C || buffer[buffer.Length - 509] != 0x79; } public override bool Identify(Stream stream) @@ -139,8 +140,7 @@ namespace DiscImageChef.Filters stream.Read(buffer, 0, 4); stream.Seek(0, SeekOrigin.Begin); // Check it is not an UDIF - if(buffer[0] == 0x6B && buffer[1] == 0x6F && buffer[2] == 0x6C && buffer[3] == 0x79) - return false; + if(buffer[0] == 0x6B && buffer[1] == 0x6F && buffer[2] == 0x6C && buffer[3] == 0x79) return false; return true; } diff --git a/DiscImageChef.Filters/Filter.cs b/DiscImageChef.Filters/Filter.cs index 3f0b33dac..ff4672e69 100644 --- a/DiscImageChef.Filters/Filter.cs +++ b/DiscImageChef.Filters/Filter.cs @@ -41,126 +41,127 @@ namespace DiscImageChef.Filters public Guid UUID; /// - /// Closes all opened streams. + /// Closes all opened streams. /// public abstract void Close(); /// - /// Gets the path used to open this filter.
- /// UNIX: /path/to/archive.zip/path/to/file.bin => /path/to/archive.zip/path/to/file.bin
- /// Windows: C:\path\to\archive.zip\path\to\file.bin => C:\path\to\archive.zip\path\to\file.bin + /// Gets the path used to open this filter.
+ /// UNIX: /path/to/archive.zip/path/to/file.bin => /path/to/archive.zip/path/to/file.bin
+ /// Windows: C:\path\to\archive.zip\path\to\file.bin => C:\path\to\archive.zip\path\to\file.bin ///
/// Path used to open this filter. public abstract string GetBasePath(); /// - /// Gets creation time of file referenced by this filter. + /// Gets creation time of file referenced by this filter. /// /// The creation time. public abstract DateTime GetCreationTime(); /// - /// Gets length of this filter's data fork. + /// Gets length of this filter's data fork. /// /// The data fork length. public abstract long GetDataForkLength(); /// - /// Gets a stream to access the data fork contents. + /// Gets a stream to access the data fork contents. /// /// The data fork stream. public abstract Stream GetDataForkStream(); /// - /// Gets the filename for the file referenced by this filter.
- /// UNIX: /path/to/archive.zip/path/to/file.bin => file.bin
- /// Windows: C:\path\to\archive.zip\path\to\file.bin => file.bin + /// Gets the filename for the file referenced by this filter.
+ /// UNIX: /path/to/archive.zip/path/to/file.bin => file.bin
+ /// Windows: C:\path\to\archive.zip\path\to\file.bin => file.bin ///
/// The filename. public abstract string GetFilename(); /// - /// Gets last write time of file referenced by this filter. + /// Gets last write time of file referenced by this filter. /// /// The last write time. public abstract DateTime GetLastWriteTime(); /// - /// Gets length of file referenced by ths filter. + /// Gets length of file referenced by ths filter. /// /// The length. public abstract long GetLength(); /// - /// Gets full path to file referenced by this filter. If it's an archive, it's the path inside the archive.
- /// UNIX: /path/to/archive.zip/path/to/file.bin => /path/to/file.bin
- /// Windows: C:\path\to\archive.zip\path\to\file.bin => \path\to\file.bin + /// Gets full path to file referenced by this filter. If it's an archive, it's the path inside the archive.
+ /// UNIX: /path/to/archive.zip/path/to/file.bin => /path/to/file.bin
+ /// Windows: C:\path\to\archive.zip\path\to\file.bin => \path\to\file.bin ///
/// The path. public abstract string GetPath(); /// - /// Gets path to parent folder to the file referenced by this filter. If it's an archive, it's the full path to the archive itself.
- /// UNIX: /path/to/archive.zip/path/to/file.bin => /path/to/archive.zip
- /// Windows: C:\path\to\archive.zip\path\to\file.bin => C:\path\to\archive.zip + /// Gets path to parent folder to the file referenced by this filter. If it's an archive, it's the full path to the + /// archive itself.
+ /// UNIX: /path/to/archive.zip/path/to/file.bin => /path/to/archive.zip
+ /// Windows: C:\path\to\archive.zip\path\to\file.bin => C:\path\to\archive.zip ///
/// The parent folder. public abstract string GetParentFolder(); /// - /// Gets length of this filter's resource fork. + /// Gets length of this filter's resource fork. /// /// The resource fork length. public abstract long GetResourceForkLength(); /// - /// Gets a stream to access the resource fork contents. + /// Gets a stream to access the resource fork contents. /// /// The resource fork stream. public abstract Stream GetResourceForkStream(); /// - /// Returns true if the file referenced by this filter has a resource fork + /// Returns true if the file referenced by this filter has a resource fork /// public abstract bool HasResourceFork(); /// - /// Identifies if the specified path contains data recognizable by this filter instance + /// Identifies if the specified path contains data recognizable by this filter instance /// /// Path. public abstract bool Identify(string path); /// - /// Identifies if the specified stream contains data recognizable by this filter instance + /// Identifies if the specified stream contains data recognizable by this filter instance /// /// Stream. public abstract bool Identify(Stream stream); /// - /// Identifies if the specified buffer contains data recognizable by this filter instance + /// Identifies if the specified buffer contains data recognizable by this filter instance /// /// Buffer. public abstract bool Identify(byte[] buffer); /// - /// Returns true if the filter has a file/stream/buffer currently opened and no has been issued. + /// Returns true if the filter has a file/stream/buffer currently opened and no has been issued. /// public abstract bool IsOpened(); /// - /// Opens the specified path with this filter instance + /// Opens the specified path with this filter instance /// /// Path. public abstract void Open(string path); /// - /// Opens the specified stream with this filter instance + /// Opens the specified stream with this filter instance /// /// Stream. public abstract void Open(Stream stream); /// - /// Opens the specified buffer with this filter instance + /// Opens the specified buffer with this filter instance /// /// Buffer. public abstract void Open(byte[] buffer); diff --git a/DiscImageChef.Filters/Filters.cs b/DiscImageChef.Filters/Filters.cs index 08fde704e..8484f1cd2 100644 --- a/DiscImageChef.Filters/Filters.cs +++ b/DiscImageChef.Filters/Filters.cs @@ -42,7 +42,7 @@ namespace DiscImageChef.Filters public SortedDictionary Filters; /// - /// Fills the list of all known filters + /// Fills the list of all known filters /// public FiltersList() { @@ -55,13 +55,14 @@ namespace DiscImageChef.Filters if(!type.IsSubclassOf(typeof(Filter))) continue; Filter filter = (Filter)type.GetConstructor(Type.EmptyTypes)?.Invoke(new object[] { }); - if(filter != null && !Filters.ContainsKey(filter.Name.ToLower())) Filters.Add(filter.Name.ToLower(), filter); + if(filter != null && !Filters.ContainsKey(filter.Name.ToLower())) + Filters.Add(filter.Name.ToLower(), filter); } catch(Exception exception) { DicConsole.ErrorWriteLine("Exception {0}", exception); } } /// - /// Gets the filter that allows to read the specified path + /// Gets the filter that allows to read the specified path /// /// Path /// The filter that allows reading the specified path @@ -91,7 +92,7 @@ namespace DiscImageChef.Filters } /// - /// Gets all known filters + /// Gets all known filters /// /// Known filters public SortedDictionary GetFiltersList() diff --git a/DiscImageChef.Filters/ForcedSeekStream.cs b/DiscImageChef.Filters/ForcedSeekStream.cs index 821b74dbf..0d3f7dd6e 100644 --- a/DiscImageChef.Filters/ForcedSeekStream.cs +++ b/DiscImageChef.Filters/ForcedSeekStream.cs @@ -36,19 +36,19 @@ using System.IO; namespace DiscImageChef.Filters { /// - /// ForcedSeekStream allows to seek a forward-readable stream (like System.IO.Compression streams) - /// by doing the slow and known trick of rewinding and forward reading until arriving the desired position. + /// ForcedSeekStream allows to seek a forward-readable stream (like System.IO.Compression streams) + /// by doing the slow and known trick of rewinding and forward reading until arriving the desired position. /// public class ForcedSeekStream : Stream where T : Stream { + const int BUFFER_LEN = 1048576; + string backFile; + FileStream backStream; T baseStream; long streamLength; - const int BUFFER_LEN = 1048576; - FileStream backStream; - string backFile; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The real (uncompressed) length of the stream. /// Parameters that are used to create the base stream. @@ -62,7 +62,7 @@ namespace DiscImageChef.Filters } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// Parameters that are used to create the base stream. public ForcedSeekStream(params object[] args) @@ -73,27 +73,6 @@ namespace DiscImageChef.Filters CalculateLength(); } - /// - /// Calculates the real (uncompressed) length of the stream. - /// It basically reads (uncompresses) the whole stream to memory discarding its contents, - /// so it should be used as a last resort. - /// - /// The length. - public void CalculateLength() - { - int read; - do - { - byte[] buffer = new byte[BUFFER_LEN]; - read = baseStream.Read(buffer, 0, BUFFER_LEN); - backStream.Write(buffer, 0, read); - } - while(read == BUFFER_LEN); - - streamLength = backStream.Length; - backStream.Position = 0; - } - public override bool CanRead => baseStream.CanRead; public override bool CanSeek => true; @@ -109,6 +88,27 @@ namespace DiscImageChef.Filters set => SetPosition(value); } + /// + /// Calculates the real (uncompressed) length of the stream. + /// It basically reads (uncompresses) the whole stream to memory discarding its contents, + /// so it should be used as a last resort. + /// + /// The length. + public void CalculateLength() + { + int read; + do + { + byte[] buffer = new byte[BUFFER_LEN]; + read = baseStream.Read(buffer, 0, BUFFER_LEN); + backStream.Write(buffer, 0, read); + } + while(read == BUFFER_LEN); + + streamLength = backStream.Length; + backStream.Position = 0; + } + void SetPosition(long position) { if(position == backStream.Position) return; diff --git a/DiscImageChef.Filters/GZip.cs b/DiscImageChef.Filters/GZip.cs index 29c97dbd7..f8becc398 100644 --- a/DiscImageChef.Filters/GZip.cs +++ b/DiscImageChef.Filters/GZip.cs @@ -37,16 +37,16 @@ using System.IO.Compression; namespace DiscImageChef.Filters { /// - /// Decompress gzip files while reading + /// Decompress gzip files while reading /// public class GZip : Filter { - Stream dataStream; string basePath; - DateTime lastWriteTime; DateTime creationTime; - bool opened; + Stream dataStream; uint decompressedSize; + DateTime lastWriteTime; + bool opened; Stream zStream; public GZip() diff --git a/DiscImageChef.Filters/LZip.cs b/DiscImageChef.Filters/LZip.cs index a8dcf58ff..be438b0e0 100644 --- a/DiscImageChef.Filters/LZip.cs +++ b/DiscImageChef.Filters/LZip.cs @@ -38,17 +38,17 @@ using SharpCompress.Compressors.LZMA; namespace DiscImageChef.Filters { /// - /// Decompress lzip files while reading + /// Decompress lzip files while reading /// public class LZip : Filter { - Stream dataStream; string basePath; - DateTime lastWriteTime; DateTime creationTime; - bool opened; + Stream dataStream; long decompressedSize; Stream innerStream; + DateTime lastWriteTime; + bool opened; public LZip() { diff --git a/DiscImageChef.Filters/MacBinary.cs b/DiscImageChef.Filters/MacBinary.cs index cee331e3f..f65cc2512 100644 --- a/DiscImageChef.Filters/MacBinary.cs +++ b/DiscImageChef.Filters/MacBinary.cs @@ -39,143 +39,22 @@ namespace DiscImageChef.Filters { // TODO: Interpret fdScript /// - /// Decodes MacBinary files + /// Decodes MacBinary files /// public class MacBinary : Filter { - [StructLayout(LayoutKind.Sequential, Pack = 1)] - struct MacBinaryHeader - { - /// - /// 0x00, MacBinary version, 0 - /// - public byte version; - /// - /// 0x01, Str63 Pascal filename - /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] public byte[] filename; - /// - /// 0x41, File type - /// - public uint type; - /// - /// 0x45, File creator - /// - public uint creator; - /// - /// 0x49, High byte of Finder flags - /// - public byte finderFlags; - /// - /// 0x4A, Must be 0 - /// - public byte zero1; - /// - /// 0x4B, File's icon vertical position within its window - /// - public ushort verticalPosition; - /// - /// 0x4D, File's icon horizontal position within its window - /// - public ushort horizontalPosition; - /// - /// 0x4F, File's window or folder ID - /// - public short windowID; - /// - /// 0x51, Protected flag - /// - public byte protect; - /// - /// 0x52, Must be 0 - /// - public byte zero2; - /// - /// 0x53, Size of data fork - /// - public uint dataLength; - /// - /// 0x57, Size of resource fork - /// - public uint resourceLength; - /// - /// 0x5B, File's creation time - /// - public uint creationTime; - /// - /// 0x5F, File's last modified time - /// - public uint modificationTime; - /// - /// 0x63, Length of Get Info comment - /// - public ushort commentLength; - /// - /// 0x65, Low byte of Finder flags - /// - public byte finderFlags2; - - #region MacBinary III - /// - /// 0x66, magic identifier, "mBIN" - /// - public uint magic; - /// - /// 0x6A, fdScript from fxInfo, identifies codepage of filename - /// - public byte fdScript; - /// - /// 0x6B, fdXFlags from fxInfo, extended Mac OS 8 finder flags - /// - public byte fdXFlags; - #endregion MacBinary III - - /// - /// 0x6C, unused - /// - public ulong reserved; - /// - /// 0x74, Total unpacked files - /// - public uint totalPackedFiles; - - #region MacBinary II - /// - /// 0x78, Length of secondary header - /// - public ushort secondaryHeaderLength; - /// - /// 0x7A, version number of MacBinary that wrote this file, starts at 129 - /// - public byte version2; - /// - /// 0x7B, version number of MacBinary required to open this file, starts at 129 - /// - public byte minVersion; - /// - /// 0x7C, CRC of previous bytes - /// - public short crc; - #endregion MacBinary II - - /// - /// 0x7E, Reserved for computer type and OS ID - /// - public short computerID; - } - const uint MACBINARY_MAGIC = 0x6D42494E; + string basePath; + byte[] bytes; + DateTime creationTime; long dataForkOff; - long rsrcForkOff; - byte[] bytes; - Stream stream; - bool isBytes, isStream, isPath, opened; - string basePath; - DateTime lastWriteTime; - DateTime creationTime; - MacBinaryHeader header; string filename; + MacBinaryHeader header; + bool isBytes, isStream, isPath, opened; + DateTime lastWriteTime; + long rsrcForkOff; + Stream stream; public MacBinary() { @@ -278,8 +157,7 @@ namespace DiscImageChef.Filters header = BigEndianMarshal.ByteArrayToStructureBigEndian(hdr_b); return header.magic == MACBINARY_MAGIC || header.version == 0 && header.filename[0] > 0 && - header.filename[0] < 64 && header.zero1 == 0 && - header.zero2 == 0 && header.reserved == 0 && + header.filename[0] < 64 && header.zero1 == 0 && header.zero2 == 0 && header.reserved == 0 && (header.dataLength > 0 || header.resourceLength > 0); } @@ -293,8 +171,7 @@ namespace DiscImageChef.Filters header = BigEndianMarshal.ByteArrayToStructureBigEndian(hdr_b); return header.magic == MACBINARY_MAGIC || header.version == 0 && header.filename[0] > 0 && - header.filename[0] < 64 && header.zero1 == 0 && - header.zero2 == 0 && header.reserved == 0 && + header.filename[0] < 64 && header.zero1 == 0 && header.zero2 == 0 && header.reserved == 0 && (header.dataLength > 0 || header.resourceLength > 0); } @@ -309,8 +186,7 @@ namespace DiscImageChef.Filters fstream.Close(); return header.magic == MACBINARY_MAGIC || header.version == 0 && header.filename[0] > 0 && - header.filename[0] < 64 && header.zero1 == 0 && - header.zero2 == 0 && header.reserved == 0 && + header.filename[0] < 64 && header.zero1 == 0 && header.zero2 == 0 && header.reserved == 0 && (header.dataLength > 0 || header.resourceLength > 0); } @@ -398,5 +274,126 @@ namespace DiscImageChef.Filters isPath = true; basePath = path; } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + struct MacBinaryHeader + { + /// + /// 0x00, MacBinary version, 0 + /// + public byte version; + /// + /// 0x01, Str63 Pascal filename + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] public byte[] filename; + /// + /// 0x41, File type + /// + public uint type; + /// + /// 0x45, File creator + /// + public uint creator; + /// + /// 0x49, High byte of Finder flags + /// + public byte finderFlags; + /// + /// 0x4A, Must be 0 + /// + public byte zero1; + /// + /// 0x4B, File's icon vertical position within its window + /// + public ushort verticalPosition; + /// + /// 0x4D, File's icon horizontal position within its window + /// + public ushort horizontalPosition; + /// + /// 0x4F, File's window or folder ID + /// + public short windowID; + /// + /// 0x51, Protected flag + /// + public byte protect; + /// + /// 0x52, Must be 0 + /// + public byte zero2; + /// + /// 0x53, Size of data fork + /// + public uint dataLength; + /// + /// 0x57, Size of resource fork + /// + public uint resourceLength; + /// + /// 0x5B, File's creation time + /// + public uint creationTime; + /// + /// 0x5F, File's last modified time + /// + public uint modificationTime; + /// + /// 0x63, Length of Get Info comment + /// + public ushort commentLength; + /// + /// 0x65, Low byte of Finder flags + /// + public byte finderFlags2; + + #region MacBinary III + /// + /// 0x66, magic identifier, "mBIN" + /// + public uint magic; + /// + /// 0x6A, fdScript from fxInfo, identifies codepage of filename + /// + public byte fdScript; + /// + /// 0x6B, fdXFlags from fxInfo, extended Mac OS 8 finder flags + /// + public byte fdXFlags; + #endregion MacBinary III + + /// + /// 0x6C, unused + /// + public ulong reserved; + /// + /// 0x74, Total unpacked files + /// + public uint totalPackedFiles; + + #region MacBinary II + /// + /// 0x78, Length of secondary header + /// + public ushort secondaryHeaderLength; + /// + /// 0x7A, version number of MacBinary that wrote this file, starts at 129 + /// + public byte version2; + /// + /// 0x7B, version number of MacBinary required to open this file, starts at 129 + /// + public byte minVersion; + /// + /// 0x7C, CRC of previous bytes + /// + public short crc; + #endregion MacBinary II + + /// + /// 0x7E, Reserved for computer type and OS ID + /// + public short computerID; + } } } \ No newline at end of file diff --git a/DiscImageChef.Filters/OffsetStream.cs b/DiscImageChef.Filters/OffsetStream.cs index 96319f248..3d3260335 100644 --- a/DiscImageChef.Filters/OffsetStream.cs +++ b/DiscImageChef.Filters/OffsetStream.cs @@ -38,13 +38,13 @@ using Microsoft.Win32.SafeHandles; namespace DiscImageChef.Filters { /// - /// Creates a stream that is a subset of another stream. + /// Creates a stream that is a subset of another stream. /// public class OffsetStream : Stream { readonly Stream baseStream; - readonly long streamStart; readonly long streamEnd; + readonly long streamStart; public OffsetStream(Stream stream, long start, long end) { @@ -291,12 +291,6 @@ namespace DiscImageChef.Filters if(end > baseStream.Length) throw new ArgumentOutOfRangeException(nameof(end), "End is after stream end."); } - ~OffsetStream() - { - baseStream.Close(); - baseStream.Dispose(); - } - public override bool CanRead => baseStream.CanRead; public override bool CanSeek => baseStream.CanSeek; @@ -317,6 +311,12 @@ namespace DiscImageChef.Filters } } + ~OffsetStream() + { + baseStream.Close(); + baseStream.Dispose(); + } + public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state) { diff --git a/DiscImageChef.Filters/PCExchange.cs b/DiscImageChef.Filters/PCExchange.cs index 56ede6f05..50918e7c0 100644 --- a/DiscImageChef.Filters/PCExchange.cs +++ b/DiscImageChef.Filters/PCExchange.cs @@ -40,82 +40,22 @@ using System.Text; namespace DiscImageChef.Filters { /// - /// Decodes PCExchange files + /// Decodes PCExchange files /// public class PCExchange : Filter { const string FILE_ID = "FILEID.DAT"; const string FINDER_INFO = "FINDER.DAT"; const string RESOURCES = "RESOURCE.FRK"; - - [StructLayout(LayoutKind.Sequential, Pack = 1)] - struct PCExchangeEntry - { - /// - /// Name in Macintosh. If PCExchange version supports FAT's LFN they are the same. - /// Illegal characters for FAT get substituted with '_' both here and in FAT's LFN entry. - /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public byte[] macName; - /// - /// File type - /// - public uint type; - /// - /// File creator - /// - public uint creator; - /// - /// Finder flags - /// - public ushort fdFlags; - /// - /// File's icon vertical position within its window - /// - public ushort verticalPosition; - /// - /// File's icon horizontal position within its window - /// - public ushort horizontalPosition; - /// - /// Unknown, all bytes are empty but last, except in volume's label entry - /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 18)] public byte[] unknown1; - /// - /// File's creation date - /// - public uint creationDate; - /// - /// File's modification date - /// - public uint modificationDate; - /// - /// File's last backup date - /// - public uint backupDate; - /// - /// Unknown, but is unique, starts 0x7FFFFFFF and counts in reverse. - /// Probably file ID for alias look up? - /// - public uint unknown2; - /// - /// Name as in FAT entry (not LFN). - /// Resource fork file is always using this name, never LFN. - /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 11)] public byte[] dosName; - /// - /// Unknown, flags? - /// - public byte unknown3; - } - - bool opened; string basePath; - string dataPath; - string rsrcPath; - DateTime lastWriteTime; DateTime creationTime; long dataLen; + string dataPath; + DateTime lastWriteTime; + + bool opened; long rsrcLen; + string rsrcPath; public PCExchange() { @@ -203,7 +143,8 @@ namespace DiscImageChef.Filters { string parentFolder = Path.GetDirectoryName(path); - if(!File.Exists(Path.Combine(parentFolder ?? throw new InvalidOperationException(), FINDER_INFO))) return false; + if(!File.Exists(Path.Combine(parentFolder ?? throw new InvalidOperationException(), FINDER_INFO))) + return false; if(!Directory.Exists(Path.Combine(parentFolder, RESOURCES))) return false; @@ -233,9 +174,10 @@ namespace DiscImageChef.Filters if(baseFilename != macName && baseFilename != dosName && baseFilename != dosNameLow) continue; - dataFound |= File.Exists(Path.Combine(parentFolder, macName ?? throw new InvalidOperationException())) || - File.Exists(Path.Combine(parentFolder, dosName)) || - File.Exists(Path.Combine(parentFolder, dosNameLow)); + dataFound |= + File.Exists(Path.Combine(parentFolder, macName ?? throw new InvalidOperationException())) || + File.Exists(Path.Combine(parentFolder, dosName)) || + File.Exists(Path.Combine(parentFolder, dosNameLow)); rsrcFound |= File.Exists(Path.Combine(parentFolder, RESOURCES, dosName)) || File.Exists(Path.Combine(parentFolder, RESOURCES, dosNameLow)); @@ -269,7 +211,8 @@ namespace DiscImageChef.Filters string baseFilename = Path.GetFileName(path); FileStream finderDatStream = - new FileStream(Path.Combine(parentFolder ?? throw new InvalidOperationException(), FINDER_INFO), FileMode.Open, FileAccess.Read); + new FileStream(Path.Combine(parentFolder ?? throw new InvalidOperationException(), FINDER_INFO), + FileMode.Open, FileAccess.Read); while(finderDatStream.Position + 0x5C <= finderDatStream.Length) { @@ -288,7 +231,8 @@ namespace DiscImageChef.Filters if(baseFilename != macName && baseFilename != dosName && baseFilename != dosNameLow) continue; - if(File.Exists(Path.Combine(parentFolder, macName ?? throw new InvalidOperationException()))) dataPath = Path.Combine(parentFolder, macName); + if(File.Exists(Path.Combine(parentFolder, macName ?? throw new InvalidOperationException()))) + dataPath = Path.Combine(parentFolder, macName); else if(File.Exists(Path.Combine(parentFolder, dosName))) dataPath = Path.Combine(parentFolder, dosName); else if(File.Exists(Path.Combine(parentFolder, dosNameLow))) @@ -315,5 +259,65 @@ namespace DiscImageChef.Filters finderDatStream.Close(); } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + struct PCExchangeEntry + { + /// + /// Name in Macintosh. If PCExchange version supports FAT's LFN they are the same. + /// Illegal characters for FAT get substituted with '_' both here and in FAT's LFN entry. + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public byte[] macName; + /// + /// File type + /// + public uint type; + /// + /// File creator + /// + public uint creator; + /// + /// Finder flags + /// + public ushort fdFlags; + /// + /// File's icon vertical position within its window + /// + public ushort verticalPosition; + /// + /// File's icon horizontal position within its window + /// + public ushort horizontalPosition; + /// + /// Unknown, all bytes are empty but last, except in volume's label entry + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 18)] public byte[] unknown1; + /// + /// File's creation date + /// + public uint creationDate; + /// + /// File's modification date + /// + public uint modificationDate; + /// + /// File's last backup date + /// + public uint backupDate; + /// + /// Unknown, but is unique, starts 0x7FFFFFFF and counts in reverse. + /// Probably file ID for alias look up? + /// + public uint unknown2; + /// + /// Name as in FAT entry (not LFN). + /// Resource fork file is always using this name, never LFN. + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 11)] public byte[] dosName; + /// + /// Unknown, flags? + /// + public byte unknown3; + } } } \ No newline at end of file diff --git a/DiscImageChef.Filters/XZ.cs b/DiscImageChef.Filters/XZ.cs index 99ab8a559..5f62e30bc 100644 --- a/DiscImageChef.Filters/XZ.cs +++ b/DiscImageChef.Filters/XZ.cs @@ -37,17 +37,17 @@ using SharpCompress.Compressors.Xz; namespace DiscImageChef.Filters { /// - /// Decompress xz files while reading + /// Decompress xz files while reading /// public class XZ : Filter { - Stream dataStream; string basePath; - DateTime lastWriteTime; DateTime creationTime; - bool opened; + Stream dataStream; long decompressedSize; Stream innerStream; + DateTime lastWriteTime; + bool opened; public XZ() { @@ -242,7 +242,10 @@ namespace DiscImageChef.Filters { if(basePath?.EndsWith(".xz", StringComparison.InvariantCultureIgnoreCase) == true) return basePath.Substring(0, basePath.Length - 3); - return basePath?.EndsWith(".xzip", StringComparison.InvariantCultureIgnoreCase) == true ? basePath.Substring(0, basePath.Length - 5) : basePath; + + return basePath?.EndsWith(".xzip", StringComparison.InvariantCultureIgnoreCase) == true + ? basePath.Substring(0, basePath.Length - 5) + : basePath; } public override string GetParentFolder() diff --git a/DiscImageChef.Filters/ZZZNoFilter.cs b/DiscImageChef.Filters/ZZZNoFilter.cs index 983fdd0ad..e99667873 100644 --- a/DiscImageChef.Filters/ZZZNoFilter.cs +++ b/DiscImageChef.Filters/ZZZNoFilter.cs @@ -36,14 +36,14 @@ using System.IO; namespace DiscImageChef.Filters { /// - /// No filter for reading files not recognized by any filter + /// No filter for reading files not recognized by any filter /// public class ZZZNoFilter : Filter { - Stream dataStream; string basePath; - DateTime lastWriteTime; DateTime creationTime; + Stream dataStream; + DateTime lastWriteTime; bool opened; public ZZZNoFilter()