diff --git a/DiscImageChef.DiscImages/Alcohol120.cs b/DiscImageChef.DiscImages/Alcohol120.cs index b3b340a5..bedaa788 100644 --- a/DiscImageChef.DiscImages/Alcohol120.cs +++ b/DiscImageChef.DiscImages/Alcohol120.cs @@ -37,6 +37,7 @@ using System.Runtime.InteropServices; using DiscImageChef.CommonTypes; using DiscImageChef.Console; using System.Text; +using DiscImageChef.Filters; namespace DiscImageChef.ImagePlugins { @@ -162,10 +163,10 @@ namespace DiscImageChef.ImagePlugins Dictionary> alcToc; Dictionary alcTrackExtras; AlcoholFooter alcFooter; - string alcImage; + Filter alcImage; byte[] bca; List sessions; - FileStream imageStream; + Stream imageStream; byte[] fullToc; bool isDvd; byte[] dmi; @@ -202,9 +203,9 @@ namespace DiscImageChef.ImagePlugins ImageInfo.driveFirmwareRevision = null; } - public override bool IdentifyImage(string imagePath) + public override bool IdentifyImage(Filter imageFilter) { - FileStream stream = new FileStream(imagePath, FileMode.Open, FileAccess.Read); + Stream stream = imageFilter.GetDataForkStream(); stream.Seek(0, SeekOrigin.Begin); if(stream.Length < 88) return false; @@ -216,14 +217,13 @@ namespace DiscImageChef.ImagePlugins Marshal.Copy(hdr, 0, hdrPtr, 88); header = (AlcoholHeader)Marshal.PtrToStructure(hdrPtr, typeof(AlcoholHeader)); Marshal.FreeHGlobal(hdrPtr); - stream.Close(); return header.signature == "MEDIA DESCRIPTO"; } - public override bool OpenImage(string imagePath) + public override bool OpenImage(Filter imageFilter) { - FileStream stream = new FileStream(imagePath, FileMode.Open, FileAccess.Read); + Stream stream = imageFilter.GetDataForkStream(); stream.Seek(0, SeekOrigin.Begin); if(stream.Length < 88) return false; @@ -383,6 +383,8 @@ namespace DiscImageChef.ImagePlugins DicConsole.DebugWriteLine("Alcohol 120% plugin", "footer.unknown2 = 0x{0:X8}", alcFooter.unknown2); } + string alcFile = "*.mdf"; + if(alcFooter.filenameOffset > 0) { stream.Seek(alcFooter.filenameOffset, SeekOrigin.Begin); @@ -394,15 +396,15 @@ namespace DiscImageChef.ImagePlugins stream.Read(filename, 0, filename.Length); if(alcFooter.widechar == 1) - alcImage = Encoding.Unicode.GetString(filename); + alcFile = Encoding.Unicode.GetString(filename); else - alcImage = Encoding.Default.GetString(filename); + alcFile = Encoding.Default.GetString(filename); - DicConsole.DebugWriteLine("Alcohol 120% plugin", "footer.filename = {0}", alcImage); + DicConsole.DebugWriteLine("Alcohol 120% plugin", "footer.filename = {0}", alcFile); } - if(alcFooter.filenameOffset == 0 || string.Compare(alcImage, "*.mdf", StringComparison.InvariantCultureIgnoreCase) == 0) - alcImage = Path.GetFileNameWithoutExtension(imagePath) + ".mdf"; + if(alcFooter.filenameOffset == 0 || string.Compare(alcFile, "*.mdf", StringComparison.InvariantCultureIgnoreCase) == 0) + alcFile = Path.GetFileNameWithoutExtension(imageFilter.GetBasePath()) + ".mdf"; if(header.bcaLength > 0 && header.bcaOffset > 0 && isDvd) { @@ -558,8 +560,6 @@ namespace DiscImageChef.ImagePlugins DicConsole.DebugWriteLine("Alcohol 120% plugin", "ImageInfo.mediaType = {0}", ImageInfo.mediaType); - stream.Close(); - sessions = new List(); foreach(AlcoholSession alcSes in alcSessions.Values) { @@ -676,12 +676,17 @@ namespace DiscImageChef.ImagePlugins ImageInfo.imageApplication = "Alcohol 120%"; - DicConsole.DebugWriteLine("Alcohol 120% plugin", "Data filename: {0}", alcImage); + DicConsole.DebugWriteLine("Alcohol 120% plugin", "Data filename: {0}", alcFile); - FileInfo fi = new FileInfo(alcImage); - ImageInfo.imageSize = (ulong)fi.Length; - ImageInfo.imageCreationTime = fi.CreationTimeUtc; - ImageInfo.imageLastModificationTime = fi.LastWriteTimeUtc; + FiltersList filtersList = new FiltersList(); + alcImage = filtersList.GetFilter(alcFile); + + if(alcImage == null) + throw new Exception("Cannot open data file"); + + ImageInfo.imageSize = (ulong)alcImage.GetDataForkLength(); + ImageInfo.imageCreationTime = alcImage.GetCreationTime(); + ImageInfo.imageLastModificationTime = alcImage.GetLastWriteTime(); ImageInfo.xmlMediaType = XmlMediaType.OpticalDisc; ImageInfo.imageVersion = string.Format("{0}.{1}", header.version[0], header.version[1]); @@ -942,22 +947,20 @@ namespace DiscImageChef.ImagePlugins byte[] buffer = new byte[sector_size * length]; - imageStream = new FileStream(alcImage, FileMode.Open, FileAccess.Read); - using(BinaryReader br = new BinaryReader(imageStream)) + imageStream = alcImage.GetDataForkStream(); + BinaryReader br = new BinaryReader(imageStream); + br.BaseStream.Seek((long)_track.startOffset + (long)(sectorAddress * (sector_offset + sector_size + sector_skip)), SeekOrigin.Begin); + if(sector_offset == 0 && sector_skip == 0) + buffer = br.ReadBytes((int)(sector_size * length)); + else { - br.BaseStream.Seek((long)_track.startOffset + (long)(sectorAddress * (sector_offset + sector_size + sector_skip)), SeekOrigin.Begin); - if(sector_offset == 0 && sector_skip == 0) - buffer = br.ReadBytes((int)(sector_size * length)); - else + for(int i = 0; i < length; i++) { - for(int i = 0; i < length; i++) - { - byte[] sector; - br.BaseStream.Seek(sector_offset, SeekOrigin.Current); - sector = br.ReadBytes((int)sector_size); - br.BaseStream.Seek(sector_skip, SeekOrigin.Current); - Array.Copy(sector, 0, buffer, i * sector_size, sector_size); - } + byte[] sector; + br.BaseStream.Seek(sector_offset, SeekOrigin.Current); + sector = br.ReadBytes((int)sector_size); + br.BaseStream.Seek(sector_skip, SeekOrigin.Current); + Array.Copy(sector, 0, buffer, i * sector_size, sector_size); } } @@ -1275,22 +1278,20 @@ namespace DiscImageChef.ImagePlugins byte[] buffer = new byte[sector_size * length]; - imageStream = new FileStream(alcImage, FileMode.Open, FileAccess.Read); - using(BinaryReader br = new BinaryReader(imageStream)) + imageStream = alcImage.GetDataForkStream(); + BinaryReader br = new BinaryReader(imageStream); + br.BaseStream.Seek((long)_track.startOffset + (long)(sectorAddress * (sector_offset + sector_size + sector_skip)), SeekOrigin.Begin); + if(sector_offset == 0 && sector_skip == 0) + buffer = br.ReadBytes((int)(sector_size * length)); + else { - br.BaseStream.Seek((long)_track.startOffset + (long)(sectorAddress * (sector_offset + sector_size + sector_skip)), SeekOrigin.Begin); - if(sector_offset == 0 && sector_skip == 0) - buffer = br.ReadBytes((int)(sector_size * length)); - else + for(int i = 0; i < length; i++) { - for(int i = 0; i < length; i++) - { - byte[] sector; - br.BaseStream.Seek(sector_offset, SeekOrigin.Current); - sector = br.ReadBytes((int)sector_size); - br.BaseStream.Seek(sector_skip, SeekOrigin.Current); - Array.Copy(sector, 0, buffer, i * sector_size, sector_size); - } + byte[] sector; + br.BaseStream.Seek(sector_offset, SeekOrigin.Current); + sector = br.ReadBytes((int)sector_size); + br.BaseStream.Seek(sector_skip, SeekOrigin.Current); + Array.Copy(sector, 0, buffer, i * sector_size, sector_size); } } @@ -1364,12 +1365,10 @@ namespace DiscImageChef.ImagePlugins byte[] buffer = new byte[sector_size * length]; - imageStream = new FileStream(alcImage, FileMode.Open, FileAccess.Read); - using(BinaryReader br = new BinaryReader(imageStream)) - { - br.BaseStream.Seek((long)_track.startOffset + (long)(sectorAddress * (sector_offset + sector_size + sector_skip)), SeekOrigin.Begin); - buffer = br.ReadBytes((int)(sector_size * length)); - } + imageStream = alcImage.GetDataForkStream(); + BinaryReader br = new BinaryReader(imageStream); + br.BaseStream.Seek((long)_track.startOffset + (long)(sectorAddress * (sector_offset + sector_size + sector_skip)), SeekOrigin.Begin); + buffer = br.ReadBytes((int)(sector_size * length)); return buffer; } @@ -1430,7 +1429,8 @@ namespace DiscImageChef.ImagePlugins _track.TrackSession = sessionNo; _track.TrackSequence = track.point; _track.TrackType = AlcoholTrackTypeToTrackType(track.mode); - _track.TrackFile = alcImage; + _track.TrackFilter = alcImage; + _track.TrackFile = alcImage.GetFilename(); _track.TrackFileOffset = track.startOffset; _track.TrackFileType = "BINARY"; _track.TrackRawBytesPerSector = track.sectorSize; @@ -1438,7 +1438,8 @@ namespace DiscImageChef.ImagePlugins switch(track.subMode) { case AlcoholSubchannelMode.Interleaved: - _track.TrackSubchannelFile = alcImage; + _track.TrackSubchannelFilter = alcImage; + _track.TrackSubchannelFile = alcImage.GetFilename(); _track.TrackSubchannelOffset = track.startOffset; _track.TrackSubchannelType = TrackSubchannelType.RawInterleaved; _track.TrackRawBytesPerSector += 96; @@ -1495,7 +1496,8 @@ namespace DiscImageChef.ImagePlugins _track.TrackSession = sessionNo; _track.TrackSequence = track.point; _track.TrackType = AlcoholTrackTypeToTrackType(track.mode); - _track.TrackFile = alcImage; + _track.TrackFilter = alcImage; + _track.TrackFile = alcImage.GetFilename(); _track.TrackFileOffset = track.startOffset; _track.TrackFileType = "BINARY"; _track.TrackRawBytesPerSector = track.sectorSize; @@ -1503,7 +1505,8 @@ namespace DiscImageChef.ImagePlugins switch(track.subMode) { case AlcoholSubchannelMode.Interleaved: - _track.TrackSubchannelFile = alcImage; + _track.TrackSubchannelFilter = alcImage; + _track.TrackSubchannelFile = alcImage.GetFilename(); _track.TrackSubchannelOffset = track.startOffset; _track.TrackSubchannelType = TrackSubchannelType.RawInterleaved; _track.TrackRawBytesPerSector += 96; diff --git a/DiscImageChef.DiscImages/Apple2MG.cs b/DiscImageChef.DiscImages/Apple2MG.cs index 8fc45db2..15bf8ef4 100644 --- a/DiscImageChef.DiscImages/Apple2MG.cs +++ b/DiscImageChef.DiscImages/Apple2MG.cs @@ -36,6 +36,7 @@ using System.IO; using System.Text; using DiscImageChef.Console; using DiscImageChef.CommonTypes; +using DiscImageChef.Filters; namespace DiscImageChef.ImagePlugins { @@ -166,7 +167,7 @@ namespace DiscImageChef.ImagePlugins #region Internal variables A2IMGHeader ImageHeader; - string a2mgImagePath; + Filter a2mgImageFilter; #endregion @@ -197,9 +198,9 @@ namespace DiscImageChef.ImagePlugins ImageInfo.driveFirmwareRevision = null; } - public override bool IdentifyImage(string imagePath) + public override bool IdentifyImage(Filter imageFilter) { - FileStream stream = new FileStream(imagePath, FileMode.Open, FileAccess.Read); + Stream stream = imageFilter.GetDataForkStream(); stream.Seek(0, SeekOrigin.Begin); if(stream.Length < 65) @@ -239,9 +240,9 @@ namespace DiscImageChef.ImagePlugins return creatoroff + creatorsize <= stream.Length; } - public override bool OpenImage(string imagePath) + public override bool OpenImage(Filter imageFilter) { - FileStream stream = new FileStream(imagePath, FileMode.Open, FileAccess.Read); + Stream stream = imageFilter.GetDataForkStream(); stream.Seek(0, SeekOrigin.Begin); ImageHeader = new A2IMGHeader(); @@ -354,14 +355,11 @@ namespace DiscImageChef.ImagePlugins ImageInfo.imageComments = Encoding.ASCII.GetString(comments); } - FileInfo fi = new FileInfo(imagePath); - ImageInfo.imageCreationTime = fi.CreationTimeUtc; - ImageInfo.imageLastModificationTime = fi.LastWriteTimeUtc; - ImageInfo.imageName = Path.GetFileNameWithoutExtension(imagePath); + ImageInfo.imageCreationTime = imageFilter.GetCreationTime(); + ImageInfo.imageLastModificationTime = imageFilter.GetLastWriteTime(); + ImageInfo.imageName = Path.GetFileNameWithoutExtension(imageFilter.GetFilename()); - stream.Close(); - - a2mgImagePath = imagePath; + a2mgImageFilter = imageFilter; ImageInfo.xmlMediaType = XmlMediaType.BlockMedia; @@ -473,14 +471,12 @@ namespace DiscImageChef.ImagePlugins byte[] buffer = new byte[length * ImageInfo.sectorSize]; - FileStream stream = new FileStream(a2mgImagePath, FileMode.Open, FileAccess.Read); + Stream stream = a2mgImageFilter.GetDataForkStream(); stream.Seek((long)(ImageHeader.dataOffset + sectorAddress * ImageInfo.sectorSize), SeekOrigin.Begin); stream.Read(buffer, 0, (int)(length * ImageInfo.sectorSize)); - stream.Close(); - return buffer; } diff --git a/DiscImageChef.DiscImages/BLU.cs b/DiscImageChef.DiscImages/BLU.cs index e2f3626f..c5150edc 100644 --- a/DiscImageChef.DiscImages/BLU.cs +++ b/DiscImageChef.DiscImages/BLU.cs @@ -35,6 +35,7 @@ using System.Collections.Generic; using System.IO; using DiscImageChef.Console; using DiscImageChef.CommonTypes; +using DiscImageChef.Filters; namespace DiscImageChef.ImagePlugins { @@ -60,7 +61,7 @@ namespace DiscImageChef.ImagePlugins #region Internal variables BLUHeader ImageHeader; - string bluImagePath; + Filter bluImageFilter; int bptag; #endregion Internal variables @@ -93,9 +94,9 @@ namespace DiscImageChef.ImagePlugins ImageInfo.driveFirmwareRevision = null; } - public override bool IdentifyImage(string imagePath) + public override bool IdentifyImage(Filter imageFilter) { - FileStream stream = new FileStream(imagePath, FileMode.Open, FileAccess.Read); + Stream stream = imageFilter.GetDataForkStream(); stream.Seek(0, SeekOrigin.Begin); if(stream.Length < 0x200) @@ -125,9 +126,9 @@ namespace DiscImageChef.ImagePlugins return true; } - public override bool OpenImage(string imagePath) + public override bool OpenImage(Filter imageFilter) { - FileStream stream = new FileStream(imagePath, FileMode.Open, FileAccess.Read); + Stream stream = imageFilter.GetDataForkStream(); stream.Seek(0, SeekOrigin.Begin); ImageHeader = new BLUHeader(); @@ -201,14 +202,11 @@ namespace DiscImageChef.ImagePlugins ImageInfo.imageApplication = StringHandlers.CToString(hdrTag); - FileInfo fi = new FileInfo(imagePath); - ImageInfo.imageCreationTime = fi.CreationTimeUtc; - ImageInfo.imageLastModificationTime = fi.LastWriteTimeUtc; - ImageInfo.imageName = Path.GetFileNameWithoutExtension(imagePath); + ImageInfo.imageCreationTime = imageFilter.GetCreationTime(); + ImageInfo.imageLastModificationTime = imageFilter.GetLastWriteTime(); + ImageInfo.imageName = Path.GetFileNameWithoutExtension(imageFilter.GetFilename()); - stream.Close(); - - bluImagePath = imagePath; + bluImageFilter = imageFilter; ImageInfo.xmlMediaType = XmlMediaType.BlockMedia; @@ -302,7 +300,7 @@ namespace DiscImageChef.ImagePlugins int read = 0x200; int skip = bptag; - FileStream stream = new FileStream(bluImagePath, FileMode.Open, FileAccess.Read); + Stream stream = bluImageFilter.GetDataForkStream(); stream.Seek((long)((sectorAddress + 1) * ImageHeader.bytesPerBlock), SeekOrigin.Begin); for(int i = 0; i < length; i++) @@ -314,7 +312,6 @@ namespace DiscImageChef.ImagePlugins stream.Seek(skip, SeekOrigin.Current); } - stream.Close(); return buffer.ToArray(); } @@ -337,7 +334,7 @@ namespace DiscImageChef.ImagePlugins int read = bptag; int skip = 0; - FileStream stream = new FileStream(bluImagePath, FileMode.Open, FileAccess.Read); + Stream stream = bluImageFilter.GetDataForkStream(); stream.Seek((long)((sectorAddress + 1) * ImageHeader.bytesPerBlock), SeekOrigin.Begin); for(int i = 0; i < length; i++) @@ -349,7 +346,6 @@ namespace DiscImageChef.ImagePlugins stream.Seek(skip, SeekOrigin.Current); } - stream.Close(); return buffer.ToArray(); } @@ -367,10 +363,9 @@ namespace DiscImageChef.ImagePlugins throw new ArgumentOutOfRangeException(nameof(length), "Requested more sectors than available"); byte[] buffer = new byte[length * ImageHeader.bytesPerBlock]; - FileStream stream = new FileStream(bluImagePath, FileMode.Open, FileAccess.Read); + Stream stream = bluImageFilter.GetDataForkStream(); stream.Seek((long)((sectorAddress + 1) * ImageHeader.bytesPerBlock), SeekOrigin.Begin); stream.Read(buffer, 0, buffer.Length); - stream.Close(); return buffer; } diff --git a/DiscImageChef.DiscImages/BlindWrite4.cs b/DiscImageChef.DiscImages/BlindWrite4.cs index 353b1644..e7b6b500 100644 --- a/DiscImageChef.DiscImages/BlindWrite4.cs +++ b/DiscImageChef.DiscImages/BlindWrite4.cs @@ -39,6 +39,7 @@ using System.Text; using DiscImageChef.Console; using System.Runtime.InteropServices; using System.Globalization; +using DiscImageChef.Filters; namespace DiscImageChef.ImagePlugins { @@ -74,6 +75,8 @@ namespace DiscImageChef.ImagePlugins public string volumeIdentifier; public string systemIdentifier; public string comments; + public Filter dataFilter; + public Filter subchannelFilter; public string dataFile; public string subchannelFile; } @@ -175,8 +178,8 @@ namespace DiscImageChef.ImagePlugins Dictionary offsetmap; List partitions; List sessions; - string dataFile, subFile; - FileStream imageStream; + Filter dataFilter, subFilter; + Stream imageStream; Dictionary trackFlags; #endregion Internal variables @@ -205,9 +208,9 @@ namespace DiscImageChef.ImagePlugins ImageInfo.driveFirmwareRevision = null; } - public override bool IdentifyImage(string imagePath) + public override bool IdentifyImage(Filter imageFilter) { - FileStream stream = new FileStream(imagePath, FileMode.Open, FileAccess.Read); + Stream stream = imageFilter.GetDataForkStream(); stream.Seek(0, SeekOrigin.Begin); if(stream.Length < 19) return false; @@ -215,14 +218,12 @@ namespace DiscImageChef.ImagePlugins byte[] signature = new byte[19]; stream.Read(signature, 0, 19); - stream.Close(); - return BW4_Signature.SequenceEqual(signature); } - public override bool OpenImage(string imagePath) + public override bool OpenImage(Filter imageFilter) { - FileStream stream = new FileStream(imagePath, FileMode.Open, FileAccess.Read); + Stream stream = imageFilter.GetDataForkStream(); stream.Seek(0, SeekOrigin.Begin); if(stream.Length < 19) return false; @@ -303,8 +304,10 @@ namespace DiscImageChef.ImagePlugins DicConsole.DebugWriteLine("BlindWrite4 plugin", "header.comments = {0}", header.comments); DicConsole.DebugWriteLine("BlindWrite4 plugin", "header.trackDescriptors = {0}", header.trackDescriptors); DicConsole.DebugWriteLine("BlindWrite4 plugin", "header.dataFileLength = {0}", header.dataFileLength); + DicConsole.DebugWriteLine("BlindWrite4 plugin", "header.dataFilter = {0}", header.dataFilter); DicConsole.DebugWriteLine("BlindWrite4 plugin", "header.dataFile = {0}", header.dataFile); DicConsole.DebugWriteLine("BlindWrite4 plugin", "header.subchannelFileLength = {0}", header.subchannelFileLength); + DicConsole.DebugWriteLine("BlindWrite4 plugin", "header.subchannelFilter = {0}", header.subchannelFilter); DicConsole.DebugWriteLine("BlindWrite4 plugin", "header.subchannelFile = {0}", header.subchannelFile); DicConsole.DebugWriteLine("BlindWrite4 plugin", "header.unknown2 = {0}", header.unknown2); DicConsole.DebugWriteLine("BlindWrite4 plugin", "header.unknown3 = {0}", header.unknown3); @@ -536,32 +539,40 @@ namespace DiscImageChef.ImagePlugins bwTracks.Add(track); } + FiltersList filtersList = new FiltersList(); + if(!string.IsNullOrEmpty(header.dataFile)) { while(true) { - dataFile = header.dataFile; - if(File.Exists(dataFile)) + dataFilter = filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), + header.dataFile)); + if(dataFilter != null) break; - dataFile = header.dataFile.ToLower(CultureInfo.CurrentCulture); - if(File.Exists(dataFile)) + dataFilter = filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), + header.dataFile.ToLower(CultureInfo.CurrentCulture))); + if(dataFilter != null) break; - dataFile = header.dataFile.ToUpper(CultureInfo.CurrentCulture); - if(File.Exists(dataFile)) + dataFilter = filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), + header.dataFile.ToUpper(CultureInfo.CurrentCulture))); + if(dataFilter != null) break; - dataFile = header.dataFile.Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries).Last(); - if(File.Exists(dataFile)) + dataFilter = filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), + header.dataFile.Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries).Last())); + if(dataFilter != null) break; - dataFile = header.dataFile.Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries).Last().ToLower(CultureInfo.CurrentCulture); - if(File.Exists(dataFile)) + dataFilter = filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), + header.dataFile.Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries).Last().ToLower(CultureInfo.CurrentCulture))); + if(dataFilter != null) break; - dataFile = header.dataFile.Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries).Last().ToUpper(CultureInfo.CurrentCulture); - if(File.Exists(dataFile)) + dataFilter = filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), + header.dataFile.Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries).Last().ToUpper(CultureInfo.CurrentCulture))); + if(dataFilter != null) break; throw new ArgumentException(string.Format("Data file {0} not found", header.dataFile)); @@ -570,35 +581,42 @@ namespace DiscImageChef.ImagePlugins else throw new ArgumentException("Unable to find data file"); - if(!string.IsNullOrEmpty(header.dataFile)) + if(!string.IsNullOrEmpty(header.subchannelFile)) { do { - subFile = header.subchannelFile; - if(File.Exists(subFile)) + subFilter = filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), + header.subchannelFile)); + if(subFilter != null) break; - subFile = header.subchannelFile.ToLower(CultureInfo.CurrentCulture); - if(File.Exists(subFile)) + subFilter = filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), + header.subchannelFile.ToLower(CultureInfo.CurrentCulture))); + if(subFilter != null) break; - subFile = header.subchannelFile.ToUpper(CultureInfo.CurrentCulture); - if(File.Exists(subFile)) + subFilter = filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), + header.subchannelFile.ToUpper(CultureInfo.CurrentCulture))); + if(subFilter != null) break; - subFile = header.subchannelFile.Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries).Last(); - if(File.Exists(subFile)) + subFilter = filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), + header.subchannelFile.Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries).Last())); + if(subFilter != null) break; - subFile = header.subchannelFile.Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries).Last().ToLower(CultureInfo.CurrentCulture); - if(File.Exists(subFile)) + subFilter = filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), + header.subchannelFile.Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries).Last().ToLower(CultureInfo.CurrentCulture))); + if(subFilter != null) break; - subFile = header.subchannelFile.Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries).Last().ToUpper(CultureInfo.CurrentCulture); - if(File.Exists(subFile)) + subFilter = filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), + header.subchannelFile.Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries).Last().ToUpper(CultureInfo.CurrentCulture))); + if(subFilter != null) break; - subFile = null; + subFilter = null; + break; } while(true); } @@ -621,37 +639,42 @@ namespace DiscImageChef.ImagePlugins { do { - track.TrackFile = bwTrack.filename; - if(File.Exists(track.TrackFile)) + track.TrackFilter = filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), + bwTrack.filename)); + if(track.TrackFilter != null) break; - track.TrackFile = bwTrack.filename.ToLower(CultureInfo.CurrentCulture); - if(File.Exists(track.TrackFile)) + track.TrackFilter = filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), + bwTrack.filename.ToLower(CultureInfo.CurrentCulture))); + if(track.TrackFilter != null) break; - track.TrackFile = bwTrack.filename.ToUpper(CultureInfo.CurrentCulture); - if(File.Exists(track.TrackFile)) + track.TrackFilter = filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), + bwTrack.filename.ToUpper(CultureInfo.CurrentCulture))); + if(track.TrackFilter != null) break; - track.TrackFile = bwTrack.filename.Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries).Last(); - if(File.Exists(track.TrackFile)) + track.TrackFilter = filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), + bwTrack.filename.Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries).Last())); + if(track.TrackFilter != null) break; - track.TrackFile = bwTrack.filename.Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries).Last().ToLower(CultureInfo.CurrentCulture); - if(File.Exists(track.TrackFile)) + track.TrackFilter = filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), + bwTrack.filename.Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries).Last().ToLower(CultureInfo.CurrentCulture))); + if(track.TrackFilter != null) break; - track.TrackFile = bwTrack.filename.Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries).Last().ToUpper(CultureInfo.CurrentCulture); - if(File.Exists(track.TrackFile)) - break; + track.TrackFilter = filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), + bwTrack.filename.Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries).Last().ToUpper(CultureInfo.CurrentCulture))); - track.TrackFile = dataFile; + track.TrackFilter = dataFilter; } while(true); } else - track.TrackFile = dataFile; + track.TrackFilter = dataFilter; + track.TrackFile = dataFilter.GetFilename(); track.TrackFileOffset = bwTrack.offset; if(bwTrack.pregap > 0) track.TrackFileOffset += (ulong)(bwTrack.startSector - bwTrack.pregap) * 2352; @@ -663,9 +686,10 @@ namespace DiscImageChef.ImagePlugins if(track.TrackSession > maxSession) maxSession = track.TrackSession; track.TrackStartSector = (ulong)bwTrack.startSector; - track.TrackSubchannelFile = subFile; + track.TrackSubchannelFilter = subFilter; + track.TrackSubchannelFile = subFilter.GetFilename(); track.TrackSubchannelOffset = track.TrackStartSector / 96; - if(!string.IsNullOrEmpty(track.TrackSubchannelFile) && bwTrack.subchannel > 0) + if(subFilter != null && bwTrack.subchannel > 0) { track.TrackSubchannelType = TrackSubchannelType.Packed; if(!ImageInfo.readableSectorTags.Contains(SectorTagType.CDSectorSubchannel)) @@ -790,10 +814,9 @@ namespace DiscImageChef.ImagePlugins ImageInfo.imageApplicationVersion = "4"; ImageInfo.imageVersion = "4"; - FileInfo fi = new FileInfo(dataFile); - ImageInfo.imageSize = (ulong)fi.Length; - ImageInfo.imageCreationTime = fi.CreationTimeUtc; - ImageInfo.imageLastModificationTime = fi.LastWriteTimeUtc; + ImageInfo.imageSize = (ulong)dataFilter.GetDataForkLength(); + ImageInfo.imageCreationTime = dataFilter.GetCreationTime(); + ImageInfo.imageLastModificationTime = dataFilter.GetLastWriteTime(); ImageInfo.xmlMediaType = XmlMediaType.OpticalDisc; bool data = false; @@ -1002,25 +1025,22 @@ namespace DiscImageChef.ImagePlugins byte[] buffer = new byte[sector_size * length]; - imageStream = new FileStream(_track.TrackFile, FileMode.Open, FileAccess.Read); - using(BinaryReader br = new BinaryReader(imageStream)) + imageStream = _track.TrackFilter.GetDataForkStream(); + BinaryReader br = new BinaryReader(imageStream); + br.BaseStream.Seek((long)_track.TrackFileOffset + (long)(sectorAddress * (sector_offset + sector_size + sector_skip)), SeekOrigin.Begin); + if(sector_offset == 0 && sector_skip == 0) + buffer = br.ReadBytes((int)(sector_size * length)); + else { - br.BaseStream.Seek((long)_track.TrackFileOffset + (long)(sectorAddress * (sector_offset + sector_size + sector_skip)), SeekOrigin.Begin); - if(sector_offset == 0 && sector_skip == 0) - buffer = br.ReadBytes((int)(sector_size * length)); - else + for(int i = 0; i < length; i++) { - for(int i = 0; i < length; i++) - { - byte[] sector; - br.BaseStream.Seek(sector_offset, SeekOrigin.Current); - sector = br.ReadBytes((int)sector_size); - br.BaseStream.Seek(sector_skip, SeekOrigin.Current); - Array.Copy(sector, 0, buffer, i * sector_size, sector_size); - } + byte[] sector; + br.BaseStream.Seek(sector_offset, SeekOrigin.Current); + sector = br.ReadBytes((int)sector_size); + br.BaseStream.Seek(sector_skip, SeekOrigin.Current); + Array.Copy(sector, 0, buffer, i * sector_size, sector_size); } } - imageStream.Close(); return buffer; } @@ -1175,25 +1195,22 @@ namespace DiscImageChef.ImagePlugins byte[] buffer = new byte[sector_size * length]; - imageStream = new FileStream(_track.TrackFile, FileMode.Open, FileAccess.Read); - using(BinaryReader br = new BinaryReader(imageStream)) + imageStream = _track.TrackFilter.GetDataForkStream(); + BinaryReader br = new BinaryReader(imageStream); + br.BaseStream.Seek((long)_track.TrackFileOffset + (long)(sectorAddress * (sector_offset + sector_size + sector_skip)), SeekOrigin.Begin); + if(sector_offset == 0 && sector_skip == 0) + buffer = br.ReadBytes((int)(sector_size * length)); + else { - br.BaseStream.Seek((long)_track.TrackFileOffset + (long)(sectorAddress * (sector_offset + sector_size + sector_skip)), SeekOrigin.Begin); - if(sector_offset == 0 && sector_skip == 0) - buffer = br.ReadBytes((int)(sector_size * length)); - else + for(int i = 0; i < length; i++) { - for(int i = 0; i < length; i++) - { - byte[] sector; - br.BaseStream.Seek(sector_offset, SeekOrigin.Current); - sector = br.ReadBytes((int)sector_size); - br.BaseStream.Seek(sector_skip, SeekOrigin.Current); - Array.Copy(sector, 0, buffer, i * sector_size, sector_size); - } + byte[] sector; + br.BaseStream.Seek(sector_offset, SeekOrigin.Current); + sector = br.ReadBytes((int)sector_size); + br.BaseStream.Seek(sector_skip, SeekOrigin.Current); + Array.Copy(sector, 0, buffer, i * sector_size, sector_size); } } - imageStream.Close(); return buffer; } @@ -1271,13 +1288,10 @@ namespace DiscImageChef.ImagePlugins byte[] buffer = new byte[sector_size * length]; - imageStream = new FileStream(_track.TrackFile, FileMode.Open, FileAccess.Read); - using(BinaryReader br = new BinaryReader(imageStream)) - { - br.BaseStream.Seek((long)_track.TrackFileOffset + (long)(sectorAddress * (sector_offset + sector_size + sector_skip)), SeekOrigin.Begin); - buffer = br.ReadBytes((int)(sector_size * length)); - } - imageStream.Close(); + imageStream = _track.TrackFilter.GetDataForkStream(); + BinaryReader br = new BinaryReader(imageStream); + br.BaseStream.Seek((long)_track.TrackFileOffset + (long)(sectorAddress * (sector_offset + sector_size + sector_skip)), SeekOrigin.Begin); + buffer = br.ReadBytes((int)(sector_size * length)); return buffer; } diff --git a/DiscImageChef.DiscImages/BlindWrite5.cs b/DiscImageChef.DiscImages/BlindWrite5.cs index 02adcdbf..ce28436b 100644 --- a/DiscImageChef.DiscImages/BlindWrite5.cs +++ b/DiscImageChef.DiscImages/BlindWrite5.cs @@ -40,6 +40,7 @@ using DiscImageChef.Console; using DiscImageChef.Decoders.SCSI.MMC; using System.Text; using System.Globalization; +using DiscImageChef.Filters; namespace DiscImageChef.ImagePlugins { @@ -186,6 +187,7 @@ namespace DiscImageChef.ImagePlugins struct DataFileCharacteristics { + public Filter fileFilter; public string filePath; public TrackSubchannelType subchannel; public long sectorSize; @@ -216,7 +218,7 @@ namespace DiscImageChef.ImagePlugins byte[] fullToc; Dictionary offsetmap; Dictionary trackFlags; - FileStream imageStream; + Stream imageStream; #endregion Internal variables #region Public Methods @@ -244,9 +246,9 @@ namespace DiscImageChef.ImagePlugins ImageInfo.driveFirmwareRevision = null; } - public override bool IdentifyImage(string imagePath) + public override bool IdentifyImage(Filter imageFilter) { - FileStream stream = new FileStream(imagePath, FileMode.Open, FileAccess.Read); + Stream stream = imageFilter.GetDataForkStream(); stream.Seek(0, SeekOrigin.Begin); if(stream.Length < 276) return false; @@ -258,14 +260,12 @@ namespace DiscImageChef.ImagePlugins stream.Seek(-16, SeekOrigin.End); stream.Read(footer, 0, 16); - stream.Close(); - return BW5_Signature.SequenceEqual(signature) && BW5_Footer.SequenceEqual(footer); } - public override bool OpenImage(string imagePath) + public override bool OpenImage(Filter imageFilter) { - FileStream stream = new FileStream(imagePath, FileMode.Open, FileAccess.Read); + Stream stream = imageFilter.GetDataForkStream(); stream.Seek(0, SeekOrigin.Begin); if(stream.Length < 276) return false; @@ -590,7 +590,7 @@ namespace DiscImageChef.ImagePlugins else DicConsole.ErrorWriteLine("BlindWrite5 image ends after expected position. Probably new version with different data. Errors may occur."); - stream.Close(); + FiltersList filtersList = new FiltersList(); filePaths = new List(); foreach(BW5_DataFile dataFile in dataFiles) @@ -598,60 +598,70 @@ namespace DiscImageChef.ImagePlugins DataFileCharacteristics chars = new DataFileCharacteristics(); string path = Path.Combine(dataPath, dataFile.filename); - if(File.Exists(path)) + if(filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), path)) != null) { + chars.fileFilter = filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), path)); chars.filePath = path; } else { path = Path.Combine(dataPath, dataFile.filename.ToLower(CultureInfo.CurrentCulture)); - if(File.Exists(path)) + if(filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), path)) != null) { + chars.fileFilter = filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), path)); chars.filePath = path; } else { path = Path.Combine(dataPath, dataFile.filename.ToUpper(CultureInfo.CurrentCulture)); - if(File.Exists(path)) + if(filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), path)) != null) { + chars.fileFilter = filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), path)); chars.filePath = path; } else { path = Path.Combine(dataPath.ToLower(CultureInfo.CurrentCulture), dataFile.filename); - if(File.Exists(path)) + if(filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), path)) != null) { + chars.fileFilter = filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), path)); chars.filePath = path; } else { path = Path.Combine(dataPath.ToUpper(CultureInfo.CurrentCulture), dataFile.filename); - if(File.Exists(path)) + if(filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), path)) != null) { + chars.fileFilter = filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), path)); chars.filePath = path; } else { path = Path.Combine(dataPath, dataFile.filename); - if(File.Exists(path.ToLower(CultureInfo.CurrentCulture))) + if(filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), path.ToLower(CultureInfo.CurrentCulture))) != null) { chars.filePath = path.ToLower(CultureInfo.CurrentCulture); + chars.fileFilter = filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), path.ToLower(CultureInfo.CurrentCulture))); } - else if(File.Exists(path.ToUpper(CultureInfo.CurrentCulture))) + else if(filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), path.ToUpper(CultureInfo.CurrentCulture))) != null) { chars.filePath = path.ToUpper(CultureInfo.CurrentCulture); + chars.fileFilter = filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), path.ToUpper(CultureInfo.CurrentCulture))); } - else if(File.Exists(dataFile.filename.ToLower(CultureInfo.CurrentCulture))) + else if(filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), dataFile.filename.ToLower(CultureInfo.CurrentCulture))) != null) { chars.filePath = dataFile.filename.ToLower(CultureInfo.CurrentCulture); + chars.fileFilter = filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), dataFile.filename.ToLower(CultureInfo.CurrentCulture))); } - else if(File.Exists(dataFile.filename.ToUpper(CultureInfo.CurrentCulture))) + else if(filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), dataFile.filename.ToUpper(CultureInfo.CurrentCulture))) != null) { chars.filePath = dataFile.filename.ToUpper(CultureInfo.CurrentCulture); + chars.fileFilter = filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), dataFile.filename.ToUpper(CultureInfo.CurrentCulture))); } - else if(File.Exists(dataFile.filename)) + else if(filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), dataFile.filename)) != null) { chars.filePath = dataFile.filename; + chars.fileFilter = filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), dataFile.filename)); } else { @@ -809,7 +819,8 @@ namespace DiscImageChef.ImagePlugins { if(trk.startLba >= chars.startLba && (trk.startLba + trk.sectors) <= (chars.startLba + chars.sectors)) { - track.TrackFile = Path.GetFileName(chars.filePath); + track.TrackFilter = chars.fileFilter; + track.TrackFile = chars.fileFilter.GetFilename(); if(trk.startLba >= 0) track.TrackFileOffset = (ulong)((trk.startLba - chars.startLba) * chars.sectorSize); else @@ -817,6 +828,7 @@ namespace DiscImageChef.ImagePlugins track.TrackFileType = "BINARY"; if(chars.subchannel != TrackSubchannelType.None) { + track.TrackSubchannelFilter = track.TrackFilter; track.TrackSubchannelFile = track.TrackFile; track.TrackSubchannelType = chars.subchannel; track.TrackSubchannelOffset = track.TrackFileOffset; @@ -1026,16 +1038,15 @@ namespace DiscImageChef.ImagePlugins ImageInfo.driveModel = StringHandlers.CToString(header.product); ImageInfo.driveFirmwareRevision = StringHandlers.CToString(header.revision); ImageInfo.imageApplication = "BlindWrite"; - if(string.Compare(Path.GetExtension(imagePath), "B5T", StringComparison.OrdinalIgnoreCase) == 0) + if(string.Compare(Path.GetExtension(imageFilter.GetFilename()), "B5T", StringComparison.OrdinalIgnoreCase) == 0) ImageInfo.imageApplicationVersion = "5"; - else if(string.Compare(Path.GetExtension(imagePath), "B6T", StringComparison.OrdinalIgnoreCase) == 0) + else if(string.Compare(Path.GetExtension(imageFilter.GetFilename()), "B6T", StringComparison.OrdinalIgnoreCase) == 0) ImageInfo.imageApplicationVersion = "6"; ImageInfo.imageVersion = "5"; - FileInfo fi = new FileInfo(imagePath); - ImageInfo.imageSize = (ulong)fi.Length; - ImageInfo.imageCreationTime = fi.CreationTimeUtc; - ImageInfo.imageLastModificationTime = fi.LastWriteTimeUtc; + ImageInfo.imageSize = (ulong)imageFilter.GetDataForkLength(); + ImageInfo.imageCreationTime = imageFilter.GetCreationTime(); + ImageInfo.imageLastModificationTime = imageFilter.GetLastWriteTime(); ImageInfo.xmlMediaType = XmlMediaType.OpticalDisc; if(pma != null) @@ -1301,8 +1312,8 @@ namespace DiscImageChef.ImagePlugins } } - if(string.IsNullOrEmpty(chars.filePath)) - throw new ArgumentOutOfRangeException(nameof(chars.filePath), "Track does not exist in disc image"); + if(string.IsNullOrEmpty(chars.filePath) || chars.fileFilter == null) + throw new ArgumentOutOfRangeException(nameof(chars.fileFilter), "Track does not exist in disc image"); uint sector_offset; uint sector_size; @@ -1373,26 +1384,23 @@ namespace DiscImageChef.ImagePlugins byte[] buffer = new byte[sector_size * length]; - imageStream = new FileStream(chars.filePath, FileMode.Open, FileAccess.Read); - using(BinaryReader br = new BinaryReader(imageStream)) - { - br.BaseStream.Seek((long)_track.TrackFileOffset + (long)(sectorAddress * (sector_offset + sector_size + sector_skip)), SeekOrigin.Begin); + imageStream = chars.fileFilter.GetDataForkStream(); + BinaryReader br = new BinaryReader(imageStream); + br.BaseStream.Seek((long)_track.TrackFileOffset + (long)(sectorAddress * (sector_offset + sector_size + sector_skip)), SeekOrigin.Begin); - if(sector_offset == 0 && sector_skip == 0) - buffer = br.ReadBytes((int)(sector_size * length)); - else + if(sector_offset == 0 && sector_skip == 0) + buffer = br.ReadBytes((int)(sector_size * length)); + else + { + for(int i = 0; i < length; i++) { - for(int i = 0; i < length; i++) - { - byte[] sector; - br.BaseStream.Seek(sector_offset, SeekOrigin.Current); - sector = br.ReadBytes((int)sector_size); - br.BaseStream.Seek(sector_skip, SeekOrigin.Current); - Array.Copy(sector, 0, buffer, i * sector_size, sector_size); - } + byte[] sector; + br.BaseStream.Seek(sector_offset, SeekOrigin.Current); + sector = br.ReadBytes((int)sector_size); + br.BaseStream.Seek(sector_skip, SeekOrigin.Current); + Array.Copy(sector, 0, buffer, i * sector_size, sector_size); } } - imageStream.Close(); return buffer; } @@ -1429,8 +1437,8 @@ namespace DiscImageChef.ImagePlugins } } - if(string.IsNullOrEmpty(chars.filePath)) - throw new ArgumentOutOfRangeException(nameof(chars.filePath), "Track does not exist in disc image"); + if(string.IsNullOrEmpty(chars.filePath) || chars.fileFilter == null) + throw new ArgumentOutOfRangeException(nameof(chars.fileFilter), "Track does not exist in disc image"); if(_track.TrackType == TrackType.Data) throw new ArgumentException("Unsupported tag requested", nameof(tag)); @@ -1671,25 +1679,22 @@ namespace DiscImageChef.ImagePlugins byte[] buffer = new byte[sector_size * length]; - imageStream = new FileStream(_track.TrackFile, FileMode.Open, FileAccess.Read); - using(BinaryReader br = new BinaryReader(imageStream)) + imageStream = _track.TrackFilter.GetDataForkStream(); + BinaryReader br = new BinaryReader(imageStream); + br.BaseStream.Seek((long)_track.TrackFileOffset + (long)(sectorAddress * (sector_offset + sector_size + sector_skip)), SeekOrigin.Begin); + if(sector_offset == 0 && sector_skip == 0) + buffer = br.ReadBytes((int)(sector_size * length)); + else { - br.BaseStream.Seek((long)_track.TrackFileOffset + (long)(sectorAddress * (sector_offset + sector_size + sector_skip)), SeekOrigin.Begin); - if(sector_offset == 0 && sector_skip == 0) - buffer = br.ReadBytes((int)(sector_size * length)); - else + for(int i = 0; i < length; i++) { - for(int i = 0; i < length; i++) - { - byte[] sector; - br.BaseStream.Seek(sector_offset, SeekOrigin.Current); - sector = br.ReadBytes((int)sector_size); - br.BaseStream.Seek(sector_skip, SeekOrigin.Current); - Array.Copy(sector, 0, buffer, i * sector_size, sector_size); - } + byte[] sector; + br.BaseStream.Seek(sector_offset, SeekOrigin.Current); + sector = br.ReadBytes((int)sector_size); + br.BaseStream.Seek(sector_skip, SeekOrigin.Current); + Array.Copy(sector, 0, buffer, i * sector_size, sector_size); } } - imageStream.Close(); return buffer; } @@ -1756,8 +1761,8 @@ namespace DiscImageChef.ImagePlugins } } - if(string.IsNullOrEmpty(chars.filePath)) - throw new ArgumentOutOfRangeException(nameof(chars.filePath), "Track does not exist in disc image"); + if(string.IsNullOrEmpty(chars.filePath) || chars.fileFilter == null) + throw new ArgumentOutOfRangeException(nameof(chars.fileFilter), "Track does not exist in disc image"); uint sector_offset; uint sector_size; @@ -1804,25 +1809,22 @@ namespace DiscImageChef.ImagePlugins byte[] buffer = new byte[sector_size * length]; - imageStream = new FileStream(_track.TrackFile, FileMode.Open, FileAccess.Read); - using(BinaryReader br = new BinaryReader(imageStream)) + imageStream = _track.TrackFilter.GetDataForkStream(); + BinaryReader br = new BinaryReader(imageStream); + br.BaseStream.Seek((long)_track.TrackFileOffset + (long)(sectorAddress * (sector_offset + sector_size + sector_skip)), SeekOrigin.Begin); + if(sector_offset == 0 && sector_skip == 0) + buffer = br.ReadBytes((int)(sector_size * length)); + else { - br.BaseStream.Seek((long)_track.TrackFileOffset + (long)(sectorAddress * (sector_offset + sector_size + sector_skip)), SeekOrigin.Begin); - if(sector_offset == 0 && sector_skip == 0) - buffer = br.ReadBytes((int)(sector_size * length)); - else + for(int i = 0; i < length; i++) { - for(int i = 0; i < length; i++) - { - byte[] sector; - br.BaseStream.Seek(sector_offset, SeekOrigin.Current); - sector = br.ReadBytes((int)sector_size); - br.BaseStream.Seek(sector_skip, SeekOrigin.Current); - Array.Copy(sector, 0, buffer, i * sector_size, sector_size); - } + byte[] sector; + br.BaseStream.Seek(sector_offset, SeekOrigin.Current); + sector = br.ReadBytes((int)sector_size); + br.BaseStream.Seek(sector_skip, SeekOrigin.Current); + Array.Copy(sector, 0, buffer, i * sector_size, sector_size); } } - imageStream.Close(); return buffer; } diff --git a/DiscImageChef.DiscImages/CDRDAO.cs b/DiscImageChef.DiscImages/CDRDAO.cs index cc66c90b..8ead711b 100644 --- a/DiscImageChef.DiscImages/CDRDAO.cs +++ b/DiscImageChef.DiscImages/CDRDAO.cs @@ -37,6 +37,7 @@ using System.Text.RegularExpressions; using DiscImageChef.Console; using DiscImageChef.CommonTypes; using System.Text; +using DiscImageChef.Filters; namespace DiscImageChef.ImagePlugins { @@ -50,6 +51,8 @@ namespace DiscImageChef.ImagePlugins { /// Track # public uint sequence; + /// Filter of file containing track + public Filter datafilter; /// Path of file containing track public string datafile; /// Offset of track start in file @@ -161,9 +164,9 @@ namespace DiscImageChef.ImagePlugins #region Internal variables - string imagePath; + Filter imageFilter; StreamReader tocStream; - FileStream imageStream; + Stream imageStream; /// Dictionary, index is track #, value is TrackFile Dictionary offsetmap; List partitions; @@ -214,7 +217,6 @@ namespace DiscImageChef.ImagePlugins { Name = "CDRDAO tocfile"; PluginUUID = new Guid("04D7BA12-1BE8-44D4-97A4-1B48A505463E"); - imagePath = ""; ImageInfo = new ImageInfo(); ImageInfo.readableSectorTags = new List(); ImageInfo.readableMediaTags = new List(); @@ -237,13 +239,12 @@ namespace DiscImageChef.ImagePlugins #endregion Public methods - public override bool IdentifyImage(string imagePath) + public override bool IdentifyImage(Filter imageFilter) { - this.imagePath = imagePath; - try { - tocStream = new StreamReader(this.imagePath); + imageFilter.GetDataForkStream().Seek(0, SeekOrigin.Begin); + tocStream = new StreamReader(imageFilter.GetDataForkStream()); string _line = tocStream.ReadLine(); Regex Dr = new Regex(DiskTypeRegEx); @@ -255,7 +256,7 @@ namespace DiscImageChef.ImagePlugins } catch(Exception ex) { - DicConsole.ErrorWriteLine("Exception trying to identify image file {0}", this.imagePath); + DicConsole.ErrorWriteLine("Exception trying to identify image file {0}", this.imageFilter.GetFilename()); DicConsole.ErrorWriteLine("Exception: {0}", ex.Message); DicConsole.ErrorWriteLine("Stack trace: {0}", ex.StackTrace); return false; @@ -264,18 +265,19 @@ namespace DiscImageChef.ImagePlugins #region Not implemented methods - public override bool OpenImage(string imagePath) + public override bool OpenImage(Filter imageFilter) { - if(imagePath == null) + if(imageFilter == null) return false; - if(imagePath == "") + if(imageFilter == null) return false; - this.imagePath = imagePath; + this.imageFilter = imageFilter; try { - tocStream = new StreamReader(imagePath); + imageFilter.GetDataForkStream().Seek(0, SeekOrigin.Begin); + tocStream = new StreamReader(imageFilter.GetDataForkStream()); int line = 0; bool intrack = false; @@ -352,7 +354,7 @@ namespace DiscImageChef.ImagePlugins int nextindex = 2; StringBuilder commentBuilder = new StringBuilder(); - tocStream = new StreamReader(this.imagePath); + tocStream = new StreamReader(this.imageFilter.GetDataForkStream()); string _line = tocStream.ReadLine(); MatchDiskType = RegexDiskType.Match(_line); @@ -363,8 +365,8 @@ namespace DiscImageChef.ImagePlugins return false; } - tocStream.Close(); - tocStream = new StreamReader(this.imagePath); + tocStream = new StreamReader(this.imageFilter.GetDataForkStream()); + FiltersList filtersList = new FiltersList(); while(tocStream.Peek() >= 0) { @@ -564,6 +566,7 @@ namespace DiscImageChef.ImagePlugins DicConsole.DebugWriteLine("CDRDAO plugin", "Found AUDIOFILE \"{1}\" at line {0}", line, MatchAudioFile.Groups["filename"].Value); currenttrack.trackfile = new CDRDAOTrackFile(); + currenttrack.trackfile.datafilter = filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), MatchAudioFile.Groups["filename"].Value)); currenttrack.trackfile.datafile = MatchAudioFile.Groups["filename"].Value; currenttrack.trackfile.offset = MatchAudioFile.Groups["base_offset"].Value != "" ? ulong.Parse(MatchAudioFile.Groups["base_offset"].Value) : 0; @@ -586,17 +589,15 @@ namespace DiscImageChef.ImagePlugins currenttrack.sectors = ulong.Parse(lengthString[0]) * 60 * 75 + ulong.Parse(lengthString[1]) * 75 + ulong.Parse(lengthString[2]); } else - { - FileInfo pfi = new FileInfo(currenttrack.trackfile.datafile); - currenttrack.sectors = ((ulong)pfi.Length - currenttrack.trackfile.offset) / currenttrack.bps; - } + currenttrack.sectors = ((ulong)currenttrack.trackfile.datafilter.GetDataForkLength() - currenttrack.trackfile.offset) / currenttrack.bps; } else if(MatchFile.Success) { DicConsole.DebugWriteLine("CDRDAO plugin", "Found DATAFILE \"{1}\" at line {0}", line, MatchFile.Groups["filename"].Value); currenttrack.trackfile = new CDRDAOTrackFile(); - currenttrack.trackfile.datafile = MatchFile.Groups["filename"].Value; + currenttrack.trackfile.datafilter = filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), MatchAudioFile.Groups["filename"].Value)); + currenttrack.trackfile.datafile = MatchAudioFile.Groups["filename"].Value; currenttrack.trackfile.offset = MatchFile.Groups["base_offset"].Value != "" ? ulong.Parse(MatchFile.Groups["base_offset"].Value) : 0; currenttrack.trackfile.filetype = "BINARY"; @@ -607,10 +608,7 @@ namespace DiscImageChef.ImagePlugins currenttrack.sectors = ulong.Parse(lengthString[0]) * 60 * 75 + ulong.Parse(lengthString[1]) * 75 + ulong.Parse(lengthString[2]); } else - { - FileInfo pfi = new FileInfo(currenttrack.trackfile.datafile); - currenttrack.sectors = ((ulong)pfi.Length - currenttrack.trackfile.offset) / currenttrack.bps; - } + currenttrack.sectors = ((ulong)currenttrack.trackfile.datafilter.GetDataForkLength() - currenttrack.trackfile.offset) / currenttrack.bps; } else if(MatchTitle.Success) { @@ -762,7 +760,7 @@ namespace DiscImageChef.ImagePlugins DicConsole.DebugWriteLine("CDRDAO plugin", "\t\tTrack has pre-emphasis applied"); DicConsole.DebugWriteLine("CDRDAO plugin", "\t\tTrack resides in file {0}, type defined as {1}, starting at byte {2}", - discimage.tracks[i].trackfile.datafile, discimage.tracks[i].trackfile.filetype, discimage.tracks[i].trackfile.offset); + discimage.tracks[i].trackfile.datafilter, discimage.tracks[i].trackfile.filetype, discimage.tracks[i].trackfile.offset); DicConsole.DebugWriteLine("CDRDAO plugin", "\t\tIndexes:"); foreach(KeyValuePair kvp in discimage.tracks[i].indexes) @@ -874,10 +872,8 @@ namespace DiscImageChef.ImagePlugins ImageInfo.imageApplication = "CDRDAO"; - FileInfo fi = new FileInfo(discimage.tracks[0].trackfile.datafile); - - ImageInfo.imageCreationTime = fi.CreationTimeUtc; - ImageInfo.imageLastModificationTime = fi.LastWriteTimeUtc; + ImageInfo.imageCreationTime = imageFilter.GetCreationTime(); + ImageInfo.imageLastModificationTime = imageFilter.GetLastWriteTime(); ImageInfo.imageComments = discimage.comment; ImageInfo.mediaSerialNumber = discimage.mcn; @@ -954,7 +950,7 @@ namespace DiscImageChef.ImagePlugins } catch(Exception ex) { - DicConsole.ErrorWriteLine("Exception trying to identify image file {0}", imagePath); + DicConsole.ErrorWriteLine("Exception trying to identify image file {0}", imageFilter); DicConsole.ErrorWriteLine("Exception: {0}", ex.Message); DicConsole.ErrorWriteLine("Stack trace: {0}", ex.StackTrace); return false; @@ -1138,22 +1134,20 @@ namespace DiscImageChef.ImagePlugins byte[] buffer = new byte[sector_size * length]; - imageStream = new FileStream(_track.trackfile.datafile, FileMode.Open, FileAccess.Read); - using(BinaryReader br = new BinaryReader(imageStream)) + imageStream = _track.trackfile.datafilter.GetDataForkStream(); + BinaryReader br = new BinaryReader(imageStream); + br.BaseStream.Seek((long)_track.trackfile.offset + (long)(sectorAddress * (sector_offset + sector_size + sector_skip)), SeekOrigin.Begin); + if(sector_offset == 0 && sector_skip == 0) + buffer = br.ReadBytes((int)(sector_size * length)); + else { - br.BaseStream.Seek((long)_track.trackfile.offset + (long)(sectorAddress * (sector_offset + sector_size + sector_skip)), SeekOrigin.Begin); - if(sector_offset == 0 && sector_skip == 0) - buffer = br.ReadBytes((int)(sector_size * length)); - else + for(int i = 0; i < length; i++) { - for(int i = 0; i < length; i++) - { - byte[] sector; - br.BaseStream.Seek(sector_offset, SeekOrigin.Current); - sector = br.ReadBytes((int)sector_size); - br.BaseStream.Seek(sector_skip, SeekOrigin.Current); - Array.Copy(sector, 0, buffer, i * sector_size, sector_size); - } + byte[] sector; + br.BaseStream.Seek(sector_offset, SeekOrigin.Current); + sector = br.ReadBytes((int)sector_size); + br.BaseStream.Seek(sector_skip, SeekOrigin.Current); + Array.Copy(sector, 0, buffer, i * sector_size, sector_size); } } @@ -1324,22 +1318,20 @@ namespace DiscImageChef.ImagePlugins byte[] buffer = new byte[sector_size * length]; - imageStream = new FileStream(_track.trackfile.datafile, FileMode.Open, FileAccess.Read); - using(BinaryReader br = new BinaryReader(imageStream)) + imageStream = _track.trackfile.datafilter.GetDataForkStream(); + BinaryReader br = new BinaryReader(imageStream); + br.BaseStream.Seek((long)_track.trackfile.offset + (long)(sectorAddress * (sector_offset + sector_size + sector_skip)), SeekOrigin.Begin); + if(sector_offset == 0 && sector_skip == 0) + buffer = br.ReadBytes((int)(sector_size * length)); + else { - br.BaseStream.Seek((long)_track.trackfile.offset + (long)(sectorAddress * (sector_offset + sector_size + sector_skip)), SeekOrigin.Begin); - if(sector_offset == 0 && sector_skip == 0) - buffer = br.ReadBytes((int)(sector_size * length)); - else + for(int i = 0; i < length; i++) { - for(int i = 0; i < length; i++) - { - byte[] sector; - br.BaseStream.Seek(sector_offset, SeekOrigin.Current); - sector = br.ReadBytes((int)sector_size); - br.BaseStream.Seek(sector_skip, SeekOrigin.Current); - Array.Copy(sector, 0, buffer, i * sector_size, sector_size); - } + byte[] sector; + br.BaseStream.Seek(sector_offset, SeekOrigin.Current); + sector = br.ReadBytes((int)sector_size); + br.BaseStream.Seek(sector_skip, SeekOrigin.Current); + Array.Copy(sector, 0, buffer, i * sector_size, sector_size); } } @@ -1444,7 +1436,7 @@ namespace DiscImageChef.ImagePlugins byte[] buffer = new byte[sector_size * length]; - imageStream = new FileStream(_track.trackfile.datafile, FileMode.Open, FileAccess.Read); + imageStream = _track.trackfile.datafilter.GetDataForkStream(); BinaryReader br = new BinaryReader(imageStream); br.BaseStream.Seek((long)_track.trackfile.offset + (long)(sectorAddress * (sector_offset + sector_size + sector_skip)), SeekOrigin.Begin); @@ -1540,7 +1532,8 @@ namespace DiscImageChef.ImagePlugins _track.TrackSession = 1; _track.TrackSequence = cdr_track.sequence; _track.TrackType = CDRDAOTrackTypeToTrackType(cdr_track.tracktype); - _track.TrackFile = cdr_track.trackfile.datafile; + _track.TrackFilter = cdr_track.trackfile.datafilter; + _track.TrackFile = cdr_track.trackfile.datafilter.GetFilename(); _track.TrackFileOffset = cdr_track.trackfile.offset; _track.TrackFileType = cdr_track.trackfile.filetype; _track.TrackRawBytesPerSector = cdr_track.bps; @@ -1548,8 +1541,8 @@ namespace DiscImageChef.ImagePlugins if(cdr_track.subchannel) { _track.TrackSubchannelType = cdr_track.packedsubchannel ? TrackSubchannelType.PackedInterleaved : TrackSubchannelType.RawInterleaved; - - _track.TrackSubchannelFile = cdr_track.trackfile.datafile; + _track.TrackSubchannelFilter = cdr_track.trackfile.datafilter; + _track.TrackSubchannelFile = cdr_track.trackfile.datafilter.GetFilename(); _track.TrackSubchannelOffset = cdr_track.trackfile.offset; } else diff --git a/DiscImageChef.DiscImages/CDRWin.cs b/DiscImageChef.DiscImages/CDRWin.cs index 37588d46..0015dd6d 100644 --- a/DiscImageChef.DiscImages/CDRWin.cs +++ b/DiscImageChef.DiscImages/CDRWin.cs @@ -38,6 +38,7 @@ using System.Text.RegularExpressions; using System.Collections.Generic; using DiscImageChef.Console; using DiscImageChef.CommonTypes; +using DiscImageChef.Filters; namespace DiscImageChef.ImagePlugins { @@ -49,8 +50,8 @@ namespace DiscImageChef.ImagePlugins { /// Track # public uint sequence; - /// Path of file containing track - public string datafile; + /// Filter of file containing track + public Filter datafilter; /// Offset of track start in file public ulong offset; /// Type of file @@ -243,9 +244,9 @@ namespace DiscImageChef.ImagePlugins #region Internal variables - string imagePath; + Filter imageFilter; StreamReader cueStream; - FileStream imageStream; + Stream imageStream; /// Dictionary, index is track #, value is TrackFile Dictionary offsetmap; CDRWinDisc discimage; @@ -287,7 +288,6 @@ namespace DiscImageChef.ImagePlugins { Name = "CDRWin cuesheet"; PluginUUID = new Guid("664568B2-15D4-4E64-8A7A-20BDA8B8386F"); - imagePath = ""; ImageInfo = new ImageInfo(); ImageInfo.readableSectorTags = new List(); ImageInfo.readableMediaTags = new List(); @@ -309,13 +309,14 @@ namespace DiscImageChef.ImagePlugins } // Due to .cue format, this method must parse whole file, ignoring errors (those will be thrown by OpenImage()). - public override bool IdentifyImage(string imagePath) + public override bool IdentifyImage(Filter imageFilter) { - this.imagePath = imagePath; + this.imageFilter = imageFilter; try { - cueStream = new StreamReader(this.imagePath); + imageFilter.GetDataForkStream().Seek(0, SeekOrigin.Begin); + cueStream = new StreamReader(this.imageFilter.GetDataForkStream()); int line = 0; while(cueStream.Peek() >= 0) @@ -351,25 +352,24 @@ namespace DiscImageChef.ImagePlugins } catch(Exception ex) { - DicConsole.ErrorWriteLine("Exception trying to identify image file {0}", this.imagePath); + DicConsole.ErrorWriteLine("Exception trying to identify image file {0}", this.imageFilter); DicConsole.ErrorWriteLine("Exception: {0}", ex.Message); DicConsole.ErrorWriteLine("Stack trace: {0}", ex.StackTrace); return false; } } - public override bool OpenImage(string imagePath) + public override bool OpenImage(Filter imageFilter) { - if(imagePath == null) - return false; - if(imagePath == "") + if(imageFilter == null) return false; - this.imagePath = imagePath; + this.imageFilter = imageFilter; try { - cueStream = new StreamReader(imagePath); + imageFilter.GetDataForkStream().Seek(0, SeekOrigin.Begin); + cueStream = new StreamReader(imageFilter.GetDataForkStream()); int line = 0; bool intrack = false; byte currentsession = 1; @@ -458,14 +458,10 @@ namespace DiscImageChef.ImagePlugins cuetracks = new CDRWinTrack[track_count]; line = 0; - // Mono <= 3.5 allowed this to work, with .Peek() NOT returning EOF. - // However .NET framework has always returned EOF even with this rewind. - // Mono 4.0 copied their bug (feature?) - //cueStream.BaseStream.Seek(0, SeekOrigin.Begin); + imageFilter.GetDataForkStream().Seek(0, SeekOrigin.Begin); + cueStream = new StreamReader(imageFilter.GetDataForkStream()); - // Forcing me to do - cueStream.Close(); - cueStream = new StreamReader(imagePath); + FiltersList filtersList = new FiltersList(); while(cueStream.Peek() >= 0) { @@ -580,63 +576,64 @@ namespace DiscImageChef.ImagePlugins { currentfile.sequence = currenttrack.sequence; currenttrack.trackfile = currentfile; - FileInfo finfo = new FileInfo(currentfile.datafile); - currenttrack.sectors = ((ulong)finfo.Length - currentfile.offset) / CDRWinTrackTypeToBytesPerSector(currenttrack.tracktype); + currenttrack.sectors = ((ulong)currentfile.datafilter.GetLength() - currentfile.offset) / CDRWinTrackTypeToBytesPerSector(currenttrack.tracktype); cuetracks[currenttrack.sequence - 1] = currenttrack; intrack = false; currenttrack = new CDRWinTrack(); } - currentfile.datafile = MatchFile.Groups[1].Value; + string datafile = MatchFile.Groups[1].Value; currentfile.filetype = MatchFile.Groups[2].Value; // Check if file path is quoted - if(currentfile.datafile[0] == '"' && currentfile.datafile[currentfile.datafile.Length - 1] == '"') + if(datafile[0] == '"' && datafile[datafile.Length - 1] == '"') { - currentfile.datafile = currentfile.datafile.Substring(1, currentfile.datafile.Length - 2); // Unquote it + datafile = datafile.Substring(1, datafile.Length - 2); // Unquote it } + currentfile.datafilter = filtersList.GetFilter(datafile); + // Check if file exists - if(!File.Exists(currentfile.datafile)) + if(currentfile.datafilter == null) { - if(currentfile.datafile[0] == '/' || (currentfile.datafile[0] == '/' && currentfile.datafile[1] == '.')) // UNIX absolute path + if(datafile[0] == '/' || (datafile[0] == '/' && datafile[1] == '.')) // UNIX absolute path { Regex unixpath = new Regex("^(.+)/([^/]+)$"); - Match unixpathmatch = unixpath.Match(currentfile.datafile); + Match unixpathmatch = unixpath.Match(datafile); if(unixpathmatch.Success) { - currentfile.datafile = unixpathmatch.Groups[1].Value; + currentfile.datafilter = filtersList.GetFilter(unixpathmatch.Groups[1].Value); - if(!File.Exists(currentfile.datafile)) + if(currentfile.datafilter == null) { - string path = Path.GetPathRoot(imagePath); - currentfile.datafile = path + Path.PathSeparator + currentfile.datafile; + string path = imageFilter.GetParentFolder() + Path.PathSeparator + unixpathmatch.Groups[1].Value; + currentfile.datafilter = filtersList.GetFilter(path); - if(!File.Exists(currentfile.datafile)) + if(currentfile.datafilter == null) throw new FeatureUnsupportedImageException(string.Format("File \"{0}\" not found.", MatchFile.Groups[1].Value)); } } else throw new FeatureUnsupportedImageException(string.Format("File \"{0}\" not found.", MatchFile.Groups[1].Value)); } - else if((currentfile.datafile[1] == ':' && currentfile.datafile[2] == '\\') || - (currentfile.datafile[0] == '\\' && currentfile.datafile[1] == '\\') || - ((currentfile.datafile[0] == '.' && currentfile.datafile[1] == '\\'))) // Windows absolute path + else if((datafile[1] == ':' && datafile[2] == '\\') || + (datafile[0] == '\\' && datafile[1] == '\\') || + ((datafile[0] == '.' && datafile[1] == '\\'))) // Windows absolute path { Regex winpath = new Regex("^(?:[a-zA-Z]\\:(\\\\|\\/)|file\\:\\/\\/|\\\\\\\\|\\.(\\/|\\\\))([^\\\\\\/\\:\\*\\?\\<\\>\\\"\\|]+(\\\\|\\/){0,1})+$"); - Match winpathmatch = winpath.Match(currentfile.datafile); + Match winpathmatch = winpath.Match(datafile); if(winpathmatch.Success) { - currentfile.datafile = winpathmatch.Groups[1].Value; + currentfile.datafilter = filtersList.GetFilter(winpathmatch.Groups[1].Value); - if(!File.Exists(currentfile.datafile)) + if(currentfile.datafilter == null) { - string path = Path.GetPathRoot(imagePath); - currentfile.datafile = path + Path.PathSeparator + currentfile.datafile; + string path = imageFilter.GetParentFolder() + Path.PathSeparator + winpathmatch.Groups[1].Value; + currentfile.datafilter = filtersList.GetFilter(path); - if(!File.Exists(currentfile.datafile)) + if(currentfile.datafilter == null) throw new FeatureUnsupportedImageException(string.Format("File \"{0}\" not found.", MatchFile.Groups[1].Value)); } } @@ -645,16 +642,16 @@ namespace DiscImageChef.ImagePlugins } else { - string path = Path.GetDirectoryName(imagePath); - currentfile.datafile = path + Path.DirectorySeparatorChar + currentfile.datafile; + string path = imageFilter.GetParentFolder() + Path.PathSeparator + datafile; + currentfile.datafilter = filtersList.GetFilter(path); - if(!File.Exists(currentfile.datafile)) + if(currentfile.datafilter == null) throw new FeatureUnsupportedImageException(string.Format("File \"{0}\" not found.", MatchFile.Groups[1].Value)); } } // File does exist, process it - DicConsole.DebugWriteLine("CDRWin plugin", "File \"{0}\" found", currentfile.datafile); + DicConsole.DebugWriteLine("CDRWin plugin", "File \"{0}\" found", currentfile.datafilter); switch(currentfile.filetype) { @@ -788,7 +785,7 @@ namespace DiscImageChef.ImagePlugins else if(MatchTrack.Success) { DicConsole.DebugWriteLine("CDRWin plugin", "Found TRACK at line {0}", line); - if(currentfile.datafile == "") + if(currentfile.datafilter == null) throw new FeatureUnsupportedImageException(string.Format("Found TRACK field before a file is defined at line {0}", line)); if(intrack) { @@ -825,8 +822,7 @@ namespace DiscImageChef.ImagePlugins { currentfile.sequence = currenttrack.sequence; currenttrack.trackfile = currentfile; - FileInfo finfo = new FileInfo(currentfile.datafile); - currenttrack.sectors = ((ulong)finfo.Length - currentfile.offset) / CDRWinTrackTypeToBytesPerSector(currenttrack.tracktype); + currenttrack.sectors = ((ulong)currentfile.datafilter.GetLength() - currentfile.offset) / CDRWinTrackTypeToBytesPerSector(currenttrack.tracktype); cuetracks[currenttrack.sequence - 1] = currenttrack; } @@ -1007,7 +1003,7 @@ namespace DiscImageChef.ImagePlugins DicConsole.DebugWriteLine("CDRWin plugin", "\t\tTrack has SCMS"); DicConsole.DebugWriteLine("CDRWin plugin", "\t\tTrack resides in file {0}, type defined as {1}, starting at byte {2}", - discimage.tracks[i].trackfile.datafile, discimage.tracks[i].trackfile.filetype, discimage.tracks[i].trackfile.offset); + discimage.tracks[i].trackfile.datafilter, discimage.tracks[i].trackfile.filetype, discimage.tracks[i].trackfile.offset); DicConsole.DebugWriteLine("CDRWin plugin", "\t\tIndexes:"); foreach(KeyValuePair kvp in discimage.tracks[i].indexes) @@ -1207,10 +1203,8 @@ namespace DiscImageChef.ImagePlugins else ImageInfo.imageApplication = "CDRWin"; - FileInfo fi = new FileInfo(discimage.tracks[0].trackfile.datafile); - - ImageInfo.imageCreationTime = fi.CreationTimeUtc; - ImageInfo.imageLastModificationTime = fi.LastWriteTimeUtc; + ImageInfo.imageCreationTime = imageFilter.GetCreationTime(); + ImageInfo.imageLastModificationTime = imageFilter.GetLastWriteTime(); ImageInfo.imageComments = discimage.comment; ImageInfo.mediaSerialNumber = discimage.mcn; @@ -1290,7 +1284,7 @@ namespace DiscImageChef.ImagePlugins } catch(Exception ex) { - DicConsole.ErrorWriteLine("Exception trying to identify image file {0}", imagePath); + DicConsole.ErrorWriteLine("Exception trying to identify image file {0}", imageFilter); DicConsole.ErrorWriteLine("Exception: {0}", ex.Message); DicConsole.ErrorWriteLine("Stack trace: {0}", ex.StackTrace); return false; @@ -1492,27 +1486,23 @@ namespace DiscImageChef.ImagePlugins byte[] buffer = new byte[sector_size * length]; - imageStream = new FileStream(_track.trackfile.datafile, FileMode.Open, FileAccess.Read); - using(BinaryReader br = new BinaryReader(imageStream)) + imageStream = _track.trackfile.datafilter.GetDataForkStream(); + BinaryReader br = new BinaryReader(imageStream); + br.BaseStream.Seek((long)_track.trackfile.offset + (long)(sectorAddress * (sector_offset + sector_size + sector_skip)), SeekOrigin.Begin); + if(sector_offset == 0 && sector_skip == 0) + buffer = br.ReadBytes((int)(sector_size * length)); + else { - br.BaseStream.Seek((long)_track.trackfile.offset + (long)(sectorAddress * (sector_offset + sector_size + sector_skip)), SeekOrigin.Begin); - if(sector_offset == 0 && sector_skip == 0) - buffer = br.ReadBytes((int)(sector_size * length)); - else + for(int i = 0; i < length; i++) { - for(int i = 0; i < length; i++) - { - byte[] sector; - br.BaseStream.Seek(sector_offset, SeekOrigin.Current); - sector = br.ReadBytes((int)sector_size); - br.BaseStream.Seek(sector_skip, SeekOrigin.Current); - Array.Copy(sector, 0, buffer, i * sector_size, sector_size); - } + byte[] sector; + br.BaseStream.Seek(sector_offset, SeekOrigin.Current); + sector = br.ReadBytes((int)sector_size); + br.BaseStream.Seek(sector_skip, SeekOrigin.Current); + Array.Copy(sector, 0, buffer, i * sector_size, sector_size); } } - - return buffer; } @@ -1690,27 +1680,23 @@ namespace DiscImageChef.ImagePlugins byte[] buffer = new byte[sector_size * length]; - imageStream = new FileStream(_track.trackfile.datafile, FileMode.Open, FileAccess.Read); - using(BinaryReader br = new BinaryReader(imageStream)) + imageStream = _track.trackfile.datafilter.GetDataForkStream(); + BinaryReader br = new BinaryReader(imageStream); + br.BaseStream.Seek((long)_track.trackfile.offset + (long)(sectorAddress * (sector_offset + sector_size + sector_skip)), SeekOrigin.Begin); + if(sector_offset == 0 && sector_skip == 0) + buffer = br.ReadBytes((int)(sector_size * length)); + else { - br.BaseStream.Seek((long)_track.trackfile.offset + (long)(sectorAddress * (sector_offset + sector_size + sector_skip)), SeekOrigin.Begin); - if(sector_offset == 0 && sector_skip == 0) - buffer = br.ReadBytes((int)(sector_size * length)); - else + for(int i = 0; i < length; i++) { - for(int i = 0; i < length; i++) - { - byte[] sector; - br.BaseStream.Seek(sector_offset, SeekOrigin.Current); - sector = br.ReadBytes((int)sector_size); - br.BaseStream.Seek(sector_skip, SeekOrigin.Current); - Array.Copy(sector, 0, buffer, i * sector_size, sector_size); - } + byte[] sector; + br.BaseStream.Seek(sector_offset, SeekOrigin.Current); + sector = br.ReadBytes((int)sector_size); + br.BaseStream.Seek(sector_skip, SeekOrigin.Current); + Array.Copy(sector, 0, buffer, i * sector_size, sector_size); } } - - return buffer; } @@ -1817,7 +1803,7 @@ namespace DiscImageChef.ImagePlugins byte[] buffer = new byte[sector_size * length]; - imageStream = new FileStream(_track.trackfile.datafile, FileMode.Open, FileAccess.Read); + imageStream = _track.trackfile.datafilter.GetDataForkStream(); BinaryReader br = new BinaryReader(imageStream); br.BaseStream.Seek((long)_track.trackfile.offset + (long)(sectorAddress * (sector_offset + sector_size + sector_skip)), SeekOrigin.Begin); @@ -1915,14 +1901,16 @@ namespace DiscImageChef.ImagePlugins _track.TrackSession = cdr_track.session; _track.TrackSequence = cdr_track.sequence; _track.TrackType = CDRWinTrackTypeToTrackType(cdr_track.tracktype); - _track.TrackFile = cdr_track.trackfile.datafile; + _track.TrackFile = cdr_track.trackfile.datafilter.GetFilename(); + _track.TrackFilter = cdr_track.trackfile.datafilter; _track.TrackFileOffset = cdr_track.trackfile.offset; _track.TrackFileType = cdr_track.trackfile.filetype; _track.TrackRawBytesPerSector = cdr_track.bps; _track.TrackBytesPerSector = CDRWinTrackTypeToCookedBytesPerSector(cdr_track.tracktype); if(cdr_track.bps == 2448) { - _track.TrackSubchannelFile = cdr_track.trackfile.datafile; + _track.TrackSubchannelFilter = cdr_track.trackfile.datafilter; + _track.TrackSubchannelFile = cdr_track.trackfile.datafilter.GetFilename(); _track.TrackSubchannelOffset = cdr_track.trackfile.offset; _track.TrackSubchannelType = TrackSubchannelType.RawInterleaved; } @@ -1964,14 +1952,16 @@ namespace DiscImageChef.ImagePlugins _track.TrackSession = cdr_track.session; _track.TrackSequence = cdr_track.sequence; _track.TrackType = CDRWinTrackTypeToTrackType(cdr_track.tracktype); - _track.TrackFile = cdr_track.trackfile.datafile; + _track.TrackFile = cdr_track.trackfile.datafilter.GetFilename(); + _track.TrackFilter = cdr_track.trackfile.datafilter; _track.TrackFileOffset = cdr_track.trackfile.offset; _track.TrackFileType = cdr_track.trackfile.filetype; _track.TrackRawBytesPerSector = cdr_track.bps; _track.TrackBytesPerSector = CDRWinTrackTypeToCookedBytesPerSector(cdr_track.tracktype); if(cdr_track.bps == 2448) { - _track.TrackSubchannelFile = cdr_track.trackfile.datafile; + _track.TrackSubchannelFilter = cdr_track.trackfile.datafilter; + _track.TrackSubchannelFile = cdr_track.trackfile.datafilter.GetFilename(); _track.TrackSubchannelOffset = cdr_track.trackfile.offset; _track.TrackSubchannelType = TrackSubchannelType.RawInterleaved; } @@ -2275,5 +2265,4 @@ namespace DiscImageChef.ImagePlugins #endregion } -} - +} \ No newline at end of file diff --git a/DiscImageChef.DiscImages/CPCDSK.cs b/DiscImageChef.DiscImages/CPCDSK.cs index 8fc6e1f1..a969e8d5 100644 --- a/DiscImageChef.DiscImages/CPCDSK.cs +++ b/DiscImageChef.DiscImages/CPCDSK.cs @@ -39,6 +39,7 @@ using DiscImageChef.Checksums; using DiscImageChef.CommonTypes; using DiscImageChef.Console; using DiscImageChef.Decoders.Floppy; +using DiscImageChef.Filters; namespace DiscImageChef.ImagePlugins { @@ -221,9 +222,9 @@ namespace DiscImageChef.ImagePlugins ImageInfo.driveFirmwareRevision = null; } - public override bool IdentifyImage(string imagePath) + public override bool IdentifyImage(Filter imageFilter) { - FileStream stream = new FileStream(imagePath, FileMode.Open, FileAccess.Read); + Stream stream = imageFilter.GetDataForkStream(); stream.Seek(0, SeekOrigin.Begin); if(stream.Length < 512) @@ -242,9 +243,9 @@ namespace DiscImageChef.ImagePlugins return CPCDSKId.SequenceEqual(header.magic) || EDSKId.SequenceEqual(header.magic); } - public override bool OpenImage(string imagePath) + public override bool OpenImage(Filter imageFilter) { - FileStream stream = new FileStream(imagePath, FileMode.Open, FileAccess.Read); + Stream stream = imageFilter.GetDataForkStream(); stream.Seek(0, SeekOrigin.Begin); if(stream.Length < 512) @@ -420,17 +421,16 @@ namespace DiscImageChef.ImagePlugins DicConsole.DebugWriteLine("CPCDSK plugin", "All tracks are same size? {0}", allTracksSameSize); ImageInfo.imageApplication = StringHandlers.CToString(header.creator); - FileInfo fi = new FileInfo(imagePath); - ImageInfo.imageCreationTime = fi.CreationTimeUtc; - ImageInfo.imageLastModificationTime = fi.LastWriteTimeUtc; - ImageInfo.imageName = Path.GetFileNameWithoutExtension(imagePath); + ImageInfo.imageCreationTime = imageFilter.GetCreationTime(); + ImageInfo.imageLastModificationTime = imageFilter.GetLastWriteTime(); + ImageInfo.imageName = Path.GetFileNameWithoutExtension(imageFilter.GetFilename()); ImageInfo.sectors = (ulong)sectors.Count; ImageInfo.xmlMediaType = XmlMediaType.BlockMedia; ImageInfo.mediaType = MediaType.CompactFloppy; ImageInfo.readableSectorTags.Add(SectorTagType.FloppyAddressMark); // Debug writing full disk as raw - + /* FileStream foo = new FileStream(Path.GetFileNameWithoutExtension(imagePath) + ".bin", FileMode.Create); for(ulong i = 0; i < (ulong)sectors.Count; i++) { @@ -439,9 +439,7 @@ namespace DiscImageChef.ImagePlugins foo.Write(foob, 0, foob.Length); } foo.Close(); - - - stream.Close(); + */ return true; } diff --git a/DiscImageChef.DiscImages/ChangeLog b/DiscImageChef.DiscImages/ChangeLog index 336a0b07..dc9dd05f 100644 --- a/DiscImageChef.DiscImages/ChangeLog +++ b/DiscImageChef.DiscImages/ChangeLog @@ -1,3 +1,32 @@ +2016-09-05 Natalia Portillo + + * GDI.cs: + * VDI.cs: + * VHD.cs: + * DIM.cs: + * BLU.cs: + * QED.cs: + * UDIF.cs: + * QCOW.cs: + * VHDX.cs: + * Nero.cs: + * QCOW2.cs: + * CDRWin.cs: + * CopyQM.cs: + * CPCDSK.cs: + * VMware.cs: + * CDRDAO.cs: + * TeleDisk.cs: + * Apple2MG.cs: + * Parallels.cs: + * DiskCopy42.cs: + * Alcohol120.cs: + * ImagePlugin.cs: + * BlindWrite5.cs: + * BlindWrite4.cs: + * ZZZRawImage.cs: + * DiscImageChef.DiscImages.csproj: Added filters. + 2016-09-02 Natalia Portillo * UDIF.cs: diff --git a/DiscImageChef.DiscImages/CopyQM.cs b/DiscImageChef.DiscImages/CopyQM.cs index 2619d006..caec1c9e 100644 --- a/DiscImageChef.DiscImages/CopyQM.cs +++ b/DiscImageChef.DiscImages/CopyQM.cs @@ -36,6 +36,7 @@ using System.IO; using System.Runtime.InteropServices; using DiscImageChef.CommonTypes; using DiscImageChef.Console; +using DiscImageChef.Filters; namespace DiscImageChef.ImagePlugins { @@ -190,9 +191,9 @@ namespace DiscImageChef.ImagePlugins } #region Public methods - public override bool IdentifyImage(string imagePath) + public override bool IdentifyImage(Filter imageFilter) { - FileStream stream = new FileStream(imagePath, FileMode.Open, FileAccess.Read); + Stream stream = imageFilter.GetDataForkStream(); stream.Seek(0, SeekOrigin.Begin); if(stream.Length < 133) return false; @@ -208,9 +209,9 @@ namespace DiscImageChef.ImagePlugins return true; } - public override bool OpenImage(string imagePath) + public override bool OpenImage(Filter imageFilter) { - FileStream stream = new FileStream(imagePath, FileMode.Open, FileAccess.Read); + Stream stream = imageFilter.GetDataForkStream(); stream.Seek(0, SeekOrigin.Begin); byte[] hdr = new byte[133]; @@ -301,9 +302,11 @@ namespace DiscImageChef.ImagePlugins decodedImage.Write(filling, 0, filling.Length); } + /* FileStream debugStream = new FileStream("debug.img", FileMode.CreateNew, FileAccess.ReadWrite); debugStream.Write(decodedImage.ToArray(), 0, (int)decodedImage.Length); debugStream.Close(); + */ int sum = 0; for(int i = 0; i < hdr.Length - 1; i++) @@ -402,7 +405,6 @@ namespace DiscImageChef.ImagePlugins decodedDisk = decodedImage.ToArray(); decodedImage.Close(); - stream.Close(); DicConsole.VerboseWriteLine("CopyQM image contains a disk of type {0}", ImageInfo.mediaType); if(!string.IsNullOrEmpty(ImageInfo.imageComments)) diff --git a/DiscImageChef.DiscImages/DIM.cs b/DiscImageChef.DiscImages/DIM.cs index 23f127e3..73fb907c 100644 --- a/DiscImageChef.DiscImages/DIM.cs +++ b/DiscImageChef.DiscImages/DIM.cs @@ -37,6 +37,7 @@ using DiscImageChef.Console; using DiscImageChef.CommonTypes; using System.Linq; using System.Text; +using DiscImageChef.Filters; namespace DiscImageChef.ImagePlugins { @@ -65,7 +66,7 @@ namespace DiscImageChef.ImagePlugins /// Start of data sectors in disk image, should be 0x100 const uint dataOffset = 0x100; /// Disk image file - string dimImagePath; + Filter dimImageFilter; byte[] comment; byte[] hdrId; DiskType dskType; @@ -98,9 +99,9 @@ namespace DiscImageChef.ImagePlugins ImageInfo.driveFirmwareRevision = null; } - public override bool IdentifyImage(string imagePath) + public override bool IdentifyImage(Filter imageFilter) { - FileStream stream = new FileStream(imagePath, FileMode.Open, FileAccess.Read); + Stream stream = imageFilter.GetDataForkStream(); stream.Seek(0, SeekOrigin.Begin); if(stream.Length < dataOffset) @@ -114,14 +115,13 @@ namespace DiscImageChef.ImagePlugins stream.Read(hdrId, 0, 13); stream.Seek(0xC2, SeekOrigin.Begin); stream.Read(comment, 0, 60); - stream.Close(); return HeaderID.SequenceEqual(hdrId); } - public override bool OpenImage(string imagePath) + public override bool OpenImage(Filter imageFilter) { - FileStream stream = new FileStream(imagePath, FileMode.Open, FileAccess.Read); + Stream stream = imageFilter.GetDataForkStream(); stream.Seek(0, SeekOrigin.Begin); if(stream.Length < dataOffset) @@ -137,7 +137,6 @@ namespace DiscImageChef.ImagePlugins stream.Read(hdrId, 0, 13); stream.Seek(0xC2, SeekOrigin.Begin); stream.Read(comment, 0, 60); - stream.Close(); if(!HeaderID.SequenceEqual(hdrId)) return false; @@ -229,13 +228,12 @@ namespace DiscImageChef.ImagePlugins if(!string.IsNullOrEmpty(ImageInfo.imageComments)) DicConsole.VerboseWriteLine("DIM comments: {0}", ImageInfo.imageComments); - dimImagePath = imagePath; + dimImageFilter = imageFilter; - FileInfo fi = new FileInfo(imagePath); ImageInfo.imageSize = (ulong)diskSize; - ImageInfo.imageCreationTime = fi.CreationTimeUtc; - ImageInfo.imageLastModificationTime = fi.LastWriteTimeUtc; - ImageInfo.imageName = Path.GetFileNameWithoutExtension(imagePath); + ImageInfo.imageCreationTime = imageFilter.GetCreationTime(); + ImageInfo.imageLastModificationTime = imageFilter.GetLastWriteTime(); + ImageInfo.imageName = Path.GetFileNameWithoutExtension(imageFilter.GetFilename()); ImageInfo.sectors = ImageInfo.imageSize / ImageInfo.sectorSize; ImageInfo.imageComments = StringHandlers.CToString(comment, Encoding.GetEncoding(932)); ImageInfo.xmlMediaType = XmlMediaType.BlockMedia; @@ -328,14 +326,12 @@ namespace DiscImageChef.ImagePlugins byte[] buffer = new byte[length * ImageInfo.sectorSize]; - FileStream stream = new FileStream(dimImagePath, FileMode.Open, FileAccess.Read); + Stream stream = dimImageFilter.GetDataForkStream(); stream.Seek((long)(dataOffset + sectorAddress * ImageInfo.sectorSize), SeekOrigin.Begin); stream.Read(buffer, 0, (int)(length * ImageInfo.sectorSize)); - stream.Close(); - return buffer; } diff --git a/DiscImageChef.DiscImages/DiscImageChef.DiscImages.csproj b/DiscImageChef.DiscImages/DiscImageChef.DiscImages.csproj index 0b407cf8..d0c4092f 100644 --- a/DiscImageChef.DiscImages/DiscImageChef.DiscImages.csproj +++ b/DiscImageChef.DiscImages/DiscImageChef.DiscImages.csproj @@ -90,6 +90,10 @@ {CA231ED3-0C78-496C-AAFE-D085F6E9BEC6} Claunia.RsrcFork + + {D571B8EF-903D-4353-BDD5-B834F9F029EF} + DiscImageChef.Filters + diff --git a/DiscImageChef.DiscImages/DiskCopy42.cs b/DiscImageChef.DiscImages/DiskCopy42.cs index 95145dfe..bf33f328 100644 --- a/DiscImageChef.DiscImages/DiskCopy42.cs +++ b/DiscImageChef.DiscImages/DiskCopy42.cs @@ -35,6 +35,7 @@ using System.IO; using System.Collections.Generic; using DiscImageChef.Console; using DiscImageChef.CommonTypes; +using DiscImageChef.Filters; namespace DiscImageChef.ImagePlugins { @@ -122,7 +123,7 @@ namespace DiscImageChef.ImagePlugins /// Header of opened image DC42Header header; /// Disk image file - string dc42ImagePath; + Filter dc42ImageFilter; byte[] twiggyCache; byte[] twiggyCacheTags; @@ -157,14 +158,13 @@ namespace DiscImageChef.ImagePlugins ImageInfo.driveFirmwareRevision = null; } - public override bool IdentifyImage(string imagePath) + public override bool IdentifyImage(Filter imageFilter) { - FileStream stream = new FileStream(imagePath, FileMode.Open, FileAccess.Read); + Stream stream = imageFilter.GetDataForkStream(); stream.Seek(0, SeekOrigin.Begin); byte[] buffer = new byte[0x58]; byte[] pString = new byte[64]; stream.Read(buffer, 0, 0x58); - stream.Close(); // Incorrect pascal string length, not DC42 if(buffer[0] > 63) @@ -199,9 +199,7 @@ namespace DiscImageChef.ImagePlugins if(tmp_header.valid != 1 || tmp_header.reserved != 0) return false; - FileInfo fi = new FileInfo(imagePath); - - if(tmp_header.dataSize + tmp_header.tagSize + 0x54 != fi.Length && tmp_header.format != kSigmaFormatTwiggy) + if(tmp_header.dataSize + tmp_header.tagSize + 0x54 != imageFilter.GetDataForkLength() && tmp_header.format != kSigmaFormatTwiggy) return false; if(tmp_header.format != kSonyFormat400K && tmp_header.format != kSonyFormat800K && tmp_header.format != kSonyFormat720K && @@ -232,14 +230,13 @@ namespace DiscImageChef.ImagePlugins return true; } - public override bool OpenImage(string imagePath) + public override bool OpenImage(Filter imageFilter) { - FileStream stream = new FileStream(imagePath, FileMode.Open, FileAccess.Read); + Stream stream = imageFilter.GetDataForkStream(); stream.Seek(0, SeekOrigin.Begin); byte[] buffer = new byte[0x58]; byte[] pString = new byte[64]; stream.Read(buffer, 0, 0x58); - stream.Close(); // Incorrect pascal string length, not DC42 if(buffer[0] > 63) @@ -272,9 +269,7 @@ namespace DiscImageChef.ImagePlugins if(header.valid != 1 || header.reserved != 0) return false; - FileInfo fi = new FileInfo(imagePath); - - if(header.dataSize + header.tagSize + 0x54 != fi.Length && header.format != kSigmaFormatTwiggy) + if(header.dataSize + header.tagSize + 0x54 != imageFilter.GetDataForkLength() && header.format != kSigmaFormatTwiggy) return false; if(header.format != kSonyFormat400K && header.format != kSonyFormat800K && header.format != kSonyFormat720K && @@ -304,7 +299,7 @@ namespace DiscImageChef.ImagePlugins tagOffset = header.tagSize != 0 ? 0x54 + header.dataSize : 0; ImageInfo.sectorSize = 512; bptag = (uint)(header.tagSize != 0 ? 12 : 0); - dc42ImagePath = imagePath; + dc42ImageFilter = imageFilter; ImageInfo.sectors = header.dataSize / 512; @@ -323,8 +318,8 @@ namespace DiscImageChef.ImagePlugins } ImageInfo.imageSize = ImageInfo.sectors * ImageInfo.sectorSize + ImageInfo.sectors * bptag; - ImageInfo.imageCreationTime = fi.CreationTimeUtc; - ImageInfo.imageLastModificationTime = fi.LastWriteTimeUtc; + ImageInfo.imageCreationTime = imageFilter.GetCreationTime(); + ImageInfo.imageLastModificationTime = imageFilter.GetLastWriteTime(); ImageInfo.imageName = header.diskName; switch(header.format) @@ -381,15 +376,13 @@ namespace DiscImageChef.ImagePlugins twiggyCacheTags = new byte[header.tagSize]; twiggy = true; - FileStream datastream = new FileStream(dc42ImagePath, FileMode.Open, FileAccess.Read); + Stream datastream = imageFilter.GetDataForkStream(); datastream.Seek((dataOffset), SeekOrigin.Begin); datastream.Read(data, 0, (int)header.dataSize); - datastream.Close(); - FileStream tagstream = new FileStream(dc42ImagePath, FileMode.Open, FileAccess.Read); + Stream tagstream = imageFilter.GetDataForkStream(); tagstream.Seek((tagOffset), SeekOrigin.Begin); tagstream.Read(tags, 0, (int)header.tagSize); - tagstream.Close(); ushort MFS_Magic = BigEndianBitConverter.ToUInt16(data, (int)((data.Length / 2) + 0x400)); ushort MFS_AllBlocks = BigEndianBitConverter.ToUInt16(data, (int)((data.Length / 2) + 0x412)); @@ -485,10 +478,9 @@ namespace DiscImageChef.ImagePlugins uint tagsChk = 0; DicConsole.DebugWriteLine("DC42 plugin", "Reading data"); - FileStream datastream = new FileStream(dc42ImagePath, FileMode.Open, FileAccess.Read); + Stream datastream = dc42ImageFilter.GetDataForkStream(); datastream.Seek((dataOffset), SeekOrigin.Begin); datastream.Read(data, 0, (int)header.dataSize); - datastream.Close(); DicConsole.DebugWriteLine("DC42 plugin", "Calculating data checksum"); dataChk = DC42CheckSum(data); @@ -498,10 +490,9 @@ namespace DiscImageChef.ImagePlugins if(header.tagSize > 0) { DicConsole.DebugWriteLine("DC42 plugin", "Reading tags"); - FileStream tagstream = new FileStream(dc42ImagePath, FileMode.Open, FileAccess.Read); + Stream tagstream = dc42ImageFilter.GetDataForkStream(); tagstream.Seek((tagOffset), SeekOrigin.Begin); tagstream.Read(tags, 0, (int)header.tagSize); - tagstream.Close(); DicConsole.DebugWriteLine("DC42 plugin", "Calculating tag checksum"); tagsChk = DC42CheckSum(tags); @@ -558,10 +549,9 @@ namespace DiscImageChef.ImagePlugins } else { - FileStream stream = new FileStream(dc42ImagePath, FileMode.Open, FileAccess.Read); + Stream stream = dc42ImageFilter.GetDataForkStream(); stream.Seek((long)(dataOffset + sectorAddress * ImageInfo.sectorSize), SeekOrigin.Begin); stream.Read(buffer, 0, (int)(length * ImageInfo.sectorSize)); - stream.Close(); } return buffer; @@ -589,10 +579,9 @@ namespace DiscImageChef.ImagePlugins } else { - FileStream stream = new FileStream(dc42ImagePath, FileMode.Open, FileAccess.Read); + Stream stream = dc42ImageFilter.GetDataForkStream(); stream.Seek((long)(tagOffset + sectorAddress * bptag), SeekOrigin.Begin); stream.Read(buffer, 0, (int)(length * bptag)); - stream.Close(); } return buffer; diff --git a/DiscImageChef.DiscImages/GDI.cs b/DiscImageChef.DiscImages/GDI.cs index 6703dc34..264d2c09 100644 --- a/DiscImageChef.DiscImages/GDI.cs +++ b/DiscImageChef.DiscImages/GDI.cs @@ -36,6 +36,7 @@ using System.IO; using System.Text.RegularExpressions; using DiscImageChef.Console; using DiscImageChef.CommonTypes; +using DiscImageChef.Filters; namespace DiscImageChef.ImagePlugins { @@ -49,6 +50,8 @@ namespace DiscImageChef.ImagePlugins { /// Track # public uint sequence; + /// Track filter + public Filter trackfilter; /// Track file public string trackfile; /// Track byte offset in file @@ -83,9 +86,8 @@ namespace DiscImageChef.ImagePlugins #region Internal variables - string imagePath; StreamReader gdiStream; - FileStream imageStream; + Stream imageStream; /// Dictionary, index is track #, value is track number, or 0 if a TOC Dictionary offsetmap; GDIDisc discimage; @@ -106,7 +108,6 @@ namespace DiscImageChef.ImagePlugins { Name = "Dreamcast GDI image"; PluginUUID = new Guid("281ECBF2-D2A7-414C-8497-1A33F6DCB2DD"); - imagePath = ""; ImageInfo = new ImageInfo(); ImageInfo.readableSectorTags = new List(); ImageInfo.readableMediaTags = new List(); @@ -128,13 +129,12 @@ namespace DiscImageChef.ImagePlugins } // Due to .gdi format, this method must parse whole file, ignoring errors (those will be thrown by OpenImage()). - public override bool IdentifyImage(string imagePath) + public override bool IdentifyImage(Filter imageFilter) { - this.imagePath = imagePath; - try { - gdiStream = new StreamReader(this.imagePath); + imageFilter.GetDataForkStream().Seek(0, SeekOrigin.Begin); + gdiStream = new StreamReader(imageFilter.GetDataForkStream()); int line = 0; int tracksFound = 0; int tracks = 0; @@ -169,30 +169,26 @@ namespace DiscImageChef.ImagePlugins } catch(Exception ex) { - DicConsole.ErrorWriteLine("Exception trying to identify image file {0}", this.imagePath); + DicConsole.ErrorWriteLine("Exception trying to identify image file {0}", imageFilter.GetBasePath()); DicConsole.ErrorWriteLine("Exception: {0}", ex.Message); DicConsole.ErrorWriteLine("Stack trace: {0}", ex.StackTrace); return false; } } - public override bool OpenImage(string imagePath) + public override bool OpenImage(Filter imageFilter) { - if(imagePath == null) + if(imageFilter == null) return false; - if(imagePath == "") - return false; - - this.imagePath = imagePath; try { - gdiStream = new StreamReader(imagePath); + imageFilter.GetDataForkStream().Seek(0, SeekOrigin.Begin); + gdiStream = new StreamReader(imageFilter.GetDataForkStream()); int line = 0; int tracksFound = 0; int tracks = 0; bool highDensity = false; - FileInfo trackFileInfo; // Initialize all RegExs Regex RegexTrack = new Regex(TrackRegEx); @@ -210,6 +206,8 @@ namespace DiscImageChef.ImagePlugins GDITrack currentTrack; densitySeparationSectors = 0; + FiltersList filtersList = new FiltersList(); + while(gdiStream.Peek() >= 0) { line++; @@ -239,7 +237,8 @@ namespace DiscImageChef.ImagePlugins currentTrack.offset = long.Parse(TrackMatch.Groups["offset"].Value); currentTrack.sequence = uint.Parse(TrackMatch.Groups["track"].Value); currentTrack.startSector = ulong.Parse(TrackMatch.Groups["start"].Value); - currentTrack.trackfile = TrackMatch.Groups["filename"].Value.Replace("\\\"", "\"").Trim(new[] { '"' }); + currentTrack.trackfilter = filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), TrackMatch.Groups["filename"].Value.Replace("\\\"", "\"").Trim(new[] { '"' }))); + currentTrack.trackfile = currentTrack.trackfilter.GetFilename(); if((currentTrack.startSector - currentStart) > 0) { @@ -257,11 +256,10 @@ namespace DiscImageChef.ImagePlugins } } - trackFileInfo = new FileInfo(currentTrack.trackfile); - if(((trackFileInfo.Length - currentTrack.offset) % currentTrack.bps) != 0) + if(((currentTrack.trackfilter.GetDataForkLength() - currentTrack.offset) % currentTrack.bps) != 0) throw new ImageNotSupportedException("Track size not a multiple of sector size"); - currentTrack.sectors = (ulong)((trackFileInfo.Length - currentTrack.offset) / currentTrack.bps); + currentTrack.sectors = (ulong)((currentTrack.trackfilter.GetDataForkLength() - currentTrack.offset) / currentTrack.bps); currentTrack.sectors += currentTrack.pregap; currentStart += currentTrack.sectors; currentTrack.highDensity = highDensity; @@ -364,7 +362,7 @@ namespace DiscImageChef.ImagePlugins DicConsole.DebugWriteLine("GDI plugin", "\t\tTrack has pre-emphasis applied"); DicConsole.DebugWriteLine("GDI plugin", "\t\tTrack resides in file {0}, type defined as {1}, starting at byte {2}", - discimage.tracks[i].trackfile, discimage.tracks[i].tracktype, discimage.tracks[i].offset); + discimage.tracks[i].trackfilter, discimage.tracks[i].tracktype, discimage.tracks[i].offset); } DicConsole.DebugWriteLine("GDI plugin", "Building offset map"); @@ -417,10 +415,8 @@ namespace DiscImageChef.ImagePlugins } } - FileInfo fi = new FileInfo(discimage.tracks[0].trackfile); - - ImageInfo.imageCreationTime = fi.CreationTimeUtc; - ImageInfo.imageLastModificationTime = fi.LastWriteTimeUtc; + ImageInfo.imageCreationTime = imageFilter.GetCreationTime(); + ImageInfo.imageLastModificationTime = imageFilter.GetLastWriteTime(); ImageInfo.mediaType = discimage.disktype; @@ -434,7 +430,7 @@ namespace DiscImageChef.ImagePlugins } catch(Exception ex) { - DicConsole.ErrorWriteLine("Exception trying to identify image file {0}", imagePath); + DicConsole.ErrorWriteLine("Exception trying to identify image file {0}", imageFilter.GetBasePath()); DicConsole.ErrorWriteLine("Exception: {0}", ex.Message); DicConsole.ErrorWriteLine("Stack trace: {0}", ex.StackTrace); return false; @@ -623,22 +619,20 @@ namespace DiscImageChef.ImagePlugins if(remainingSectors == 0) return buffer; - imageStream = new FileStream(_track.trackfile, FileMode.Open, FileAccess.Read); - using(BinaryReader br = new BinaryReader(imageStream)) + imageStream = _track.trackfilter.GetDataForkStream(); + BinaryReader br = new BinaryReader(imageStream); + br.BaseStream.Seek(_track.offset + (long)(sectorAddress * (sector_offset + sector_size + sector_skip) + _track.pregap * _track.bps), SeekOrigin.Begin); + if(sector_offset == 0 && sector_skip == 0) + buffer = br.ReadBytes((int)(sector_size * remainingSectors)); + else { - br.BaseStream.Seek(_track.offset + (long)(sectorAddress * (sector_offset + sector_size + sector_skip) + _track.pregap * _track.bps), SeekOrigin.Begin); - if(sector_offset == 0 && sector_skip == 0) - buffer = br.ReadBytes((int)(sector_size * remainingSectors)); - else + for(ulong i = 0; i < remainingSectors; i++) { - for(ulong i = 0; i < remainingSectors; i++) - { - byte[] sector; - br.BaseStream.Seek(sector_offset, SeekOrigin.Current); - sector = br.ReadBytes((int)sector_size); - br.BaseStream.Seek(sector_skip, SeekOrigin.Current); - Array.Copy(sector, 0, buffer, (int)(i * sector_size), sector_size); - } + byte[] sector; + br.BaseStream.Seek(sector_offset, SeekOrigin.Current); + sector = br.ReadBytes((int)sector_size); + br.BaseStream.Seek(sector_skip, SeekOrigin.Current); + Array.Copy(sector, 0, buffer, (int)(i * sector_size), sector_size); } } @@ -792,22 +786,20 @@ namespace DiscImageChef.ImagePlugins if(remainingSectors == 0) return buffer; - imageStream = new FileStream(_track.trackfile, FileMode.Open, FileAccess.Read); - using(BinaryReader br = new BinaryReader(imageStream)) + imageStream = _track.trackfilter.GetDataForkStream(); + BinaryReader br = new BinaryReader(imageStream); + br.BaseStream.Seek(_track.offset + (long)(sectorAddress * (sector_offset + sector_size + sector_skip) + _track.pregap * _track.bps), SeekOrigin.Begin); + if(sector_offset == 0 && sector_skip == 0) + buffer = br.ReadBytes((int)(sector_size * remainingSectors)); + else { - br.BaseStream.Seek(_track.offset + (long)(sectorAddress * (sector_offset + sector_size + sector_skip) + _track.pregap * _track.bps), SeekOrigin.Begin); - if(sector_offset == 0 && sector_skip == 0) - buffer = br.ReadBytes((int)(sector_size * remainingSectors)); - else + for(ulong i = 0; i < remainingSectors; i++) { - for(ulong i = 0; i < remainingSectors; i++) - { - byte[] sector; - br.BaseStream.Seek(sector_offset, SeekOrigin.Current); - sector = br.ReadBytes((int)sector_size); - br.BaseStream.Seek(sector_skip, SeekOrigin.Current); - Array.Copy(sector, 0, buffer, (int)(i * sector_size), sector_size); - } + byte[] sector; + br.BaseStream.Seek(sector_offset, SeekOrigin.Current); + sector = br.ReadBytes((int)sector_size); + br.BaseStream.Seek(sector_skip, SeekOrigin.Current); + Array.Copy(sector, 0, buffer, (int)(i * sector_size), sector_size); } } @@ -931,22 +923,20 @@ namespace DiscImageChef.ImagePlugins if(remainingSectors == 0) return buffer; - imageStream = new FileStream(_track.trackfile, FileMode.Open, FileAccess.Read); - using(BinaryReader br = new BinaryReader(imageStream)) + imageStream = _track.trackfilter.GetDataForkStream(); + BinaryReader br = new BinaryReader(imageStream); + br.BaseStream.Seek(_track.offset + (long)(sectorAddress * (sector_offset + sector_size + sector_skip) + _track.pregap * _track.bps), SeekOrigin.Begin); + if(sector_offset == 0 && sector_skip == 0) + buffer = br.ReadBytes((int)(sector_size * remainingSectors)); + else { - br.BaseStream.Seek(_track.offset + (long)(sectorAddress * (sector_offset + sector_size + sector_skip) + _track.pregap * _track.bps), SeekOrigin.Begin); - if(sector_offset == 0 && sector_skip == 0) - buffer = br.ReadBytes((int)(sector_size * remainingSectors)); - else + for(ulong i = 0; i < remainingSectors; i++) { - for(ulong i = 0; i < remainingSectors; i++) - { - byte[] sector; - br.BaseStream.Seek(sector_offset, SeekOrigin.Current); - sector = br.ReadBytes((int)sector_size); - br.BaseStream.Seek(sector_skip, SeekOrigin.Current); - Array.Copy(sector, 0, buffer, (int)(i * sector_size), sector_size); - } + byte[] sector; + br.BaseStream.Seek(sector_offset, SeekOrigin.Current); + sector = br.ReadBytes((int)sector_size); + br.BaseStream.Seek(sector_skip, SeekOrigin.Current); + Array.Copy(sector, 0, buffer, (int)(i * sector_size), sector_size); } } @@ -1027,6 +1017,7 @@ namespace DiscImageChef.ImagePlugins _track.TrackSession = 1; _track.TrackSequence = gdi_track.sequence; _track.TrackType = gdi_track.tracktype; + _track.TrackFilter = gdi_track.trackfilter; _track.TrackFile = gdi_track.trackfile; _track.TrackFileOffset = (ulong)gdi_track.offset; _track.TrackFileType = "BINARY"; @@ -1086,6 +1077,7 @@ namespace DiscImageChef.ImagePlugins _track.TrackSession = 1; _track.TrackSequence = gdi_track.sequence; _track.TrackType = gdi_track.tracktype; + _track.TrackFilter = gdi_track.trackfilter; _track.TrackFile = gdi_track.trackfile; _track.TrackFileOffset = (ulong)gdi_track.offset; _track.TrackFileType = "BINARY"; diff --git a/DiscImageChef.DiscImages/ImagePlugin.cs b/DiscImageChef.DiscImages/ImagePlugin.cs index d2f4a99d..21cc478e 100644 --- a/DiscImageChef.DiscImages/ImagePlugin.cs +++ b/DiscImageChef.DiscImages/ImagePlugin.cs @@ -33,6 +33,7 @@ using System; using System.Collections.Generic; using DiscImageChef.CommonTypes; +using DiscImageChef.Filters; namespace DiscImageChef.ImagePlugins { @@ -58,15 +59,15 @@ namespace DiscImageChef.ImagePlugins /// Identifies the image. /// /// true, if image was identified, false otherwise. - /// Image path. - public abstract bool IdentifyImage(string imagePath); + /// Image filter. + public abstract bool IdentifyImage(Filter imageFilter); /// /// Opens the image. /// /// true, if image was opened, false otherwise. - /// Image path. - public abstract bool OpenImage(string imagePath); + /// Image filter. + public abstract bool OpenImage(Filter imageFilter); /// /// Asks the disk image plugin if the image contains partitions @@ -461,6 +462,8 @@ namespace DiscImageChef.ImagePlugins public string TrackDescription; /// Indexes, 00 to 99 and sector offset public Dictionary Indexes; + /// Which filter stores this track + public Filter TrackFilter; /// Which file stores this track public string TrackFile; /// Starting at which byte is this track stored @@ -471,6 +474,8 @@ namespace DiscImageChef.ImagePlugins public int TrackBytesPerSector; /// How many main channel bytes per sector are in the file with this track public int TrackRawBytesPerSector; + /// Which filter stores this track's subchannel + public Filter TrackSubchannelFilter; /// Which file stores this track's subchannel public string TrackSubchannelFile; /// Starting at which byte are this track's subchannel stored diff --git a/DiscImageChef.DiscImages/Nero.cs b/DiscImageChef.DiscImages/Nero.cs index be9ca3de..a9d21d0a 100644 --- a/DiscImageChef.DiscImages/Nero.cs +++ b/DiscImageChef.DiscImages/Nero.cs @@ -35,6 +35,7 @@ using System.IO; using System.Collections.Generic; using DiscImageChef.Console; using DiscImageChef.CommonTypes; +using DiscImageChef.Filters; namespace DiscImageChef.ImagePlugins { @@ -834,9 +835,8 @@ namespace DiscImageChef.ImagePlugins #region Internal variables - string _imagePath; - FileStream imageStream; - FileInfo imageInfo; + Filter _imageFilter; + Stream imageStream; bool imageNewFormat; Dictionary neroSessions; NeroV1Cuesheet neroCuesheetV1; @@ -867,7 +867,6 @@ namespace DiscImageChef.ImagePlugins { Name = "Nero Burning ROM image"; PluginUUID = new Guid("D160F9FF-5941-43FC-B037-AD81DD141F05"); - _imagePath = ""; imageNewFormat = false; ImageInfo = new ImageInfo(); ImageInfo.readableSectorTags = new List(); @@ -880,10 +879,9 @@ namespace DiscImageChef.ImagePlugins } // Due to .cue format, this method must parse whole file, ignoring errors (those will be thrown by OpenImage()). - public override bool IdentifyImage(string imagePath) + public override bool IdentifyImage(Filter imageFilter) { - imageInfo = new FileInfo(imagePath); - imageStream = new FileStream(imagePath, FileMode.Open, FileAccess.Read); + imageStream = imageFilter.GetDataForkStream(); BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian; byte[] buffer; @@ -902,33 +900,29 @@ namespace DiscImageChef.ImagePlugins footerV2.ChunkID = BigEndianBitConverter.ToUInt32(buffer, 0); footerV2.FirstChunkOffset = BigEndianBitConverter.ToUInt64(buffer, 4); - DicConsole.DebugWriteLine("Nero plugin", "imageInfo.Length = {0}", imageInfo.Length); + DicConsole.DebugWriteLine("Nero plugin", "imageStream.Length = {0}", imageStream.Length); DicConsole.DebugWriteLine("Nero plugin", "footerV1.ChunkID = 0x{0:X8}", footerV1.ChunkID); DicConsole.DebugWriteLine("Nero plugin", "footerV1.FirstChunkOffset = {0}", footerV1.FirstChunkOffset); DicConsole.DebugWriteLine("Nero plugin", "footerV2.ChunkID = 0x{0:X8}", footerV2.ChunkID); DicConsole.DebugWriteLine("Nero plugin", "footerV2.FirstChunkOffset = {0}", footerV2.FirstChunkOffset); - if(footerV2.ChunkID == NeroV2FooterID && footerV2.FirstChunkOffset < (ulong)imageInfo.Length) + if(footerV2.ChunkID == NeroV2FooterID && footerV2.FirstChunkOffset < (ulong)imageStream.Length) { - imageStream.Close(); return true; } - if(footerV1.ChunkID == NeroV1FooterID && footerV1.FirstChunkOffset < (ulong)imageInfo.Length) + if(footerV1.ChunkID == NeroV1FooterID && footerV1.FirstChunkOffset < (ulong)imageStream.Length) { - imageStream.Close(); return true; } - imageStream.Close(); return false; } - public override bool OpenImage(string imagePath) + public override bool OpenImage(Filter imageFilter) { try { - imageInfo = new FileInfo(imagePath); - imageStream = new FileStream(imagePath, FileMode.Open, FileAccess.Read); + imageStream = imageFilter.GetDataForkStream(); BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian; byte[] buffer; @@ -947,21 +941,18 @@ namespace DiscImageChef.ImagePlugins footerV2.ChunkID = BigEndianBitConverter.ToUInt32(buffer, 0); footerV2.FirstChunkOffset = BigEndianBitConverter.ToUInt64(buffer, 4); - DicConsole.DebugWriteLine("Nero plugin", "imageInfo.Length = {0}", imageInfo.Length); + DicConsole.DebugWriteLine("Nero plugin", "imageStream.Length = {0}", imageStream.Length); DicConsole.DebugWriteLine("Nero plugin", "footerV1.ChunkID = 0x{0:X8} (\"{1}\")", footerV1.ChunkID, System.Text.Encoding.ASCII.GetString(BigEndianBitConverter.GetBytes(footerV1.ChunkID))); DicConsole.DebugWriteLine("Nero plugin", "footerV1.FirstChunkOffset = {0}", footerV1.FirstChunkOffset); DicConsole.DebugWriteLine("Nero plugin", "footerV2.ChunkID = 0x{0:X8} (\"{1}\")", footerV2.ChunkID, System.Text.Encoding.ASCII.GetString(BigEndianBitConverter.GetBytes(footerV2.ChunkID))); DicConsole.DebugWriteLine("Nero plugin", "footerV2.FirstChunkOffset = {0}", footerV2.FirstChunkOffset); - if(footerV1.ChunkID == NeroV1FooterID && footerV1.FirstChunkOffset < (ulong)imageInfo.Length) + if(footerV1.ChunkID == NeroV1FooterID && footerV1.FirstChunkOffset < (ulong)imageStream.Length) imageNewFormat = false; - else if(footerV2.ChunkID == NeroV2FooterID && footerV2.FirstChunkOffset < (ulong)imageInfo.Length) + else if(footerV2.ChunkID == NeroV2FooterID && footerV2.FirstChunkOffset < (ulong)imageStream.Length) imageNewFormat = true; else - { - imageStream.Close(); - return true; - } + return false; if(imageNewFormat) imageStream.Seek((long)footerV2.FirstChunkOffset, SeekOrigin.Begin); @@ -1476,9 +1467,9 @@ namespace DiscImageChef.ImagePlugins ImageInfo.imageHasPartitions = true; ImageInfo.imageHasSessions = true; ImageInfo.imageCreator = null; - ImageInfo.imageCreationTime = imageInfo.CreationTimeUtc; - ImageInfo.imageLastModificationTime = imageInfo.LastWriteTimeUtc; - ImageInfo.imageName = Path.GetFileNameWithoutExtension(imagePath); + ImageInfo.imageCreationTime = imageFilter.GetCreationTime(); + ImageInfo.imageLastModificationTime = imageFilter.GetLastWriteTime(); + ImageInfo.imageName = Path.GetFileNameWithoutExtension(imageFilter.GetFilename()); ImageInfo.imageComments = null; ImageInfo.mediaManufacturer = null; ImageInfo.mediaModel = null; @@ -1542,7 +1533,8 @@ namespace DiscImageChef.ImagePlugins _track.TrackSession = currentsession; _track.TrackStartSector = _neroTrack.StartLBA; _track.TrackType = NeroTrackModeToTrackType((DAOMode)_neroTrack.Mode); - _track.TrackFile = imagePath; + _track.TrackFile = imageFilter.GetFilename(); + _track.TrackFilter = imageFilter; _track.TrackFileOffset = _neroTrack.Offset; _track.TrackFileType = "BINARY"; _track.TrackSubchannelType = TrackSubchannelType.None; @@ -1588,7 +1580,8 @@ namespace DiscImageChef.ImagePlugins if(_track.TrackSubchannelType == TrackSubchannelType.RawInterleaved) { - _track.TrackSubchannelFile = _imagePath; + _track.TrackSubchannelFilter = imageFilter; + _track.TrackSubchannelFile = imageFilter.GetFilename(); _track.TrackSubchannelOffset = _neroTrack.Offset; } @@ -1664,8 +1657,7 @@ namespace DiscImageChef.ImagePlugins } } - _imagePath = imagePath; - imageStream.Close(); + _imageFilter = imageFilter; if(ImageInfo.mediaType == MediaType.Unknown || ImageInfo.mediaType == MediaType.CD) { @@ -1898,26 +1890,23 @@ namespace DiscImageChef.ImagePlugins byte[] buffer = new byte[sector_size * length]; - imageStream = new FileStream(_imagePath, FileMode.Open, FileAccess.Read); - using(BinaryReader br = new BinaryReader(imageStream)) + imageStream = _imageFilter.GetDataForkStream(); + BinaryReader br = new BinaryReader(imageStream); + br.BaseStream.Seek((long)_track.Offset + (long)(sectorAddress * (sector_offset + sector_size + sector_skip)), SeekOrigin.Begin); + if(sector_offset == 0 && sector_skip == 0) + buffer = br.ReadBytes((int)(sector_size * length)); + else { - br.BaseStream.Seek((long)_track.Offset + (long)(sectorAddress * (sector_offset + sector_size + sector_skip)), SeekOrigin.Begin); - if(sector_offset == 0 && sector_skip == 0) - buffer = br.ReadBytes((int)(sector_size * length)); - else + for(int i = 0; i < length; i++) { - for(int i = 0; i < length; i++) - { - byte[] sector; - br.BaseStream.Seek(sector_offset, SeekOrigin.Current); - sector = br.ReadBytes((int)sector_size); - br.BaseStream.Seek(sector_skip, SeekOrigin.Current); - Array.Copy(sector, 0, buffer, i * sector_size, sector_size); - } + byte[] sector; + br.BaseStream.Seek(sector_offset, SeekOrigin.Current); + sector = br.ReadBytes((int)sector_size); + br.BaseStream.Seek(sector_skip, SeekOrigin.Current); + Array.Copy(sector, 0, buffer, i * sector_size, sector_size); } } - imageStream.Close(); return buffer; } @@ -2134,26 +2123,23 @@ namespace DiscImageChef.ImagePlugins byte[] buffer = new byte[sector_size * length]; - imageStream = new FileStream(_imagePath, FileMode.Open, FileAccess.Read); - using(BinaryReader br = new BinaryReader(imageStream)) + imageStream = _imageFilter.GetDataForkStream(); + BinaryReader br = new BinaryReader(imageStream); + br.BaseStream.Seek((long)_track.Offset + (long)(sectorAddress * (sector_offset + sector_size + sector_skip)), SeekOrigin.Begin); + if(sector_offset == 0 && sector_skip == 0) + buffer = br.ReadBytes((int)(sector_size * length)); + else { - br.BaseStream.Seek((long)_track.Offset + (long)(sectorAddress * (sector_offset + sector_size + sector_skip)), SeekOrigin.Begin); - if(sector_offset == 0 && sector_skip == 0) - buffer = br.ReadBytes((int)(sector_size * length)); - else + for(int i = 0; i < length; i++) { - for(int i = 0; i < length; i++) - { - byte[] sector; - br.BaseStream.Seek(sector_offset, SeekOrigin.Current); - sector = br.ReadBytes((int)sector_size); - br.BaseStream.Seek(sector_skip, SeekOrigin.Current); - Array.Copy(sector, 0, buffer, i * sector_size, sector_size); - } + byte[] sector; + br.BaseStream.Seek(sector_offset, SeekOrigin.Current); + sector = br.ReadBytes((int)sector_size); + br.BaseStream.Seek(sector_skip, SeekOrigin.Current); + Array.Copy(sector, 0, buffer, i * sector_size, sector_size); } } - imageStream.Close(); return buffer; } @@ -2242,7 +2228,7 @@ namespace DiscImageChef.ImagePlugins byte[] buffer = new byte[sector_size * length]; - imageStream = new FileStream(_imagePath, FileMode.Open, FileAccess.Read); + imageStream = _imageFilter.GetDataForkStream(); BinaryReader br = new BinaryReader(imageStream); br.BaseStream.Seek((long)_track.Offset + (long)(sectorAddress * (sector_offset + sector_size + sector_skip)), SeekOrigin.Begin); @@ -2262,7 +2248,6 @@ namespace DiscImageChef.ImagePlugins } } - imageStream.Close(); return buffer; } diff --git a/DiscImageChef.DiscImages/Parallels.cs b/DiscImageChef.DiscImages/Parallels.cs index 70c1ae60..d5e97e79 100644 --- a/DiscImageChef.DiscImages/Parallels.cs +++ b/DiscImageChef.DiscImages/Parallels.cs @@ -38,6 +38,7 @@ using DiscImageChef.ImagePlugins; using System.Linq; using DiscImageChef.CommonTypes; using DiscImageChef.Console; +using DiscImageChef.Filters; namespace DiscImageChef.DiscImages { @@ -116,7 +117,7 @@ namespace DiscImageChef.DiscImages long dataOffset; uint clusterBytes; bool empty; - FileStream imageStream; + Stream imageStream; Dictionary sectorCache; @@ -150,9 +151,9 @@ namespace DiscImageChef.DiscImages ImageInfo.driveFirmwareRevision = null; } - public override bool IdentifyImage(string imagePath) + public override bool IdentifyImage(Filter imageFilter) { - FileStream stream = new FileStream(imagePath, FileMode.Open, FileAccess.Read); + Stream stream = imageFilter.GetDataForkStream(); stream.Seek(0, SeekOrigin.Begin); if(stream.Length < 512) @@ -169,9 +170,9 @@ namespace DiscImageChef.DiscImages return ParallelsMagic.SequenceEqual(pHdr.magic) || ParallelsExtMagic.SequenceEqual(pHdr.magic); } - public override bool OpenImage(string imagePath) + public override bool OpenImage(Filter imageFilter) { - FileStream stream = new FileStream(imagePath, FileMode.Open, FileAccess.Read); + Stream stream = imageFilter.GetDataForkStream(); stream.Seek(0, SeekOrigin.Begin); if(stream.Length < 512) @@ -217,10 +218,9 @@ namespace DiscImageChef.DiscImages empty = (pHdr.flags & ParallelsEmpty) == ParallelsEmpty; - FileInfo fi = new FileInfo(imagePath); - ImageInfo.imageCreationTime = fi.CreationTimeUtc; - ImageInfo.imageLastModificationTime = fi.LastWriteTimeUtc; - ImageInfo.imageName = Path.GetFileNameWithoutExtension(imagePath); + ImageInfo.imageCreationTime = imageFilter.GetCreationTime(); + ImageInfo.imageLastModificationTime = imageFilter.GetLastWriteTime(); + ImageInfo.imageName = Path.GetFileNameWithoutExtension(imageFilter.GetFilename()); ImageInfo.sectors = pHdr.sectors; ImageInfo.sectorSize = 512; ImageInfo.xmlMediaType = XmlMediaType.BlockMedia; diff --git a/DiscImageChef.DiscImages/QCOW.cs b/DiscImageChef.DiscImages/QCOW.cs index 762336db..7410b252 100644 --- a/DiscImageChef.DiscImages/QCOW.cs +++ b/DiscImageChef.DiscImages/QCOW.cs @@ -36,6 +36,7 @@ using System.IO; using System.Runtime.InteropServices; using DiscImageChef.CommonTypes; using DiscImageChef.Console; +using DiscImageChef.Filters; namespace DiscImageChef.ImagePlugins { @@ -128,7 +129,7 @@ namespace DiscImageChef.ImagePlugins int maxL2TableCache; int maxClusterCache; - FileStream imageStream; + Stream imageStream; public QCOW() { @@ -157,9 +158,9 @@ namespace DiscImageChef.ImagePlugins ImageInfo.driveFirmwareRevision = null; } - public override bool IdentifyImage(string imagePath) + public override bool IdentifyImage(Filter imageFilter) { - FileStream stream = new FileStream(imagePath, FileMode.Open, FileAccess.Read); + Stream stream = imageFilter.GetDataForkStream(); stream.Seek(0, SeekOrigin.Begin); if(stream.Length < 512) @@ -172,9 +173,9 @@ namespace DiscImageChef.ImagePlugins return qHdr.magic == QCowMagic && qHdr.version == QCowVersion; } - public override bool OpenImage(string imagePath) + public override bool OpenImage(Filter imageFilter) { - FileStream stream = new FileStream(imagePath, FileMode.Open, FileAccess.Read); + Stream stream = imageFilter.GetDataForkStream(); stream.Seek(0, SeekOrigin.Begin); if(stream.Length < 512) @@ -278,13 +279,12 @@ namespace DiscImageChef.ImagePlugins l2TableCache = new Dictionary(); clusterCache = new Dictionary(); - FileInfo fi = new FileInfo(imagePath); - ImageInfo.imageCreationTime = fi.CreationTimeUtc; + ImageInfo.imageCreationTime = imageFilter.GetCreationTime(); if(qHdr.mtime > 0) ImageInfo.imageLastModificationTime = DateHandlers.UNIXUnsignedToDateTime(qHdr.mtime); else - ImageInfo.imageLastModificationTime = fi.LastWriteTimeUtc; - ImageInfo.imageName = Path.GetFileNameWithoutExtension(imagePath); + ImageInfo.imageLastModificationTime = imageFilter.GetLastWriteTime(); + ImageInfo.imageName = Path.GetFileNameWithoutExtension(imageFilter.GetFilename()); ImageInfo.sectors = qHdr.size / 512; ImageInfo.sectorSize = 512; ImageInfo.xmlMediaType = XmlMediaType.BlockMedia; diff --git a/DiscImageChef.DiscImages/QCOW2.cs b/DiscImageChef.DiscImages/QCOW2.cs index b2deb535..90c2fd29 100644 --- a/DiscImageChef.DiscImages/QCOW2.cs +++ b/DiscImageChef.DiscImages/QCOW2.cs @@ -36,6 +36,7 @@ using System.IO; using System.Runtime.InteropServices; using DiscImageChef.CommonTypes; using DiscImageChef.Console; +using DiscImageChef.Filters; namespace DiscImageChef.ImagePlugins { @@ -158,7 +159,7 @@ namespace DiscImageChef.ImagePlugins int maxL2TableCache; int maxClusterCache; - FileStream imageStream; + Stream imageStream; public QCOW2() { @@ -187,9 +188,9 @@ namespace DiscImageChef.ImagePlugins ImageInfo.driveFirmwareRevision = null; } - public override bool IdentifyImage(string imagePath) + public override bool IdentifyImage(Filter imageFilter) { - FileStream stream = new FileStream(imagePath, FileMode.Open, FileAccess.Read); + Stream stream = imageFilter.GetDataForkStream(); stream.Seek(0, SeekOrigin.Begin); if(stream.Length < 512) @@ -205,9 +206,9 @@ namespace DiscImageChef.ImagePlugins return qHdr.magic == QCowMagic && (qHdr.version == QCowVersion2 || qHdr.version == QCowVersion3); } - public override bool OpenImage(string imagePath) + public override bool OpenImage(Filter imageFilter) { - FileStream stream = new FileStream(imagePath, FileMode.Open, FileAccess.Read); + Stream stream = imageFilter.GetDataForkStream(); stream.Seek(0, SeekOrigin.Begin); if(stream.Length < 512) @@ -322,10 +323,9 @@ namespace DiscImageChef.ImagePlugins l2TableCache = new Dictionary(); clusterCache = new Dictionary(); - FileInfo fi = new FileInfo(imagePath); - ImageInfo.imageCreationTime = fi.CreationTimeUtc; - ImageInfo.imageLastModificationTime = fi.LastWriteTimeUtc; - ImageInfo.imageName = Path.GetFileNameWithoutExtension(imagePath); + ImageInfo.imageCreationTime = imageFilter.GetCreationTime(); + ImageInfo.imageLastModificationTime = imageFilter.GetLastWriteTime(); + ImageInfo.imageName = Path.GetFileNameWithoutExtension(imageFilter.GetFilename()); ImageInfo.sectors = qHdr.size / 512; ImageInfo.sectorSize = 512; ImageInfo.xmlMediaType = XmlMediaType.BlockMedia; diff --git a/DiscImageChef.DiscImages/QED.cs b/DiscImageChef.DiscImages/QED.cs index af5a2523..84fcbea8 100644 --- a/DiscImageChef.DiscImages/QED.cs +++ b/DiscImageChef.DiscImages/QED.cs @@ -36,6 +36,7 @@ using System.IO; using System.Runtime.InteropServices; using DiscImageChef.CommonTypes; using DiscImageChef.Console; +using DiscImageChef.Filters; namespace DiscImageChef.ImagePlugins { @@ -141,7 +142,7 @@ namespace DiscImageChef.ImagePlugins uint maxL2TableCache; uint maxClusterCache; - FileStream imageStream; + Stream imageStream; public QED() { @@ -170,9 +171,9 @@ namespace DiscImageChef.ImagePlugins ImageInfo.driveFirmwareRevision = null; } - public override bool IdentifyImage(string imagePath) + public override bool IdentifyImage(Filter imageFilter) { - FileStream stream = new FileStream(imagePath, FileMode.Open, FileAccess.Read); + Stream stream = imageFilter.GetDataForkStream(); stream.Seek(0, SeekOrigin.Begin); if(stream.Length < 512) @@ -189,9 +190,9 @@ namespace DiscImageChef.ImagePlugins return qHdr.magic == QedMagic; } - public override bool OpenImage(string imagePath) + public override bool OpenImage(Filter imageFilter) { - FileStream stream = new FileStream(imagePath, FileMode.Open, FileAccess.Read); + Stream stream = imageFilter.GetDataForkStream(); stream.Seek(0, SeekOrigin.Begin); if(stream.Length < 512) @@ -289,10 +290,9 @@ namespace DiscImageChef.ImagePlugins l2TableCache = new Dictionary(); clusterCache = new Dictionary(); - FileInfo fi = new FileInfo(imagePath); - ImageInfo.imageCreationTime = fi.CreationTimeUtc; - ImageInfo.imageLastModificationTime = fi.LastWriteTimeUtc; - ImageInfo.imageName = Path.GetFileNameWithoutExtension(imagePath); + ImageInfo.imageCreationTime = imageFilter.GetCreationTime(); + ImageInfo.imageLastModificationTime = imageFilter.GetLastWriteTime(); + ImageInfo.imageName = Path.GetFileNameWithoutExtension(imageFilter.GetFilename()); ImageInfo.sectors = qHdr.image_size / 512; ImageInfo.sectorSize = 512; ImageInfo.xmlMediaType = XmlMediaType.BlockMedia; diff --git a/DiscImageChef.DiscImages/TeleDisk.cs b/DiscImageChef.DiscImages/TeleDisk.cs index 151feecd..5a618af7 100644 --- a/DiscImageChef.DiscImages/TeleDisk.cs +++ b/DiscImageChef.DiscImages/TeleDisk.cs @@ -35,6 +35,7 @@ using System.IO; using System.Collections.Generic; using DiscImageChef.Console; using DiscImageChef.CommonTypes; +using DiscImageChef.Filters; namespace DiscImageChef.ImagePlugins { @@ -224,14 +225,14 @@ namespace DiscImageChef.ImagePlugins SectorsWhereCRCHasFailed = new List(); } - public override bool IdentifyImage(string imagePath) + public override bool IdentifyImage(Filter imageFilter) { header = new TD0Header(); byte[] headerBytes = new byte[12]; - FileStream stream = new FileStream(imagePath, FileMode.Open, FileAccess.Read); + Stream stream = imageFilter.GetDataForkStream(); + stream.Seek(0, SeekOrigin.Begin); stream.Read(headerBytes, 0, 12); - stream.Close(); header.signature = BitConverter.ToUInt16(headerBytes, 0); @@ -284,11 +285,12 @@ namespace DiscImageChef.ImagePlugins return true; } - public override bool OpenImage(string imagePath) + public override bool OpenImage(Filter imageFilter) { header = new TD0Header(); byte[] headerBytes = new byte[12]; - FileStream stream = new FileStream(imagePath, FileMode.Open, FileAccess.Read); + Stream stream = imageFilter.GetDataForkStream(); + stream.Seek(0, SeekOrigin.Begin); stream.Read(headerBytes, 0, 12); @@ -307,7 +309,7 @@ namespace DiscImageChef.ImagePlugins header.sides = headerBytes[9]; header.crc = BitConverter.ToUInt16(headerBytes, 10); - ImageInfo.imageName = Path.GetFileNameWithoutExtension(imagePath); + ImageInfo.imageName = Path.GetFileNameWithoutExtension(imageFilter.GetFilename()); ImageInfo.imageVersion = string.Format("{0}.{1}", (header.version & 0xF0) >> 4, header.version & 0x0F); ImageInfo.imageApplication = ImageInfo.imageVersion; @@ -407,10 +409,9 @@ namespace DiscImageChef.ImagePlugins commentHeader.hour, commentHeader.minute, commentHeader.second, DateTimeKind.Unspecified); } - FileInfo fi = new FileInfo(imagePath); if(ImageInfo.imageCreationTime == DateTime.MinValue) - ImageInfo.imageCreationTime = fi.CreationTimeUtc; - ImageInfo.imageLastModificationTime = fi.LastWriteTimeUtc; + ImageInfo.imageCreationTime = imageFilter.GetCreationTime(); + ImageInfo.imageLastModificationTime = imageFilter.GetLastWriteTime(); DicConsole.DebugWriteLine("TeleDisk plugin", "Image created on {0}", ImageInfo.imageCreationTime); DicConsole.DebugWriteLine("TeleDisk plugin", "Image modified on {0}", ImageInfo.imageLastModificationTime); @@ -572,8 +573,6 @@ namespace DiscImageChef.ImagePlugins ImageInfo.sectors = (ulong)sectorsData.Count; ImageInfo.mediaType = DecodeTeleDiskDiskType(); - stream.Close(); - ImageInfo.xmlMediaType = XmlMediaType.BlockMedia; DicConsole.VerboseWriteLine("TeleDisk image contains a disk of type {0}", ImageInfo.mediaType); diff --git a/DiscImageChef.DiscImages/UDIF.cs b/DiscImageChef.DiscImages/UDIF.cs index ae4d7458..17326b71 100644 --- a/DiscImageChef.DiscImages/UDIF.cs +++ b/DiscImageChef.DiscImages/UDIF.cs @@ -39,6 +39,7 @@ using Claunia.RsrcFork; using DiscImageChef.CommonTypes; using DiscImageChef.Console; using DiscImageChef.ImagePlugins; +using DiscImageChef.Filters; namespace DiscImageChef.DiscImages { @@ -146,7 +147,7 @@ namespace DiscImageChef.DiscImages const uint sectorSize = 512; uint maxCachedSectors = MaxCacheSize / sectorSize; - FileStream imageStream; + Stream imageStream; public UDIF() { @@ -175,9 +176,9 @@ namespace DiscImageChef.DiscImages ImageInfo.driveFirmwareRevision = null; } - public override bool IdentifyImage(string imagePath) + public override bool IdentifyImage(Filter imageFilter) { - FileStream stream = new FileStream(imagePath, FileMode.Open, FileAccess.Read); + Stream stream = imageFilter.GetDataForkStream(); if(stream.Length < 512) return false; @@ -201,9 +202,9 @@ namespace DiscImageChef.DiscImages return footer.signature == UDIF_Signature; } - public override bool OpenImage(string imagePath) + public override bool OpenImage(Filter imageFilter) { - FileStream stream = new FileStream(imagePath, FileMode.Open, FileAccess.Read); + Stream stream = imageFilter.GetDataForkStream(); if(stream.Length < 512) return false; @@ -411,10 +412,9 @@ namespace DiscImageChef.DiscImages sectorCache = new Dictionary(); imageStream = stream; - FileInfo fi = new FileInfo(imagePath); - ImageInfo.imageCreationTime = fi.CreationTimeUtc; - ImageInfo.imageLastModificationTime = fi.LastWriteTimeUtc; - ImageInfo.imageName = Path.GetFileNameWithoutExtension(imagePath); + ImageInfo.imageCreationTime = imageFilter.GetCreationTime(); + ImageInfo.imageLastModificationTime = imageFilter.GetLastWriteTime(); + ImageInfo.imageName = Path.GetFileNameWithoutExtension(imageFilter.GetFilename()); ImageInfo.sectorSize = sectorSize; ImageInfo.xmlMediaType = XmlMediaType.BlockMedia; ImageInfo.mediaType = MediaType.GENERIC_HDD; diff --git a/DiscImageChef.DiscImages/VDI.cs b/DiscImageChef.DiscImages/VDI.cs index 802314cf..b30c7446 100644 --- a/DiscImageChef.DiscImages/VDI.cs +++ b/DiscImageChef.DiscImages/VDI.cs @@ -37,6 +37,7 @@ using System.Runtime.InteropServices; using DiscImageChef.CommonTypes; using DiscImageChef.Console; using DiscImageChef.ImagePlugins; +using DiscImageChef.Filters; namespace DiscImageChef.DiscImages { @@ -100,7 +101,7 @@ namespace DiscImageChef.DiscImages VDIHeader vHdr; uint[] IBM; - FileStream imageStream; + Stream imageStream; Dictionary sectorCache; @@ -134,9 +135,9 @@ namespace DiscImageChef.DiscImages ImageInfo.driveFirmwareRevision = null; } - public override bool IdentifyImage(string imagePath) + public override bool IdentifyImage(Filter imageFilter) { - FileStream stream = new FileStream(imagePath, FileMode.Open, FileAccess.Read); + Stream stream = imageFilter.GetDataForkStream(); stream.Seek(0, SeekOrigin.Begin); if(stream.Length < 512) @@ -153,9 +154,9 @@ namespace DiscImageChef.DiscImages return vHdr.magic == VDIMagic; } - public override bool OpenImage(string imagePath) + public override bool OpenImage(Filter imageFilter) { - FileStream stream = new FileStream(imagePath, FileMode.Open, FileAccess.Read); + Stream stream = imageFilter.GetDataForkStream(); stream.Seek(0, SeekOrigin.Begin); if(stream.Length < 512) @@ -201,10 +202,9 @@ namespace DiscImageChef.DiscImages sectorCache = new Dictionary(); - FileInfo fi = new FileInfo(imagePath); - ImageInfo.imageCreationTime = fi.CreationTimeUtc; - ImageInfo.imageLastModificationTime = fi.LastWriteTimeUtc; - ImageInfo.imageName = Path.GetFileNameWithoutExtension(imagePath); + ImageInfo.imageCreationTime = imageFilter.GetCreationTime(); + ImageInfo.imageLastModificationTime = imageFilter.GetLastWriteTime(); + ImageInfo.imageName = Path.GetFileNameWithoutExtension(imageFilter.GetFilename()); ImageInfo.sectors = vHdr.size / vHdr.sectorSize; ImageInfo.imageSize = vHdr.size; ImageInfo.sectorSize = vHdr.sectorSize; diff --git a/DiscImageChef.DiscImages/VHD.cs b/DiscImageChef.DiscImages/VHD.cs index 519f543f..134d83f5 100644 --- a/DiscImageChef.DiscImages/VHD.cs +++ b/DiscImageChef.DiscImages/VHD.cs @@ -37,6 +37,7 @@ using System.Text; using System.Runtime.InteropServices; using DiscImageChef.Console; using DiscImageChef.CommonTypes; +using DiscImageChef.Filters; namespace DiscImageChef.ImagePlugins { @@ -354,7 +355,7 @@ namespace DiscImageChef.ImagePlugins DynamicDiskHeader thisDynamic; DateTime thisDateTime; DateTime parentDateTime; - string thisPath; + Filter thisFilter; uint[] blockAllocationTable; uint bitmapSize; byte[][] locatorEntriesData; @@ -391,9 +392,9 @@ namespace DiscImageChef.ImagePlugins #region public methods - public override bool IdentifyImage(string imagePath) + public override bool IdentifyImage(Filter imageFilter) { - FileStream imageStream = new FileStream(imagePath, FileMode.Open, FileAccess.Read); + Stream imageStream = imageFilter.GetDataForkStream(); ulong headerCookie; ulong footerCookie; @@ -416,9 +417,9 @@ namespace DiscImageChef.ImagePlugins return (headerCookie == ImageCookie || footerCookie == ImageCookie); } - public override bool OpenImage(string imagePath) + public override bool OpenImage(Filter imageFilter) { - FileStream imageStream = new FileStream(imagePath, FileMode.Open, FileAccess.Read); + Stream imageStream = imageFilter.GetDataForkStream(); byte[] header = new byte[512]; byte[] footer; @@ -622,15 +623,14 @@ namespace DiscImageChef.ImagePlugins } } - thisPath = imagePath; + thisFilter = imageFilter; ImageInfo.imageSize = thisFooter.currentSize; ImageInfo.sectors = thisFooter.currentSize / 512; ImageInfo.sectorSize = 512; - FileInfo fi = new FileInfo(imagePath); - ImageInfo.imageCreationTime = fi.CreationTimeUtc; + ImageInfo.imageCreationTime = imageFilter.GetCreationTime(); ImageInfo.imageLastModificationTime = thisDateTime; - ImageInfo.imageName = Path.GetFileNameWithoutExtension(imagePath); + ImageInfo.imageName = Path.GetFileNameWithoutExtension(imageFilter.GetFilename()); if(thisFooter.diskType == typeDynamic || thisFooter.diskType == typeDifferencing) { @@ -782,7 +782,6 @@ namespace DiscImageChef.ImagePlugins case typeDynamic: { // Nothing to do here, really. - imageStream.Close(); return true; } case typeDifferencing: @@ -820,6 +819,7 @@ namespace DiscImageChef.ImagePlugins int currentLocator = 0; bool locatorFound = false; string parentPath = null; + FiltersList filters = new FiltersList(); while(!locatorFound && currentLocator < 8) { @@ -848,8 +848,10 @@ namespace DiscImageChef.ImagePlugins if(parentPath != null) { DicConsole.DebugWriteLine("VirtualPC plugin", "Possible parent path: \"{0}\"", parentPath); + Filter parentFilter = filters.GetFilter(Path.Combine(imageFilter.GetParentFolder(), parentPath)); - locatorFound |= File.Exists(parentPath); + if(parentFilter != null) + locatorFound = true; if(!locatorFound) parentPath = null; @@ -862,15 +864,19 @@ namespace DiscImageChef.ImagePlugins else { parentImage = new VHD(); + Filter parentFilter = filters.GetFilter(Path.Combine(imageFilter.GetParentFolder(), parentPath)); + + if(parentFilter == null) + throw new ImageNotSupportedException("(VirtualPC plugin): Cannot find parent image filter"); /* PluginBase plugins = new PluginBase(); plugins.RegisterAllPlugins(); if (!plugins.ImagePluginsList.TryGetValue(Name.ToLower(), out parentImage)) throw new SystemException("(VirtualPC plugin): Unable to open myself");*/ - if(!parentImage.IdentifyImage(parentPath)) + if(!parentImage.IdentifyImage(parentFilter)) throw new ImageNotSupportedException("(VirtualPC plugin): Parent image is not a Virtual PC disk image"); - if(!parentImage.OpenImage(parentPath)) + if(!parentImage.OpenImage(parentFilter)) throw new ImageNotSupportedException("(VirtualPC plugin): Cannot open parent disk image"); // While specification says that parent and child disk images should contain UUID relationship @@ -991,13 +997,11 @@ namespace DiscImageChef.ImagePlugins int bitmapByte = (int)Math.Floor((double)sectorInBlock / 8); int bitmapBit = (int)(sectorInBlock % 8); - FileStream thisStream = new FileStream(thisPath, FileMode.Open, FileAccess.Read); + Stream thisStream = thisFilter.GetDataForkStream(); thisStream.Seek(blockOffset, SeekOrigin.Begin); thisStream.Read(bitmap, 0, (int)bitmapSize * 512); - thisStream.Close(); - byte mask = (byte)(1 << (7 - bitmapBit)); bool dirty = false || (bitmap[bitmapByte] & mask) == mask; @@ -1023,13 +1027,11 @@ namespace DiscImageChef.ImagePlugins byte[] data = new byte[512]; uint sectorOffset = blockAllocationTable[blockNumber] + bitmapSize + sectorInBlock; - thisStream = new FileStream(thisPath, FileMode.Open, FileAccess.Read); + thisStream = thisFilter.GetDataForkStream(); thisStream.Seek((sectorOffset * 512), SeekOrigin.Begin); thisStream.Read(data, 0, 512); - thisStream.Close(); - return data; } @@ -1051,15 +1053,14 @@ namespace DiscImageChef.ImagePlugins { case typeFixed: { - FileStream thisStream; + Stream thisStream; byte[] data = new byte[512 * length]; - thisStream = new FileStream(thisPath, FileMode.Open, FileAccess.Read); + thisStream = thisFilter.GetDataForkStream(); thisStream.Seek((long)(sectorAddress * 512), SeekOrigin.Begin); thisStream.Read(data, 0, (int)(512 * length)); - thisStream.Close(); return data; } // Contrary to Microsoft's specifications that tell us to check the bitmap @@ -1068,7 +1069,7 @@ namespace DiscImageChef.ImagePlugins // as long as it is in the block. case typeDynamic: { - FileStream thisStream; + Stream thisStream; // Block number for BAT searching uint blockNumber = (uint)Math.Floor((double)(sectorAddress / (thisDynamic.blockSize / 512))); @@ -1101,10 +1102,9 @@ namespace DiscImageChef.ImagePlugins // 0xFFFFFFFF means unallocated if(sectorOffset != 0xFFFFFFFF) { - thisStream = new FileStream(thisPath, FileMode.Open, FileAccess.Read); + thisStream = thisFilter.GetDataForkStream(); thisStream.Seek((sectorOffset * 512), SeekOrigin.Begin); thisStream.Read(prefix, 0, (int)(512 * sectorsToReadHere)); - thisStream.Close(); } // If it is unallocated, just fill with zeroes else diff --git a/DiscImageChef.DiscImages/VHDX.cs b/DiscImageChef.DiscImages/VHDX.cs index d935bb4f..57e52c65 100644 --- a/DiscImageChef.DiscImages/VHDX.cs +++ b/DiscImageChef.DiscImages/VHDX.cs @@ -37,6 +37,7 @@ using System.Runtime.InteropServices; using System.Text; using DiscImageChef.CommonTypes; using DiscImageChef.Console; +using DiscImageChef.Filters; namespace DiscImageChef.ImagePlugins { @@ -324,7 +325,7 @@ namespace DiscImageChef.ImagePlugins byte[] sectorBitmap; ImagePlugin parentImage; bool hasParent; - FileStream imageStream; + Stream imageStream; const int MaxCacheSize = 16777216; int maxBlockCache; @@ -364,9 +365,9 @@ namespace DiscImageChef.ImagePlugins #region public methods - public override bool IdentifyImage(string imagePath) + public override bool IdentifyImage(Filter imageFilter) { - FileStream stream = new FileStream(imagePath, FileMode.Open, FileAccess.Read); + Stream stream = imageFilter.GetDataForkStream(); stream.Seek(0, SeekOrigin.Begin); if(stream.Length < 512) @@ -383,9 +384,9 @@ namespace DiscImageChef.ImagePlugins return vhdxId.signature == VHDXSignature; } - public override bool OpenImage(string imagePath) + public override bool OpenImage(Filter imageFilter) { - FileStream stream = new FileStream(imagePath, FileMode.Open, FileAccess.Read); + Stream stream = imageFilter.GetDataForkStream(); stream.Seek(0, SeekOrigin.Begin); if(stream.Length < 512) @@ -601,6 +602,8 @@ namespace DiscImageChef.ImagePlugins { parentImage = new VHDX(); bool parentWorks = false; + FiltersList filtersList = new FiltersList(); + Filter parentFilter; foreach(VHDXParentLocatorEntry parentEntry in vPars) { @@ -618,7 +621,8 @@ namespace DiscImageChef.ImagePlugins try { - if(parentImage.OpenImage(entryValue)) + parentFilter = filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), entryValue)); + if(parentFilter != null && parentImage.OpenImage(parentFilter)) { parentWorks = true; break; @@ -626,11 +630,12 @@ namespace DiscImageChef.ImagePlugins } catch { parentWorks = false; } - string relEntry = Path.Combine(Path.GetDirectoryName(imagePath), entryValue); + string relEntry = Path.Combine(Path.GetDirectoryName(imageFilter.GetPath()), entryValue); try { - if(parentImage.OpenImage(relEntry)) + parentFilter = filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), relEntry)); + if(parentFilter != null && parentImage.OpenImage(parentFilter)) { parentWorks = true; break; @@ -648,7 +653,8 @@ namespace DiscImageChef.ImagePlugins try { - if(parentImage.OpenImage(entryValue)) + parentFilter = filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), entryValue)); + if(parentFilter != null && parentImage.OpenImage(parentFilter)) { parentWorks = true; break; @@ -741,10 +747,9 @@ namespace DiscImageChef.ImagePlugins sectorCache = new Dictionary(); blockCache = new Dictionary(); - FileInfo fi = new FileInfo(imagePath); - ImageInfo.imageCreationTime = fi.CreationTimeUtc; - ImageInfo.imageLastModificationTime = fi.LastWriteTimeUtc; - ImageInfo.imageName = Path.GetFileNameWithoutExtension(imagePath); + ImageInfo.imageCreationTime = imageFilter.GetCreationTime(); + ImageInfo.imageLastModificationTime = imageFilter.GetLastWriteTime(); + ImageInfo.imageName = Path.GetFileNameWithoutExtension(imageFilter.GetFilename()); ImageInfo.sectorSize = LogicalSectorSize; ImageInfo.xmlMediaType = XmlMediaType.BlockMedia; ImageInfo.mediaType = MediaType.GENERIC_HDD; diff --git a/DiscImageChef.DiscImages/VMware.cs b/DiscImageChef.DiscImages/VMware.cs index cc165de7..e50e1c29 100644 --- a/DiscImageChef.DiscImages/VMware.cs +++ b/DiscImageChef.DiscImages/VMware.cs @@ -39,6 +39,7 @@ using System.Text.RegularExpressions; using DiscImageChef.CommonTypes; using DiscImageChef.Console; using DiscImageChef.ImagePlugins; +using DiscImageChef.Filters; namespace DiscImageChef.DiscImages { @@ -155,6 +156,7 @@ namespace DiscImageChef.DiscImages public string access; public uint sectors; public string type; + public Filter filter; public string filename; public uint offset; } @@ -179,7 +181,7 @@ namespace DiscImageChef.DiscImages ImagePlugin parentImage; bool hasParent; - string gdPath; + Filter gdFilter; uint[] gTable; ulong grainSize; @@ -211,9 +213,9 @@ namespace DiscImageChef.DiscImages ImageInfo.driveFirmwareRevision = null; } - public override bool IdentifyImage(string imagePath) + public override bool IdentifyImage(Filter imageFilter) { - FileStream stream = new FileStream(imagePath, FileMode.Open, FileAccess.Read); + Stream stream = imageFilter.GetDataForkStream(); byte[] ddfMagic = new byte[0x15]; @@ -252,9 +254,9 @@ namespace DiscImageChef.DiscImages return DDFMagicBytes.SequenceEqual(ddfMagic); } - public override bool OpenImage(string imagePath) + public override bool OpenImage(Filter imageFilter) { - FileStream stream = new FileStream(imagePath, FileMode.Open, FileAccess.Read); + Stream stream = imageFilter.GetDataForkStream(); vmEHdr = new VMwareExtentHeader(); vmCHdr = new VMwareCowHeader(); @@ -289,7 +291,7 @@ namespace DiscImageChef.DiscImages if(vmEHdr.magic == VMwareExtentMagic) { vmEHdrSet = true; - gdPath = imagePath; + gdFilter = imageFilter; if(vmEHdr.descriptorOffset == 0 || vmEHdr.descriptorSize == 0) throw new Exception("Please open VMDK descriptor."); @@ -304,7 +306,7 @@ namespace DiscImageChef.DiscImages } else if(vmCHdr.magic == VMwareCowMagic) { - gdPath = imagePath; + gdFilter = imageFilter; cowD = true; } else @@ -316,9 +318,8 @@ namespace DiscImageChef.DiscImages if(!DDFMagicBytes.SequenceEqual(ddfMagic)) throw new Exception("Not a descriptor."); - FileInfo ddfFi = new FileInfo(imagePath); stream.Seek(0, SeekOrigin.Begin); - byte[] ddfExternal = new byte[ddfFi.Length]; + byte[] ddfExternal = new byte[imageFilter.GetDataForkLength()]; stream.Read(ddfExternal, 0, ddfExternal.Length); ddfStream.Write(ddfExternal, 0, ddfExternal.Length); } @@ -326,10 +327,12 @@ namespace DiscImageChef.DiscImages extents = new Dictionary(); ulong currentSector = 0; + FiltersList filtersList = new FiltersList(); + if(cowD) { int cowCount = 1; - string basePath = Path.Combine(Path.GetDirectoryName(imagePath), Path.GetFileNameWithoutExtension(imagePath)); + string basePath = Path.GetFileNameWithoutExtension(imageFilter.GetBasePath()); while(true) { @@ -342,7 +345,8 @@ namespace DiscImageChef.DiscImages if(!File.Exists(curPath)) break; - FileStream extentStream = new FileStream(curPath, FileMode.Open, FileAccess.Read); + Filter extentFilter = filtersList.GetFilter(curPath); + Stream extentStream = extentFilter.GetDataForkStream(); if(stream.Length > Marshal.SizeOf(vmCHdr)) { @@ -360,12 +364,13 @@ namespace DiscImageChef.DiscImages VMwareExtent newExtent = new VMwareExtent(); newExtent.access = "RW"; - newExtent.filename = curPath; + newExtent.filter = extentFilter; + newExtent.filename = extentFilter.GetFilename(); newExtent.offset = 0; newExtent.sectors = extHdrCow.sectors; newExtent.type = "SPARSE"; - DicConsole.DebugWriteLine("VMware plugin", "{0} {1} {2} \"{3}\" {4}", newExtent.access, newExtent.sectors, newExtent.type, newExtent.filename, newExtent.offset); + DicConsole.DebugWriteLine("VMware plugin", "{0} {1} {2} \"{3}\" {4}", newExtent.access, newExtent.sectors, newExtent.type, newExtent.filter, newExtent.offset); extents.Add(currentSector, newExtent); currentSector += newExtent.sectors; @@ -434,13 +439,13 @@ namespace DiscImageChef.DiscImages VMwareExtent newExtent = new VMwareExtent(); newExtent.access = MatchExtent.Groups["access"].Value; if(!embedded) - newExtent.filename = Path.Combine(Path.GetDirectoryName(imagePath), MatchExtent.Groups["filename"].Value); + newExtent.filter = filtersList.GetFilter(Path.Combine(Path.GetDirectoryName(imageFilter.GetBasePath()), MatchExtent.Groups["filename"].Value)); else - newExtent.filename = imagePath; + newExtent.filter = imageFilter; uint.TryParse(MatchExtent.Groups["offset"].Value, out newExtent.offset); uint.TryParse(MatchExtent.Groups["sectors"].Value, out newExtent.sectors); newExtent.type = MatchExtent.Groups["type"].Value; - DicConsole.DebugWriteLine("VMware plugin", "{0} {1} {2} \"{3}\" {4}", newExtent.access, newExtent.sectors, newExtent.type, newExtent.filename, newExtent.offset); + DicConsole.DebugWriteLine("VMware plugin", "{0} {1} {2} \"{3}\" {4}", newExtent.access, newExtent.sectors, newExtent.type, newExtent.filter, newExtent.offset); extents.Add(currentSector, newExtent); currentSector += newExtent.sectors; @@ -486,8 +491,8 @@ namespace DiscImageChef.DiscImages foreach(VMwareExtent extent in extents.Values) { - if(!File.Exists(extent.filename)) - throw new Exception(string.Format("Extent file {0} not found.", extent.filename)); + if(extent.filter == null) + throw new Exception(string.Format("Extent file {0} not found.", extent.filter)); if(extent.access == "NOACCESS") throw new Exception("Cannot access NOACCESS extents ;)."); @@ -497,11 +502,11 @@ namespace DiscImageChef.DiscImages extent.type != "VMFS" && !cowD) { - FileStream extentStream = new FileStream(extent.filename, FileMode.Open, FileAccess.Read); + Stream extentStream = extent.filter.GetDataForkStream(); extentStream.Seek(0, SeekOrigin.Begin); if(extentStream.Length < sectorSize) - throw new Exception(string.Format("Extent {0} is too small.", extent.filename)); + throw new Exception(string.Format("Extent {0} is too small.", extent.filter)); VMwareExtentHeader extentHdr = new VMwareExtentHeader(); byte[] extentHdr_b = new byte[Marshal.SizeOf(extentHdr)]; @@ -512,7 +517,7 @@ namespace DiscImageChef.DiscImages Marshal.FreeHGlobal(extentHdrPtr); if(extentHdr.magic != VMwareExtentMagic) - throw new Exception(string.Format("{0} is not an VMware extent.", extent.filename)); + throw new Exception(string.Format("{0} is not an VMware extent.", extent.filter)); if(extentHdr.capacity != extent.sectors) throw new Exception(string.Format("Extent contains incorrect number of sectors, {0}. {1} were expected", extentHdr.capacity, extent.sectors)); @@ -524,11 +529,10 @@ namespace DiscImageChef.DiscImages if(!vmEHdrSet) { vmEHdr = extentHdr; - gdPath = extent.filename; + gdFilter = extent.filter; vmEHdrSet = true; } - extentStream.Close(); oneNoFlat = true; } } @@ -609,7 +613,7 @@ namespace DiscImageChef.DiscImages DicConsole.DebugWriteLine("VMware plugin", "{0} sectors in {1} grains in {2} tables", ImageInfo.sectors, grains, gdEntries); - FileStream gdStream = new FileStream(gdPath, FileMode.Open, FileAccess.Read); + Stream gdStream = gdFilter.GetDataForkStream(); gdStream.Seek(gdOffset * sectorSize, SeekOrigin.Begin); @@ -637,27 +641,26 @@ namespace DiscImageChef.DiscImages maxCachedGrains = (uint)(MaxCacheSize / (grainSize * sectorSize)); - gdStream.Close(); grainCache = new Dictionary(); } if(hasParent) { - if(!File.Exists(parentName)) + Filter parentFilter = filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), parentName)); + if(parentFilter == null) throw new Exception(string.Format("Cannot find parent \"{0}\".", parentName)); parentImage = new VMware(); - if(!parentImage.OpenImage(parentName)) + if(!parentImage.OpenImage(parentFilter)) throw new Exception(string.Format("Cannot open parent \"{0}\".", parentName)); } sectorCache = new Dictionary(); - FileInfo fi = new FileInfo(imagePath); - ImageInfo.imageCreationTime = fi.CreationTimeUtc; - ImageInfo.imageLastModificationTime = fi.LastWriteTimeUtc; - ImageInfo.imageName = Path.GetFileNameWithoutExtension(imagePath); + ImageInfo.imageCreationTime = imageFilter.GetCreationTime(); + ImageInfo.imageLastModificationTime = imageFilter.GetLastWriteTime(); + ImageInfo.imageName = Path.GetFileNameWithoutExtension(imageFilter.GetFilename()); ImageInfo.sectorSize = sectorSize; ImageInfo.xmlMediaType = XmlMediaType.BlockMedia; ImageInfo.mediaType = MediaType.GENERIC_HDD; @@ -698,7 +701,7 @@ namespace DiscImageChef.DiscImages if(!extentFound) throw new ArgumentOutOfRangeException(nameof(sectorAddress), string.Format("Sector address {0} not found", sectorAddress)); - FileStream dataStream; + Stream dataStream; if(currentExtent.type == "ZERO") { @@ -713,7 +716,7 @@ namespace DiscImageChef.DiscImages if(currentExtent.type == "FLAT" || currentExtent.type == "VMFS") { - dataStream = new FileStream(currentExtent.filename, FileMode.Open, FileAccess.Read); + dataStream = currentExtent.filter.GetDataForkStream(); dataStream.Seek((long)(currentExtent.offset + ((sectorAddress - extentStartSector) * sectorSize)), SeekOrigin.Begin); sector = new byte[sectorSize]; dataStream.Read(sector, 0, sector.Length); @@ -749,7 +752,7 @@ namespace DiscImageChef.DiscImages if(!grainCache.TryGetValue(grainOff, out grain)) { grain = new byte[sectorSize * grainSize]; - dataStream = new FileStream(currentExtent.filename, FileMode.Open, FileAccess.Read); + dataStream = currentExtent.filter.GetDataForkStream(); dataStream.Seek((long)(((grainOff - extentStartSector) * sectorSize)), SeekOrigin.Begin); dataStream.Read(grain, 0, grain.Length); diff --git a/DiscImageChef.DiscImages/ZZZRawImage.cs b/DiscImageChef.DiscImages/ZZZRawImage.cs index 5060c268..b97eddc9 100644 --- a/DiscImageChef.DiscImages/ZZZRawImage.cs +++ b/DiscImageChef.DiscImages/ZZZRawImage.cs @@ -35,6 +35,7 @@ using System.Collections.Generic; using System.IO; using DiscImageChef.CommonTypes; using DiscImageChef.Console; +using DiscImageChef.Filters; namespace DiscImageChef.ImagePlugins { @@ -43,7 +44,7 @@ namespace DiscImageChef.ImagePlugins { #region Internal variables - string rawImagePath; + Filter rawImageFilter; bool differentTrackZeroSize; #endregion @@ -76,15 +77,13 @@ namespace DiscImageChef.ImagePlugins ImageInfo.driveFirmwareRevision = null; } - public override bool IdentifyImage(string imagePath) + public override bool IdentifyImage(Filter imageFilter) { - FileInfo fi = new FileInfo(imagePath); - // Check if file is not multiple of 512 - if((fi.Length % 512) != 0) + if((imageFilter.GetDataForkLength() % 512) != 0) { // Check known disk sizes with sectors smaller than 512 - switch(fi.Length) + switch(imageFilter.GetDataForkLength()) { case 81664: case 116480: @@ -110,19 +109,17 @@ namespace DiscImageChef.ImagePlugins return true; } - public override bool OpenImage(string imagePath) + public override bool OpenImage(Filter imageFilter) { - FileStream stream = new FileStream(imagePath, FileMode.Open, FileAccess.Read); + Stream stream = imageFilter.GetDataForkStream(); stream.Seek(0, SeekOrigin.Begin); - stream.Close(); - FileInfo fi = new FileInfo(imagePath); - string extension = Path.GetExtension(imagePath).ToLower(); - if(extension == ".iso" && (fi.Length % 2048) == 0) + string extension = Path.GetExtension(imageFilter.GetFilename()).ToLower(); + if(extension == ".iso" && (imageFilter.GetDataForkLength() % 2048) == 0) ImageInfo.sectorSize = 2048; else { - switch(fi.Length) + switch(imageFilter.GetDataForkLength()) { case 242944: case 256256: @@ -171,14 +168,14 @@ namespace DiscImageChef.ImagePlugins } } - ImageInfo.imageSize = (ulong)fi.Length; - ImageInfo.imageCreationTime = fi.CreationTimeUtc; - ImageInfo.imageLastModificationTime = fi.LastWriteTimeUtc; - ImageInfo.imageName = Path.GetFileNameWithoutExtension(imagePath); + ImageInfo.imageSize = (ulong)imageFilter.GetDataForkLength(); + ImageInfo.imageCreationTime = imageFilter.GetCreationTime(); + ImageInfo.imageLastModificationTime = imageFilter.GetLastWriteTime(); + ImageInfo.imageName = Path.GetFileNameWithoutExtension(imageFilter.GetFilename()); differentTrackZeroSize = false; - rawImagePath = imagePath; + rawImageFilter = imageFilter; - switch(fi.Length) + switch(imageFilter.GetDataForkLength()) { case 242944: ImageInfo.sectors = 1898; @@ -276,7 +273,7 @@ namespace DiscImageChef.ImagePlugins } // Sharp X68000 SASI hard disks - if(Path.GetExtension(imagePath).ToLowerInvariant() == ".hdf") + if(extension == ".hdf") { if(ImageInfo.imageSize % 256 == 0) { @@ -331,14 +328,12 @@ namespace DiscImageChef.ImagePlugins byte[] buffer = new byte[length * ImageInfo.sectorSize]; - FileStream stream = new FileStream(rawImagePath, FileMode.Open, FileAccess.Read); + Stream stream = rawImageFilter.GetDataForkStream(); stream.Seek((long)(sectorAddress * ImageInfo.sectorSize), SeekOrigin.Begin); stream.Read(buffer, 0, (int)(length * ImageInfo.sectorSize)); - stream.Close(); - return buffer; } @@ -413,7 +408,7 @@ namespace DiscImageChef.ImagePlugins Track trk = new Track(); trk.TrackBytesPerSector = (int)ImageInfo.sectorSize; trk.TrackEndSector = ImageInfo.sectors - 1; - trk.TrackFile = rawImagePath; + trk.TrackFile = rawImageFilter.GetFilename(); trk.TrackFileOffset = 0; trk.TrackFileType = "BINARY"; trk.TrackRawBytesPerSector = (int)ImageInfo.sectorSize; @@ -440,7 +435,8 @@ namespace DiscImageChef.ImagePlugins Track trk = new Track(); trk.TrackBytesPerSector = (int)ImageInfo.sectorSize; trk.TrackEndSector = ImageInfo.sectors - 1; - trk.TrackFile = rawImagePath; + trk.TrackFilter = rawImageFilter; + trk.TrackFile = rawImageFilter.GetFilename(); trk.TrackFileOffset = 0; trk.TrackFileType = "BINARY"; trk.TrackRawBytesPerSector = (int)ImageInfo.sectorSize; @@ -467,7 +463,8 @@ namespace DiscImageChef.ImagePlugins Track trk = new Track(); trk.TrackBytesPerSector = (int)ImageInfo.sectorSize; trk.TrackEndSector = ImageInfo.sectors - 1; - trk.TrackFile = rawImagePath; + trk.TrackFilter = rawImageFilter; + trk.TrackFile = rawImageFilter.GetFilename(); trk.TrackFileOffset = 0; trk.TrackFileType = "BINARY"; trk.TrackRawBytesPerSector = (int)ImageInfo.sectorSize; diff --git a/DiscImageChef.Filesystems/CPM/Info.cs b/DiscImageChef.Filesystems/CPM/Info.cs index 86d3bbf9..cd95993e 100644 --- a/DiscImageChef.Filesystems/CPM/Info.cs +++ b/DiscImageChef.Filesystems/CPM/Info.cs @@ -835,10 +835,10 @@ namespace DiscImageChef.Filesystems.CPM thirdPartyTimestamps = false; return false; } - catch(Exception ex) + catch { - throw ex; -// return false; + //throw ex; + return false; } } diff --git a/DiscImageChef.Filesystems/ChangeLog b/DiscImageChef.Filesystems/ChangeLog index b3af1ffd..46aaaec8 100644 --- a/DiscImageChef.Filesystems/ChangeLog +++ b/DiscImageChef.Filesystems/ChangeLog @@ -1,3 +1,7 @@ +2016-09-05 Natalia Portillo + + * Info.cs: Do not throw identification exceptions. + 2016-09-02 Natalia Portillo * XFS.cs: diff --git a/DiscImageChef.Filters/ChangeLog b/DiscImageChef.Filters/ChangeLog new file mode 100644 index 00000000..f5c8ee7f --- /dev/null +++ b/DiscImageChef.Filters/ChangeLog @@ -0,0 +1,11 @@ +2016-09-05 Natalia Portillo + + * GZip.cs: + * Filter.cs: + * Filters.cs: + * ZZZNoFilter.cs: + * OffsetStream.cs: + * ForcedSeekStream.cs: + * AssemblyInfo.cs: + * DiscImageChef.Filters.csproj: Added filters. + diff --git a/DiscImageChef.Filters/DiscImageChef.Filters.csproj b/DiscImageChef.Filters/DiscImageChef.Filters.csproj new file mode 100644 index 00000000..bcf3b201 --- /dev/null +++ b/DiscImageChef.Filters/DiscImageChef.Filters.csproj @@ -0,0 +1,70 @@ + + + + Debug + AnyCPU + 8.0.30703 + 2.0 + {D571B8EF-903D-4353-BDD5-B834F9F029EF} + Library + DiscImageChef.Filters + DiscImageChef.Filters + 3.2.99.2 + + + true + full + false + bin\Debug + DEBUG; + prompt + 4 + false + + + true + bin\Release + prompt + 4 + false + + + + + + + + + + + + + + + + LICENSE.LGPL + + + + + {CCAA7AFE-C094-4D82-A66D-630DE8A3F545} + DiscImageChef.Console + + + {F8BDF57B-1571-4CD0-84B3-B422088D359A} + DiscImageChef.Helpers + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/DiscImageChef.Filters/Filter.cs b/DiscImageChef.Filters/Filter.cs new file mode 100644 index 00000000..52d272b3 --- /dev/null +++ b/DiscImageChef.Filters/Filter.cs @@ -0,0 +1,173 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : Filter.cs +// Author(s) : Natalia Portillo +// +// Component : Filters. +// +// --[ Description ] ---------------------------------------------------------- +// +// Defines the interface for a Filter. +// +// --[ License ] -------------------------------------------------------------- +// +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 2.1 of the +// License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, see . +// +// ---------------------------------------------------------------------------- +// Copyright © 2011-2016 Natalia Portillo +// ****************************************************************************/ + +using System; +using System.IO; + +namespace DiscImageChef.Filters +{ + public abstract class Filter + { + public string Name; + public Guid UUID; + + protected Filter() + { + } + + /// + /// 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 + ///
+ /// Path used to open this filter. + public abstract string GetBasePath(); + + /// + /// Gets creation time of file referenced by this filter. + /// + /// The creation time. + public abstract DateTime GetCreationTime(); + + /// + /// 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. + /// + /// 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 + ///
+ /// The filename. + public abstract string GetFilename(); + + /// + /// 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. + /// + /// 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 + ///
+ /// 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 + ///
+ /// The parent folder. + public abstract string GetParentFolder(); + + /// + /// 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. + /// + /// The resource fork stream. + public abstract Stream GetResourceForkStream(); + + /// + /// 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 + /// + /// Path. + public abstract bool Identify(string path); + + /// + /// 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 + /// + /// Buffer. + public abstract bool Identify(byte[] buffer); + + /// + /// 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 + /// + /// Path. + public abstract void Open(string path); + + /// + /// Opens the specified stream with this filter instance + /// + /// Stream. + public abstract void Open(Stream stream); + + /// + /// 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 new file mode 100644 index 00000000..24a9c00c --- /dev/null +++ b/DiscImageChef.Filters/Filters.cs @@ -0,0 +1,91 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : Filters.cs +// Author(s) : Natalia Portillo +// +// Component : Filters. +// +// --[ Description ] ---------------------------------------------------------- +// +// Enumerates all filters and instantiates the correct one. +// +// --[ License ] -------------------------------------------------------------- +// +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 2.1 of the +// License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, see . +// +// ---------------------------------------------------------------------------- +// Copyright © 2011-2016 Natalia Portillo +// ****************************************************************************/ +using System; +using System.Collections.Generic; +using System.Reflection; +using DiscImageChef.Console; + +namespace DiscImageChef.Filters +{ + public class FiltersList + { + public SortedDictionary filtersList; + + public FiltersList() + { + Assembly assembly = Assembly.GetAssembly(typeof(Filter)); + filtersList = new SortedDictionary(); + + foreach(Type type in assembly.GetTypes()) + { + try + { + if(type.IsSubclassOf(typeof(Filter))) + { + Filter filter = (Filter)type.GetConstructor(Type.EmptyTypes).Invoke(new object[] { }); + if(!filtersList.ContainsKey(filter.Name.ToLower())) + { + filtersList.Add(filter.Name.ToLower(), filter); + } + } + } + catch(Exception exception) + { + DicConsole.ErrorWriteLine("Exception {0}", exception); + } + } + } + + public Filter GetFilter(string path) + { + foreach(Filter filter in filtersList.Values) + { + if(filter.Identify(path)) + { + Filter foundFilter = (Filter)filter.GetType().GetConstructor(Type.EmptyTypes).Invoke(new object[] { }); + foundFilter.Open(path); + + if(foundFilter.IsOpened()) + return foundFilter; + } + } + + return null; + } + + public SortedDictionary GetFiltersList() + { + return filtersList; + } + } +} + diff --git a/DiscImageChef.Filters/ForcedSeekStream.cs b/DiscImageChef.Filters/ForcedSeekStream.cs new file mode 100644 index 00000000..1669d88b --- /dev/null +++ b/DiscImageChef.Filters/ForcedSeekStream.cs @@ -0,0 +1,228 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : ForcedSeekStream.cs +// Author(s) : Natalia Portillo +// +// Component : Filters. +// +// --[ Description ] ---------------------------------------------------------- +// +// Provides a seekable stream from a forward-readable stream. +// +// --[ License ] -------------------------------------------------------------- +// +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 2.1 of the +// License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, see . +// +// ---------------------------------------------------------------------------- +// Copyright © 2011-2016 Natalia Portillo +// ****************************************************************************/ + +using System; +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. + /// + public class ForcedSeekStream : Stream where T : Stream + { + T baseStream; + long currentPosition; + object[] parameters; + long streamLength; + const int bufferLen = 1048576; + + /// + /// Initializes a new instance of the class. + /// + /// The real (uncompressed) length of the stream. + /// Parameters that are used to create the base stream. + public ForcedSeekStream(long length, params object[] args) + { + parameters = args; + Rewind(); + streamLength = length; + } + + /// + /// Initializes a new instance of the class. + /// + /// Parameters that are used to create the base stream. + public ForcedSeekStream(params object[] args) + { + parameters = args; + Rewind(); + streamLength = baseStream.Length; + } + + /// + /// Rewinds the stream to start + /// + public void Rewind() + { + baseStream = (T)Activator.CreateInstance(typeof(T), parameters); + currentPosition = 0; + } + + /// + /// 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() + { + long count = 0; + int read; + Rewind(); + do + { + byte[] buffer = new byte[bufferLen]; + read = baseStream.Read(buffer, 0, bufferLen); + count += read; + } + while(read == bufferLen); + + streamLength = count; + } + + public override bool CanRead + { + get + { + return baseStream.CanRead; + } + } + + public override bool CanSeek + { + get + { + return true; + } + } + + public override bool CanWrite + { + get + { + return false; + } + } + + public override long Length + { + get + { + return baseStream.Length; + } + } + + public override long Position + { + get + { + return currentPosition; + } + + set + { + if(value == currentPosition) + return; + + if(value < currentPosition) + Rewind(); + + int fullBufferReads = (int)(value / bufferLen); + int restToRead = (int)(value % bufferLen); + byte[] buffer; + + for(int i = 0; i < fullBufferReads; i++) + { + buffer = new byte[bufferLen]; + baseStream.Read(buffer, 0, bufferLen); + } + + buffer = new byte[restToRead]; + baseStream.Read(buffer, 0, restToRead); + + currentPosition = value; + } + } + + public override void Flush() + { + baseStream.Flush(); + } + + public override int Read(byte[] buffer, int offset, int count) + { + int read = baseStream.Read(buffer, offset, count); + + currentPosition += read; + + return read; + } + + public override int ReadByte() + { + int byt = baseStream.ReadByte(); + + // Because -1 equals end of stream so we cannot go farther + if(byt > 0) + currentPosition++; + + return byt; + } + + public override long Seek(long offset, SeekOrigin origin) + { + switch(origin) + { + case SeekOrigin.Begin: + if(offset < 0) + throw new IOException("Cannot seek before stream start."); + Position = offset; + break; + case SeekOrigin.End: + if(offset > 0) + throw new IOException("Cannot seek after stream end."); + if(streamLength == 0) + CalculateLength(); + Position = streamLength + offset; + break; + default: + Position = currentPosition + offset; + break; + } + + return currentPosition; + } + + public override void SetLength(long value) + { + throw new NotSupportedException(); + } + + public override void Write(byte[] buffer, int offset, int count) + { + throw new NotSupportedException(); + } + } +} + diff --git a/DiscImageChef.Filters/GZip.cs b/DiscImageChef.Filters/GZip.cs new file mode 100644 index 00000000..5f5d8f1a --- /dev/null +++ b/DiscImageChef.Filters/GZip.cs @@ -0,0 +1,239 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : GZip.cs +// Author(s) : Natalia Portillo +// +// Component : Filters. +// +// --[ Description ] ---------------------------------------------------------- +// +// Allow to open files that are compressed using gzip. +// +// --[ License ] -------------------------------------------------------------- +// +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 2.1 of the +// License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, see . +// +// ---------------------------------------------------------------------------- +// Copyright © 2011-2016 Natalia Portillo +// ****************************************************************************/ + +using System; +using System.IO; +using System.IO.Compression; + +namespace DiscImageChef.Filters +{ + public class GZip : Filter + { + Stream dataStream; + string basePath; + DateTime lastWriteTime; + DateTime creationTime; + bool opened; + uint decompressedSize; + + public GZip() + { + Name = "GZip"; + UUID = new Guid("F4996661-4A29-42C9-A2C7-3904EF40F3B0"); + } + + public override void Close() + { + if(dataStream != null) + dataStream.Close(); + dataStream = null; + basePath = null; + opened = false; + } + + public override string GetBasePath() + { + return basePath; + } + + public override Stream GetDataForkStream() + { + // Otherwise base stream is not at correct position and deflate throws errors + dataStream.Seek(0, SeekOrigin.Begin); + return new ForcedSeekStream(decompressedSize, dataStream, CompressionMode.Decompress); + } + + public override string GetPath() + { + return basePath; + } + + public override Stream GetResourceForkStream() + { + return null; + } + + public override bool HasResourceFork() + { + return false; + } + + public override bool Identify(byte[] buffer) + { + return buffer[0] == 0x1F && buffer[1] == 0x8B && buffer[2] == 0x08; + } + + public override bool Identify(Stream stream) + { + byte[] buffer = new byte[3]; + + stream.Seek(0, SeekOrigin.Begin); + stream.Read(buffer, 0, 3); + stream.Seek(0, SeekOrigin.Begin); + + return buffer[0] == 0x1F && buffer[1] == 0x8B && buffer[2] == 0x08; + } + + public override bool Identify(string path) + { + if(File.Exists(path)) + { + FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read); + byte[] buffer = new byte[3]; + + stream.Seek(0, SeekOrigin.Begin); + stream.Read(buffer, 0, 3); + stream.Seek(0, SeekOrigin.Begin); + + return buffer[0] == 0x1F && buffer[1] == 0x8B && buffer[2] == 0x08; + } + + return false; + } + + public override void Open(byte[] buffer) + { + byte[] mtime_b = new byte[4]; + byte[] isize_b = new byte[4]; + uint mtime; + uint isize; + + dataStream = new MemoryStream(buffer); + basePath = null; + + dataStream.Seek(4, SeekOrigin.Begin); + dataStream.Read(mtime_b, 0, 4); + dataStream.Seek(-4, SeekOrigin.End); + dataStream.Read(isize_b, 0, 4); + dataStream.Seek(0, SeekOrigin.Begin); + + mtime = BitConverter.ToUInt32(mtime_b, 0); + isize = BitConverter.ToUInt32(isize_b, 0); + + decompressedSize = isize; + creationTime = DateHandlers.UNIXUnsignedToDateTime(mtime); + lastWriteTime = creationTime; + opened = true; + } + + public override void Open(Stream stream) + { + byte[] mtime_b = new byte[4]; + byte[] isize_b = new byte[4]; + uint mtime; + uint isize; + + dataStream = stream; + basePath = null; + + dataStream.Seek(4, SeekOrigin.Begin); + dataStream.Read(mtime_b, 0, 4); + dataStream.Seek(-4, SeekOrigin.End); + dataStream.Read(isize_b, 0, 4); + dataStream.Seek(0, SeekOrigin.Begin); + + mtime = BitConverter.ToUInt32(mtime_b, 0); + isize = BitConverter.ToUInt32(isize_b, 0); + + decompressedSize = isize; + creationTime = DateHandlers.UNIXUnsignedToDateTime(mtime); + lastWriteTime = creationTime; + opened = true; + } + + public override void Open(string path) + { + byte[] mtime_b = new byte[4]; + byte[] isize_b = new byte[4]; + uint mtime; + uint isize; + + dataStream = new FileStream(path, FileMode.Open, FileAccess.Read); + basePath = Path.GetFullPath(path); + + dataStream.Seek(4, SeekOrigin.Begin); + dataStream.Read(mtime_b, 0, 4); + dataStream.Seek(-4, SeekOrigin.End); + dataStream.Read(isize_b, 0, 4); + dataStream.Seek(0, SeekOrigin.Begin); + + mtime = BitConverter.ToUInt32(mtime_b, 0); + isize = BitConverter.ToUInt32(isize_b, 0); + + decompressedSize = isize; + FileInfo fi = new FileInfo(path); + creationTime = fi.CreationTimeUtc; + lastWriteTime = DateHandlers.UNIXUnsignedToDateTime(mtime); + opened = true; + } + + public override DateTime GetCreationTime() + { + return creationTime; + } + + public override long GetDataForkLength() + { + return decompressedSize; + } + + public override DateTime GetLastWriteTime() + { + return lastWriteTime; + } + + public override long GetLength() + { + return decompressedSize; + } + + public override long GetResourceForkLength() + { + return 0; + } + + public override string GetFilename() + { + return basePath != null ? Path.GetFileName(basePath) : null; + } + + public override string GetParentFolder() + { + return Path.GetDirectoryName(basePath); + } + + public override bool IsOpened() + { + return opened; + } + } +} \ No newline at end of file diff --git a/DiscImageChef.Filters/OffsetStream.cs b/DiscImageChef.Filters/OffsetStream.cs new file mode 100644 index 00000000..14000f77 --- /dev/null +++ b/DiscImageChef.Filters/OffsetStream.cs @@ -0,0 +1,488 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : OffsetStream.cs +// Author(s) : Natalia Portillo +// +// Component : Filters. +// +// --[ Description ] ---------------------------------------------------------- +// +// Provides a stream that's a subset of another stream. +// +// --[ License ] -------------------------------------------------------------- +// +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 2.1 of the +// License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, see . +// +// ---------------------------------------------------------------------------- +// Copyright © 2011-2016 Natalia Portillo +// ****************************************************************************/ + +using System; +using System.IO; +using System.Security.AccessControl; +using Microsoft.Win32.SafeHandles; + +namespace DiscImageChef.Filters +{ + /// + /// Creates a stream that is a subset of another stream. + /// + public class OffsetStream : Stream + { + readonly Stream baseStream; + readonly long streamStart; + readonly long streamEnd; + + public OffsetStream(Stream stream, long start, long end) + { + if(start < 0) + throw new ArgumentOutOfRangeException(nameof(start), "Start can't be a negative number."); + + if(end < 0) + throw new ArgumentOutOfRangeException(nameof(end), "End can't be a negative number."); + + streamStart = start; + streamEnd = end; + + baseStream = stream; + + if(end > baseStream.Length) + throw new ArgumentOutOfRangeException(nameof(end), "End is after stream end."); + } + + public OffsetStream(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, FileOptions options, long start, long end) + { + if(start < 0) + throw new ArgumentOutOfRangeException(nameof(start), "Start can't be a negative number."); + + if(end < 0) + throw new ArgumentOutOfRangeException(nameof(end), "End can't be a negative number."); + + streamStart = start; + streamEnd = end; + + baseStream = new FileStream(path, mode, access, share, bufferSize, options); + + if(end > baseStream.Length) + throw new ArgumentOutOfRangeException(nameof(end), "End is after stream end."); + } + + public OffsetStream(SafeFileHandle handle, FileAccess access, long start, long end) + { + if(start < 0) + throw new ArgumentOutOfRangeException(nameof(start), "Start can't be a negative number."); + + if(end < 0) + throw new ArgumentOutOfRangeException(nameof(end), "End can't be a negative number."); + + streamStart = start; + streamEnd = end; + + baseStream = new FileStream(handle, access); + + if(end > baseStream.Length) + throw new ArgumentOutOfRangeException(nameof(end), "End is after stream end."); + } + + public OffsetStream(SafeFileHandle handle, FileAccess access, int bufferSize, long start, long end) + { + if(start < 0) + throw new ArgumentOutOfRangeException(nameof(start), "Start can't be a negative number."); + + if(end < 0) + throw new ArgumentOutOfRangeException(nameof(end), "End can't be a negative number."); + + streamStart = start; + streamEnd = end; + + baseStream = new FileStream(handle, access, bufferSize); + + if(end > baseStream.Length) + throw new ArgumentOutOfRangeException(nameof(end), "End is after stream end."); + } + + public OffsetStream(SafeFileHandle handle, FileAccess access, int bufferSize, bool isAsync, long start, long end) + { + if(start < 0) + throw new ArgumentOutOfRangeException(nameof(start), "Start can't be a negative number."); + + if(end < 0) + throw new ArgumentOutOfRangeException(nameof(end), "End can't be a negative number."); + + streamStart = start; + streamEnd = end; + + baseStream = new FileStream(handle, access, bufferSize, isAsync); + + if(end > baseStream.Length) + throw new ArgumentOutOfRangeException(nameof(end), "End is after stream end."); + } + + public OffsetStream(string path, FileMode mode, FileSystemRights rights, FileShare share, int bufferSize, FileOptions options, long start, long end) + { + if(start < 0) + throw new ArgumentOutOfRangeException(nameof(start), "Start can't be a negative number."); + + if(end < 0) + throw new ArgumentOutOfRangeException(nameof(end), "End can't be a negative number."); + + streamStart = start; + streamEnd = end; + + baseStream = new FileStream(path, mode, rights, share, bufferSize, options); + + if(end > baseStream.Length) + throw new ArgumentOutOfRangeException(nameof(end), "End is after stream end."); + } + + public OffsetStream(string path, FileMode mode, FileSystemRights rights, FileShare share, int bufferSize, FileOptions options, FileSecurity fileSecurity, long start, long end) + { + if(start < 0) + throw new ArgumentOutOfRangeException(nameof(start), "Start can't be a negative number."); + + if(end < 0) + throw new ArgumentOutOfRangeException(nameof(end), "End can't be a negative number."); + + streamStart = start; + streamEnd = end; + + baseStream = new FileStream(path, mode, rights, share, bufferSize, options, fileSecurity); + + if(end > baseStream.Length) + throw new ArgumentOutOfRangeException(nameof(end), "End is after stream end."); + } + + public OffsetStream(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, bool useAsync, long start, long end) + { + if(start < 0) + throw new ArgumentOutOfRangeException(nameof(start), "Start can't be a negative number."); + + if(end < 0) + throw new ArgumentOutOfRangeException(nameof(end), "End can't be a negative number."); + + streamStart = start; + streamEnd = end; + + baseStream = new FileStream(path, mode, access, share, bufferSize, useAsync); + + if(end > baseStream.Length) + throw new ArgumentOutOfRangeException(nameof(end), "End is after stream end."); + } + + public OffsetStream(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, long start, long end) + { + if(start < 0) + throw new ArgumentOutOfRangeException(nameof(start), "Start can't be a negative number."); + + if(end < 0) + throw new ArgumentOutOfRangeException(nameof(end), "End can't be a negative number."); + + streamStart = start; + streamEnd = end; + + baseStream = new FileStream(path, mode, access, share, bufferSize); + + if(end > baseStream.Length) + throw new ArgumentOutOfRangeException(nameof(end), "End is after stream end."); + } + + public OffsetStream(string path, FileMode mode, FileAccess access, FileShare share, long start, long end) + { + if(start < 0) + throw new ArgumentOutOfRangeException(nameof(start), "Start can't be a negative number."); + + if(end < 0) + throw new ArgumentOutOfRangeException(nameof(end), "End can't be a negative number."); + + streamStart = start; + streamEnd = end; + + baseStream = new FileStream(path, mode, access, share); + + if(end > baseStream.Length) + throw new ArgumentOutOfRangeException(nameof(end), "End is after stream end."); + } + + public OffsetStream(string path, FileMode mode, FileAccess access, long start, long end) + { + if(start < 0) + throw new ArgumentOutOfRangeException(nameof(start), "Start can't be a negative number."); + + if(end < 0) + throw new ArgumentOutOfRangeException(nameof(end), "End can't be a negative number."); + + streamStart = start; + streamEnd = end; + + baseStream = new FileStream(path, mode, access); + + if(end > baseStream.Length) + throw new ArgumentOutOfRangeException(nameof(end), "End is after stream end."); + } + + public OffsetStream(string path, FileMode mode, long start, long end) + { + if(start < 0) + throw new ArgumentOutOfRangeException(nameof(start), "Start can't be a negative number."); + + if(end < 0) + throw new ArgumentOutOfRangeException(nameof(end), "End can't be a negative number."); + + streamStart = start; + streamEnd = end; + + baseStream = new FileStream(path, mode); + + if(end > baseStream.Length) + throw new ArgumentOutOfRangeException(nameof(end), "End is after stream end."); + } + + public OffsetStream(byte[] buffer, int index, int count, bool writable, bool publiclyVisible, long start, long end) + { + if(start < 0) + throw new ArgumentOutOfRangeException(nameof(start), "Start can't be a negative number."); + + if(end < 0) + throw new ArgumentOutOfRangeException(nameof(end), "End can't be a negative number."); + + streamStart = start; + streamEnd = end; + + baseStream = new MemoryStream(buffer, index, count, writable, publiclyVisible); + + if(end > baseStream.Length) + throw new ArgumentOutOfRangeException(nameof(end), "End is after stream end."); + } + + public OffsetStream(byte[] buffer, int index, int count, bool writable, long start, long end) + { + if(start < 0) + throw new ArgumentOutOfRangeException(nameof(start), "Start can't be a negative number."); + + if(end < 0) + throw new ArgumentOutOfRangeException(nameof(end), "End can't be a negative number."); + + streamStart = start; + streamEnd = end; + + baseStream = new MemoryStream(buffer, index, count, writable); + + if(end > baseStream.Length) + throw new ArgumentOutOfRangeException(nameof(end), "End is after stream end."); + } + + public OffsetStream(byte[] buffer, int index, int count, long start, long end) + { + if(start < 0) + throw new ArgumentOutOfRangeException(nameof(start), "Start can't be a negative number."); + + if(end < 0) + throw new ArgumentOutOfRangeException(nameof(end), "End can't be a negative number."); + + streamStart = start; + streamEnd = end; + + baseStream = new MemoryStream(buffer, index, count); + + if(end > baseStream.Length) + throw new ArgumentOutOfRangeException(nameof(end), "End is after stream end."); + } + + public OffsetStream(byte[] buffer, bool writable, long start, long end) + { + if(start < 0) + throw new ArgumentOutOfRangeException(nameof(start), "Start can't be a negative number."); + + if(end < 0) + throw new ArgumentOutOfRangeException(nameof(end), "End can't be a negative number."); + + streamStart = start; + streamEnd = end; + + baseStream = new MemoryStream(buffer, writable); + + if(end > baseStream.Length) + throw new ArgumentOutOfRangeException(nameof(end), "End is after stream end."); + } + + public OffsetStream(byte[] buffer, long start, long end) + { + if(start < 0) + throw new ArgumentOutOfRangeException(nameof(start), "Start can't be a negative number."); + + if(end < 0) + throw new ArgumentOutOfRangeException(nameof(end), "End can't be a negative number."); + + streamStart = start; + streamEnd = end; + + baseStream = new MemoryStream(buffer); + + if(end > baseStream.Length) + throw new ArgumentOutOfRangeException(nameof(end), "End is after stream end."); + } + + ~OffsetStream() + { + baseStream.Close(); + baseStream.Dispose(); + } + + public override bool CanRead + { + get + { + return baseStream.CanRead; + } + } + + public override bool CanSeek + { + get + { + return baseStream.CanSeek; + } + } + + public override bool CanWrite + { + get + { + return baseStream.CanWrite; + } + } + + public override long Length + { + get + { + return streamEnd - streamStart; + } + } + + public override long Position + { + get + { + return baseStream.Position - streamStart; + } + + set + { + if(value + streamStart > streamEnd) + throw new IOException("Cannot set position past stream end."); + + baseStream.Position = value; + } + } + + public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state) + { + if(baseStream.Position + count > streamEnd) + throw new IOException("Cannot read past stream end."); + + return baseStream.BeginRead(buffer, offset, count, callback, state); + } + + public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state) + { + if(baseStream.Position + count > streamEnd) + throw new IOException("Cannot write past stream end."); + + return baseStream.BeginWrite(buffer, offset, count, callback, state); + } + + public override void Close() + { + baseStream.Close(); + } + + protected new void Dispose() + { + baseStream.Dispose(); + base.Dispose(); + } + + public override int EndRead(IAsyncResult asyncResult) + { + return baseStream.EndRead(asyncResult); + } + + public override void EndWrite(IAsyncResult asyncResult) + { + baseStream.EndWrite(asyncResult); + } + + public override int ReadByte() + { + return baseStream.Position == streamEnd ? -1 : baseStream.ReadByte(); + } + + public override void WriteByte(byte value) + { + if(baseStream.Position + 1 > streamEnd) + throw new IOException("Cannot write past stream end."); + + baseStream.WriteByte(value); + } + + public override void Flush() + { + baseStream.Flush(); + } + + public override int Read(byte[] buffer, int offset, int count) + { + if(baseStream.Position + count > streamEnd) + throw new IOException("Cannot read past stream end."); + + return baseStream.Read(buffer, offset, count); + } + + public override long Seek(long offset, SeekOrigin origin) + { + switch(origin) + { + case SeekOrigin.Begin: + if(offset + streamStart > streamEnd) + throw new IOException("Cannot seek past stream end."); + return baseStream.Seek(offset + streamStart, SeekOrigin.Begin) - streamStart; + case SeekOrigin.End: + if(offset - (baseStream.Length - streamEnd) < streamStart) + throw new IOException("Cannot seek before stream start."); + return baseStream.Seek(offset - (baseStream.Length - streamEnd), SeekOrigin.End) - streamStart; + default: + if(offset + baseStream.Position > streamEnd) + throw new IOException("Cannot seek past stream end."); + return baseStream.Seek(offset, SeekOrigin.Current) - streamStart; + } + } + + public override void SetLength(long value) + { + throw new NotSupportedException("Growing OffsetStream is not supported."); + } + + public override void Write(byte[] buffer, int offset, int count) + { + if(baseStream.Position + count > streamEnd) + throw new IOException("Cannot write past stream end."); + + baseStream.Write(buffer, offset, count); + } + } +} + diff --git a/DiscImageChef.Filters/Properties/AssemblyInfo.cs b/DiscImageChef.Filters/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..cb462123 --- /dev/null +++ b/DiscImageChef.Filters/Properties/AssemblyInfo.cs @@ -0,0 +1,64 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : AssemblyInfo.cs +// Version : 1.0 +// Author(s) : Natalia Portillo +// +// Component : Component +// +// Revision : $Revision$ +// Last change by : $Author$ +// Date : $Date$ +// +// --[ Description ] ---------------------------------------------------------- +// +// Description +// +// --[ License ] -------------------------------------------------------------- +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// ---------------------------------------------------------------------------- +// Copyright (C) 2011-2015 Claunia.com +// ****************************************************************************/ +// //$Id$ +using System.Reflection; +using System.Runtime.CompilerServices; + +// Information about this assembly is defined by the following attributes. +// Change them to the values specific to your project. + +[assembly: AssemblyTitle("DiscImageChef.Filters")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Claunia.com")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("© Claunia.com")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". +// The form "{Major}.{Minor}.*" will automatically update the build and revision, +// and "{Major}.{Minor}.{Build}.*" will update just the revision. + +[assembly: AssemblyVersion("1.0.*")] + +// The following attributes are used to specify the signing key for the assembly, +// if desired. See the Mono documentation for more information about signing. + +//[assembly: AssemblyDelaySign(false)] +//[assembly: AssemblyKeyFile("")] + diff --git a/DiscImageChef.Filters/ZZZNoFilter.cs b/DiscImageChef.Filters/ZZZNoFilter.cs new file mode 100644 index 00000000..9efe0629 --- /dev/null +++ b/DiscImageChef.Filters/ZZZNoFilter.cs @@ -0,0 +1,171 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : ZZZNoFilter.cs +// Author(s) : Natalia Portillo +// +// Component : Filters. +// +// --[ Description ] ---------------------------------------------------------- +// +// Provides a filter to open single files. +// +// --[ License ] -------------------------------------------------------------- +// +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 2.1 of the +// License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, see . +// +// ---------------------------------------------------------------------------- +// Copyright © 2011-2016 Natalia Portillo +// ****************************************************************************/ + +using System; +using System.IO; + +namespace DiscImageChef.Filters +{ + public class ZZZNoFilter : Filter + { + Stream dataStream; + string basePath; + DateTime lastWriteTime; + DateTime creationTime; + bool opened; + + public ZZZNoFilter() + { + Name = "No filter"; + UUID = new Guid("12345678-AAAA-BBBB-CCCC-123456789000"); + } + + public override void Close() + { + if(dataStream != null) + dataStream.Close(); + dataStream = null; + basePath = null; + opened = false; + } + + public override string GetBasePath() + { + return basePath; + } + + public override Stream GetDataForkStream() + { + return dataStream; + } + + public override string GetPath() + { + return basePath; + } + + public override Stream GetResourceForkStream() + { + return null; + } + + public override bool HasResourceFork() + { + // TODO: Implement support for xattrs/ADS + return false; + } + + public override bool Identify(byte[] buffer) + { + return buffer != null && buffer.Length > 0; + } + + public override bool Identify(Stream stream) + { + return stream != null && stream.Length > 0; + } + + public override bool Identify(string path) + { + return File.Exists(path); + } + + public override void Open(byte[] buffer) + { + dataStream = new MemoryStream(buffer); + basePath = null; + creationTime = DateTime.UtcNow; + lastWriteTime = creationTime; + opened = true; + } + + public override void Open(Stream stream) + { + dataStream = stream; + basePath = null; + creationTime = DateTime.UtcNow; + lastWriteTime = creationTime; + opened = true; + } + + public override void Open(string path) + { + dataStream = new FileStream(path, FileMode.Open, FileAccess.Read); + basePath = Path.GetFullPath(path); + FileInfo fi = new FileInfo(path); + creationTime = fi.CreationTimeUtc; + lastWriteTime = fi.LastWriteTimeUtc; + opened = true; + } + + public override DateTime GetCreationTime() + { + return creationTime; + } + + public override long GetDataForkLength() + { + return dataStream.Length; + } + + public override DateTime GetLastWriteTime() + { + return lastWriteTime; + } + + public override long GetLength() + { + return dataStream.Length; + } + + public override long GetResourceForkLength() + { + return 0; + } + + public override string GetFilename() + { + return basePath != null ? Path.GetFileName(basePath) : null; + } + + public override string GetParentFolder() + { + return Path.GetDirectoryName(basePath); + } + + public override bool IsOpened() + { + return opened; + } + } +} + diff --git a/DiscImageChef.Settings/ChangeLog b/DiscImageChef.Settings/ChangeLog index d06af0ca..65ec2c19 100644 --- a/DiscImageChef.Settings/ChangeLog +++ b/DiscImageChef.Settings/ChangeLog @@ -1,3 +1,7 @@ +2016-09-05 Natalia Portillo + + * Settings.cs: Added filters. + 2016-08-09 Natalia Portillo * DiscImageChef.Settings.csproj: Bumped version to 3.2.99.2. diff --git a/DiscImageChef.Settings/Settings.cs b/DiscImageChef.Settings/Settings.cs index e5b2c083..be1c84ee 100644 --- a/DiscImageChef.Settings/Settings.cs +++ b/DiscImageChef.Settings/Settings.cs @@ -59,6 +59,7 @@ namespace DiscImageChef.Settings public bool CommandStats; public bool DeviceStats; public bool FilesystemStats; + public bool FilterStats; public bool MediaImageStats; public bool MediaScanStats; public bool PartitionStats; @@ -246,6 +247,13 @@ namespace DiscImageChef.Settings else Current.Stats.FilesystemStats = false; + if(stats.TryGetValue("FilterStats", out obj2)) + { + Current.Stats.FilterStats = ((NSNumber)obj2).ToBool(); + } + else + Current.Stats.FilterStats = false; + if(stats.TryGetValue("MediaImageStats", out obj2)) { Current.Stats.MediaImageStats = ((NSNumber)obj2).ToBool(); @@ -326,6 +334,7 @@ namespace DiscImageChef.Settings Current.Stats.CommandStats = Convert.ToBoolean(key.GetValue("CommandStats")); Current.Stats.DeviceStats = Convert.ToBoolean(key.GetValue("DeviceStats")); Current.Stats.FilesystemStats = Convert.ToBoolean(key.GetValue("FilesystemStats")); + Current.Stats.FilterStats = Convert.ToBoolean(key.GetValue("FilterStats")); Current.Stats.MediaImageStats = Convert.ToBoolean(key.GetValue("MediaImageStats")); Current.Stats.MediaScanStats = Convert.ToBoolean(key.GetValue("MediaScanStats")); Current.Stats.PartitionStats = Convert.ToBoolean(key.GetValue("PartitionStats")); @@ -383,6 +392,7 @@ namespace DiscImageChef.Settings stats.Add("CommandStats", Current.Stats.CommandStats); stats.Add("DeviceStats", Current.Stats.DeviceStats); stats.Add("FilesystemStats", Current.Stats.FilesystemStats); + stats.Add("FilterStats", Current.Stats.FilterStats); stats.Add("MediaImageStats", Current.Stats.MediaImageStats); stats.Add("MediaScanStats", Current.Stats.MediaScanStats); stats.Add("PartitionStats", Current.Stats.PartitionStats); @@ -419,6 +429,7 @@ namespace DiscImageChef.Settings key.SetValue("CommandStats", Current.Stats.CommandStats); key.SetValue("DeviceStats", Current.Stats.DeviceStats); key.SetValue("FilesystemStats", Current.Stats.FilesystemStats); + key.SetValue("FilterStats", Current.Stats.FilterStats); key.SetValue("MediaImageStats", Current.Stats.MediaImageStats); key.SetValue("MediaScanStats", Current.Stats.MediaScanStats); key.SetValue("PartitionStats", Current.Stats.PartitionStats); @@ -476,6 +487,7 @@ namespace DiscImageChef.Settings Current.Stats.FilesystemStats = true; Current.Stats.MediaImageStats = true; Current.Stats.MediaScanStats = true; + Current.Stats.FilterStats = true; Current.Stats.MediaStats = true; Current.Stats.PartitionStats = true; Current.Stats.ShareStats = true; diff --git a/DiscImageChef.sln b/DiscImageChef.sln index 444a826f..f731a9bc 100644 --- a/DiscImageChef.sln +++ b/DiscImageChef.sln @@ -31,6 +31,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CommandLine", "commandline\ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Claunia.RsrcFork", "Claunia.RsrcFork\Claunia.RsrcFork\Claunia.RsrcFork.csproj", "{CA231ED3-0C78-496C-AAFE-D085F6E9BEC6}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DiscImageChef.Filters", "DiscImageChef.Filters\DiscImageChef.Filters.csproj", "{D571B8EF-903D-4353-BDD5-B834F9F029EF}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x86 = Debug|x86 @@ -97,6 +99,10 @@ Global {CA231ED3-0C78-496C-AAFE-D085F6E9BEC6}.Debug|x86.Build.0 = Debug|Any CPU {CA231ED3-0C78-496C-AAFE-D085F6E9BEC6}.Release|x86.ActiveCfg = Release|Any CPU {CA231ED3-0C78-496C-AAFE-D085F6E9BEC6}.Release|x86.Build.0 = Release|Any CPU + {D571B8EF-903D-4353-BDD5-B834F9F029EF}.Debug|x86.ActiveCfg = Debug|Any CPU + {D571B8EF-903D-4353-BDD5-B834F9F029EF}.Debug|x86.Build.0 = Debug|Any CPU + {D571B8EF-903D-4353-BDD5-B834F9F029EF}.Release|x86.ActiveCfg = Release|Any CPU + {D571B8EF-903D-4353-BDD5-B834F9F029EF}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(MonoDevelopProperties) = preSolution Policies = $0 diff --git a/DiscImageChef/ChangeLog b/DiscImageChef/ChangeLog index 20219492..ea62de03 100644 --- a/DiscImageChef/ChangeLog +++ b/DiscImageChef/ChangeLog @@ -1,3 +1,27 @@ +2016-09-05 Natalia Portillo + + * Commands/Ls.cs: + * Commands/Verify.cs: + * Core/Statistics.cs: + * Commands/Decode.cs: + * Commands/Entropy.cs: + * Commands/Analyze.cs: + * Commands/Compare.cs: + * Commands/Formats.cs: + * Commands/PrintHex.cs: + * DetectImageFormat.cs: + * DiscImageChef.csproj: + * Commands/Checksum.cs: + * Commands/DumpMedia.cs: + * Commands/Configure.cs: + * Commands/Statistics.cs: + * Commands/ExtractFiles.cs: + * Commands/CreateSidecar.cs: + Added filters. + + * Plugins.cs: + Sorted plugins lists. + 2016-08-27 Natalia Portillo * DetectImageFormat.cs: diff --git a/DiscImageChef/Commands/Analyze.cs b/DiscImageChef/Commands/Analyze.cs index b1b5cb2a..09eb4da4 100644 --- a/DiscImageChef/Commands/Analyze.cs +++ b/DiscImageChef/Commands/Analyze.cs @@ -36,6 +36,7 @@ using DiscImageChef.Filesystems; using DiscImageChef.ImagePlugins; using DiscImageChef.PartPlugins; using DiscImageChef.Console; +using DiscImageChef.Filters; namespace DiscImageChef.Commands { @@ -49,9 +50,12 @@ namespace DiscImageChef.Commands DicConsole.DebugWriteLine("Analyze command", "--filesystems={0}", options.SearchForFilesystems); DicConsole.DebugWriteLine("Analyze command", "--partitions={0}", options.SearchForPartitions); - if(!System.IO.File.Exists(options.InputFile)) + FiltersList filtersList = new FiltersList(); + Filter inputFilter = filtersList.GetFilter(options.InputFile); + + if(inputFilter == null) { - DicConsole.ErrorWriteLine("Specified file does not exist."); + DicConsole.ErrorWriteLine("Cannot open specified file."); return; } @@ -66,7 +70,7 @@ namespace DiscImageChef.Commands try { - _imageFormat = ImageFormat.Detect(options.InputFile); + _imageFormat = ImageFormat.Detect(inputFilter); if(_imageFormat == null) { @@ -83,7 +87,7 @@ namespace DiscImageChef.Commands try { - if(!_imageFormat.OpenImage(options.InputFile)) + if(!_imageFormat.OpenImage(inputFilter)) { DicConsole.WriteLine("Unable to open image format"); DicConsole.WriteLine("No error given"); @@ -97,6 +101,7 @@ namespace DiscImageChef.Commands Core.Statistics.AddMediaFormat(_imageFormat.GetImageFormat()); Core.Statistics.AddMedia(_imageFormat.ImageInfo.mediaType, false); + Core.Statistics.AddFilter(inputFilter.Name); } catch(Exception ex) { diff --git a/DiscImageChef/Commands/Checksum.cs b/DiscImageChef/Commands/Checksum.cs index b7332c2e..c9787f23 100644 --- a/DiscImageChef/Commands/Checksum.cs +++ b/DiscImageChef/Commands/Checksum.cs @@ -36,6 +36,7 @@ using DiscImageChef.Checksums; using System.Collections.Generic; using DiscImageChef.Console; using System.Threading; +using DiscImageChef.Filters; namespace DiscImageChef.Commands { @@ -63,13 +64,16 @@ namespace DiscImageChef.Commands DicConsole.DebugWriteLine("Checksum command", "--sha512={0}", options.DoSHA512); DicConsole.DebugWriteLine("Checksum command", "--spamsum={0}", options.DoSpamSum); - if(!System.IO.File.Exists(options.InputFile)) + FiltersList filtersList = new FiltersList(); + Filter inputFilter = filtersList.GetFilter(options.InputFile); + + if(inputFilter == null) { - DicConsole.ErrorWriteLine("Specified file does not exist."); + DicConsole.ErrorWriteLine("Cannot open specified file."); return; } - ImagePlugin inputFormat = ImageFormat.Detect(options.InputFile); + ImagePlugin inputFormat = ImageFormat.Detect(inputFilter); if(inputFormat == null) { @@ -77,9 +81,10 @@ namespace DiscImageChef.Commands return; } - inputFormat.OpenImage(options.InputFile); + inputFormat.OpenImage(inputFilter); Core.Statistics.AddMediaFormat(inputFormat.GetImageFormat()); Core.Statistics.AddMedia(inputFormat.ImageInfo.mediaType, false); + Core.Statistics.AddFilter(inputFilter.Name); if(inputFormat.ImageInfo.imageHasPartitions) { diff --git a/DiscImageChef/Commands/Compare.cs b/DiscImageChef/Commands/Compare.cs index 8f816afd..0f6bb0dc 100644 --- a/DiscImageChef/Commands/Compare.cs +++ b/DiscImageChef/Commands/Compare.cs @@ -35,6 +35,7 @@ using DiscImageChef.ImagePlugins; using System.Text; using System.Collections.Generic; using DiscImageChef.Console; +using DiscImageChef.Filters; namespace DiscImageChef.Commands { @@ -47,20 +48,24 @@ namespace DiscImageChef.Commands DicConsole.DebugWriteLine("Compare command", "--input1={0}", options.InputFile1); DicConsole.DebugWriteLine("Compare command", "--input2={0}", options.InputFile2); - if(!System.IO.File.Exists(options.InputFile1)) + FiltersList filtersList = new FiltersList(); + Filter inputFilter1 = filtersList.GetFilter(options.InputFile1); + Filter inputFilter2 = filtersList.GetFilter(options.InputFile2); + + if(inputFilter1 == null) { - DicConsole.ErrorWriteLine("Input file 1 does not exist."); + DicConsole.ErrorWriteLine("Cannot open input file 1"); return; } - if(!System.IO.File.Exists(options.InputFile2)) + if(inputFilter2 == null) { - DicConsole.ErrorWriteLine("Input file 2 does not exist."); + DicConsole.ErrorWriteLine("Cannot open input file 2"); return; } - ImagePlugin input1Format = ImageFormat.Detect(options.InputFile1); - ImagePlugin input2Format = ImageFormat.Detect(options.InputFile2); + ImagePlugin input1Format = ImageFormat.Detect(inputFilter1); + ImagePlugin input2Format = ImageFormat.Detect(inputFilter2); if(input1Format == null) { @@ -88,13 +93,15 @@ namespace DiscImageChef.Commands DicConsole.WriteLine("Input file 2 format identified by {0}.", input2Format.Name); } - input1Format.OpenImage(options.InputFile1); - input2Format.OpenImage(options.InputFile2); + input1Format.OpenImage(inputFilter1); + input2Format.OpenImage(inputFilter2); Core.Statistics.AddMediaFormat(input1Format.GetImageFormat()); Core.Statistics.AddMediaFormat(input2Format.GetImageFormat()); Core.Statistics.AddMedia(input1Format.ImageInfo.mediaType, false); Core.Statistics.AddMedia(input2Format.ImageInfo.mediaType, false); + Core.Statistics.AddFilter(inputFilter1.Name); + Core.Statistics.AddFilter(inputFilter2.Name); StringBuilder sb = new StringBuilder(); diff --git a/DiscImageChef/Commands/Configure.cs b/DiscImageChef/Commands/Configure.cs index 359eae6d..52e9ae36 100644 --- a/DiscImageChef/Commands/Configure.cs +++ b/DiscImageChef/Commands/Configure.cs @@ -109,6 +109,15 @@ namespace DiscImageChef.Commands } Settings.Settings.Current.Stats.FilesystemStats = pressedKey.Key == ConsoleKey.Y; + pressedKey = new ConsoleKeyInfo(); + while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N) + { + DicConsole.Write("Do you want to gather statistics about found file filters? (Y/N): "); + pressedKey = System.Console.ReadKey(); + DicConsole.WriteLine(); + } + Settings.Settings.Current.Stats.FilterStats = pressedKey.Key == ConsoleKey.Y; + pressedKey = new ConsoleKeyInfo(); while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N) { diff --git a/DiscImageChef/Commands/CreateSidecar.cs b/DiscImageChef/Commands/CreateSidecar.cs index bf5bea9e..b2a46df8 100644 --- a/DiscImageChef/Commands/CreateSidecar.cs +++ b/DiscImageChef/Commands/CreateSidecar.cs @@ -39,6 +39,7 @@ using DiscImageChef.Console; using System.IO; using DiscImageChef.CommonTypes; using DiscImageChef.PartPlugins; +using DiscImageChef.Filters; namespace DiscImageChef.Commands { @@ -51,15 +52,18 @@ namespace DiscImageChef.Commands plugins.RegisterAllPlugins(); ImagePlugin _imageFormat; - if(!File.Exists(options.InputFile)) + FiltersList filtersList = new FiltersList(); + Filter inputFilter = filtersList.GetFilter(options.InputFile); + + if(inputFilter == null) { - DicConsole.ErrorWriteLine("Specified file does not exist."); + DicConsole.ErrorWriteLine("Cannot open specified file."); return; } try { - _imageFormat = ImageFormat.Detect(options.InputFile); + _imageFormat = ImageFormat.Detect(inputFilter); if(_imageFormat == null) { @@ -76,7 +80,7 @@ namespace DiscImageChef.Commands try { - if(!_imageFormat.OpenImage(options.InputFile)) + if(!_imageFormat.OpenImage(inputFilter)) { DicConsole.WriteLine("Unable to open image format"); DicConsole.WriteLine("No error given"); @@ -93,6 +97,7 @@ namespace DiscImageChef.Commands } Core.Statistics.AddMediaFormat(_imageFormat.GetImageFormat()); + Core.Statistics.AddFilter(inputFilter.Name); FileInfo fi = new FileInfo(options.InputFile); FileStream fs = new FileStream(options.InputFile, FileMode.Open, FileAccess.Read); diff --git a/DiscImageChef/Commands/Decode.cs b/DiscImageChef/Commands/Decode.cs index 4e44294b..8b1da3da 100644 --- a/DiscImageChef/Commands/Decode.cs +++ b/DiscImageChef/Commands/Decode.cs @@ -32,6 +32,7 @@ using DiscImageChef.ImagePlugins; using DiscImageChef.Console; +using DiscImageChef.Filters; namespace DiscImageChef.Commands { @@ -47,13 +48,16 @@ namespace DiscImageChef.Commands DicConsole.DebugWriteLine("Decode command", "--disk-tags={0}", options.DiskTags); DicConsole.DebugWriteLine("Decode command", "--sector-tags={0}", options.SectorTags); - if(!System.IO.File.Exists(options.InputFile)) + FiltersList filtersList = new FiltersList(); + Filter inputFilter = filtersList.GetFilter(options.InputFile); + + if(inputFilter == null) { - DicConsole.ErrorWriteLine("Specified file does not exist."); + DicConsole.ErrorWriteLine("Cannot open specified file."); return; } - ImagePlugin inputFormat = ImageFormat.Detect(options.InputFile); + ImagePlugin inputFormat = ImageFormat.Detect(inputFilter); if(inputFormat == null) { @@ -61,9 +65,10 @@ namespace DiscImageChef.Commands return; } - inputFormat.OpenImage(options.InputFile); + inputFormat.OpenImage(inputFilter); Core.Statistics.AddMediaFormat(inputFormat.GetImageFormat()); Core.Statistics.AddMedia(inputFormat.ImageInfo.mediaType, false); + Core.Statistics.AddFilter(inputFilter.Name); if(options.DiskTags) { diff --git a/DiscImageChef/Commands/DumpMedia.cs b/DiscImageChef/Commands/DumpMedia.cs index c11962bd..6bcb2b0e 100644 --- a/DiscImageChef/Commands/DumpMedia.cs +++ b/DiscImageChef/Commands/DumpMedia.cs @@ -40,6 +40,7 @@ using DiscImageChef.CommonTypes; using DiscImageChef.ImagePlugins; using DiscImageChef.PartPlugins; using DiscImageChef.Filesystems; +using DiscImageChef.Filters; namespace DiscImageChef.Commands { @@ -749,12 +750,22 @@ namespace DiscImageChef.Commands PluginBase plugins = new PluginBase(); plugins.RegisterAllPlugins(); ImagePlugin _imageFormat; - _imageFormat = ImageFormat.Detect(options.OutputPrefix + ".bin"); + + FiltersList filtersList = new FiltersList(); + Filter inputFilter = filtersList.GetFilter(options.OutputPrefix + ".bin"); + + if(inputFilter == null) + { + DicConsole.ErrorWriteLine("Cannot open file just created, this should not happen."); + return; + } + + _imageFormat = ImageFormat.Detect(inputFilter); PartitionType[] xmlFileSysInfo = null; try { - if(!_imageFormat.OpenImage(options.OutputPrefix + ".bin")) + if(!_imageFormat.OpenImage(inputFilter)) _imageFormat = null; } catch @@ -2951,12 +2962,21 @@ namespace DiscImageChef.Commands PluginBase plugins = new PluginBase(); plugins.RegisterAllPlugins(); ImagePlugin _imageFormat; - _imageFormat = ImageFormat.Detect(options.OutputPrefix + ".bin"); + FiltersList filtersList = new FiltersList(); + Filter inputFilter = filtersList.GetFilter(options.OutputPrefix + ".bin"); + + if(inputFilter == null) + { + DicConsole.ErrorWriteLine("Cannot open file just created, this should not happen."); + return; + } + + _imageFormat = ImageFormat.Detect(inputFilter); PartitionType[] xmlFileSysInfo = null; try { - if(!_imageFormat.OpenImage(options.OutputPrefix + ".bin")) + if(!_imageFormat.OpenImage(inputFilter)) _imageFormat = null; } catch diff --git a/DiscImageChef/Commands/Entropy.cs b/DiscImageChef/Commands/Entropy.cs index 004bc05f..3be7e9b0 100644 --- a/DiscImageChef/Commands/Entropy.cs +++ b/DiscImageChef/Commands/Entropy.cs @@ -35,6 +35,7 @@ using DiscImageChef.ImagePlugins; using DiscImageChef.Checksums; using System.Collections.Generic; using DiscImageChef.Console; +using DiscImageChef.Filters; namespace DiscImageChef.Commands { @@ -49,13 +50,16 @@ namespace DiscImageChef.Commands DicConsole.DebugWriteLine("Entropy command", "--input={0}", options.InputFile); DicConsole.DebugWriteLine("Entropy command", "--duplicated-sectors={0}", options.DuplicatedSectors); - if(!System.IO.File.Exists(options.InputFile)) + FiltersList filtersList = new FiltersList(); + Filter inputFilter = filtersList.GetFilter(options.InputFile); + + if(inputFilter == null) { - DicConsole.ErrorWriteLine("Specified file does not exist."); + DicConsole.ErrorWriteLine("Cannot open specified file."); return; } - ImagePlugin inputFormat = ImageFormat.Detect(options.InputFile); + ImagePlugin inputFormat = ImageFormat.Detect(inputFilter); if(inputFormat == null) { @@ -63,9 +67,10 @@ namespace DiscImageChef.Commands return; } - inputFormat.OpenImage(options.InputFile); + inputFormat.OpenImage(inputFilter); Core.Statistics.AddMediaFormat(inputFormat.GetImageFormat()); Core.Statistics.AddMedia(inputFormat.ImageInfo.mediaType, false); + Core.Statistics.AddFilter(inputFilter.Name); if(options.SeparatedTracks) { diff --git a/DiscImageChef/Commands/ExtractFiles.cs b/DiscImageChef/Commands/ExtractFiles.cs index 5a1da25d..43e8ccf2 100644 --- a/DiscImageChef/Commands/ExtractFiles.cs +++ b/DiscImageChef/Commands/ExtractFiles.cs @@ -37,6 +37,7 @@ using DiscImageChef.Filesystems; using DiscImageChef.ImagePlugins; using DiscImageChef.PartPlugins; using System.IO; +using DiscImageChef.Filters; namespace DiscImageChef.Commands { @@ -50,9 +51,12 @@ namespace DiscImageChef.Commands DicConsole.DebugWriteLine("Extract-Files command", "--xattrs={0}", options.Xattrs); DicConsole.DebugWriteLine("Extract-Files command", "--output={0}", options.OutputDir); - if(!File.Exists(options.InputFile)) + FiltersList filtersList = new FiltersList(); + Filter inputFilter = filtersList.GetFilter(options.InputFile); + + if(inputFilter == null) { - DicConsole.ErrorWriteLine("Specified file does not exist."); + DicConsole.ErrorWriteLine("Cannot open specified file."); return; } @@ -66,7 +70,7 @@ namespace DiscImageChef.Commands try { - _imageFormat = ImageFormat.Detect(options.InputFile); + _imageFormat = ImageFormat.Detect(inputFilter); if(_imageFormat == null) { @@ -91,7 +95,7 @@ namespace DiscImageChef.Commands try { - if(!_imageFormat.OpenImage(options.InputFile)) + if(!_imageFormat.OpenImage(inputFilter)) { DicConsole.WriteLine("Unable to open image format"); DicConsole.WriteLine("No error given"); @@ -105,6 +109,7 @@ namespace DiscImageChef.Commands Core.Statistics.AddMediaFormat(_imageFormat.GetImageFormat()); Core.Statistics.AddMedia(_imageFormat.ImageInfo.mediaType, false); + Core.Statistics.AddFilter(inputFilter.Name); } catch(Exception ex) { diff --git a/DiscImageChef/Commands/Formats.cs b/DiscImageChef/Commands/Formats.cs index 0c61013c..42d67da2 100644 --- a/DiscImageChef/Commands/Formats.cs +++ b/DiscImageChef/Commands/Formats.cs @@ -35,6 +35,7 @@ using DiscImageChef.ImagePlugins; using DiscImageChef.PartPlugins; using DiscImageChef.Filesystems; using DiscImageChef.Console; +using DiscImageChef.Filters; namespace DiscImageChef.Commands { @@ -44,7 +45,19 @@ namespace DiscImageChef.Commands { PluginBase plugins = new PluginBase(); plugins.RegisterAllPlugins(); + FiltersList filtersList = new FiltersList(); + DicConsole.WriteLine("Supported filters:"); + if(FormatsOptions.Verbose) + DicConsole.VerboseWriteLine("GUID\t\t\t\t\tFilter"); + foreach(KeyValuePair kvp in filtersList.filtersList) + { + if(FormatsOptions.Verbose) + DicConsole.VerboseWriteLine("{0}\t{1}", kvp.Value.UUID, kvp.Value.Name); + else + DicConsole.WriteLine(kvp.Value.Name); + } + DicConsole.WriteLine(); DicConsole.WriteLine("Supported disc image formats:"); if(FormatsOptions.Verbose) DicConsole.VerboseWriteLine("GUID\t\t\t\t\tPlugin"); diff --git a/DiscImageChef/Commands/Ls.cs b/DiscImageChef/Commands/Ls.cs index 8f182b24..b79fd321 100644 --- a/DiscImageChef/Commands/Ls.cs +++ b/DiscImageChef/Commands/Ls.cs @@ -34,6 +34,7 @@ using System; using System.Collections.Generic; using DiscImageChef.Console; using DiscImageChef.Filesystems; +using DiscImageChef.Filters; using DiscImageChef.ImagePlugins; using DiscImageChef.PartPlugins; @@ -47,12 +48,15 @@ namespace DiscImageChef.Commands DicConsole.DebugWriteLine("Ls command", "--verbose={0}", options.Verbose); DicConsole.DebugWriteLine("Ls command", "--input={0}", options.InputFile); - if(!System.IO.File.Exists(options.InputFile)) + FiltersList filtersList = new FiltersList(); + Filter inputFilter = filtersList.GetFilter(options.InputFile); + + if(inputFilter == null) { - DicConsole.ErrorWriteLine("Specified file does not exist."); + DicConsole.ErrorWriteLine("Cannot open specified file."); return; } - + PluginBase plugins = new PluginBase(); plugins.RegisterAllPlugins(); @@ -63,7 +67,7 @@ namespace DiscImageChef.Commands try { - _imageFormat = ImageFormat.Detect(options.InputFile); + _imageFormat = ImageFormat.Detect(inputFilter); if(_imageFormat == null) { @@ -80,7 +84,7 @@ namespace DiscImageChef.Commands try { - if(!_imageFormat.OpenImage(options.InputFile)) + if(!_imageFormat.OpenImage(inputFilter)) { DicConsole.WriteLine("Unable to open image format"); DicConsole.WriteLine("No error given"); @@ -94,6 +98,7 @@ namespace DiscImageChef.Commands Core.Statistics.AddMediaFormat(_imageFormat.GetImageFormat()); Core.Statistics.AddMedia(_imageFormat.ImageInfo.mediaType, false); + Core.Statistics.AddFilter(inputFilter.Name); } catch(Exception ex) { diff --git a/DiscImageChef/Commands/PrintHex.cs b/DiscImageChef/Commands/PrintHex.cs index 7452608c..9976a937 100644 --- a/DiscImageChef/Commands/PrintHex.cs +++ b/DiscImageChef/Commands/PrintHex.cs @@ -32,6 +32,7 @@ using DiscImageChef.ImagePlugins; using DiscImageChef.Console; +using DiscImageChef.Filters; namespace DiscImageChef.Commands { @@ -47,13 +48,16 @@ namespace DiscImageChef.Commands DicConsole.DebugWriteLine("PrintHex command", "--long-sectors={0}", options.LongSectors); DicConsole.DebugWriteLine("PrintHex command", "--WidthBytes={0}", options.WidthBytes); - if(!System.IO.File.Exists(options.InputFile)) + FiltersList filtersList = new FiltersList(); + Filter inputFilter = filtersList.GetFilter(options.InputFile); + + if(inputFilter == null) { - DicConsole.ErrorWriteLine("Specified file does not exist."); + DicConsole.ErrorWriteLine("Cannot open specified file."); return; } - ImagePlugin inputFormat = ImageFormat.Detect(options.InputFile); + ImagePlugin inputFormat = ImageFormat.Detect(inputFilter); if(inputFormat == null) { @@ -61,7 +65,7 @@ namespace DiscImageChef.Commands return; } - inputFormat.OpenImage(options.InputFile); + inputFormat.OpenImage(inputFilter); for(ulong i = 0; i < options.Length; i++) { diff --git a/DiscImageChef/Commands/Statistics.cs b/DiscImageChef/Commands/Statistics.cs index 8fdaae8a..9177399a 100644 --- a/DiscImageChef/Commands/Statistics.cs +++ b/DiscImageChef/Commands/Statistics.cs @@ -101,6 +101,16 @@ namespace DiscImageChef.Commands thereAreStats = true; } + if(Core.Statistics.AllStats.Filters != null && Core.Statistics.AllStats.Filters.Count > 0) + { + DicConsole.WriteLine("Filters statistics"); + DicConsole.WriteLine("=================="); + foreach(Core.NameValueStats nvs in Core.Statistics.AllStats.Filters) + DicConsole.WriteLine("Filter {0} has been found {1} times.", nvs.name, nvs.Value); + DicConsole.WriteLine(); + thereAreStats = true; + } + if(Core.Statistics.AllStats.MediaImages != null && Core.Statistics.AllStats.MediaImages.Count > 0) { DicConsole.WriteLine("Media image statistics"); diff --git a/DiscImageChef/Commands/Verify.cs b/DiscImageChef/Commands/Verify.cs index 237c0595..f2374685 100644 --- a/DiscImageChef/Commands/Verify.cs +++ b/DiscImageChef/Commands/Verify.cs @@ -34,6 +34,7 @@ using System; using DiscImageChef.ImagePlugins; using System.Collections.Generic; using DiscImageChef.Console; +using DiscImageChef.Filters; namespace DiscImageChef.Commands { @@ -47,13 +48,16 @@ namespace DiscImageChef.Commands DicConsole.DebugWriteLine("Verify command", "--verify-disc={0}", options.VerifyDisc); DicConsole.DebugWriteLine("Verify command", "--verify-sectors={0}", options.VerifySectors); - if(!System.IO.File.Exists(options.InputFile)) + FiltersList filtersList = new FiltersList(); + Filter inputFilter = filtersList.GetFilter(options.InputFile); + + if(inputFilter == null) { - DicConsole.ErrorWriteLine("Specified file does not exist."); + DicConsole.ErrorWriteLine("Cannot open specified file."); return; } - ImagePlugin inputFormat = ImageFormat.Detect(options.InputFile); + ImagePlugin inputFormat = ImageFormat.Detect(inputFilter); if(inputFormat == null) { @@ -61,9 +65,10 @@ namespace DiscImageChef.Commands return; } - inputFormat.OpenImage(options.InputFile); + inputFormat.OpenImage(inputFilter); Core.Statistics.AddMediaFormat(inputFormat.GetImageFormat()); Core.Statistics.AddMedia(inputFormat.ImageInfo.mediaType, false); + Core.Statistics.AddFilter(inputFilter.Name); bool? correctDisc = null; long totalSectors = 0; diff --git a/DiscImageChef/Core/Statistics.cs b/DiscImageChef/Core/Statistics.cs index 00b61811..da3ec831 100644 --- a/DiscImageChef/Core/Statistics.cs +++ b/DiscImageChef/Core/Statistics.cs @@ -47,6 +47,8 @@ namespace DiscImageChef.Core public List Partitions; [XmlArrayItem("Format")] public List MediaImages; + [XmlArrayItem("Filter", IsNullable = true)] + public List Filters; [XmlArrayItem("Device", IsNullable = true)] public List Devices; [XmlArrayItem("Media")] @@ -411,6 +413,65 @@ namespace DiscImageChef.Core } } + public static void AddFilter(string format) + { + if(Settings.Settings.Current.Stats != null && Settings.Settings.Current.Stats.FilterStats) + { + if(AllStats.Filters == null) + AllStats.Filters = new List(); + if(CurrentStats.Filters == null) + CurrentStats.Filters = new List(); + + NameValueStats old = null; + foreach(NameValueStats nvs in AllStats.Filters) + { + if(nvs.name == format) + { + old = nvs; + break; + } + } + + NameValueStats nw = new NameValueStats(); + if(old != null) + { + nw.name = old.name; + nw.Value = old.Value + 1; + AllStats.Filters.Remove(old); + } + else + { + nw.name = format; + nw.Value = 1; + } + AllStats.Filters.Add(nw); + + old = null; + foreach(NameValueStats nvs in CurrentStats.Filters) + { + if(nvs.name == format) + { + old = nvs; + break; + } + } + + nw = new NameValueStats(); + if(old != null) + { + nw.name = old.name; + nw.Value = old.Value + 1; + CurrentStats.Filters.Remove(old); + } + else + { + nw.name = format; + nw.Value = 1; + } + CurrentStats.Filters.Add(nw); + } + } + public static void AddMediaFormat(string format) { if(Settings.Settings.Current.Stats != null && Settings.Settings.Current.Stats.MediaImageStats) diff --git a/DiscImageChef/DetectImageFormat.cs b/DiscImageChef/DetectImageFormat.cs index 4c296dc3..9a190ffe 100644 --- a/DiscImageChef/DetectImageFormat.cs +++ b/DiscImageChef/DetectImageFormat.cs @@ -31,12 +31,13 @@ // ****************************************************************************/ using System; +using DiscImageChef.Filters; namespace DiscImageChef.ImagePlugins { public static class ImageFormat { - public static ImagePlugin Detect(string imagePath) + public static ImagePlugin Detect(Filter imageFilter) { try { @@ -53,7 +54,7 @@ namespace DiscImageChef.ImagePlugins { try { - if(_imageplugin.IdentifyImage(imagePath)) + if(_imageplugin.IdentifyImage(imageFilter)) { _imageFormat = _imageplugin; break; @@ -76,7 +77,7 @@ namespace DiscImageChef.ImagePlugins { try { - if(_imageplugin.IdentifyImage(imagePath)) + if(_imageplugin.IdentifyImage(imageFilter)) { _imageFormat = _imageplugin; break; diff --git a/DiscImageChef/DiscImageChef.csproj b/DiscImageChef/DiscImageChef.csproj index 1b3f6dba..18593844 100644 --- a/DiscImageChef/DiscImageChef.csproj +++ b/DiscImageChef/DiscImageChef.csproj @@ -212,6 +212,10 @@ {E1BD3C65-49C3-49E7-BABA-C60980CB3F20} CommandLine + + {D571B8EF-903D-4353-BDD5-B834F9F029EF} + DiscImageChef.Filters + diff --git a/DiscImageChef/Plugins.cs b/DiscImageChef/Plugins.cs index 5f7fbc3b..9dbb2dae 100644 --- a/DiscImageChef/Plugins.cs +++ b/DiscImageChef/Plugins.cs @@ -42,15 +42,15 @@ namespace DiscImageChef { public class PluginBase { - public Dictionary PluginsList; - public Dictionary PartPluginsList; - public Dictionary ImagePluginsList; + public SortedDictionary PluginsList; + public SortedDictionary PartPluginsList; + public SortedDictionary ImagePluginsList; public PluginBase() { - PluginsList = new Dictionary(); - PartPluginsList = new Dictionary(); - ImagePluginsList = new Dictionary(); + PluginsList = new SortedDictionary(); + PartPluginsList = new SortedDictionary(); + ImagePluginsList = new SortedDictionary(); } public void RegisterAllPlugins() diff --git a/README.md b/README.md index a9776d51..9833b799 100644 --- a/README.md +++ b/README.md @@ -144,6 +144,10 @@ Supported checksums * SHA-2 (256, 384 and 512 bits) * SpamSum (fuzzy hashing) +Supported filters +================= +* GZip + Changelog ========= diff --git a/TODO b/TODO index c996bc8c..69bcfbb5 100644 --- a/TODO +++ b/TODO @@ -65,4 +65,13 @@ VMDK plugin: --- Add support for encrypted extents UDIF plugin: ---- Add support for compressed chunks \ No newline at end of file +--- Add support for compressed chunks + +Filters: +--- Add support for BZip2 compressed files +--- Add support for XZ compressed files +--- Add support for AppleSingle files +--- Add support for AppleDouble files +--- Add support for MacBinary files +--- Add support for ZIP archives +--- Add support for 7Z archives \ No newline at end of file