diff --git a/DiscImageChef.Core/Devices/Dumping/ATA.cs b/DiscImageChef.Core/Devices/Dumping/ATA.cs index 46cf1d7ca..84a56a810 100644 --- a/DiscImageChef.Core/Devices/Dumping/ATA.cs +++ b/DiscImageChef.Core/Devices/Dumping/ATA.cs @@ -417,6 +417,7 @@ namespace DiscImageChef.Core.Devices.Dumping (double)blockSize * (double)(blocks + 1) / 1024 / (totalDuration / 1000)); } + outputPlugin.SetDumpHardware(resume.Tries); dumpLog.WriteLine("Closing output file."); DicConsole.WriteLine("Closing output file."); outputPlugin.Close(); diff --git a/DiscImageChef.Core/Devices/Dumping/CompactDisc.cs b/DiscImageChef.Core/Devices/Dumping/CompactDisc.cs index 5e8f9e5cd..1df764641 100644 --- a/DiscImageChef.Core/Devices/Dumping/CompactDisc.cs +++ b/DiscImageChef.Core/Devices/Dumping/CompactDisc.cs @@ -886,6 +886,7 @@ namespace DiscImageChef.Core.Devices.Dumping throw new ArgumentException(outputPlugin.ErrorMessage); } + outputPlugin.SetDumpHardware(resume.Tries); dumpLog.WriteLine("Closing output file."); DicConsole.WriteLine("Closing output file."); outputPlugin.Close(); diff --git a/DiscImageChef.Core/Devices/Dumping/SBC.cs b/DiscImageChef.Core/Devices/Dumping/SBC.cs index 80dc94245..b5393648b 100644 --- a/DiscImageChef.Core/Devices/Dumping/SBC.cs +++ b/DiscImageChef.Core/Devices/Dumping/SBC.cs @@ -645,6 +645,7 @@ namespace DiscImageChef.Core.Devices.Dumping } } + outputPlugin.SetDumpHardware(resume.Tries); dumpLog.WriteLine("Closing output file."); DicConsole.WriteLine("Closing output file."); outputPlugin.Close(); diff --git a/DiscImageChef.Core/Devices/Dumping/SecureDigital.cs b/DiscImageChef.Core/Devices/Dumping/SecureDigital.cs index 7ae324b8b..5b0dd9ec9 100644 --- a/DiscImageChef.Core/Devices/Dumping/SecureDigital.cs +++ b/DiscImageChef.Core/Devices/Dumping/SecureDigital.cs @@ -390,6 +390,7 @@ namespace DiscImageChef.Core.Devices.Dumping currentTry.Extents = ExtentsConverter.ToMetadata(extents); + outputPlugin.SetDumpHardware(resume.Tries); dumpLog.WriteLine("Closing output file."); DicConsole.WriteLine("Closing output file."); outputPlugin.Close(); diff --git a/DiscImageChef.Core/Devices/Dumping/XGD.cs b/DiscImageChef.Core/Devices/Dumping/XGD.cs index 6fbb47965..1a65890e0 100644 --- a/DiscImageChef.Core/Devices/Dumping/XGD.cs +++ b/DiscImageChef.Core/Devices/Dumping/XGD.cs @@ -770,6 +770,7 @@ namespace DiscImageChef.Core.Devices.Dumping throw new ArgumentException(outputPlugin.ErrorMessage); } + outputPlugin.SetDumpHardware(resume.Tries); dumpLog.WriteLine("Closing output file."); DicConsole.WriteLine("Closing output file."); outputPlugin.Close(); diff --git a/DiscImageChef.Core/Sidecar/BlockMedia.cs b/DiscImageChef.Core/Sidecar/BlockMedia.cs index e108147c0..cfa89e939 100644 --- a/DiscImageChef.Core/Sidecar/BlockMedia.cs +++ b/DiscImageChef.Core/Sidecar/BlockMedia.cs @@ -61,7 +61,8 @@ namespace DiscImageChef.Core /// Image plugins /// List of image checksums /// Metadata sidecar - static void BlockMedia(IMediaImage image, Guid filterId, string imagePath, FileInfo fi, PluginBase plugins, + static void BlockMedia(IMediaImage image, Guid filterId, string imagePath, + FileInfo fi, PluginBase plugins, List imgChecksums, ref CICMMetadataType sidecar, Encoding encoding) { sidecar.BlockMedia = new[] @@ -69,14 +70,14 @@ namespace DiscImageChef.Core new BlockMediaType { Checksums = imgChecksums.ToArray(), - Image = new ImageType + Image = new ImageType { - format = image.Format, - offset = 0, + format = image.Format, + offset = 0, offsetSpecified = true, - Value = Path.GetFileName(imagePath) + Value = Path.GetFileName(imagePath) }, - Size = fi.Length, + Size = fi.Length, Sequence = new SequenceType {MediaTitle = image.Info.MediaTitle} } }; @@ -84,12 +85,12 @@ namespace DiscImageChef.Core if(image.Info.MediaSequence != 0 && image.Info.LastMediaSequence != 0) { sidecar.BlockMedia[0].Sequence.MediaSequence = image.Info.MediaSequence; - sidecar.BlockMedia[0].Sequence.TotalMedia = image.Info.LastMediaSequence; + sidecar.BlockMedia[0].Sequence.TotalMedia = image.Info.LastMediaSequence; } else { sidecar.BlockMedia[0].Sequence.MediaSequence = 1; - sidecar.BlockMedia[0].Sequence.TotalMedia = 1; + sidecar.BlockMedia[0].Sequence.TotalMedia = 1; } foreach(MediaTagType tagType in image.Info.ReadableMediaTags) @@ -118,7 +119,7 @@ namespace DiscImageChef.Core }; break; case MediaTagType.PCMCIA_CIS: - byte[] cis = image.ReadDiskTag(MediaTagType.PCMCIA_CIS); + byte[] cis = image.ReadDiskTag(MediaTagType.PCMCIA_CIS); sidecar.BlockMedia[0].PCMCIA = new PCMCIAType { CIS = new DumpType {Checksums = Checksum.GetChecksums(cis).ToArray(), Size = cis.Length} @@ -134,11 +135,13 @@ namespace DiscImageChef.Core if(manfid != null) { - sidecar.BlockMedia[0].PCMCIA.ManufacturerCode = manfid.ManufacturerID; - sidecar.BlockMedia[0].PCMCIA.CardCode = manfid.CardID; + sidecar.BlockMedia[0].PCMCIA.ManufacturerCode = + manfid.ManufacturerID; + sidecar.BlockMedia[0].PCMCIA.CardCode = manfid.CardID; sidecar.BlockMedia[0].PCMCIA.ManufacturerCodeSpecified = true; - sidecar.BlockMedia[0].PCMCIA.CardCodeSpecified = true; + sidecar.BlockMedia[0].PCMCIA.CardCodeSpecified = true; } + break; case TupleCodes.CISTPL_VERS_1: Level1VersionTuple vers = CIS.DecodeLevel1VersionTuple(tuple); @@ -146,12 +149,13 @@ namespace DiscImageChef.Core if(vers != null) { sidecar.BlockMedia[0].PCMCIA.Manufacturer = vers.Manufacturer; - sidecar.BlockMedia[0].PCMCIA.ProductName = vers.Product; - sidecar.BlockMedia[0].PCMCIA.Compliance = + sidecar.BlockMedia[0].PCMCIA.ProductName = vers.Product; + sidecar.BlockMedia[0].PCMCIA.Compliance = $"{vers.MajorVersion}.{vers.MinorVersion}"; sidecar.BlockMedia[0].PCMCIA.AdditionalInformation = vers.AdditionalInformation; } + break; } @@ -173,7 +177,7 @@ namespace DiscImageChef.Core sidecar.BlockMedia[0].SecureDigital.CID = new DumpType { Checksums = Checksum.GetChecksums(image.ReadDiskTag(MediaTagType.SD_CID)).ToArray(), - Size = image.ReadDiskTag(MediaTagType.SD_CID).Length + Size = image.ReadDiskTag(MediaTagType.SD_CID).Length }; break; case MediaTagType.SD_CSD: @@ -182,7 +186,7 @@ namespace DiscImageChef.Core sidecar.BlockMedia[0].SecureDigital.CSD = new DumpType { Checksums = Checksum.GetChecksums(image.ReadDiskTag(MediaTagType.SD_CSD)).ToArray(), - Size = image.ReadDiskTag(MediaTagType.SD_CSD).Length + Size = image.ReadDiskTag(MediaTagType.SD_CSD).Length }; break; case MediaTagType.SD_SCR: @@ -191,7 +195,7 @@ namespace DiscImageChef.Core sidecar.BlockMedia[0].SecureDigital.SCR = new DumpType { Checksums = Checksum.GetChecksums(image.ReadDiskTag(MediaTagType.SD_SCR)).ToArray(), - Size = image.ReadDiskTag(MediaTagType.SD_SCR).Length + Size = image.ReadDiskTag(MediaTagType.SD_SCR).Length }; break; case MediaTagType.SD_OCR: @@ -200,7 +204,7 @@ namespace DiscImageChef.Core sidecar.BlockMedia[0].SecureDigital.OCR = new DumpType { Checksums = Checksum.GetChecksums(image.ReadDiskTag(MediaTagType.SD_OCR)).ToArray(), - Size = image.ReadDiskTag(MediaTagType.SD_OCR).Length + Size = image.ReadDiskTag(MediaTagType.SD_OCR).Length }; break; case MediaTagType.MMC_CID: @@ -209,7 +213,7 @@ namespace DiscImageChef.Core sidecar.BlockMedia[0].MultiMediaCard.CID = new DumpType { Checksums = Checksum.GetChecksums(image.ReadDiskTag(MediaTagType.SD_CID)).ToArray(), - Size = image.ReadDiskTag(MediaTagType.SD_CID).Length + Size = image.ReadDiskTag(MediaTagType.SD_CID).Length }; break; case MediaTagType.MMC_CSD: @@ -218,7 +222,7 @@ namespace DiscImageChef.Core sidecar.BlockMedia[0].MultiMediaCard.CSD = new DumpType { Checksums = Checksum.GetChecksums(image.ReadDiskTag(MediaTagType.SD_CSD)).ToArray(), - Size = image.ReadDiskTag(MediaTagType.SD_CSD).Length + Size = image.ReadDiskTag(MediaTagType.SD_CSD).Length }; break; case MediaTagType.MMC_OCR: @@ -227,12 +231,12 @@ namespace DiscImageChef.Core sidecar.BlockMedia[0].MultiMediaCard.OCR = new DumpType { Checksums = Checksum.GetChecksums(image.ReadDiskTag(MediaTagType.SD_OCR)).ToArray(), - Size = image.ReadDiskTag(MediaTagType.SD_OCR).Length + Size = image.ReadDiskTag(MediaTagType.SD_OCR).Length }; break; case MediaTagType.MMC_ExtendedCSD: if(sidecar.BlockMedia[0].MultiMediaCard == null) - sidecar.BlockMedia[0].MultiMediaCard = new MultiMediaCardType(); + sidecar.BlockMedia[0].MultiMediaCard = new MultiMediaCardType(); sidecar.BlockMedia[0].MultiMediaCard.ExtendedCSD = new DumpType { Checksums = @@ -253,9 +257,9 @@ namespace DiscImageChef.Core // For fast debugging, skip checksum //goto skipImageChecksum; - uint sectorsToRead = 512; - ulong sectors = image.Info.Sectors; - ulong doneSectors = 0; + uint sectorsToRead = 512; + ulong sectors = image.Info.Sectors; + ulong doneSectors = 0; InitProgress2(); while(doneSectors < sectors) @@ -289,13 +293,13 @@ namespace DiscImageChef.Core } MediaType.MediaTypeToString(image.Info.MediaType, out string dskType, out string dskSubType); - sidecar.BlockMedia[0].DiskType = dskType; + sidecar.BlockMedia[0].DiskType = dskType; sidecar.BlockMedia[0].DiskSubType = dskSubType; Statistics.AddMedia(image.Info.MediaType, false); sidecar.BlockMedia[0].Dimensions = Dimensions.DimensionsFromMediaType(image.Info.MediaType); - sidecar.BlockMedia[0].LogicalBlocks = (long)image.Info.Sectors; + sidecar.BlockMedia[0].LogicalBlocks = (long)image.Info.Sectors; sidecar.BlockMedia[0].LogicalBlockSize = (int)image.Info.SectorSize; // TODO: Detect it sidecar.BlockMedia[0].PhysicalBlockSize = (int)image.Info.SectorSize; @@ -314,11 +318,11 @@ namespace DiscImageChef.Core sidecar.BlockMedia[0].FileSystemInformation[i] = new PartitionType { Description = partitions[i].Description, - EndSector = (int)partitions[i].End, - Name = partitions[i].Name, - Sequence = (int)partitions[i].Sequence, + EndSector = (int)partitions[i].End, + Name = partitions[i].Name, + Sequence = (int)partitions[i].Sequence, StartSector = (int)partitions[i].Start, - Type = partitions[i].Type + Type = partitions[i].Type }; List lstFs = new List(); @@ -331,9 +335,9 @@ namespace DiscImageChef.Core lstFs.Add(plugin.XmlFsType); Statistics.AddFilesystem(plugin.XmlFsType.Type); } -#pragma warning disable RECS0022 // A catch clause that catches System.Exception and has an empty body + #pragma warning disable RECS0022 // A catch clause that catches System.Exception and has an empty body catch -#pragma warning restore RECS0022 // A catch clause that catches System.Exception and has an empty body + #pragma warning restore RECS0022 // A catch clause that catches System.Exception and has an empty body { //DicConsole.DebugWriteLine("Create-sidecar command", "Plugin {0} crashed", _plugin.Name); } @@ -343,17 +347,14 @@ namespace DiscImageChef.Core } else { - sidecar.BlockMedia[0].FileSystemInformation[0] = new PartitionType - { - StartSector = 0, - EndSector = (int)(image.Info.Sectors - 1) - }; + sidecar.BlockMedia[0].FileSystemInformation[0] = + new PartitionType {StartSector = 0, EndSector = (int)(image.Info.Sectors - 1)}; Partition wholePart = new Partition { - Name = "Whole device", + Name = "Whole device", Length = image.Info.Sectors, - Size = image.Info.Sectors * image.Info.SectorSize + Size = image.Info.Sectors * image.Info.SectorSize }; List lstFs = new List(); @@ -367,9 +368,9 @@ namespace DiscImageChef.Core lstFs.Add(plugin.XmlFsType); Statistics.AddFilesystem(plugin.XmlFsType.Type); } -#pragma warning disable RECS0022 // A catch clause that catches System.Exception and has an empty body + #pragma warning disable RECS0022 // A catch clause that catches System.Exception and has an empty body catch -#pragma warning restore RECS0022 // A catch clause that catches System.Exception and has an empty body + #pragma warning restore RECS0022 // A catch clause that catches System.Exception and has an empty body { //DicConsole.DebugWriteLine("Create-sidecar command", "Plugin {0} crashed", _plugin.Name); } @@ -379,39 +380,41 @@ namespace DiscImageChef.Core if(image.Info.Cylinders > 0 && image.Info.Heads > 0 && image.Info.SectorsPerTrack > 0) { - sidecar.BlockMedia[0].CylindersSpecified = true; - sidecar.BlockMedia[0].HeadsSpecified = true; + sidecar.BlockMedia[0].CylindersSpecified = true; + sidecar.BlockMedia[0].HeadsSpecified = true; sidecar.BlockMedia[0].SectorsPerTrackSpecified = true; - sidecar.BlockMedia[0].Cylinders = image.Info.Cylinders; - sidecar.BlockMedia[0].Heads = image.Info.Heads; - sidecar.BlockMedia[0].SectorsPerTrack = image.Info.SectorsPerTrack; + sidecar.BlockMedia[0].Cylinders = image.Info.Cylinders; + sidecar.BlockMedia[0].Heads = image.Info.Heads; + sidecar.BlockMedia[0].SectorsPerTrack = image.Info.SectorsPerTrack; } if(image.Info.ReadableMediaTags.Contains(MediaTagType.ATA_IDENTIFY)) { Identify.IdentifyDevice? ataId = Identify.Decode(image.ReadDiskTag(MediaTagType.ATA_IDENTIFY)); if(ataId.HasValue) - if(ataId.Value.CurrentCylinders > 0 && ataId.Value.CurrentHeads > 0 && + if(ataId.Value.CurrentCylinders > 0 && ataId.Value.CurrentHeads > 0 && ataId.Value.CurrentSectorsPerTrack > 0) { - sidecar.BlockMedia[0].CylindersSpecified = true; - sidecar.BlockMedia[0].HeadsSpecified = true; + sidecar.BlockMedia[0].CylindersSpecified = true; + sidecar.BlockMedia[0].HeadsSpecified = true; sidecar.BlockMedia[0].SectorsPerTrackSpecified = true; - sidecar.BlockMedia[0].Cylinders = ataId.Value.CurrentCylinders; - sidecar.BlockMedia[0].Heads = ataId.Value.CurrentHeads; - sidecar.BlockMedia[0].SectorsPerTrack = ataId.Value.CurrentSectorsPerTrack; + sidecar.BlockMedia[0].Cylinders = ataId.Value.CurrentCylinders; + sidecar.BlockMedia[0].Heads = ataId.Value.CurrentHeads; + sidecar.BlockMedia[0].SectorsPerTrack = ataId.Value.CurrentSectorsPerTrack; } else if(ataId.Value.Cylinders > 0 && ataId.Value.Heads > 0 && ataId.Value.SectorsPerTrack > 0) { - sidecar.BlockMedia[0].CylindersSpecified = true; - sidecar.BlockMedia[0].HeadsSpecified = true; + sidecar.BlockMedia[0].CylindersSpecified = true; + sidecar.BlockMedia[0].HeadsSpecified = true; sidecar.BlockMedia[0].SectorsPerTrackSpecified = true; - sidecar.BlockMedia[0].Cylinders = ataId.Value.Cylinders; - sidecar.BlockMedia[0].Heads = ataId.Value.Heads; - sidecar.BlockMedia[0].SectorsPerTrack = ataId.Value.SectorsPerTrack; + sidecar.BlockMedia[0].Cylinders = ataId.Value.Cylinders; + sidecar.BlockMedia[0].Heads = ataId.Value.Heads; + sidecar.BlockMedia[0].SectorsPerTrack = ataId.Value.SectorsPerTrack; } } + if(image.DumpHardware != null) sidecar.BlockMedia[0].DumpHardwareArray = image.DumpHardware.ToArray(); + // TODO: This is more of a hack, redo it planned for >4.0 string trkFormat = null; @@ -533,8 +536,8 @@ namespace DiscImageChef.Core if(File.Exists(scpFilePath)) { - SuperCardPro scpImage = new SuperCardPro(); - ZZZNoFilter scpFilter = new ZZZNoFilter(); + SuperCardPro scpImage = new SuperCardPro(); + ZZZNoFilter scpFilter = new ZZZNoFilter(); scpFilter.Open(scpFilePath); if(image.Info.Heads <= 2 && scpImage.Identify(scpFilter)) @@ -542,46 +545,46 @@ namespace DiscImageChef.Core try { scpImage.Open(scpFilter); } catch(NotImplementedException) { } - if(image.Info.Heads == 2 && scpImage.Header.heads == 0 || image.Info.Heads == 1 && - (scpImage.Header.heads == 1 || scpImage.Header.heads == 2)) + if(image.Info.Heads == 2 && scpImage.Header.heads == 0 || image.Info.Heads == 1 && + (scpImage.Header.heads == 1 || scpImage.Header.heads == 2)) if(scpImage.Header.end + 1 >= image.Info.Cylinders) { List scpBlockTrackTypes = new List(); - long currentSector = 0; - Stream scpStream = scpFilter.GetDataForkStream(); + long currentSector = 0; + Stream scpStream = scpFilter.GetDataForkStream(); for(byte t = scpImage.Header.start; t <= scpImage.Header.end; t++) { BlockTrackType scpBlockTrackType = new BlockTrackType { Cylinder = t / image.Info.Heads, - Head = t % image.Info.Heads, - Image = new ImageType + Head = t % image.Info.Heads, + Image = new ImageType { format = scpImage.Format, - Value = Path.GetFileName(scpFilePath), + Value = Path.GetFileName(scpFilePath), offset = scpImage.Header.offsets[t] } }; if(scpBlockTrackType.Cylinder < image.Info.Cylinders) { - scpBlockTrackType.StartSector = currentSector; - currentSector += image.Info.SectorsPerTrack; - scpBlockTrackType.EndSector = currentSector - 1; - scpBlockTrackType.Sectors = image.Info.SectorsPerTrack; - scpBlockTrackType.BytesPerSector = (int)image.Info.SectorSize; - scpBlockTrackType.Format = trkFormat; + scpBlockTrackType.StartSector = currentSector; + currentSector += image.Info.SectorsPerTrack; + scpBlockTrackType.EndSector = currentSector - 1; + scpBlockTrackType.Sectors = image.Info.SectorsPerTrack; + scpBlockTrackType.BytesPerSector = (int)image.Info.SectorSize; + scpBlockTrackType.Format = trkFormat; } if(scpImage.ScpTracks.TryGetValue(t, out SuperCardPro.TrackHeader scpTrack)) { byte[] trackContents = - new byte[scpTrack.Entries.Last().dataOffset + + new byte[scpTrack.Entries.Last().dataOffset + scpTrack.Entries.Last().trackLength - scpImage.Header.offsets[t] + 1]; scpStream.Position = scpImage.Header.offsets[t]; scpStream.Read(trackContents, 0, trackContents.Length); - scpBlockTrackType.Size = trackContents.Length; + scpBlockTrackType.Size = trackContents.Length; scpBlockTrackType.Checksums = Checksum.GetChecksums(trackContents).ToArray(); } @@ -593,18 +596,18 @@ namespace DiscImageChef.Core } else DicConsole - .ErrorWriteLine("SuperCardPro image do not contain same number of tracks ({0}) than disk image ({1}), ignoring...", - scpImage.Header.end + 1, image.Info.Cylinders); + .ErrorWriteLine("SuperCardPro image do not contain same number of tracks ({0}) than disk image ({1}), ignoring...", + scpImage.Header.end + 1, image.Info.Cylinders); else DicConsole - .ErrorWriteLine("SuperCardPro image do not contain same number of heads ({0}) than disk image ({1}), ignoring...", - 2, image.Info.Heads); + .ErrorWriteLine("SuperCardPro image do not contain same number of heads ({0}) than disk image ({1}), ignoring...", + 2, image.Info.Heads); } } #endregion #region KryoFlux - string kfFile = null; + string kfFile = null; string basename = Path.Combine(Path.GetDirectoryName(imagePath), Path.GetFileNameWithoutExtension(imagePath)); bool kfDir = false; @@ -615,15 +618,17 @@ namespace DiscImageChef.Core if(possibleKfStarts.Length > 0) { kfFile = possibleKfStarts[0]; - kfDir = true; + kfDir = true; } } - else if(File.Exists(basename + "00.0.raw")) kfFile = basename + "00.0.raw"; - else if(File.Exists(basename + "00.1.raw")) kfFile = basename + "00.1.raw"; + else if(File.Exists(basename + "00.0.raw")) + kfFile = basename + "00.0.raw"; + else if(File.Exists(basename + "00.1.raw")) + kfFile = basename + "00.1.raw"; if(kfFile != null) { - KryoFlux kfImage = new KryoFlux(); + KryoFlux kfImage = new KryoFlux(); ZZZNoFilter kfFilter = new ZZZNoFilter(); kfFilter.Open(kfFile); if(image.Info.Heads <= 2 && kfImage.Identify(kfFilter)) @@ -631,7 +636,7 @@ namespace DiscImageChef.Core try { kfImage.Open(kfFilter); } catch(NotImplementedException) { } - if(kfImage.Info.Heads == image.Info.Heads) + if(kfImage.Info.Heads == image.Info.Heads) if(kfImage.Info.Cylinders >= image.Info.Cylinders) { List kfBlockTrackTypes = new List(); @@ -643,34 +648,34 @@ namespace DiscImageChef.Core BlockTrackType kfBlockTrackType = new BlockTrackType { Cylinder = kvp.Key / image.Info.Heads, - Head = kvp.Key % image.Info.Heads, - Image = new ImageType + Head = kvp.Key % image.Info.Heads, + Image = new ImageType { format = kfImage.Format, - Value = kfDir - ? Path + Value = kfDir + ? Path .Combine(Path.GetFileName(Path.GetDirectoryName(kvp.Value.GetBasePath())), kvp.Value.GetFilename()) - : kvp.Value.GetFilename(), + : kvp.Value.GetFilename(), offset = 0 } }; if(kfBlockTrackType.Cylinder < image.Info.Cylinders) { - kfBlockTrackType.StartSector = currentSector; - currentSector += image.Info.SectorsPerTrack; - kfBlockTrackType.EndSector = currentSector - 1; - kfBlockTrackType.Sectors = image.Info.SectorsPerTrack; - kfBlockTrackType.BytesPerSector = (int)image.Info.SectorSize; - kfBlockTrackType.Format = trkFormat; + kfBlockTrackType.StartSector = currentSector; + currentSector += image.Info.SectorsPerTrack; + kfBlockTrackType.EndSector = currentSector - 1; + kfBlockTrackType.Sectors = image.Info.SectorsPerTrack; + kfBlockTrackType.BytesPerSector = (int)image.Info.SectorSize; + kfBlockTrackType.Format = trkFormat; } - Stream kfStream = kvp.Value.GetDataForkStream(); + Stream kfStream = kvp.Value.GetDataForkStream(); byte[] trackContents = new byte[kfStream.Length]; - kfStream.Position = 0; + kfStream.Position = 0; kfStream.Read(trackContents, 0, trackContents.Length); - kfBlockTrackType.Size = trackContents.Length; + kfBlockTrackType.Size = trackContents.Length; kfBlockTrackType.Checksums = Checksum.GetChecksums(trackContents).ToArray(); kfBlockTrackTypes.Add(kfBlockTrackType); @@ -681,12 +686,12 @@ namespace DiscImageChef.Core } else DicConsole - .ErrorWriteLine("KryoFlux image do not contain same number of tracks ({0}) than disk image ({1}), ignoring...", - kfImage.Info.Cylinders, image.Info.Cylinders); + .ErrorWriteLine("KryoFlux image do not contain same number of tracks ({0}) than disk image ({1}), ignoring...", + kfImage.Info.Cylinders, image.Info.Cylinders); else DicConsole - .ErrorWriteLine("KryoFluximage do not contain same number of heads ({0}) than disk image ({1}), ignoring...", - kfImage.Info.Heads, image.Info.Heads); + .ErrorWriteLine("KryoFluximage do not contain same number of heads ({0}) than disk image ({1}), ignoring...", + kfImage.Info.Heads, image.Info.Heads); } } #endregion @@ -697,7 +702,7 @@ namespace DiscImageChef.Core if(!File.Exists(dfiFilePath)) return; - DiscFerret dfiImage = new DiscFerret(); + DiscFerret dfiImage = new DiscFerret(); ZZZNoFilter dfiFilter = new ZZZNoFilter(); dfiFilter.Open(dfiFilePath); @@ -706,40 +711,40 @@ namespace DiscImageChef.Core try { dfiImage.Open(dfiFilter); } catch(NotImplementedException) { } - if(image.Info.Heads == dfiImage.Info.Heads) + if(image.Info.Heads == dfiImage.Info.Heads) if(dfiImage.Info.Cylinders >= image.Info.Cylinders) { List dfiBlockTrackTypes = new List(); - long currentSector = 0; - Stream dfiStream = dfiFilter.GetDataForkStream(); + long currentSector = 0; + Stream dfiStream = dfiFilter.GetDataForkStream(); foreach(int t in dfiImage.TrackOffsets.Keys) { BlockTrackType dfiBlockTrackType = new BlockTrackType { Cylinder = t / image.Info.Heads, - Head = t % image.Info.Heads, - Image = new ImageType {format = dfiImage.Format, Value = Path.GetFileName(dfiFilePath)} + Head = t % image.Info.Heads, + Image = new ImageType {format = dfiImage.Format, Value = Path.GetFileName(dfiFilePath)} }; if(dfiBlockTrackType.Cylinder < image.Info.Cylinders) { - dfiBlockTrackType.StartSector = currentSector; - currentSector += image.Info.SectorsPerTrack; - dfiBlockTrackType.EndSector = currentSector - 1; - dfiBlockTrackType.Sectors = image.Info.SectorsPerTrack; - dfiBlockTrackType.BytesPerSector = (int)image.Info.SectorSize; - dfiBlockTrackType.Format = trkFormat; + dfiBlockTrackType.StartSector = currentSector; + currentSector += image.Info.SectorsPerTrack; + dfiBlockTrackType.EndSector = currentSector - 1; + dfiBlockTrackType.Sectors = image.Info.SectorsPerTrack; + dfiBlockTrackType.BytesPerSector = (int)image.Info.SectorSize; + dfiBlockTrackType.Format = trkFormat; } if(dfiImage.TrackOffsets.TryGetValue(t, out long offset) && dfiImage.TrackLengths.TryGetValue(t, out long length)) { dfiBlockTrackType.Image.offset = offset; - byte[] trackContents = new byte[length]; - dfiStream.Position = offset; + byte[] trackContents = new byte[length]; + dfiStream.Position = offset; dfiStream.Read(trackContents, 0, trackContents.Length); - dfiBlockTrackType.Size = trackContents.Length; + dfiBlockTrackType.Size = trackContents.Length; dfiBlockTrackType.Checksums = Checksum.GetChecksums(trackContents).ToArray(); } @@ -751,12 +756,12 @@ namespace DiscImageChef.Core } else DicConsole - .ErrorWriteLine("DiscFerret image do not contain same number of tracks ({0}) than disk image ({1}), ignoring...", - dfiImage.Info.Cylinders, image.Info.Cylinders); + .ErrorWriteLine("DiscFerret image do not contain same number of tracks ({0}) than disk image ({1}), ignoring...", + dfiImage.Info.Cylinders, image.Info.Cylinders); else DicConsole - .ErrorWriteLine("DiscFerret image do not contain same number of heads ({0}) than disk image ({1}), ignoring...", - dfiImage.Info.Heads, image.Info.Heads); + .ErrorWriteLine("DiscFerret image do not contain same number of heads ({0}) than disk image ({1}), ignoring...", + dfiImage.Info.Heads, image.Info.Heads); #endregion // TODO: Implement support for getting CHS from SCSI mode pages diff --git a/DiscImageChef.Core/Sidecar/OpticalDisc.cs b/DiscImageChef.Core/Sidecar/OpticalDisc.cs index 49a0e3267..8ff6d0000 100644 --- a/DiscImageChef.Core/Sidecar/OpticalDisc.cs +++ b/DiscImageChef.Core/Sidecar/OpticalDisc.cs @@ -58,7 +58,8 @@ namespace DiscImageChef.Core /// Image plugins /// List of image checksums /// Metadata sidecar - static void OpticalDisc(IMediaImage image, Guid filterId, string imagePath, FileInfo fi, PluginBase plugins, + static void OpticalDisc(IMediaImage image, Guid filterId, string imagePath, + FileInfo fi, PluginBase plugins, List imgChecksums, ref CICMMetadataType sidecar, Encoding encoding) { sidecar.OpticalDisc = new[] @@ -66,14 +67,14 @@ namespace DiscImageChef.Core new OpticalDiscType { Checksums = imgChecksums.ToArray(), - Image = new ImageType + Image = new ImageType { - format = image.Format, - offset = 0, + format = image.Format, + offset = 0, offsetSpecified = true, - Value = Path.GetFileName(imagePath) + Value = Path.GetFileName(imagePath) }, - Size = fi.Length, + Size = fi.Length, Sequence = new SequenceType {MediaTitle = image.Info.MediaTitle} } }; @@ -81,12 +82,12 @@ namespace DiscImageChef.Core if(image.Info.MediaSequence != 0 && image.Info.LastMediaSequence != 0) { sidecar.OpticalDisc[0].Sequence.MediaSequence = image.Info.MediaSequence; - sidecar.OpticalDisc[0].Sequence.TotalMedia = image.Info.LastMediaSequence; + sidecar.OpticalDisc[0].Sequence.TotalMedia = image.Info.LastMediaSequence; } else { sidecar.OpticalDisc[0].Sequence.MediaSequence = 1; - sidecar.OpticalDisc[0].Sequence.TotalMedia = 1; + sidecar.OpticalDisc[0].Sequence.TotalMedia = 1; } MediaType dskType = image.Info.MediaType; @@ -98,32 +99,34 @@ namespace DiscImageChef.Core sidecar.OpticalDisc[0].ATIP = new DumpType { Checksums = Checksum.GetChecksums(image.ReadDiskTag(MediaTagType.CD_ATIP)).ToArray(), - Size = image.ReadDiskTag(MediaTagType.CD_ATIP).Length + Size = image.ReadDiskTag(MediaTagType.CD_ATIP).Length }; ATIP.CDATIP? atip = ATIP.Decode(image.ReadDiskTag(MediaTagType.CD_ATIP)); if(atip.HasValue) - if(atip.Value.DDCD) dskType = atip.Value.DiscType ? MediaType.DDCDRW : MediaType.DDCDR; - else dskType = atip.Value.DiscType ? MediaType.CDRW : MediaType.CDR; + if(atip.Value.DDCD) + dskType = atip.Value.DiscType ? MediaType.DDCDRW : MediaType.DDCDR; + else + dskType = atip.Value.DiscType ? MediaType.CDRW : MediaType.CDR; break; case MediaTagType.DVD_BCA: sidecar.OpticalDisc[0].BCA = new DumpType { Checksums = Checksum.GetChecksums(image.ReadDiskTag(MediaTagType.DVD_BCA)).ToArray(), - Size = image.ReadDiskTag(MediaTagType.DVD_BCA).Length + Size = image.ReadDiskTag(MediaTagType.DVD_BCA).Length }; break; case MediaTagType.BD_BCA: sidecar.OpticalDisc[0].BCA = new DumpType { Checksums = Checksum.GetChecksums(image.ReadDiskTag(MediaTagType.BD_BCA)).ToArray(), - Size = image.ReadDiskTag(MediaTagType.BD_BCA).Length + Size = image.ReadDiskTag(MediaTagType.BD_BCA).Length }; break; case MediaTagType.DVD_CMI: sidecar.OpticalDisc[0].CMI = new DumpType { Checksums = Checksum.GetChecksums(image.ReadDiskTag(MediaTagType.DVD_CMI)).ToArray(), - Size = image.ReadDiskTag(MediaTagType.DVD_CMI).Length + Size = image.ReadDiskTag(MediaTagType.DVD_CMI).Length }; CSS_CPRM.LeadInCopyright? cmi = CSS_CPRM.DecodeLeadInCopyright(image.ReadDiskTag(MediaTagType.DVD_CMI)); @@ -146,24 +149,25 @@ namespace DiscImageChef.Core sidecar.OpticalDisc[0].DMI = new DumpType { Checksums = Checksum.GetChecksums(image.ReadDiskTag(MediaTagType.DVD_DMI)).ToArray(), - Size = image.ReadDiskTag(MediaTagType.DVD_DMI).Length + Size = image.ReadDiskTag(MediaTagType.DVD_DMI).Length }; if(DMI.IsXbox(image.ReadDiskTag(MediaTagType.DVD_DMI))) { - dskType = MediaType.XGD; + dskType = MediaType.XGD; sidecar.OpticalDisc[0].Dimensions = new DimensionsType {Diameter = 120}; } else if(DMI.IsXbox360(image.ReadDiskTag(MediaTagType.DVD_DMI))) { - dskType = MediaType.XGD2; + dskType = MediaType.XGD2; sidecar.OpticalDisc[0].Dimensions = new DimensionsType {Diameter = 120}; } + break; case MediaTagType.DVD_PFI: sidecar.OpticalDisc[0].PFI = new DumpType { Checksums = Checksum.GetChecksums(image.ReadDiskTag(MediaTagType.DVD_PFI)).ToArray(), - Size = image.ReadDiskTag(MediaTagType.DVD_PFI).Length + Size = image.ReadDiskTag(MediaTagType.DVD_PFI).Length }; PFI.PhysicalFormatInformation? pfi = PFI.Decode(image.ReadDiskTag(MediaTagType.DVD_PFI)); if(pfi.HasValue) @@ -215,13 +219,14 @@ namespace DiscImageChef.Core break; } - if(dskType == MediaType.DVDR && pfi.Value.PartVersion == 6) dskType = MediaType.DVDRDL; + if(dskType == MediaType.DVDR && pfi.Value.PartVersion == 6) dskType = MediaType.DVDRDL; if(dskType == MediaType.DVDRW && pfi.Value.PartVersion == 3) dskType = MediaType.DVDRWDL; if(dskType == MediaType.GOD && pfi.Value.DiscSize == DVDSize.OneTwenty) dskType = MediaType.WOD; - sidecar.OpticalDisc[0].Dimensions = new DimensionsType(); + sidecar.OpticalDisc[0].Dimensions = + new DimensionsType(); if(dskType == MediaType.UMD) sidecar.OpticalDisc[0].Dimensions.Diameter = 60; else switch(pfi.Value.DiscSize) @@ -240,25 +245,25 @@ namespace DiscImageChef.Core sidecar.OpticalDisc[0].PMA = new DumpType { Checksums = Checksum.GetChecksums(image.ReadDiskTag(MediaTagType.CD_PMA)).ToArray(), - Size = image.ReadDiskTag(MediaTagType.CD_PMA).Length + Size = image.ReadDiskTag(MediaTagType.CD_PMA).Length }; break; } try { - List sessions = image.Sessions; + List sessions = image.Sessions; sidecar.OpticalDisc[0].Sessions = sessions?.Count ?? 1; } catch { sidecar.OpticalDisc[0].Sessions = 1; } - List tracks = image.Tracks; + List tracks = image.Tracks; List trksLst = null; if(tracks != null) { - sidecar.OpticalDisc[0].Tracks = new int[1]; + sidecar.OpticalDisc[0].Tracks = new int[1]; sidecar.OpticalDisc[0].Tracks[0] = tracks.Count; - trksLst = new List(); + trksLst = new List(); } InitProgress(); @@ -305,24 +310,25 @@ namespace DiscImageChef.Core break; } - xmlTrk.Sequence = + xmlTrk.Sequence = new TrackSequenceType {Session = trk.TrackSession, TrackNumber = (int)trk.TrackSequence}; - xmlTrk.StartSector = (long)trk.TrackStartSector; - xmlTrk.EndSector = (long)trk.TrackEndSector; + xmlTrk.StartSector = (long)trk.TrackStartSector; + xmlTrk.EndSector = (long)trk.TrackEndSector; if(trk.Indexes != null && trk.Indexes.ContainsKey(0)) - if(trk.Indexes.TryGetValue(0, out ulong idx0)) xmlTrk.StartSector = (long)idx0; + if(trk.Indexes.TryGetValue(0, out ulong idx0)) + xmlTrk.StartSector = (long)idx0; switch(sidecar.OpticalDisc[0].DiscType) { case "CD": case "GD": xmlTrk.StartMSF = LbaToMsf(xmlTrk.StartSector); - xmlTrk.EndMSF = LbaToMsf(xmlTrk.EndSector); + xmlTrk.EndMSF = LbaToMsf(xmlTrk.EndSector); break; case "DDCD": xmlTrk.StartMSF = DdcdLbaToMsf(xmlTrk.StartSector); - xmlTrk.EndMSF = DdcdLbaToMsf(xmlTrk.EndSector); + xmlTrk.EndMSF = DdcdLbaToMsf(xmlTrk.EndSector); break; } @@ -330,16 +336,16 @@ namespace DiscImageChef.Core if(trk.TrackFileOffset > 0) { - xmlTrk.Image.offset = (long)trk.TrackFileOffset; + xmlTrk.Image.offset = (long)trk.TrackFileOffset; xmlTrk.Image.offsetSpecified = true; } - xmlTrk.Size = (xmlTrk.EndSector - xmlTrk.StartSector + 1) * trk.TrackRawBytesPerSector; + xmlTrk.Size = (xmlTrk.EndSector - xmlTrk.StartSector + 1) * trk.TrackRawBytesPerSector; xmlTrk.BytesPerSector = trk.TrackBytesPerSector; - uint sectorsToRead = 512; - ulong sectors = (ulong)(xmlTrk.EndSector - xmlTrk.StartSector + 1); - ulong doneSectors = 0; + uint sectorsToRead = 512; + ulong sectors = (ulong)(xmlTrk.EndSector - xmlTrk.StartSector + 1); + ulong doneSectors = 0; // If there is only one track, and it's the same as the image file (e.g. ".iso" files), don't re-checksum. if(image.Id == new Guid("12345678-AAAA-BBBB-CCCC-123456789000") && @@ -376,7 +382,7 @@ namespace DiscImageChef.Core (uint)xmlTrk.Sequence.TrackNumber); UpdateProgress2("Hashings sector {0} of {1}", (long)doneSectors, (long)(trk.TrackEndSector - trk.TrackStartSector + 1)); - doneSectors += sectors - doneSectors; + doneSectors += sectors - doneSectors; } trkChkWorker.Update(sector); @@ -416,13 +422,13 @@ namespace DiscImageChef.Core if(trk.TrackFileOffset > 0) { - xmlTrk.SubChannel.Image.offset = (long)trk.TrackSubchannelOffset; + xmlTrk.SubChannel.Image.offset = (long)trk.TrackSubchannelOffset; xmlTrk.SubChannel.Image.offsetSpecified = true; } Checksum subChkWorker = new Checksum(); - sectors = (ulong)(xmlTrk.EndSector - xmlTrk.StartSector + 1); + sectors = (ulong)(xmlTrk.EndSector - xmlTrk.StartSector + 1); doneSectors = 0; InitProgress2(); @@ -445,7 +451,7 @@ namespace DiscImageChef.Core SectorTagType.CdSectorSubchannel); UpdateProgress2("Hashings subchannel sector {0} of {1}", (long)doneSectors, (long)(trk.TrackEndSector - trk.TrackStartSector + 1)); - doneSectors += sectors - doneSectors; + doneSectors += sectors - doneSectors; } subChkWorker.Update(sector); @@ -462,7 +468,7 @@ namespace DiscImageChef.Core //skipChecksum: UpdateStatus("Checking filesystems on track {0} from sector {1} to {2}", xmlTrk.Sequence.TrackNumber, - xmlTrk.StartSector, xmlTrk.EndSector); + xmlTrk.StartSector, xmlTrk.EndSector); List partitions = Partitions.GetAll(image); Partitions.AddSchemesToStats(partitions); @@ -476,11 +482,11 @@ namespace DiscImageChef.Core xmlTrk.FileSystemInformation[i] = new PartitionType { Description = partitions[i].Description, - EndSector = (int)partitions[i].End, - Name = partitions[i].Name, - Sequence = (int)partitions[i].Sequence, + EndSector = (int)partitions[i].End, + Name = partitions[i].Name, + Sequence = (int)partitions[i].Sequence, StartSector = (int)partitions[i].Start, - Type = partitions[i].Type + Type = partitions[i].Type }; List lstFs = new List(); @@ -509,9 +515,9 @@ namespace DiscImageChef.Core break; } } -#pragma warning disable RECS0022 // A catch clause that catches System.Exception and has an empty body + #pragma warning disable RECS0022 // A catch clause that catches System.Exception and has an empty body catch -#pragma warning restore RECS0022 // A catch clause that catches System.Exception and has an empty body + #pragma warning restore RECS0022 // A catch clause that catches System.Exception and has an empty body { //DicConsole.DebugWriteLine("Create-sidecar command", "Plugin {0} crashed", _plugin.Name); } @@ -523,17 +529,17 @@ namespace DiscImageChef.Core { xmlTrk.FileSystemInformation[0] = new PartitionType { - EndSector = (int)xmlTrk.EndSector, + EndSector = (int)xmlTrk.EndSector, StartSector = (int)xmlTrk.StartSector }; List lstFs = new List(); Partition xmlPart = new Partition { - Start = (ulong)xmlTrk.StartSector, - Length = (ulong)(xmlTrk.EndSector - xmlTrk.StartSector + 1), - Type = xmlTrk.TrackType1.ToString(), - Size = (ulong)xmlTrk.Size, + Start = (ulong)xmlTrk.StartSector, + Length = (ulong)(xmlTrk.EndSector - xmlTrk.StartSector + 1), + Type = xmlTrk.TrackType1.ToString(), + Size = (ulong)xmlTrk.Size, Sequence = (ulong)xmlTrk.Sequence.TrackNumber }; foreach(IFilesystem plugin in plugins.PluginsList.Values) @@ -561,9 +567,9 @@ namespace DiscImageChef.Core break; } } -#pragma warning disable RECS0022 // A catch clause that catches System.Exception and has an empty body + #pragma warning disable RECS0022 // A catch clause that catches System.Exception and has an empty body catch -#pragma warning restore RECS0022 // A catch clause that catches System.Exception and has an empty body + #pragma warning restore RECS0022 // A catch clause that catches System.Exception and has an empty body { //DicConsole.DebugWriteLine("Create-sidecar command", "Plugin {0} crashed", _plugin.Name); } @@ -581,35 +587,36 @@ namespace DiscImageChef.Core // All XGD3 all have the same number of blocks if(dskType == MediaType.XGD2 && sidecar.OpticalDisc[0].Track.Length == 1) { - ulong blocks = (ulong)(sidecar.OpticalDisc[0].Track[0].EndSector - + ulong blocks = (ulong)(sidecar.OpticalDisc[0].Track[0].EndSector - sidecar.OpticalDisc[0].Track[0].StartSector + 1); - if(blocks == 25063 || // Locked (or non compatible drive) + if(blocks == 25063 || // Locked (or non compatible drive) blocks == 4229664 || // Xtreme unlock - blocks == 4246304) // Wxripper unlock + blocks == 4246304) // Wxripper unlock dskType = MediaType.XGD3; } Metadata.MediaType.MediaTypeToString(dskType, out string dscType, out string dscSubType); - sidecar.OpticalDisc[0].DiscType = dscType; + sidecar.OpticalDisc[0].DiscType = dscType; sidecar.OpticalDisc[0].DiscSubType = dscSubType; Statistics.AddMedia(dskType, false); - if(!string.IsNullOrEmpty(image.Info.DriveManufacturer) || - !string.IsNullOrEmpty(image.Info.DriveModel) || - !string.IsNullOrEmpty(image.Info.DriveFirmwareRevision) || - !string.IsNullOrEmpty(image.Info.DriveSerialNumber)) + if(image.DumpHardware != null) sidecar.OpticalDisc[0].DumpHardwareArray = image.DumpHardware.ToArray(); + else if(!string.IsNullOrEmpty(image.Info.DriveManufacturer) || + !string.IsNullOrEmpty(image.Info.DriveModel) || + !string.IsNullOrEmpty(image.Info.DriveFirmwareRevision) || + !string.IsNullOrEmpty(image.Info.DriveSerialNumber)) sidecar.OpticalDisc[0].DumpHardwareArray = new[] { new DumpHardwareType { - Extents = new[] {new ExtentType {Start = 0, End = image.Info.Sectors}}, + Extents = new[] {new ExtentType {Start = 0, End = image.Info.Sectors}}, Manufacturer = image.Info.DriveManufacturer, - Model = image.Info.DriveModel, - Firmware = image.Info.DriveFirmwareRevision, - Serial = image.Info.DriveSerialNumber, - Software = new SoftwareType + Model = image.Info.DriveModel, + Firmware = image.Info.DriveFirmwareRevision, + Serial = image.Info.DriveSerialNumber, + Software = new SoftwareType { - Name = image.Info.Application, + Name = image.Info.Application, Version = image.Info.ApplicationVersion } } diff --git a/DiscImageChef.Core/Sidecar/Sidecar.cs b/DiscImageChef.Core/Sidecar/Sidecar.cs index 67bb06488..84db40416 100644 --- a/DiscImageChef.Core/Sidecar/Sidecar.cs +++ b/DiscImageChef.Core/Sidecar/Sidecar.cs @@ -51,10 +51,10 @@ namespace DiscImageChef.Core /// The metadata sidecar public static CICMMetadataType Create(IMediaImage image, string imagePath, Guid filterId, Encoding encoding) { - CICMMetadataType sidecar = new CICMMetadataType(); - PluginBase plugins = new PluginBase(); + CICMMetadataType sidecar = image.CicmMetadata ?? new CICMMetadataType(); + PluginBase plugins = new PluginBase(); - FileInfo fi = new FileInfo(imagePath); + FileInfo fi = new FileInfo(imagePath); FileStream fs = new FileStream(imagePath, FileMode.Open, FileAccess.Read); Checksum imgChkWorker = new Checksum(); @@ -63,7 +63,7 @@ namespace DiscImageChef.Core //goto skipImageChecksum; byte[] data; - long position = 0; + long position = 0; InitProgress(); while(position < fi.Length - 1048576) { @@ -77,7 +77,7 @@ namespace DiscImageChef.Core position += 1048576; } - data = new byte[fi.Length - position]; + data = new byte[fi.Length - position]; fs.Read(data, 0, (int)(fi.Length - position)); UpdateProgress("Hashing image file byte {0} of {1}", position, fi.Length); @@ -92,6 +92,11 @@ namespace DiscImageChef.Core List imgChecksums = imgChkWorker.End(); + sidecar.OpticalDisc = null; + sidecar.BlockMedia = null; + sidecar.AudioMedia = null; + sidecar.LinearMedia = null; + switch(image.Info.XmlMediaType) { case XmlMediaType.OpticalDisc: diff --git a/DiscImageChef.DiscImages/Alcohol120.cs b/DiscImageChef.DiscImages/Alcohol120.cs index 8cefea781..5e46d17b3 100644 --- a/DiscImageChef.DiscImages/Alcohol120.cs +++ b/DiscImageChef.DiscImages/Alcohol120.cs @@ -43,6 +43,7 @@ using DiscImageChef.Console; using DiscImageChef.Decoders.CD; using DiscImageChef.Decoders.DVD; using DiscImageChef.Filters; +using Schemas; using DMI = DiscImageChef.Decoders.Xbox.DMI; namespace DiscImageChef.DiscImages @@ -102,7 +103,7 @@ namespace DiscImageChef.DiscImages public string Format => "Alcohol 120% Media Descriptor Structure"; - public List Partitions { get; set; } + public List Partitions { get; private set; } public List Tracks { @@ -1432,6 +1433,9 @@ namespace DiscImageChef.DiscImages return null; } + public List DumpHardware => null; + public CICMMetadataType CicmMetadata => null; + public IEnumerable SupportedMediaTags => new[] {MediaTagType.CD_FullTOC, MediaTagType.DVD_BCA, MediaTagType.DVD_DMI, MediaTagType.DVD_PFI}; public IEnumerable SupportedSectorTags => @@ -2052,12 +2056,11 @@ namespace DiscImageChef.DiscImages byte[] filename = Encoding.Unicode.GetBytes("*.mdf"); // Yup, Alcohol stores no filename but a wildcard. - byte[] block; IntPtr blockPtr; // Write header descriptorStream.Seek(0, SeekOrigin.Begin); - block = new byte[Marshal.SizeOf(header)]; + byte[] block = new byte[Marshal.SizeOf(header)]; blockPtr = Marshal.AllocHGlobal(Marshal.SizeOf(header)); Marshal.StructureToPtr(header, blockPtr, true); Marshal.Copy(blockPtr, block, 0, block.Length); @@ -2284,6 +2287,18 @@ namespace DiscImageChef.DiscImages } } + public bool SetDumpHardware(List dumpHardware) + { + // Not supported + return false; + } + + public bool SetCicmMetadata(CICMMetadataType metadata) + { + // Not supported + return false; + } + static ushort AlcoholTrackModeToBytesPerSector(AlcoholTrackMode trackMode) { switch(trackMode) diff --git a/DiscImageChef.DiscImages/Anex86.cs b/DiscImageChef.DiscImages/Anex86.cs index af0f73dfd..1d2bc2d6e 100644 --- a/DiscImageChef.DiscImages/Anex86.cs +++ b/DiscImageChef.DiscImages/Anex86.cs @@ -38,6 +38,7 @@ using System.Runtime.InteropServices; using DiscImageChef.CommonTypes; using DiscImageChef.Console; using DiscImageChef.Filters; +using Schemas; namespace DiscImageChef.DiscImages { @@ -279,6 +280,9 @@ namespace DiscImageChef.DiscImages return null; } + public List DumpHardware => null; + public CICMMetadataType CicmMetadata => null; + public IEnumerable SupportedMediaTags => new MediaTagType[] { }; public IEnumerable SupportedSectorTags => new SectorTagType[] { }; // TODO: Test with real hardware to see real supported media @@ -317,7 +321,7 @@ namespace DiscImageChef.DiscImages if(sectors * sectorSize > int.MaxValue || sectors > (long)int.MaxValue * 8 * 33) { - ErrorMessage = $"Too many sectors"; + ErrorMessage = "Too many sectors"; return false; } @@ -516,6 +520,18 @@ namespace DiscImageChef.DiscImages return false; } + public bool SetDumpHardware(List dumpHardware) + { + // Not supported + return false; + } + + public bool SetCicmMetadata(CICMMetadataType metadata) + { + // Not supported + return false; + } + [StructLayout(LayoutKind.Sequential, Pack = 1)] struct Anex86Header { diff --git a/DiscImageChef.DiscImages/Apple2MG.cs b/DiscImageChef.DiscImages/Apple2MG.cs index 2bb7699f8..f9115668f 100644 --- a/DiscImageChef.DiscImages/Apple2MG.cs +++ b/DiscImageChef.DiscImages/Apple2MG.cs @@ -40,6 +40,7 @@ using System.Text; using DiscImageChef.CommonTypes; using DiscImageChef.Console; using DiscImageChef.Filters; +using Schemas; namespace DiscImageChef.DiscImages { @@ -520,6 +521,9 @@ namespace DiscImageChef.DiscImages return null; } + public List DumpHardware => null; + public CICMMetadataType CicmMetadata => null; + public IEnumerable SupportedMediaTags => new MediaTagType[] { }; public IEnumerable SupportedSectorTags => new SectorTagType[] { }; public IEnumerable SupportedMediaTypes => @@ -733,6 +737,18 @@ namespace DiscImageChef.DiscImages return false; } + public bool SetDumpHardware(List dumpHardware) + { + // Not supported + return false; + } + + public bool SetCicmMetadata(CICMMetadataType metadata) + { + // Not supported + return false; + } + MediaType GetMediaType() { switch(imageInfo.Sectors) diff --git a/DiscImageChef.DiscImages/AppleDOS.cs b/DiscImageChef.DiscImages/AppleDOS.cs index 1895edfbb..9ca24f09b 100644 --- a/DiscImageChef.DiscImages/AppleDOS.cs +++ b/DiscImageChef.DiscImages/AppleDOS.cs @@ -35,6 +35,7 @@ using System.Collections.Generic; using System.IO; using DiscImageChef.CommonTypes; using DiscImageChef.Filters; +using Schemas; namespace DiscImageChef.DiscImages { @@ -195,6 +196,9 @@ namespace DiscImageChef.DiscImages return null; } + public List DumpHardware => null; + public CICMMetadataType CicmMetadata => null; + public List GetSessionTracks(Session session) { throw new FeatureUnsupportedImageException("Feature not supported by image format"); @@ -425,5 +429,17 @@ namespace DiscImageChef.DiscImages ErrorMessage = "Writing sectors with tags is not supported."; return false; } + + public bool SetDumpHardware(List dumpHardware) + { + // Not supported + return false; + } + + public bool SetCicmMetadata(CICMMetadataType metadata) + { + // Not supported + return false; + } } } \ No newline at end of file diff --git a/DiscImageChef.DiscImages/AppleNIB.cs b/DiscImageChef.DiscImages/AppleNIB.cs index a47f42ab7..16d3c0186 100644 --- a/DiscImageChef.DiscImages/AppleNIB.cs +++ b/DiscImageChef.DiscImages/AppleNIB.cs @@ -38,55 +38,56 @@ using DiscImageChef.CommonTypes; using DiscImageChef.Console; using DiscImageChef.Decoders.Floppy; using DiscImageChef.Filters; +using Schemas; namespace DiscImageChef.DiscImages { // TODO: Checksum sectors public class AppleNib : IMediaImage { - readonly byte[] apple3_sign = {0x8D, 0xD0, 0x03, 0x4C, 0xC7, 0xA4}; - readonly byte[] cpm_sign = {0xA2, 0x55, 0xA9, 0x00, 0x9D, 0x00, 0x0D, 0xCA}; - readonly byte[] dos_sign = {0xA2, 0x02, 0x8E, 0x52}; - readonly ulong[] dosSkewing = {0, 7, 14, 6, 13, 5, 12, 4, 11, 3, 10, 2, 9, 1, 8, 15}; - readonly byte[] dri_string = + readonly byte[] apple3_sign = {0x8D, 0xD0, 0x03, 0x4C, 0xC7, 0xA4}; + readonly byte[] cpm_sign = {0xA2, 0x55, 0xA9, 0x00, 0x9D, 0x00, 0x0D, 0xCA}; + readonly byte[] dos_sign = {0xA2, 0x02, 0x8E, 0x52}; + readonly ulong[] dosSkewing = {0, 7, 14, 6, 13, 5, 12, 4, 11, 3, 10, 2, 9, 1, 8, 15}; + readonly byte[] dri_string = { 0x43, 0x4F, 0x50, 0x59, 0x52, 0x49, 0x47, 0x48, 0x54, 0x20, 0x28, 0x43, 0x29, 0x20, 0x31, 0x39, 0x37, 0x39, 0x2C, 0x20, 0x44, 0x49, 0x47, 0x49, 0x54, 0x41, 0x4C, 0x20, 0x52, 0x45, 0x53, 0x45, 0x41, 0x52, 0x43, 0x48 }; - readonly byte[] pascal_sign = {0x08, 0xA5, 0x0F, 0x29}; - readonly byte[] pascal_string = {0x53, 0x59, 0x53, 0x54, 0x45, 0x2E, 0x41, 0x50, 0x50, 0x4C, 0x45}; - readonly byte[] pascal2_sign = {0xFF, 0xA2, 0x00, 0x8E}; - readonly byte[] prodos_string = {0x50, 0x52, 0x4F, 0x44, 0x4F, 0x53}; - readonly ulong[] proDosSkewing = {0, 8, 1, 9, 2, 10, 3, 11, 4, 12, 5, 13, 6, 14, 7, 15}; - readonly byte[] sos_sign = {0xC9, 0x20, 0xF0, 0x3E}; + readonly byte[] pascal_sign = {0x08, 0xA5, 0x0F, 0x29}; + readonly byte[] pascal_string = {0x53, 0x59, 0x53, 0x54, 0x45, 0x2E, 0x41, 0x50, 0x50, 0x4C, 0x45}; + readonly byte[] pascal2_sign = {0xFF, 0xA2, 0x00, 0x8E}; + readonly byte[] prodos_string = {0x50, 0x52, 0x4F, 0x44, 0x4F, 0x53}; + readonly ulong[] proDosSkewing = {0, 8, 1, 9, 2, 10, 3, 11, 4, 12, 5, 13, 6, 14, 7, 15}; + readonly byte[] sos_sign = {0xC9, 0x20, 0xF0, 0x3E}; Dictionary addressFields; Dictionary cookedSectors; - ImageInfo imageInfo; + ImageInfo imageInfo; Dictionary longSectors; public AppleNib() { imageInfo = new ImageInfo { - ReadableSectorTags = new List(), - ReadableMediaTags = new List(), - HasPartitions = false, - HasSessions = false, - Version = null, - Application = null, - ApplicationVersion = null, - Creator = null, - Comments = null, - MediaManufacturer = null, - MediaModel = null, - MediaSerialNumber = null, - MediaBarcode = null, - MediaPartNumber = null, - MediaSequence = 0, - LastMediaSequence = 0, - DriveManufacturer = null, - DriveModel = null, - DriveSerialNumber = null, + ReadableSectorTags = new List(), + ReadableMediaTags = new List(), + HasPartitions = false, + HasSessions = false, + Version = null, + Application = null, + ApplicationVersion = null, + Creator = null, + Comments = null, + MediaManufacturer = null, + MediaModel = null, + MediaSerialNumber = null, + MediaBarcode = null, + MediaPartNumber = null, + MediaSequence = 0, + LastMediaSequence = 0, + DriveManufacturer = null, + DriveModel = null, + DriveSerialNumber = null, DriveFirmwareRevision = null }; } @@ -94,7 +95,7 @@ namespace DiscImageChef.DiscImages public ImageInfo Info => imageInfo; public string Name => "Apple NIB"; - public Guid Id => new Guid("AE171AE8-6747-49CC-B861-9D450B7CD42E"); + public Guid Id => new Guid("AE171AE8-6747-49CC-B861-9D450B7CD42E"); public string Format => "Apple nibbles"; @@ -136,19 +137,18 @@ namespace DiscImageChef.DiscImages Dictionary rawSectors = new Dictionary(); - int spt = 0; + int spt = 0; bool allTracksEqual = true; - for(int i = 1; i < tracks.Count; i++) + for(int i = 1; i < tracks.Count; i++) allTracksEqual &= tracks[i - 1].sectors.Length == tracks[i].sectors.Length; if(allTracksEqual) spt = tracks[0].sectors.Length; - bool skewed = spt == 16; + bool skewed = spt == 16; ulong[] skewing = proDosSkewing; // Detect ProDOS skewed disks if(skewed) - { foreach(Apple2.RawSector sector in tracks[17].sectors) { if(!sector.addressField.sector.SequenceEqual(new byte[] {170, 170})) continue; @@ -162,21 +162,21 @@ namespace DiscImageChef.DiscImages sector0[0x37] == 1; if(isDos) skewing = dosSkewing; - - DicConsole.DebugWriteLine("Apple NIB Plugin", "Using {0}DOS skewing", skewing.SequenceEqual(dosSkewing) ? "" : "Pro"); + + DicConsole.DebugWriteLine("Apple NIB Plugin", "Using {0}DOS skewing", + skewing.SequenceEqual(dosSkewing) ? "" : "Pro"); } - } for(int i = 0; i < tracks.Count; i++) foreach(Apple2.RawSector sector in tracks[i].sectors) if(skewed && spt != 0) { ulong sectorNo = (ulong)((((sector.addressField.sector[0] & 0x55) << 1) | - (sector.addressField.sector[1] & 0x55)) & 0xFF); + (sector.addressField.sector[1] & 0x55)) & 0xFF); DicConsole.DebugWriteLine("Apple NIB Plugin", "Hardware sector {0} of track {1} goes to logical sector {2}", sectorNo, i, skewing[sectorNo] + (ulong)(i * spt)); - rawSectors.Add(skewing[sectorNo] + (ulong)(i * spt), sector); + rawSectors.Add(skewing[sectorNo] + (ulong)(i * spt), sector); imageInfo.Sectors++; } else @@ -189,40 +189,43 @@ namespace DiscImageChef.DiscImages DicConsole.DebugWriteLine("Apple NIB Plugin", "Cooking sectors"); - longSectors = new Dictionary(); + longSectors = new Dictionary(); cookedSectors = new Dictionary(); addressFields = new Dictionary(); foreach(KeyValuePair kvp in rawSectors) { byte[] cooked = Apple2.DecodeSector(kvp.Value); - byte[] raw = Apple2.MarshalSector(kvp.Value); - byte[] addr = Apple2.MarshalAddressField(kvp.Value.addressField); + byte[] raw = Apple2.MarshalSector(kvp.Value); + byte[] addr = Apple2.MarshalAddressField(kvp.Value.addressField); longSectors.Add(kvp.Key, raw); cookedSectors.Add(kvp.Key, cooked); addressFields.Add(kvp.Key, addr); } - imageInfo.ImageSize = (ulong)imageFilter.GetDataForkLength(); - imageInfo.CreationTime = imageFilter.GetCreationTime(); + imageInfo.ImageSize = (ulong)imageFilter.GetDataForkLength(); + imageInfo.CreationTime = imageFilter.GetCreationTime(); imageInfo.LastModificationTime = imageFilter.GetLastWriteTime(); - imageInfo.MediaTitle = Path.GetFileNameWithoutExtension(imageFilter.GetFilename()); - if(imageInfo.Sectors == 455) imageInfo.MediaType = MediaType.Apple32SS; - else if(imageInfo.Sectors == 560) imageInfo.MediaType = MediaType.Apple33SS; - else imageInfo.MediaType = MediaType.Unknown; - imageInfo.SectorSize = 256; - imageInfo.XmlMediaType = XmlMediaType.BlockMedia; + imageInfo.MediaTitle = + Path.GetFileNameWithoutExtension(imageFilter.GetFilename()); + if(imageInfo.Sectors == 455) imageInfo.MediaType = MediaType.Apple32SS; + else if(imageInfo.Sectors == 560) + imageInfo.MediaType = MediaType.Apple33SS; + else + imageInfo.MediaType = MediaType.Unknown; + imageInfo.SectorSize = 256; + imageInfo.XmlMediaType = XmlMediaType.BlockMedia; imageInfo.ReadableSectorTags.Add(SectorTagType.FloppyAddressMark); switch(imageInfo.MediaType) { case MediaType.Apple32SS: - imageInfo.Cylinders = 35; - imageInfo.Heads = 1; + imageInfo.Cylinders = 35; + imageInfo.Heads = 1; imageInfo.SectorsPerTrack = 13; break; case MediaType.Apple33SS: - imageInfo.Cylinders = 35; - imageInfo.Heads = 1; + imageInfo.Cylinders = 35; + imageInfo.Heads = 1; imageInfo.SectorsPerTrack = 16; break; } @@ -230,16 +233,6 @@ namespace DiscImageChef.DiscImages return true; } - MediaType GetMediaType() - { - switch(imageInfo.Sectors) - { - case 455: return MediaType.Apple32SS; - case 560: return MediaType.Apple33SS; - default: return MediaType.Unknown; - } - } - public byte[] ReadSector(ulong sectorAddress) { if(sectorAddress > imageInfo.Sectors - 1) @@ -392,7 +385,7 @@ namespace DiscImageChef.DiscImages } public bool? VerifySectors(ulong sectorAddress, uint length, out List failingLbas, - out List unknownLbas) + out List unknownLbas) { failingLbas = new List(); unknownLbas = new List(); @@ -402,7 +395,7 @@ namespace DiscImageChef.DiscImages } public bool? VerifySectors(ulong sectorAddress, uint length, uint track, out List failingLbas, - out List unknownLbas) + out List unknownLbas) { throw new FeatureUnsupportedImageException("Feature not supported by image format"); } @@ -411,5 +404,18 @@ namespace DiscImageChef.DiscImages { return null; } + + public List DumpHardware => null; + public CICMMetadataType CicmMetadata => null; + + MediaType GetMediaType() + { + switch(imageInfo.Sectors) + { + case 455: return MediaType.Apple32SS; + case 560: return MediaType.Apple33SS; + default: return MediaType.Unknown; + } + } } } \ No newline at end of file diff --git a/DiscImageChef.DiscImages/Apridisk.cs b/DiscImageChef.DiscImages/Apridisk.cs index 74484198d..3013e581e 100644 --- a/DiscImageChef.DiscImages/Apridisk.cs +++ b/DiscImageChef.DiscImages/Apridisk.cs @@ -39,6 +39,7 @@ using System.Text; using DiscImageChef.CommonTypes; using DiscImageChef.Console; using DiscImageChef.Filters; +using Schemas; namespace DiscImageChef.DiscImages { @@ -424,6 +425,9 @@ namespace DiscImageChef.DiscImages return null; } + public List DumpHardware => null; + public CICMMetadataType CicmMetadata => null; + public IEnumerable SupportedMediaTags => new MediaTagType[] { }; public IEnumerable SupportedSectorTags => new SectorTagType[] { }; // TODO: Test with real hardware to see real supported media @@ -691,6 +695,18 @@ namespace DiscImageChef.DiscImages return false; } + public bool SetDumpHardware(List dumpHardware) + { + // Not supported + return false; + } + + public bool SetCicmMetadata(CICMMetadataType metadata) + { + // Not supported + return false; + } + static uint Decompress(byte[] compressed, out byte[] decompressed) { int readp = 0; diff --git a/DiscImageChef.DiscImages/BLU.cs b/DiscImageChef.DiscImages/BLU.cs index 76d38b2e1..6e362b6b7 100644 --- a/DiscImageChef.DiscImages/BLU.cs +++ b/DiscImageChef.DiscImages/BLU.cs @@ -39,6 +39,7 @@ using DiscImageChef.CommonTypes; using DiscImageChef.Console; using DiscImageChef.Decoders; using DiscImageChef.Filters; +using Schemas; using Version = DiscImageChef.Interop.Version; namespace DiscImageChef.DiscImages @@ -394,6 +395,9 @@ namespace DiscImageChef.DiscImages return null; } + public List DumpHardware => null; + public CICMMetadataType CicmMetadata => null; + public IEnumerable SupportedMediaTags => new MediaTagType[] { }; public IEnumerable SupportedSectorTags => new[] {SectorTagType.AppleSectorTag}; public IEnumerable SupportedMediaTypes => @@ -420,7 +424,7 @@ namespace DiscImageChef.DiscImages if(sectors > 0xFFFFFF) { - ErrorMessage = $"Too many sectors"; + ErrorMessage = "Too many sectors"; return false; } @@ -752,6 +756,18 @@ namespace DiscImageChef.DiscImages return false; } + public bool SetDumpHardware(List dumpHardware) + { + // Not supported + return false; + } + + public bool SetCicmMetadata(CICMMetadataType metadata) + { + // Not supported + return false; + } + struct BluHeader { public byte[] DeviceName; diff --git a/DiscImageChef.DiscImages/BlindWrite4.cs b/DiscImageChef.DiscImages/BlindWrite4.cs index 9122dddd5..a48478784 100644 --- a/DiscImageChef.DiscImages/BlindWrite4.cs +++ b/DiscImageChef.DiscImages/BlindWrite4.cs @@ -41,6 +41,7 @@ using DiscImageChef.Checksums; using DiscImageChef.CommonTypes; using DiscImageChef.Console; using DiscImageChef.Filters; +using Schemas; namespace DiscImageChef.DiscImages { @@ -565,9 +566,9 @@ namespace DiscImageChef.DiscImages if(bwTrack.pregap != 0) track.TrackFileOffset += (ulong)(bwTrack.startSector - bwTrack.pregap) * 2352; - track.TrackFileType = "BINARY"; - track.TrackPregap = (ulong)(bwTrack.startSector - bwTrack.pregap); - track.TrackRawBytesPerSector = 2352; + track.TrackFileType = "BINARY"; + track.TrackPregap = (ulong)(bwTrack.startSector - bwTrack.pregap); + track.TrackRawBytesPerSector = 2352; track.TrackSequence = bwTrack.point; track.TrackSession = bwTrack.session; if(track.TrackSession > maxSession) maxSession = track.TrackSession; @@ -1198,6 +1199,9 @@ namespace DiscImageChef.DiscImages return null; } + public List DumpHardware => null; + public CICMMetadataType CicmMetadata => null; + struct Bw4Header { public byte[] Signature; diff --git a/DiscImageChef.DiscImages/BlindWrite5.cs b/DiscImageChef.DiscImages/BlindWrite5.cs index dd85f0fce..3332ef4d2 100644 --- a/DiscImageChef.DiscImages/BlindWrite5.cs +++ b/DiscImageChef.DiscImages/BlindWrite5.cs @@ -45,6 +45,7 @@ using DiscImageChef.Decoders.DVD; using DiscImageChef.Decoders.SCSI; using DiscImageChef.Decoders.SCSI.MMC; using DiscImageChef.Filters; +using Schemas; using DMI = DiscImageChef.Decoders.Xbox.DMI; namespace DiscImageChef.DiscImages @@ -58,51 +59,48 @@ namespace DiscImageChef.DiscImages /// "BWT5 STREAM SIGN" readonly byte[] bw5Signature = {0x42, 0x57, 0x54, 0x35, 0x20, 0x53, 0x54, 0x52, 0x45, 0x41, 0x4D, 0x20, 0x53, 0x49, 0x47, 0x4E}; - byte[] atip; - byte[] bca; - List bwSessions; - byte[] cdtext; - List dataFiles; - string dataPath; - byte[] discInformation; - byte[] dmi; - byte[] dpm; + byte[] atip; + byte[] bca; + List bwSessions; + byte[] cdtext; + List dataFiles; + string dataPath; + byte[] discInformation; + byte[] dmi; + byte[] dpm; List filePaths; - byte[] fullToc; + byte[] fullToc; - Bw5Header header; - ImageInfo imageInfo; - Stream imageStream; - byte[] mode2A; + Bw5Header header; + ImageInfo imageInfo; + Stream imageStream; + byte[] mode2A; Dictionary offsetmap; - List partitions; - byte[] pfi; - byte[] pma; - List sessions; - Dictionary trackFlags; - List tracks; - byte[] unkBlock; + byte[] pfi; + byte[] pma; + Dictionary trackFlags; + byte[] unkBlock; public BlindWrite5() { imageInfo = new ImageInfo { - ReadableSectorTags = new List(), - ReadableMediaTags = new List(), - HasPartitions = true, - HasSessions = true, - Version = null, - ApplicationVersion = null, - MediaTitle = null, - Creator = null, - MediaManufacturer = null, - MediaModel = null, - MediaPartNumber = null, - MediaSequence = 0, - LastMediaSequence = 0, - DriveManufacturer = null, - DriveModel = null, - DriveSerialNumber = null, + ReadableSectorTags = new List(), + ReadableMediaTags = new List(), + HasPartitions = true, + HasSessions = true, + Version = null, + ApplicationVersion = null, + MediaTitle = null, + Creator = null, + MediaManufacturer = null, + MediaModel = null, + MediaPartNumber = null, + MediaSequence = 0, + LastMediaSequence = 0, + DriveManufacturer = null, + DriveModel = null, + DriveSerialNumber = null, DriveFirmwareRevision = null }; } @@ -110,15 +108,15 @@ namespace DiscImageChef.DiscImages public ImageInfo Info => imageInfo; public string Name => "BlindWrite 5"; - public Guid Id => new Guid("9CB7A381-0509-4F9F-B801-3F65434BC3EE"); + public Guid Id => new Guid("9CB7A381-0509-4F9F-B801-3F65434BC3EE"); public string Format => "BlindWrite 5 TOC file"; - public List Partitions => partitions; + public List Partitions { get; set; } - public List Tracks => tracks; + public List Tracks { get; set; } - public List Sessions => sessions; + public List Sessions { get; set; } public bool Identify(IFilter imageFilter) { @@ -144,7 +142,7 @@ namespace DiscImageChef.DiscImages byte[] hdr = new byte[260]; stream.Read(hdr, 0, 260); - header = new Bw5Header(); + header = new Bw5Header(); IntPtr hdrPtr = Marshal.AllocHGlobal(260); Marshal.Copy(hdr, 0, hdrPtr, 260); header = (Bw5Header)Marshal.PtrToStructure(hdrPtr, typeof(Bw5Header)); @@ -156,29 +154,30 @@ namespace DiscImageChef.DiscImages DicConsole.DebugWriteLine("BlindWrite5 plugin", "header.unknown1[{1}] = 0x{0:X8}", header.unknown1[i], i); - DicConsole.DebugWriteLine("BlindWrite5 plugin", "header.profile = {0}", header.profile); + DicConsole.DebugWriteLine("BlindWrite5 plugin", "header.profile = {0}", header.profile); DicConsole.DebugWriteLine("BlindWrite5 plugin", "header.sessions = {0}", header.sessions); for(int i = 0; i < header.unknown2.Length; i++) DicConsole.DebugWriteLine("BlindWrite5 plugin", "header.unknown2[{1}] = 0x{0:X8}", header.unknown2[i], i); DicConsole.DebugWriteLine("BlindWrite5 plugin", "header.mcnIsValid = {0}", header.mcnIsValid); - DicConsole.DebugWriteLine("BlindWrite5 plugin", "header.mcn = {0}", StringHandlers.CToString(header.mcn)); + DicConsole.DebugWriteLine("BlindWrite5 plugin", "header.mcn = {0}", + StringHandlers.CToString(header.mcn)); DicConsole.DebugWriteLine("BlindWrite5 plugin", "header.unknown3 = 0x{0:X4}", header.unknown3); for(int i = 0; i < header.unknown4.Length; i++) DicConsole.DebugWriteLine("BlindWrite5 plugin", "header.unknown4[{1}] = 0x{0:X8}", header.unknown4[i], i); - DicConsole.DebugWriteLine("BlindWrite5 plugin", "header.pmaLen = {0}", header.pmaLen); - DicConsole.DebugWriteLine("BlindWrite5 plugin", "header.atipLen = {0}", header.atipLen); - DicConsole.DebugWriteLine("BlindWrite5 plugin", "header.cdtLen = {0}", header.cdtLen); + DicConsole.DebugWriteLine("BlindWrite5 plugin", "header.pmaLen = {0}", header.pmaLen); + DicConsole.DebugWriteLine("BlindWrite5 plugin", "header.atipLen = {0}", header.atipLen); + DicConsole.DebugWriteLine("BlindWrite5 plugin", "header.cdtLen = {0}", header.cdtLen); DicConsole.DebugWriteLine("BlindWrite5 plugin", "header.cdInfoLen = {0}", header.cdInfoLen); - DicConsole.DebugWriteLine("BlindWrite5 plugin", "header.bcaLen = {0}", header.bcaLen); + DicConsole.DebugWriteLine("BlindWrite5 plugin", "header.bcaLen = {0}", header.bcaLen); for(int i = 0; i < header.unknown5.Length; i++) DicConsole.DebugWriteLine("BlindWrite5 plugin", "header.unknown5[{1}] = 0x{0:X8}", header.unknown5[i], i); - DicConsole.DebugWriteLine("BlindWrite5 plugin", "header.dvdStrLen = {0}", header.dvdStrLen); + DicConsole.DebugWriteLine("BlindWrite5 plugin", "header.dvdStrLen = {0}", header.dvdStrLen); DicConsole.DebugWriteLine("BlindWrite5 plugin", "header.dvdInfoLen = {0}", header.dvdInfoLen); for(int i = 0; i < header.unknown6.Length; i++) DicConsole.DebugWriteLine("BlindWrite5 plugin", "header.unknown6[{1}] = 0x{0:X2}", header.unknown6[i], @@ -194,17 +193,17 @@ namespace DiscImageChef.DiscImages StringHandlers.CToString(header.vendor)); DicConsole.DebugWriteLine("BlindWrite5 plugin", "header.volumeId = {0}", StringHandlers.CToString(header.volumeId)); - DicConsole.DebugWriteLine("BlindWrite5 plugin", "header.mode2ALen = {0}", header.mode2ALen); - DicConsole.DebugWriteLine("BlindWrite5 plugin", "header.unkBlkLen = {0}", header.unkBlkLen); - DicConsole.DebugWriteLine("BlindWrite5 plugin", "header.dataLen = {0}", header.dataLen); + DicConsole.DebugWriteLine("BlindWrite5 plugin", "header.mode2ALen = {0}", header.mode2ALen); + DicConsole.DebugWriteLine("BlindWrite5 plugin", "header.unkBlkLen = {0}", header.unkBlkLen); + DicConsole.DebugWriteLine("BlindWrite5 plugin", "header.dataLen = {0}", header.dataLen); DicConsole.DebugWriteLine("BlindWrite5 plugin", "header.sessionsLen = {0}", header.sessionsLen); - DicConsole.DebugWriteLine("BlindWrite5 plugin", "header.dpmLen = {0}", header.dpmLen); + DicConsole.DebugWriteLine("BlindWrite5 plugin", "header.dpmLen = {0}", header.dpmLen); mode2A = new byte[header.mode2ALen]; if(mode2A.Length > 0) { stream.Read(mode2A, 0, mode2A.Length); - mode2A[1] -= 2; + mode2A[1] -= 2; Modes.ModePage_2A? decoded2A = Modes.DecodeModePage_2A(mode2A); if(decoded2A.HasValue) DicConsole.DebugWriteLine("BlindWrite5 plugin", "mode page 2A: {0}", @@ -220,7 +219,7 @@ namespace DiscImageChef.DiscImages { byte[] tushort = BitConverter.GetBytes((ushort)(temp.Length + 2)); stream.Read(temp, 0, temp.Length); - pma = new byte[temp.Length + 4]; + pma = new byte[temp.Length + 4]; pma[0] = tushort[1]; pma[1] = tushort[0]; Array.Copy(temp, 0, pma, 4, temp.Length); @@ -236,7 +235,7 @@ namespace DiscImageChef.DiscImages { byte[] tushort = BitConverter.GetBytes((ushort)(temp.Length + 2)); stream.Read(temp, 0, temp.Length); - atip = new byte[temp.Length + 4]; + atip = new byte[temp.Length + 4]; atip[0] = tushort[1]; atip[1] = tushort[0]; Array.Copy(temp, 0, atip, 4, temp.Length); @@ -252,7 +251,7 @@ namespace DiscImageChef.DiscImages { byte[] tushort = BitConverter.GetBytes((ushort)(temp.Length + 2)); stream.Read(temp, 0, temp.Length); - cdtext = new byte[temp.Length + 4]; + cdtext = new byte[temp.Length + 4]; cdtext[0] = tushort[1]; cdtext[1] = tushort[0]; Array.Copy(temp, 0, cdtext, 4, temp.Length); @@ -275,7 +274,7 @@ namespace DiscImageChef.DiscImages dmi = new byte[2052]; pfi = new byte[2052]; - Array.Copy(temp, 0, dmi, 0, 2050); + Array.Copy(temp, 0, dmi, 0, 2050); Array.Copy(temp, 0x802, pfi, 4, 2048); pfi[0] = 0x08; @@ -325,7 +324,7 @@ namespace DiscImageChef.DiscImages uint dataBlockCount = BitConverter.ToUInt32(tmpArray, 0); stream.Read(tmpArray, 0, tmpArray.Length); - uint dataPathLen = BitConverter.ToUInt32(tmpArray, 0); + uint dataPathLen = BitConverter.ToUInt32(tmpArray, 0); byte[] dataPathBytes = new byte[dataPathLen]; stream.Read(dataPathBytes, 0, dataPathBytes.Length); dataPath = Encoding.Unicode.GetString(dataPathBytes); @@ -334,29 +333,29 @@ namespace DiscImageChef.DiscImages dataFiles = new List(); for(int cD = 0; cD < dataBlockCount; cD++) { - tmpArray = new byte[52]; + tmpArray = new byte[52]; Bw5DataFile dataFile = new Bw5DataFile {Unknown1 = new uint[4], Unknown2 = new uint[3]}; stream.Read(tmpArray, 0, tmpArray.Length); - dataFile.Type = BitConverter.ToUInt32(tmpArray, 0); - dataFile.Length = BitConverter.ToUInt32(tmpArray, 4); - dataFile.Unknown1[0] = BitConverter.ToUInt32(tmpArray, 8); - dataFile.Unknown1[1] = BitConverter.ToUInt32(tmpArray, 12); - dataFile.Unknown1[2] = BitConverter.ToUInt32(tmpArray, 16); - dataFile.Unknown1[3] = BitConverter.ToUInt32(tmpArray, 20); - dataFile.Offset = BitConverter.ToUInt32(tmpArray, 24); - dataFile.Unknown2[0] = BitConverter.ToUInt32(tmpArray, 28); - dataFile.Unknown2[1] = BitConverter.ToUInt32(tmpArray, 32); - dataFile.Unknown2[2] = BitConverter.ToUInt32(tmpArray, 36); - dataFile.StartLba = BitConverter.ToInt32(tmpArray, 40); - dataFile.Sectors = BitConverter.ToInt32(tmpArray, 44); - dataFile.FilenameLen = BitConverter.ToUInt32(tmpArray, 48); + dataFile.Type = BitConverter.ToUInt32(tmpArray, 0); + dataFile.Length = BitConverter.ToUInt32(tmpArray, 4); + dataFile.Unknown1[0] = BitConverter.ToUInt32(tmpArray, 8); + dataFile.Unknown1[1] = BitConverter.ToUInt32(tmpArray, 12); + dataFile.Unknown1[2] = BitConverter.ToUInt32(tmpArray, 16); + dataFile.Unknown1[3] = BitConverter.ToUInt32(tmpArray, 20); + dataFile.Offset = BitConverter.ToUInt32(tmpArray, 24); + dataFile.Unknown2[0] = BitConverter.ToUInt32(tmpArray, 28); + dataFile.Unknown2[1] = BitConverter.ToUInt32(tmpArray, 32); + dataFile.Unknown2[2] = BitConverter.ToUInt32(tmpArray, 36); + dataFile.StartLba = BitConverter.ToInt32(tmpArray, 40); + dataFile.Sectors = BitConverter.ToInt32(tmpArray, 44); + dataFile.FilenameLen = BitConverter.ToUInt32(tmpArray, 48); dataFile.FilenameBytes = new byte[dataFile.FilenameLen]; tmpArray = new byte[dataFile.FilenameLen]; stream.Read(tmpArray, 0, tmpArray.Length); dataFile.FilenameBytes = tmpArray; - tmpArray = new byte[4]; + tmpArray = new byte[4]; stream.Read(tmpArray, 0, tmpArray.Length); dataFile.Unknown3 = BitConverter.ToUInt32(tmpArray, 0); @@ -364,7 +363,7 @@ namespace DiscImageChef.DiscImages dataFiles.Add(dataFile); DicConsole.DebugWriteLine("BlindWrite5 plugin", "dataFile.type = 0x{0:X8}", dataFile.Type); - DicConsole.DebugWriteLine("BlindWrite5 plugin", "dataFile.length = {0}", dataFile.Length); + DicConsole.DebugWriteLine("BlindWrite5 plugin", "dataFile.length = {0}", dataFile.Length); for(int i = 0; i < dataFile.Unknown1.Length; i++) DicConsole.DebugWriteLine("BlindWrite5 plugin", "dataFile.unknown1[{1}] = {0}", dataFile.Unknown1[i], i); @@ -374,33 +373,33 @@ namespace DiscImageChef.DiscImages DicConsole.DebugWriteLine("BlindWrite5 plugin", "dataFile.unknown2[{1}] = {0}", dataFile.Unknown2[i], i); - DicConsole.DebugWriteLine("BlindWrite5 plugin", "dataFile.startLba = {0}", dataFile.StartLba); - DicConsole.DebugWriteLine("BlindWrite5 plugin", "dataFile.sectors = {0}", dataFile.Sectors); + DicConsole.DebugWriteLine("BlindWrite5 plugin", "dataFile.startLba = {0}", dataFile.StartLba); + DicConsole.DebugWriteLine("BlindWrite5 plugin", "dataFile.sectors = {0}", dataFile.Sectors); DicConsole.DebugWriteLine("BlindWrite5 plugin", "dataFile.filenameLen = {0}", dataFile.FilenameLen); - DicConsole.DebugWriteLine("BlindWrite5 plugin", "dataFile.filename = {0}", dataFile.Filename); - DicConsole.DebugWriteLine("BlindWrite5 plugin", "dataFile.unknown3 = {0}", dataFile.Unknown3); + DicConsole.DebugWriteLine("BlindWrite5 plugin", "dataFile.filename = {0}", dataFile.Filename); + DicConsole.DebugWriteLine("BlindWrite5 plugin", "dataFile.unknown3 = {0}", dataFile.Unknown3); } bwSessions = new List(); for(int ses = 0; ses < header.sessions; ses++) { Bw5SessionDescriptor session = new Bw5SessionDescriptor(); - tmpArray = new byte[16]; + tmpArray = new byte[16]; stream.Read(tmpArray, 0, tmpArray.Length); - session.Sequence = BitConverter.ToUInt16(tmpArray, 0); - session.Entries = tmpArray[2]; - session.Unknown = tmpArray[3]; - session.Start = BitConverter.ToInt32(tmpArray, 4); - session.End = BitConverter.ToInt32(tmpArray, 8); + session.Sequence = BitConverter.ToUInt16(tmpArray, 0); + session.Entries = tmpArray[2]; + session.Unknown = tmpArray[3]; + session.Start = BitConverter.ToInt32(tmpArray, 4); + session.End = BitConverter.ToInt32(tmpArray, 8); session.FirstTrack = BitConverter.ToUInt16(tmpArray, 12); - session.LastTrack = BitConverter.ToUInt16(tmpArray, 14); - session.Tracks = new Bw5TrackDescriptor[session.Entries]; + session.LastTrack = BitConverter.ToUInt16(tmpArray, 14); + session.Tracks = new Bw5TrackDescriptor[session.Entries]; DicConsole.DebugWriteLine("BlindWrite5 plugin", "session[{0}].filename = {1}", ses, session.Sequence); - DicConsole.DebugWriteLine("BlindWrite5 plugin", "session[{0}].entries = {1}", ses, session.Entries); - DicConsole.DebugWriteLine("BlindWrite5 plugin", "session[{0}].unknown = {1}", ses, session.Unknown); - DicConsole.DebugWriteLine("BlindWrite5 plugin", "session[{0}].start = {1}", ses, session.Start); - DicConsole.DebugWriteLine("BlindWrite5 plugin", "session[{0}].end = {1}", ses, session.End); + DicConsole.DebugWriteLine("BlindWrite5 plugin", "session[{0}].entries = {1}", ses, session.Entries); + DicConsole.DebugWriteLine("BlindWrite5 plugin", "session[{0}].unknown = {1}", ses, session.Unknown); + DicConsole.DebugWriteLine("BlindWrite5 plugin", "session[{0}].start = {1}", ses, session.Start); + DicConsole.DebugWriteLine("BlindWrite5 plugin", "session[{0}].end = {1}", ses, session.End); DicConsole.DebugWriteLine("BlindWrite5 plugin", "session[{0}].firstTrack = {1}", ses, session.FirstTrack); DicConsole.DebugWriteLine("BlindWrite5 plugin", "session[{0}].lastTrack = {1}", ses, session.LastTrack); @@ -410,7 +409,7 @@ namespace DiscImageChef.DiscImages byte[] trk = new byte[72]; stream.Read(trk, 0, 72); session.Tracks[tSeq] = new Bw5TrackDescriptor(); - IntPtr trkPtr = Marshal.AllocHGlobal(72); + IntPtr trkPtr = Marshal.AllocHGlobal(72); Marshal.Copy(trk, 0, trkPtr, 72); session.Tracks[tSeq] = (Bw5TrackDescriptor)Marshal.PtrToStructure(trkPtr, typeof(Bw5TrackDescriptor)); @@ -509,39 +508,41 @@ namespace DiscImageChef.DiscImages DicConsole.DebugWriteLine("BlindWrite5 plugin", "Correctly arrived end of image"); else DicConsole - .ErrorWriteLine("BlindWrite5 image ends after expected position. Probably new version with different data. Errors may occur."); + .ErrorWriteLine("BlindWrite5 image ends after expected position. Probably new version with different data. Errors may occur."); filePaths = new List(); foreach(Bw5DataFile dataFile in dataFiles) { - DataFileCharacteristics chars = new DataFileCharacteristics(); - string path = Path.Combine(dataPath, dataFile.Filename); - FiltersList filtersList = new FiltersList(); + DataFileCharacteristics chars = new DataFileCharacteristics(); + string path = Path.Combine(dataPath, dataFile.Filename); + FiltersList filtersList = new FiltersList(); if(filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), path)) != null) { chars.FileFilter = filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), path)); - chars.FilePath = path; + chars.FilePath = path; } else { - path = Path.Combine(dataPath, dataFile.Filename.ToLower(CultureInfo.CurrentCulture)); + path = Path.Combine(dataPath, + dataFile.Filename.ToLower(CultureInfo.CurrentCulture)); if(filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), path)) != null) { chars.FileFilter = filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), path)); - chars.FilePath = path; + chars.FilePath = path; } else { - path = Path.Combine(dataPath, dataFile.Filename.ToUpper(CultureInfo.CurrentCulture)); + path = Path.Combine(dataPath, + dataFile.Filename.ToUpper(CultureInfo.CurrentCulture)); if(filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), path)) != null) { chars.FileFilter = filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), path)); - chars.FilePath = path; + chars.FilePath = path; } else { - path = Path.Combine(dataPath.ToLower(CultureInfo.CurrentCulture), dataFile.Filename); + path = Path.Combine(dataPath.ToLower(CultureInfo.CurrentCulture), dataFile.Filename); if(filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), path)) != null) { chars.FileFilter = @@ -550,7 +551,7 @@ namespace DiscImageChef.DiscImages } else { - path = Path.Combine(dataPath.ToUpper(CultureInfo.CurrentCulture), dataFile.Filename); + path = Path.Combine(dataPath.ToUpper(CultureInfo.CurrentCulture), dataFile.Filename); if(filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), path)) != null) { chars.FileFilter = @@ -564,49 +565,49 @@ namespace DiscImageChef.DiscImages path.ToLower(CultureInfo.CurrentCulture))) != null) { - chars.FilePath = path.ToLower(CultureInfo.CurrentCulture); + chars.FilePath = path.ToLower(CultureInfo.CurrentCulture); chars.FileFilter = filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), path.ToLower(CultureInfo - .CurrentCulture))); + .CurrentCulture))); } else if(filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), path.ToUpper(CultureInfo - .CurrentCulture))) != + .CurrentCulture))) != null) { - chars.FilePath = path.ToUpper(CultureInfo.CurrentCulture); + chars.FilePath = path.ToUpper(CultureInfo.CurrentCulture); chars.FileFilter = filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), path.ToUpper(CultureInfo - .CurrentCulture))); + .CurrentCulture))); } else if(filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), dataFile.Filename.ToLower(CultureInfo - .CurrentCulture))) != + .CurrentCulture))) != null) { - chars.FilePath = dataFile.Filename.ToLower(CultureInfo.CurrentCulture); + chars.FilePath = dataFile.Filename.ToLower(CultureInfo.CurrentCulture); chars.FileFilter = filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), dataFile.Filename.ToLower(CultureInfo - .CurrentCulture))); + .CurrentCulture))); } else if(filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), dataFile.Filename.ToUpper(CultureInfo - .CurrentCulture))) != + .CurrentCulture))) != null) { - chars.FilePath = dataFile.Filename.ToUpper(CultureInfo.CurrentCulture); + chars.FilePath = dataFile.Filename.ToUpper(CultureInfo.CurrentCulture); chars.FileFilter = filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), dataFile.Filename.ToUpper(CultureInfo - .CurrentCulture))); + .CurrentCulture))); } else if(filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), dataFile.Filename)) != null) { - chars.FilePath = dataFile.Filename; + chars.FilePath = dataFile.Filename; chars.FileFilter = filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), dataFile.Filename)); @@ -640,23 +641,23 @@ namespace DiscImageChef.DiscImages else chars.Subchannel = TrackSubchannelType.None; chars.SectorSize = sectorSize; - chars.StartLba = dataFile.StartLba; - chars.Sectors = dataFile.Sectors; + chars.StartLba = dataFile.StartLba; + chars.Sectors = dataFile.Sectors; filePaths.Add(chars); } - sessions = new List(); - tracks = new List(); - partitions = new List(); + Sessions = new List(); + Tracks = new List(); + Partitions = new List(); MemoryStream fullTocStream = new MemoryStream(); fullTocStream.Write(new byte[] {0, 0, 0, 0}, 0, 4); ulong offsetBytes = 0; - offsetmap = new Dictionary(); - bool isDvd = false; + offsetmap = new Dictionary(); + bool isDvd = false; byte firstSession = byte.MaxValue; - byte lastSession = 0; - trackFlags = new Dictionary(); + byte lastSession = 0; + trackFlags = new Dictionary(); imageInfo.Sectors = 0; DicConsole.DebugWriteLine("BlindWrite5 plugin", "Building maps"); @@ -673,7 +674,7 @@ namespace DiscImageChef.DiscImages */ if(ses.Sequence < firstSession) firstSession = (byte)ses.Sequence; - if(ses.Sequence > lastSession) lastSession = (byte)ses.Sequence; + if(ses.Sequence > lastSession) lastSession = (byte)ses.Sequence; foreach(Bw5TrackDescriptor trk in ses.Tracks) { @@ -692,7 +693,7 @@ namespace DiscImageChef.DiscImages if(trk.point >= 0xA0) continue; - Track track = new Track(); + Track track = new Track(); Partition partition = new Partition(); trackFlags.Add(trk.point, trk.ctl); @@ -700,8 +701,8 @@ namespace DiscImageChef.DiscImages switch(trk.type) { case Bw5TrackType.Audio: - track.TrackBytesPerSector = 2352; - track.TrackRawBytesPerSector = 2352; + track.TrackBytesPerSector = 2352; + track.TrackRawBytesPerSector = 2352; if(imageInfo.SectorSize < 2352) imageInfo.SectorSize = 2352; break; case Bw5TrackType.Mode1: @@ -720,8 +721,8 @@ namespace DiscImageChef.DiscImages imageInfo.ReadableSectorTags.Add(SectorTagType.CdSectorEccQ); if(!imageInfo.ReadableSectorTags.Contains(SectorTagType.CdSectorEdc)) imageInfo.ReadableSectorTags.Add(SectorTagType.CdSectorEdc); - track.TrackBytesPerSector = 2048; - track.TrackRawBytesPerSector = 2352; + track.TrackBytesPerSector = 2048; + track.TrackRawBytesPerSector = 2352; if(imageInfo.SectorSize < 2048) imageInfo.SectorSize = 2048; break; case Bw5TrackType.Mode2: @@ -729,8 +730,8 @@ namespace DiscImageChef.DiscImages imageInfo.ReadableSectorTags.Add(SectorTagType.CdSectorSync); if(!imageInfo.ReadableSectorTags.Contains(SectorTagType.CdSectorHeader)) imageInfo.ReadableSectorTags.Add(SectorTagType.CdSectorHeader); - track.TrackBytesPerSector = 2336; - track.TrackRawBytesPerSector = 2352; + track.TrackBytesPerSector = 2336; + track.TrackRawBytesPerSector = 2352; if(imageInfo.SectorSize < 2336) imageInfo.SectorSize = 2336; break; case Bw5TrackType.Mode2F2: @@ -742,37 +743,39 @@ namespace DiscImageChef.DiscImages imageInfo.ReadableSectorTags.Add(SectorTagType.CdSectorSubHeader); if(!imageInfo.ReadableSectorTags.Contains(SectorTagType.CdSectorEdc)) imageInfo.ReadableSectorTags.Add(SectorTagType.CdSectorEdc); - track.TrackBytesPerSector = 2336; - track.TrackRawBytesPerSector = 2352; + track.TrackBytesPerSector = 2336; + track.TrackRawBytesPerSector = 2352; if(imageInfo.SectorSize < 2324) imageInfo.SectorSize = 2324; break; case Bw5TrackType.Dvd: - track.TrackBytesPerSector = 2048; - track.TrackRawBytesPerSector = 2048; + track.TrackBytesPerSector = 2048; + track.TrackRawBytesPerSector = 2048; if(imageInfo.SectorSize < 2048) imageInfo.SectorSize = 2048; - isDvd = true; + isDvd = true; break; } track.TrackDescription = $"Track {trk.point}"; track.TrackStartSector = (ulong)(trk.startLba + trk.pregap); - track.TrackEndSector = (ulong)(trk.sectors + trk.startLba); + track.TrackEndSector = (ulong)(trk.sectors + trk.startLba); - foreach(DataFileCharacteristics chars in filePaths.Where(chars => trk.startLba >= chars.StartLba && - trk.startLba + trk.sectors <= - chars.StartLba + chars.Sectors)) + foreach(DataFileCharacteristics chars in filePaths.Where(chars => + trk.startLba >= + chars.StartLba && + trk.startLba + trk.sectors <= + chars.StartLba + chars.Sectors)) { track.TrackFilter = chars.FileFilter; - track.TrackFile = chars.FileFilter.GetFilename(); + track.TrackFile = chars.FileFilter.GetFilename(); if(trk.startLba >= 0) - track.TrackFileOffset = (ulong)((trk.startLba - chars.StartLba) * chars.SectorSize); - else track.TrackFileOffset = (ulong)(trk.startLba * -1 * chars.SectorSize); - track.TrackFileType = "BINARY"; + track.TrackFileOffset = (ulong)((trk.startLba - chars.StartLba) * chars.SectorSize); + else track.TrackFileOffset = (ulong)(trk.startLba * -1 * chars.SectorSize); + track.TrackFileType = "BINARY"; if(chars.Subchannel != TrackSubchannelType.None) { track.TrackSubchannelFilter = track.TrackFilter; - track.TrackSubchannelFile = track.TrackFile; - track.TrackSubchannelType = chars.Subchannel; + track.TrackSubchannelFile = track.TrackFile; + track.TrackSubchannelType = chars.Subchannel; track.TrackSubchannelOffset = track.TrackFileOffset; if(chars.Subchannel == TrackSubchannelType.PackedInterleaved) @@ -783,51 +786,52 @@ namespace DiscImageChef.DiscImages break; } - track.TrackPregap = trk.pregap; + track.TrackPregap = trk.pregap; track.TrackSequence = trk.point; - track.TrackType = BlindWriteTrackTypeToTrackType(trk.type); - track.Indexes = new Dictionary {{1, track.TrackStartSector}}; + track.TrackType = BlindWriteTrackTypeToTrackType(trk.type); + track.Indexes = new Dictionary {{1, track.TrackStartSector}}; partition.Description = track.TrackDescription; - partition.Size = (track.TrackEndSector - track.TrackStartSector) * - (ulong)track.TrackRawBytesPerSector; - partition.Length = track.TrackEndSector - track.TrackStartSector; + partition.Size = (track.TrackEndSector - track.TrackStartSector) * + (ulong)track.TrackRawBytesPerSector; + partition.Length = track.TrackEndSector - track.TrackStartSector; partition.Sequence = track.TrackSequence; - partition.Offset = offsetBytes; - partition.Start = track.TrackStartSector; - partition.Type = track.TrackType.ToString(); + partition.Offset = offsetBytes; + partition.Start = track.TrackStartSector; + partition.Type = track.TrackType.ToString(); offsetBytes += partition.Size; - tracks.Add(track); - partitions.Add(partition); + Tracks.Add(track); + Partitions.Add(partition); offsetmap.Add(track.TrackSequence, track.TrackStartSector); imageInfo.Sectors += partition.Length; } } DicConsole.DebugWriteLine("BlindWrite5 plugin", "printing track map"); - foreach(Track track in tracks) + foreach(Track track in Tracks) { - DicConsole.DebugWriteLine("BlindWrite5 plugin", "Partition sequence: {0}", track.TrackSequence); + DicConsole.DebugWriteLine("BlindWrite5 plugin", "Partition sequence: {0}", track.TrackSequence); DicConsole.DebugWriteLine("BlindWrite5 plugin", "\tPartition description: {0}", track.TrackDescription); - DicConsole.DebugWriteLine("BlindWrite5 plugin", "\tPartition type: {0}", track.TrackType); + DicConsole.DebugWriteLine("BlindWrite5 plugin", "\tPartition type: {0}", track.TrackType); DicConsole.DebugWriteLine("BlindWrite5 plugin", "\tPartition starting sector: {0}", track.TrackStartSector); DicConsole.DebugWriteLine("BlindWrite5 plugin", "\tPartition ending sector: {0}", track.TrackEndSector); } DicConsole.DebugWriteLine("BlindWrite5 plugin", "printing partition map"); - foreach(Partition partition in partitions) + foreach(Partition partition in Partitions) { DicConsole.DebugWriteLine("BlindWrite5 plugin", "Partition sequence: {0}", partition.Sequence); - DicConsole.DebugWriteLine("BlindWrite5 plugin", "\tPartition name: {0}", partition.Name); - DicConsole.DebugWriteLine("BlindWrite5 plugin", "\tPartition description: {0}", partition.Description); - DicConsole.DebugWriteLine("BlindWrite5 plugin", "\tPartition type: {0}", partition.Type); + DicConsole.DebugWriteLine("BlindWrite5 plugin", "\tPartition name: {0}", partition.Name); + DicConsole.DebugWriteLine("BlindWrite5 plugin", "\tPartition description: {0}", + partition.Description); + DicConsole.DebugWriteLine("BlindWrite5 plugin", "\tPartition type: {0}", partition.Type); DicConsole.DebugWriteLine("BlindWrite5 plugin", "\tPartition starting sector: {0}", partition.Start); - DicConsole.DebugWriteLine("BlindWrite5 plugin", "\tPartition sectors: {0}", partition.Length); + DicConsole.DebugWriteLine("BlindWrite5 plugin", "\tPartition sectors: {0}", partition.Length); DicConsole.DebugWriteLine("BlindWrite5 plugin", "\tPartition starting offset: {0}", partition.Offset); - DicConsole.DebugWriteLine("BlindWrite5 plugin", "\tPartition size in bytes: {0}", partition.Size); + DicConsole.DebugWriteLine("BlindWrite5 plugin", "\tPartition size in bytes: {0}", partition.Size); } if(!isDvd) @@ -838,10 +842,10 @@ namespace DiscImageChef.DiscImages DicConsole.DebugWriteLine("BlindWrite5 plugin", "TOC len {0}", fullToc.Length); byte[] fullTocSize = BitConverter.GetBytes((short)(fullToc.Length - 2)); - fullToc[0] = fullTocSize[1]; - fullToc[1] = fullTocSize[0]; - fullToc[2] = firstSession; - fullToc[3] = lastSession; + fullToc[0] = fullTocSize[1]; + fullToc[1] = fullTocSize[0]; + fullToc[2] = firstSession; + fullToc[3] = lastSession; FullTOC.CDFullTOC? decodedFullToc = FullTOC.Decode(fullToc); @@ -912,18 +916,19 @@ namespace DiscImageChef.DiscImages } if(DMI.IsXbox(dmi)) imageInfo.MediaType = MediaType.XGD; - else if(DMI.IsXbox360(dmi)) imageInfo.MediaType = MediaType.XGD2; + else if(DMI.IsXbox360(dmi)) + imageInfo.MediaType = MediaType.XGD2; } } else if(imageInfo.MediaType == MediaType.CD || imageInfo.MediaType == MediaType.CDROM) { - bool data = false; - bool mode2 = false; + bool data = false; + bool mode2 = false; bool firstaudio = false; - bool firstdata = false; - bool audio = false; + bool firstdata = false; + bool audio = false; - foreach(Track bwTrack in tracks) + foreach(Track bwTrack in Tracks) { // First track is audio firstaudio |= bwTrack.TrackSequence == 1 && bwTrack.TrackType == TrackType.Audio; @@ -947,27 +952,32 @@ namespace DiscImageChef.DiscImages } } - if(!data && !firstdata) imageInfo.MediaType = MediaType.CDDA; - else if(firstaudio && data && sessions.Count > 1 && mode2) imageInfo.MediaType = MediaType.CDPLUS; - else if(firstdata && audio || mode2) imageInfo.MediaType = MediaType.CDROMXA; - else if(!audio) imageInfo.MediaType = MediaType.CDROM; - else imageInfo.MediaType = MediaType.CD; + if(!data && !firstdata) imageInfo.MediaType = MediaType.CDDA; + else if(firstaudio && data && Sessions.Count > 1 && mode2) + imageInfo.MediaType = MediaType.CDPLUS; + else if(firstdata && audio || mode2) + imageInfo.MediaType = MediaType.CDROMXA; + else if(!audio) + imageInfo.MediaType = MediaType.CDROM; + else + imageInfo.MediaType = MediaType.CD; } - imageInfo.DriveManufacturer = StringHandlers.CToString(header.manufacturer); - imageInfo.DriveModel = StringHandlers.CToString(header.product); + imageInfo.DriveManufacturer = StringHandlers.CToString(header.manufacturer); + imageInfo.DriveModel = StringHandlers.CToString(header.product); imageInfo.DriveFirmwareRevision = StringHandlers.CToString(header.revision); - imageInfo.Application = "BlindWrite"; + imageInfo.Application = "BlindWrite"; if(string.Compare(Path.GetExtension(imageFilter.GetFilename()), "B5T", StringComparison.OrdinalIgnoreCase) == 0) imageInfo.ApplicationVersion = "5"; else if(string.Compare(Path.GetExtension(imageFilter.GetFilename()), "B6T", - StringComparison.OrdinalIgnoreCase) == 0) imageInfo.ApplicationVersion = "6"; - imageInfo.Version = "5"; + StringComparison.OrdinalIgnoreCase) == 0) + imageInfo.ApplicationVersion = "6"; + imageInfo.Version = "5"; - imageInfo.ImageSize = (ulong)imageFilter.GetDataForkLength(); - imageInfo.CreationTime = imageFilter.GetCreationTime(); + imageInfo.ImageSize = (ulong)imageFilter.GetDataForkLength(); + imageInfo.CreationTime = imageFilter.GetCreationTime(); imageInfo.LastModificationTime = imageFilter.GetLastWriteTime(); - imageInfo.XmlMediaType = XmlMediaType.OpticalDisc; + imageInfo.XmlMediaType = XmlMediaType.OpticalDisc; if(pma != null) { @@ -987,8 +997,8 @@ namespace DiscImageChef.DiscImages if(atip0.LeadInStartMin == 97) { - int type = atip0.LeadInStartFrame % 10; - int frm = atip0.LeadInStartFrame - type; + int type = atip0.LeadInStartFrame % 10; + int frm = atip0.LeadInStartFrame - type; imageInfo.MediaManufacturer = ATIP.ManufacturerFromATIP(atip0.LeadInStartSec, frm); } } @@ -998,7 +1008,7 @@ namespace DiscImageChef.DiscImages imageInfo.MediaType == MediaType.BDROM) { isDvd = false; - isBd = true; + isBd = true; } if(isBd && imageInfo.Sectors > 24438784) @@ -1015,20 +1025,22 @@ namespace DiscImageChef.DiscImages DicConsole.DebugWriteLine("BlindWrite5 plugin", "ImageInfo.mediaType = {0}", imageInfo.MediaType); if(mode2A != null) imageInfo.ReadableMediaTags.Add(MediaTagType.SCSI_MODEPAGE_2A); - if(pma != null) imageInfo.ReadableMediaTags.Add(MediaTagType.CD_PMA); - if(atip != null) imageInfo.ReadableMediaTags.Add(MediaTagType.CD_ATIP); + if(pma != null) imageInfo.ReadableMediaTags.Add(MediaTagType.CD_PMA); + if(atip != null) imageInfo.ReadableMediaTags.Add(MediaTagType.CD_ATIP); if(cdtext != null) imageInfo.ReadableMediaTags.Add(MediaTagType.CD_TEXT); - if(bca != null) - if(isDvd) imageInfo.ReadableMediaTags.Add(MediaTagType.DVD_BCA); - else if(isBd) imageInfo.ReadableMediaTags.Add(MediaTagType.BD_BCA); - if(dmi != null) imageInfo.ReadableMediaTags.Add(MediaTagType.DVD_DMI); - if(pfi != null) imageInfo.ReadableMediaTags.Add(MediaTagType.DVD_PFI); + if(bca != null) + if(isDvd) + imageInfo.ReadableMediaTags.Add(MediaTagType.DVD_BCA); + else if(isBd) + imageInfo.ReadableMediaTags.Add(MediaTagType.BD_BCA); + if(dmi != null) imageInfo.ReadableMediaTags.Add(MediaTagType.DVD_DMI); + if(pfi != null) imageInfo.ReadableMediaTags.Add(MediaTagType.DVD_PFI); if(fullToc != null) imageInfo.ReadableMediaTags.Add(MediaTagType.CD_FullTOC); - if(imageInfo.MediaType == MediaType.XGD2) - if(imageInfo.Sectors == 25063 || // Locked (or non compatible drive) + if(imageInfo.MediaType == MediaType.XGD2) + if(imageInfo.Sectors == 25063 || // Locked (or non compatible drive) imageInfo.Sectors == 4229664 || // Xtreme unlock - imageInfo.Sectors == 4246304) // Wxripper unlock + imageInfo.Sectors == 4246304) // Wxripper unlock imageInfo.MediaType = MediaType.XGD3; DicConsole.VerboseWriteLine("BlindWrite image describes a disc of type {0}", imageInfo.MediaType); @@ -1118,9 +1130,9 @@ namespace DiscImageChef.DiscImages { foreach(KeyValuePair kvp in from kvp in offsetmap where sectorAddress >= kvp.Value - from track in tracks - where track.TrackSequence == kvp.Key - where sectorAddress - kvp.Value < + from track in Tracks + where track.TrackSequence == kvp.Key + where sectorAddress - kvp.Value < track.TrackEndSector - track.TrackStartSector select kvp) return ReadSectors(sectorAddress - kvp.Value, length, kvp.Key); @@ -1132,9 +1144,9 @@ namespace DiscImageChef.DiscImages { foreach(KeyValuePair kvp in from kvp in offsetmap where sectorAddress >= kvp.Value - from track in tracks - where track.TrackSequence == kvp.Key - where sectorAddress - kvp.Value < + from track in Tracks + where track.TrackSequence == kvp.Key + where sectorAddress - kvp.Value < track.TrackEndSector - track.TrackStartSector select kvp) return ReadSectorsTag(sectorAddress - kvp.Value, length, kvp.Key, tag); @@ -1145,12 +1157,12 @@ namespace DiscImageChef.DiscImages public byte[] ReadSectors(ulong sectorAddress, uint length, uint track) { // TODO: Cross data files - Track dicTrack = new Track(); - DataFileCharacteristics chars = new DataFileCharacteristics(); + Track dicTrack = new Track(); + DataFileCharacteristics chars = new DataFileCharacteristics(); dicTrack.TrackSequence = 0; - foreach(Track bwTrack in tracks.Where(bwTrack => bwTrack.TrackSequence == track)) + foreach(Track bwTrack in Tracks.Where(bwTrack => bwTrack.TrackSequence == track)) { dicTrack = bwTrack; break; @@ -1165,7 +1177,7 @@ namespace DiscImageChef.DiscImages foreach(DataFileCharacteristics _chars in filePaths.Where(_chars => (long)sectorAddress >= _chars.StartLba && - length < (ulong)_chars.Sectors - + length < (ulong)_chars.Sectors - sectorAddress)) { chars = _chars; @@ -1184,43 +1196,43 @@ namespace DiscImageChef.DiscImages case TrackType.CdMode1: { sectorOffset = 16; - sectorSize = 2048; - sectorSkip = 288; + sectorSize = 2048; + sectorSkip = 288; break; } case TrackType.CdMode2Formless: { sectorOffset = 16; - sectorSize = 2336; - sectorSkip = 0; + sectorSize = 2336; + sectorSkip = 0; break; } case TrackType.CdMode2Form1: { sectorOffset = 24; - sectorSize = 2048; - sectorSkip = 280; + sectorSize = 2048; + sectorSkip = 280; break; } case TrackType.CdMode2Form2: { sectorOffset = 24; - sectorSize = 2324; - sectorSkip = 4; + sectorSize = 2324; + sectorSkip = 4; break; } case TrackType.Audio: { sectorOffset = 0; - sectorSize = 2352; - sectorSkip = 0; + sectorSize = 2352; + sectorSkip = 0; break; } case TrackType.Data: { sectorOffset = 0; - sectorSize = 2048; - sectorSkip = 0; + sectorSize = 2048; + sectorSkip = 0; break; } default: throw new FeatureSupportedButNotImplementedImageException("Unsupported track type"); @@ -1242,7 +1254,7 @@ namespace DiscImageChef.DiscImages byte[] buffer = new byte[sectorSize * length]; - imageStream = chars.FileFilter.GetDataForkStream(); + imageStream = chars.FileFilter.GetDataForkStream(); BinaryReader br = new BinaryReader(imageStream); br.BaseStream .Seek((long)dicTrack.TrackFileOffset + (long)(sectorAddress * (sectorOffset + sectorSize + sectorSkip)), @@ -1264,12 +1276,12 @@ namespace DiscImageChef.DiscImages public byte[] ReadSectorsTag(ulong sectorAddress, uint length, uint track, SectorTagType tag) { // TODO: Cross data files - Track dicTrack = new Track(); - DataFileCharacteristics chars = new DataFileCharacteristics(); + Track dicTrack = new Track(); + DataFileCharacteristics chars = new DataFileCharacteristics(); dicTrack.TrackSequence = 0; - foreach(Track bwTrack in tracks.Where(bwTrack => bwTrack.TrackSequence == track)) + foreach(Track bwTrack in Tracks.Where(bwTrack => bwTrack.TrackSequence == track)) { dicTrack = bwTrack; break; @@ -1284,7 +1296,7 @@ namespace DiscImageChef.DiscImages foreach(DataFileCharacteristics _chars in filePaths.Where(_chars => (long)sectorAddress >= _chars.StartLba && - length < (ulong)_chars.Sectors - + length < (ulong)_chars.Sectors - sectorAddress)) { chars = _chars; @@ -1310,7 +1322,7 @@ namespace DiscImageChef.DiscImages case SectorTagType.CdTrackFlags: if(trackFlags.TryGetValue(track, out byte flag)) return new[] {flag}; - throw new ArgumentException("Unsupported tag requested", nameof(tag)); + throw new ArgumentException("Unsupported tag requested", nameof(tag)); default: throw new ArgumentException("Unsupported tag requested", nameof(tag)); } @@ -1326,15 +1338,15 @@ namespace DiscImageChef.DiscImages case SectorTagType.CdSectorSync: { sectorOffset = 0; - sectorSize = 12; - sectorSkip = 2340; + sectorSize = 12; + sectorSkip = 2340; break; } case SectorTagType.CdSectorHeader: { sectorOffset = 12; - sectorSize = 4; - sectorSkip = 2336; + sectorSize = 4; + sectorSkip = 2336; break; } case SectorTagType.CdSectorSubHeader: @@ -1342,29 +1354,29 @@ namespace DiscImageChef.DiscImages case SectorTagType.CdSectorEcc: { sectorOffset = 2076; - sectorSize = 276; - sectorSkip = 0; + sectorSize = 276; + sectorSkip = 0; break; } case SectorTagType.CdSectorEccP: { sectorOffset = 2076; - sectorSize = 172; - sectorSkip = 104; + sectorSize = 172; + sectorSkip = 104; break; } case SectorTagType.CdSectorEccQ: { sectorOffset = 2248; - sectorSize = 104; - sectorSkip = 0; + sectorSize = 104; + sectorSkip = 0; break; } case SectorTagType.CdSectorEdc: { sectorOffset = 2064; - sectorSize = 4; - sectorSkip = 284; + sectorSize = 4; + sectorSkip = 284; break; } case SectorTagType.CdSectorSubchannel: @@ -1386,15 +1398,15 @@ namespace DiscImageChef.DiscImages case SectorTagType.CdSectorSubHeader: { sectorOffset = 0; - sectorSize = 8; - sectorSkip = 2328; + sectorSize = 8; + sectorSkip = 2328; break; } case SectorTagType.CdSectorEdc: { sectorOffset = 2332; - sectorSize = 4; - sectorSkip = 0; + sectorSize = 4; + sectorSkip = 0; break; } case SectorTagType.CdSectorSubchannel: @@ -1410,50 +1422,50 @@ namespace DiscImageChef.DiscImages case SectorTagType.CdSectorSync: { sectorOffset = 0; - sectorSize = 12; - sectorSkip = 2340; + sectorSize = 12; + sectorSkip = 2340; break; } case SectorTagType.CdSectorHeader: { sectorOffset = 12; - sectorSize = 4; - sectorSkip = 2336; + sectorSize = 4; + sectorSkip = 2336; break; } case SectorTagType.CdSectorSubHeader: { sectorOffset = 16; - sectorSize = 8; - sectorSkip = 2328; + sectorSize = 8; + sectorSkip = 2328; break; } case SectorTagType.CdSectorEcc: { sectorOffset = 2076; - sectorSize = 276; - sectorSkip = 0; + sectorSize = 276; + sectorSkip = 0; break; } case SectorTagType.CdSectorEccP: { sectorOffset = 2076; - sectorSize = 172; - sectorSkip = 104; + sectorSize = 172; + sectorSkip = 104; break; } case SectorTagType.CdSectorEccQ: { sectorOffset = 2248; - sectorSize = 104; - sectorSkip = 0; + sectorSize = 104; + sectorSkip = 0; break; } case SectorTagType.CdSectorEdc: { sectorOffset = 2072; - sectorSize = 4; - sectorSkip = 276; + sectorSize = 4; + sectorSkip = 276; break; } case SectorTagType.CdSectorSubchannel: @@ -1468,29 +1480,29 @@ namespace DiscImageChef.DiscImages case SectorTagType.CdSectorSync: { sectorOffset = 0; - sectorSize = 12; - sectorSkip = 2340; + sectorSize = 12; + sectorSkip = 2340; break; } case SectorTagType.CdSectorHeader: { sectorOffset = 12; - sectorSize = 4; - sectorSkip = 2336; + sectorSize = 4; + sectorSkip = 2336; break; } case SectorTagType.CdSectorSubHeader: { sectorOffset = 16; - sectorSize = 8; - sectorSkip = 2328; + sectorSize = 8; + sectorSkip = 2328; break; } case SectorTagType.CdSectorEdc: { sectorOffset = 2348; - sectorSize = 4; - sectorSkip = 0; + sectorSize = 4; + sectorSkip = 0; break; } case SectorTagType.CdSectorSubchannel: @@ -1527,7 +1539,7 @@ namespace DiscImageChef.DiscImages byte[] buffer = new byte[sectorSize * length]; - imageStream = dicTrack.TrackFilter.GetDataForkStream(); + imageStream = dicTrack.TrackFilter.GetDataForkStream(); BinaryReader br = new BinaryReader(imageStream); br.BaseStream .Seek((long)dicTrack.TrackFileOffset + (long)(sectorAddress * (sectorOffset + sectorSize + sectorSkip)), @@ -1559,9 +1571,9 @@ namespace DiscImageChef.DiscImages { foreach(KeyValuePair kvp in from kvp in offsetmap where sectorAddress >= kvp.Value - from track in tracks - where track.TrackSequence == kvp.Key - where sectorAddress - kvp.Value < + from track in Tracks + where track.TrackSequence == kvp.Key + where sectorAddress - kvp.Value < track.TrackEndSector - track.TrackStartSector select kvp) return ReadSectorsLong(sectorAddress - kvp.Value, length, kvp.Key); @@ -1572,12 +1584,12 @@ namespace DiscImageChef.DiscImages public byte[] ReadSectorsLong(ulong sectorAddress, uint length, uint track) { // TODO: Cross data files - Track dicTrack = new Track(); - DataFileCharacteristics chars = new DataFileCharacteristics(); + Track dicTrack = new Track(); + DataFileCharacteristics chars = new DataFileCharacteristics(); dicTrack.TrackSequence = 0; - foreach(Track bwTrack in tracks.Where(bwTrack => bwTrack.TrackSequence == track)) + foreach(Track bwTrack in Tracks.Where(bwTrack => bwTrack.TrackSequence == track)) { dicTrack = bwTrack; break; @@ -1592,7 +1604,7 @@ namespace DiscImageChef.DiscImages foreach(DataFileCharacteristics _chars in filePaths.Where(_chars => (long)sectorAddress >= _chars.StartLba && - length < (ulong)_chars.Sectors - + length < (ulong)_chars.Sectors - sectorAddress)) { chars = _chars; @@ -1615,15 +1627,15 @@ namespace DiscImageChef.DiscImages case TrackType.Audio: { sectorOffset = 0; - sectorSize = 2352; - sectorSkip = 0; + sectorSize = 2352; + sectorSkip = 0; break; } case TrackType.Data: { sectorOffset = 0; - sectorSize = 2048; - sectorSkip = 0; + sectorSize = 2048; + sectorSkip = 0; break; } default: throw new FeatureSupportedButNotImplementedImageException("Unsupported track type"); @@ -1645,7 +1657,7 @@ namespace DiscImageChef.DiscImages byte[] buffer = new byte[sectorSize * length]; - imageStream = dicTrack.TrackFilter.GetDataForkStream(); + imageStream = dicTrack.TrackFilter.GetDataForkStream(); BinaryReader br = new BinaryReader(imageStream); br.BaseStream .Seek((long)dicTrack.TrackFileOffset + (long)(sectorAddress * (sectorOffset + sectorSize + sectorSkip)), @@ -1665,14 +1677,14 @@ namespace DiscImageChef.DiscImages public List GetSessionTracks(Session session) { - if(sessions.Contains(session)) return GetSessionTracks(session.SessionSequence); + if(Sessions.Contains(session)) return GetSessionTracks(session.SessionSequence); throw new ImageNotSupportedException("Session does not exist in disc image"); } public List GetSessionTracks(ushort session) { - return tracks.Where(dicTrack => dicTrack.TrackSession == session).ToList(); + return Tracks.Where(dicTrack => dicTrack.TrackSession == session).ToList(); } public bool? VerifySector(ulong sectorAddress) @@ -1688,13 +1700,13 @@ namespace DiscImageChef.DiscImages } public bool? VerifySectors(ulong sectorAddress, uint length, out List failingLbas, - out List unknownLbas) + out List unknownLbas) { byte[] buffer = ReadSectorsLong(sectorAddress, length); - int bps = (int)(buffer.Length / length); + int bps = (int)(buffer.Length / length); byte[] sector = new byte[bps]; - failingLbas = new List(); - unknownLbas = new List(); + failingLbas = new List(); + unknownLbas = new List(); for(int i = 0; i < length; i++) { @@ -1718,13 +1730,13 @@ namespace DiscImageChef.DiscImages } public bool? VerifySectors(ulong sectorAddress, uint length, uint track, out List failingLbas, - out List unknownLbas) + out List unknownLbas) { byte[] buffer = ReadSectorsLong(sectorAddress, length, track); - int bps = (int)(buffer.Length / length); + int bps = (int)(buffer.Length / length); byte[] sector = new byte[bps]; - failingLbas = new List(); - unknownLbas = new List(); + failingLbas = new List(); + unknownLbas = new List(); for(int i = 0; i < length; i++) { @@ -1752,16 +1764,19 @@ namespace DiscImageChef.DiscImages return null; } + public List DumpHardware => null; + public CICMMetadataType CicmMetadata => null; + static TrackType BlindWriteTrackTypeToTrackType(Bw5TrackType trackType) { switch(trackType) { - case Bw5TrackType.Mode1: return TrackType.CdMode1; + case Bw5TrackType.Mode1: return TrackType.CdMode1; case Bw5TrackType.Mode2F1: return TrackType.CdMode2Form1; case Bw5TrackType.Mode2F2: return TrackType.CdMode2Form2; - case Bw5TrackType.Mode2: return TrackType.CdMode2Formless; - case Bw5TrackType.Audio: return TrackType.Audio; - default: return TrackType.Data; + case Bw5TrackType.Mode2: return TrackType.CdMode2Formless; + case Bw5TrackType.Audio: return TrackType.Audio; + default: return TrackType.Data; } } @@ -1769,7 +1784,7 @@ namespace DiscImageChef.DiscImages { switch(profile) { - case ProfileNumber.BDRE: return MediaType.BDRE; + case ProfileNumber.BDRE: return MediaType.BDRE; case ProfileNumber.BDROM: return MediaType.BDROM; case ProfileNumber.BDRRdm: case ProfileNumber.BDRSeq: return MediaType.BDR; @@ -1778,99 +1793,114 @@ namespace DiscImageChef.DiscImages case ProfileNumber.CDROM: case ProfileNumber.HDBURNROM: return MediaType.CDROM; case ProfileNumber.CDRW: - case ProfileNumber.HDBURNRW: return MediaType.CDRW; - case ProfileNumber.DDCDR: return MediaType.DDCDR; - case ProfileNumber.DDCDROM: return MediaType.DDCD; - case ProfileNumber.DDCDRW: return MediaType.DDCDRW; + case ProfileNumber.HDBURNRW: return MediaType.CDRW; + case ProfileNumber.DDCDR: return MediaType.DDCDR; + case ProfileNumber.DDCDROM: return MediaType.DDCD; + case ProfileNumber.DDCDRW: return MediaType.DDCDRW; case ProfileNumber.DVDDownload: return MediaType.DVDDownload; - case ProfileNumber.DVDRAM: return MediaType.DVDRAM; + case ProfileNumber.DVDRAM: return MediaType.DVDRAM; case ProfileNumber.DVDRDLJump: - case ProfileNumber.DVDRDLSeq: return MediaType.DVDRDL; - case ProfileNumber.DVDRDLPlus: return MediaType.DVDPRDL; - case ProfileNumber.DVDROM: return MediaType.DVDROM; - case ProfileNumber.DVDRPlus: return MediaType.DVDPR; - case ProfileNumber.DVDRSeq: return MediaType.DVDR; - case ProfileNumber.DVDRWDL: return MediaType.DVDRWDL; + case ProfileNumber.DVDRDLSeq: return MediaType.DVDRDL; + case ProfileNumber.DVDRDLPlus: return MediaType.DVDPRDL; + case ProfileNumber.DVDROM: return MediaType.DVDROM; + case ProfileNumber.DVDRPlus: return MediaType.DVDPR; + case ProfileNumber.DVDRSeq: return MediaType.DVDR; + case ProfileNumber.DVDRWDL: return MediaType.DVDRWDL; case ProfileNumber.DVDRWDLPlus: return MediaType.DVDPRWDL; - case ProfileNumber.DVDRWPlus: return MediaType.DVDPRW; + case ProfileNumber.DVDRWPlus: return MediaType.DVDPRW; case ProfileNumber.DVDRWRes: - case ProfileNumber.DVDRWSeq: return MediaType.DVDRW; - case ProfileNumber.HDDVDR: return MediaType.HDDVDR; - case ProfileNumber.HDDVDRAM: return MediaType.HDDVDRAM; - case ProfileNumber.HDDVDRDL: return MediaType.HDDVDRDL; - case ProfileNumber.HDDVDROM: return MediaType.HDDVDROM; - case ProfileNumber.HDDVDRW: return MediaType.HDDVDRW; + case ProfileNumber.DVDRWSeq: return MediaType.DVDRW; + case ProfileNumber.HDDVDR: return MediaType.HDDVDR; + case ProfileNumber.HDDVDRAM: return MediaType.HDDVDRAM; + case ProfileNumber.HDDVDRDL: return MediaType.HDDVDRDL; + case ProfileNumber.HDDVDROM: return MediaType.HDDVDROM; + case ProfileNumber.HDDVDRW: return MediaType.HDDVDRW; case ProfileNumber.HDDVDRWDL: return MediaType.HDDVDRWDL; case ProfileNumber.ASMO: - case ProfileNumber.MOErasable: return MediaType.UnknownMO; + case ProfileNumber.MOErasable: return MediaType.UnknownMO; case ProfileNumber.NonRemovable: return MediaType.GENERIC_HDD; - default: return MediaType.CD; + default: return MediaType.CD; } } enum Bw5TrackType : byte { NotData = 0, - Audio = 1, - Mode1 = 2, - Mode2 = 3, + Audio = 1, + Mode1 = 2, + Mode2 = 3, Mode2F1 = 4, Mode2F2 = 5, - Dvd = 6 + Dvd = 6 } enum Bw5TrackSubchannel : byte { - None = 0, - Q16 = 2, + None = 0, + Q16 = 2, Linear = 4 } [StructLayout(LayoutKind.Sequential, Pack = 1)] struct Bw5Header { - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] signature; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public uint[] unknown1; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] + public byte[] signature; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] + public uint[] unknown1; public ProfileNumber profile; - public ushort sessions; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public uint[] unknown2; - [MarshalAs(UnmanagedType.U1, SizeConst = 3)] public bool mcnIsValid; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 13)] public byte[] mcn; + public ushort sessions; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] + public uint[] unknown2; + [MarshalAs(UnmanagedType.U1, SizeConst = 3)] + public bool mcnIsValid; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 13)] + public byte[] mcn; public ushort unknown3; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public uint[] unknown4; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] + public uint[] unknown4; public ushort pmaLen; public ushort atipLen; public ushort cdtLen; public ushort cdInfoLen; - public uint bcaLen; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public uint[] unknown5; - public uint dvdStrLen; - public uint dvdInfoLen; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public byte[] unknown6; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public byte[] manufacturer; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] product; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public byte[] revision; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)] public byte[] vendor; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public byte[] volumeId; - public uint mode2ALen; - public uint unkBlkLen; - public uint dataLen; - public uint sessionsLen; - public uint dpmLen; + public uint bcaLen; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] + public uint[] unknown5; + public uint dvdStrLen; + public uint dvdInfoLen; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] + public byte[] unknown6; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] + public byte[] manufacturer; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] + public byte[] product; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] + public byte[] revision; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)] + public byte[] vendor; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] + public byte[] volumeId; + public uint mode2ALen; + public uint unkBlkLen; + public uint dataLen; + public uint sessionsLen; + public uint dpmLen; } struct Bw5DataFile { public uint Type; public uint Length; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public uint[] Unknown1; - public uint Offset; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public uint[] Unknown2; - public int StartLba; - public int Sectors; - public uint FilenameLen; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] + public uint[] Unknown1; + public uint Offset; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] + public uint[] Unknown2; + public int StartLba; + public int Sectors; + public uint FilenameLen; public byte[] FilenameBytes; - public uint Unknown3; + public uint Unknown3; public string Filename; } @@ -1879,53 +1909,57 @@ namespace DiscImageChef.DiscImages struct Bw5TrackDescriptor { public Bw5TrackType type; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public byte[] unknown1; - public uint unknown2; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] + public byte[] unknown1; + public uint unknown2; public Bw5TrackSubchannel subchannel; - public byte unknown3; - public byte ctl; - public byte adr; - public byte point; - public byte tno; - public byte min; - public byte sec; - public byte frame; - public byte zero; - public byte pmin; - public byte psec; - public byte pframe; - public byte unknown5; - public uint pregap; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public uint[] unknown6; - public int startLba; - public int sectors; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public uint[] unknown7; - public uint session; + public byte unknown3; + public byte ctl; + public byte adr; + public byte point; + public byte tno; + public byte min; + public byte sec; + public byte frame; + public byte zero; + public byte pmin; + public byte psec; + public byte pframe; + public byte unknown5; + public uint pregap; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] + public uint[] unknown6; + public int startLba; + public int sectors; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] + public uint[] unknown7; + public uint session; public ushort unknown8; // Seems to be only on non DVD track descriptors - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public uint[] unknown9; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] + public uint[] unknown9; } struct Bw5SessionDescriptor { - public ushort Sequence; - public byte Entries; - public byte Unknown; - public int Start; - public int End; - public ushort FirstTrack; - public ushort LastTrack; + public ushort Sequence; + public byte Entries; + public byte Unknown; + public int Start; + public int End; + public ushort FirstTrack; + public ushort LastTrack; public Bw5TrackDescriptor[] Tracks; } struct DataFileCharacteristics { - public IFilter FileFilter; - public string FilePath; + public IFilter FileFilter; + public string FilePath; public TrackSubchannelType Subchannel; - public long SectorSize; - public int StartLba; - public int Sectors; + public long SectorSize; + public int StartLba; + public int Sectors; } } } \ No newline at end of file diff --git a/DiscImageChef.DiscImages/CDRDAO.cs b/DiscImageChef.DiscImages/CDRDAO.cs index 4bed743c9..6e42fe471 100644 --- a/DiscImageChef.DiscImages/CDRDAO.cs +++ b/DiscImageChef.DiscImages/CDRDAO.cs @@ -41,6 +41,7 @@ using DiscImageChef.Checksums; using DiscImageChef.CommonTypes; using DiscImageChef.Console; using DiscImageChef.Filters; +using Schemas; namespace DiscImageChef.DiscImages { @@ -1476,6 +1477,9 @@ namespace DiscImageChef.DiscImages return null; } + public List DumpHardware => null; + public CICMMetadataType CicmMetadata => null; + // TODO: Decode CD-Text to text public IEnumerable SupportedMediaTags => new[] {MediaTagType.CD_MCN}; public IEnumerable SupportedSectorTags => @@ -2089,6 +2093,18 @@ namespace DiscImageChef.DiscImages } } + public bool SetDumpHardware(List dumpHardware) + { + // Not supported + return false; + } + + public bool SetCicmMetadata(CICMMetadataType metadata) + { + // Not supported + return false; + } + static ushort CdrdaoTrackTypeToBytesPerSector(string trackType) { switch(trackType) diff --git a/DiscImageChef.DiscImages/CDRWin.cs b/DiscImageChef.DiscImages/CDRWin.cs index ffbc6d1e5..b8d763e32 100644 --- a/DiscImageChef.DiscImages/CDRWin.cs +++ b/DiscImageChef.DiscImages/CDRWin.cs @@ -40,6 +40,7 @@ using DiscImageChef.Checksums; using DiscImageChef.CommonTypes; using DiscImageChef.Console; using DiscImageChef.Filters; +using Schemas; namespace DiscImageChef.DiscImages { @@ -1826,6 +1827,9 @@ namespace DiscImageChef.DiscImages return null; } + public List DumpHardware => null; + public CICMMetadataType CicmMetadata => null; + public IEnumerable SupportedMediaTags => new[] {MediaTagType.CD_MCN, MediaTagType.CD_TEXT}; public IEnumerable SupportedSectorTags => new[] @@ -2297,6 +2301,18 @@ namespace DiscImageChef.DiscImages return WriteSectorTag(data, sectorAddress, tag); } + public bool SetDumpHardware(List dumpHardware) + { + // Not supported + return false; + } + + public bool SetCicmMetadata(CICMMetadataType metadata) + { + // Not supported + return false; + } + public bool SetMetadata(ImageInfo metadata) { discimage.Barcode = metadata.MediaBarcode; diff --git a/DiscImageChef.DiscImages/CHD.cs b/DiscImageChef.DiscImages/CHD.cs index 8d0c96275..28b745161 100644 --- a/DiscImageChef.DiscImages/CHD.cs +++ b/DiscImageChef.DiscImages/CHD.cs @@ -42,6 +42,7 @@ using DiscImageChef.CommonTypes; using DiscImageChef.Console; using DiscImageChef.Decoders.ATA; using DiscImageChef.Filters; +using Schemas; using SharpCompress.Compressors; using SharpCompress.Compressors.Deflate; @@ -78,84 +79,82 @@ namespace DiscImageChef.DiscImages const string REGEX_METADATA_CDROM = @"TRACK:(?\d+) TYPE:(?\S+) SUBTYPE:(?\S+) FRAMES:(?\d+)"; const string REGEX_METADATA_CDROM2 = - @"TRACK:(?\d+) TYPE:(?\S+) SUBTYPE:(?\S+) FRAMES:(?\d+) PREGAP:(?\d+) PGTYPE:(?\S+) PGSUB:(?\S+) POSTGAP:(?\d+)" - ; + @"TRACK:(?\d+) TYPE:(?\S+) SUBTYPE:(?\S+) FRAMES:(?\d+) PREGAP:(?\d+) PGTYPE:(?\S+) PGSUB:(?\S+) POSTGAP:(?\d+)"; const string REGEX_METADATA_GDROM = - @"TRACK:(?\d+) TYPE:(?\S+) SUBTYPE:(?\S+) FRAMES:(?\d+) PAD:(?\d+) PREGAP:(?\d+) PGTYPE:(?\S+) PGSUB:(?\S+) POSTGAP:(?\d+)" - ; + @"TRACK:(?\d+) TYPE:(?\S+) SUBTYPE:(?\S+) FRAMES:(?\d+) PAD:(?\d+) PREGAP:(?\d+) PGTYPE:(?\S+) PGSUB:(?\S+) POSTGAP:(?\d+)"; - const string TRACK_TYPE_MODE1 = "MODE1"; - const string TRACK_TYPE_MODE1_2K = "MODE1/2048"; - const string TRACK_TYPE_MODE1_RAW = "MODE1_RAW"; + const string TRACK_TYPE_MODE1 = "MODE1"; + const string TRACK_TYPE_MODE1_2K = "MODE1/2048"; + const string TRACK_TYPE_MODE1_RAW = "MODE1_RAW"; const string TRACK_TYPE_MODE1_RAW_2K = "MODE1/2352"; - const string TRACK_TYPE_MODE2 = "MODE2"; - const string TRACK_TYPE_MODE2_2K = "MODE2/2336"; - const string TRACK_TYPE_MODE2_F1 = "MODE2_FORM1"; - const string TRACK_TYPE_MODE2_F1_2K = "MODE2/2048"; - const string TRACK_TYPE_MODE2_F2 = "MODE2_FORM2"; - const string TRACK_TYPE_MODE2_F2_2K = "MODE2/2324"; - const string TRACK_TYPE_MODE2_FM = "MODE2_FORM_MIX"; - const string TRACK_TYPE_MODE2_RAW = "MODE2_RAW"; + const string TRACK_TYPE_MODE2 = "MODE2"; + const string TRACK_TYPE_MODE2_2K = "MODE2/2336"; + const string TRACK_TYPE_MODE2_F1 = "MODE2_FORM1"; + const string TRACK_TYPE_MODE2_F1_2K = "MODE2/2048"; + const string TRACK_TYPE_MODE2_F2 = "MODE2_FORM2"; + const string TRACK_TYPE_MODE2_F2_2K = "MODE2/2324"; + const string TRACK_TYPE_MODE2_FM = "MODE2_FORM_MIX"; + const string TRACK_TYPE_MODE2_RAW = "MODE2_RAW"; const string TRACK_TYPE_MODE2_RAW_2K = "MODE2/2352"; - const string TRACK_TYPE_AUDIO = "AUDIO"; + const string TRACK_TYPE_AUDIO = "AUDIO"; const string SUB_TYPE_COOKED = "RW"; - const string SUB_TYPE_RAW = "RW_RAW"; - const string SUB_TYPE_NONE = "NONE"; + const string SUB_TYPE_RAW = "RW_RAW"; + const string SUB_TYPE_NONE = "NONE"; const int MAX_CACHE_SIZE = 16777216; /// "MComprHD" - readonly byte[] chdTag = {0x4D, 0x43, 0x6F, 0x6D, 0x70, 0x72, 0x48, 0x44}; - uint bytesPerHunk; - byte[] cis; - byte[] expectedChecksum; - uint hdrCompression; - uint hdrCompression1; - uint hdrCompression2; - uint hdrCompression3; + readonly byte[] chdTag = {0x4D, 0x43, 0x6F, 0x6D, 0x70, 0x72, 0x48, 0x44}; + uint bytesPerHunk; + byte[] cis; + byte[] expectedChecksum; + uint hdrCompression; + uint hdrCompression1; + uint hdrCompression2; + uint hdrCompression3; Dictionary hunkCache; - byte[] hunkMap; - ulong[] hunkTable; - uint[] hunkTableSmall; - byte[] identify; - ImageInfo imageInfo; - Stream imageStream; - bool isCdrom; - bool isGdrom; - bool isHdd; - uint mapVersion; - int maxBlockCache; - int maxSectorCache; - Dictionary offsetmap; - List partitions; + byte[] hunkMap; + ulong[] hunkTable; + uint[] hunkTableSmall; + byte[] identify; + ImageInfo imageInfo; + Stream imageStream; + bool isCdrom; + bool isGdrom; + bool isHdd; + uint mapVersion; + int maxBlockCache; + int maxSectorCache; + Dictionary offsetmap; + List partitions; Dictionary sectorCache; - uint sectorsPerHunk; - bool swapAudio; - uint totalHunks; - Dictionary tracks; + uint sectorsPerHunk; + bool swapAudio; + uint totalHunks; + Dictionary tracks; public Chd() { imageInfo = new ImageInfo { - ReadableSectorTags = new List(), - ReadableMediaTags = new List(), - HasPartitions = false, - HasSessions = false, - Application = "MAME", - Creator = null, - Comments = null, - MediaManufacturer = null, - MediaModel = null, - MediaSerialNumber = null, - MediaBarcode = null, - MediaPartNumber = null, - MediaSequence = 0, - LastMediaSequence = 0, - DriveManufacturer = null, - DriveModel = null, - DriveSerialNumber = null, + ReadableSectorTags = new List(), + ReadableMediaTags = new List(), + HasPartitions = false, + HasSessions = false, + Application = "MAME", + Creator = null, + Comments = null, + MediaManufacturer = null, + MediaModel = null, + MediaSerialNumber = null, + MediaBarcode = null, + MediaPartNumber = null, + MediaSequence = 0, + LastMediaSequence = 0, + DriveManufacturer = null, + DriveModel = null, + DriveSerialNumber = null, DriveFirmwareRevision = null }; } @@ -163,7 +162,7 @@ namespace DiscImageChef.DiscImages public ImageInfo Info => imageInfo; public string Name => "MAME Compressed Hunks of Data"; - public Guid Id => new Guid("0D50233A-08BD-47D4-988B-27EAA0358597"); + public Guid Id => new Guid("0D50233A-08BD-47D4-988B-27EAA0358597"); public string Format => "Compressed Hunks of Data"; @@ -220,11 +219,12 @@ namespace DiscImageChef.DiscImages byte[] magic = new byte[8]; stream.Read(magic, 0, 8); if(!chdTag.SequenceEqual(magic)) return false; + // Read length byte[] buffer = new byte[4]; stream.Read(buffer, 0, 4); uint length = BitConverter.ToUInt32(buffer.Reverse().ToArray(), 0); - buffer = new byte[4]; + buffer = new byte[4]; stream.Read(buffer, 0, 4); uint version = BitConverter.ToUInt32(buffer.Reverse().ToArray(), 0); @@ -240,18 +240,20 @@ namespace DiscImageChef.DiscImages { ChdHeaderV1 hdrV1 = BigEndianMarshal.ByteArrayToStructureBigEndian(buffer); - DicConsole.DebugWriteLine("CHD plugin", "hdrV1.tag = \"{0}\"", Encoding.ASCII.GetString(hdrV1.tag)); + DicConsole.DebugWriteLine("CHD plugin", "hdrV1.tag = \"{0}\"", + Encoding.ASCII.GetString(hdrV1.tag)); DicConsole.DebugWriteLine("CHD plugin", "hdrV1.length = {0} bytes", hdrV1.length); - DicConsole.DebugWriteLine("CHD plugin", "hdrV1.version = {0}", hdrV1.version); - DicConsole.DebugWriteLine("CHD plugin", "hdrV1.flags = {0}", (ChdFlags)hdrV1.flags); + DicConsole.DebugWriteLine("CHD plugin", "hdrV1.version = {0}", hdrV1.version); + DicConsole.DebugWriteLine("CHD plugin", "hdrV1.flags = {0}", (ChdFlags)hdrV1.flags); DicConsole.DebugWriteLine("CHD plugin", "hdrV1.compression = {0}", (ChdCompression)hdrV1.compression); - DicConsole.DebugWriteLine("CHD plugin", "hdrV1.hunksize = {0}", hdrV1.hunksize); + DicConsole.DebugWriteLine("CHD plugin", "hdrV1.hunksize = {0}", hdrV1.hunksize); DicConsole.DebugWriteLine("CHD plugin", "hdrV1.totalhunks = {0}", hdrV1.totalhunks); - DicConsole.DebugWriteLine("CHD plugin", "hdrV1.cylinders = {0}", hdrV1.cylinders); - DicConsole.DebugWriteLine("CHD plugin", "hdrV1.heads = {0}", hdrV1.heads); - DicConsole.DebugWriteLine("CHD plugin", "hdrV1.sectors = {0}", hdrV1.sectors); - DicConsole.DebugWriteLine("CHD plugin", "hdrV1.md5 = {0}", ArrayHelpers.ByteArrayToHex(hdrV1.md5)); + DicConsole.DebugWriteLine("CHD plugin", "hdrV1.cylinders = {0}", hdrV1.cylinders); + DicConsole.DebugWriteLine("CHD plugin", "hdrV1.heads = {0}", hdrV1.heads); + DicConsole.DebugWriteLine("CHD plugin", "hdrV1.sectors = {0}", hdrV1.sectors); + DicConsole.DebugWriteLine("CHD plugin", "hdrV1.md5 = {0}", + ArrayHelpers.ByteArrayToHex(hdrV1.md5)); DicConsole.DebugWriteLine("CHD plugin", "hdrV1.parentmd5 = {0}", ArrayHelpers.ArrayIsNullOrEmpty(hdrV1.parentmd5) ? "null" @@ -271,14 +273,14 @@ namespace DiscImageChef.DiscImages stream.Read(hunkSectorBytes, 0, 512); // This does the big-endian trick but reverses the order of elements also Array.Reverse(hunkSectorBytes); - GCHandle handle = GCHandle.Alloc(hunkSectorBytes, GCHandleType.Pinned); + GCHandle handle = GCHandle.Alloc(hunkSectorBytes, GCHandleType.Pinned); HunkSector hunkSector = (HunkSector)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(HunkSector)); handle.Free(); // This restores the order of elements Array.Reverse(hunkSector.hunkEntry); - if(hunkTable.Length >= i * 512 / 8 + 512 / 8) - Array.Copy(hunkSector.hunkEntry, 0, hunkTable, i * 512 / 8, 512 / 8); + if(hunkTable.Length >= i * 512 / 8 + 512 / 8) + Array.Copy(hunkSector.hunkEntry, 0, hunkTable, i * 512 / 8, 512 / 8); else Array.Copy(hunkSector.hunkEntry, 0, hunkTable, i * 512 / 8, hunkTable.Length - i * 512 / 8); } @@ -286,21 +288,21 @@ namespace DiscImageChef.DiscImages DateTime end = DateTime.UtcNow; System.Console.WriteLine("Took {0} seconds", (end - start).TotalSeconds); - imageInfo.MediaType = MediaType.GENERIC_HDD; - imageInfo.Sectors = hdrV1.hunksize * hdrV1.totalhunks; + imageInfo.MediaType = MediaType.GENERIC_HDD; + imageInfo.Sectors = hdrV1.hunksize * hdrV1.totalhunks; imageInfo.XmlMediaType = XmlMediaType.BlockMedia; - imageInfo.SectorSize = 512; - imageInfo.Version = "1"; - imageInfo.ImageSize = imageInfo.SectorSize * hdrV1.hunksize * hdrV1.totalhunks; + imageInfo.SectorSize = 512; + imageInfo.Version = "1"; + imageInfo.ImageSize = imageInfo.SectorSize * hdrV1.hunksize * hdrV1.totalhunks; - totalHunks = hdrV1.totalhunks; + totalHunks = hdrV1.totalhunks; sectorsPerHunk = hdrV1.hunksize; hdrCompression = hdrV1.compression; - mapVersion = 1; - isHdd = true; + mapVersion = 1; + isHdd = true; - imageInfo.Cylinders = hdrV1.cylinders; - imageInfo.Heads = hdrV1.heads; + imageInfo.Cylinders = hdrV1.cylinders; + imageInfo.Heads = hdrV1.heads; imageInfo.SectorsPerTrack = hdrV1.sectors; break; @@ -309,18 +311,20 @@ namespace DiscImageChef.DiscImages { ChdHeaderV2 hdrV2 = BigEndianMarshal.ByteArrayToStructureBigEndian(buffer); - DicConsole.DebugWriteLine("CHD plugin", "hdrV2.tag = \"{0}\"", Encoding.ASCII.GetString(hdrV2.tag)); + DicConsole.DebugWriteLine("CHD plugin", "hdrV2.tag = \"{0}\"", + Encoding.ASCII.GetString(hdrV2.tag)); DicConsole.DebugWriteLine("CHD plugin", "hdrV2.length = {0} bytes", hdrV2.length); - DicConsole.DebugWriteLine("CHD plugin", "hdrV2.version = {0}", hdrV2.version); - DicConsole.DebugWriteLine("CHD plugin", "hdrV2.flags = {0}", (ChdFlags)hdrV2.flags); + DicConsole.DebugWriteLine("CHD plugin", "hdrV2.version = {0}", hdrV2.version); + DicConsole.DebugWriteLine("CHD plugin", "hdrV2.flags = {0}", (ChdFlags)hdrV2.flags); DicConsole.DebugWriteLine("CHD plugin", "hdrV2.compression = {0}", (ChdCompression)hdrV2.compression); - DicConsole.DebugWriteLine("CHD plugin", "hdrV2.hunksize = {0}", hdrV2.hunksize); + DicConsole.DebugWriteLine("CHD plugin", "hdrV2.hunksize = {0}", hdrV2.hunksize); DicConsole.DebugWriteLine("CHD plugin", "hdrV2.totalhunks = {0}", hdrV2.totalhunks); - DicConsole.DebugWriteLine("CHD plugin", "hdrV2.cylinders = {0}", hdrV2.cylinders); - DicConsole.DebugWriteLine("CHD plugin", "hdrV2.heads = {0}", hdrV2.heads); - DicConsole.DebugWriteLine("CHD plugin", "hdrV2.sectors = {0}", hdrV2.sectors); - DicConsole.DebugWriteLine("CHD plugin", "hdrV2.md5 = {0}", ArrayHelpers.ByteArrayToHex(hdrV2.md5)); + DicConsole.DebugWriteLine("CHD plugin", "hdrV2.cylinders = {0}", hdrV2.cylinders); + DicConsole.DebugWriteLine("CHD plugin", "hdrV2.heads = {0}", hdrV2.heads); + DicConsole.DebugWriteLine("CHD plugin", "hdrV2.sectors = {0}", hdrV2.sectors); + DicConsole.DebugWriteLine("CHD plugin", "hdrV2.md5 = {0}", + ArrayHelpers.ByteArrayToHex(hdrV2.md5)); DicConsole.DebugWriteLine("CHD plugin", "hdrV2.parentmd5 = {0}", ArrayHelpers.ArrayIsNullOrEmpty(hdrV2.parentmd5) ? "null" @@ -342,14 +346,14 @@ namespace DiscImageChef.DiscImages stream.Read(hunkSectorBytes, 0, 512); // This does the big-endian trick but reverses the order of elements also Array.Reverse(hunkSectorBytes); - GCHandle handle = GCHandle.Alloc(hunkSectorBytes, GCHandleType.Pinned); + GCHandle handle = GCHandle.Alloc(hunkSectorBytes, GCHandleType.Pinned); HunkSector hunkSector = (HunkSector)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(HunkSector)); handle.Free(); // This restores the order of elements Array.Reverse(hunkSector.hunkEntry); - if(hunkTable.Length >= i * 512 / 8 + 512 / 8) - Array.Copy(hunkSector.hunkEntry, 0, hunkTable, i * 512 / 8, 512 / 8); + if(hunkTable.Length >= i * 512 / 8 + 512 / 8) + Array.Copy(hunkSector.hunkEntry, 0, hunkTable, i * 512 / 8, 512 / 8); else Array.Copy(hunkSector.hunkEntry, 0, hunkTable, i * 512 / 8, hunkTable.Length - i * 512 / 8); } @@ -357,21 +361,21 @@ namespace DiscImageChef.DiscImages DateTime end = DateTime.UtcNow; System.Console.WriteLine("Took {0} seconds", (end - start).TotalSeconds); - imageInfo.MediaType = MediaType.GENERIC_HDD; - imageInfo.Sectors = hdrV2.hunksize * hdrV2.totalhunks; + imageInfo.MediaType = MediaType.GENERIC_HDD; + imageInfo.Sectors = hdrV2.hunksize * hdrV2.totalhunks; imageInfo.XmlMediaType = XmlMediaType.BlockMedia; - imageInfo.SectorSize = hdrV2.seclen; - imageInfo.Version = "2"; - imageInfo.ImageSize = imageInfo.SectorSize * hdrV2.hunksize * hdrV2.totalhunks; + imageInfo.SectorSize = hdrV2.seclen; + imageInfo.Version = "2"; + imageInfo.ImageSize = imageInfo.SectorSize * hdrV2.hunksize * hdrV2.totalhunks; - totalHunks = hdrV2.totalhunks; + totalHunks = hdrV2.totalhunks; sectorsPerHunk = hdrV2.hunksize; hdrCompression = hdrV2.compression; - mapVersion = 1; - isHdd = true; + mapVersion = 1; + isHdd = true; - imageInfo.Cylinders = hdrV2.cylinders; - imageInfo.Heads = hdrV2.heads; + imageInfo.Cylinders = hdrV2.cylinders; + imageInfo.Heads = hdrV2.heads; imageInfo.SectorsPerTrack = hdrV2.sectors; break; @@ -380,16 +384,18 @@ namespace DiscImageChef.DiscImages { ChdHeaderV3 hdrV3 = BigEndianMarshal.ByteArrayToStructureBigEndian(buffer); - DicConsole.DebugWriteLine("CHD plugin", "hdrV3.tag = \"{0}\"", Encoding.ASCII.GetString(hdrV3.tag)); + DicConsole.DebugWriteLine("CHD plugin", "hdrV3.tag = \"{0}\"", + Encoding.ASCII.GetString(hdrV3.tag)); DicConsole.DebugWriteLine("CHD plugin", "hdrV3.length = {0} bytes", hdrV3.length); - DicConsole.DebugWriteLine("CHD plugin", "hdrV3.version = {0}", hdrV3.version); - DicConsole.DebugWriteLine("CHD plugin", "hdrV3.flags = {0}", (ChdFlags)hdrV3.flags); + DicConsole.DebugWriteLine("CHD plugin", "hdrV3.version = {0}", hdrV3.version); + DicConsole.DebugWriteLine("CHD plugin", "hdrV3.flags = {0}", (ChdFlags)hdrV3.flags); DicConsole.DebugWriteLine("CHD plugin", "hdrV3.compression = {0}", (ChdCompression)hdrV3.compression); - DicConsole.DebugWriteLine("CHD plugin", "hdrV3.totalhunks = {0}", hdrV3.totalhunks); + DicConsole.DebugWriteLine("CHD plugin", "hdrV3.totalhunks = {0}", hdrV3.totalhunks); DicConsole.DebugWriteLine("CHD plugin", "hdrV3.logicalbytes = {0}", hdrV3.logicalbytes); - DicConsole.DebugWriteLine("CHD plugin", "hdrV3.metaoffset = {0}", hdrV3.metaoffset); - DicConsole.DebugWriteLine("CHD plugin", "hdrV3.md5 = {0}", ArrayHelpers.ByteArrayToHex(hdrV3.md5)); + DicConsole.DebugWriteLine("CHD plugin", "hdrV3.metaoffset = {0}", hdrV3.metaoffset); + DicConsole.DebugWriteLine("CHD plugin", "hdrV3.md5 = {0}", + ArrayHelpers.ByteArrayToHex(hdrV3.md5)); DicConsole.DebugWriteLine("CHD plugin", "hdrV3.parentmd5 = {0}", ArrayHelpers.ArrayIsNullOrEmpty(hdrV3.parentmd5) ? "null" @@ -414,12 +420,12 @@ namespace DiscImageChef.DiscImages nextMetaOff = hdrV3.metaoffset; imageInfo.ImageSize = hdrV3.logicalbytes; - imageInfo.Version = "3"; + imageInfo.Version = "3"; - totalHunks = hdrV3.totalhunks; - bytesPerHunk = hdrV3.hunkbytes; + totalHunks = hdrV3.totalhunks; + bytesPerHunk = hdrV3.hunkbytes; hdrCompression = hdrV3.compression; - mapVersion = 3; + mapVersion = 3; break; } @@ -427,16 +433,17 @@ namespace DiscImageChef.DiscImages { ChdHeaderV4 hdrV4 = BigEndianMarshal.ByteArrayToStructureBigEndian(buffer); - DicConsole.DebugWriteLine("CHD plugin", "hdrV4.tag = \"{0}\"", Encoding.ASCII.GetString(hdrV4.tag)); + DicConsole.DebugWriteLine("CHD plugin", "hdrV4.tag = \"{0}\"", + Encoding.ASCII.GetString(hdrV4.tag)); DicConsole.DebugWriteLine("CHD plugin", "hdrV4.length = {0} bytes", hdrV4.length); - DicConsole.DebugWriteLine("CHD plugin", "hdrV4.version = {0}", hdrV4.version); - DicConsole.DebugWriteLine("CHD plugin", "hdrV4.flags = {0}", (ChdFlags)hdrV4.flags); + DicConsole.DebugWriteLine("CHD plugin", "hdrV4.version = {0}", hdrV4.version); + DicConsole.DebugWriteLine("CHD plugin", "hdrV4.flags = {0}", (ChdFlags)hdrV4.flags); DicConsole.DebugWriteLine("CHD plugin", "hdrV4.compression = {0}", (ChdCompression)hdrV4.compression); - DicConsole.DebugWriteLine("CHD plugin", "hdrV4.totalhunks = {0}", hdrV4.totalhunks); + DicConsole.DebugWriteLine("CHD plugin", "hdrV4.totalhunks = {0}", hdrV4.totalhunks); DicConsole.DebugWriteLine("CHD plugin", "hdrV4.logicalbytes = {0}", hdrV4.logicalbytes); - DicConsole.DebugWriteLine("CHD plugin", "hdrV4.metaoffset = {0}", hdrV4.metaoffset); - DicConsole.DebugWriteLine("CHD plugin", "hdrV4.hunkbytes = {0}", hdrV4.hunkbytes); + DicConsole.DebugWriteLine("CHD plugin", "hdrV4.metaoffset = {0}", hdrV4.metaoffset); + DicConsole.DebugWriteLine("CHD plugin", "hdrV4.hunkbytes = {0}", hdrV4.hunkbytes); DicConsole.DebugWriteLine("CHD plugin", "hdrV4.sha1 = {0}", ArrayHelpers.ByteArrayToHex(hdrV4.sha1)); DicConsole.DebugWriteLine("CHD plugin", "hdrV4.parentsha1 = {0}", @@ -458,12 +465,12 @@ namespace DiscImageChef.DiscImages nextMetaOff = hdrV4.metaoffset; imageInfo.ImageSize = hdrV4.logicalbytes; - imageInfo.Version = "4"; + imageInfo.Version = "4"; - totalHunks = hdrV4.totalhunks; - bytesPerHunk = hdrV4.hunkbytes; + totalHunks = hdrV4.totalhunks; + bytesPerHunk = hdrV4.hunkbytes; hdrCompression = hdrV4.compression; - mapVersion = 3; + mapVersion = 3; break; } @@ -471,26 +478,27 @@ namespace DiscImageChef.DiscImages { ChdHeaderV5 hdrV5 = BigEndianMarshal.ByteArrayToStructureBigEndian(buffer); - DicConsole.DebugWriteLine("CHD plugin", "hdrV5.tag = \"{0}\"", Encoding.ASCII.GetString(hdrV5.tag)); + DicConsole.DebugWriteLine("CHD plugin", "hdrV5.tag = \"{0}\"", + Encoding.ASCII.GetString(hdrV5.tag)); DicConsole.DebugWriteLine("CHD plugin", "hdrV5.length = {0} bytes", hdrV5.length); - DicConsole.DebugWriteLine("CHD plugin", "hdrV5.version = {0}", hdrV5.version); + DicConsole.DebugWriteLine("CHD plugin", "hdrV5.version = {0}", hdrV5.version); DicConsole.DebugWriteLine("CHD plugin", "hdrV5.compressor0 = \"{0}\"", Encoding.ASCII.GetString(BigEndianBitConverter - .GetBytes(hdrV5.compressor0))); + .GetBytes(hdrV5.compressor0))); DicConsole.DebugWriteLine("CHD plugin", "hdrV5.compressor1 = \"{0}\"", Encoding.ASCII.GetString(BigEndianBitConverter - .GetBytes(hdrV5.compressor1))); + .GetBytes(hdrV5.compressor1))); DicConsole.DebugWriteLine("CHD plugin", "hdrV5.compressor2 = \"{0}\"", Encoding.ASCII.GetString(BigEndianBitConverter - .GetBytes(hdrV5.compressor2))); + .GetBytes(hdrV5.compressor2))); DicConsole.DebugWriteLine("CHD plugin", "hdrV5.compressor3 = \"{0}\"", Encoding.ASCII.GetString(BigEndianBitConverter - .GetBytes(hdrV5.compressor3))); + .GetBytes(hdrV5.compressor3))); DicConsole.DebugWriteLine("CHD plugin", "hdrV5.logicalbytes = {0}", hdrV5.logicalbytes); - DicConsole.DebugWriteLine("CHD plugin", "hdrV5.mapoffset = {0}", hdrV5.mapoffset); - DicConsole.DebugWriteLine("CHD plugin", "hdrV5.metaoffset = {0}", hdrV5.metaoffset); - DicConsole.DebugWriteLine("CHD plugin", "hdrV5.hunkbytes = {0}", hdrV5.hunkbytes); - DicConsole.DebugWriteLine("CHD plugin", "hdrV5.unitbytes = {0}", hdrV5.unitbytes); + DicConsole.DebugWriteLine("CHD plugin", "hdrV5.mapoffset = {0}", hdrV5.mapoffset); + DicConsole.DebugWriteLine("CHD plugin", "hdrV5.metaoffset = {0}", hdrV5.metaoffset); + DicConsole.DebugWriteLine("CHD plugin", "hdrV5.hunkbytes = {0}", hdrV5.hunkbytes); + DicConsole.DebugWriteLine("CHD plugin", "hdrV5.unitbytes = {0}", hdrV5.unitbytes); DicConsole.DebugWriteLine("CHD plugin", "hdrV5.sha1 = {0}", ArrayHelpers.ByteArrayToHex(hdrV5.sha1)); DicConsole.DebugWriteLine("CHD plugin", "hdrV5.parentsha1 = {0}", @@ -519,18 +527,18 @@ namespace DiscImageChef.DiscImages stream.Read(hunkSectorBytes, 0, 512); // This does the big-endian trick but reverses the order of elements also Array.Reverse(hunkSectorBytes); - GCHandle handle = GCHandle.Alloc(hunkSectorBytes, GCHandleType.Pinned); + GCHandle handle = GCHandle.Alloc(hunkSectorBytes, GCHandleType.Pinned); HunkSectorSmall hunkSector = (HunkSectorSmall)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(HunkSectorSmall)); handle.Free(); // This restores the order of elements Array.Reverse(hunkSector.hunkEntry); - if(hunkTableSmall.Length >= i * 512 / 4 + 512 / 4) - Array.Copy(hunkSector.hunkEntry, 0, hunkTableSmall, i * 512 / 4, 512 / 4); + if(hunkTableSmall.Length >= i * 512 / 4 + 512 / 4) + Array.Copy(hunkSector.hunkEntry, 0, hunkTableSmall, i * 512 / 4, 512 / 4); else Array.Copy(hunkSector.hunkEntry, 0, hunkTableSmall, i * 512 / 4, - hunkTableSmall.Length - i * 512 / 4); + hunkTableSmall.Length - i * 512 / 4); } DateTime end = DateTime.UtcNow; @@ -541,15 +549,15 @@ namespace DiscImageChef.DiscImages nextMetaOff = hdrV5.metaoffset; imageInfo.ImageSize = hdrV5.logicalbytes; - imageInfo.Version = "5"; + imageInfo.Version = "5"; - totalHunks = (uint)(hdrV5.logicalbytes / hdrV5.hunkbytes); - bytesPerHunk = hdrV5.hunkbytes; - hdrCompression = hdrV5.compressor0; + totalHunks = (uint)(hdrV5.logicalbytes / hdrV5.hunkbytes); + bytesPerHunk = hdrV5.hunkbytes; + hdrCompression = hdrV5.compressor0; hdrCompression1 = hdrV5.compressor1; hdrCompression2 = hdrV5.compressor2; hdrCompression3 = hdrV5.compressor3; - mapVersion = 5; + mapVersion = 5; break; } @@ -558,16 +566,16 @@ namespace DiscImageChef.DiscImages if(mapVersion >= 3) { - isCdrom = false; - isHdd = false; - isGdrom = false; + isCdrom = false; + isHdd = false; + isGdrom = false; swapAudio = false; - tracks = new Dictionary(); + tracks = new Dictionary(); DicConsole.DebugWriteLine("CHD plugin", "Reading metadata."); ulong currentSector = 0; - uint currentTrack = 1; + uint currentTrack = 1; while(nextMetaOff > 0) { @@ -589,17 +597,18 @@ namespace DiscImageChef.DiscImages throw new ImageNotSupportedException("Image cannot be a hard disk and a C/GD-ROM at the same time, aborting."); - string gddd = StringHandlers.CToString(meta); - Regex gdddRegEx = new Regex(REGEX_METADATA_HDD); - Match gdddMatch = gdddRegEx.Match(gddd); + string gddd = StringHandlers.CToString(meta); + Regex gdddRegEx = new Regex(REGEX_METADATA_HDD); + Match gdddMatch = gdddRegEx.Match(gddd); if(gdddMatch.Success) { - isHdd = true; - imageInfo.SectorSize = uint.Parse(gdddMatch.Groups["bps"].Value); - imageInfo.Cylinders = uint.Parse(gdddMatch.Groups["cylinders"].Value); - imageInfo.Heads = uint.Parse(gdddMatch.Groups["heads"].Value); + isHdd = true; + imageInfo.SectorSize = uint.Parse(gdddMatch.Groups["bps"].Value); + imageInfo.Cylinders = uint.Parse(gdddMatch.Groups["cylinders"].Value); + imageInfo.Heads = uint.Parse(gdddMatch.Groups["heads"].Value); imageInfo.SectorsPerTrack = uint.Parse(gdddMatch.Groups["sectors"].Value); } + break; // "CHCD" case CDROM_OLD_METADATA: @@ -617,7 +626,7 @@ namespace DiscImageChef.DiscImages if(chdTracksNumber > 99) { BigEndianBitConverter.IsLittleEndian = !BitConverter.IsLittleEndian; - chdTracksNumber = BigEndianBitConverter.ToUInt32(meta, 0); + chdTracksNumber = BigEndianBitConverter.ToUInt32(meta, 0); } currentSector = 0; @@ -626,11 +635,11 @@ namespace DiscImageChef.DiscImages { ChdTrackOld chdTrack = new ChdTrackOld { - type = BigEndianBitConverter.ToUInt32(meta, (int)(4 + i * 24 + 0)), - subType = BigEndianBitConverter.ToUInt32(meta, (int)(4 + i * 24 + 4)), - dataSize = BigEndianBitConverter.ToUInt32(meta, (int)(4 + i * 24 + 8)), - subSize = BigEndianBitConverter.ToUInt32(meta, (int)(4 + i * 24 + 12)), - frames = BigEndianBitConverter.ToUInt32(meta, (int)(4 + i * 24 + 16)), + type = BigEndianBitConverter.ToUInt32(meta, (int)(4 + i * 24 + 0)), + subType = BigEndianBitConverter.ToUInt32(meta, (int)(4 + i * 24 + 4)), + dataSize = BigEndianBitConverter.ToUInt32(meta, (int)(4 + i * 24 + 8)), + subSize = BigEndianBitConverter.ToUInt32(meta, (int)(4 + i * 24 + 12)), + frames = BigEndianBitConverter.ToUInt32(meta, (int)(4 + i * 24 + 16)), extraFrames = BigEndianBitConverter.ToUInt32(meta, (int)(4 + i * 24 + 20)) }; @@ -638,40 +647,40 @@ namespace DiscImageChef.DiscImages switch((ChdOldTrackType)chdTrack.type) { case ChdOldTrackType.Audio: - dicTrack.TrackBytesPerSector = 2352; + dicTrack.TrackBytesPerSector = 2352; dicTrack.TrackRawBytesPerSector = 2352; - dicTrack.TrackType = TrackType.Audio; + dicTrack.TrackType = TrackType.Audio; break; case ChdOldTrackType.Mode1: - dicTrack.TrackBytesPerSector = 2048; + dicTrack.TrackBytesPerSector = 2048; dicTrack.TrackRawBytesPerSector = 2048; - dicTrack.TrackType = TrackType.CdMode1; + dicTrack.TrackType = TrackType.CdMode1; break; case ChdOldTrackType.Mode1Raw: - dicTrack.TrackBytesPerSector = 2048; + dicTrack.TrackBytesPerSector = 2048; dicTrack.TrackRawBytesPerSector = 2352; - dicTrack.TrackType = TrackType.CdMode1; + dicTrack.TrackType = TrackType.CdMode1; break; case ChdOldTrackType.Mode2: case ChdOldTrackType.Mode2FormMix: - dicTrack.TrackBytesPerSector = 2336; + dicTrack.TrackBytesPerSector = 2336; dicTrack.TrackRawBytesPerSector = 2336; - dicTrack.TrackType = TrackType.CdMode2Formless; + dicTrack.TrackType = TrackType.CdMode2Formless; break; case ChdOldTrackType.Mode2Form1: - dicTrack.TrackBytesPerSector = 2048; + dicTrack.TrackBytesPerSector = 2048; dicTrack.TrackRawBytesPerSector = 2048; - dicTrack.TrackType = TrackType.CdMode2Form1; + dicTrack.TrackType = TrackType.CdMode2Form1; break; case ChdOldTrackType.Mode2Form2: - dicTrack.TrackBytesPerSector = 2324; + dicTrack.TrackBytesPerSector = 2324; dicTrack.TrackRawBytesPerSector = 2324; - dicTrack.TrackType = TrackType.CdMode2Form2; + dicTrack.TrackType = TrackType.CdMode2Form2; break; case ChdOldTrackType.Mode2Raw: - dicTrack.TrackBytesPerSector = 2336; + dicTrack.TrackBytesPerSector = 2336; dicTrack.TrackRawBytesPerSector = 2352; - dicTrack.TrackType = TrackType.CdMode2Formless; + dicTrack.TrackType = TrackType.CdMode2Formless; break; default: throw new ImageNotSupportedException($"Unsupported track type {chdTrack.type}"); @@ -680,16 +689,16 @@ namespace DiscImageChef.DiscImages switch((ChdOldSubType)chdTrack.subType) { case ChdOldSubType.Cooked: - dicTrack.TrackSubchannelFile = imageFilter.GetFilename(); - dicTrack.TrackSubchannelType = TrackSubchannelType.PackedInterleaved; + dicTrack.TrackSubchannelFile = imageFilter.GetFilename(); + dicTrack.TrackSubchannelType = TrackSubchannelType.PackedInterleaved; dicTrack.TrackSubchannelFilter = imageFilter; break; case ChdOldSubType.None: dicTrack.TrackSubchannelType = TrackSubchannelType.None; break; case ChdOldSubType.Raw: - dicTrack.TrackSubchannelFile = imageFilter.GetFilename(); - dicTrack.TrackSubchannelType = TrackSubchannelType.RawInterleaved; + dicTrack.TrackSubchannelFile = imageFilter.GetFilename(); + dicTrack.TrackSubchannelType = TrackSubchannelType.RawInterleaved; dicTrack.TrackSubchannelFilter = imageFilter; break; default: @@ -697,21 +706,21 @@ namespace DiscImageChef.DiscImages ImageNotSupportedException($"Unsupported subchannel type {chdTrack.type}"); } - dicTrack.Indexes = new Dictionary(); - dicTrack.TrackDescription = $"Track {i + 1}"; - dicTrack.TrackEndSector = currentSector + chdTrack.frames - 1; - dicTrack.TrackFile = imageFilter.GetFilename(); - dicTrack.TrackFileType = "BINARY"; - dicTrack.TrackFilter = imageFilter; - dicTrack.TrackStartSector = currentSector; - dicTrack.TrackSequence = i + 1; - dicTrack.TrackSession = 1; - currentSector += chdTrack.frames + chdTrack.extraFrames; + dicTrack.Indexes = new Dictionary(); + dicTrack.TrackDescription = $"Track {i + 1}"; + dicTrack.TrackEndSector = currentSector + chdTrack.frames - 1; + dicTrack.TrackFile = imageFilter.GetFilename(); + dicTrack.TrackFileType = "BINARY"; + dicTrack.TrackFilter = imageFilter; + dicTrack.TrackStartSector = currentSector; + dicTrack.TrackSequence = i + 1; + dicTrack.TrackSession = 1; + currentSector += chdTrack.frames + chdTrack.extraFrames; tracks.Add(dicTrack.TrackSequence, dicTrack); } BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian; - isCdrom = true; + isCdrom = true; break; // "CHTR" @@ -724,16 +733,16 @@ namespace DiscImageChef.DiscImages throw new ImageNotSupportedException("Image cannot be a GD-ROM and a CD-ROM at the same time, aborting."); - string chtr = StringHandlers.CToString(meta); - Regex chtrRegEx = new Regex(REGEX_METADATA_CDROM); - Match chtrMatch = chtrRegEx.Match(chtr); + string chtr = StringHandlers.CToString(meta); + Regex chtrRegEx = new Regex(REGEX_METADATA_CDROM); + Match chtrMatch = chtrRegEx.Match(chtr); if(chtrMatch.Success) { isCdrom = true; - uint trackNo = uint.Parse(chtrMatch.Groups["track"].Value); - uint frames = uint.Parse(chtrMatch.Groups["frames"].Value); - string subtype = chtrMatch.Groups["sub_type"].Value; + uint trackNo = uint.Parse(chtrMatch.Groups["track"].Value); + uint frames = uint.Parse(chtrMatch.Groups["frames"].Value); + string subtype = chtrMatch.Groups["sub_type"].Value; string tracktype = chtrMatch.Groups["track_type"].Value; if(trackNo != currentTrack) @@ -743,46 +752,46 @@ namespace DiscImageChef.DiscImages switch(tracktype) { case TRACK_TYPE_AUDIO: - dicTrack.TrackBytesPerSector = 2352; + dicTrack.TrackBytesPerSector = 2352; dicTrack.TrackRawBytesPerSector = 2352; - dicTrack.TrackType = TrackType.Audio; + dicTrack.TrackType = TrackType.Audio; break; case TRACK_TYPE_MODE1: case TRACK_TYPE_MODE1_2K: - dicTrack.TrackBytesPerSector = 2048; + dicTrack.TrackBytesPerSector = 2048; dicTrack.TrackRawBytesPerSector = 2048; - dicTrack.TrackType = TrackType.CdMode1; + dicTrack.TrackType = TrackType.CdMode1; break; case TRACK_TYPE_MODE1_RAW: case TRACK_TYPE_MODE1_RAW_2K: - dicTrack.TrackBytesPerSector = 2048; + dicTrack.TrackBytesPerSector = 2048; dicTrack.TrackRawBytesPerSector = 2352; - dicTrack.TrackType = TrackType.CdMode1; + dicTrack.TrackType = TrackType.CdMode1; break; case TRACK_TYPE_MODE2: case TRACK_TYPE_MODE2_2K: case TRACK_TYPE_MODE2_FM: - dicTrack.TrackBytesPerSector = 2336; + dicTrack.TrackBytesPerSector = 2336; dicTrack.TrackRawBytesPerSector = 2336; - dicTrack.TrackType = TrackType.CdMode2Formless; + dicTrack.TrackType = TrackType.CdMode2Formless; break; case TRACK_TYPE_MODE2_F1: case TRACK_TYPE_MODE2_F1_2K: - dicTrack.TrackBytesPerSector = 2048; + dicTrack.TrackBytesPerSector = 2048; dicTrack.TrackRawBytesPerSector = 2048; - dicTrack.TrackType = TrackType.CdMode2Form1; + dicTrack.TrackType = TrackType.CdMode2Form1; break; case TRACK_TYPE_MODE2_F2: case TRACK_TYPE_MODE2_F2_2K: - dicTrack.TrackBytesPerSector = 2324; + dicTrack.TrackBytesPerSector = 2324; dicTrack.TrackRawBytesPerSector = 2324; - dicTrack.TrackType = TrackType.CdMode2Form2; + dicTrack.TrackType = TrackType.CdMode2Form2; break; case TRACK_TYPE_MODE2_RAW: case TRACK_TYPE_MODE2_RAW_2K: - dicTrack.TrackBytesPerSector = 2336; + dicTrack.TrackBytesPerSector = 2336; dicTrack.TrackRawBytesPerSector = 2352; - dicTrack.TrackType = TrackType.CdMode2Formless; + dicTrack.TrackType = TrackType.CdMode2Formless; break; default: throw new ImageNotSupportedException($"Unsupported track type {tracktype}"); @@ -791,32 +800,32 @@ namespace DiscImageChef.DiscImages switch(subtype) { case SUB_TYPE_COOKED: - dicTrack.TrackSubchannelFile = imageFilter.GetFilename(); - dicTrack.TrackSubchannelType = TrackSubchannelType.PackedInterleaved; + dicTrack.TrackSubchannelFile = imageFilter.GetFilename(); + dicTrack.TrackSubchannelType = TrackSubchannelType.PackedInterleaved; dicTrack.TrackSubchannelFilter = imageFilter; break; case SUB_TYPE_NONE: dicTrack.TrackSubchannelType = TrackSubchannelType.None; break; case SUB_TYPE_RAW: - dicTrack.TrackSubchannelFile = imageFilter.GetFilename(); - dicTrack.TrackSubchannelType = TrackSubchannelType.RawInterleaved; + dicTrack.TrackSubchannelFile = imageFilter.GetFilename(); + dicTrack.TrackSubchannelType = TrackSubchannelType.RawInterleaved; dicTrack.TrackSubchannelFilter = imageFilter; break; default: throw new ImageNotSupportedException($"Unsupported subchannel type {subtype}"); } - dicTrack.Indexes = new Dictionary(); - dicTrack.TrackDescription = $"Track {trackNo}"; - dicTrack.TrackEndSector = currentSector + frames - 1; - dicTrack.TrackFile = imageFilter.GetFilename(); - dicTrack.TrackFileType = "BINARY"; - dicTrack.TrackFilter = imageFilter; - dicTrack.TrackStartSector = currentSector; - dicTrack.TrackSequence = trackNo; - dicTrack.TrackSession = 1; - currentSector += frames; + dicTrack.Indexes = new Dictionary(); + dicTrack.TrackDescription = $"Track {trackNo}"; + dicTrack.TrackEndSector = currentSector + frames - 1; + dicTrack.TrackFile = imageFilter.GetFilename(); + dicTrack.TrackFileType = "BINARY"; + dicTrack.TrackFilter = imageFilter; + dicTrack.TrackStartSector = currentSector; + dicTrack.TrackSequence = trackNo; + dicTrack.TrackSession = 1; + currentSector += frames; currentTrack++; tracks.Add(dicTrack.TrackSequence, dicTrack); } @@ -832,22 +841,22 @@ namespace DiscImageChef.DiscImages throw new ImageNotSupportedException("Image cannot be a GD-ROM and a CD-ROM at the same time, aborting."); - string cht2 = StringHandlers.CToString(meta); - Regex cht2RegEx = new Regex(REGEX_METADATA_CDROM2); - Match cht2Match = cht2RegEx.Match(cht2); + string cht2 = StringHandlers.CToString(meta); + Regex cht2RegEx = new Regex(REGEX_METADATA_CDROM2); + Match cht2Match = cht2RegEx.Match(cht2); if(cht2Match.Success) { isCdrom = true; - uint trackNo = uint.Parse(cht2Match.Groups["track"].Value); - uint frames = uint.Parse(cht2Match.Groups["frames"].Value); - string subtype = cht2Match.Groups["sub_type"].Value; + uint trackNo = uint.Parse(cht2Match.Groups["track"].Value); + uint frames = uint.Parse(cht2Match.Groups["frames"].Value); + string subtype = cht2Match.Groups["sub_type"].Value; string tracktype = cht2Match.Groups["track_type"].Value; // TODO: Check pregap and postgap behaviour - uint pregap = uint.Parse(cht2Match.Groups["pregap"].Value); - string pregapType = cht2Match.Groups["pgtype"].Value; + uint pregap = uint.Parse(cht2Match.Groups["pregap"].Value); + string pregapType = cht2Match.Groups["pgtype"].Value; string pregapSubType = cht2Match.Groups["pgsub"].Value; - uint postgap = uint.Parse(cht2Match.Groups["postgap"].Value); + uint postgap = uint.Parse(cht2Match.Groups["postgap"].Value); if(trackNo != currentTrack) throw new ImageNotSupportedException("Unsorted tracks, cannot proceed."); @@ -856,46 +865,46 @@ namespace DiscImageChef.DiscImages switch(tracktype) { case TRACK_TYPE_AUDIO: - dicTrack.TrackBytesPerSector = 2352; + dicTrack.TrackBytesPerSector = 2352; dicTrack.TrackRawBytesPerSector = 2352; - dicTrack.TrackType = TrackType.Audio; + dicTrack.TrackType = TrackType.Audio; break; case TRACK_TYPE_MODE1: case TRACK_TYPE_MODE1_2K: - dicTrack.TrackBytesPerSector = 2048; + dicTrack.TrackBytesPerSector = 2048; dicTrack.TrackRawBytesPerSector = 2048; - dicTrack.TrackType = TrackType.CdMode1; + dicTrack.TrackType = TrackType.CdMode1; break; case TRACK_TYPE_MODE1_RAW: case TRACK_TYPE_MODE1_RAW_2K: - dicTrack.TrackBytesPerSector = 2048; + dicTrack.TrackBytesPerSector = 2048; dicTrack.TrackRawBytesPerSector = 2352; - dicTrack.TrackType = TrackType.CdMode1; + dicTrack.TrackType = TrackType.CdMode1; break; case TRACK_TYPE_MODE2: case TRACK_TYPE_MODE2_2K: case TRACK_TYPE_MODE2_FM: - dicTrack.TrackBytesPerSector = 2336; + dicTrack.TrackBytesPerSector = 2336; dicTrack.TrackRawBytesPerSector = 2336; - dicTrack.TrackType = TrackType.CdMode2Formless; + dicTrack.TrackType = TrackType.CdMode2Formless; break; case TRACK_TYPE_MODE2_F1: case TRACK_TYPE_MODE2_F1_2K: - dicTrack.TrackBytesPerSector = 2048; + dicTrack.TrackBytesPerSector = 2048; dicTrack.TrackRawBytesPerSector = 2048; - dicTrack.TrackType = TrackType.CdMode2Form1; + dicTrack.TrackType = TrackType.CdMode2Form1; break; case TRACK_TYPE_MODE2_F2: case TRACK_TYPE_MODE2_F2_2K: - dicTrack.TrackBytesPerSector = 2324; + dicTrack.TrackBytesPerSector = 2324; dicTrack.TrackRawBytesPerSector = 2324; - dicTrack.TrackType = TrackType.CdMode2Form2; + dicTrack.TrackType = TrackType.CdMode2Form2; break; case TRACK_TYPE_MODE2_RAW: case TRACK_TYPE_MODE2_RAW_2K: - dicTrack.TrackBytesPerSector = 2336; + dicTrack.TrackBytesPerSector = 2336; dicTrack.TrackRawBytesPerSector = 2352; - dicTrack.TrackType = TrackType.CdMode2Formless; + dicTrack.TrackType = TrackType.CdMode2Formless; break; default: throw new ImageNotSupportedException($"Unsupported track type {tracktype}"); @@ -904,32 +913,32 @@ namespace DiscImageChef.DiscImages switch(subtype) { case SUB_TYPE_COOKED: - dicTrack.TrackSubchannelFile = imageFilter.GetFilename(); - dicTrack.TrackSubchannelType = TrackSubchannelType.PackedInterleaved; + dicTrack.TrackSubchannelFile = imageFilter.GetFilename(); + dicTrack.TrackSubchannelType = TrackSubchannelType.PackedInterleaved; dicTrack.TrackSubchannelFilter = imageFilter; break; case SUB_TYPE_NONE: dicTrack.TrackSubchannelType = TrackSubchannelType.None; break; case SUB_TYPE_RAW: - dicTrack.TrackSubchannelFile = imageFilter.GetFilename(); - dicTrack.TrackSubchannelType = TrackSubchannelType.RawInterleaved; + dicTrack.TrackSubchannelFile = imageFilter.GetFilename(); + dicTrack.TrackSubchannelType = TrackSubchannelType.RawInterleaved; dicTrack.TrackSubchannelFilter = imageFilter; break; default: throw new ImageNotSupportedException($"Unsupported subchannel type {subtype}"); } - dicTrack.Indexes = new Dictionary(); - dicTrack.TrackDescription = $"Track {trackNo}"; - dicTrack.TrackEndSector = currentSector + frames - 1; - dicTrack.TrackFile = imageFilter.GetFilename(); - dicTrack.TrackFileType = "BINARY"; - dicTrack.TrackFilter = imageFilter; - dicTrack.TrackStartSector = currentSector; - dicTrack.TrackSequence = trackNo; - dicTrack.TrackSession = 1; - currentSector += frames; + dicTrack.Indexes = new Dictionary(); + dicTrack.TrackDescription = $"Track {trackNo}"; + dicTrack.TrackEndSector = currentSector + frames - 1; + dicTrack.TrackFile = imageFilter.GetFilename(); + dicTrack.TrackFileType = "BINARY"; + dicTrack.TrackFilter = imageFilter; + dicTrack.TrackStartSector = currentSector; + dicTrack.TrackSequence = trackNo; + dicTrack.TrackSession = 1; + currentSector += frames; currentTrack++; tracks.Add(dicTrack.TrackSequence, dicTrack); } @@ -949,23 +958,23 @@ namespace DiscImageChef.DiscImages throw new ImageNotSupportedException("Image cannot be a CD-ROM and a GD-ROM at the same time, aborting."); - string chgd = StringHandlers.CToString(meta); - Regex chgdRegEx = new Regex(REGEX_METADATA_GDROM); - Match chgdMatch = chgdRegEx.Match(chgd); + string chgd = StringHandlers.CToString(meta); + Regex chgdRegEx = new Regex(REGEX_METADATA_GDROM); + Match chgdMatch = chgdRegEx.Match(chgd); if(chgdMatch.Success) { isGdrom = true; - uint trackNo = uint.Parse(chgdMatch.Groups["track"].Value); - uint frames = uint.Parse(chgdMatch.Groups["frames"].Value); - string subtype = chgdMatch.Groups["sub_type"].Value; + uint trackNo = uint.Parse(chgdMatch.Groups["track"].Value); + uint frames = uint.Parse(chgdMatch.Groups["frames"].Value); + string subtype = chgdMatch.Groups["sub_type"].Value; string tracktype = chgdMatch.Groups["track_type"].Value; // TODO: Check pregap, postgap and pad behaviour - uint pregap = uint.Parse(chgdMatch.Groups["pregap"].Value); - string pregapType = chgdMatch.Groups["pgtype"].Value; + uint pregap = uint.Parse(chgdMatch.Groups["pregap"].Value); + string pregapType = chgdMatch.Groups["pgtype"].Value; string pregapSubType = chgdMatch.Groups["pgsub"].Value; - uint postgap = uint.Parse(chgdMatch.Groups["postgap"].Value); - uint pad = uint.Parse(chgdMatch.Groups["pad"].Value); + uint postgap = uint.Parse(chgdMatch.Groups["postgap"].Value); + uint pad = uint.Parse(chgdMatch.Groups["pad"].Value); if(trackNo != currentTrack) throw new ImageNotSupportedException("Unsorted tracks, cannot proceed."); @@ -974,46 +983,46 @@ namespace DiscImageChef.DiscImages switch(tracktype) { case TRACK_TYPE_AUDIO: - dicTrack.TrackBytesPerSector = 2352; + dicTrack.TrackBytesPerSector = 2352; dicTrack.TrackRawBytesPerSector = 2352; - dicTrack.TrackType = TrackType.Audio; + dicTrack.TrackType = TrackType.Audio; break; case TRACK_TYPE_MODE1: case TRACK_TYPE_MODE1_2K: - dicTrack.TrackBytesPerSector = 2048; + dicTrack.TrackBytesPerSector = 2048; dicTrack.TrackRawBytesPerSector = 2048; - dicTrack.TrackType = TrackType.CdMode1; + dicTrack.TrackType = TrackType.CdMode1; break; case TRACK_TYPE_MODE1_RAW: case TRACK_TYPE_MODE1_RAW_2K: - dicTrack.TrackBytesPerSector = 2048; + dicTrack.TrackBytesPerSector = 2048; dicTrack.TrackRawBytesPerSector = 2352; - dicTrack.TrackType = TrackType.CdMode1; + dicTrack.TrackType = TrackType.CdMode1; break; case TRACK_TYPE_MODE2: case TRACK_TYPE_MODE2_2K: case TRACK_TYPE_MODE2_FM: - dicTrack.TrackBytesPerSector = 2336; + dicTrack.TrackBytesPerSector = 2336; dicTrack.TrackRawBytesPerSector = 2336; - dicTrack.TrackType = TrackType.CdMode2Formless; + dicTrack.TrackType = TrackType.CdMode2Formless; break; case TRACK_TYPE_MODE2_F1: case TRACK_TYPE_MODE2_F1_2K: - dicTrack.TrackBytesPerSector = 2048; + dicTrack.TrackBytesPerSector = 2048; dicTrack.TrackRawBytesPerSector = 2048; - dicTrack.TrackType = TrackType.CdMode2Form1; + dicTrack.TrackType = TrackType.CdMode2Form1; break; case TRACK_TYPE_MODE2_F2: case TRACK_TYPE_MODE2_F2_2K: - dicTrack.TrackBytesPerSector = 2324; + dicTrack.TrackBytesPerSector = 2324; dicTrack.TrackRawBytesPerSector = 2324; - dicTrack.TrackType = TrackType.CdMode2Form2; + dicTrack.TrackType = TrackType.CdMode2Form2; break; case TRACK_TYPE_MODE2_RAW: case TRACK_TYPE_MODE2_RAW_2K: - dicTrack.TrackBytesPerSector = 2336; + dicTrack.TrackBytesPerSector = 2336; dicTrack.TrackRawBytesPerSector = 2352; - dicTrack.TrackType = TrackType.CdMode2Formless; + dicTrack.TrackType = TrackType.CdMode2Formless; break; default: throw new ImageNotSupportedException($"Unsupported track type {tracktype}"); @@ -1022,32 +1031,32 @@ namespace DiscImageChef.DiscImages switch(subtype) { case SUB_TYPE_COOKED: - dicTrack.TrackSubchannelFile = imageFilter.GetFilename(); - dicTrack.TrackSubchannelType = TrackSubchannelType.PackedInterleaved; + dicTrack.TrackSubchannelFile = imageFilter.GetFilename(); + dicTrack.TrackSubchannelType = TrackSubchannelType.PackedInterleaved; dicTrack.TrackSubchannelFilter = imageFilter; break; case SUB_TYPE_NONE: dicTrack.TrackSubchannelType = TrackSubchannelType.None; break; case SUB_TYPE_RAW: - dicTrack.TrackSubchannelFile = imageFilter.GetFilename(); - dicTrack.TrackSubchannelType = TrackSubchannelType.RawInterleaved; + dicTrack.TrackSubchannelFile = imageFilter.GetFilename(); + dicTrack.TrackSubchannelType = TrackSubchannelType.RawInterleaved; dicTrack.TrackSubchannelFilter = imageFilter; break; default: throw new ImageNotSupportedException($"Unsupported subchannel type {subtype}"); } - dicTrack.Indexes = new Dictionary(); - dicTrack.TrackDescription = $"Track {trackNo}"; - dicTrack.TrackEndSector = currentSector + frames - 1; - dicTrack.TrackFile = imageFilter.GetFilename(); - dicTrack.TrackFileType = "BINARY"; - dicTrack.TrackFilter = imageFilter; - dicTrack.TrackStartSector = currentSector; - dicTrack.TrackSequence = trackNo; - dicTrack.TrackSession = (ushort)(trackNo > 2 ? 2 : 1); - currentSector += frames; + dicTrack.Indexes = new Dictionary(); + dicTrack.TrackDescription = $"Track {trackNo}"; + dicTrack.TrackEndSector = currentSector + frames - 1; + dicTrack.TrackFile = imageFilter.GetFilename(); + dicTrack.TrackFileType = "BINARY"; + dicTrack.TrackFilter = imageFilter; + dicTrack.TrackStartSector = currentSector; + dicTrack.TrackSequence = trackNo; + dicTrack.TrackSession = (ushort)(trackNo > 2 ? 2 : 1); + currentSector += frames; currentTrack++; tracks.Add(dicTrack.TrackSequence, dicTrack); } @@ -1058,25 +1067,26 @@ namespace DiscImageChef.DiscImages Identify.IdentifyDevice? idnt = Decoders.ATA.Identify.Decode(meta); if(idnt.HasValue) { - imageInfo.MediaManufacturer = idnt.Value.MediaManufacturer; - imageInfo.MediaSerialNumber = idnt.Value.MediaSerial; - imageInfo.DriveModel = idnt.Value.Model; - imageInfo.DriveSerialNumber = idnt.Value.SerialNumber; + imageInfo.MediaManufacturer = idnt.Value.MediaManufacturer; + imageInfo.MediaSerialNumber = idnt.Value.MediaSerial; + imageInfo.DriveModel = idnt.Value.Model; + imageInfo.DriveSerialNumber = idnt.Value.SerialNumber; imageInfo.DriveFirmwareRevision = idnt.Value.FirmwareRevision; - if(idnt.Value.CurrentCylinders > 0 && idnt.Value.CurrentHeads > 0 && + if(idnt.Value.CurrentCylinders > 0 && idnt.Value.CurrentHeads > 0 && idnt.Value.CurrentSectorsPerTrack > 0) { - imageInfo.Cylinders = idnt.Value.CurrentCylinders; - imageInfo.Heads = idnt.Value.CurrentHeads; + imageInfo.Cylinders = idnt.Value.CurrentCylinders; + imageInfo.Heads = idnt.Value.CurrentHeads; imageInfo.SectorsPerTrack = idnt.Value.CurrentSectorsPerTrack; } else { - imageInfo.Cylinders = idnt.Value.Cylinders; - imageInfo.Heads = idnt.Value.Heads; + imageInfo.Cylinders = idnt.Value.Cylinders; + imageInfo.Heads = idnt.Value.Heads; imageInfo.SectorsPerTrack = idnt.Value.SectorsPerTrack; } } + identify = meta; if(!imageInfo.ReadableMediaTags.Contains(MediaTagType.ATA_IDENTIFY)) imageInfo.ReadableMediaTags.Add(MediaTagType.ATA_IDENTIFY); @@ -1093,16 +1103,16 @@ namespace DiscImageChef.DiscImages if(isHdd) { - sectorsPerHunk = bytesPerHunk / imageInfo.SectorSize; - imageInfo.Sectors = imageInfo.ImageSize / imageInfo.SectorSize; - imageInfo.MediaType = MediaType.GENERIC_HDD; + sectorsPerHunk = bytesPerHunk / imageInfo.SectorSize; + imageInfo.Sectors = imageInfo.ImageSize / imageInfo.SectorSize; + imageInfo.MediaType = MediaType.GENERIC_HDD; imageInfo.XmlMediaType = XmlMediaType.BlockMedia; } else if(isCdrom) { // Hardcoded on MAME for CD-ROM - sectorsPerHunk = 8; - imageInfo.MediaType = MediaType.CDROM; + sectorsPerHunk = 8; + imageInfo.MediaType = MediaType.CDROM; imageInfo.XmlMediaType = XmlMediaType.OpticalDisc; foreach(Track dicTrack in tracks.Values) @@ -1111,34 +1121,35 @@ namespace DiscImageChef.DiscImages else if(isGdrom) { // Hardcoded on MAME for GD-ROM - sectorsPerHunk = 8; - imageInfo.MediaType = MediaType.GDROM; + sectorsPerHunk = 8; + imageInfo.MediaType = MediaType.GDROM; imageInfo.XmlMediaType = XmlMediaType.OpticalDisc; foreach(Track dicTrack in tracks.Values) imageInfo.Sectors += dicTrack.TrackEndSector - dicTrack.TrackStartSector + 1; } - else throw new ImageNotSupportedException("Image does not represent a known media, aborting"); + else + throw new ImageNotSupportedException("Image does not represent a known media, aborting"); } if(isCdrom || isGdrom) { - offsetmap = new Dictionary(); - partitions = new List(); + offsetmap = new Dictionary(); + partitions = new List(); ulong partPos = 0; foreach(Track dicTrack in tracks.Values) { Partition partition = new Partition { Description = dicTrack.TrackDescription, - Size = + Size = (dicTrack.TrackEndSector - dicTrack.TrackStartSector + 1) * (ulong)dicTrack.TrackRawBytesPerSector, - Length = dicTrack.TrackEndSector - dicTrack.TrackStartSector + 1, + Length = dicTrack.TrackEndSector - dicTrack.TrackStartSector + 1, Sequence = dicTrack.TrackSequence, - Offset = partPos, - Start = dicTrack.TrackStartSector, - Type = dicTrack.TrackType.ToString() + Offset = partPos, + Start = dicTrack.TrackStartSector, + Type = dicTrack.TrackType.ToString() }; partPos += partition.Length; offsetmap.Add(dicTrack.TrackStartSector, dicTrack.TrackSequence); @@ -1168,6 +1179,7 @@ namespace DiscImageChef.DiscImages if(!imageInfo.ReadableSectorTags.Contains(SectorTagType.CdSectorEdc)) imageInfo.ReadableSectorTags.Add(SectorTagType.CdSectorEdc); } + break; case TrackType.CdMode2Form2: if(dicTrack.TrackRawBytesPerSector == 2352) @@ -1181,6 +1193,7 @@ namespace DiscImageChef.DiscImages if(!imageInfo.ReadableSectorTags.Contains(SectorTagType.CdSectorEdc)) imageInfo.ReadableSectorTags.Add(SectorTagType.CdSectorEdc); } + break; case TrackType.CdMode2Formless: if(dicTrack.TrackRawBytesPerSector == 2352) @@ -1190,6 +1203,7 @@ namespace DiscImageChef.DiscImages if(!imageInfo.ReadableSectorTags.Contains(SectorTagType.CdSectorHeader)) imageInfo.ReadableSectorTags.Add(SectorTagType.CdSectorHeader); } + break; } @@ -1200,16 +1214,16 @@ namespace DiscImageChef.DiscImages } imageInfo.HasPartitions = true; - imageInfo.HasSessions = true; + imageInfo.HasSessions = true; } - maxBlockCache = (int)(MAX_CACHE_SIZE / (imageInfo.SectorSize * sectorsPerHunk)); + maxBlockCache = (int)(MAX_CACHE_SIZE / (imageInfo.SectorSize * sectorsPerHunk)); maxSectorCache = (int)(MAX_CACHE_SIZE / imageInfo.SectorSize); imageStream = stream; sectorCache = new Dictionary(); - hunkCache = new Dictionary(); + hunkCache = new Dictionary(); // TODO: Detect CompactFlash // TODO: Get manufacturer and drive name from CIS if applicable @@ -1218,136 +1232,6 @@ namespace DiscImageChef.DiscImages return true; } - Track GetTrack(ulong sector) - { - Track track = new Track(); - foreach(KeyValuePair kvp in offsetmap.Where(kvp => sector >= kvp.Key)) - tracks.TryGetValue(kvp.Value, out track); - - return track; - } - - ulong GetAbsoluteSector(ulong relativeSector, uint track) - { - tracks.TryGetValue(track, out Track dicTrack); - return dicTrack.TrackStartSector + relativeSector; - } - - byte[] GetHunk(ulong hunkNo) - { - if(hunkCache.TryGetValue(hunkNo, out byte[] hunk)) return hunk; - - switch(mapVersion) - { - case 1: - ulong offset = hunkTable[hunkNo] & 0x00000FFFFFFFFFFF; - ulong length = hunkTable[hunkNo] >> 44; - - byte[] compHunk = new byte[length]; - imageStream.Seek((long)offset, SeekOrigin.Begin); - imageStream.Read(compHunk, 0, compHunk.Length); - - if(length == sectorsPerHunk * imageInfo.SectorSize) hunk = compHunk; - else if((ChdCompression)hdrCompression > ChdCompression.Zlib) - throw new - ImageNotSupportedException($"Unsupported compression {(ChdCompression)hdrCompression}"); - else - { - DeflateStream zStream = - new DeflateStream(new MemoryStream(compHunk), CompressionMode.Decompress); - hunk = new byte[sectorsPerHunk * imageInfo.SectorSize]; - int read = zStream.Read(hunk, 0, (int)(sectorsPerHunk * imageInfo.SectorSize)); - if(read != sectorsPerHunk * imageInfo.SectorSize) - throw new - IOException($"Unable to decompress hunk correctly, got {read} bytes, expected {sectorsPerHunk * imageInfo.SectorSize}"); - - zStream.Close(); - } - - break; - case 3: - byte[] entryBytes = new byte[16]; - Array.Copy(hunkMap, (int)(hunkNo * 16), entryBytes, 0, 16); - ChdMapV3Entry entry = BigEndianMarshal.ByteArrayToStructureBigEndian(entryBytes); - switch((Chdv3EntryFlags)(entry.flags & 0x0F)) - { - case Chdv3EntryFlags.Invalid: throw new ArgumentException("Invalid hunk found."); - case Chdv3EntryFlags.Compressed: - switch((ChdCompression)hdrCompression) - { - case ChdCompression.None: goto uncompressedV3; - case ChdCompression.Zlib: - case ChdCompression.ZlibPlus: - if(isHdd) - { - byte[] zHunk = new byte[(entry.lengthLsb << 16) + entry.lengthLsb]; - imageStream.Seek((long)entry.offset, SeekOrigin.Begin); - imageStream.Read(zHunk, 0, zHunk.Length); - DeflateStream zStream = - new DeflateStream(new MemoryStream(zHunk), CompressionMode.Decompress); - hunk = new byte[bytesPerHunk]; - int read = zStream.Read(hunk, 0, (int)bytesPerHunk); - if(read != bytesPerHunk) - throw new - IOException($"Unable to decompress hunk correctly, got {read} bytes, expected {bytesPerHunk}"); - - zStream.Close(); - } - // TODO: Guess wth is MAME doing with these hunks - else - throw new - ImageNotSupportedException("Compressed CD/GD-ROM hunks are not yet supported"); - - break; - case ChdCompression.Av: - throw new - ImageNotSupportedException($"Unsupported compression {(ChdCompression)hdrCompression}"); - } - - break; - case Chdv3EntryFlags.Uncompressed: - uncompressedV3: - hunk = new byte[bytesPerHunk]; - imageStream.Seek((long)entry.offset, SeekOrigin.Begin); - imageStream.Read(hunk, 0, hunk.Length); - break; - case Chdv3EntryFlags.Mini: - hunk = new byte[bytesPerHunk]; - byte[] mini; - mini = BigEndianBitConverter.GetBytes(entry.offset); - for(int i = 0; i < bytesPerHunk; i++) hunk[i] = mini[i % 8]; - - break; - case Chdv3EntryFlags.SelfHunk: return GetHunk(entry.offset); - case Chdv3EntryFlags.ParentHunk: - throw new ImageNotSupportedException("Parent images are not supported"); - case Chdv3EntryFlags.SecondCompressed: - throw new ImageNotSupportedException("FLAC is not supported"); - default: - throw new ImageNotSupportedException($"Hunk type {entry.flags & 0xF} is not supported"); - } - - break; - case 5: - if(hdrCompression == 0) - { - hunk = new byte[bytesPerHunk]; - imageStream.Seek(hunkTableSmall[hunkNo] * bytesPerHunk, SeekOrigin.Begin); - imageStream.Read(hunk, 0, hunk.Length); - } - else throw new ImageNotSupportedException("Compressed v5 hunks not yet supported"); - - break; - default: throw new ImageNotSupportedException($"Unsupported hunk map version {mapVersion}"); - } - - if(hunkCache.Count >= maxBlockCache) hunkCache.Clear(); - - hunkCache.Add(hunkNo, hunk); - - return hunk; - } - public bool? VerifySector(ulong sectorAddress) { if(isHdd) return null; @@ -1365,14 +1249,14 @@ namespace DiscImageChef.DiscImages } public bool? VerifySectors(ulong sectorAddress, uint length, out List failingLbas, - out List unknownLbas) + out List unknownLbas) { unknownLbas = new List(); failingLbas = new List(); if(isHdd) return null; byte[] buffer = ReadSectorsLong(sectorAddress, length); - int bps = (int)(buffer.Length / length); + int bps = (int)(buffer.Length / length); byte[] sector = new byte[bps]; for(int i = 0; i < length; i++) @@ -1397,14 +1281,14 @@ namespace DiscImageChef.DiscImages } public bool? VerifySectors(ulong sectorAddress, uint length, uint track, out List failingLbas, - out List unknownLbas) + out List unknownLbas) { unknownLbas = new List(); failingLbas = new List(); if(isHdd) return null; byte[] buffer = ReadSectorsLong(sectorAddress, length, track); - int bps = (int)(buffer.Length / length); + int bps = (int)(buffer.Length / length); byte[] sector = new byte[bps]; for(int i = 0; i < length; i++) @@ -1451,6 +1335,9 @@ namespace DiscImageChef.DiscImages return expectedChecksum.SequenceEqual(calculated); } + public List DumpHardware => null; + public CICMMetadataType CicmMetadata => null; + public byte[] ReadSector(ulong sectorAddress) { if(sectorAddress > imageInfo.Sectors - 1) @@ -1458,14 +1345,14 @@ namespace DiscImageChef.DiscImages $"Sector address {sectorAddress} not found"); Track track = new Track(); - uint sectorSize; + uint sectorSize; if(!sectorCache.TryGetValue(sectorAddress, out byte[] sector)) { if(isHdd) sectorSize = imageInfo.SectorSize; else { - track = GetTrack(sectorAddress); + track = GetTrack(sectorAddress); sectorSize = (uint)track.TrackRawBytesPerSector; } @@ -1494,13 +1381,14 @@ namespace DiscImageChef.DiscImages if(track.TrackRawBytesPerSector == 2352) { sectorOffset = 16; - sectorSize = 2048; + sectorSize = 2048; } else { sectorOffset = 0; - sectorSize = 2048; + sectorSize = 2048; } + break; } case TrackType.CdMode2Form2: @@ -1508,13 +1396,14 @@ namespace DiscImageChef.DiscImages if(track.TrackRawBytesPerSector == 2352) { sectorOffset = 16; - sectorSize = 2324; + sectorSize = 2324; } else { sectorOffset = 0; - sectorSize = 2324; + sectorSize = 2324; } + break; } case TrackType.CdMode2Formless: @@ -1522,19 +1411,20 @@ namespace DiscImageChef.DiscImages if(track.TrackRawBytesPerSector == 2352) { sectorOffset = 16; - sectorSize = 2336; + sectorSize = 2336; } else { sectorOffset = 0; - sectorSize = 2336; + sectorSize = 2336; } + break; } case TrackType.Audio: { sectorOffset = 0; - sectorSize = 2352; + sectorSize = 2352; break; } default: throw new FeatureSupportedButNotImplementedImageException("Unsupported track type"); @@ -1542,11 +1432,11 @@ namespace DiscImageChef.DiscImages byte[] buffer = new byte[sectorSize]; - if(track.TrackType == TrackType.Audio && swapAudio) + if(track.TrackType == TrackType.Audio && swapAudio) for(int i = 0; i < 2352; i += 2) { buffer[i + 1] = sector[i]; - buffer[i] = sector[i + 1]; + buffer[i] = sector[i + 1]; } else Array.Copy(sector, sectorOffset, buffer, 0, sectorSize); @@ -1567,7 +1457,7 @@ namespace DiscImageChef.DiscImages if(!sectorCache.TryGetValue(sectorAddress, out byte[] sector)) { - track = GetTrack(sectorAddress); + track = GetTrack(sectorAddress); sectorSize = (uint)track.TrackRawBytesPerSector; ulong hunkNo = sectorAddress / sectorsPerHunk; @@ -1594,7 +1484,7 @@ namespace DiscImageChef.DiscImages throw new FeatureNotPresentImageException("Requested sector does not contain subchannel"); case TrackSubchannelType.RawInterleaved: sectorOffset = (uint)track.TrackRawBytesPerSector; - sectorSize = 96; + sectorSize = 96; break; default: throw new @@ -1612,13 +1502,13 @@ namespace DiscImageChef.DiscImages case SectorTagType.CdSectorSync: { sectorOffset = 0; - sectorSize = 12; + sectorSize = 12; break; } case SectorTagType.CdSectorHeader: { sectorOffset = 12; - sectorSize = 4; + sectorSize = 4; break; } case SectorTagType.CdSectorSubHeader: @@ -1627,25 +1517,25 @@ namespace DiscImageChef.DiscImages case SectorTagType.CdSectorEcc: { sectorOffset = 2076; - sectorSize = 276; + sectorSize = 276; break; } case SectorTagType.CdSectorEccP: { sectorOffset = 2076; - sectorSize = 172; + sectorSize = 172; break; } case SectorTagType.CdSectorEccQ: { sectorOffset = 2248; - sectorSize = 104; + sectorSize = 104; break; } case SectorTagType.CdSectorEdc: { sectorOffset = 2064; - sectorSize = 4; + sectorSize = 4; break; } default: throw new ArgumentException("Unsupported tag requested", nameof(tag)); @@ -1662,25 +1552,25 @@ namespace DiscImageChef.DiscImages case SectorTagType.CdSectorSync: { sectorOffset = 0; - sectorSize = 12; + sectorSize = 12; break; } case SectorTagType.CdSectorHeader: { sectorOffset = 12; - sectorSize = 4; + sectorSize = 4; break; } case SectorTagType.CdSectorSubHeader: { sectorOffset = 16; - sectorSize = 8; + sectorSize = 8; break; } case SectorTagType.CdSectorEdc: { sectorOffset = 2348; - sectorSize = 4; + sectorSize = 4; break; } default: throw new ArgumentException("Unsupported tag requested", nameof(tag)); @@ -1699,13 +1589,13 @@ namespace DiscImageChef.DiscImages case SectorTagType.CdSectorSubHeader: { sectorOffset = 0; - sectorSize = 8; + sectorSize = 8; break; } case SectorTagType.CdSectorEdc: { sectorOffset = 2332; - sectorSize = 4; + sectorSize = 4; break; } default: throw new ArgumentException("Unsupported tag requested", nameof(tag)); @@ -1728,13 +1618,13 @@ namespace DiscImageChef.DiscImages case SectorTagType.CdSectorSubHeader: { sectorOffset = 0; - sectorSize = 8; + sectorSize = 8; break; } case SectorTagType.CdSectorEdc: { sectorOffset = 2332; - sectorSize = 4; + sectorSize = 4; break; } default: throw new ArgumentException("Unsupported tag requested", nameof(tag)); @@ -1750,19 +1640,19 @@ namespace DiscImageChef.DiscImages byte[] buffer = new byte[sectorSize]; - if(track.TrackType == TrackType.Audio && swapAudio) + if(track.TrackType == TrackType.Audio && swapAudio) for(int i = 0; i < 2352; i += 2) { buffer[i + 1] = sector[i]; - buffer[i] = sector[i + 1]; + buffer[i] = sector[i + 1]; } else Array.Copy(sector, sectorOffset, buffer, 0, sectorSize); - if(track.TrackType == TrackType.Audio && swapAudio) + if(track.TrackType == TrackType.Audio && swapAudio) for(int i = 0; i < 2352; i += 2) { buffer[i + 1] = sector[i]; - buffer[i] = sector[i + 1]; + buffer[i] = sector[i + 1]; } else Array.Copy(sector, sectorOffset, buffer, 0, sectorSize); @@ -1823,10 +1713,8 @@ namespace DiscImageChef.DiscImages if(!sectorCache.TryGetValue(sectorAddress, out byte[] sector)) { - uint sectorSize; - - track = GetTrack(sectorAddress); - sectorSize = (uint)track.TrackRawBytesPerSector; + track = GetTrack(sectorAddress); + uint sectorSize = (uint)track.TrackRawBytesPerSector; ulong hunkNo = sectorAddress / sectorsPerHunk; ulong secOff = sectorAddress * sectorSize % (sectorsPerHunk * sectorSize); @@ -1843,11 +1731,11 @@ namespace DiscImageChef.DiscImages byte[] buffer = new byte[track.TrackRawBytesPerSector]; - if(track.TrackType == TrackType.Audio && swapAudio) + if(track.TrackType == TrackType.Audio && swapAudio) for(int i = 0; i < 2352; i += 2) { buffer[i + 1] = sector[i]; - buffer[i] = sector[i + 1]; + buffer[i] = sector[i + 1]; } else Array.Copy(sector, 0, buffer, 0, track.TrackRawBytesPerSector); @@ -1948,18 +1836,149 @@ namespace DiscImageChef.DiscImages return ReadSectorLong(GetAbsoluteSector(sectorAddress, track), length); } + Track GetTrack(ulong sector) + { + Track track = new Track(); + foreach(KeyValuePair kvp in offsetmap.Where(kvp => sector >= kvp.Key)) + tracks.TryGetValue(kvp.Value, out track); + + return track; + } + + ulong GetAbsoluteSector(ulong relativeSector, uint track) + { + tracks.TryGetValue(track, out Track dicTrack); + return dicTrack.TrackStartSector + relativeSector; + } + + byte[] GetHunk(ulong hunkNo) + { + if(hunkCache.TryGetValue(hunkNo, out byte[] hunk)) return hunk; + + switch(mapVersion) + { + case 1: + ulong offset = hunkTable[hunkNo] & 0x00000FFFFFFFFFFF; + ulong length = hunkTable[hunkNo] >> 44; + + byte[] compHunk = new byte[length]; + imageStream.Seek((long)offset, SeekOrigin.Begin); + imageStream.Read(compHunk, 0, compHunk.Length); + + if(length == sectorsPerHunk * imageInfo.SectorSize) hunk = compHunk; + else if((ChdCompression)hdrCompression > ChdCompression.Zlib) + throw new + ImageNotSupportedException($"Unsupported compression {(ChdCompression)hdrCompression}"); + else + { + DeflateStream zStream = + new DeflateStream(new MemoryStream(compHunk), CompressionMode.Decompress); + hunk = new byte[sectorsPerHunk * imageInfo.SectorSize]; + int read = zStream.Read(hunk, 0, (int)(sectorsPerHunk * imageInfo.SectorSize)); + if(read != sectorsPerHunk * imageInfo.SectorSize) + throw new + IOException($"Unable to decompress hunk correctly, got {read} bytes, expected {sectorsPerHunk * imageInfo.SectorSize}"); + + zStream.Close(); + } + + break; + case 3: + byte[] entryBytes = new byte[16]; + Array.Copy(hunkMap, (int)(hunkNo * 16), entryBytes, 0, 16); + ChdMapV3Entry entry = BigEndianMarshal.ByteArrayToStructureBigEndian(entryBytes); + switch((Chdv3EntryFlags)(entry.flags & 0x0F)) + { + case Chdv3EntryFlags.Invalid: throw new ArgumentException("Invalid hunk found."); + case Chdv3EntryFlags.Compressed: + switch((ChdCompression)hdrCompression) + { + case ChdCompression.None: goto uncompressedV3; + case ChdCompression.Zlib: + case ChdCompression.ZlibPlus: + if(isHdd) + { + byte[] zHunk = new byte[(entry.lengthLsb << 16) + entry.lengthLsb]; + imageStream.Seek((long)entry.offset, SeekOrigin.Begin); + imageStream.Read(zHunk, 0, zHunk.Length); + DeflateStream zStream = + new DeflateStream(new MemoryStream(zHunk), CompressionMode.Decompress); + hunk = new byte[bytesPerHunk]; + int read = zStream.Read(hunk, 0, (int)bytesPerHunk); + if(read != bytesPerHunk) + throw new + IOException($"Unable to decompress hunk correctly, got {read} bytes, expected {bytesPerHunk}"); + + zStream.Close(); + } + // TODO: Guess wth is MAME doing with these hunks + else + throw new + ImageNotSupportedException("Compressed CD/GD-ROM hunks are not yet supported"); + + break; + case ChdCompression.Av: + throw new + ImageNotSupportedException($"Unsupported compression {(ChdCompression)hdrCompression}"); + } + + break; + case Chdv3EntryFlags.Uncompressed: + uncompressedV3: + hunk = new byte[bytesPerHunk]; + imageStream.Seek((long)entry.offset, SeekOrigin.Begin); + imageStream.Read(hunk, 0, hunk.Length); + break; + case Chdv3EntryFlags.Mini: + hunk = new byte[bytesPerHunk]; + byte[] mini; + mini = + BigEndianBitConverter.GetBytes(entry.offset); + for(int i = 0; i < bytesPerHunk; i++) hunk[i] = mini[i % 8]; + + break; + case Chdv3EntryFlags.SelfHunk: return GetHunk(entry.offset); + case Chdv3EntryFlags.ParentHunk: + throw new ImageNotSupportedException("Parent images are not supported"); + case Chdv3EntryFlags.SecondCompressed: + throw new ImageNotSupportedException("FLAC is not supported"); + default: + throw new ImageNotSupportedException($"Hunk type {entry.flags & 0xF} is not supported"); + } + + break; + case 5: + if(hdrCompression == 0) + { + hunk = new byte[bytesPerHunk]; + imageStream.Seek(hunkTableSmall[hunkNo] * bytesPerHunk, SeekOrigin.Begin); + imageStream.Read(hunk, 0, hunk.Length); + } + else throw new ImageNotSupportedException("Compressed v5 hunks not yet supported"); + + break; + default: throw new ImageNotSupportedException($"Unsupported hunk map version {mapVersion}"); + } + + if(hunkCache.Count >= maxBlockCache) hunkCache.Clear(); + + hunkCache.Add(hunkNo, hunk); + + return hunk; + } + enum ChdCompression : uint { - None = 0, - Zlib = 1, + None = 0, + Zlib = 1, ZlibPlus = 2, - Av = 3 + Av = 3 } enum ChdFlags : uint { HasParent = 1, - Writable = 2 + Writable = 2 } enum Chdv3EntryFlags : byte @@ -2007,7 +2026,8 @@ namespace DiscImageChef.DiscImages /// /// Magic identifier, 'MComprHD' /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public byte[] tag; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] + public byte[] tag; /// /// Length of header /// @@ -2047,11 +2067,13 @@ namespace DiscImageChef.DiscImages /// /// MD5 of raw data /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] md5; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] + public byte[] md5; /// /// MD5 of parent file /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] parentmd5; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] + public byte[] parentmd5; } // Hunks are represented in a 64 bit integer with 44 bit as offset, 20 bits as length @@ -2061,7 +2083,8 @@ namespace DiscImageChef.DiscImages /// /// Magic identifier, 'MComprHD' /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public byte[] tag; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] + public byte[] tag; /// /// Length of header /// @@ -2101,11 +2124,13 @@ namespace DiscImageChef.DiscImages /// /// MD5 of raw data /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] md5; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] + public byte[] md5; /// /// MD5 of parent file /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] parentmd5; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] + public byte[] parentmd5; /// /// Bytes per sector /// @@ -2118,7 +2143,8 @@ namespace DiscImageChef.DiscImages /// /// Magic identifier, 'MComprHD' /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public byte[] tag; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] + public byte[] tag; /// /// Length of header /// @@ -2150,11 +2176,13 @@ namespace DiscImageChef.DiscImages /// /// MD5 of raw data /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] md5; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] + public byte[] md5; /// /// MD5 of parent file /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] parentmd5; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] + public byte[] parentmd5; /// /// Bytes per hunk /// @@ -2162,11 +2190,13 @@ namespace DiscImageChef.DiscImages /// /// SHA1 of raw data /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)] public byte[] sha1; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)] + public byte[] sha1; /// /// SHA1 of parent file /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)] public byte[] parentsha1; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)] + public byte[] parentsha1; } [StructLayout(LayoutKind.Sequential, Pack = 1)] @@ -2211,7 +2241,8 @@ namespace DiscImageChef.DiscImages /// /// Magic identifier, 'MComprHD' /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public byte[] tag; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] + public byte[] tag; /// /// Length of header /// @@ -2247,15 +2278,18 @@ namespace DiscImageChef.DiscImages /// /// SHA1 of raw+meta data /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)] public byte[] sha1; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)] + public byte[] sha1; /// /// SHA1 of parent file /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)] public byte[] parentsha1; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)] + public byte[] parentsha1; /// /// SHA1 of raw data /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)] public byte[] rawsha1; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)] + public byte[] rawsha1; } [StructLayout(LayoutKind.Sequential, Pack = 1)] @@ -2264,7 +2298,8 @@ namespace DiscImageChef.DiscImages /// /// Magic identifier, 'MComprHD' /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public byte[] tag; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] + public byte[] tag; /// /// Length of header /// @@ -2312,15 +2347,18 @@ namespace DiscImageChef.DiscImages /// /// SHA1 of raw data /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)] public byte[] rawsha1; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)] + public byte[] rawsha1; /// /// SHA1 of raw+meta data /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)] public byte[] sha1; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)] + public byte[] sha1; /// /// SHA1 of parent file /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)] public byte[] parentsha1; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)] + public byte[] parentsha1; } [StructLayout(LayoutKind.Sequential, Pack = 1)] @@ -2365,21 +2403,23 @@ namespace DiscImageChef.DiscImages [StructLayout(LayoutKind.Sequential, Pack = 1)] struct ChdMetadataHeader { - public uint tag; - public uint flagsAndLength; + public uint tag; + public uint flagsAndLength; public ulong next; } [StructLayout(LayoutKind.Sequential, Pack = 1)] struct HunkSector { - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] public ulong[] hunkEntry; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] + public ulong[] hunkEntry; } [StructLayout(LayoutKind.Sequential, Pack = 1)] struct HunkSectorSmall { - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)] public uint[] hunkEntry; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)] + public uint[] hunkEntry; } } } \ No newline at end of file diff --git a/DiscImageChef.DiscImages/CPCDSK.cs b/DiscImageChef.DiscImages/CPCDSK.cs index 0bc93ae8d..1688a6161 100644 --- a/DiscImageChef.DiscImages/CPCDSK.cs +++ b/DiscImageChef.DiscImages/CPCDSK.cs @@ -40,6 +40,7 @@ using DiscImageChef.CommonTypes; using DiscImageChef.Console; using DiscImageChef.Decoders.Floppy; using DiscImageChef.Filters; +using Schemas; namespace DiscImageChef.DiscImages { @@ -72,36 +73,36 @@ namespace DiscImageChef.DiscImages /// /// Identifier for track information, "Track-Info\r\n" /// - readonly byte[] trackId = {0x54, 0x72, 0x61, 0x63, 0x6B, 0x2D, 0x49, 0x6E, 0x66, 0x6F}; + readonly byte[] trackId = {0x54, 0x72, 0x61, 0x63, 0x6B, 0x2D, 0x49, 0x6E, 0x66, 0x6F}; Dictionary addressMarks; - bool extended; - ImageInfo imageInfo; + bool extended; + ImageInfo imageInfo; Dictionary sectors; public Cpcdsk() { imageInfo = new ImageInfo { - ReadableSectorTags = new List(), - ReadableMediaTags = new List(), - HasPartitions = false, - HasSessions = false, - Version = null, - Application = null, - ApplicationVersion = null, - Creator = null, - Comments = null, - MediaManufacturer = null, - MediaModel = null, - MediaSerialNumber = null, - MediaBarcode = null, - MediaPartNumber = null, - MediaSequence = 0, - LastMediaSequence = 0, - DriveManufacturer = null, - DriveModel = null, - DriveSerialNumber = null, + ReadableSectorTags = new List(), + ReadableMediaTags = new List(), + HasPartitions = false, + HasSessions = false, + Version = null, + Application = null, + ApplicationVersion = null, + Creator = null, + Comments = null, + MediaManufacturer = null, + MediaModel = null, + MediaSerialNumber = null, + MediaBarcode = null, + MediaPartNumber = null, + MediaSequence = 0, + LastMediaSequence = 0, + DriveManufacturer = null, + DriveModel = null, + DriveSerialNumber = null, DriveFirmwareRevision = null }; } @@ -109,7 +110,7 @@ namespace DiscImageChef.DiscImages public ImageInfo Info => imageInfo; public string Name => "CPCEMU Disk-File and Extended CPC Disk-File"; - public Guid Id => new Guid("724B16CC-ADB9-492E-BA07-CAEEC1012B16"); + public Guid Id => new Guid("724B16CC-ADB9-492E-BA07-CAEEC1012B16"); public string Format => extended ? "CPCEMU Extended disk image" : "CPCEMU disk image"; @@ -168,8 +169,8 @@ namespace DiscImageChef.DiscImages StringHandlers.CToString(header.magic2)); DicConsole.DebugWriteLine("CPCDSK plugin", "header.creator = \"{0}\"", StringHandlers.CToString(header.creator)); - DicConsole.DebugWriteLine("CPCDSK plugin", "header.tracks = {0}", header.tracks); - DicConsole.DebugWriteLine("CPCDSK plugin", "header.sides = {0}", header.sides); + DicConsole.DebugWriteLine("CPCDSK plugin", "header.tracks = {0}", header.tracks); + DicConsole.DebugWriteLine("CPCDSK plugin", "header.sides = {0}", header.sides); if(!extended) DicConsole.DebugWriteLine("CPCDSK plugin", "header.tracksize = {0}", header.tracksize); else for(int i = 0; i < header.tracks; i++) @@ -179,12 +180,12 @@ namespace DiscImageChef.DiscImages header.tracksizeTable[i * header.sides + j] * 256); } - ulong currentSector = 0; - sectors = new Dictionary(); - addressMarks = new Dictionary(); - ulong readtracks = 0; - bool allTracksSameSize = true; - ulong sectorsPerTrack = 0; + ulong currentSector = 0; + sectors = new Dictionary(); + addressMarks = new Dictionary(); + ulong readtracks = 0; + bool allTracksSameSize = true; + ulong sectorsPerTrack = 0; // Seek to first track descriptor stream.Seek(256, SeekOrigin.Begin); @@ -226,14 +227,16 @@ namespace DiscImageChef.DiscImages trackInfo.recordingMode, i, j); DicConsole.DebugWriteLine("CPCDSK plugin", "trackInfo[{1}:{2}].sectors = {0}", trackInfo.sectors, i, j); - DicConsole.DebugWriteLine("CPCDSK plugin", "trackInfo[{1}:{2}].side = {0}", trackInfo.side, i, j); + DicConsole.DebugWriteLine("CPCDSK plugin", "trackInfo[{1}:{2}].side = {0}", trackInfo.side, i, j); DicConsole.DebugWriteLine("CPCDSK plugin", "trackInfo[{1}:{2}].track = {0}", trackInfo.track, i, j); - if(trackInfo.sectors != sectorsPerTrack) - if(sectorsPerTrack == 0) sectorsPerTrack = trackInfo.sectors; - else allTracksSameSize = false; + if(trackInfo.sectors != sectorsPerTrack) + if(sectorsPerTrack == 0) + sectorsPerTrack = trackInfo.sectors; + else + allTracksSameSize = false; - byte[][] thisTrackSectors = new byte[trackInfo.sectors][]; + byte[][] thisTrackSectors = new byte[trackInfo.sectors][]; byte[][] thisTrackAddressMarks = new byte[trackInfo.sectors][]; for(int k = 1; k <= trackInfo.sectors; k++) @@ -253,10 +256,9 @@ namespace DiscImageChef.DiscImages DicConsole.DebugWriteLine("CPCDSK plugin", "trackInfo[{1}:{2}].sector[{3}].track = {0}", trackInfo.sectorsInfo[k - 1].track, i, j, k); - int sectLen; - sectLen = extended - ? trackInfo.sectorsInfo[k - 1].len - : SizeCodeToBytes(trackInfo.sectorsInfo[k - 1].size); + int sectLen = extended + ? trackInfo.sectorsInfo[k - 1].len + : SizeCodeToBytes(trackInfo.sectorsInfo[k - 1].size); byte[] sector = new byte[sectLen]; stream.Read(sector, 0, sectLen); @@ -277,20 +279,20 @@ namespace DiscImageChef.DiscImages thisTrackSectors[(trackInfo.sectorsInfo[k - 1].id & 0x3F) - 1] = sector; byte[] amForCrc = new byte[8]; - amForCrc[0] = 0xA1; - amForCrc[1] = 0xA1; - amForCrc[2] = 0xA1; - amForCrc[3] = (byte)IBMIdType.AddressMark; - amForCrc[4] = trackInfo.sectorsInfo[k - 1].track; - amForCrc[5] = trackInfo.sectorsInfo[k - 1].side; - amForCrc[6] = trackInfo.sectorsInfo[k - 1].id; - amForCrc[7] = (byte)trackInfo.sectorsInfo[k - 1].size; + amForCrc[0] = 0xA1; + amForCrc[1] = 0xA1; + amForCrc[2] = 0xA1; + amForCrc[3] = (byte)IBMIdType.AddressMark; + amForCrc[4] = trackInfo.sectorsInfo[k - 1].track; + amForCrc[5] = trackInfo.sectorsInfo[k - 1].side; + amForCrc[6] = trackInfo.sectorsInfo[k - 1].id; + amForCrc[7] = (byte)trackInfo.sectorsInfo[k - 1].size; Crc16Context.Data(amForCrc, 8, out byte[] amCrc); byte[] addressMark = new byte[22]; Array.Copy(amForCrc, 0, addressMark, 12, 8); - Array.Copy(amCrc, 0, addressMark, 20, 2); + Array.Copy(amCrc, 0, addressMark, 20, 2); thisTrackAddressMarks[(trackInfo.sectorsInfo[k - 1].id & 0x3F) - 1] = addressMark; } @@ -307,7 +309,8 @@ namespace DiscImageChef.DiscImages stream.Seek(trackPos, SeekOrigin.Begin); if(extended) { - stream.Seek(header.tracksizeTable[i * header.sides + j] * 256, SeekOrigin.Current); + stream.Seek(header.tracksizeTable[i * header.sides + j] * 256, + SeekOrigin.Current); imageInfo.ImageSize += (ulong)(header.tracksizeTable[i * header.sides + j] * 256) - 256; } else @@ -320,17 +323,17 @@ namespace DiscImageChef.DiscImages } } - DicConsole.DebugWriteLine("CPCDSK plugin", "Read {0} sectors", sectors.Count); - DicConsole.DebugWriteLine("CPCDSK plugin", "Read {0} tracks", readtracks); + DicConsole.DebugWriteLine("CPCDSK plugin", "Read {0} sectors", sectors.Count); + DicConsole.DebugWriteLine("CPCDSK plugin", "Read {0} tracks", readtracks); DicConsole.DebugWriteLine("CPCDSK plugin", "All tracks are same size? {0}", allTracksSameSize); - imageInfo.Application = StringHandlers.CToString(header.creator); - imageInfo.CreationTime = imageFilter.GetCreationTime(); + imageInfo.Application = StringHandlers.CToString(header.creator); + imageInfo.CreationTime = imageFilter.GetCreationTime(); imageInfo.LastModificationTime = imageFilter.GetLastWriteTime(); - imageInfo.MediaTitle = Path.GetFileNameWithoutExtension(imageFilter.GetFilename()); - imageInfo.Sectors = (ulong)sectors.Count; - imageInfo.XmlMediaType = XmlMediaType.BlockMedia; - imageInfo.MediaType = MediaType.CompactFloppy; + imageInfo.MediaTitle = 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 @@ -345,29 +348,13 @@ namespace DiscImageChef.DiscImages foo.Close(); */ - imageInfo.Cylinders = header.tracks; - imageInfo.Heads = header.sides; + imageInfo.Cylinders = header.tracks; + imageInfo.Heads = header.sides; imageInfo.SectorsPerTrack = (uint)(imageInfo.Sectors / (imageInfo.Cylinders * imageInfo.Heads)); return true; } - static int SizeCodeToBytes(IBMSectorSizeCode code) - { - switch(code) - { - case IBMSectorSizeCode.EighthKilo: return 128; - case IBMSectorSizeCode.QuarterKilo: return 256; - case IBMSectorSizeCode.HalfKilo: return 512; - case IBMSectorSizeCode.Kilo: return 1024; - case IBMSectorSizeCode.TwiceKilo: return 2048; - case IBMSectorSizeCode.FriceKilo: return 4096; - case IBMSectorSizeCode.TwiceFriceKilo: return 8192; - case IBMSectorSizeCode.FricelyFriceKilo: return 16384; - default: return 0; - } - } - public byte[] ReadSector(ulong sectorAddress) { if(sectors.TryGetValue(sectorAddress, out byte[] sector)) return sector; @@ -494,7 +481,7 @@ namespace DiscImageChef.DiscImages } public bool? VerifySectors(ulong sectorAddress, uint length, out List failingLbas, - out List unknownLbas) + out List unknownLbas) { failingLbas = new List(); unknownLbas = new List(); @@ -504,7 +491,7 @@ namespace DiscImageChef.DiscImages } public bool? VerifySectors(ulong sectorAddress, uint length, uint track, out List failingLbas, - out List unknownLbas) + out List unknownLbas) { throw new FeatureUnsupportedImageException("Feature not supported by image format"); } @@ -514,21 +501,43 @@ namespace DiscImageChef.DiscImages return null; } + public List DumpHardware => null; + public CICMMetadataType CicmMetadata => null; + + static int SizeCodeToBytes(IBMSectorSizeCode code) + { + switch(code) + { + case IBMSectorSizeCode.EighthKilo: return 128; + case IBMSectorSizeCode.QuarterKilo: return 256; + case IBMSectorSizeCode.HalfKilo: return 512; + case IBMSectorSizeCode.Kilo: return 1024; + case IBMSectorSizeCode.TwiceKilo: return 2048; + case IBMSectorSizeCode.FriceKilo: return 4096; + case IBMSectorSizeCode.TwiceFriceKilo: return 8192; + case IBMSectorSizeCode.FricelyFriceKilo: return 16384; + default: return 0; + } + } + [StructLayout(LayoutKind.Sequential, Pack = 1)] struct CpcDiskInfo { /// /// Magic number, "MV - CPCEMU Disk-File" in old files, "EXTENDED CPC DSK File" in extended ones /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 21)] public byte[] magic; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 21)] + public byte[] magic; /// /// Second part of magic, should be "\r\nDisk-Info\r\n" in all, but some emulators write spaces instead. /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 13)] public byte[] magic2; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 13)] + public byte[] magic2; /// /// Creator application (can be null) /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 14)] public byte[] creator; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 14)] + public byte[] creator; /// /// Tracks /// @@ -545,7 +554,8 @@ namespace DiscImageChef.DiscImages /// /// Size of each track in the extended format. 0 indicates track is not formatted and not present in image. /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 204)] public byte[] tracksizeTable; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 204)] + public byte[] tracksizeTable; } [StructLayout(LayoutKind.Sequential, Pack = 1)] @@ -554,8 +564,10 @@ namespace DiscImageChef.DiscImages /// /// Magic number, "Track-Info\r\n" /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)] public byte[] magic; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public byte[] carriageReturn; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)] + public byte[] magic; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] + public byte[] carriageReturn; /// /// Padding /// @@ -595,7 +607,8 @@ namespace DiscImageChef.DiscImages /// /// Informatino for up to 32 sectors /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public CpcSectorInfo[] sectorsInfo; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] + public CpcSectorInfo[] sectorsInfo; } /// diff --git a/DiscImageChef.DiscImages/CisCopy.cs b/DiscImageChef.DiscImages/CisCopy.cs index aef56128d..1402d8be0 100644 --- a/DiscImageChef.DiscImages/CisCopy.cs +++ b/DiscImageChef.DiscImages/CisCopy.cs @@ -38,6 +38,7 @@ using System.Linq; using DiscImageChef.CommonTypes; using DiscImageChef.Console; using DiscImageChef.Filters; +using Schemas; namespace DiscImageChef.DiscImages { @@ -351,6 +352,9 @@ namespace DiscImageChef.DiscImages return null; } + public List DumpHardware => null; + public CICMMetadataType CicmMetadata => null; + public byte[] ReadSector(ulong sectorAddress) { return ReadSectors(sectorAddress, 1); @@ -659,6 +663,18 @@ namespace DiscImageChef.DiscImages return false; } + public bool SetDumpHardware(List dumpHardware) + { + // Not supported + return false; + } + + public bool SetCicmMetadata(CICMMetadataType metadata) + { + // Not supported + return false; + } + [SuppressMessage("ReSharper", "InconsistentNaming")] enum DiskType : byte { diff --git a/DiscImageChef.DiscImages/CloneCD.cs b/DiscImageChef.DiscImages/CloneCD.cs index 42f50e887..7d201025f 100644 --- a/DiscImageChef.DiscImages/CloneCD.cs +++ b/DiscImageChef.DiscImages/CloneCD.cs @@ -41,6 +41,7 @@ using DiscImageChef.CommonTypes; using DiscImageChef.Console; using DiscImageChef.Decoders.CD; using DiscImageChef.Filters; +using Schemas; namespace DiscImageChef.DiscImages { @@ -1376,6 +1377,9 @@ namespace DiscImageChef.DiscImages return null; } + public List DumpHardware => null; + public CICMMetadataType CicmMetadata => null; + public IEnumerable SupportedMediaTags => new[] {MediaTagType.CD_MCN, MediaTagType.CD_FullTOC}; public IEnumerable SupportedSectorTags => new[] @@ -1938,6 +1942,18 @@ namespace DiscImageChef.DiscImages } } + public bool SetDumpHardware(List dumpHardware) + { + // Not supported + return false; + } + + public bool SetCicmMetadata(CICMMetadataType metadata) + { + // Not supported + return false; + } + static ulong GetLba(int hour, int minute, int second, int frame) { return (ulong)(hour * 60 * 60 * 75 + minute * 60 * 75 + second * 75 + frame - 150); diff --git a/DiscImageChef.DiscImages/CopyQM.cs b/DiscImageChef.DiscImages/CopyQM.cs index 12fbcad53..e946a5771 100644 --- a/DiscImageChef.DiscImages/CopyQM.cs +++ b/DiscImageChef.DiscImages/CopyQM.cs @@ -37,6 +37,7 @@ using System.Runtime.InteropServices; using DiscImageChef.CommonTypes; using DiscImageChef.Console; using DiscImageChef.Filters; +using Schemas; namespace DiscImageChef.DiscImages { @@ -268,13 +269,13 @@ namespace DiscImageChef.DiscImages imageInfo.MediaType = Geometry.GetMediaType(((ushort)header.totalCylinders, (byte)header.heads, header.sectorsPerTrack, (uint)header.sectorSize, MediaEncoding.MFM, false)); - + switch(imageInfo.MediaType) { - case MediaType.NEC_525_HD when header.drive == COPYQM_35_HD ||header.drive == COPYQM_35_ED: + case MediaType.NEC_525_HD when header.drive == COPYQM_35_HD || header.drive == COPYQM_35_ED: imageInfo.MediaType = MediaType.NEC_35_HD_8; break; - case MediaType.DOS_525_HD when header.drive == COPYQM_35_HD ||header.drive == COPYQM_35_ED: + case MediaType.DOS_525_HD when header.drive == COPYQM_35_HD || header.drive == COPYQM_35_ED: imageInfo.MediaType = MediaType.NEC_35_HD_15; break; case MediaType.RX50 when header.drive == COPYQM_525_DD || header.drive == COPYQM_525_HD: @@ -335,6 +336,9 @@ namespace DiscImageChef.DiscImages return calculatedDataCrc == header.crc && headerChecksumOk; } + public List DumpHardware => null; + public CICMMetadataType CicmMetadata => null; + public byte[] ReadSector(ulong sectorAddress) { return ReadSectors(sectorAddress, 1); diff --git a/DiscImageChef.DiscImages/D88.cs b/DiscImageChef.DiscImages/D88.cs index 250a87877..05462cae4 100644 --- a/DiscImageChef.DiscImages/D88.cs +++ b/DiscImageChef.DiscImages/D88.cs @@ -40,6 +40,7 @@ using DiscImageChef.CommonTypes; using DiscImageChef.Console; using DiscImageChef.Decoders.Floppy; using DiscImageChef.Filters; +using Schemas; namespace DiscImageChef.DiscImages { @@ -537,6 +538,9 @@ namespace DiscImageChef.DiscImages return null; } + public List DumpHardware => null; + public CICMMetadataType CicmMetadata => null; + enum DiskType : byte { D2 = 0x00, diff --git a/DiscImageChef.DiscImages/DART.cs b/DiscImageChef.DiscImages/DART.cs index cf8f8c6ff..f22e57ea6 100644 --- a/DiscImageChef.DiscImages/DART.cs +++ b/DiscImageChef.DiscImages/DART.cs @@ -41,6 +41,7 @@ using DiscImageChef.CommonTypes; using DiscImageChef.Compression; using DiscImageChef.Console; using DiscImageChef.Filters; +using Schemas; using Version = Resources.Version; namespace DiscImageChef.DiscImages @@ -572,6 +573,9 @@ namespace DiscImageChef.DiscImages return null; } + public List DumpHardware => null; + public CICMMetadataType CicmMetadata => null; + [StructLayout(LayoutKind.Sequential, Pack = 1)] struct DartHeader { diff --git a/DiscImageChef.DiscImages/DIM.cs b/DiscImageChef.DiscImages/DIM.cs index 9b4bc7bfb..99d32ac38 100644 --- a/DiscImageChef.DiscImages/DIM.cs +++ b/DiscImageChef.DiscImages/DIM.cs @@ -38,6 +38,7 @@ using System.Text; using DiscImageChef.CommonTypes; using DiscImageChef.Console; using DiscImageChef.Filters; +using Schemas; namespace DiscImageChef.DiscImages { @@ -48,42 +49,42 @@ namespace DiscImageChef.DiscImages const uint DATA_OFFSET = 0x100; readonly byte[] headerId = {0x44, 0x49, 0x46, 0x43, 0x20, 0x48, 0x45, 0x41, 0x44, 0x45, 0x52, 0x20, 0x20}; - byte[] comment; + byte[] comment; /// Disk image file - IFilter dimImageFilter; - DiskType dskType; - byte[] hdrId; + IFilter dimImageFilter; + DiskType dskType; + byte[] hdrId; ImageInfo imageInfo; public Dim() { imageInfo = new ImageInfo { - ReadableSectorTags = new List(), - ReadableMediaTags = new List(), - HasPartitions = false, - HasSessions = false, - Version = null, - Application = null, - ApplicationVersion = null, - Creator = null, - Comments = null, - MediaManufacturer = null, - MediaModel = null, - MediaSerialNumber = null, - MediaBarcode = null, - MediaPartNumber = null, - MediaSequence = 0, - LastMediaSequence = 0, - DriveManufacturer = null, - DriveModel = null, - DriveSerialNumber = null, + ReadableSectorTags = new List(), + ReadableMediaTags = new List(), + HasPartitions = false, + HasSessions = false, + Version = null, + Application = null, + ApplicationVersion = null, + Creator = null, + Comments = null, + MediaManufacturer = null, + MediaModel = null, + MediaSerialNumber = null, + MediaBarcode = null, + MediaPartNumber = null, + MediaSequence = 0, + LastMediaSequence = 0, + DriveManufacturer = null, + DriveModel = null, + DriveSerialNumber = null, DriveFirmwareRevision = null }; } - public string Name => "DIM Disk Image"; - public Guid Id => new Guid("0240B7B1-E959-4CDC-B0BD-386D6E467B88"); + public string Name => "DIM Disk Image"; + public Guid Id => new Guid("0240B7B1-E959-4CDC-B0BD-386D6E467B88"); public ImageInfo Info => imageInfo; public string Format => "DIM disk image"; @@ -105,7 +106,7 @@ namespace DiscImageChef.DiscImages if(stream.Length < DATA_OFFSET) return false; comment = new byte[60]; - hdrId = new byte[13]; + hdrId = new byte[13]; stream.Seek(0, SeekOrigin.Begin); dskType = (DiskType)stream.ReadByte(); stream.Seek(0xAB, SeekOrigin.Begin); @@ -126,7 +127,7 @@ namespace DiscImageChef.DiscImages long diskSize = stream.Length - DATA_OFFSET; comment = new byte[60]; - hdrId = new byte[13]; + hdrId = new byte[13]; stream.Seek(0, SeekOrigin.Begin); dskType = (DiskType)stream.ReadByte(); stream.Seek(0xAB, SeekOrigin.Begin); @@ -149,7 +150,7 @@ namespace DiscImageChef.DiscImages } if(diskSize / (2 * 8 * 1024) == 77) imageInfo.MediaType = MediaType.SHARP_525; - imageInfo.SectorSize = 1024; + imageInfo.SectorSize = 1024; break; // 9 spt, 1024 bps case DiskType.Hs2: @@ -160,7 +161,7 @@ namespace DiscImageChef.DiscImages } if(diskSize / (2 * 9 * 512) == 80) imageInfo.MediaType = MediaType.SHARP_525_9; - imageInfo.SectorSize = 512; + imageInfo.SectorSize = 512; break; // 15 spt, 512 bps case DiskType.Hc2: @@ -171,7 +172,7 @@ namespace DiscImageChef.DiscImages } if(diskSize / (2 * 15 * 512) == 80) imageInfo.MediaType = MediaType.DOS_525_HD; - imageInfo.SectorSize = 512; + imageInfo.SectorSize = 512; break; // 9 spt, 1024 bps case DiskType.Hde2: @@ -182,7 +183,7 @@ namespace DiscImageChef.DiscImages } if(diskSize / (2 * 9 * 512) == 80) imageInfo.MediaType = MediaType.SHARP_35_9; - imageInfo.SectorSize = 512; + imageInfo.SectorSize = 512; break; // 18 spt, 512 bps case DiskType.Hq2: @@ -193,19 +194,19 @@ namespace DiscImageChef.DiscImages } if(diskSize / (2 * 18 * 512) == 80) imageInfo.MediaType = MediaType.DOS_35_HD; - imageInfo.SectorSize = 512; + imageInfo.SectorSize = 512; break; // 26 spt, 256 bps case DiskType.N88: if(diskSize % (2 * 26 * 256) == 0) { if(diskSize % (2 * 26 * 256) == 77) imageInfo.MediaType = MediaType.NEC_8_DD; - imageInfo.SectorSize = 256; + imageInfo.SectorSize = 256; } else if(diskSize % (2 * 26 * 128) == 0) { if(diskSize % (2 * 26 * 128) == 77) imageInfo.MediaType = MediaType.NEC_8_SD; - imageInfo.SectorSize = 256; + imageInfo.SectorSize = 256; } else { @@ -223,45 +224,45 @@ namespace DiscImageChef.DiscImages dimImageFilter = imageFilter; - imageInfo.ImageSize = (ulong)diskSize; - imageInfo.CreationTime = imageFilter.GetCreationTime(); + imageInfo.ImageSize = (ulong)diskSize; + imageInfo.CreationTime = imageFilter.GetCreationTime(); imageInfo.LastModificationTime = imageFilter.GetLastWriteTime(); - imageInfo.MediaTitle = Path.GetFileNameWithoutExtension(imageFilter.GetFilename()); - imageInfo.Sectors = imageInfo.ImageSize / imageInfo.SectorSize; - imageInfo.Comments = StringHandlers.CToString(comment, Encoding.GetEncoding(932)); - imageInfo.XmlMediaType = XmlMediaType.BlockMedia; + imageInfo.MediaTitle = Path.GetFileNameWithoutExtension(imageFilter.GetFilename()); + imageInfo.Sectors = imageInfo.ImageSize / imageInfo.SectorSize; + imageInfo.Comments = StringHandlers.CToString(comment, Encoding.GetEncoding(932)); + imageInfo.XmlMediaType = XmlMediaType.BlockMedia; switch(imageInfo.MediaType) { case MediaType.SHARP_525: - imageInfo.Cylinders = 77; - imageInfo.Heads = 2; + imageInfo.Cylinders = 77; + imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 8; break; case MediaType.SHARP_525_9: - imageInfo.Cylinders = 80; - imageInfo.Heads = 2; + imageInfo.Cylinders = 80; + imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 9; break; case MediaType.DOS_525_HD: - imageInfo.Cylinders = 80; - imageInfo.Heads = 2; + imageInfo.Cylinders = 80; + imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 15; break; case MediaType.SHARP_35_9: - imageInfo.Cylinders = 80; - imageInfo.Heads = 2; + imageInfo.Cylinders = 80; + imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 9; break; case MediaType.DOS_35_HD: - imageInfo.Cylinders = 80; - imageInfo.Heads = 2; + imageInfo.Cylinders = 80; + imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 18; break; case MediaType.NEC_8_DD: case MediaType.NEC_8_SD: - imageInfo.Cylinders = 77; - imageInfo.Heads = 2; + imageInfo.Cylinders = 77; + imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 26; break; } @@ -369,7 +370,7 @@ namespace DiscImageChef.DiscImages } public bool? VerifySectors(ulong sectorAddress, uint length, out List failingLbas, - out List unknownLbas) + out List unknownLbas) { failingLbas = new List(); unknownLbas = new List(); @@ -379,7 +380,7 @@ namespace DiscImageChef.DiscImages } public bool? VerifySectors(ulong sectorAddress, uint length, uint track, out List failingLbas, - out List unknownLbas) + out List unknownLbas) { throw new FeatureUnsupportedImageException("Feature not supported by image format"); } @@ -389,14 +390,17 @@ namespace DiscImageChef.DiscImages return null; } + public List DumpHardware => null; + public CICMMetadataType CicmMetadata => null; + enum DiskType : byte { - Hd2 = 0, - Hs2 = 1, - Hc2 = 2, + Hd2 = 0, + Hs2 = 1, + Hc2 = 2, Hde2 = 3, - Hq2 = 9, - N88 = 17 + Hq2 = 9, + N88 = 17 } } } \ No newline at end of file diff --git a/DiscImageChef.DiscImages/DiscFerret.cs b/DiscImageChef.DiscImages/DiscFerret.cs index 3748f3798..2f43da519 100644 --- a/DiscImageChef.DiscImages/DiscFerret.cs +++ b/DiscImageChef.DiscImages/DiscFerret.cs @@ -37,6 +37,7 @@ using System.Runtime.InteropServices; using DiscImageChef.CommonTypes; using DiscImageChef.Console; using DiscImageChef.Filters; +using Schemas; namespace DiscImageChef.DiscImages { @@ -50,7 +51,7 @@ namespace DiscImageChef.DiscImages /// "DFE2" /// const uint DFI_MAGIC2 = 0x32454644; - ImageInfo imageInfo; + ImageInfo imageInfo; // TODO: These variables have been made public so create-sidecar can access to this information until I define an API >4.0 public SortedDictionary TrackLengths; public SortedDictionary TrackOffsets; @@ -59,31 +60,31 @@ namespace DiscImageChef.DiscImages { imageInfo = new ImageInfo { - ReadableSectorTags = new List(), - ReadableMediaTags = new List(), - HasPartitions = false, - HasSessions = false, - Version = null, - Application = null, - ApplicationVersion = null, - Creator = null, - Comments = null, - MediaManufacturer = null, - MediaModel = null, - MediaSerialNumber = null, - MediaBarcode = null, - MediaPartNumber = null, - MediaSequence = 0, - LastMediaSequence = 0, - DriveManufacturer = null, - DriveModel = null, - DriveSerialNumber = null, + ReadableSectorTags = new List(), + ReadableMediaTags = new List(), + HasPartitions = false, + HasSessions = false, + Version = null, + Application = null, + ApplicationVersion = null, + Creator = null, + Comments = null, + MediaManufacturer = null, + MediaModel = null, + MediaSerialNumber = null, + MediaBarcode = null, + MediaPartNumber = null, + MediaSequence = 0, + LastMediaSequence = 0, + DriveManufacturer = null, + DriveModel = null, + DriveSerialNumber = null, DriveFirmwareRevision = null }; } - public string Name => "DiscFerret"; - public Guid Id => new Guid("70EA7B9B-5323-42EB-9B40-8DDA37C5EB4D"); + public string Name => "DiscFerret"; + public Guid Id => new Guid("70EA7B9B-5323-42EB-9B40-8DDA37C5EB4D"); public ImageInfo Info => imageInfo; public string Format => "DiscFerret"; @@ -116,18 +117,18 @@ namespace DiscImageChef.DiscImages if(magic != DFI_MAGIC && magic != DFI_MAGIC2) return false; - TrackOffsets = new SortedDictionary(); - TrackLengths = new SortedDictionary(); - int t = -1; + TrackOffsets = new SortedDictionary(); + TrackLengths = new SortedDictionary(); + int t = -1; ushort lastCylinder = 0, lastHead = 0; - long offset = 0; + long offset = 0; while(stream.Position < stream.Length) { long thisOffset = stream.Position; DfiBlockHeader blockHeader = new DfiBlockHeader(); - byte[] blk = new byte[Marshal.SizeOf(blockHeader)]; + byte[] blk = new byte[Marshal.SizeOf(blockHeader)]; stream.Read(blk, 0, Marshal.SizeOf(blockHeader)); blockHeader = BigEndianMarshal.ByteArrayToStructureBigEndian(blk); @@ -150,7 +151,7 @@ namespace DiscImageChef.DiscImages if(blockHeader.cylinder > 0 && blockHeader.cylinder > lastCylinder) { lastCylinder = blockHeader.cylinder; - lastHead = 0; + lastHead = 0; TrackOffsets.Add(t, offset); TrackLengths.Add(t, thisOffset - offset + 1); offset = thisOffset; @@ -166,13 +167,13 @@ namespace DiscImageChef.DiscImages } if(blockHeader.cylinder > imageInfo.Cylinders) imageInfo.Cylinders = blockHeader.cylinder; - if(blockHeader.head > imageInfo.Heads) imageInfo.Heads = blockHeader.head; + if(blockHeader.head > imageInfo.Heads) imageInfo.Heads = blockHeader.head; } imageInfo.Heads++; imageInfo.Cylinders++; - imageInfo.Application = "DiscFerret"; + imageInfo.Application = "DiscFerret"; imageInfo.ApplicationVersion = magic == DFI_MAGIC2 ? "2.0" : "1.0"; throw new NotImplementedException("Flux decoding is not yet implemented."); @@ -224,7 +225,7 @@ namespace DiscImageChef.DiscImages } public bool? VerifySectors(ulong sectorAddress, uint length, out List failingLbas, - out List unknownLbas) + out List unknownLbas) { throw new NotImplementedException("Flux decoding is not yet implemented."); } @@ -270,7 +271,7 @@ namespace DiscImageChef.DiscImages } public bool? VerifySectors(ulong sectorAddress, uint length, uint track, out List failingLbas, - out List unknownLbas) + out List unknownLbas) { throw new FeatureUnsupportedImageException("Feature not supported by image format"); } @@ -280,13 +281,16 @@ namespace DiscImageChef.DiscImages throw new FeatureUnsupportedImageException("Feature not supported by image format"); } + public List DumpHardware => null; + public CICMMetadataType CicmMetadata => null; + [StructLayout(LayoutKind.Sequential, Pack = 1)] struct DfiBlockHeader { public ushort cylinder; public ushort head; public ushort sector; - public uint length; + public uint length; } } } \ No newline at end of file diff --git a/DiscImageChef.DiscImages/DiscImageChef.DiscImages.csproj b/DiscImageChef.DiscImages/DiscImageChef.DiscImages.csproj index bc9fa9990..1d2fd9148 100644 --- a/DiscImageChef.DiscImages/DiscImageChef.DiscImages.csproj +++ b/DiscImageChef.DiscImages/DiscImageChef.DiscImages.csproj @@ -146,6 +146,10 @@ {9183f2e0-a879-4f23-9ee3-c6908f1332b2} DiscImageChef.Interop + + {9F213318-5CB8-4066-A757-074489C9F818} + DiscImageChef.Metadata + diff --git a/DiscImageChef.DiscImages/DiscImageChef.cs b/DiscImageChef.DiscImages/DiscImageChef.cs index 2ba0e988f..257be90d5 100644 --- a/DiscImageChef.DiscImages/DiscImageChef.cs +++ b/DiscImageChef.DiscImages/DiscImageChef.cs @@ -85,6 +85,7 @@ using DiscImageChef.Decoders.ATA; using DiscImageChef.Decoders.SCSI; using DiscImageChef.Decoders.SecureDigital; using DiscImageChef.Filters; +using Schemas; using SharpCompress.Compressors.LZMA; using VendorString = DiscImageChef.Decoders.SecureDigital.VendorString; @@ -1692,6 +1693,9 @@ namespace DiscImageChef.DiscImages return true; } + public List DumpHardware { get; private set; } + public CICMMetadataType CicmMetadata { get; private set; } + public IEnumerable SupportedMediaTags => Enum.GetValues(typeof(MediaTagType)).Cast(); public IEnumerable SupportedSectorTags => @@ -3471,6 +3475,18 @@ namespace DiscImageChef.DiscImages } } + public bool SetDumpHardware(List dumpHardware) + { + // TODO: Implement + return false; + } + + public bool SetCicmMetadata(CICMMetadataType metadata) + { + // TODO: Implement + return false; + } + /// /// Checks for media tags that may contain metadata and sets it up if not already set /// diff --git a/DiscImageChef.DiscImages/DiscJuggler.cs b/DiscImageChef.DiscImages/DiscJuggler.cs index 833bccf0d..54b537d4c 100644 --- a/DiscImageChef.DiscImages/DiscJuggler.cs +++ b/DiscImageChef.DiscImages/DiscJuggler.cs @@ -39,6 +39,7 @@ using DiscImageChef.Checksums; using DiscImageChef.CommonTypes; using DiscImageChef.Console; using DiscImageChef.Filters; +using Schemas; namespace DiscImageChef.DiscImages { @@ -46,50 +47,47 @@ namespace DiscImageChef.DiscImages // TODO: Too many unknowns to make this writable public class DiscJuggler : IMediaImage { - byte[] cdtext; - ImageInfo imageInfo; - Stream imageStream; + byte[] cdtext; + ImageInfo imageInfo; + Stream imageStream; Dictionary offsetmap; - List partitions; - List sessions; - Dictionary trackFlags; - List tracks; + Dictionary trackFlags; public DiscJuggler() { imageInfo = new ImageInfo { - ReadableSectorTags = new List(), - ReadableMediaTags = new List(), - HasPartitions = true, - HasSessions = true, - Version = null, - ApplicationVersion = null, - MediaTitle = null, - Creator = null, - MediaManufacturer = null, - MediaModel = null, - MediaPartNumber = null, - MediaSequence = 0, - LastMediaSequence = 0, - DriveManufacturer = null, - DriveModel = null, - DriveSerialNumber = null, + ReadableSectorTags = new List(), + ReadableMediaTags = new List(), + HasPartitions = true, + HasSessions = true, + Version = null, + ApplicationVersion = null, + MediaTitle = null, + Creator = null, + MediaManufacturer = null, + MediaModel = null, + MediaPartNumber = null, + MediaSequence = 0, + LastMediaSequence = 0, + DriveManufacturer = null, + DriveModel = null, + DriveSerialNumber = null, DriveFirmwareRevision = null }; } - public string Name => "DiscJuggler"; - public Guid Id => new Guid("2444DBC6-CD35-424C-A227-39B0C4DB01B2"); + public string Name => "DiscJuggler"; + public Guid Id => new Guid("2444DBC6-CD35-424C-A227-39B0C4DB01B2"); public ImageInfo Info => imageInfo; public string Format => "DiscJuggler"; - public List Partitions => partitions; + public List Partitions { get; set; } - public List Tracks => tracks; + public List Tracks { get; set; } - public List Sessions => sessions; + public List Sessions { get; set; } public bool Identify(IFilter imageFilter) { @@ -112,8 +110,8 @@ namespace DiscImageChef.DiscImages if(descriptor[0] > 99 || descriptor[0] == 0) return false; // Seems all sessions start with this data - if(descriptor[1] != 0x00 || descriptor[3] != 0x00 || descriptor[4] != 0x00 || descriptor[5] != 0x00 || - descriptor[6] != 0x00 || descriptor[7] != 0x00 || descriptor[8] != 0x00 || descriptor[9] != 0x00 || + if(descriptor[1] != 0x00 || descriptor[3] != 0x00 || descriptor[4] != 0x00 || descriptor[5] != 0x00 || + descriptor[6] != 0x00 || descriptor[7] != 0x00 || descriptor[8] != 0x00 || descriptor[9] != 0x00 || descriptor[10] != 0x01 || descriptor[11] != 0x00 || descriptor[12] != 0x00 || descriptor[13] != 0x00 || descriptor[14] != 0xFF || descriptor[15] != 0xFF) return false; @@ -142,17 +140,17 @@ namespace DiscImageChef.DiscImages int position = 1; ushort sessionSequence = 0; - sessions = new List(); - tracks = new List(); - partitions = new List(); - offsetmap = new Dictionary(); - trackFlags = new Dictionary(); + Sessions = new List(); + Tracks = new List(); + Partitions = new List(); + offsetmap = new Dictionary(); + trackFlags = new Dictionary(); ushort mediumType; - byte maxS = descriptor[0]; + byte maxS = descriptor[0]; DicConsole.DebugWriteLine("DiscJuggler plugin", "maxS = {0}", maxS); - uint lastSessionTrack = 0; - ulong currentOffset = 0; + uint lastSessionTrack = 0; + ulong currentOffset = 0; // Read sessions for(byte s = 0; s <= maxS; s++) @@ -160,11 +158,11 @@ namespace DiscImageChef.DiscImages DicConsole.DebugWriteLine("DiscJuggler plugin", "s = {0}", s); // Seems all sessions start with this data - if(descriptor[position + 0] != 0x00 || descriptor[position + 2] != 0x00 || - descriptor[position + 3] != 0x00 || descriptor[position + 4] != 0x00 || - descriptor[position + 5] != 0x00 || descriptor[position + 6] != 0x00 || - descriptor[position + 7] != 0x00 || descriptor[position + 8] != 0x00 || - descriptor[position + 9] != 0x01 || descriptor[position + 10] != 0x00 || + if(descriptor[position + 0] != 0x00 || descriptor[position + 2] != 0x00 || + descriptor[position + 3] != 0x00 || descriptor[position + 4] != 0x00 || + descriptor[position + 5] != 0x00 || descriptor[position + 6] != 0x00 || + descriptor[position + 7] != 0x00 || descriptor[position + 8] != 0x00 || + descriptor[position + 9] != 0x01 || descriptor[position + 10] != 0x00 || descriptor[position + 11] != 0x00 || descriptor[position + 12] != 0x00 || descriptor[position + 13] != 0xFF || descriptor[position + 14] != 0xFF) return false; @@ -178,11 +176,11 @@ namespace DiscImageChef.DiscImages Session session = new Session { SessionSequence = sessionSequence, - EndTrack = uint.MinValue, - StartTrack = uint.MaxValue + EndTrack = uint.MinValue, + StartTrack = uint.MaxValue }; - position += 15; + position += 15; bool addedATrack = false; // Read track @@ -197,21 +195,21 @@ namespace DiscImageChef.DiscImages byte[] trackFilenameB = new byte[descriptor[position]]; position++; Array.Copy(descriptor, position, trackFilenameB, 0, trackFilenameB.Length); - position += trackFilenameB.Length; - track.TrackFile = Path.GetFileName(Encoding.Default.GetString(trackFilenameB)); + position += trackFilenameB.Length; + track.TrackFile = Path.GetFileName(Encoding.Default.GetString(trackFilenameB)); DicConsole.DebugWriteLine("DiscJuggler plugin", "\tfilename = {0}", track.TrackFile); // Skip unknown position += 29; - mediumType = BitConverter.ToUInt16(descriptor, position); - position += 2; + mediumType = BitConverter.ToUInt16(descriptor, position); + position += 2; DicConsole.DebugWriteLine("DiscJuggler plugin", "\tmediumType = {0}", mediumType); // Read indices track.Indexes = new Dictionary(); - ushort maxI = BitConverter.ToUInt16(descriptor, position); - position += 2; + ushort maxI = BitConverter.ToUInt16(descriptor, position); + position += 2; DicConsole.DebugWriteLine("DiscJuggler plugin", "\tmaxI = {0}", maxI); for(ushort i = 0; i < maxI; i++) { @@ -223,7 +221,7 @@ namespace DiscImageChef.DiscImages // Read CD-Text uint maxC = BitConverter.ToUInt32(descriptor, position); - position += 4; + position += 4; DicConsole.DebugWriteLine("DiscJuggler plugin", "\tmaxC = {0}", maxC); for(uint c = 0; c < maxC; c++) { @@ -246,7 +244,7 @@ namespace DiscImageChef.DiscImages } } - position += 2; + position += 2; uint trackMode = BitConverter.ToUInt32(descriptor, position); DicConsole.DebugWriteLine("DiscJuggler plugin", "\ttrackMode = {0}", trackMode); position += 4; @@ -255,30 +253,31 @@ namespace DiscImageChef.DiscImages position += 4; session.SessionSequence = (ushort)(BitConverter.ToUInt32(descriptor, position) + 1); - track.TrackSession = (ushort)(session.SessionSequence + 1); + track.TrackSession = (ushort)(session.SessionSequence + 1); DicConsole.DebugWriteLine("DiscJuggler plugin", "\tsession = {0}", session.SessionSequence); - position += 4; - track.TrackSequence = BitConverter.ToUInt32(descriptor, position) + lastSessionTrack + 1; + position += 4; + track.TrackSequence = BitConverter.ToUInt32(descriptor, position) + lastSessionTrack + 1; DicConsole.DebugWriteLine("DiscJuggler plugin", "\ttrack = {1} + {2} + 1 = {0}", track.TrackSequence, BitConverter.ToUInt32(descriptor, position), lastSessionTrack); - position += 4; - track.TrackStartSector = BitConverter.ToUInt32(descriptor, position); + position += 4; + track.TrackStartSector = BitConverter.ToUInt32(descriptor, position); DicConsole.DebugWriteLine("DiscJuggler plugin", "\ttrackStart = {0}", track.TrackStartSector); - position += 4; - uint trackLen = BitConverter.ToUInt32(descriptor, position); + position += 4; + uint trackLen = BitConverter.ToUInt32(descriptor, position); track.TrackEndSector = track.TrackStartSector + trackLen - 1; DicConsole.DebugWriteLine("DiscJuggler plugin", "\ttrackEnd = {0}", track.TrackEndSector); position += 4; if(track.TrackSequence > session.EndTrack) { - session.EndTrack = track.TrackSequence; + session.EndTrack = track.TrackSequence; session.EndSector = track.TrackEndSector; } + if(track.TrackSequence < session.StartTrack) { - session.StartTrack = track.TrackSequence; + session.StartTrack = track.TrackSequence; session.StartSector = track.TrackStartSector; } @@ -287,7 +286,7 @@ namespace DiscImageChef.DiscImages uint readMode = BitConverter.ToUInt32(descriptor, position); DicConsole.DebugWriteLine("DiscJuggler plugin", "\treadMode = {0}", readMode); - position += 4; + position += 4; uint trackCtl = BitConverter.ToUInt32(descriptor, position); DicConsole.DebugWriteLine("DiscJuggler plugin", "\ttrackCtl = {0}", trackCtl); position += 4; @@ -298,7 +297,7 @@ namespace DiscImageChef.DiscImages byte[] isrc = new byte[12]; Array.Copy(descriptor, position, isrc, 0, 12); DicConsole.DebugWriteLine("DiscJuggler plugin", "\tisrc = {0}", StringHandlers.CToString(isrc)); - position += 12; + position += 12; uint isrcValid = BitConverter.ToUInt32(descriptor, position); DicConsole.DebugWriteLine("DiscJuggler plugin", "\tisrc_valid = {0}", isrcValid); position += 4; @@ -331,31 +330,33 @@ namespace DiscImageChef.DiscImages // Audio case 0: if(imageInfo.SectorSize < 2352) imageInfo.SectorSize = 2352; - track.TrackType = TrackType.Audio; - track.TrackBytesPerSector = 2352; - track.TrackRawBytesPerSector = 2352; + track.TrackType = TrackType.Audio; + track.TrackBytesPerSector = 2352; + track.TrackRawBytesPerSector = 2352; switch(readMode) { case 2: if(firstTrack) currentOffset += 150 * (ulong)track.TrackRawBytesPerSector; - track.TrackFileOffset = currentOffset; - currentOffset += trackLen * (ulong)track.TrackRawBytesPerSector; + track.TrackFileOffset = currentOffset; + currentOffset += trackLen * (ulong)track.TrackRawBytesPerSector; break; case 3: if(firstTrack) currentOffset += 150 * (ulong)(track.TrackRawBytesPerSector + 16); - track.TrackFileOffset = currentOffset; - track.TrackSubchannelFile = track.TrackFile; - track.TrackSubchannelOffset = currentOffset; - track.TrackSubchannelType = TrackSubchannelType.Q16Interleaved; - currentOffset += trackLen * (ulong)(track.TrackRawBytesPerSector + 16); + track.TrackFileOffset = currentOffset; + track.TrackSubchannelFile = track.TrackFile; + track.TrackSubchannelOffset = currentOffset; + track.TrackSubchannelType = TrackSubchannelType.Q16Interleaved; + currentOffset += + trackLen * (ulong)(track.TrackRawBytesPerSector + 16); break; case 4: if(firstTrack) currentOffset += 150 * (ulong)(track.TrackRawBytesPerSector + 96); - track.TrackFileOffset = currentOffset; - track.TrackSubchannelFile = track.TrackFile; - track.TrackSubchannelOffset = currentOffset; - track.TrackSubchannelType = TrackSubchannelType.RawInterleaved; - currentOffset += trackLen * (ulong)(track.TrackRawBytesPerSector + 96); + track.TrackFileOffset = currentOffset; + track.TrackSubchannelFile = track.TrackFile; + track.TrackSubchannelOffset = currentOffset; + track.TrackSubchannelType = TrackSubchannelType.RawInterleaved; + currentOffset += + trackLen * (ulong)(track.TrackRawBytesPerSector + 96); break; default: throw new ImageNotSupportedException($"Unknown read mode {readMode}"); } @@ -364,22 +365,22 @@ namespace DiscImageChef.DiscImages // Mode 1 or DVD case 1: if(imageInfo.SectorSize < 2048) imageInfo.SectorSize = 2048; - track.TrackType = TrackType.CdMode1; - track.TrackBytesPerSector = 2048; + track.TrackType = TrackType.CdMode1; + track.TrackBytesPerSector = 2048; switch(readMode) { case 0: - track.TrackRawBytesPerSector = 2048; + track.TrackRawBytesPerSector = 2048; if(firstTrack) currentOffset += 150 * (ulong)track.TrackRawBytesPerSector; - track.TrackFileOffset = currentOffset; - currentOffset += trackLen * (ulong)track.TrackRawBytesPerSector; + track.TrackFileOffset = currentOffset; + currentOffset += trackLen * (ulong)track.TrackRawBytesPerSector; break; case 1: throw new ImageNotSupportedException($"Invalid read mode {readMode} for this track"); case 2: - track.TrackRawBytesPerSector = 2352; - currentOffset += trackLen * (ulong)track.TrackRawBytesPerSector; + track.TrackRawBytesPerSector = 2352; + currentOffset += trackLen * (ulong)track.TrackRawBytesPerSector; if(!imageInfo.ReadableSectorTags.Contains(SectorTagType.CdSectorSync)) imageInfo.ReadableSectorTags.Add(SectorTagType.CdSectorSync); if(!imageInfo.ReadableSectorTags.Contains(SectorTagType.CdSectorHeader)) @@ -394,13 +395,14 @@ namespace DiscImageChef.DiscImages imageInfo.ReadableSectorTags.Add(SectorTagType.CdSectorEdc); break; case 3: - track.TrackRawBytesPerSector = 2352; + track.TrackRawBytesPerSector = 2352; if(firstTrack) currentOffset += 150 * (ulong)(track.TrackRawBytesPerSector + 16); - track.TrackFileOffset = currentOffset; - track.TrackSubchannelFile = track.TrackFile; - track.TrackSubchannelOffset = currentOffset; - track.TrackSubchannelType = TrackSubchannelType.Q16Interleaved; - currentOffset += trackLen * (ulong)(track.TrackRawBytesPerSector + 16); + track.TrackFileOffset = currentOffset; + track.TrackSubchannelFile = track.TrackFile; + track.TrackSubchannelOffset = currentOffset; + track.TrackSubchannelType = TrackSubchannelType.Q16Interleaved; + currentOffset += + trackLen * (ulong)(track.TrackRawBytesPerSector + 16); if(!imageInfo.ReadableSectorTags.Contains(SectorTagType.CdSectorSync)) imageInfo.ReadableSectorTags.Add(SectorTagType.CdSectorSync); if(!imageInfo.ReadableSectorTags.Contains(SectorTagType.CdSectorHeader)) @@ -415,13 +417,14 @@ namespace DiscImageChef.DiscImages imageInfo.ReadableSectorTags.Add(SectorTagType.CdSectorEdc); break; case 4: - track.TrackRawBytesPerSector = 2352; + track.TrackRawBytesPerSector = 2352; if(firstTrack) currentOffset += 150 * (ulong)(track.TrackRawBytesPerSector + 96); - track.TrackFileOffset = currentOffset; - track.TrackSubchannelFile = track.TrackFile; - track.TrackSubchannelOffset = currentOffset; - track.TrackSubchannelType = TrackSubchannelType.RawInterleaved; - currentOffset += trackLen * (ulong)(track.TrackRawBytesPerSector + 96); + track.TrackFileOffset = currentOffset; + track.TrackSubchannelFile = track.TrackFile; + track.TrackSubchannelOffset = currentOffset; + track.TrackSubchannelType = TrackSubchannelType.RawInterleaved; + currentOffset += + trackLen * (ulong)(track.TrackRawBytesPerSector + 96); if(!imageInfo.ReadableSectorTags.Contains(SectorTagType.CdSectorSync)) imageInfo.ReadableSectorTags.Add(SectorTagType.CdSectorSync); if(!imageInfo.ReadableSectorTags.Contains(SectorTagType.CdSectorHeader)) @@ -442,48 +445,50 @@ namespace DiscImageChef.DiscImages // Mode 2 case 2: if(imageInfo.SectorSize < 2336) imageInfo.SectorSize = 2336; - track.TrackType = TrackType.CdMode2Formless; - track.TrackBytesPerSector = 2336; + track.TrackType = TrackType.CdMode2Formless; + track.TrackBytesPerSector = 2336; switch(readMode) { case 0: throw new ImageNotSupportedException($"Invalid read mode {readMode} for this track"); case 1: - track.TrackRawBytesPerSector = 2336; + track.TrackRawBytesPerSector = 2336; if(firstTrack) currentOffset += 150 * (ulong)track.TrackRawBytesPerSector; - track.TrackFileOffset = currentOffset; - currentOffset += trackLen * (ulong)track.TrackRawBytesPerSector; + track.TrackFileOffset = currentOffset; + currentOffset += trackLen * (ulong)track.TrackRawBytesPerSector; break; case 2: - track.TrackRawBytesPerSector = 2352; - currentOffset += trackLen * (ulong)track.TrackRawBytesPerSector; + track.TrackRawBytesPerSector = 2352; + currentOffset += trackLen * (ulong)track.TrackRawBytesPerSector; if(!imageInfo.ReadableSectorTags.Contains(SectorTagType.CdSectorSync)) imageInfo.ReadableSectorTags.Add(SectorTagType.CdSectorSync); if(!imageInfo.ReadableSectorTags.Contains(SectorTagType.CdSectorHeader)) imageInfo.ReadableSectorTags.Add(SectorTagType.CdSectorHeader); break; case 3: - track.TrackRawBytesPerSector = 2352; + track.TrackRawBytesPerSector = 2352; if(firstTrack) currentOffset += 150 * (ulong)(track.TrackRawBytesPerSector + 16); - track.TrackFileOffset = currentOffset; - track.TrackSubchannelFile = track.TrackFile; - track.TrackSubchannelOffset = currentOffset; - track.TrackSubchannelType = TrackSubchannelType.Q16Interleaved; - currentOffset += trackLen * (ulong)(track.TrackRawBytesPerSector + 16); + track.TrackFileOffset = currentOffset; + track.TrackSubchannelFile = track.TrackFile; + track.TrackSubchannelOffset = currentOffset; + track.TrackSubchannelType = TrackSubchannelType.Q16Interleaved; + currentOffset += + trackLen * (ulong)(track.TrackRawBytesPerSector + 16); if(!imageInfo.ReadableSectorTags.Contains(SectorTagType.CdSectorSync)) imageInfo.ReadableSectorTags.Add(SectorTagType.CdSectorSync); if(!imageInfo.ReadableSectorTags.Contains(SectorTagType.CdSectorHeader)) imageInfo.ReadableSectorTags.Add(SectorTagType.CdSectorHeader); break; case 4: - track.TrackRawBytesPerSector = 2352; + track.TrackRawBytesPerSector = 2352; if(firstTrack) currentOffset += 150 * (ulong)(track.TrackRawBytesPerSector + 96); - track.TrackFileOffset = currentOffset; - track.TrackSubchannelFile = track.TrackFile; - track.TrackSubchannelOffset = currentOffset; - track.TrackSubchannelType = TrackSubchannelType.RawInterleaved; - currentOffset += trackLen * (ulong)(track.TrackRawBytesPerSector + 96); + track.TrackFileOffset = currentOffset; + track.TrackSubchannelFile = track.TrackFile; + track.TrackSubchannelOffset = currentOffset; + track.TrackSubchannelType = TrackSubchannelType.RawInterleaved; + currentOffset += + trackLen * (ulong)(track.TrackRawBytesPerSector + 96); if(!imageInfo.ReadableSectorTags.Contains(SectorTagType.CdSectorSync)) imageInfo.ReadableSectorTags.Add(SectorTagType.CdSectorSync); if(!imageInfo.ReadableSectorTags.Contains(SectorTagType.CdSectorHeader)) @@ -496,11 +501,11 @@ namespace DiscImageChef.DiscImages default: throw new ImageNotSupportedException($"Unknown track mode {trackMode}"); } - track.TrackFile = imageFilter.GetFilename(); + track.TrackFile = imageFilter.GetFilename(); track.TrackFilter = imageFilter; if(track.TrackSubchannelType != TrackSubchannelType.None) { - track.TrackSubchannelFile = imageFilter.GetFilename(); + track.TrackSubchannelFile = imageFilter.GetFilename(); track.TrackSubchannelFilter = imageFilter; if(!imageInfo.ReadableSectorTags.Contains(SectorTagType.CdSectorSubchannel)) imageInfo.ReadableSectorTags.Add(SectorTagType.CdSectorSubchannel); @@ -509,17 +514,17 @@ namespace DiscImageChef.DiscImages Partition partition = new Partition { Description = track.TrackDescription, - Size = (ulong)(trackLen * track.TrackBytesPerSector), - Length = trackLen, - Sequence = track.TrackSequence, - Offset = track.TrackFileOffset, - Start = track.TrackStartSector, - Type = track.TrackType.ToString() + Size = (ulong)(trackLen * track.TrackBytesPerSector), + Length = trackLen, + Sequence = track.TrackSequence, + Offset = track.TrackFileOffset, + Start = track.TrackStartSector, + Type = track.TrackType.ToString() }; imageInfo.Sectors += partition.Length; - partitions.Add(partition); + Partitions.Add(partition); offsetmap.Add(track.TrackSequence, track.TrackStartSector); - tracks.Add(track); + Tracks.Add(track); trackFlags.Add(track.TrackSequence, (byte)(trackCtl & 0xFF)); addedATrack = true; } @@ -527,11 +532,11 @@ namespace DiscImageChef.DiscImages if(!addedATrack) continue; lastSessionTrack = session.EndTrack; - sessions.Add(session); - DicConsole.DebugWriteLine("DiscJuggler plugin", "session.StartTrack = {0}", session.StartTrack); + Sessions.Add(session); + DicConsole.DebugWriteLine("DiscJuggler plugin", "session.StartTrack = {0}", session.StartTrack); DicConsole.DebugWriteLine("DiscJuggler plugin", "session.StartSector = {0}", session.StartSector); - DicConsole.DebugWriteLine("DiscJuggler plugin", "session.EndTrack = {0}", session.EndTrack); - DicConsole.DebugWriteLine("DiscJuggler plugin", "session.EndSector = {0}", session.EndSector); + DicConsole.DebugWriteLine("DiscJuggler plugin", "session.EndTrack = {0}", session.EndTrack); + DicConsole.DebugWriteLine("DiscJuggler plugin", "session.EndSector = {0}", session.EndSector); DicConsole.DebugWriteLine("DiscJuggler plugin", "session.SessionSequence = {0}", session.SessionSequence); } @@ -543,25 +548,25 @@ namespace DiscImageChef.DiscImages byte[] filenameB = new byte[descriptor[position]]; position++; Array.Copy(descriptor, position, filenameB, 0, filenameB.Length); - position += filenameB.Length; + position += filenameB.Length; string filename = Path.GetFileName(Encoding.Default.GetString(filenameB)); DicConsole.DebugWriteLine("DiscJuggler plugin", "filename = {0}", filename); // Skip unknown position += 29; - mediumType = BitConverter.ToUInt16(descriptor, position); - position += 2; + mediumType = BitConverter.ToUInt16(descriptor, position); + position += 2; DicConsole.DebugWriteLine("DiscJuggler plugin", "mediumType = {0}", mediumType); uint discSize = BitConverter.ToUInt32(descriptor, position); - position += 4; + position += 4; DicConsole.DebugWriteLine("DiscJuggler plugin", "discSize = {0}", discSize); byte[] volidB = new byte[descriptor[position]]; position++; Array.Copy(descriptor, position, volidB, 0, volidB.Length); - position += volidB.Length; + position += volidB.Length; string volid = Path.GetFileName(Encoding.Default.GetString(volidB)); DicConsole.DebugWriteLine("DiscJuggler plugin", "volid = {0}", volid); @@ -571,7 +576,7 @@ namespace DiscImageChef.DiscImages byte[] mcn = new byte[13]; Array.Copy(descriptor, position, mcn, 0, 13); DicConsole.DebugWriteLine("DiscJuggler plugin", "mcn = {0}", StringHandlers.CToString(mcn)); - position += 13; + position += 13; uint mcnValid = BitConverter.ToUInt32(descriptor, position); DicConsole.DebugWriteLine("DiscJuggler plugin", "mcn_valid = {0}", mcnValid); position += 4; @@ -594,27 +599,27 @@ namespace DiscImageChef.DiscImages if(imageInfo.MediaType == MediaType.CDROM) { - bool data = false; - bool mode2 = false; + bool data = false; + bool mode2 = false; bool firstaudio = false; - bool firstdata = false; - bool audio = false; + bool firstdata = false; + bool audio = false; - for(int i = 0; i < tracks.Count; i++) + for(int i = 0; i < Tracks.Count; i++) { // First track is audio - firstaudio |= i == 0 && tracks[i].TrackType == TrackType.Audio; + firstaudio |= i == 0 && Tracks[i].TrackType == TrackType.Audio; // First track is data - firstdata |= i == 0 && tracks[i].TrackType != TrackType.Audio; + firstdata |= i == 0 && Tracks[i].TrackType != TrackType.Audio; // Any non first track is data - data |= i != 0 && tracks[i].TrackType != TrackType.Audio; + data |= i != 0 && Tracks[i].TrackType != TrackType.Audio; // Any non first track is audio - audio |= i != 0 && tracks[i].TrackType == TrackType.Audio; + audio |= i != 0 && Tracks[i].TrackType == TrackType.Audio; - switch(tracks[i].TrackType) + switch(Tracks[i].TrackType) { case TrackType.CdMode2Form1: case TrackType.CdMode2Form2: @@ -624,32 +629,26 @@ namespace DiscImageChef.DiscImages } } - if(!data && !firstdata) imageInfo.MediaType = MediaType.CDDA; - else if(firstaudio && data && sessions.Count > 1 && mode2) imageInfo.MediaType = MediaType.CDPLUS; - else if(firstdata && audio || mode2) imageInfo.MediaType = MediaType.CDROMXA; - else if(!audio) imageInfo.MediaType = MediaType.CDROM; - else imageInfo.MediaType = MediaType.CD; + if(!data && !firstdata) imageInfo.MediaType = MediaType.CDDA; + else if(firstaudio && data && Sessions.Count > 1 && mode2) + imageInfo.MediaType = MediaType.CDPLUS; + else if(firstdata && audio || mode2) + imageInfo.MediaType = MediaType.CDROMXA; + else if(!audio) + imageInfo.MediaType = MediaType.CDROM; + else + imageInfo.MediaType = MediaType.CD; } - imageInfo.Application = "DiscJuggler"; - imageInfo.ImageSize = (ulong)imageFilter.GetDataForkLength(); - imageInfo.CreationTime = imageFilter.GetCreationTime(); + imageInfo.Application = "DiscJuggler"; + imageInfo.ImageSize = (ulong)imageFilter.GetDataForkLength(); + imageInfo.CreationTime = imageFilter.GetCreationTime(); imageInfo.LastModificationTime = imageFilter.GetLastWriteTime(); - imageInfo.XmlMediaType = XmlMediaType.OpticalDisc; + imageInfo.XmlMediaType = XmlMediaType.OpticalDisc; return true; } - static MediaType DecodeCdiMediumType(ushort type) - { - switch(type) - { - case 56: return MediaType.DVDROM; - case 152: return MediaType.CDROM; - default: return MediaType.Unknown; - } - } - public byte[] ReadDiskTag(MediaTagType tag) { switch(tag) @@ -689,9 +688,9 @@ namespace DiscImageChef.DiscImages { foreach(KeyValuePair kvp in from kvp in offsetmap where sectorAddress >= kvp.Value - from track in tracks + from track in Tracks where track.TrackSequence == kvp.Key - where sectorAddress < track.TrackEndSector + where sectorAddress < track.TrackEndSector select kvp) return ReadSectors(sectorAddress - kvp.Value, length, kvp.Key); @@ -701,9 +700,11 @@ namespace DiscImageChef.DiscImages public byte[] ReadSectorsTag(ulong sectorAddress, uint length, SectorTagType tag) { foreach(KeyValuePair kvp in offsetmap - .Where(kvp => sectorAddress >= kvp.Value) - .Where(kvp => tracks.Where(track => track.TrackSequence == kvp.Key) - .Any(track => sectorAddress < track.TrackEndSector))) + .Where(kvp => sectorAddress >= kvp.Value) + .Where(kvp => Tracks + .Where(track => track.TrackSequence == kvp.Key) + .Any(track => sectorAddress < + track.TrackEndSector))) return ReadSectorsTag(sectorAddress - kvp.Value, length, kvp.Key, tag); throw new ArgumentOutOfRangeException(nameof(sectorAddress), $"Sector address {sectorAddress} not found"); @@ -713,7 +714,7 @@ namespace DiscImageChef.DiscImages { Track dicTrack = new Track {TrackSequence = 0}; - foreach(Track linqTrack in tracks.Where(linqTrack => linqTrack.TrackSequence == track)) + foreach(Track linqTrack in Tracks.Where(linqTrack => linqTrack.TrackSequence == track)) { dicTrack = linqTrack; break; @@ -735,37 +736,39 @@ namespace DiscImageChef.DiscImages case TrackType.Audio: { sectorOffset = 0; - sectorSize = 2352; - sectorSkip = 0; + sectorSize = 2352; + sectorSkip = 0; break; } case TrackType.CdMode1: if(dicTrack.TrackRawBytesPerSector == 2352) { sectorOffset = 16; - sectorSize = 2048; - sectorSkip = 288; + sectorSize = 2048; + sectorSkip = 288; } else { sectorOffset = 0; - sectorSize = 2048; - sectorSkip = 0; + sectorSize = 2048; + sectorSkip = 0; } + break; case TrackType.CdMode2Formless: if(dicTrack.TrackRawBytesPerSector == 2352) { sectorOffset = 16; - sectorSize = 2336; - sectorSkip = 0; + sectorSize = 2336; + sectorSkip = 0; } else { sectorOffset = 0; - sectorSize = 2336; - sectorSkip = 0; + sectorSize = 2336; + sectorSkip = 0; } + break; default: throw new FeatureSupportedButNotImplementedImageException("Unsupported track type"); } @@ -806,7 +809,7 @@ namespace DiscImageChef.DiscImages { Track dicTrack = new Track {TrackSequence = 0}; - foreach(Track linqTrack in tracks.Where(linqTrack => linqTrack.TrackSequence == track)) + foreach(Track linqTrack in Tracks.Where(linqTrack => linqTrack.TrackSequence == track)) { dicTrack = linqTrack; break; @@ -835,7 +838,7 @@ namespace DiscImageChef.DiscImages case SectorTagType.CdTrackFlags: if(trackFlags.TryGetValue(track, out byte flag)) return new[] {flag}; - throw new ArgumentException("Unsupported tag requested", nameof(tag)); + throw new ArgumentException("Unsupported tag requested", nameof(tag)); default: throw new ArgumentException("Unsupported tag requested", nameof(tag)); } @@ -854,15 +857,15 @@ namespace DiscImageChef.DiscImages case SectorTagType.CdSectorSync: { sectorOffset = 0; - sectorSize = 12; - sectorSkip = 2340; + sectorSize = 12; + sectorSkip = 2340; break; } case SectorTagType.CdSectorHeader: { sectorOffset = 12; - sectorSize = 4; - sectorSkip = 2336; + sectorSize = 4; + sectorSkip = 2336; break; } case SectorTagType.CdSectorSubHeader: @@ -870,29 +873,29 @@ namespace DiscImageChef.DiscImages case SectorTagType.CdSectorEcc: { sectorOffset = 2076; - sectorSize = 276; - sectorSkip = 0; + sectorSize = 276; + sectorSkip = 0; break; } case SectorTagType.CdSectorEccP: { sectorOffset = 2076; - sectorSize = 172; - sectorSkip = 104; + sectorSize = 172; + sectorSkip = 104; break; } case SectorTagType.CdSectorEccQ: { sectorOffset = 2248; - sectorSize = 104; - sectorSkip = 0; + sectorSize = 104; + sectorSkip = 0; break; } case SectorTagType.CdSectorEdc: { sectorOffset = 2064; - sectorSize = 4; - sectorSkip = 284; + sectorSize = 4; + sectorSkip = 284; break; } case SectorTagType.CdSectorSubchannel: @@ -906,8 +909,8 @@ namespace DiscImageChef.DiscImages } sectorOffset = 2352; - sectorSize = 96; - sectorSkip = 0; + sectorSize = 96; + sectorSkip = 0; break; default: throw new ArgumentException("Unsupported tag requested", nameof(tag)); } @@ -929,15 +932,15 @@ namespace DiscImageChef.DiscImages case SectorTagType.CdSectorSubHeader: { sectorOffset = 0; - sectorSize = 8; - sectorSkip = 2328; + sectorSize = 8; + sectorSkip = 2328; break; } case SectorTagType.CdSectorEdc: { sectorOffset = 2332; - sectorSize = 4; - sectorSkip = 0; + sectorSize = 4; + sectorSkip = 0; break; } case SectorTagType.CdSectorSubchannel: @@ -951,8 +954,8 @@ namespace DiscImageChef.DiscImages } sectorOffset = 2352; - sectorSize = 96; - sectorSkip = 0; + sectorSize = 96; + sectorSkip = 0; break; default: throw new ArgumentException("Unsupported tag requested", nameof(tag)); } @@ -974,8 +977,8 @@ namespace DiscImageChef.DiscImages } sectorOffset = 2352; - sectorSize = 96; - sectorSkip = 0; + sectorSize = 96; + sectorSkip = 0; break; default: throw new ArgumentException("Unsupported tag requested", nameof(tag)); } @@ -1031,9 +1034,9 @@ namespace DiscImageChef.DiscImages { foreach(KeyValuePair kvp in from kvp in offsetmap where sectorAddress >= kvp.Value - from track in tracks - where track.TrackSequence == kvp.Key - where sectorAddress - kvp.Value < + from track in Tracks + where track.TrackSequence == kvp.Key + where sectorAddress - kvp.Value < track.TrackEndSector - track.TrackStartSector select kvp) return ReadSectorsLong(sectorAddress - kvp.Value, length, kvp.Key); @@ -1045,7 +1048,7 @@ namespace DiscImageChef.DiscImages { Track dicTrack = new Track {TrackSequence = 0}; - foreach(Track linqTrack in tracks.Where(linqTrack => linqTrack.TrackSequence == track)) + foreach(Track linqTrack in Tracks.Where(linqTrack => linqTrack.TrackSequence == track)) { dicTrack = linqTrack; break; @@ -1094,14 +1097,14 @@ namespace DiscImageChef.DiscImages public List GetSessionTracks(Session session) { - if(sessions.Contains(session)) return GetSessionTracks(session.SessionSequence); + if(Sessions.Contains(session)) return GetSessionTracks(session.SessionSequence); throw new ImageNotSupportedException("Session does not exist in disc image"); } public List GetSessionTracks(ushort session) { - return tracks.Where(track => track.TrackSession == session).ToList(); + return Tracks.Where(track => track.TrackSession == session).ToList(); } public bool? VerifySector(ulong sectorAddress) @@ -1117,13 +1120,13 @@ namespace DiscImageChef.DiscImages } public bool? VerifySectors(ulong sectorAddress, uint length, out List failingLbas, - out List unknownLbas) + out List unknownLbas) { byte[] buffer = ReadSectorsLong(sectorAddress, length); - int bps = (int)(buffer.Length / length); + int bps = (int)(buffer.Length / length); byte[] sector = new byte[bps]; - failingLbas = new List(); - unknownLbas = new List(); + failingLbas = new List(); + unknownLbas = new List(); for(int i = 0; i < length; i++) { @@ -1147,13 +1150,13 @@ namespace DiscImageChef.DiscImages } public bool? VerifySectors(ulong sectorAddress, uint length, uint track, out List failingLbas, - out List unknownLbas) + out List unknownLbas) { byte[] buffer = ReadSectorsLong(sectorAddress, length, track); - int bps = (int)(buffer.Length / length); + int bps = (int)(buffer.Length / length); byte[] sector = new byte[bps]; - failingLbas = new List(); - unknownLbas = new List(); + failingLbas = new List(); + unknownLbas = new List(); for(int i = 0; i < length; i++) { @@ -1180,5 +1183,18 @@ namespace DiscImageChef.DiscImages { return null; } + + public List DumpHardware => null; + public CICMMetadataType CicmMetadata => null; + + static MediaType DecodeCdiMediumType(ushort type) + { + switch(type) + { + case 56: return MediaType.DVDROM; + case 152: return MediaType.CDROM; + default: return MediaType.Unknown; + } + } } } \ No newline at end of file diff --git a/DiscImageChef.DiscImages/DiskCopy42.cs b/DiscImageChef.DiscImages/DiskCopy42.cs index 015057568..feb537d14 100644 --- a/DiscImageChef.DiscImages/DiskCopy42.cs +++ b/DiscImageChef.DiscImages/DiskCopy42.cs @@ -40,6 +40,7 @@ using Claunia.RsrcFork; using DiscImageChef.CommonTypes; using DiscImageChef.Console; using DiscImageChef.Filters; +using Schemas; using Encoding = System.Text.Encoding; using Version = Resources.Version; @@ -635,6 +636,9 @@ namespace DiscImageChef.DiscImages return dataChk == header.DataChecksum && tagsChk == header.TagChecksum; } + public List DumpHardware => null; + public CICMMetadataType CicmMetadata => null; + public byte[] ReadSector(ulong sectorAddress) { return ReadSectors(sectorAddress, 1); @@ -1162,6 +1166,18 @@ namespace DiscImageChef.DiscImages return false; } + public bool SetDumpHardware(List dumpHardware) + { + // Not supported + return false; + } + + public bool SetCicmMetadata(CICMMetadataType metadata) + { + // Not supported + return false; + } + // DiskCopy 4.2 header, big-endian, data-fork, start of file, 84 bytes struct Dc42Header { diff --git a/DiscImageChef.DiscImages/DriDiskCopy.cs b/DiscImageChef.DiscImages/DriDiskCopy.cs index 97e09d878..7bf75b8a0 100644 --- a/DiscImageChef.DiscImages/DriDiskCopy.cs +++ b/DiscImageChef.DiscImages/DriDiskCopy.cs @@ -41,6 +41,7 @@ using System.Text.RegularExpressions; using DiscImageChef.CommonTypes; using DiscImageChef.Console; using DiscImageChef.Filters; +using Schemas; namespace DiscImageChef.DiscImages { @@ -271,6 +272,9 @@ namespace DiscImageChef.DiscImages return null; } + public List DumpHardware => null; + public CICMMetadataType CicmMetadata => null; + public byte[] ReadSector(ulong sectorAddress) { return ReadSectors(sectorAddress, 1); @@ -390,7 +394,7 @@ namespace DiscImageChef.DiscImages if(sectors > ushort.MaxValue) { - ErrorMessage = $"Too many sectors"; + ErrorMessage = "Too many sectors"; return false; } @@ -564,6 +568,18 @@ namespace DiscImageChef.DiscImages return false; } + public bool SetDumpHardware(List dumpHardware) + { + // Not supported + return false; + } + + public bool SetCicmMetadata(CICMMetadataType metadata) + { + // Not supported + return false; + } + [StructLayout(LayoutKind.Sequential, Pack = 1)] struct DriFooter { diff --git a/DiscImageChef.DiscImages/GDI.cs b/DiscImageChef.DiscImages/GDI.cs index 4333be9d4..643c50254 100644 --- a/DiscImageChef.DiscImages/GDI.cs +++ b/DiscImageChef.DiscImages/GDI.cs @@ -39,6 +39,7 @@ using DiscImageChef.Checksums; using DiscImageChef.CommonTypes; using DiscImageChef.Console; using DiscImageChef.Filters; +using Schemas; namespace DiscImageChef.DiscImages { @@ -1008,6 +1009,9 @@ namespace DiscImageChef.DiscImages return null; } + public List DumpHardware => null; + public CICMMetadataType CicmMetadata => null; + struct GdiTrack { /// Track # diff --git a/DiscImageChef.DiscImages/HDCopy.cs b/DiscImageChef.DiscImages/HDCopy.cs index df5521c69..a96a66d60 100644 --- a/DiscImageChef.DiscImages/HDCopy.cs +++ b/DiscImageChef.DiscImages/HDCopy.cs @@ -70,6 +70,7 @@ using System.Runtime.InteropServices; using DiscImageChef.CommonTypes; using DiscImageChef.Console; using DiscImageChef.Filters; +using Schemas; namespace DiscImageChef.DiscImages { @@ -128,8 +129,8 @@ namespace DiscImageChef.DiscImages public string Name => "HD-Copy disk image"; public Guid Id => new Guid("8D57483F-71A5-42EC-9B87-66AEC439C792"); - public string Format => "HD-Copy image"; - public List Partitions => + public string Format => "HD-Copy image"; + public List Partitions => throw new FeatureUnsupportedImageException("Feature not supported by image format"); public List Tracks => @@ -376,6 +377,9 @@ namespace DiscImageChef.DiscImages return null; } + public List DumpHardware => null; + public CICMMetadataType CicmMetadata => null; + void ReadTrackIntoCache(Stream stream, int tracknum) { byte[] trackData = new byte[imageInfo.SectorSize * imageInfo.SectorsPerTrack]; diff --git a/DiscImageChef.DiscImages/IMD.cs b/DiscImageChef.DiscImages/IMD.cs index 5e439db38..ab81a7aa9 100644 --- a/DiscImageChef.DiscImages/IMD.cs +++ b/DiscImageChef.DiscImages/IMD.cs @@ -38,6 +38,7 @@ using System.Text.RegularExpressions; using DiscImageChef.CommonTypes; using DiscImageChef.Console; using DiscImageChef.Filters; +using Schemas; namespace DiscImageChef.DiscImages { @@ -288,6 +289,9 @@ namespace DiscImageChef.DiscImages return null; } + public List DumpHardware => null; + public CICMMetadataType CicmMetadata => null; + public byte[] ReadSector(ulong sectorAddress) { return ReadSectors(sectorAddress, 1); diff --git a/DiscImageChef.DiscImages/IMediaImage.cs b/DiscImageChef.DiscImages/IMediaImage.cs index 0a0a0fb04..55b0bdab4 100644 --- a/DiscImageChef.DiscImages/IMediaImage.cs +++ b/DiscImageChef.DiscImages/IMediaImage.cs @@ -32,9 +32,9 @@ using System; using System.Collections.Generic; -using System.Runtime.Serialization; using DiscImageChef.CommonTypes; using DiscImageChef.Filters; +using Schemas; namespace DiscImageChef.DiscImages { @@ -71,6 +71,10 @@ namespace DiscImageChef.DiscImages /// /// The sessions. List Sessions { get; } + /// List of dump hardware used to create the image from real media + List DumpHardware { get; } + /// Gets the CICM XML metadata for the image + CICMMetadataType CicmMetadata { get; } /// /// Identifies the image. @@ -242,7 +246,7 @@ namespace DiscImageChef.DiscImages /// List of incorrect sectors /// List of uncheckable sectors bool? VerifySectors(ulong sectorAddress, uint length, uint track, out List failingLbas, - out List unknownLbas); + out List unknownLbas); /// /// Verifies media image internal checksum. diff --git a/DiscImageChef.DiscImages/IWritableImage.cs b/DiscImageChef.DiscImages/IWritableImage.cs index 0c9efefa3..4dea6553f 100644 --- a/DiscImageChef.DiscImages/IWritableImage.cs +++ b/DiscImageChef.DiscImages/IWritableImage.cs @@ -33,6 +33,7 @@ using System; using System.Collections.Generic; using DiscImageChef.CommonTypes; +using Schemas; namespace DiscImageChef.DiscImages { @@ -160,7 +161,7 @@ namespace DiscImageChef.DiscImages /// Tag type /// true if operating completed successfully, false otherwise bool WriteSectorTag(byte[] data, ulong sectorAddress, SectorTagType tag); - + /// /// Writes parallel or subchannel sector tag for several sector /// @@ -170,5 +171,15 @@ namespace DiscImageChef.DiscImages /// Tag type /// true if operating completed successfully, false otherwise bool WriteSectorsTag(byte[] data, ulong sectorAddress, uint length, SectorTagType tag); + + /// + /// Sets the list of dump hardware used to create the image from real media + /// + bool SetDumpHardware(List dumpHardware); + + /// + /// Sets the CICM XML metadata for the image + /// + bool SetCicmMetadata(CICMMetadataType metadata); } } \ No newline at end of file diff --git a/DiscImageChef.DiscImages/KryoFlux.cs b/DiscImageChef.DiscImages/KryoFlux.cs index d58e726f0..e1925bda4 100644 --- a/DiscImageChef.DiscImages/KryoFlux.cs +++ b/DiscImageChef.DiscImages/KryoFlux.cs @@ -40,54 +40,55 @@ using System.Runtime.InteropServices; using DiscImageChef.CommonTypes; using DiscImageChef.Console; using DiscImageChef.Filters; +using Schemas; namespace DiscImageChef.DiscImages { [SuppressMessage("ReSharper", "InconsistentNaming")] public class KryoFlux : IMediaImage { - const string hostDate = "host_date"; - const string hostTime = "host_time"; - const string kfName = "name"; + const string hostDate = "host_date"; + const string hostTime = "host_time"; + const string kfName = "name"; const string kfVersion = "version"; - const string kfDate = "date"; - const string kfTime = "time"; - const string kfHwId = "hwid"; - const string kfHwRv = "hwrv"; - const string kfSck = "sck"; - const string kfIck = "ick"; + const string kfDate = "date"; + const string kfTime = "time"; + const string kfHwId = "hwid"; + const string kfHwRv = "hwrv"; + const string kfSck = "sck"; + const string kfIck = "ick"; // TODO: These variables have been made public so create-sidecar can access to this information until I define an API >4.0 public SortedDictionary tracks; - public ImageInfo imageInfo; - public ImageInfo Info => imageInfo; + public ImageInfo imageInfo; + public ImageInfo Info => imageInfo; public string Name => "KryoFlux STREAM"; - public Guid Id => new Guid("4DBC95E4-93EE-4F7A-9492-919887E60EFE"); + public Guid Id => new Guid("4DBC95E4-93EE-4F7A-9492-919887E60EFE"); public KryoFlux() { imageInfo = new ImageInfo { - ReadableSectorTags = new List(), - ReadableMediaTags = new List(), - HasPartitions = false, - HasSessions = false, - Version = null, - Application = null, - ApplicationVersion = null, - Creator = null, - Comments = null, - MediaManufacturer = null, - MediaModel = null, - MediaSerialNumber = null, - MediaBarcode = null, - MediaPartNumber = null, - MediaSequence = 0, - LastMediaSequence = 0, - DriveManufacturer = null, - DriveModel = null, - DriveSerialNumber = null, + ReadableSectorTags = new List(), + ReadableMediaTags = new List(), + HasPartitions = false, + HasSessions = false, + Version = null, + Application = null, + ApplicationVersion = null, + Creator = null, + Comments = null, + MediaManufacturer = null, + MediaModel = null, + MediaSerialNumber = null, + MediaBarcode = null, + MediaPartNumber = null, + MediaSequence = 0, + LastMediaSequence = 0, + DriveManufacturer = null, + DriveModel = null, + DriveSerialNumber = null, DriveFirmwareRevision = null }; } @@ -95,7 +96,7 @@ namespace DiscImageChef.DiscImages public bool Identify(IFilter imageFilter) { OobBlock header = new OobBlock(); - Stream stream = imageFilter.GetDataForkStream(); + Stream stream = imageFilter.GetDataForkStream(); stream.Seek(0, SeekOrigin.Begin); if(stream.Length < Marshal.SizeOf(header)) return false; @@ -119,13 +120,13 @@ namespace DiscImageChef.DiscImages Marshal.FreeHGlobal(hdrPtr); return header.blockId == BlockIds.Oob && header.blockType == OobTypes.KFInfo && - footer.blockId == BlockIds.Oob && footer.blockType == OobTypes.EOF && footer.length == 0x0D0D; + footer.blockId == BlockIds.Oob && footer.blockType == OobTypes.EOF && footer.length == 0x0D0D; } public bool Open(IFilter imageFilter) { OobBlock header = new OobBlock(); - Stream stream = imageFilter.GetDataForkStream(); + Stream stream = imageFilter.GetDataForkStream(); stream.Seek(0, SeekOrigin.Begin); if(stream.Length < Marshal.SizeOf(header)) return false; @@ -149,22 +150,22 @@ namespace DiscImageChef.DiscImages Marshal.FreeHGlobal(hdrPtr); if(header.blockId != BlockIds.Oob || header.blockType != OobTypes.KFInfo || - footer.blockId != BlockIds.Oob || footer.blockType != OobTypes.EOF || - footer.length != 0x0D0D) return false; + footer.blockId != BlockIds.Oob || footer.blockType != OobTypes.EOF || + footer.length != 0x0D0D) return false; // TODO: This is supposing NoFilter, shouldn't - tracks = new SortedDictionary(); - byte step = 1; - byte heads = 2; - bool topHead = false; + tracks = new SortedDictionary(); + byte step = 1; + byte heads = 2; + bool topHead = false; string basename = Path.Combine(imageFilter.GetParentFolder(), imageFilter.GetFilename() .Substring(0, imageFilter.GetFilename().Length - 8)); for(byte t = 0; t < 166; t += step) { - int cylinder = t / heads; - int head = topHead ? 1 : t % heads; + int cylinder = t / heads; + int head = topHead ? 1 : t % heads; string trackfile = Directory.Exists(basename) ? Path.Combine(basename, $"{cylinder:D2}.{head:D1}.raw") : $"{basename}{cylinder:D2}.{head:D1}.raw"; @@ -177,7 +178,7 @@ namespace DiscImageChef.DiscImages DicConsole.DebugWriteLine("KryoFlux plugin", "Cannot find cyl 0 hd 0, supposing only top head was dumped"); topHead = true; - heads = 1; + heads = 1; continue; } @@ -202,7 +203,7 @@ namespace DiscImageChef.DiscImages trackFilter.Open(trackfile); if(!trackFilter.IsOpened()) throw new IOException("Could not open KryoFlux track file."); - imageInfo.CreationTime = DateTime.MaxValue; + imageInfo.CreationTime = DateTime.MaxValue; imageInfo.LastModificationTime = DateTime.MinValue; Stream trackStream = trackFilter.GetDataForkStream(); @@ -238,12 +239,12 @@ namespace DiscImageChef.DiscImages byte[] kfinfo = new byte[oobBlk.length]; trackStream.Read(kfinfo, 0, oobBlk.length); - string kfinfoStr = StringHandlers.CToString(kfinfo); - string[] lines = kfinfoStr.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries); + string kfinfoStr = StringHandlers.CToString(kfinfo); + string[] lines = kfinfoStr.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries); DateTime blockDate = DateTime.Now; DateTime blockTime = DateTime.Now; - bool foundDate = false; + bool foundDate = false; foreach(string[] kvp in lines.Select(line => line.Split('=')).Where(kvp => kvp.Length == 2)) { @@ -306,7 +307,7 @@ namespace DiscImageChef.DiscImages tracks.Add(t, trackFilter); } - imageInfo.Heads = heads; + imageInfo.Heads = heads; imageInfo.Cylinders = (uint)(tracks.Count / heads); throw new NotImplementedException("Flux decoding is not yet implemented."); @@ -360,7 +361,7 @@ namespace DiscImageChef.DiscImages } public bool? VerifySectors(ulong sectorAddress, uint length, out List failingLbas, - out List unknownLbas) + out List unknownLbas) { throw new NotImplementedException("Flux decoding is not yet implemented."); } @@ -415,7 +416,7 @@ namespace DiscImageChef.DiscImages } public bool? VerifySectors(ulong sectorAddress, uint length, uint track, out List failingLbas, - out List unknownLbas) + out List unknownLbas) { throw new FeatureUnsupportedImageException("Feature not supported by image format"); } @@ -425,17 +426,20 @@ namespace DiscImageChef.DiscImages throw new FeatureUnsupportedImageException("Feature not supported by image format"); } + public List DumpHardware => null; + public CICMMetadataType CicmMetadata => null; + [StructLayout(LayoutKind.Sequential, Pack = 1)] struct OobBlock { public BlockIds blockId; public OobTypes blockType; - public ushort length; + public ushort length; } enum BlockIds : byte { - Flux2 = 0x00, + Flux2 = 0x00, Flux2_1 = 0x01, Flux2_2 = 0x02, Flux2_3 = 0x03, @@ -443,22 +447,22 @@ namespace DiscImageChef.DiscImages Flux2_5 = 0x05, Flux2_6 = 0x06, Flux2_7 = 0x07, - Nop1 = 0x08, - Nop2 = 0x09, - Nop3 = 0x0A, - Ovl16 = 0x0B, - Flux3 = 0x0C, - Oob = 0x0D + Nop1 = 0x08, + Nop2 = 0x09, + Nop3 = 0x0A, + Ovl16 = 0x0B, + Flux3 = 0x0C, + Oob = 0x0D } enum OobTypes : byte { - Invalid = 0x00, + Invalid = 0x00, StreamInfo = 0x01, - Index = 0x02, - StreamEnd = 0x03, - KFInfo = 0x04, - EOF = 0x0D + Index = 0x02, + StreamEnd = 0x03, + KFInfo = 0x04, + EOF = 0x0D } } } \ No newline at end of file diff --git a/DiscImageChef.DiscImages/MaxiDisk.cs b/DiscImageChef.DiscImages/MaxiDisk.cs index 7c066e808..a9f4b60ba 100644 --- a/DiscImageChef.DiscImages/MaxiDisk.cs +++ b/DiscImageChef.DiscImages/MaxiDisk.cs @@ -39,6 +39,7 @@ using DiscImageChef.CommonTypes; using DiscImageChef.Console; using DiscImageChef.Filters; using DiscImageChef.Helpers; +using Schemas; namespace DiscImageChef.DiscImages { @@ -228,6 +229,9 @@ namespace DiscImageChef.DiscImages return null; } + public List DumpHardware => null; + public CICMMetadataType CicmMetadata => null; + public byte[] ReadSector(ulong sectorAddress) { return ReadSectors(sectorAddress, 1); @@ -346,7 +350,7 @@ namespace DiscImageChef.DiscImages if(sectors > 90 * 2 * 255) { - ErrorMessage = $"Too many sectors"; + ErrorMessage = "Too many sectors"; return false; } @@ -555,6 +559,18 @@ namespace DiscImageChef.DiscImages return false; } + public bool SetDumpHardware(List dumpHardware) + { + // Not supported + return false; + } + + public bool SetCicmMetadata(CICMMetadataType metadata) + { + // Not supported + return false; + } + [StructLayout(LayoutKind.Sequential, Pack = 1)] struct HdkHeader { diff --git a/DiscImageChef.DiscImages/NDIF.cs b/DiscImageChef.DiscImages/NDIF.cs index ccbb78e90..981321274 100644 --- a/DiscImageChef.DiscImages/NDIF.cs +++ b/DiscImageChef.DiscImages/NDIF.cs @@ -41,6 +41,7 @@ using DiscImageChef.CommonTypes; using DiscImageChef.Compression; using DiscImageChef.Console; using DiscImageChef.Filters; +using Schemas; using SharpCompress.Compressors.ADC; using Version = Resources.Version; @@ -61,34 +62,34 @@ namespace DiscImageChef.DiscImages /// const short NDIF_RESOURCEID = 128; - const byte CHUNK_TYPE_NOCOPY = 0; - const byte CHUNK_TYPE_COPY = 2; + const byte CHUNK_TYPE_NOCOPY = 0; + const byte CHUNK_TYPE_COPY = 2; const byte CHUNK_TYPE_KENCODE = 0x80; - const byte CHUNK_TYPE_RLE = 0x81; - const byte CHUNK_TYPE_LZH = 0x82; - const byte CHUNK_TYPE_ADC = 0x83; + const byte CHUNK_TYPE_RLE = 0x81; + const byte CHUNK_TYPE_LZH = 0x82; + const byte CHUNK_TYPE_ADC = 0x83; /// /// Created by ShrinkWrap 3.5, dunno which version of the StuffIt algorithm it is using /// const byte CHUNK_TYPE_STUFFIT = 0xF0; - const byte CHUNK_TYPE_END = 0xFF; + const byte CHUNK_TYPE_END = 0xFF; const byte CHUNK_TYPE_COMPRESSED_MASK = 0x80; - const short DRIVER_OSX = -1; - const short DRIVER_HFS = 0; - const short DRIVER_PRODOS = 256; - const short DRIVER_DOS = 18771; - const uint MAX_CACHE_SIZE = 16777216; - const uint SECTOR_SIZE = 512; - const uint MAX_CACHED_SECTORS = MAX_CACHE_SIZE / SECTOR_SIZE; - uint buffersize; - Dictionary chunkCache; + const short DRIVER_OSX = -1; + const short DRIVER_HFS = 0; + const short DRIVER_PRODOS = 256; + const short DRIVER_DOS = 18771; + const uint MAX_CACHE_SIZE = 16777216; + const uint SECTOR_SIZE = 512; + const uint MAX_CACHED_SECTORS = MAX_CACHE_SIZE / SECTOR_SIZE; + uint buffersize; + Dictionary chunkCache; Dictionary chunks; - uint currentChunkCacheSize; + uint currentChunkCacheSize; ChunkHeader header; - ImageInfo imageInfo; + ImageInfo imageInfo; Stream imageStream; @@ -98,25 +99,25 @@ namespace DiscImageChef.DiscImages { imageInfo = new ImageInfo { - ReadableSectorTags = new List(), - ReadableMediaTags = new List(), - HasPartitions = false, - HasSessions = false, - Version = null, - Application = null, - ApplicationVersion = null, - Creator = null, - Comments = null, - MediaManufacturer = null, - MediaModel = null, - MediaSerialNumber = null, - MediaBarcode = null, - MediaPartNumber = null, - MediaSequence = 0, - LastMediaSequence = 0, - DriveManufacturer = null, - DriveModel = null, - DriveSerialNumber = null, + ReadableSectorTags = new List(), + ReadableMediaTags = new List(), + HasPartitions = false, + HasSessions = false, + Version = null, + Application = null, + ApplicationVersion = null, + Creator = null, + Comments = null, + MediaManufacturer = null, + MediaModel = null, + MediaSerialNumber = null, + MediaBarcode = null, + MediaPartNumber = null, + MediaSequence = 0, + LastMediaSequence = 0, + DriveManufacturer = null, + DriveModel = null, + DriveSerialNumber = null, DriveFirmwareRevision = null }; } @@ -124,7 +125,7 @@ namespace DiscImageChef.DiscImages public ImageInfo Info => imageInfo; public string Name => "Apple New Disk Image Format"; - public Guid Id => new Guid("5A7FF7D8-491E-458D-8674-5B5EADBECC24"); + public Guid Id => new Guid("5A7FF7D8-491E-458D-8674-5B5EADBECC24"); public string Format => "Apple New Disk Image Format"; @@ -160,8 +161,8 @@ namespace DiscImageChef.DiscImages if(!imageFilter.HasResourceFork() || imageFilter.GetResourceForkLength() == 0) return false; ResourceFork rsrcFork; - Resource rsrc; - short[] bcems; + Resource rsrc; + short[] bcems; try { @@ -183,26 +184,26 @@ namespace DiscImageChef.DiscImages header = BigEndianMarshal.ByteArrayToStructureBigEndian(bcem); - DicConsole.DebugWriteLine("NDIF plugin", "footer.type = {0}", header.version); + DicConsole.DebugWriteLine("NDIF plugin", "footer.type = {0}", header.version); DicConsole.DebugWriteLine("NDIF plugin", "footer.driver = {0}", header.driver); DicConsole.DebugWriteLine("NDIF plugin", "footer.name = {0}", StringHandlers.PascalToString(header.name, Encoding.GetEncoding("macintosh"))); - DicConsole.DebugWriteLine("NDIF plugin", "footer.sectors = {0}", header.sectors); + DicConsole.DebugWriteLine("NDIF plugin", "footer.sectors = {0}", header.sectors); DicConsole.DebugWriteLine("NDIF plugin", "footer.maxSectorsPerChunk = {0}", header.maxSectorsPerChunk); - DicConsole.DebugWriteLine("NDIF plugin", "footer.dataOffset = {0}", header.dataOffset); - DicConsole.DebugWriteLine("NDIF plugin", "footer.crc = 0x{0:X7}", header.crc); - DicConsole.DebugWriteLine("NDIF plugin", "footer.segmented = {0}", header.segmented); - DicConsole.DebugWriteLine("NDIF plugin", "footer.p1 = 0x{0:X8}", header.p1); - DicConsole.DebugWriteLine("NDIF plugin", "footer.p2 = 0x{0:X8}", header.p2); - DicConsole.DebugWriteLine("NDIF plugin", "footer.unknown[0] = 0x{0:X8}", header.unknown[0]); - DicConsole.DebugWriteLine("NDIF plugin", "footer.unknown[1] = 0x{0:X8}", header.unknown[1]); - DicConsole.DebugWriteLine("NDIF plugin", "footer.unknown[2] = 0x{0:X8}", header.unknown[2]); - DicConsole.DebugWriteLine("NDIF plugin", "footer.unknown[3] = 0x{0:X8}", header.unknown[3]); - DicConsole.DebugWriteLine("NDIF plugin", "footer.unknown[4] = 0x{0:X8}", header.unknown[4]); - DicConsole.DebugWriteLine("NDIF plugin", "footer.encrypted = {0}", header.encrypted); - DicConsole.DebugWriteLine("NDIF plugin", "footer.hash = 0x{0:X8}", header.hash); - DicConsole.DebugWriteLine("NDIF plugin", "footer.chunks = {0}", header.chunks); + DicConsole.DebugWriteLine("NDIF plugin", "footer.dataOffset = {0}", header.dataOffset); + DicConsole.DebugWriteLine("NDIF plugin", "footer.crc = 0x{0:X7}", header.crc); + DicConsole.DebugWriteLine("NDIF plugin", "footer.segmented = {0}", header.segmented); + DicConsole.DebugWriteLine("NDIF plugin", "footer.p1 = 0x{0:X8}", header.p1); + DicConsole.DebugWriteLine("NDIF plugin", "footer.p2 = 0x{0:X8}", header.p2); + DicConsole.DebugWriteLine("NDIF plugin", "footer.unknown[0] = 0x{0:X8}", header.unknown[0]); + DicConsole.DebugWriteLine("NDIF plugin", "footer.unknown[1] = 0x{0:X8}", header.unknown[1]); + DicConsole.DebugWriteLine("NDIF plugin", "footer.unknown[2] = 0x{0:X8}", header.unknown[2]); + DicConsole.DebugWriteLine("NDIF plugin", "footer.unknown[3] = 0x{0:X8}", header.unknown[3]); + DicConsole.DebugWriteLine("NDIF plugin", "footer.unknown[4] = 0x{0:X8}", header.unknown[4]); + DicConsole.DebugWriteLine("NDIF plugin", "footer.encrypted = {0}", header.encrypted); + DicConsole.DebugWriteLine("NDIF plugin", "footer.hash = 0x{0:X8}", header.hash); + DicConsole.DebugWriteLine("NDIF plugin", "footer.chunks = {0}", header.chunks); // Block chunks and headers chunks = new Dictionary(); @@ -213,18 +214,18 @@ namespace DiscImageChef.DiscImages { // Obsolete read-only NDIF only prepended the header and then put the image without any kind of block references. // So let's falsify a block chunk - BlockChunk bChnk = new BlockChunk(); - byte[] sector = new byte[4]; + BlockChunk bChnk = new BlockChunk(); + byte[] sector = new byte[4]; Array.Copy(bcem, 128 + 0 + i * 12, sector, 1, 3); bChnk.sector = BigEndianBitConverter.ToUInt32(sector, 0); - bChnk.type = bcem[128 + 3 + i * 12]; + bChnk.type = bcem[128 + 3 + i * 12]; bChnk.offset = BigEndianBitConverter.ToUInt32(bcem, 128 + 4 + i * 12); bChnk.length = BigEndianBitConverter.ToUInt32(bcem, 128 + 8 + i * 12); DicConsole.DebugWriteLine("NDIF plugin", "bHdr.chunk[{0}].type = 0x{1:X2}", i, bChnk.type); - DicConsole.DebugWriteLine("NDIF plugin", "bHdr.chunk[{0}].sector = {1}", i, bChnk.sector); - DicConsole.DebugWriteLine("NDIF plugin", "bHdr.chunk[{0}].offset = {1}", i, bChnk.offset); - DicConsole.DebugWriteLine("NDIF plugin", "bHdr.chunk[{0}].length = {1}", i, bChnk.length); + DicConsole.DebugWriteLine("NDIF plugin", "bHdr.chunk[{0}].sector = {1}", i, bChnk.sector); + DicConsole.DebugWriteLine("NDIF plugin", "bHdr.chunk[{0}].offset = {1}", i, bChnk.offset); + DicConsole.DebugWriteLine("NDIF plugin", "bHdr.chunk[{0}].length = {1}", i, bChnk.length); if(bChnk.type == CHUNK_TYPE_END) break; @@ -245,10 +246,9 @@ namespace DiscImageChef.DiscImages } // TODO: Handle compressed chunks - if(bChnk.type > CHUNK_TYPE_COPY && bChnk.type < CHUNK_TYPE_KENCODE || - bChnk.type > CHUNK_TYPE_ADC && bChnk.type < CHUNK_TYPE_STUFFIT || - bChnk.type > CHUNK_TYPE_STUFFIT && bChnk.type < CHUNK_TYPE_END || - bChnk.type == 1) + if(bChnk.type > CHUNK_TYPE_COPY && bChnk.type < CHUNK_TYPE_KENCODE || + bChnk.type > CHUNK_TYPE_ADC && bChnk.type < CHUNK_TYPE_STUFFIT || + bChnk.type > CHUNK_TYPE_STUFFIT && bChnk.type < CHUNK_TYPE_END || bChnk.type == 1) throw new ImageNotSupportedException($"Unsupported chunk type 0x{bChnk.type:X8} found"); chunks.Add(bChnk.sector, bChnk); @@ -290,12 +290,12 @@ namespace DiscImageChef.DiscImages Version version = new Version(vers); string release = null; - string dev = null; - string pre = null; + string dev = null; + string pre = null; string major = $"{version.MajorVersion}"; string minor = $".{version.MinorVersion / 10}"; - if(version.MinorVersion % 10 > 0) release = $".{version.MinorVersion % 10}"; + if(version.MinorVersion % 10 > 0) release = $".{version.MinorVersion % 10}"; switch(version.DevStage) { case Version.DevelopmentStage.Alpha: @@ -314,58 +314,60 @@ namespace DiscImageChef.DiscImages if(dev != null) pre = $"{version.PreReleaseVersion}"; imageInfo.ApplicationVersion = $"{major}{minor}{release}{dev}{pre}"; - imageInfo.Application = version.VersionString; - imageInfo.Comments = version.VersionMessage; + imageInfo.Application = version.VersionString; + imageInfo.Comments = version.VersionMessage; - if(version.MajorVersion == 3) imageInfo.Application = "ShrinkWrapâ„¢"; - else if(version.MajorVersion == 6) imageInfo.Application = "DiskCopy"; + if(version.MajorVersion == 3) imageInfo.Application = "ShrinkWrapâ„¢"; + else if(version.MajorVersion == 6) + imageInfo.Application = "DiskCopy"; } } DicConsole.DebugWriteLine("NDIF plugin", "Image application = {0} version {1}", imageInfo.Application, imageInfo.ApplicationVersion); - sectorCache = new Dictionary(); - chunkCache = new Dictionary(); + sectorCache = new Dictionary(); + chunkCache = new Dictionary(); currentChunkCacheSize = 0; - imageStream = imageFilter.GetDataForkStream(); - buffersize = header.maxSectorsPerChunk * SECTOR_SIZE; + imageStream = imageFilter.GetDataForkStream(); + buffersize = header.maxSectorsPerChunk * SECTOR_SIZE; - imageInfo.CreationTime = imageFilter.GetCreationTime(); + imageInfo.CreationTime = imageFilter.GetCreationTime(); imageInfo.LastModificationTime = imageFilter.GetLastWriteTime(); - imageInfo.MediaTitle = StringHandlers.PascalToString(header.name, Encoding.GetEncoding("macintosh")); - imageInfo.SectorSize = SECTOR_SIZE; - imageInfo.XmlMediaType = XmlMediaType.BlockMedia; - imageInfo.ImageSize = imageInfo.Sectors * SECTOR_SIZE; + imageInfo.MediaTitle = + StringHandlers.PascalToString(header.name, Encoding.GetEncoding("macintosh")); + imageInfo.SectorSize = SECTOR_SIZE; + imageInfo.XmlMediaType = XmlMediaType.BlockMedia; + imageInfo.ImageSize = imageInfo.Sectors * SECTOR_SIZE; imageInfo.ApplicationVersion = "6"; - imageInfo.Application = "Apple DiskCopy"; + imageInfo.Application = "Apple DiskCopy"; switch(imageInfo.MediaType) { case MediaType.AppleSonyDS: - imageInfo.Cylinders = 80; - imageInfo.Heads = 2; + imageInfo.Cylinders = 80; + imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 10; break; case MediaType.DOS_35_DS_DD_9: - imageInfo.Cylinders = 80; - imageInfo.Heads = 2; + imageInfo.Cylinders = 80; + imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 9; break; case MediaType.DOS_35_HD: - imageInfo.Cylinders = 80; - imageInfo.Heads = 2; + imageInfo.Cylinders = 80; + imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 18; break; case MediaType.DMF: - imageInfo.Cylinders = 80; - imageInfo.Heads = 2; + imageInfo.Cylinders = 80; + imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 21; break; default: - imageInfo.MediaType = MediaType.GENERIC_HDD; - imageInfo.Cylinders = (uint)(imageInfo.Sectors / 16 / 63); - imageInfo.Heads = 16; + imageInfo.MediaType = MediaType.GENERIC_HDD; + imageInfo.Cylinders = (uint)(imageInfo.Sectors / 16 / 63); + imageInfo.Heads = 16; imageInfo.SectorsPerTrack = 63; break; } @@ -381,14 +383,14 @@ namespace DiscImageChef.DiscImages if(sectorCache.TryGetValue(sectorAddress, out byte[] sector)) return sector; - BlockChunk currentChunk = new BlockChunk(); - bool chunkFound = false; - ulong chunkStartSector = 0; + BlockChunk currentChunk = new BlockChunk(); + bool chunkFound = false; + ulong chunkStartSector = 0; foreach(KeyValuePair kvp in chunks.Where(kvp => sectorAddress >= kvp.Key)) { - currentChunk = kvp.Value; - chunkFound = true; + currentChunk = kvp.Value; + chunkFound = true; chunkStartSector = kvp.Key; } @@ -410,7 +412,7 @@ namespace DiscImageChef.DiscImages imageStream.Seek(currentChunk.offset, SeekOrigin.Begin); imageStream.Read(cmpBuffer, 0, cmpBuffer.Length); MemoryStream cmpMs = new MemoryStream(cmpBuffer); - int realSize = 0; + int realSize; switch(currentChunk.type) { @@ -585,7 +587,7 @@ namespace DiscImageChef.DiscImages } public bool? VerifySectors(ulong sectorAddress, uint length, out List failingLbas, - out List unknownLbas) + out List unknownLbas) { failingLbas = new List(); unknownLbas = new List(); @@ -595,7 +597,7 @@ namespace DiscImageChef.DiscImages } public bool? VerifySectors(ulong sectorAddress, uint length, uint track, out List failingLbas, - out List unknownLbas) + out List unknownLbas) { throw new FeatureUnsupportedImageException("Feature not supported by image format"); } @@ -605,6 +607,9 @@ namespace DiscImageChef.DiscImages return null; } + public List DumpHardware => null; + public CICMMetadataType CicmMetadata => null; + [StructLayout(LayoutKind.Sequential, Pack = 1)] struct ChunkHeader { @@ -619,7 +624,8 @@ namespace DiscImageChef.DiscImages /// /// Disk image name, Str63 (Pascal string) /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] public byte[] name; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] + public byte[] name; /// /// Sectors in image /// @@ -651,7 +657,8 @@ namespace DiscImageChef.DiscImages /// /// Unknown, spare? /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)] public uint[] unknown; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)] + public uint[] unknown; /// /// Set to 1 by ShrinkWrap if image is encrypted /// diff --git a/DiscImageChef.DiscImages/NHDr0.cs b/DiscImageChef.DiscImages/NHDr0.cs index 9a8d5365a..d7dc1eb24 100644 --- a/DiscImageChef.DiscImages/NHDr0.cs +++ b/DiscImageChef.DiscImages/NHDr0.cs @@ -39,6 +39,7 @@ using System.Text; using DiscImageChef.CommonTypes; using DiscImageChef.Console; using DiscImageChef.Filters; +using Schemas; namespace DiscImageChef.DiscImages { @@ -286,6 +287,9 @@ namespace DiscImageChef.DiscImages return null; } + public List DumpHardware => null; + public CICMMetadataType CicmMetadata => null; + public IEnumerable SupportedMediaTags => new MediaTagType[] { }; public IEnumerable SupportedSectorTags => new SectorTagType[] { }; public IEnumerable SupportedMediaTypes => new[] {MediaType.GENERIC_HDD, MediaType.Unknown}; @@ -518,6 +522,18 @@ namespace DiscImageChef.DiscImages return false; } + public bool SetDumpHardware(List dumpHardware) + { + // Not supported + return false; + } + + public bool SetCicmMetadata(CICMMetadataType metadata) + { + // Not supported + return false; + } + [StructLayout(LayoutKind.Sequential, Pack = 1)] struct Nhdr0Header { diff --git a/DiscImageChef.DiscImages/Nero.cs b/DiscImageChef.DiscImages/Nero.cs index 527cb0d87..d3d4d06f4 100644 --- a/DiscImageChef.DiscImages/Nero.cs +++ b/DiscImageChef.DiscImages/Nero.cs @@ -40,6 +40,7 @@ using DiscImageChef.Checksums; using DiscImageChef.CommonTypes; using DiscImageChef.Console; using DiscImageChef.Filters; +using Schemas; #pragma warning disable 414 #pragma warning disable 169 @@ -1624,6 +1625,9 @@ namespace DiscImageChef.DiscImages return null; } + public List DumpHardware => null; + public CICMMetadataType CicmMetadata => null; + static MediaType NeroMediaTypeToMediaType(NeroMediaTypes type) { switch(type) diff --git a/DiscImageChef.DiscImages/Parallels.cs b/DiscImageChef.DiscImages/Parallels.cs index 4de678f5e..dfbd4b96e 100644 --- a/DiscImageChef.DiscImages/Parallels.cs +++ b/DiscImageChef.DiscImages/Parallels.cs @@ -38,6 +38,7 @@ using System.Runtime.InteropServices; using DiscImageChef.CommonTypes; using DiscImageChef.Console; using DiscImageChef.Filters; +using Schemas; namespace DiscImageChef.DiscImages { @@ -346,6 +347,9 @@ namespace DiscImageChef.DiscImages return null; } + public List DumpHardware => null; + public CICMMetadataType CicmMetadata => null; + public IEnumerable SupportedMediaTags => new MediaTagType[] { }; public IEnumerable SupportedSectorTags => new SectorTagType[] { }; public IEnumerable SupportedMediaTypes => @@ -596,6 +600,18 @@ namespace DiscImageChef.DiscImages return false; } + public bool SetDumpHardware(List dumpHardware) + { + // Not supported + return false; + } + + public bool SetCicmMetadata(CICMMetadataType metadata) + { + // Not supported + return false; + } + /// /// Parallels disk image header, little-endian /// diff --git a/DiscImageChef.DiscImages/PartClone.cs b/DiscImageChef.DiscImages/PartClone.cs index d57f849a2..3c6f2c4da 100644 --- a/DiscImageChef.DiscImages/PartClone.cs +++ b/DiscImageChef.DiscImages/PartClone.cs @@ -39,6 +39,7 @@ using DiscImageChef.CommonTypes; using DiscImageChef.Console; using DiscImageChef.Filters; using Extents; +using Schemas; namespace DiscImageChef.DiscImages { @@ -46,20 +47,20 @@ namespace DiscImageChef.DiscImages { const int CRC_SIZE = 4; - const uint MAX_CACHE_SIZE = 16777216; - const uint MAX_CACHED_SECTORS = MAX_CACHE_SIZE / 512; - readonly byte[] biTmAgIc = {0x42, 0x69, 0x54, 0x6D, 0x41, 0x67, 0x49, 0x63}; - readonly byte[] partCloneMagic = + const uint MAX_CACHE_SIZE = 16777216; + const uint MAX_CACHED_SECTORS = MAX_CACHE_SIZE / 512; + readonly byte[] biTmAgIc = {0x42, 0x69, 0x54, 0x6D, 0x41, 0x67, 0x49, 0x63}; + readonly byte[] partCloneMagic = {0x70, 0x61, 0x72, 0x74, 0x63, 0x6C, 0x6F, 0x6E, 0x65, 0x2D, 0x69, 0x6D, 0x61, 0x67, 0x65}; // The used block "bitmap" uses one byte per block // TODO: Convert on-image bytemap to on-memory bitmap byte[] byteMap; - long dataOff; + long dataOff; - ExtentsULong extents; + ExtentsULong extents; Dictionary extentsOff; - ImageInfo imageInfo; - Stream imageStream; + ImageInfo imageInfo; + Stream imageStream; PartCloneHeader pHdr; @@ -69,30 +70,30 @@ namespace DiscImageChef.DiscImages { imageInfo = new ImageInfo { - ReadableSectorTags = new List(), - ReadableMediaTags = new List(), - HasPartitions = false, - HasSessions = false, - Application = "PartClone", - ApplicationVersion = null, - Creator = null, - Comments = null, - MediaManufacturer = null, - MediaModel = null, - MediaSerialNumber = null, - MediaBarcode = null, - MediaPartNumber = null, - MediaSequence = 0, - LastMediaSequence = 0, - DriveManufacturer = null, - DriveModel = null, - DriveSerialNumber = null, + ReadableSectorTags = new List(), + ReadableMediaTags = new List(), + HasPartitions = false, + HasSessions = false, + Application = "PartClone", + ApplicationVersion = null, + Creator = null, + Comments = null, + MediaManufacturer = null, + MediaModel = null, + MediaSerialNumber = null, + MediaBarcode = null, + MediaPartNumber = null, + MediaSequence = 0, + LastMediaSequence = 0, + DriveManufacturer = null, + DriveModel = null, + DriveSerialNumber = null, DriveFirmwareRevision = null }; } - public string Name => "PartClone disk image"; - public Guid Id => new Guid("AB1D7518-B548-4099-A4E2-C29C53DDE0C3"); + public string Name => "PartClone disk image"; + public Guid Id => new Guid("AB1D7518-B548-4099-A4E2-C29C53DDE0C3"); public ImageInfo Info => imageInfo; public string Format => "PartClone"; @@ -115,7 +116,7 @@ namespace DiscImageChef.DiscImages byte[] pHdrB = new byte[Marshal.SizeOf(pHdr)]; stream.Read(pHdrB, 0, Marshal.SizeOf(pHdr)); - pHdr = new PartCloneHeader(); + pHdr = new PartCloneHeader(); IntPtr headerPtr = Marshal.AllocHGlobal(Marshal.SizeOf(pHdr)); Marshal.Copy(pHdrB, 0, headerPtr, Marshal.SizeOf(pHdr)); pHdr = (PartCloneHeader)Marshal.PtrToStructure(headerPtr, typeof(PartCloneHeader)); @@ -140,7 +141,7 @@ namespace DiscImageChef.DiscImages byte[] pHdrB = new byte[Marshal.SizeOf(pHdr)]; stream.Read(pHdrB, 0, Marshal.SizeOf(pHdr)); - pHdr = new PartCloneHeader(); + pHdr = new PartCloneHeader(); IntPtr headerPtr = Marshal.AllocHGlobal(Marshal.SizeOf(pHdr)); Marshal.Copy(pHdrB, 0, headerPtr, Marshal.SizeOf(pHdr)); pHdr = (PartCloneHeader)Marshal.PtrToStructure(headerPtr, typeof(PartCloneHeader)); @@ -149,11 +150,12 @@ namespace DiscImageChef.DiscImages DicConsole.DebugWriteLine("PartClone plugin", "pHdr.magic = {0}", StringHandlers.CToString(pHdr.magic)); DicConsole.DebugWriteLine("PartClone plugin", "pHdr.filesystem = {0}", StringHandlers.CToString(pHdr.filesystem)); - DicConsole.DebugWriteLine("PartClone plugin", "pHdr.version = {0}", StringHandlers.CToString(pHdr.version)); - DicConsole.DebugWriteLine("PartClone plugin", "pHdr.blockSize = {0}", pHdr.blockSize); - DicConsole.DebugWriteLine("PartClone plugin", "pHdr.deviceSize = {0}", pHdr.deviceSize); + DicConsole.DebugWriteLine("PartClone plugin", "pHdr.version = {0}", + StringHandlers.CToString(pHdr.version)); + DicConsole.DebugWriteLine("PartClone plugin", "pHdr.blockSize = {0}", pHdr.blockSize); + DicConsole.DebugWriteLine("PartClone plugin", "pHdr.deviceSize = {0}", pHdr.deviceSize); DicConsole.DebugWriteLine("PartClone plugin", "pHdr.totalBlocks = {0}", pHdr.totalBlocks); - DicConsole.DebugWriteLine("PartClone plugin", "pHdr.usedBlocks = {0}", pHdr.usedBlocks); + DicConsole.DebugWriteLine("PartClone plugin", "pHdr.usedBlocks = {0}", pHdr.usedBlocks); byteMap = new byte[pHdr.totalBlocks]; DicConsole.DebugWriteLine("PartClone plugin", "Reading bytemap {0} bytes", byteMap.Length); @@ -171,11 +173,11 @@ namespace DiscImageChef.DiscImages DicConsole.DebugWriteLine("PartClone plugin", "pHdr.dataOff = {0}", dataOff); DicConsole.DebugWriteLine("PartClone plugin", "Filling extents"); - DateTime start = DateTime.Now; - extents = new ExtentsULong(); - extentsOff = new Dictionary(); - bool current = byteMap[0] > 0; - ulong blockOff = 0; + DateTime start = DateTime.Now; + extents = new ExtentsULong(); + extentsOff = new Dictionary(); + bool current = byteMap[0] > 0; + ulong blockOff = 0; ulong extentStart = 0; for(ulong i = 1; i < pHdr.totalBlocks; i++) @@ -206,26 +208,19 @@ namespace DiscImageChef.DiscImages sectorCache = new Dictionary(); - imageInfo.CreationTime = imageFilter.GetCreationTime(); + imageInfo.CreationTime = imageFilter.GetCreationTime(); imageInfo.LastModificationTime = imageFilter.GetLastWriteTime(); - imageInfo.MediaTitle = Path.GetFileNameWithoutExtension(imageFilter.GetFilename()); - imageInfo.Sectors = pHdr.totalBlocks; - imageInfo.SectorSize = pHdr.blockSize; - imageInfo.XmlMediaType = XmlMediaType.BlockMedia; - imageInfo.MediaType = MediaType.GENERIC_HDD; - imageInfo.ImageSize = (ulong)(stream.Length - (4096 + 0x40 + (long)pHdr.totalBlocks)); - imageStream = stream; + imageInfo.MediaTitle = Path.GetFileNameWithoutExtension(imageFilter.GetFilename()); + imageInfo.Sectors = pHdr.totalBlocks; + imageInfo.SectorSize = pHdr.blockSize; + imageInfo.XmlMediaType = XmlMediaType.BlockMedia; + imageInfo.MediaType = MediaType.GENERIC_HDD; + imageInfo.ImageSize = (ulong)(stream.Length - (4096 + 0x40 + (long)pHdr.totalBlocks)); + imageStream = stream; return true; } - ulong BlockOffset(ulong sectorAddress) - { - extents.GetStart(sectorAddress, out ulong extentStart); - extentsOff.TryGetValue(extentStart, out ulong extentStartingOffset); - return extentStartingOffset + (sectorAddress - extentStart); - } - public byte[] ReadSector(ulong sectorAddress) { if(sectorAddress > imageInfo.Sectors - 1) @@ -261,7 +256,7 @@ namespace DiscImageChef.DiscImages MemoryStream ms = new MemoryStream(); bool allEmpty = true; - for(uint i = 0; i < length; i++) + for(uint i = 0; i < length; i++) if(byteMap[sectorAddress + i] != 0) { allEmpty = false; @@ -355,7 +350,7 @@ namespace DiscImageChef.DiscImages } public bool? VerifySectors(ulong sectorAddress, uint length, out List failingLbas, - out List unknownLbas) + out List unknownLbas) { failingLbas = new List(); unknownLbas = new List(); @@ -365,7 +360,7 @@ namespace DiscImageChef.DiscImages } public bool? VerifySectors(ulong sectorAddress, uint length, uint track, out List failingLbas, - out List unknownLbas) + out List unknownLbas) { throw new FeatureUnsupportedImageException("Feature not supported by image format"); } @@ -376,6 +371,16 @@ namespace DiscImageChef.DiscImages return null; } + public List DumpHardware => null; + public CICMMetadataType CicmMetadata => null; + + ulong BlockOffset(ulong sectorAddress) + { + extents.GetStart(sectorAddress, out ulong extentStart); + extentsOff.TryGetValue(extentStart, out ulong extentStartingOffset); + return extentStartingOffset + (sectorAddress - extentStart); + } + /// /// PartClone disk image header, little-endian /// @@ -385,15 +390,18 @@ namespace DiscImageChef.DiscImages /// /// Magic, /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 15)] public byte[] magic; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 15)] + public byte[] magic; /// /// Source filesystem /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 15)] public byte[] filesystem; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 15)] + public byte[] filesystem; /// /// Version /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public byte[] version; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] + public byte[] version; /// /// Padding /// @@ -417,7 +425,8 @@ namespace DiscImageChef.DiscImages /// /// Empty space /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4096)] public byte[] buffer; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4096)] + public byte[] buffer; } } } \ No newline at end of file diff --git a/DiscImageChef.DiscImages/Partimage.cs b/DiscImageChef.DiscImages/Partimage.cs index 81068a9f7..242852cd0 100644 --- a/DiscImageChef.DiscImages/Partimage.cs +++ b/DiscImageChef.DiscImages/Partimage.cs @@ -39,6 +39,7 @@ using DiscImageChef.CommonTypes; using DiscImageChef.Console; using DiscImageChef.Filters; using Extents; +using Schemas; #pragma warning disable 649 @@ -46,50 +47,50 @@ namespace DiscImageChef.DiscImages { public class Partimage : IMediaImage { - const int MAX_DESCRIPTION = 4096; - const int MAX_HOSTNAMESIZE = 128; - const int MAX_DEVICENAMELEN = 512; - const int MAX_UNAMEINFOLEN = 65; //SYS_NMLN - const int MBR_SIZE_WHOLE = 512; - const int MAX_DESC_MODEL = 128; - const int MAX_DESC_GEOMETRY = 1024; - const int MAX_DESC_IDENTIFY = 4096; - const int CHECK_FREQUENCY = 65536; + const int MAX_DESCRIPTION = 4096; + const int MAX_HOSTNAMESIZE = 128; + const int MAX_DEVICENAMELEN = 512; + const int MAX_UNAMEINFOLEN = 65; //SYS_NMLN + const int MBR_SIZE_WHOLE = 512; + const int MAX_DESC_MODEL = 128; + const int MAX_DESC_GEOMETRY = 1024; + const int MAX_DESC_IDENTIFY = 4096; + const int CHECK_FREQUENCY = 65536; const string MAGIC_BEGIN_LOCALHEADER = "MAGIC-BEGIN-LOCALHEADER"; - const string MAGIC_BEGIN_DATABLOCKS = "MAGIC-BEGIN-DATABLOCKS"; - const string MAGIC_BEGIN_BITMAP = "MAGIC-BEGIN-BITMAP"; - const string MAGIC_BEGIN_MBRBACKUP = "MAGIC-BEGIN-MBRBACKUP"; - const string MAGIC_BEGIN_TAIL = "MAGIC-BEGIN-TAIL"; - const string MAGIC_BEGIN_INFO = "MAGIC-BEGIN-INFO"; - const string MAGIC_BEGIN_EXT000 = "MAGIC-BEGIN-EXT000"; // reserved for future use - const string MAGIC_BEGIN_EXT001 = "MAGIC-BEGIN-EXT001"; // reserved for future use - const string MAGIC_BEGIN_EXT002 = "MAGIC-BEGIN-EXT002"; // reserved for future use - const string MAGIC_BEGIN_EXT003 = "MAGIC-BEGIN-EXT003"; // reserved for future use - const string MAGIC_BEGIN_EXT004 = "MAGIC-BEGIN-EXT004"; // reserved for future use - const string MAGIC_BEGIN_EXT005 = "MAGIC-BEGIN-EXT005"; // reserved for future use - const string MAGIC_BEGIN_EXT006 = "MAGIC-BEGIN-EXT006"; // reserved for future use - const string MAGIC_BEGIN_EXT007 = "MAGIC-BEGIN-EXT007"; // reserved for future use - const string MAGIC_BEGIN_EXT008 = "MAGIC-BEGIN-EXT008"; // reserved for future use - const string MAGIC_BEGIN_EXT009 = "MAGIC-BEGIN-EXT009"; // reserved for future use - const string MAGIC_BEGIN_VOLUME = "PaRtImAgE-VoLuMe"; + const string MAGIC_BEGIN_DATABLOCKS = "MAGIC-BEGIN-DATABLOCKS"; + const string MAGIC_BEGIN_BITMAP = "MAGIC-BEGIN-BITMAP"; + const string MAGIC_BEGIN_MBRBACKUP = "MAGIC-BEGIN-MBRBACKUP"; + const string MAGIC_BEGIN_TAIL = "MAGIC-BEGIN-TAIL"; + const string MAGIC_BEGIN_INFO = "MAGIC-BEGIN-INFO"; + const string MAGIC_BEGIN_EXT000 = "MAGIC-BEGIN-EXT000"; // reserved for future use + const string MAGIC_BEGIN_EXT001 = "MAGIC-BEGIN-EXT001"; // reserved for future use + const string MAGIC_BEGIN_EXT002 = "MAGIC-BEGIN-EXT002"; // reserved for future use + const string MAGIC_BEGIN_EXT003 = "MAGIC-BEGIN-EXT003"; // reserved for future use + const string MAGIC_BEGIN_EXT004 = "MAGIC-BEGIN-EXT004"; // reserved for future use + const string MAGIC_BEGIN_EXT005 = "MAGIC-BEGIN-EXT005"; // reserved for future use + const string MAGIC_BEGIN_EXT006 = "MAGIC-BEGIN-EXT006"; // reserved for future use + const string MAGIC_BEGIN_EXT007 = "MAGIC-BEGIN-EXT007"; // reserved for future use + const string MAGIC_BEGIN_EXT008 = "MAGIC-BEGIN-EXT008"; // reserved for future use + const string MAGIC_BEGIN_EXT009 = "MAGIC-BEGIN-EXT009"; // reserved for future use + const string MAGIC_BEGIN_VOLUME = "PaRtImAgE-VoLuMe"; - const uint MAX_CACHE_SIZE = 16777216; - const uint MAX_CACHED_SECTORS = MAX_CACHE_SIZE / 512; - readonly byte[] partimageMagic = + const uint MAX_CACHE_SIZE = 16777216; + const uint MAX_CACHED_SECTORS = MAX_CACHE_SIZE / 512; + readonly byte[] partimageMagic = { 0x50, 0x61, 0x52, 0x74, 0x49, 0x6D, 0x41, 0x67, 0x45, 0x2D, 0x56, 0x6F, 0x4C, 0x75, 0x4D, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - byte[] bitmap; + byte[] bitmap; PartimageMainHeader cMainHeader; PartimageHeader cVolumeHeader; - long dataOff; + long dataOff; - ExtentsULong extents; + ExtentsULong extents; Dictionary extentsOff; - ImageInfo imageInfo; - Stream imageStream; + ImageInfo imageInfo; + Stream imageStream; Dictionary sectorCache; @@ -97,24 +98,24 @@ namespace DiscImageChef.DiscImages { imageInfo = new ImageInfo { - ReadableSectorTags = new List(), - ReadableMediaTags = new List(), - HasPartitions = false, - HasSessions = false, - Application = "Partimage", - ApplicationVersion = null, - Creator = null, - Comments = null, - MediaManufacturer = null, - MediaModel = null, - MediaSerialNumber = null, - MediaBarcode = null, - MediaPartNumber = null, - MediaSequence = 0, - LastMediaSequence = 0, - DriveManufacturer = null, - DriveModel = null, - DriveSerialNumber = null, + ReadableSectorTags = new List(), + ReadableMediaTags = new List(), + HasPartitions = false, + HasSessions = false, + Application = "Partimage", + ApplicationVersion = null, + Creator = null, + Comments = null, + MediaManufacturer = null, + MediaModel = null, + MediaSerialNumber = null, + MediaBarcode = null, + MediaPartNumber = null, + MediaSequence = 0, + LastMediaSequence = 0, + DriveManufacturer = null, + DriveModel = null, + DriveSerialNumber = null, DriveFirmwareRevision = null }; } @@ -122,7 +123,7 @@ namespace DiscImageChef.DiscImages public ImageInfo Info => imageInfo; public string Name => "Partimage disk image"; - public Guid Id => new Guid("AAFDB99D-2B77-49EA-831C-C9BB58C68C95"); + public Guid Id => new Guid("AAFDB99D-2B77-49EA-831C-C9BB58C68C95"); public string Format => "Partimage"; @@ -144,7 +145,7 @@ namespace DiscImageChef.DiscImages byte[] pHdrB = new byte[Marshal.SizeOf(cVolumeHeader)]; stream.Read(pHdrB, 0, Marshal.SizeOf(cVolumeHeader)); - cVolumeHeader = new PartimageHeader(); + cVolumeHeader = new PartimageHeader(); IntPtr headerPtr = Marshal.AllocHGlobal(Marshal.SizeOf(cVolumeHeader)); Marshal.Copy(pHdrB, 0, headerPtr, Marshal.SizeOf(cVolumeHeader)); cVolumeHeader = (PartimageHeader)Marshal.PtrToStructure(headerPtr, typeof(PartimageHeader)); @@ -162,7 +163,7 @@ namespace DiscImageChef.DiscImages byte[] hdrB = new byte[Marshal.SizeOf(cVolumeHeader)]; stream.Read(hdrB, 0, Marshal.SizeOf(cVolumeHeader)); - cVolumeHeader = new PartimageHeader(); + cVolumeHeader = new PartimageHeader(); IntPtr headerPtr = Marshal.AllocHGlobal(Marshal.SizeOf(cVolumeHeader)); Marshal.Copy(hdrB, 0, headerPtr, Marshal.SizeOf(cVolumeHeader)); cVolumeHeader = (PartimageHeader)Marshal.PtrToStructure(headerPtr, typeof(PartimageHeader)); @@ -184,7 +185,7 @@ namespace DiscImageChef.DiscImages hdrB = new byte[Marshal.SizeOf(cMainHeader)]; stream.Read(hdrB, 0, Marshal.SizeOf(cMainHeader)); cMainHeader = new PartimageMainHeader(); - headerPtr = Marshal.AllocHGlobal(Marshal.SizeOf(cMainHeader)); + headerPtr = Marshal.AllocHGlobal(Marshal.SizeOf(cMainHeader)); Marshal.Copy(hdrB, 0, headerPtr, Marshal.SizeOf(cMainHeader)); cMainHeader = (PartimageMainHeader)Marshal.PtrToStructure(headerPtr, typeof(PartimageMainHeader)); Marshal.FreeHGlobal(headerPtr); @@ -233,7 +234,7 @@ namespace DiscImageChef.DiscImages DicConsole.DebugWriteLine("Partimage plugin", "CMainHeader.dateCreate.tm_zone = {0}", cMainHeader.dateCreate.Timezone); - DateTime dateCreate = new DateTime(1900 + (int)cMainHeader.dateCreate.Year, + DateTime dateCreate = new DateTime(1900 + (int)cMainHeader.dateCreate.Year, (int)cMainHeader.dateCreate.Month + 1, (int)cMainHeader.dateCreate.DayOfMonth, (int)cMainHeader.dateCreate.Hour, (int)cMainHeader.dateCreate.Minute, (int)cMainHeader.dateCreate.Second); @@ -245,7 +246,7 @@ namespace DiscImageChef.DiscImages DicConsole.DebugWriteLine("Partimage plugin", "CMainHeader.szVersion = {0}", StringHandlers.CToString(cMainHeader.szVersion)); DicConsole.DebugWriteLine("Partimage plugin", "CMainHeader.dwMbrCount = {0}", cMainHeader.dwMbrCount); - DicConsole.DebugWriteLine("Partimage plugin", "CMainHeader.dwMbrSize = {0}", cMainHeader.dwMbrSize); + DicConsole.DebugWriteLine("Partimage plugin", "CMainHeader.dwMbrSize = {0}", cMainHeader.dwMbrSize); DicConsole.DebugWriteLine("Partimage plugin", "CMainHeader.dwEncryptAlgo = {0} ({1})", cMainHeader.dwEncryptAlgo, (uint)cMainHeader.dwEncryptAlgo); DicConsole.DebugWriteLine("Partimage plugin", "ArrayIsNullOrEmpty(CMainHeader.cHashTestKey) = {0}", @@ -306,7 +307,7 @@ namespace DiscImageChef.DiscImages CLocalHeader localHeader = (CLocalHeader)Marshal.PtrToStructure(headerPtr, typeof(CLocalHeader)); Marshal.FreeHGlobal(headerPtr); - DicConsole.DebugWriteLine("Partimage plugin", "CLocalHeader.qwBlockSize = {0}", localHeader.qwBlockSize); + DicConsole.DebugWriteLine("Partimage plugin", "CLocalHeader.qwBlockSize = {0}", localHeader.qwBlockSize); DicConsole.DebugWriteLine("Partimage plugin", "CLocalHeader.qwUsedBlocks = {0}", localHeader.qwUsedBlocks); DicConsole.DebugWriteLine("Partimage plugin", "CLocalHeader.qwBlocksCount = {0}", localHeader.qwBlocksCount); @@ -355,11 +356,11 @@ namespace DiscImageChef.DiscImages ImageNotSupportedException("Cannot find tail. Multiple volumes are not supported or image is corrupt."); DicConsole.DebugWriteLine("Partimage plugin", "Filling extents"); - DateTime start = DateTime.Now; - extents = new ExtentsULong(); - extentsOff = new Dictionary(); - bool current = (bitmap[0] & (1 << (0 % 8))) != 0; - ulong blockOff = 0; + DateTime start = DateTime.Now; + extents = new ExtentsULong(); + extentsOff = new Dictionary(); + bool current = (bitmap[0] & (1 << (0 % 8))) != 0; + ulong blockOff = 0; ulong extentStart = 0; for(ulong i = 1; i <= localHeader.qwBlocksCount; i++) @@ -376,7 +377,7 @@ namespace DiscImageChef.DiscImages else { extents.Add(extentStart, i); - extentsOff.TryGetValue(extentStart, out ulong foo); + extentsOff.TryGetValue(extentStart, out ulong _); } if(next && current) blockOff++; @@ -390,29 +391,22 @@ namespace DiscImageChef.DiscImages sectorCache = new Dictionary(); - imageInfo.CreationTime = dateCreate; + imageInfo.CreationTime = dateCreate; imageInfo.LastModificationTime = imageFilter.GetLastWriteTime(); - imageInfo.MediaTitle = Path.GetFileNameWithoutExtension(imageFilter.GetFilename()); - imageInfo.Sectors = localHeader.qwBlocksCount + 1; - imageInfo.SectorSize = (uint)localHeader.qwBlockSize; - imageInfo.XmlMediaType = XmlMediaType.BlockMedia; - imageInfo.MediaType = MediaType.GENERIC_HDD; - imageInfo.Version = StringHandlers.CToString(cMainHeader.szVersion); - imageInfo.Comments = StringHandlers.CToString(cMainHeader.szPartDescription); - imageInfo.ImageSize = + imageInfo.MediaTitle = Path.GetFileNameWithoutExtension(imageFilter.GetFilename()); + imageInfo.Sectors = localHeader.qwBlocksCount + 1; + imageInfo.SectorSize = (uint)localHeader.qwBlockSize; + imageInfo.XmlMediaType = XmlMediaType.BlockMedia; + imageInfo.MediaType = MediaType.GENERIC_HDD; + imageInfo.Version = StringHandlers.CToString(cMainHeader.szVersion); + imageInfo.Comments = StringHandlers.CToString(cMainHeader.szPartDescription); + imageInfo.ImageSize = (ulong)(stream.Length - (dataOff + Marshal.SizeOf(typeof(CMainTail)) + MAGIC_BEGIN_TAIL.Length)); imageStream = stream; return true; } - ulong BlockOffset(ulong sectorAddress) - { - extents.GetStart(sectorAddress, out ulong extentStart); - extentsOff.TryGetValue(extentStart, out ulong extentStartingOffset); - return extentStartingOffset + (sectorAddress - extentStart); - } - public byte[] ReadSector(ulong sectorAddress) { if(sectorAddress > imageInfo.Sectors - 1) @@ -462,7 +456,7 @@ namespace DiscImageChef.DiscImages MemoryStream ms = new MemoryStream(); bool allEmpty = true; - for(uint i = 0; i < length; i++) + for(uint i = 0; i < length; i++) if((bitmap[sectorAddress / 8] & (1 << (int)(sectorAddress % 8))) != 0) { allEmpty = false; @@ -556,7 +550,7 @@ namespace DiscImageChef.DiscImages } public bool? VerifySectors(ulong sectorAddress, uint length, out List failingLbas, - out List unknownLbas) + out List unknownLbas) { failingLbas = new List(); unknownLbas = new List(); @@ -566,7 +560,7 @@ namespace DiscImageChef.DiscImages } public bool? VerifySectors(ulong sectorAddress, uint length, uint track, out List failingLbas, - out List unknownLbas) + out List unknownLbas) { throw new FeatureUnsupportedImageException("Feature not supported by image format"); } @@ -577,6 +571,16 @@ namespace DiscImageChef.DiscImages return null; } + public List DumpHardware => null; + public CICMMetadataType CicmMetadata => null; + + ulong BlockOffset(ulong sectorAddress) + { + extents.GetStart(sectorAddress, out ulong extentStart); + extentsOff.TryGetValue(extentStart, out ulong extentStartingOffset); + return extentStartingOffset + (sectorAddress - extentStart); + } + /// /// Partimage disk image header, little-endian /// @@ -586,11 +590,13 @@ namespace DiscImageChef.DiscImages /// /// Magic, /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public byte[] magic; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] + public byte[] magic; /// /// Source filesystem /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] public byte[] version; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] + public byte[] version; /// /// Volume number /// @@ -602,7 +608,8 @@ namespace DiscImageChef.DiscImages /// /// Empty space /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 404)] public byte[] reserved; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 404)] + public byte[] reserved; } struct PortableTm @@ -623,10 +630,10 @@ namespace DiscImageChef.DiscImages enum PCompression : uint { - None = 0, - Gzip = 1, + None = 0, + Gzip = 1, Bzip2 = 2, - Lzo = 3 + Lzo = 3 } enum PEncryption : uint @@ -650,22 +657,29 @@ namespace DiscImageChef.DiscImages public byte[] szFirstImageFilepath; //MAXPATHLEN]; // for splitted image files // system and hardware infos - [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_UNAMEINFOLEN)] public byte[] szUnameSysname; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_UNAMEINFOLEN)] public byte[] szUnameNodename; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_UNAMEINFOLEN)] public byte[] szUnameRelease; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_UNAMEINFOLEN)] public byte[] szUnameVersion; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_UNAMEINFOLEN)] public byte[] szUnameMachine; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_UNAMEINFOLEN)] + public byte[] szUnameSysname; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_UNAMEINFOLEN)] + public byte[] szUnameNodename; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_UNAMEINFOLEN)] + public byte[] szUnameRelease; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_UNAMEINFOLEN)] + public byte[] szUnameVersion; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_UNAMEINFOLEN)] + public byte[] szUnameMachine; public PCompression dwCompression; // COMPRESS_XXXXXX - public uint dwMainFlags; - public PortableTm dateCreate; // date of image creation - public ulong qwPartSize; // size of the partition in bytes - [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_HOSTNAMESIZE)] public byte[] szHostname; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] public byte[] szVersion; // version of the image file + public uint dwMainFlags; + public PortableTm dateCreate; // date of image creation + public ulong qwPartSize; // size of the partition in bytes + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_HOSTNAMESIZE)] + public byte[] szHostname; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] + public byte[] szVersion; // version of the image file // MBR backup public uint dwMbrCount; // how many MBR are saved in the image file - public uint dwMbrSize; // size of a MBR record (allow to change the size in the next versions) + public uint dwMbrSize; // size of a MBR record (allow to change the size in the next versions) // future encryption support public PEncryption dwEncryptAlgo; // algo used to encrypt data @@ -693,15 +707,19 @@ namespace DiscImageChef.DiscImages [StructLayout(LayoutKind.Sequential, Pack = 1)] struct CMbr // must be 1024 { - [MarshalAs(UnmanagedType.ByValArray, SizeConst = MBR_SIZE_WHOLE)] public byte[] cData; - public uint dwDataCRC; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_DEVICENAMELEN)] public byte[] szDevice; // ex: "hda" + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MBR_SIZE_WHOLE)] + public byte[] cData; + public uint dwDataCRC; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_DEVICENAMELEN)] + public byte[] szDevice; // ex: "hda" // disk identificators ulong qwBlocksCount; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_DESC_MODEL)] public byte[] szDescModel; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_DESC_MODEL)] + public byte[] szDescModel; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 884)] public byte[] cReserved; // for future use + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 884)] + public byte[] cReserved; // for future use //public byte[] szDescGeometry[MAX_DESC_GEOMETRY]; //public byte[] szDescIdentify[MAX_DESC_IDENTIFY]; @@ -710,9 +728,10 @@ namespace DiscImageChef.DiscImages [StructLayout(LayoutKind.Sequential, Pack = 1)] struct CCheck { - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] byte[] cMagic; // must be 'C','H','K' - public uint dwCRC; // CRC of the CHECK_FREQUENCY blocks - public ulong qwPos; // number of the last block written + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] + byte[] cMagic; // must be 'C','H','K' + public uint dwCRC; // CRC of the CHECK_FREQUENCY blocks + public ulong qwPos; // number of the last block written } [StructLayout(LayoutKind.Sequential, Pack = 1)] @@ -723,7 +742,8 @@ namespace DiscImageChef.DiscImages public ulong qwBlocksCount; public ulong qwBitmapSize; // bytes in the bitmap public ulong qwBadBlocksCount; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] public byte[] szLabel; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] + public byte[] szLabel; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16280)] public byte[] cReserved; // Adjust to fit with total header size @@ -735,7 +755,7 @@ namespace DiscImageChef.DiscImages struct CMainTail // size must be 16384 (adjust the reserved data) { public ulong qwCRC; - public uint dwVolumeNumber; + public uint dwVolumeNumber; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16372)] public byte[] cReserved; // Adjust to fit with total header size diff --git a/DiscImageChef.DiscImages/QCOW.cs b/DiscImageChef.DiscImages/QCOW.cs index dcbfdb1b1..b88b5bd4f 100644 --- a/DiscImageChef.DiscImages/QCOW.cs +++ b/DiscImageChef.DiscImages/QCOW.cs @@ -38,6 +38,7 @@ using System.Runtime.InteropServices; using DiscImageChef.CommonTypes; using DiscImageChef.Console; using DiscImageChef.Filters; +using Schemas; using SharpCompress.Compressors; using SharpCompress.Compressors.Deflate; @@ -306,12 +307,9 @@ namespace DiscImageChef.DiscImages { if((offset & QCOW_COMPRESSED) == QCOW_COMPRESSED) { - ulong compSizeMask; - ulong offMask; - - compSizeMask = (ulong)(1 << qHdr.cluster_bits) - 1; - compSizeMask <<= 63 - qHdr.cluster_bits; - offMask = ~compSizeMask ^ QCOW_COMPRESSED; + ulong compSizeMask = (ulong)(1 << qHdr.cluster_bits) - 1; + compSizeMask <<= 63 - qHdr.cluster_bits; + ulong offMask = ~compSizeMask ^ QCOW_COMPRESSED; ulong realOff = offset & offMask; ulong compSize = (offset & compSizeMask) >> (63 - qHdr.cluster_bits); @@ -467,6 +465,9 @@ namespace DiscImageChef.DiscImages return null; } + public List DumpHardware => null; + public CICMMetadataType CicmMetadata => null; + public IEnumerable SupportedMediaTags => new MediaTagType[] { }; public IEnumerable SupportedSectorTags => new SectorTagType[] { }; public IEnumerable SupportedMediaTypes => @@ -749,6 +750,18 @@ namespace DiscImageChef.DiscImages return false; } + public bool SetDumpHardware(List dumpHardware) + { + // Not supported + return false; + } + + public bool SetCicmMetadata(CICMMetadataType metadata) + { + // Not supported + return false; + } + /// /// QCOW header, big-endian /// diff --git a/DiscImageChef.DiscImages/QCOW2.cs b/DiscImageChef.DiscImages/QCOW2.cs index 088158452..c377fc89b 100644 --- a/DiscImageChef.DiscImages/QCOW2.cs +++ b/DiscImageChef.DiscImages/QCOW2.cs @@ -38,6 +38,7 @@ using System.Runtime.InteropServices; using DiscImageChef.CommonTypes; using DiscImageChef.Console; using DiscImageChef.Filters; +using Schemas; using SharpCompress.Compressors; using SharpCompress.Compressors.Deflate; @@ -332,13 +333,10 @@ namespace DiscImageChef.DiscImages { if((offset & QCOW_COMPRESSED) == QCOW_COMPRESSED) { - ulong compSizeMask; - ulong offMask; - - compSizeMask = (ulong)(1 << (int)(qHdr.cluster_bits - 8)) - 1; - byte countbits = (byte)(qHdr.cluster_bits - 8); - compSizeMask <<= 62 - countbits; - offMask = ~compSizeMask & QCOW_FLAGS_MASK; + ulong compSizeMask = (ulong)(1 << (int)(qHdr.cluster_bits - 8)) - 1; + byte countbits = (byte)(qHdr.cluster_bits - 8); + compSizeMask <<= 62 - countbits; + ulong offMask = ~compSizeMask & QCOW_FLAGS_MASK; ulong realOff = offset & offMask; ulong compSize = (((offset & compSizeMask) >> (62 - countbits)) + 1) * 512; @@ -494,6 +492,9 @@ namespace DiscImageChef.DiscImages return null; } + public List DumpHardware => null; + public CICMMetadataType CicmMetadata => null; + public IEnumerable SupportedMediaTags => new MediaTagType[] { }; public IEnumerable SupportedSectorTags => new SectorTagType[] { }; public IEnumerable SupportedMediaTypes => @@ -824,6 +825,18 @@ namespace DiscImageChef.DiscImages return false; } + public bool SetDumpHardware(List dumpHardware) + { + // Not supported + return false; + } + + public bool SetCicmMetadata(CICMMetadataType metadata) + { + // Not supported + return false; + } + /// /// QCOW header, big-endian /// diff --git a/DiscImageChef.DiscImages/QED.cs b/DiscImageChef.DiscImages/QED.cs index d5b44bd0b..9dff8fea8 100644 --- a/DiscImageChef.DiscImages/QED.cs +++ b/DiscImageChef.DiscImages/QED.cs @@ -38,6 +38,7 @@ using System.Runtime.InteropServices; using DiscImageChef.CommonTypes; using DiscImageChef.Console; using DiscImageChef.Filters; +using Schemas; namespace DiscImageChef.DiscImages { @@ -447,6 +448,9 @@ namespace DiscImageChef.DiscImages return null; } + public List DumpHardware => null; + public CICMMetadataType CicmMetadata => null; + public IEnumerable SupportedMediaTags => new MediaTagType[] { }; public IEnumerable SupportedSectorTags => new SectorTagType[] { }; public IEnumerable SupportedMediaTypes => @@ -713,6 +717,18 @@ namespace DiscImageChef.DiscImages return false; } + public bool SetDumpHardware(List dumpHardware) + { + // Not supported + return false; + } + + public bool SetCicmMetadata(CICMMetadataType metadata) + { + // Not supported + return false; + } + static bool IsPowerOfTwo(uint x) { while((x & 1) == 0 && x > 1) x >>= 1; diff --git a/DiscImageChef.DiscImages/RayDIM.cs b/DiscImageChef.DiscImages/RayDIM.cs index 319599989..1bfc9c233 100644 --- a/DiscImageChef.DiscImages/RayDIM.cs +++ b/DiscImageChef.DiscImages/RayDIM.cs @@ -41,6 +41,7 @@ using System.Text.RegularExpressions; using DiscImageChef.CommonTypes; using DiscImageChef.Console; using DiscImageChef.Filters; +using Schemas; namespace DiscImageChef.DiscImages { @@ -227,6 +228,9 @@ namespace DiscImageChef.DiscImages return null; } + public List DumpHardware => null; + public CICMMetadataType CicmMetadata => null; + public byte[] ReadSector(ulong sectorAddress) { return ReadSectors(sectorAddress, 1); @@ -344,7 +348,7 @@ namespace DiscImageChef.DiscImages if(sectors > 255 * 255 * 255) { - ErrorMessage = $"Too many sectors"; + ErrorMessage = "Too many sectors"; return false; } @@ -476,6 +480,18 @@ namespace DiscImageChef.DiscImages return false; } + public bool SetDumpHardware(List dumpHardware) + { + // Not supported + return false; + } + + public bool SetCicmMetadata(CICMMetadataType metadata) + { + // Not supported + return false; + } + public bool Close() { if(!IsWriting) diff --git a/DiscImageChef.DiscImages/RsIde.cs b/DiscImageChef.DiscImages/RsIde.cs index b64a47d0a..b19527231 100644 --- a/DiscImageChef.DiscImages/RsIde.cs +++ b/DiscImageChef.DiscImages/RsIde.cs @@ -38,6 +38,7 @@ using System.Runtime.InteropServices; using System.Text; using DiscImageChef.CommonTypes; using DiscImageChef.Filters; +using Schemas; using static DiscImageChef.Decoders.ATA.Identify; namespace DiscImageChef.DiscImages @@ -289,6 +290,9 @@ namespace DiscImageChef.DiscImages return null; } + public List DumpHardware => null; + public CICMMetadataType CicmMetadata => null; + public IEnumerable SupportedMediaTags => new[] {MediaTagType.ATA_IDENTIFY}; public IEnumerable SupportedSectorTags => new SectorTagType[] { }; public IEnumerable SupportedMediaTypes => @@ -315,7 +319,7 @@ namespace DiscImageChef.DiscImages if(sectors > 63 * 16 * 1024) { - ErrorMessage = $"Too many sectors"; + ErrorMessage = "Too many sectors"; return false; } @@ -442,8 +446,6 @@ namespace DiscImageChef.DiscImages return false; } - Version thisVersion = GetType().Assembly.GetName().Version; - if(imageInfo.Cylinders == 0) { imageInfo.Cylinders = (uint)(imageInfo.Sectors / 16 / 63); @@ -514,10 +516,10 @@ namespace DiscImageChef.DiscImages Marshal.Copy(ptr, ataIdBytes, 0, Marshal.SizeOf(ataId)); Marshal.FreeHGlobal(ptr); - Array.Copy(ScrambleATAString(imageInfo.DriveManufacturer + " " + imageInfo.DriveModel, 40), 0, + Array.Copy(ScrambleAtaString(imageInfo.DriveManufacturer + " " + imageInfo.DriveModel, 40), 0, ataIdBytes, 27 * 2, 40); - Array.Copy(ScrambleATAString(imageInfo.DriveFirmwareRevision, 8), 0, ataIdBytes, 23 * 2, 8); - Array.Copy(ScrambleATAString(imageInfo.DriveSerialNumber, 20), 0, ataIdBytes, 10 * 2, 20); + Array.Copy(ScrambleAtaString(imageInfo.DriveFirmwareRevision, 8), 0, ataIdBytes, 23 * 2, 8); + Array.Copy(ScrambleAtaString(imageInfo.DriveSerialNumber, 20), 0, ataIdBytes, 10 * 2, 20); Array.Copy(ataIdBytes, 0, header.identify, 0, 106); } else Array.Copy(identify, 0, header.identify, 0, 106); @@ -588,7 +590,19 @@ namespace DiscImageChef.DiscImages return false; } - static byte[] ScrambleATAString(string text, int length) + public bool SetDumpHardware(List dumpHardware) + { + // Not supported + return false; + } + + public bool SetCicmMetadata(CICMMetadataType metadata) + { + // Not supported + return false; + } + + static byte[] ScrambleAtaString(string text, int length) { byte[] inbuf = Encoding.ASCII.GetBytes(text); if(inbuf.Length % 2 != 0) diff --git a/DiscImageChef.DiscImages/SaveDskF.cs b/DiscImageChef.DiscImages/SaveDskF.cs index e063e785b..01eb98ec4 100644 --- a/DiscImageChef.DiscImages/SaveDskF.cs +++ b/DiscImageChef.DiscImages/SaveDskF.cs @@ -39,6 +39,7 @@ using System.Text; using DiscImageChef.CommonTypes; using DiscImageChef.Console; using DiscImageChef.Filters; +using Schemas; namespace DiscImageChef.DiscImages { @@ -243,6 +244,9 @@ namespace DiscImageChef.DiscImages return calculatedChk == header.checksum; } + public List DumpHardware => null; + public CICMMetadataType CicmMetadata => null; + public byte[] ReadSector(ulong sectorAddress) { return ReadSectors(sectorAddress, 1); @@ -501,7 +505,7 @@ namespace DiscImageChef.DiscImages if(sectors > ushort.MaxValue) { - ErrorMessage = $"Too many sectors"; + ErrorMessage = "Too many sectors"; return false; } @@ -557,6 +561,18 @@ namespace DiscImageChef.DiscImages return false; } + public bool SetDumpHardware(List dumpHardware) + { + // Not supported + return false; + } + + public bool SetCicmMetadata(CICMMetadataType metadata) + { + // Not supported + return false; + } + [StructLayout(LayoutKind.Sequential, Pack = 1)] struct SaveDskFHeader { diff --git a/DiscImageChef.DiscImages/SuperCardPro.cs b/DiscImageChef.DiscImages/SuperCardPro.cs index de66af3b9..bb3bbb8f0 100644 --- a/DiscImageChef.DiscImages/SuperCardPro.cs +++ b/DiscImageChef.DiscImages/SuperCardPro.cs @@ -39,6 +39,7 @@ using System.Text; using DiscImageChef.CommonTypes; using DiscImageChef.Console; using DiscImageChef.Filters; +using Schemas; namespace DiscImageChef.DiscImages { @@ -46,28 +47,28 @@ namespace DiscImageChef.DiscImages { public enum ScpDiskType : byte { - Commodore64 = 0x00, + Commodore64 = 0x00, CommodoreAmiga = 0x04, - AtariFMSS = 0x10, - AtariFMDS = 0x11, - AtariFSEx = 0x12, - AtariSTSS = 0x14, - AtariSTDS = 0x15, - AppleII = 0x20, - AppleIIPro = 0x21, - Apple400K = 0x24, - Apple800K = 0x25, - Apple144 = 0x26, - PC360K = 0x30, - PC720K = 0x31, - PC12M = 0x32, - PC144M = 0x33, - TandySSSD = 0x40, - TandySSDD = 0x41, - TandyDSSD = 0x42, - TandyDSDD = 0x43, - Ti994A = 0x50, - RolandD20 = 0x60 + AtariFMSS = 0x10, + AtariFMDS = 0x11, + AtariFSEx = 0x12, + AtariSTSS = 0x14, + AtariSTDS = 0x15, + AppleII = 0x20, + AppleIIPro = 0x21, + Apple400K = 0x24, + Apple800K = 0x25, + Apple144 = 0x26, + PC360K = 0x30, + PC720K = 0x31, + PC12M = 0x32, + PC144M = 0x33, + TandySSSD = 0x40, + TandySSDD = 0x41, + TandyDSSD = 0x42, + TandyDSDD = 0x43, + Ti994A = 0x50, + RolandD20 = 0x60 } [Flags] @@ -114,34 +115,34 @@ namespace DiscImageChef.DiscImages readonly byte[] trkSignature = {0x54, 0x52, 0x4B}; // TODO: These variables have been made public so create-sidecar can access to this information until I define an API >4.0 - public ScpHeader Header; - ImageInfo imageInfo; - Stream scpStream; + public ScpHeader Header; + ImageInfo imageInfo; + Stream scpStream; public Dictionary ScpTracks; public SuperCardPro() { imageInfo = new ImageInfo { - ReadableSectorTags = new List(), - ReadableMediaTags = new List(), - HasPartitions = false, - HasSessions = false, - Version = null, - Application = null, - ApplicationVersion = null, - Creator = null, - Comments = null, - MediaManufacturer = null, - MediaModel = null, - MediaSerialNumber = null, - MediaBarcode = null, - MediaPartNumber = null, - MediaSequence = 0, - LastMediaSequence = 0, - DriveManufacturer = null, - DriveModel = null, - DriveSerialNumber = null, + ReadableSectorTags = new List(), + ReadableMediaTags = new List(), + HasPartitions = false, + HasSessions = false, + Version = null, + Application = null, + ApplicationVersion = null, + Creator = null, + Comments = null, + MediaManufacturer = null, + MediaModel = null, + MediaSerialNumber = null, + MediaBarcode = null, + MediaPartNumber = null, + MediaSequence = 0, + LastMediaSequence = 0, + DriveManufacturer = null, + DriveModel = null, + DriveSerialNumber = null, DriveFirmwareRevision = null }; } @@ -149,7 +150,7 @@ namespace DiscImageChef.DiscImages public ImageInfo Info => imageInfo; public string Name => "SuperCardPro"; - public Guid Id => new Guid("C5D3182E-1D45-4767-A205-E6E5C83444DC"); + public Guid Id => new Guid("C5D3182E-1D45-4767-A205-E6E5C83444DC"); public string Format => "SuperCardPro"; @@ -164,7 +165,7 @@ namespace DiscImageChef.DiscImages public bool Identify(IFilter imageFilter) { - Header = new ScpHeader(); + Header = new ScpHeader(); Stream stream = imageFilter.GetDataForkStream(); stream.Seek(0, SeekOrigin.Begin); if(stream.Length < Marshal.SizeOf(Header)) return false; @@ -182,7 +183,7 @@ namespace DiscImageChef.DiscImages public bool Open(IFilter imageFilter) { - Header = new ScpHeader(); + Header = new ScpHeader(); scpStream = imageFilter.GetDataForkStream(); scpStream.Seek(0, SeekOrigin.Begin); if(scpStream.Length < Marshal.SizeOf(Header)) return false; @@ -198,16 +199,16 @@ namespace DiscImageChef.DiscImages DicConsole.DebugWriteLine("SuperCardPro plugin", "header.signature = \"{0}\"", StringHandlers.CToString(Header.signature)); DicConsole.DebugWriteLine("SuperCardPro plugin", "header.version = {0}.{1}", (Header.version & 0xF0) >> 4, - Header.version & 0xF); - DicConsole.DebugWriteLine("SuperCardPro plugin", "header.type = {0}", Header.type); - DicConsole.DebugWriteLine("SuperCardPro plugin", "header.revolutions = {0}", Header.revolutions); - DicConsole.DebugWriteLine("SuperCardPro plugin", "header.start = {0}", Header.start); - DicConsole.DebugWriteLine("SuperCardPro plugin", "header.end = {0}", Header.end); - DicConsole.DebugWriteLine("SuperCardPro plugin", "header.flags = {0}", Header.flags); + Header.version & 0xF); + DicConsole.DebugWriteLine("SuperCardPro plugin", "header.type = {0}", Header.type); + DicConsole.DebugWriteLine("SuperCardPro plugin", "header.revolutions = {0}", Header.revolutions); + DicConsole.DebugWriteLine("SuperCardPro plugin", "header.start = {0}", Header.start); + DicConsole.DebugWriteLine("SuperCardPro plugin", "header.end = {0}", Header.end); + DicConsole.DebugWriteLine("SuperCardPro plugin", "header.flags = {0}", Header.flags); DicConsole.DebugWriteLine("SuperCardPro plugin", "header.bitCellEncoding = {0}", Header.bitCellEncoding); - DicConsole.DebugWriteLine("SuperCardPro plugin", "header.heads = {0}", Header.heads); - DicConsole.DebugWriteLine("SuperCardPro plugin", "header.reserved = {0}", Header.reserved); - DicConsole.DebugWriteLine("SuperCardPro plugin", "header.checksum = 0x{0:X8}", Header.checksum); + DicConsole.DebugWriteLine("SuperCardPro plugin", "header.heads = {0}", Header.heads); + DicConsole.DebugWriteLine("SuperCardPro plugin", "header.reserved = {0}", Header.reserved); + DicConsole.DebugWriteLine("SuperCardPro plugin", "header.checksum = 0x{0:X8}", Header.checksum); if(!scpSignature.SequenceEqual(Header.signature)) return false; @@ -217,8 +218,8 @@ namespace DiscImageChef.DiscImages { if(t >= Header.offsets.Length) break; - scpStream.Position = Header.offsets[t]; - TrackHeader trk = + scpStream.Position = Header.offsets[t]; + TrackHeader trk = new TrackHeader {Signature = new byte[3], Entries = new TrackEntry[Header.revolutions]}; scpStream.Read(trk.Signature, 0, trk.Signature.Length); trk.TrackNumber = (byte)scpStream.ReadByte(); @@ -298,7 +299,7 @@ namespace DiscImageChef.DiscImages footer.modificationTime); DicConsole.DebugWriteLine("SuperCardPro plugin", "footer.applicationVersion = {0}.{1}", (footer.applicationVersion & 0xF0) >> 4, - footer.applicationVersion & 0xF); + footer.applicationVersion & 0xF); DicConsole.DebugWriteLine("SuperCardPro plugin", "footer.hardwareVersion = {0}.{1}", (footer.hardwareVersion & 0xF0) >> 4, footer.hardwareVersion & 0xF); DicConsole.DebugWriteLine("SuperCardPro plugin", "footer.firmwareVersion = {0}.{1}", @@ -309,11 +310,11 @@ namespace DiscImageChef.DiscImages StringHandlers.CToString(BitConverter.GetBytes(footer.signature))); imageInfo.DriveManufacturer = ReadPStringUtf8(scpStream, footer.manufacturerOffset); - imageInfo.DriveModel = ReadPStringUtf8(scpStream, footer.modelOffset); + imageInfo.DriveModel = ReadPStringUtf8(scpStream, footer.modelOffset); imageInfo.DriveSerialNumber = ReadPStringUtf8(scpStream, footer.serialOffset); - imageInfo.Creator = ReadPStringUtf8(scpStream, footer.creatorOffset); - imageInfo.Application = ReadPStringUtf8(scpStream, footer.applicationOffset); - imageInfo.Comments = ReadPStringUtf8(scpStream, footer.commentsOffset); + imageInfo.Creator = ReadPStringUtf8(scpStream, footer.creatorOffset); + imageInfo.Application = ReadPStringUtf8(scpStream, footer.applicationOffset); + imageInfo.Comments = ReadPStringUtf8(scpStream, footer.commentsOffset); DicConsole.DebugWriteLine("SuperCardPro plugin", "ImageInfo.driveManufacturer = \"{0}\"", imageInfo.DriveManufacturer); @@ -344,8 +345,8 @@ namespace DiscImageChef.DiscImages imageInfo.ApplicationVersion = $"{(footer.applicationVersion & 0xF0) >> 4}.{footer.applicationVersion & 0xF}"; imageInfo.DriveFirmwareRevision = - $"{(footer.firmwareVersion & 0xF0) >> 4}.{footer.firmwareVersion & 0xF}"; - imageInfo.Version = $"{(footer.imageVersion & 0xF0) >> 4}.{footer.imageVersion & 0xF}"; + $"{(footer.firmwareVersion & 0xF0) >> 4}.{footer.firmwareVersion & 0xF}"; + imageInfo.Version = $"{(footer.imageVersion & 0xF0) >> 4}.{footer.imageVersion & 0xF}"; break; } @@ -355,33 +356,16 @@ namespace DiscImageChef.DiscImages } else { - imageInfo.Application = "SuperCardPro"; - imageInfo.ApplicationVersion = $"{(Header.version & 0xF0) >> 4}.{Header.version & 0xF}"; - imageInfo.CreationTime = imageFilter.GetCreationTime(); + imageInfo.Application = "SuperCardPro"; + imageInfo.ApplicationVersion = $"{(Header.version & 0xF0) >> 4}.{Header.version & 0xF}"; + imageInfo.CreationTime = imageFilter.GetCreationTime(); imageInfo.LastModificationTime = imageFilter.GetLastWriteTime(); - imageInfo.Version = "1.5"; + imageInfo.Version = "1.5"; } throw new NotImplementedException("Flux decoding is not yet implemented."); } - static string ReadPStringUtf8(Stream stream, uint position) - { - if(position == 0) return null; - - stream.Position = position; - byte[] lenB = new byte[2]; - stream.Read(lenB, 0, 2); - ushort len = BitConverter.ToUInt16(lenB, 0); - - if(len == 0 || len + stream.Position >= stream.Length) return null; - - byte[] str = new byte[len]; - stream.Read(str, 0, len); - - return Encoding.UTF8.GetString(str); - } - public byte[] ReadDiskTag(MediaTagType tag) { throw new NotImplementedException("Flux decoding is not yet implemented."); @@ -428,7 +412,7 @@ namespace DiscImageChef.DiscImages } public bool? VerifySectors(ulong sectorAddress, uint length, out List failingLbas, - out List unknownLbas) + out List unknownLbas) { throw new NotImplementedException("Flux decoding is not yet implemented."); } @@ -438,7 +422,7 @@ namespace DiscImageChef.DiscImages if(Header.flags.HasFlag(ScpFlags.Writable)) return null; byte[] wholeFile = new byte[scpStream.Length]; - uint sum = 0; + uint sum = 0; scpStream.Position = 0; scpStream.Read(wholeFile, 0, wholeFile.Length); @@ -448,6 +432,9 @@ namespace DiscImageChef.DiscImages return Header.checksum == sum; } + public List DumpHardware => null; + public CICMMetadataType CicmMetadata => null; + public byte[] ReadSector(ulong sectorAddress, uint track) { throw new FeatureUnsupportedImageException("Feature not supported by image format"); @@ -489,32 +476,52 @@ namespace DiscImageChef.DiscImages } public bool? VerifySectors(ulong sectorAddress, uint length, uint track, out List failingLbas, - out List unknownLbas) + out List unknownLbas) { throw new FeatureUnsupportedImageException("Feature not supported by image format"); } + static string ReadPStringUtf8(Stream stream, uint position) + { + if(position == 0) return null; + + stream.Position = position; + byte[] lenB = new byte[2]; + stream.Read(lenB, 0, 2); + ushort len = BitConverter.ToUInt16(lenB, 0); + + if(len == 0 || len + stream.Position >= stream.Length) return null; + + byte[] str = new byte[len]; + stream.Read(str, 0, len); + + return Encoding.UTF8.GetString(str); + } + [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct ScpHeader { - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public byte[] signature; - public byte version; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] + public byte[] signature; + public byte version; public ScpDiskType type; - public byte revolutions; - public byte start; - public byte end; - public ScpFlags flags; - public byte bitCellEncoding; - public byte heads; - public byte reserved; - public uint checksum; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 168)] public uint[] offsets; + public byte revolutions; + public byte start; + public byte end; + public ScpFlags flags; + public byte bitCellEncoding; + public byte heads; + public byte reserved; + public uint checksum; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 168)] + public uint[] offsets; } public struct TrackHeader { - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public byte[] Signature; - public byte TrackNumber; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] + public byte[] Signature; + public byte TrackNumber; public TrackEntry[] Entries; } diff --git a/DiscImageChef.DiscImages/T98.cs b/DiscImageChef.DiscImages/T98.cs index 424ab57f1..f0131f366 100644 --- a/DiscImageChef.DiscImages/T98.cs +++ b/DiscImageChef.DiscImages/T98.cs @@ -37,6 +37,7 @@ using System.Linq; using DiscImageChef.CommonTypes; using DiscImageChef.Console; using DiscImageChef.Filters; +using Schemas; namespace DiscImageChef.DiscImages { @@ -265,6 +266,9 @@ namespace DiscImageChef.DiscImages return null; } + public List DumpHardware => null; + public CICMMetadataType CicmMetadata => null; + public IEnumerable SupportedMediaTags => new MediaTagType[] { }; public IEnumerable SupportedSectorTags => new SectorTagType[] { }; public IEnumerable SupportedMediaTypes => @@ -425,6 +429,18 @@ namespace DiscImageChef.DiscImages return false; } + public bool SetDumpHardware(List dumpHardware) + { + // Not supported + return false; + } + + public bool SetCicmMetadata(CICMMetadataType metadata) + { + // Not supported + return false; + } + public bool SetMetadata(ImageInfo metadata) { return true; diff --git a/DiscImageChef.DiscImages/TeleDisk.cs b/DiscImageChef.DiscImages/TeleDisk.cs index 7289edcb6..a03923db1 100644 --- a/DiscImageChef.DiscImages/TeleDisk.cs +++ b/DiscImageChef.DiscImages/TeleDisk.cs @@ -38,6 +38,7 @@ using DiscImageChef.CommonTypes; using DiscImageChef.Compression; using DiscImageChef.Console; using DiscImageChef.Filters; +using Schemas; namespace DiscImageChef.DiscImages { @@ -57,16 +58,16 @@ namespace DiscImageChef.DiscImages // TeleDisk drive types const byte DRIVE_TYPE_525_HD_DD_DISK = 0x00; - const byte DRIVE_TYPE_525_HD = 0x01; - const byte DRIVE_TYPE_525_DD = 0x02; - const byte DRIVE_TYPE_35_DD = 0x03; - const byte DRIVE_TYPE_35_HD = 0x04; - const byte DRIVE_TYPE_8_INCH = 0x05; - const byte DRIVE_TYPE_35_ED = 0x06; + const byte DRIVE_TYPE_525_HD = 0x01; + const byte DRIVE_TYPE_525_DD = 0x02; + const byte DRIVE_TYPE_35_DD = 0x03; + const byte DRIVE_TYPE_35_HD = 0x04; + const byte DRIVE_TYPE_8_INCH = 0x05; + const byte DRIVE_TYPE_35_ED = 0x06; // Stepping - const byte STEPPING_SINGLE = 0x00; - const byte STEPPING_DOUBLE = 0x01; + const byte STEPPING_SINGLE = 0x00; + const byte STEPPING_DOUBLE = 0x01; const byte STEPPING_EVEN_ONLY = 0x02; // If this bit is set, there is a comment block const byte COMMENT_BLOCK_PRESENT = 0x80; @@ -78,10 +79,10 @@ namespace DiscImageChef.DiscImages const byte SECTOR_SIZE_128 = 0x00; const byte SECTOR_SIZE_256 = 0x01; const byte SECTOR_SIZE_512 = 0x02; - const byte SECTOR_SIZE_1K = 0x03; - const byte SECTOR_SIZE_2K = 0x04; - const byte SECTOR_SIZE_4K = 0x05; - const byte SECTOR_SIZE_8K = 0x06; + const byte SECTOR_SIZE_1K = 0x03; + const byte SECTOR_SIZE_2K = 0x04; + const byte SECTOR_SIZE_4K = 0x05; + const byte SECTOR_SIZE_8K = 0x06; // Flags // Address mark repeats inside same track @@ -104,53 +105,53 @@ namespace DiscImageChef.DiscImages const byte DATA_BLOCK_PATTERN = 0x01; // Data is encoded as RLE const byte DATA_BLOCK_RLE = 0x02; - bool aDiskCrcHasFailed; - byte[] commentBlock; + + const int BUFSZ = 512; + bool aDiskCrcHasFailed; + byte[] commentBlock; TeleDiskCommentBlockHeader commentHeader; TeleDiskHeader header; - ImageInfo imageInfo; - Stream inStream; - byte[] leadOut; + ImageInfo imageInfo; + Stream inStream; + byte[] leadOut; // Cylinder by head, sector data matrix byte[][][][] sectorsData; - List sectorsWhereCrcHasFailed; + List sectorsWhereCrcHasFailed; // LBA, data uint totalDiskSize; - const int BUFSZ = 512; - public TeleDisk() { imageInfo = new ImageInfo { - ReadableSectorTags = new List(), - ReadableMediaTags = new List(), - HasPartitions = false, - HasSessions = false, - Application = "Sydex TeleDisk", - Comments = null, - Creator = null, - MediaManufacturer = null, - MediaModel = null, - MediaSerialNumber = null, - MediaBarcode = null, - MediaPartNumber = null, - MediaSequence = 0, - LastMediaSequence = 0, - DriveManufacturer = null, - DriveModel = null, - DriveSerialNumber = null, + ReadableSectorTags = new List(), + ReadableMediaTags = new List(), + HasPartitions = false, + HasSessions = false, + Application = "Sydex TeleDisk", + Comments = null, + Creator = null, + MediaManufacturer = null, + MediaModel = null, + MediaSerialNumber = null, + MediaBarcode = null, + MediaPartNumber = null, + MediaSequence = 0, + LastMediaSequence = 0, + DriveManufacturer = null, + DriveModel = null, + DriveSerialNumber = null, DriveFirmwareRevision = null }; - aDiskCrcHasFailed = false; + aDiskCrcHasFailed = false; sectorsWhereCrcHasFailed = new List(); } public ImageInfo Info => imageInfo; public string Name => "Sydex TeleDisk"; - public Guid Id => new Guid("0240B7B1-E959-4CDC-B0BD-386D6E467B88"); + public Guid Id => new Guid("0240B7B1-E959-4CDC-B0BD-386D6E467B88"); public string Format => "Sydex TeleDisk"; @@ -165,9 +166,9 @@ namespace DiscImageChef.DiscImages public bool Identify(IFilter imageFilter) { - header = new TeleDiskHeader(); + header = new TeleDiskHeader(); byte[] headerBytes = new byte[12]; - Stream stream = imageFilter.GetDataForkStream(); + Stream stream = imageFilter.GetDataForkStream(); stream.Seek(0, SeekOrigin.Begin); stream.Read(headerBytes, 0, 12); @@ -176,30 +177,30 @@ namespace DiscImageChef.DiscImages if(header.Signature != TD_MAGIC && header.Signature != TD_ADV_COMP_MAGIC) return false; - header.Sequence = headerBytes[2]; - header.DiskSet = headerBytes[3]; - header.Version = headerBytes[4]; - header.DataRate = headerBytes[5]; - header.DriveType = headerBytes[6]; - header.Stepping = headerBytes[7]; + header.Sequence = headerBytes[2]; + header.DiskSet = headerBytes[3]; + header.Version = headerBytes[4]; + header.DataRate = headerBytes[5]; + header.DriveType = headerBytes[6]; + header.Stepping = headerBytes[7]; header.DosAllocation = headerBytes[8]; - header.Sides = headerBytes[9]; - header.Crc = BitConverter.ToUInt16(headerBytes, 10); + header.Sides = headerBytes[9]; + header.Crc = BitConverter.ToUInt16(headerBytes, 10); byte[] headerBytesForCrc = new byte[10]; Array.Copy(headerBytes, headerBytesForCrc, 10); ushort calculatedHeaderCrc = TeleDiskCrc(0x0000, headerBytesForCrc); - DicConsole.DebugWriteLine("TeleDisk plugin", "header.signature = 0x{0:X4}", header.Signature); - DicConsole.DebugWriteLine("TeleDisk plugin", "header.sequence = 0x{0:X2}", header.Sequence); - DicConsole.DebugWriteLine("TeleDisk plugin", "header.diskSet = 0x{0:X2}", header.DiskSet); - DicConsole.DebugWriteLine("TeleDisk plugin", "header.version = 0x{0:X2}", header.Version); - DicConsole.DebugWriteLine("TeleDisk plugin", "header.dataRate = 0x{0:X2}", header.DataRate); - DicConsole.DebugWriteLine("TeleDisk plugin", "header.driveType = 0x{0:X2}", header.DriveType); - DicConsole.DebugWriteLine("TeleDisk plugin", "header.stepping = 0x{0:X2}", header.Stepping); - DicConsole.DebugWriteLine("TeleDisk plugin", "header.dosAllocation = 0x{0:X2}", header.DosAllocation); - DicConsole.DebugWriteLine("TeleDisk plugin", "header.sides = 0x{0:X2}", header.Sides); - DicConsole.DebugWriteLine("TeleDisk plugin", "header.crc = 0x{0:X4}", header.Crc); + DicConsole.DebugWriteLine("TeleDisk plugin", "header.signature = 0x{0:X4}", header.Signature); + DicConsole.DebugWriteLine("TeleDisk plugin", "header.sequence = 0x{0:X2}", header.Sequence); + DicConsole.DebugWriteLine("TeleDisk plugin", "header.diskSet = 0x{0:X2}", header.DiskSet); + DicConsole.DebugWriteLine("TeleDisk plugin", "header.version = 0x{0:X2}", header.Version); + DicConsole.DebugWriteLine("TeleDisk plugin", "header.dataRate = 0x{0:X2}", header.DataRate); + DicConsole.DebugWriteLine("TeleDisk plugin", "header.driveType = 0x{0:X2}", header.DriveType); + DicConsole.DebugWriteLine("TeleDisk plugin", "header.stepping = 0x{0:X2}", header.Stepping); + DicConsole.DebugWriteLine("TeleDisk plugin", "header.dosAllocation = 0x{0:X2}", header.DosAllocation); + DicConsole.DebugWriteLine("TeleDisk plugin", "header.sides = 0x{0:X2}", header.Sides); + DicConsole.DebugWriteLine("TeleDisk plugin", "header.crc = 0x{0:X4}", header.Crc); DicConsole.DebugWriteLine("TeleDisk plugin", "calculated header crc = 0x{0:X4}", calculatedHeaderCrc); // We need more checks as the magic is too simply. @@ -213,17 +214,17 @@ namespace DiscImageChef.DiscImages if(header.DataRate != DATA_RATE_250KBPS && header.DataRate != DATA_RATE_300KBPS && header.DataRate != DATA_RATE_500KBPS) return false; - return header.DriveType == DRIVE_TYPE_35_DD || header.DriveType == DRIVE_TYPE_35_ED || - header.DriveType == DRIVE_TYPE_35_HD || header.DriveType == DRIVE_TYPE_525_DD || + return header.DriveType == DRIVE_TYPE_35_DD || header.DriveType == DRIVE_TYPE_35_ED || + header.DriveType == DRIVE_TYPE_35_HD || header.DriveType == DRIVE_TYPE_525_DD || header.DriveType == DRIVE_TYPE_525_HD || header.DriveType == DRIVE_TYPE_525_HD_DD_DISK || header.DriveType == DRIVE_TYPE_8_INCH; } public bool Open(IFilter imageFilter) { - header = new TeleDiskHeader(); - byte[] headerBytes = new byte[12]; - inStream = imageFilter.GetDataForkStream(); + header = new TeleDiskHeader(); + byte[] headerBytes = new byte[12]; + inStream = imageFilter.GetDataForkStream(); MemoryStream stream = new MemoryStream(); inStream.Seek(0, SeekOrigin.Begin); @@ -234,34 +235,34 @@ namespace DiscImageChef.DiscImages if(header.Signature != TD_MAGIC && header.Signature != TD_ADV_COMP_MAGIC) return false; - header.Sequence = headerBytes[2]; - header.DiskSet = headerBytes[3]; - header.Version = headerBytes[4]; - header.DataRate = headerBytes[5]; - header.DriveType = headerBytes[6]; - header.Stepping = headerBytes[7]; + header.Sequence = headerBytes[2]; + header.DiskSet = headerBytes[3]; + header.Version = headerBytes[4]; + header.DataRate = headerBytes[5]; + header.DriveType = headerBytes[6]; + header.Stepping = headerBytes[7]; header.DosAllocation = headerBytes[8]; - header.Sides = headerBytes[9]; - header.Crc = BitConverter.ToUInt16(headerBytes, 10); + header.Sides = headerBytes[9]; + header.Crc = BitConverter.ToUInt16(headerBytes, 10); - imageInfo.MediaTitle = Path.GetFileNameWithoutExtension(imageFilter.GetFilename()); - imageInfo.Version = $"{(header.Version & 0xF0) >> 4}.{header.Version & 0x0F}"; + imageInfo.MediaTitle = Path.GetFileNameWithoutExtension(imageFilter.GetFilename()); + imageInfo.Version = $"{(header.Version & 0xF0) >> 4}.{header.Version & 0x0F}"; imageInfo.Application = imageInfo.Version; byte[] headerBytesForCrc = new byte[10]; Array.Copy(headerBytes, headerBytesForCrc, 10); ushort calculatedHeaderCrc = TeleDiskCrc(0x0000, headerBytesForCrc); - DicConsole.DebugWriteLine("TeleDisk plugin", "header.signature = 0x{0:X4}", header.Signature); - DicConsole.DebugWriteLine("TeleDisk plugin", "header.sequence = 0x{0:X2}", header.Sequence); - DicConsole.DebugWriteLine("TeleDisk plugin", "header.diskSet = 0x{0:X2}", header.DiskSet); - DicConsole.DebugWriteLine("TeleDisk plugin", "header.version = 0x{0:X2}", header.Version); - DicConsole.DebugWriteLine("TeleDisk plugin", "header.dataRate = 0x{0:X2}", header.DataRate); - DicConsole.DebugWriteLine("TeleDisk plugin", "header.driveType = 0x{0:X2}", header.DriveType); - DicConsole.DebugWriteLine("TeleDisk plugin", "header.stepping = 0x{0:X2}", header.Stepping); - DicConsole.DebugWriteLine("TeleDisk plugin", "header.dosAllocation = 0x{0:X2}", header.DosAllocation); - DicConsole.DebugWriteLine("TeleDisk plugin", "header.sides = 0x{0:X2}", header.Sides); - DicConsole.DebugWriteLine("TeleDisk plugin", "header.crc = 0x{0:X4}", header.Crc); + DicConsole.DebugWriteLine("TeleDisk plugin", "header.signature = 0x{0:X4}", header.Signature); + DicConsole.DebugWriteLine("TeleDisk plugin", "header.sequence = 0x{0:X2}", header.Sequence); + DicConsole.DebugWriteLine("TeleDisk plugin", "header.diskSet = 0x{0:X2}", header.DiskSet); + DicConsole.DebugWriteLine("TeleDisk plugin", "header.version = 0x{0:X2}", header.Version); + DicConsole.DebugWriteLine("TeleDisk plugin", "header.dataRate = 0x{0:X2}", header.DataRate); + DicConsole.DebugWriteLine("TeleDisk plugin", "header.driveType = 0x{0:X2}", header.DriveType); + DicConsole.DebugWriteLine("TeleDisk plugin", "header.stepping = 0x{0:X2}", header.Stepping); + DicConsole.DebugWriteLine("TeleDisk plugin", "header.dosAllocation = 0x{0:X2}", header.DosAllocation); + DicConsole.DebugWriteLine("TeleDisk plugin", "header.sides = 0x{0:X2}", header.Sides); + DicConsole.DebugWriteLine("TeleDisk plugin", "header.crc = 0x{0:X4}", header.Crc); DicConsole.DebugWriteLine("TeleDisk plugin", "calculated header crc = 0x{0:X4}", calculatedHeaderCrc); // We need more checks as the magic is too simply. @@ -279,8 +280,8 @@ namespace DiscImageChef.DiscImages if(header.DataRate != DATA_RATE_250KBPS && header.DataRate != DATA_RATE_300KBPS && header.DataRate != DATA_RATE_500KBPS) return false; - if(header.DriveType != DRIVE_TYPE_35_DD && header.DriveType != DRIVE_TYPE_35_ED && - header.DriveType != DRIVE_TYPE_35_HD && header.DriveType != DRIVE_TYPE_525_DD && + if(header.DriveType != DRIVE_TYPE_35_DD && header.DriveType != DRIVE_TYPE_35_ED && + header.DriveType != DRIVE_TYPE_35_HD && header.DriveType != DRIVE_TYPE_525_DD && header.DriveType != DRIVE_TYPE_525_HD && header.DriveType != DRIVE_TYPE_525_HD_DD_DISK && header.DriveType != DRIVE_TYPE_8_INCH) return false; @@ -290,7 +291,9 @@ namespace DiscImageChef.DiscImages inStream.Seek(12, SeekOrigin.Begin); stream.Seek(12, SeekOrigin.Begin); TeleDiskLzh lzh = new TeleDiskLzh(inStream); - do if((rd = lzh.Decode(out byte[] obuf, BUFSZ)) > 0) stream.Write(obuf, 0, rd); + do + if((rd = lzh.Decode(out byte[] obuf, BUFSZ)) > 0) + stream.Write(obuf, 0, rd); while(rd == BUFSZ); } else @@ -314,12 +317,12 @@ namespace DiscImageChef.DiscImages byte[] commentHeaderBytes = new byte[10]; stream.Read(commentHeaderBytes, 0, 10); - commentHeader.Crc = BitConverter.ToUInt16(commentHeaderBytes, 0); + commentHeader.Crc = BitConverter.ToUInt16(commentHeaderBytes, 0); commentHeader.Length = BitConverter.ToUInt16(commentHeaderBytes, 2); - commentHeader.Year = commentHeaderBytes[4]; - commentHeader.Month = commentHeaderBytes[5]; - commentHeader.Day = commentHeaderBytes[6]; - commentHeader.Hour = commentHeaderBytes[7]; + commentHeader.Year = commentHeaderBytes[4]; + commentHeader.Month = commentHeaderBytes[5]; + commentHeader.Day = commentHeaderBytes[6]; + commentHeader.Hour = commentHeaderBytes[7]; commentHeader.Minute = commentHeaderBytes[8]; commentHeader.Second = commentHeaderBytes[9]; @@ -328,19 +331,19 @@ namespace DiscImageChef.DiscImages byte[] commentBlockForCrc = new byte[commentHeader.Length + 8]; Array.Copy(commentHeaderBytes, 2, commentBlockForCrc, 0, 8); - Array.Copy(commentBlock, 0, commentBlockForCrc, 8, commentHeader.Length); + Array.Copy(commentBlock, 0, commentBlockForCrc, 8, commentHeader.Length); ushort cmtcrc = TeleDiskCrc(0, commentBlockForCrc); DicConsole.DebugWriteLine("TeleDisk plugin", "Comment header"); DicConsole.DebugWriteLine("TeleDisk plugin", "\tcommentheader.crc = 0x{0:X4}", commentHeader.Crc); - DicConsole.DebugWriteLine("TeleDisk plugin", "\tCalculated CRC = 0x{0:X4}", cmtcrc); + DicConsole.DebugWriteLine("TeleDisk plugin", "\tCalculated CRC = 0x{0:X4}", cmtcrc); DicConsole.DebugWriteLine("TeleDisk plugin", "\tcommentheader.length = {0} bytes", commentHeader.Length); - DicConsole.DebugWriteLine("TeleDisk plugin", "\tcommentheader.year = {0}", commentHeader.Year); - DicConsole.DebugWriteLine("TeleDisk plugin", "\tcommentheader.month = {0}", commentHeader.Month); - DicConsole.DebugWriteLine("TeleDisk plugin", "\tcommentheader.day = {0}", commentHeader.Day); - DicConsole.DebugWriteLine("TeleDisk plugin", "\tcommentheader.hour = {0}", commentHeader.Hour); + DicConsole.DebugWriteLine("TeleDisk plugin", "\tcommentheader.year = {0}", commentHeader.Year); + DicConsole.DebugWriteLine("TeleDisk plugin", "\tcommentheader.month = {0}", commentHeader.Month); + DicConsole.DebugWriteLine("TeleDisk plugin", "\tcommentheader.day = {0}", commentHeader.Day); + DicConsole.DebugWriteLine("TeleDisk plugin", "\tcommentheader.hour = {0}", commentHeader.Hour); DicConsole.DebugWriteLine("TeleDisk plugin", "\tcommentheader.minute = {0}", commentHeader.Minute); DicConsole.DebugWriteLine("TeleDisk plugin", "\tcommentheader.second = {0}", commentHeader.Second); @@ -348,7 +351,8 @@ namespace DiscImageChef.DiscImages for(int i = 0; i < commentBlock.Length; i++) // Replace NULLs, used by TeleDisk as newline markers, with UNIX newline marker - if(commentBlock[i] == 0x00) commentBlock[i] = 0x0A; + if(commentBlock[i] == 0x00) + commentBlock[i] = 0x0A; imageInfo.Comments = Encoding.ASCII.GetString(commentBlock); @@ -361,22 +365,22 @@ namespace DiscImageChef.DiscImages } if(imageInfo.CreationTime == DateTime.MinValue) imageInfo.CreationTime = imageFilter.GetCreationTime(); - imageInfo.LastModificationTime = imageFilter.GetLastWriteTime(); + imageInfo.LastModificationTime = imageFilter.GetLastWriteTime(); - DicConsole.DebugWriteLine("TeleDisk plugin", "Image created on {0}", imageInfo.CreationTime); + DicConsole.DebugWriteLine("TeleDisk plugin", "Image created on {0}", imageInfo.CreationTime); DicConsole.DebugWriteLine("TeleDisk plugin", "Image modified on {0}", imageInfo.LastModificationTime); DicConsole.DebugWriteLine("TeleDisk plugin", "Parsing image"); - totalDiskSize = 0; + totalDiskSize = 0; imageInfo.ImageSize = 0; - int totalCylinders = -1; - int totalHeads = -1; - int maxSector = -1; - int totalSectors = 0; - long currentPos = stream.Position; - imageInfo.SectorSize = uint.MaxValue; + int totalCylinders = -1; + int totalHeads = -1; + int maxSector = -1; + int totalSectors = 0; + long currentPos = stream.Position; + imageInfo.SectorSize = uint.MaxValue; imageInfo.SectorsPerTrack = uint.MaxValue; // Count cylinders @@ -384,14 +388,14 @@ namespace DiscImageChef.DiscImages { TeleDiskTrackHeader teleDiskTrack = new TeleDiskTrackHeader { - Sectors = (byte)stream.ReadByte(), + Sectors = (byte)stream.ReadByte(), Cylinder = (byte)stream.ReadByte(), - Head = (byte)stream.ReadByte(), - Crc = (byte)stream.ReadByte() + Head = (byte)stream.ReadByte(), + Crc = (byte)stream.ReadByte() }; if(teleDiskTrack.Cylinder > totalCylinders) totalCylinders = teleDiskTrack.Cylinder; - if(teleDiskTrack.Head > totalHeads) totalHeads = teleDiskTrack.Head; + if(teleDiskTrack.Head > totalHeads) totalHeads = teleDiskTrack.Head; if(teleDiskTrack.Sectors == 0xFF) // End of disk image break; @@ -399,30 +403,30 @@ namespace DiscImageChef.DiscImages for(byte processedSectors = 0; processedSectors < teleDiskTrack.Sectors; processedSectors++) { TeleDiskSectorHeader teleDiskSector = new TeleDiskSectorHeader(); - TeleDiskDataHeader teleDiskData = new TeleDiskDataHeader(); - byte[] dataSizeBytes = new byte[2]; + TeleDiskDataHeader teleDiskData = new TeleDiskDataHeader(); + byte[] dataSizeBytes = new byte[2]; - teleDiskSector.Cylinder = (byte)stream.ReadByte(); - teleDiskSector.Head = (byte)stream.ReadByte(); + teleDiskSector.Cylinder = (byte)stream.ReadByte(); + teleDiskSector.Head = (byte)stream.ReadByte(); teleDiskSector.SectorNumber = (byte)stream.ReadByte(); - teleDiskSector.SectorSize = (byte)stream.ReadByte(); - teleDiskSector.Flags = (byte)stream.ReadByte(); - teleDiskSector.Crc = (byte)stream.ReadByte(); + teleDiskSector.SectorSize = (byte)stream.ReadByte(); + teleDiskSector.Flags = (byte)stream.ReadByte(); + teleDiskSector.Crc = (byte)stream.ReadByte(); if(teleDiskSector.SectorNumber > maxSector) maxSector = teleDiskSector.SectorNumber; if((teleDiskSector.Flags & FLAGS_SECTOR_DATALESS) != FLAGS_SECTOR_DATALESS && - (teleDiskSector.Flags & FLAGS_SECTOR_SKIPPED) != FLAGS_SECTOR_SKIPPED) + (teleDiskSector.Flags & FLAGS_SECTOR_SKIPPED) != FLAGS_SECTOR_SKIPPED) { stream.Read(dataSizeBytes, 0, 2); teleDiskData.DataSize = BitConverter.ToUInt16(dataSizeBytes, 0); teleDiskData.DataSize--; // Sydex decided to including dataEncoding byte as part of it teleDiskData.DataEncoding = (byte)stream.ReadByte(); - byte[] data = new byte[teleDiskData.DataSize]; + byte[] data = new byte[teleDiskData.DataSize]; stream.Read(data, 0, teleDiskData.DataSize); } - if(128 << teleDiskSector.SectorSize < imageInfo.SectorSize) + if(128 << teleDiskSector.SectorSize < imageInfo.SectorSize) imageInfo.SectorSize = (uint)(128 << teleDiskSector.SectorSize); totalSectors++; @@ -437,8 +441,8 @@ namespace DiscImageChef.DiscImages bool hasLeadOutOnHead0 = false; bool hasLeadOutOnHead1 = false; - imageInfo.Cylinders = (ushort)totalCylinders; - imageInfo.Heads = (byte)totalHeads; + imageInfo.Cylinders = (ushort)totalCylinders; + imageInfo.Heads = (byte)totalHeads; // Count sectors per track stream.Seek(currentPos, SeekOrigin.Begin); @@ -446,44 +450,46 @@ namespace DiscImageChef.DiscImages { TeleDiskTrackHeader teleDiskTrack = new TeleDiskTrackHeader { - Sectors = (byte)stream.ReadByte(), + Sectors = (byte)stream.ReadByte(), Cylinder = (byte)stream.ReadByte(), - Head = (byte)stream.ReadByte(), - Crc = (byte)stream.ReadByte() + Head = (byte)stream.ReadByte(), + Crc = (byte)stream.ReadByte() }; if(teleDiskTrack.Sectors == 0xFF) // End of disk image break; - if(teleDiskTrack.Sectors < imageInfo.SectorsPerTrack) + if(teleDiskTrack.Sectors < imageInfo.SectorsPerTrack) if(teleDiskTrack.Cylinder + 1 == totalCylinders) { hasLeadOutOnHead0 |= teleDiskTrack.Head == 0; hasLeadOutOnHead1 |= teleDiskTrack.Head == 1; - if(imageInfo.Cylinders == totalCylinders) imageInfo.Cylinders--; + if(imageInfo.Cylinders == totalCylinders) imageInfo.Cylinders--; } - else imageInfo.SectorsPerTrack = teleDiskTrack.Sectors; + else + imageInfo.SectorsPerTrack = teleDiskTrack.Sectors; + for(byte processedSectors = 0; processedSectors < teleDiskTrack.Sectors; processedSectors++) { TeleDiskSectorHeader teleDiskSector = new TeleDiskSectorHeader(); - TeleDiskDataHeader teleDiskData = new TeleDiskDataHeader(); - byte[] dataSizeBytes = new byte[2]; + TeleDiskDataHeader teleDiskData = new TeleDiskDataHeader(); + byte[] dataSizeBytes = new byte[2]; - teleDiskSector.Cylinder = (byte)stream.ReadByte(); - teleDiskSector.Head = (byte)stream.ReadByte(); + teleDiskSector.Cylinder = (byte)stream.ReadByte(); + teleDiskSector.Head = (byte)stream.ReadByte(); teleDiskSector.SectorNumber = (byte)stream.ReadByte(); - teleDiskSector.SectorSize = (byte)stream.ReadByte(); - teleDiskSector.Flags = (byte)stream.ReadByte(); - teleDiskSector.Crc = (byte)stream.ReadByte(); + teleDiskSector.SectorSize = (byte)stream.ReadByte(); + teleDiskSector.Flags = (byte)stream.ReadByte(); + teleDiskSector.Crc = (byte)stream.ReadByte(); if((teleDiskSector.Flags & FLAGS_SECTOR_DATALESS) == FLAGS_SECTOR_DATALESS || - (teleDiskSector.Flags & FLAGS_SECTOR_SKIPPED) == FLAGS_SECTOR_SKIPPED) continue; + (teleDiskSector.Flags & FLAGS_SECTOR_SKIPPED) == FLAGS_SECTOR_SKIPPED) continue; stream.Read(dataSizeBytes, 0, 2); teleDiskData.DataSize = BitConverter.ToUInt16(dataSizeBytes, 0); teleDiskData.DataSize--; // Sydex decided to including dataEncoding byte as part of it teleDiskData.DataEncoding = (byte)stream.ReadByte(); - byte[] data = new byte[teleDiskData.DataSize]; + byte[] data = new byte[teleDiskData.DataSize]; stream.Read(data, 0, teleDiskData.DataSize); } } @@ -500,7 +506,7 @@ namespace DiscImageChef.DiscImages for(int i = 0; i < totalCylinders; i++) { sectorsData[i] = new byte[totalHeads][][]; - spts[i] = new uint[totalHeads]; + spts[i] = new uint[totalHeads]; for(int j = 0; j < totalHeads; j++) sectorsData[i][j] = new byte[maxSector + 1][]; } @@ -510,23 +516,22 @@ namespace DiscImageChef.DiscImages while(true) { TeleDiskTrackHeader teleDiskTrack = new TeleDiskTrackHeader(); - byte[] tdTrackForCrc = new byte[3]; - byte tdTrackCalculatedCrc; + byte[] tdTrackForCrc = new byte[3]; - teleDiskTrack.Sectors = (byte)stream.ReadByte(); + teleDiskTrack.Sectors = (byte)stream.ReadByte(); teleDiskTrack.Cylinder = (byte)stream.ReadByte(); - teleDiskTrack.Head = (byte)stream.ReadByte(); - teleDiskTrack.Crc = (byte)stream.ReadByte(); + teleDiskTrack.Head = (byte)stream.ReadByte(); + teleDiskTrack.Crc = (byte)stream.ReadByte(); tdTrackForCrc[0] = teleDiskTrack.Sectors; tdTrackForCrc[1] = teleDiskTrack.Cylinder; tdTrackForCrc[2] = teleDiskTrack.Head; - tdTrackCalculatedCrc = (byte)(TeleDiskCrc(0, tdTrackForCrc) & 0xFF); + byte tdTrackCalculatedCrc = (byte)(TeleDiskCrc(0, tdTrackForCrc) & 0xFF); DicConsole.DebugWriteLine("TeleDisk plugin", "Track follows"); - DicConsole.DebugWriteLine("TeleDisk plugin", "\tTrack cylinder: {0}\t", teleDiskTrack.Cylinder); - DicConsole.DebugWriteLine("TeleDisk plugin", "\tTrack head: {0}\t", teleDiskTrack.Head); + DicConsole.DebugWriteLine("TeleDisk plugin", "\tTrack cylinder: {0}\t", teleDiskTrack.Cylinder); + DicConsole.DebugWriteLine("TeleDisk plugin", "\tTrack head: {0}\t", teleDiskTrack.Head); DicConsole.DebugWriteLine("TeleDisk plugin", "\tSectors in track: {0}\t", teleDiskTrack.Sectors); DicConsole.DebugWriteLine("TeleDisk plugin", "\tTrack header CRC: 0x{0:X2} (calculated 0x{1:X2})\t", teleDiskTrack.Crc, tdTrackCalculatedCrc); @@ -545,16 +550,16 @@ namespace DiscImageChef.DiscImages for(byte processedSectors = 0; processedSectors < teleDiskTrack.Sectors; processedSectors++) { TeleDiskSectorHeader teleDiskSector = new TeleDiskSectorHeader(); - TeleDiskDataHeader teleDiskData = new TeleDiskDataHeader(); - byte[] dataSizeBytes = new byte[2]; - byte[] decodedData; + TeleDiskDataHeader teleDiskData = new TeleDiskDataHeader(); + byte[] dataSizeBytes = new byte[2]; + byte[] decodedData; - teleDiskSector.Cylinder = (byte)stream.ReadByte(); - teleDiskSector.Head = (byte)stream.ReadByte(); + teleDiskSector.Cylinder = (byte)stream.ReadByte(); + teleDiskSector.Head = (byte)stream.ReadByte(); teleDiskSector.SectorNumber = (byte)stream.ReadByte(); - teleDiskSector.SectorSize = (byte)stream.ReadByte(); - teleDiskSector.Flags = (byte)stream.ReadByte(); - teleDiskSector.Crc = (byte)stream.ReadByte(); + teleDiskSector.SectorSize = (byte)stream.ReadByte(); + teleDiskSector.Flags = (byte)stream.ReadByte(); + teleDiskSector.Crc = (byte)stream.ReadByte(); DicConsole.DebugWriteLine("TeleDisk plugin", "\tSector follows"); DicConsole.DebugWriteLine("TeleDisk plugin", "\t\tAddressMark cylinder: {0}", @@ -562,23 +567,24 @@ namespace DiscImageChef.DiscImages DicConsole.DebugWriteLine("TeleDisk plugin", "\t\tAddressMark head: {0}", teleDiskSector.Head); DicConsole.DebugWriteLine("TeleDisk plugin", "\t\tAddressMark sector number: {0}", teleDiskSector.SectorNumber); - DicConsole.DebugWriteLine("TeleDisk plugin", "\t\tSector size: {0}", teleDiskSector.SectorSize); + DicConsole.DebugWriteLine("TeleDisk plugin", "\t\tSector size: {0}", + teleDiskSector.SectorSize); DicConsole.DebugWriteLine("TeleDisk plugin", "\t\tSector flags: 0x{0:X2}", teleDiskSector.Flags); DicConsole.DebugWriteLine("TeleDisk plugin", "\t\tSector CRC (plus headers): 0x{0:X2}", teleDiskSector.Crc); uint lba = (uint)(teleDiskSector.Cylinder * header.Sides * imageInfo.SectorsPerTrack + - teleDiskSector.Head * imageInfo.SectorsPerTrack + - (teleDiskSector.SectorNumber - 1)); + teleDiskSector.Head * imageInfo.SectorsPerTrack + + (teleDiskSector.SectorNumber - 1)); if((teleDiskSector.Flags & FLAGS_SECTOR_DATALESS) != FLAGS_SECTOR_DATALESS && - (teleDiskSector.Flags & FLAGS_SECTOR_SKIPPED) != FLAGS_SECTOR_SKIPPED) + (teleDiskSector.Flags & FLAGS_SECTOR_SKIPPED) != FLAGS_SECTOR_SKIPPED) { stream.Read(dataSizeBytes, 0, 2); teleDiskData.DataSize = BitConverter.ToUInt16(dataSizeBytes, 0); teleDiskData.DataSize--; // Sydex decided to including dataEncoding byte as part of it - imageInfo.ImageSize += teleDiskData.DataSize; - teleDiskData.DataEncoding = (byte)stream.ReadByte(); - byte[] data = new byte[teleDiskData.DataSize]; + imageInfo.ImageSize += teleDiskData.DataSize; + teleDiskData.DataEncoding = (byte)stream.ReadByte(); + byte[] data = new byte[teleDiskData.DataSize]; stream.Read(data, 0, teleDiskData.DataSize); DicConsole.DebugWriteLine("TeleDisk plugin", "\t\tData size (in-image): {0}", teleDiskData.DataSize); @@ -624,13 +630,13 @@ namespace DiscImageChef.DiscImages MemoryStream leadOutMs = new MemoryStream(); if(hasLeadOutOnHead0) - for(int i = 0; i < sectorsData[totalCylinders - 1][0].Length; i++) - if(sectorsData[totalCylinders - 1][0][i] != null) + for(int i = 0; i < sectorsData[totalCylinders - 1][0].Length; i++) + if(sectorsData[totalCylinders - 1][0][i] != null) leadOutMs.Write(sectorsData[totalCylinders - 1][0][i], 0, sectorsData[totalCylinders - 1][0][i].Length); if(hasLeadOutOnHead1) - for(int i = 0; i < sectorsData[totalCylinders - 1][1].Length; i++) - if(sectorsData[totalCylinders - 1][1][i] != null) + for(int i = 0; i < sectorsData[totalCylinders - 1][1].Length; i++) + if(sectorsData[totalCylinders - 1][1][i] != null) leadOutMs.Write(sectorsData[totalCylinders - 1][1][i], 0, sectorsData[totalCylinders - 1][1][i].Length); @@ -640,7 +646,7 @@ namespace DiscImageChef.DiscImages imageInfo.ReadableMediaTags.Add(MediaTagType.Floppy_LeadOut); } - imageInfo.Sectors = imageInfo.Cylinders * imageInfo.Heads * imageInfo.SectorsPerTrack; + imageInfo.Sectors = imageInfo.Cylinders * imageInfo.Heads * imageInfo.SectorsPerTrack; imageInfo.MediaType = DecodeTeleDiskDiskType(); imageInfo.XmlMediaType = XmlMediaType.BlockMedia; @@ -689,15 +695,6 @@ namespace DiscImageChef.DiscImages return buffer.ToArray(); } - (ushort cylinder, byte head, byte sector) LbaToChs(ulong lba) - { - ushort cylinder = (ushort)(lba / (imageInfo.Heads * imageInfo.SectorsPerTrack)); - byte head = (byte)(lba / imageInfo.SectorsPerTrack % imageInfo.Heads); - byte sector = (byte)(lba % imageInfo.SectorsPerTrack + 1); - - return (cylinder, head, sector); - } - public byte[] ReadSectorLong(ulong sectorAddress) { return ReadSectors(sectorAddress, 1); @@ -719,19 +716,20 @@ namespace DiscImageChef.DiscImages } public bool? VerifySectors(ulong sectorAddress, uint length, out List failingLbas, - out List unknownLbas) + out List unknownLbas) { failingLbas = new List(); unknownLbas = new List(); for(ulong i = sectorAddress; i < sectorAddress + length; i++) - if(sectorsWhereCrcHasFailed.Contains(sectorAddress)) failingLbas.Add(sectorAddress); + if(sectorsWhereCrcHasFailed.Contains(sectorAddress)) + failingLbas.Add(sectorAddress); return failingLbas.Count <= 0; } public bool? VerifySectors(ulong sectorAddress, uint length, uint track, out List failingLbas, - out List unknownLbas) + out List unknownLbas) { failingLbas = new List(); unknownLbas = new List(); @@ -746,263 +744,8 @@ namespace DiscImageChef.DiscImages return aDiskCrcHasFailed; } - static ushort TeleDiskCrc(ushort crc, byte[] buffer) - { - int counter = 0; - - while(counter < buffer.Length) - { - crc ^= (ushort)((buffer[counter] & 0xFF) << 8); - - for(int i = 0; i < 8; i++) - if((crc & 0x8000) > 0) crc = (ushort)((crc << 1) ^ TELE_DISK_CRC_POLY); - else crc = (ushort)(crc << 1); - - counter++; - } - - return crc; - } - - static byte[] DecodeTeleDiskData(byte sectorSize, byte encodingType, byte[] encodedData) - { - byte[] decodedData; - switch(sectorSize) - { - case SECTOR_SIZE_128: - decodedData = new byte[128]; - break; - case SECTOR_SIZE_256: - decodedData = new byte[256]; - break; - case SECTOR_SIZE_512: - decodedData = new byte[512]; - break; - case SECTOR_SIZE_1K: - decodedData = new byte[1024]; - break; - case SECTOR_SIZE_2K: - decodedData = new byte[2048]; - break; - case SECTOR_SIZE_4K: - decodedData = new byte[4096]; - break; - case SECTOR_SIZE_8K: - decodedData = new byte[8192]; - break; - default: throw new ImageNotSupportedException($"Sector size {sectorSize} is incorrect."); - } - - switch(encodingType) - { - case DATA_BLOCK_COPY: - Array.Copy(encodedData, decodedData, decodedData.Length); - break; - case DATA_BLOCK_PATTERN: - { - int ins = 0; - int outs = 0; - while(ins < encodedData.Length) - { - ushort repeatNumber; - byte[] repeatValue = new byte[2]; - - repeatNumber = BitConverter.ToUInt16(encodedData, ins); - Array.Copy(encodedData, ins + 2, repeatValue, 0, 2); - byte[] decodedPiece = new byte[repeatNumber * 2]; - ArrayHelpers.ArrayFill(decodedPiece, repeatValue); - Array.Copy(decodedPiece, 0, decodedData, outs, decodedPiece.Length); - ins += 4; - outs += decodedPiece.Length; - } - - DicConsole.DebugWriteLine("TeleDisk plugin", "(Block pattern decoder): Input data size: {0} bytes", - encodedData.Length); - DicConsole.DebugWriteLine("TeleDisk plugin", "(Block pattern decoder): Processed input: {0} bytes", - ins); - DicConsole.DebugWriteLine("TeleDisk plugin", "(Block pattern decoder): Output data size: {0} bytes", - decodedData.Length); - DicConsole.DebugWriteLine("TeleDisk plugin", "(Block pattern decoder): Processed Output: {0} bytes", - outs); - break; - } - case DATA_BLOCK_RLE: - { - int ins = 0; - int outs = 0; - while(ins < encodedData.Length) - { - byte length; - byte encoding; - - encoding = encodedData[ins]; - if(encoding == 0x00) - { - length = encodedData[ins + 1]; - Array.Copy(encodedData, ins + 2, decodedData, outs, length); - ins += 2 + length; - outs += length; - } - else - { - length = (byte)(encoding * 2); - byte run = encodedData[ins + 1]; - byte[] part = new byte[length]; - Array.Copy(encodedData, ins + 2, part, 0, length); - byte[] piece = new byte[length * run]; - ArrayHelpers.ArrayFill(piece, part); - Array.Copy(piece, 0, decodedData, outs, piece.Length); - ins += 2 + length; - outs += piece.Length; - } - } - - DicConsole.DebugWriteLine("TeleDisk plugin", "(RLE decoder): Input data size: {0} bytes", - encodedData.Length); - DicConsole.DebugWriteLine("TeleDisk plugin", "(RLE decoder): Processed input: {0} bytes", ins); - DicConsole.DebugWriteLine("TeleDisk plugin", "(RLE decoder): Output data size: {0} bytes", - decodedData.Length); - DicConsole.DebugWriteLine("TeleDisk plugin", "(RLE decoder): Processed Output: {0} bytes", outs); - - break; - } - default: throw new ImageNotSupportedException($"Data encoding {encodingType} is incorrect."); - } - - return decodedData; - } - - MediaType DecodeTeleDiskDiskType() - { - switch(header.DriveType) - { - case DRIVE_TYPE_525_DD: - case DRIVE_TYPE_525_HD_DD_DISK: - case DRIVE_TYPE_525_HD: - { - switch(totalDiskSize) - { - case 163840: - { - // Acorn disk uses 256 bytes/sector - return imageInfo.SectorSize == 256 - ? MediaType.ACORN_525_SS_DD_40 - : MediaType.DOS_525_SS_DD_8; - // DOS disks use 512 bytes/sector - } - case 184320: - { - // Atari disk uses 256 bytes/sector - return imageInfo.SectorSize == 256 ? MediaType.ATARI_525_DD : MediaType.DOS_525_SS_DD_9; - // DOS disks use 512 bytes/sector - } - case 327680: - { - // Acorn disk uses 256 bytes/sector - return imageInfo.SectorSize == 256 - ? MediaType.ACORN_525_SS_DD_80 - : MediaType.DOS_525_DS_DD_8; - // DOS disks use 512 bytes/sector - } - case 368640: return MediaType.DOS_525_DS_DD_9; - case 1228800: return MediaType.DOS_525_HD; - case 102400: return MediaType.ACORN_525_SS_SD_40; - case 204800: return MediaType.ACORN_525_SS_SD_80; - case 655360: return MediaType.ACORN_525_DS_DD; - case 92160: return MediaType.ATARI_525_SD; - case 133120: return MediaType.ATARI_525_ED; - case 1310720: return MediaType.NEC_525_HD; - case 1261568: return MediaType.SHARP_525; - case 839680: return MediaType.FDFORMAT_525_DD; - case 1304320: return MediaType.ECMA_99_8; - case 1223424: return MediaType.ECMA_99_15; - case 1061632: return MediaType.ECMA_99_26; - case 80384: return MediaType.ECMA_66; - case 325632: return MediaType.ECMA_70; - case 653312: return MediaType.ECMA_78; - case 737280: return MediaType.ECMA_78_2; - default: - { - DicConsole.DebugWriteLine("TeleDisk plugin", "Unknown 5,25\" disk with {0} bytes", - totalDiskSize); - return MediaType.Unknown; - } - } - } - case DRIVE_TYPE_35_DD: - case DRIVE_TYPE_35_ED: - case DRIVE_TYPE_35_HD: - { - switch(totalDiskSize) - { - case 322560: return MediaType.Apricot_35; - case 327680: return MediaType.DOS_35_SS_DD_8; - case 368640: return MediaType.DOS_35_SS_DD_9; - case 655360: return MediaType.DOS_35_DS_DD_8; - case 737280: return MediaType.DOS_35_DS_DD_9; - case 1474560: return MediaType.DOS_35_HD; - case 2949120: return MediaType.DOS_35_ED; - case 1720320: return MediaType.DMF; - case 1763328: return MediaType.DMF_82; - case 1884160: // Irreal size, seen as BIOS with TSR, 23 sectors/track - case 1860608: // Real data size, sum of all sectors - return MediaType.XDF_35; - case 819200: return MediaType.CBM_35_DD; - case 901120: return MediaType.CBM_AMIGA_35_DD; - case 1802240: return MediaType.CBM_AMIGA_35_HD; - case 1310720: return MediaType.NEC_35_HD_8; - case 1228800: return MediaType.NEC_35_HD_15; - case 1261568: return MediaType.SHARP_35; - default: - { - DicConsole.DebugWriteLine("TeleDisk plugin", "Unknown 3,5\" disk with {0} bytes", - totalDiskSize); - return MediaType.Unknown; - } - } - } - case DRIVE_TYPE_8_INCH: - { - switch(totalDiskSize) - { - case 81664: return MediaType.IBM23FD; - case 242944: return MediaType.IBM33FD_128; - case 287488: return MediaType.IBM33FD_256; - case 306432: return MediaType.IBM33FD_512; - case 499200: return MediaType.IBM43FD_128; - case 574976: return MediaType.IBM43FD_256; - case 995072: return MediaType.IBM53FD_256; - case 1146624: return MediaType.IBM53FD_512; - case 1222400: return MediaType.IBM53FD_1024; - case 256256: - // Same size, with same disk geometry, for DEC RX01, NEC and ECMA, return ECMA - return MediaType.ECMA_54; - case 512512: - { - // DEC disk uses 256 bytes/sector - return imageInfo.SectorSize == 256 ? MediaType.RX02 : MediaType.ECMA_59; - // ECMA disks use 128 bytes/sector - } - case 1261568: return MediaType.NEC_8_DD; - case 1255168: return MediaType.ECMA_69_8; - case 1177344: return MediaType.ECMA_69_15; - case 1021696: return MediaType.ECMA_69_26; - default: - { - DicConsole.DebugWriteLine("TeleDisk plugin", "Unknown 8\" disk with {0} bytes", - totalDiskSize); - return MediaType.Unknown; - } - } - } - default: - { - DicConsole.DebugWriteLine("TeleDisk plugin", "Unknown drive type {1} with {0} bytes", totalDiskSize, - header.DriveType); - return MediaType.Unknown; - } - } - } + public List DumpHardware => null; + public CICMMetadataType CicmMetadata => null; public byte[] ReadDiskTag(MediaTagType tag) { @@ -1064,6 +807,277 @@ namespace DiscImageChef.DiscImages throw new FeatureUnsupportedImageException("Feature not supported by image format"); } + (ushort cylinder, byte head, byte sector) LbaToChs(ulong lba) + { + ushort cylinder = (ushort)(lba / (imageInfo.Heads * imageInfo.SectorsPerTrack)); + byte head = (byte)(lba / imageInfo.SectorsPerTrack % imageInfo.Heads); + byte sector = (byte)(lba % imageInfo.SectorsPerTrack + 1); + + return (cylinder, head, sector); + } + + static ushort TeleDiskCrc(ushort crc, byte[] buffer) + { + int counter = 0; + + while(counter < buffer.Length) + { + crc ^= (ushort)((buffer[counter] & 0xFF) << 8); + + for(int i = 0; i < 8; i++) + if((crc & 0x8000) > 0) + crc = (ushort)((crc << 1) ^ TELE_DISK_CRC_POLY); + else + crc = (ushort)(crc << 1); + + counter++; + } + + return crc; + } + + static byte[] DecodeTeleDiskData(byte sectorSize, byte encodingType, byte[] encodedData) + { + byte[] decodedData; + switch(sectorSize) + { + case SECTOR_SIZE_128: + decodedData = new byte[128]; + break; + case SECTOR_SIZE_256: + decodedData = new byte[256]; + break; + case SECTOR_SIZE_512: + decodedData = new byte[512]; + break; + case SECTOR_SIZE_1K: + decodedData = new byte[1024]; + break; + case SECTOR_SIZE_2K: + decodedData = new byte[2048]; + break; + case SECTOR_SIZE_4K: + decodedData = new byte[4096]; + break; + case SECTOR_SIZE_8K: + decodedData = new byte[8192]; + break; + default: throw new ImageNotSupportedException($"Sector size {sectorSize} is incorrect."); + } + + switch(encodingType) + { + case DATA_BLOCK_COPY: + Array.Copy(encodedData, decodedData, decodedData.Length); + break; + case DATA_BLOCK_PATTERN: + { + int ins = 0; + int outs = 0; + while(ins < encodedData.Length) + { + byte[] repeatValue = new byte[2]; + + ushort repeatNumber = BitConverter.ToUInt16(encodedData, ins); + Array.Copy(encodedData, ins + 2, repeatValue, 0, 2); + byte[] decodedPiece = new byte[repeatNumber * 2]; + ArrayHelpers.ArrayFill(decodedPiece, repeatValue); + Array.Copy(decodedPiece, 0, decodedData, outs, decodedPiece.Length); + ins += 4; + outs += decodedPiece.Length; + } + + DicConsole.DebugWriteLine("TeleDisk plugin", "(Block pattern decoder): Input data size: {0} bytes", + encodedData.Length); + DicConsole.DebugWriteLine("TeleDisk plugin", "(Block pattern decoder): Processed input: {0} bytes", + ins); + DicConsole.DebugWriteLine("TeleDisk plugin", "(Block pattern decoder): Output data size: {0} bytes", + decodedData.Length); + DicConsole.DebugWriteLine("TeleDisk plugin", "(Block pattern decoder): Processed Output: {0} bytes", + outs); + break; + } + case DATA_BLOCK_RLE: + { + int ins = 0; + int outs = 0; + while(ins < encodedData.Length) + { + byte length; + + byte encoding = encodedData[ins]; + if(encoding == 0x00) + { + length = encodedData[ins + 1]; + Array.Copy(encodedData, ins + 2, decodedData, outs, length); + ins += 2 + length; + outs += length; + } + else + { + length = (byte)(encoding * 2); + byte run = encodedData[ins + 1]; + byte[] part = new byte[length]; + Array.Copy(encodedData, ins + 2, part, 0, length); + byte[] piece = new byte[length * run]; + ArrayHelpers.ArrayFill(piece, part); + Array.Copy(piece, 0, decodedData, outs, piece.Length); + ins += 2 + length; + outs += piece.Length; + } + } + + DicConsole.DebugWriteLine("TeleDisk plugin", "(RLE decoder): Input data size: {0} bytes", + encodedData.Length); + DicConsole.DebugWriteLine("TeleDisk plugin", "(RLE decoder): Processed input: {0} bytes", ins); + DicConsole.DebugWriteLine("TeleDisk plugin", "(RLE decoder): Output data size: {0} bytes", + decodedData.Length); + DicConsole.DebugWriteLine("TeleDisk plugin", "(RLE decoder): Processed Output: {0} bytes", outs); + + break; + } + default: throw new ImageNotSupportedException($"Data encoding {encodingType} is incorrect."); + } + + return decodedData; + } + + MediaType DecodeTeleDiskDiskType() + { + switch(header.DriveType) + { + case DRIVE_TYPE_525_DD: + case DRIVE_TYPE_525_HD_DD_DISK: + case DRIVE_TYPE_525_HD: + { + switch(totalDiskSize) + { + case 163840: + { + // Acorn disk uses 256 bytes/sector + return imageInfo.SectorSize == 256 + ? MediaType.ACORN_525_SS_DD_40 + : MediaType.DOS_525_SS_DD_8; + + // DOS disks use 512 bytes/sector + } + case 184320: + { + // Atari disk uses 256 bytes/sector + return imageInfo.SectorSize == 256 ? MediaType.ATARI_525_DD : MediaType.DOS_525_SS_DD_9; + + // DOS disks use 512 bytes/sector + } + case 327680: + { + // Acorn disk uses 256 bytes/sector + return imageInfo.SectorSize == 256 + ? MediaType.ACORN_525_SS_DD_80 + : MediaType.DOS_525_DS_DD_8; + + // DOS disks use 512 bytes/sector + } + case 368640: return MediaType.DOS_525_DS_DD_9; + case 1228800: return MediaType.DOS_525_HD; + case 102400: return MediaType.ACORN_525_SS_SD_40; + case 204800: return MediaType.ACORN_525_SS_SD_80; + case 655360: return MediaType.ACORN_525_DS_DD; + case 92160: return MediaType.ATARI_525_SD; + case 133120: return MediaType.ATARI_525_ED; + case 1310720: return MediaType.NEC_525_HD; + case 1261568: return MediaType.SHARP_525; + case 839680: return MediaType.FDFORMAT_525_DD; + case 1304320: return MediaType.ECMA_99_8; + case 1223424: return MediaType.ECMA_99_15; + case 1061632: return MediaType.ECMA_99_26; + case 80384: return MediaType.ECMA_66; + case 325632: return MediaType.ECMA_70; + case 653312: return MediaType.ECMA_78; + case 737280: return MediaType.ECMA_78_2; + default: + { + DicConsole.DebugWriteLine("TeleDisk plugin", "Unknown 5,25\" disk with {0} bytes", + totalDiskSize); + return MediaType.Unknown; + } + } + } + case DRIVE_TYPE_35_DD: + case DRIVE_TYPE_35_ED: + case DRIVE_TYPE_35_HD: + { + switch(totalDiskSize) + { + case 322560: return MediaType.Apricot_35; + case 327680: return MediaType.DOS_35_SS_DD_8; + case 368640: return MediaType.DOS_35_SS_DD_9; + case 655360: return MediaType.DOS_35_DS_DD_8; + case 737280: return MediaType.DOS_35_DS_DD_9; + case 1474560: return MediaType.DOS_35_HD; + case 2949120: return MediaType.DOS_35_ED; + case 1720320: return MediaType.DMF; + case 1763328: return MediaType.DMF_82; + case 1884160: // Irreal size, seen as BIOS with TSR, 23 sectors/track + case 1860608: // Real data size, sum of all sectors + return MediaType.XDF_35; + case 819200: return MediaType.CBM_35_DD; + case 901120: return MediaType.CBM_AMIGA_35_DD; + case 1802240: return MediaType.CBM_AMIGA_35_HD; + case 1310720: return MediaType.NEC_35_HD_8; + case 1228800: return MediaType.NEC_35_HD_15; + case 1261568: return MediaType.SHARP_35; + default: + { + DicConsole.DebugWriteLine("TeleDisk plugin", "Unknown 3,5\" disk with {0} bytes", + totalDiskSize); + return MediaType.Unknown; + } + } + } + case DRIVE_TYPE_8_INCH: + { + switch(totalDiskSize) + { + case 81664: return MediaType.IBM23FD; + case 242944: return MediaType.IBM33FD_128; + case 287488: return MediaType.IBM33FD_256; + case 306432: return MediaType.IBM33FD_512; + case 499200: return MediaType.IBM43FD_128; + case 574976: return MediaType.IBM43FD_256; + case 995072: return MediaType.IBM53FD_256; + case 1146624: return MediaType.IBM53FD_512; + case 1222400: return MediaType.IBM53FD_1024; + case 256256: + // Same size, with same disk geometry, for DEC RX01, NEC and ECMA, return ECMA + return MediaType.ECMA_54; + case 512512: + { + // DEC disk uses 256 bytes/sector + return imageInfo.SectorSize == 256 ? MediaType.RX02 : MediaType.ECMA_59; + + // ECMA disks use 128 bytes/sector + } + case 1261568: return MediaType.NEC_8_DD; + case 1255168: return MediaType.ECMA_69_8; + case 1177344: return MediaType.ECMA_69_15; + case 1021696: return MediaType.ECMA_69_26; + default: + { + DicConsole.DebugWriteLine("TeleDisk plugin", "Unknown 8\" disk with {0} bytes", + totalDiskSize); + return MediaType.Unknown; + } + } + } + default: + { + DicConsole.DebugWriteLine("TeleDisk plugin", "Unknown drive type {1} with {0} bytes", totalDiskSize, + header.DriveType); + return MediaType.Unknown; + } + } + } + struct TeleDiskHeader { /// "TD" or "td" depending on compression @@ -1094,12 +1108,12 @@ namespace DiscImageChef.DiscImages public ushort Crc; /// Length of comment public ushort Length; - public byte Year; - public byte Month; - public byte Day; - public byte Hour; - public byte Minute; - public byte Second; + public byte Year; + public byte Month; + public byte Day; + public byte Hour; + public byte Minute; + public byte Second; } struct TeleDiskTrackHeader diff --git a/DiscImageChef.DiscImages/UDIF.cs b/DiscImageChef.DiscImages/UDIF.cs index 57d1cab05..33d1eada3 100644 --- a/DiscImageChef.DiscImages/UDIF.cs +++ b/DiscImageChef.DiscImages/UDIF.cs @@ -44,6 +44,7 @@ using DiscImageChef.Compression; using DiscImageChef.Console; using DiscImageChef.Filters; using Ionic.Zlib; +using Schemas; using SharpCompress.Compressors.ADC; using SharpCompress.Compressors.BZip2; using Version = Resources.Version; @@ -727,6 +728,9 @@ namespace DiscImageChef.DiscImages return null; } + public List DumpHardware => null; + public CICMMetadataType CicmMetadata => null; + public IEnumerable SupportedMediaTags => new MediaTagType[] { }; public IEnumerable SupportedSectorTags => new SectorTagType[] { }; public IEnumerable SupportedMediaTypes => @@ -1076,6 +1080,18 @@ namespace DiscImageChef.DiscImages return false; } + public bool SetDumpHardware(List dumpHardware) + { + // Not supported + return false; + } + + public bool SetCicmMetadata(CICMMetadataType metadata) + { + // Not supported + return false; + } + [StructLayout(LayoutKind.Sequential, Pack = 1)] struct UdifFooter { diff --git a/DiscImageChef.DiscImages/UkvFdi.cs b/DiscImageChef.DiscImages/UkvFdi.cs index 604a1c152..31473332d 100644 --- a/DiscImageChef.DiscImages/UkvFdi.cs +++ b/DiscImageChef.DiscImages/UkvFdi.cs @@ -38,13 +38,14 @@ using System.Runtime.InteropServices; using DiscImageChef.CommonTypes; using DiscImageChef.Console; using DiscImageChef.Filters; +using Schemas; namespace DiscImageChef.DiscImages { public class UkvFdi : IMediaImage { readonly byte[] signature = {0x46, 0x44, 0x49}; - ImageInfo imageInfo; + ImageInfo imageInfo; // Cylinder by head, sector data matrix byte[][][][] sectorsData; @@ -53,31 +54,31 @@ namespace DiscImageChef.DiscImages { imageInfo = new ImageInfo { - ReadableSectorTags = new List(), - ReadableMediaTags = new List(), - HasPartitions = false, - HasSessions = false, - Version = null, - Application = null, - ApplicationVersion = null, - Creator = null, - Comments = null, - MediaManufacturer = null, - MediaModel = null, - MediaSerialNumber = null, - MediaBarcode = null, - MediaPartNumber = null, - MediaSequence = 0, - LastMediaSequence = 0, - DriveManufacturer = null, - DriveModel = null, - DriveSerialNumber = null, + ReadableSectorTags = new List(), + ReadableMediaTags = new List(), + HasPartitions = false, + HasSessions = false, + Version = null, + Application = null, + ApplicationVersion = null, + Creator = null, + Comments = null, + MediaManufacturer = null, + MediaModel = null, + MediaSerialNumber = null, + MediaBarcode = null, + MediaPartNumber = null, + MediaSequence = 0, + LastMediaSequence = 0, + DriveManufacturer = null, + DriveModel = null, + DriveSerialNumber = null, DriveFirmwareRevision = null }; } public string Name => "Spectrum Floppy Disk Image"; - public Guid Id => new Guid("DADFC9B2-67C1-42A3-B124-825528163FC0"); + public Guid Id => new Guid("DADFC9B2-67C1-42A3-B124-825528163FC0"); public string Format => "Spectrum floppy disk image"; @@ -104,7 +105,7 @@ namespace DiscImageChef.DiscImages stream.Read(hdrB, 0, hdrB.Length); GCHandle handle = GCHandle.Alloc(hdrB, GCHandleType.Pinned); - hdr = (FdiHeader)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(FdiHeader)); + hdr = (FdiHeader)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(FdiHeader)); handle.Free(); return hdr.magic.SequenceEqual(signature); @@ -123,15 +124,15 @@ namespace DiscImageChef.DiscImages stream.Read(hdrB, 0, hdrB.Length); GCHandle handle = GCHandle.Alloc(hdrB, GCHandleType.Pinned); - hdr = (FdiHeader)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(FdiHeader)); + hdr = (FdiHeader)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(FdiHeader)); handle.Free(); DicConsole.DebugWriteLine("UkvFdi plugin", "hdr.addInfoLen = {0}", hdr.addInfoLen); - DicConsole.DebugWriteLine("UkvFdi plugin", "hdr.cylinders = {0}", hdr.cylinders); - DicConsole.DebugWriteLine("UkvFdi plugin", "hdr.dataOff = {0}", hdr.dataOff); - DicConsole.DebugWriteLine("UkvFdi plugin", "hdr.descOff = {0}", hdr.descOff); - DicConsole.DebugWriteLine("UkvFdi plugin", "hdr.flags = {0}", hdr.flags); - DicConsole.DebugWriteLine("UkvFdi plugin", "hdr.heads = {0}", hdr.heads); + DicConsole.DebugWriteLine("UkvFdi plugin", "hdr.cylinders = {0}", hdr.cylinders); + DicConsole.DebugWriteLine("UkvFdi plugin", "hdr.dataOff = {0}", hdr.dataOff); + DicConsole.DebugWriteLine("UkvFdi plugin", "hdr.descOff = {0}", hdr.descOff); + DicConsole.DebugWriteLine("UkvFdi plugin", "hdr.flags = {0}", hdr.flags); + DicConsole.DebugWriteLine("UkvFdi plugin", "hdr.heads = {0}", hdr.heads); stream.Seek(hdr.descOff, SeekOrigin.Begin); byte[] description = new byte[hdr.dataOff - hdr.descOff]; @@ -142,17 +143,17 @@ namespace DiscImageChef.DiscImages stream.Seek(0xE + hdr.addInfoLen, SeekOrigin.Begin); - long spt = long.MaxValue; + long spt = long.MaxValue; uint[][][] sectorsOff = new uint[hdr.cylinders][][]; - sectorsData = new byte[hdr.cylinders][][][]; + sectorsData = new byte[hdr.cylinders][][][]; imageInfo.Cylinders = hdr.cylinders; - imageInfo.Heads = hdr.heads; + imageInfo.Heads = hdr.heads; // Read track descriptors for(ushort cyl = 0; cyl < hdr.cylinders; cyl++) { - sectorsOff[cyl] = new uint[hdr.heads][]; + sectorsOff[cyl] = new uint[hdr.heads][]; sectorsData[cyl] = new byte[hdr.heads][][]; for(ushort head = 0; head < hdr.heads; head++) @@ -161,39 +162,39 @@ namespace DiscImageChef.DiscImages stream.Read(sctB, 0, 4); stream.Seek(2, SeekOrigin.Current); byte sectors = (byte)stream.ReadByte(); - uint trkOff = BitConverter.ToUInt32(sctB, 0); + uint trkOff = BitConverter.ToUInt32(sctB, 0); - DicConsole.DebugWriteLine("UkvFdi plugin", "trkhdr.c = {0}", cyl); - DicConsole.DebugWriteLine("UkvFdi plugin", "trkhdr.h = {0}", head); + DicConsole.DebugWriteLine("UkvFdi plugin", "trkhdr.c = {0}", cyl); + DicConsole.DebugWriteLine("UkvFdi plugin", "trkhdr.h = {0}", head); DicConsole.DebugWriteLine("UkvFdi plugin", "trkhdr.sectors = {0}", sectors); - DicConsole.DebugWriteLine("UkvFdi plugin", "trkhdr.off = {0}", trkOff); + DicConsole.DebugWriteLine("UkvFdi plugin", "trkhdr.off = {0}", trkOff); - sectorsOff[cyl][head] = new uint[sectors]; + sectorsOff[cyl][head] = new uint[sectors]; sectorsData[cyl][head] = new byte[sectors][]; if(sectors < spt && sectors > 0) spt = sectors; for(ushort sec = 0; sec < sectors; sec++) { - byte c = (byte)stream.ReadByte(); - byte h = (byte)stream.ReadByte(); - byte r = (byte)stream.ReadByte(); - byte n = (byte)stream.ReadByte(); - SectorFlags f = (SectorFlags)stream.ReadByte(); - byte[] offB = new byte[2]; + byte c = (byte)stream.ReadByte(); + byte h = (byte)stream.ReadByte(); + byte r = (byte)stream.ReadByte(); + byte n = (byte)stream.ReadByte(); + SectorFlags f = (SectorFlags)stream.ReadByte(); + byte[] offB = new byte[2]; stream.Read(offB, 0, 2); ushort secOff = BitConverter.ToUInt16(offB, 0); - DicConsole.DebugWriteLine("UkvFdi plugin", "sechdr.c = {0}", c); - DicConsole.DebugWriteLine("UkvFdi plugin", "sechdr.h = {0}", h); - DicConsole.DebugWriteLine("UkvFdi plugin", "sechdr.r = {0}", r); + DicConsole.DebugWriteLine("UkvFdi plugin", "sechdr.c = {0}", c); + DicConsole.DebugWriteLine("UkvFdi plugin", "sechdr.h = {0}", h); + DicConsole.DebugWriteLine("UkvFdi plugin", "sechdr.r = {0}", r); DicConsole.DebugWriteLine("UkvFdi plugin", "sechdr.n = {0} ({1})", n, 128 << n); - DicConsole.DebugWriteLine("UkvFdi plugin", "sechdr.f = {0}", f); + DicConsole.DebugWriteLine("UkvFdi plugin", "sechdr.f = {0}", f); DicConsole.DebugWriteLine("UkvFdi plugin", "sechdr.off = {0} ({1})", secOff, secOff + trkOff + hdr.dataOff); // TODO: This assumes sequential sectors. - sectorsOff[cyl][head][sec] = secOff + trkOff + hdr.dataOff; + sectorsOff[cyl][head][sec] = secOff + trkOff + hdr.dataOff; sectorsData[cyl][head][sec] = new byte[128 << n]; if(128 << n > imageInfo.SectorSize) imageInfo.SectorSize = (uint)(128 << n); @@ -223,7 +224,7 @@ namespace DiscImageChef.DiscImages // Create empty sectors else { - sectorsData[cyl][head] = new byte[spt][]; + sectorsData[cyl][head] = new byte[spt][]; for(int i = 0; i < spt; i++) sectorsData[cyl][head][i] = new byte[imageInfo.SectorSize]; } } @@ -232,14 +233,14 @@ namespace DiscImageChef.DiscImages } // TODO: What about double sided, half track pitch compact floppies? - imageInfo.MediaType = MediaType.CompactFloppy; - imageInfo.ImageSize = (ulong)stream.Length - hdr.dataOff; - imageInfo.CreationTime = imageFilter.GetCreationTime(); + imageInfo.MediaType = MediaType.CompactFloppy; + imageInfo.ImageSize = (ulong)stream.Length - hdr.dataOff; + imageInfo.CreationTime = imageFilter.GetCreationTime(); imageInfo.LastModificationTime = imageFilter.GetLastWriteTime(); - imageInfo.MediaTitle = Path.GetFileNameWithoutExtension(imageFilter.GetFilename()); - imageInfo.SectorsPerTrack = (uint)spt; - imageInfo.Sectors = imageInfo.Cylinders * imageInfo.Heads * imageInfo.SectorsPerTrack; - imageInfo.XmlMediaType = XmlMediaType.BlockMedia; + imageInfo.MediaTitle = Path.GetFileNameWithoutExtension(imageFilter.GetFilename()); + imageInfo.SectorsPerTrack = (uint)spt; + imageInfo.Sectors = imageInfo.Cylinders * imageInfo.Heads * imageInfo.SectorsPerTrack; + imageInfo.XmlMediaType = XmlMediaType.BlockMedia; return true; } @@ -278,15 +279,6 @@ namespace DiscImageChef.DiscImages return buffer.ToArray(); } - (ushort cylinder, byte head, byte sector) LbaToChs(ulong lba) - { - ushort cylinder = (ushort)(lba / (imageInfo.Heads * imageInfo.SectorsPerTrack)); - byte head = (byte)(lba / imageInfo.SectorsPerTrack % imageInfo.Heads); - byte sector = (byte)(lba % imageInfo.SectorsPerTrack + 1); - - return (cylinder, head, sector); - } - public byte[] ReadDiskTag(MediaTagType tag) { throw new FeatureUnsupportedImageException("Feature not supported by image format"); @@ -363,7 +355,7 @@ namespace DiscImageChef.DiscImages } public bool? VerifySectors(ulong sectorAddress, uint length, out List failingLbas, - out List unknownLbas) + out List unknownLbas) { failingLbas = new List(); unknownLbas = new List(); @@ -373,7 +365,7 @@ namespace DiscImageChef.DiscImages } public bool? VerifySectors(ulong sectorAddress, uint length, uint track, out List failingLbas, - out List unknownLbas) + out List unknownLbas) { throw new FeatureUnsupportedImageException("Feature not supported by image format"); } @@ -383,6 +375,18 @@ namespace DiscImageChef.DiscImages return null; } + public List DumpHardware => null; + public CICMMetadataType CicmMetadata => null; + + (ushort cylinder, byte head, byte sector) LbaToChs(ulong lba) + { + ushort cylinder = (ushort)(lba / (imageInfo.Heads * imageInfo.SectorsPerTrack)); + byte head = (byte)(lba / imageInfo.SectorsPerTrack % imageInfo.Heads); + byte sector = (byte)(lba % imageInfo.SectorsPerTrack + 1); + + return (cylinder, head, sector); + } + [Flags] enum DiskFlags : byte { @@ -392,25 +396,26 @@ namespace DiscImageChef.DiscImages [Flags] enum SectorFlags : byte { - CrcOk128 = 0x01, - CrcOk256 = 0x02, - CrcOk512 = 0x04, + CrcOk128 = 0x01, + CrcOk256 = 0x02, + CrcOk512 = 0x04, CrcOk1024 = 0x08, CrcOk2048 = 0x10, CrcOk4096 = 0x20, - Deleted = 0x80 + Deleted = 0x80 } [StructLayout(LayoutKind.Sequential, Pack = 1)] struct FdiHeader { - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public byte[] magic; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] + public byte[] magic; public DiskFlags flags; - public ushort cylinders; - public ushort heads; - public ushort descOff; - public ushort dataOff; - public ushort addInfoLen; + public ushort cylinders; + public ushort heads; + public ushort descOff; + public ushort dataOff; + public ushort addInfoLen; } } } \ No newline at end of file diff --git a/DiscImageChef.DiscImages/VDI.cs b/DiscImageChef.DiscImages/VDI.cs index f15fb1f9d..f81edb3e7 100644 --- a/DiscImageChef.DiscImages/VDI.cs +++ b/DiscImageChef.DiscImages/VDI.cs @@ -38,6 +38,7 @@ using System.Runtime.InteropServices; using DiscImageChef.CommonTypes; using DiscImageChef.Console; using DiscImageChef.Filters; +using Schemas; namespace DiscImageChef.DiscImages { @@ -373,6 +374,9 @@ namespace DiscImageChef.DiscImages return null; } + public List DumpHardware => null; + public CICMMetadataType CicmMetadata => null; + public IEnumerable SupportedMediaTags => new MediaTagType[] { }; public IEnumerable SupportedSectorTags => new SectorTagType[] { }; public IEnumerable SupportedMediaTypes => @@ -638,6 +642,18 @@ namespace DiscImageChef.DiscImages return false; } + public bool SetDumpHardware(List dumpHardware) + { + // Not supported + return false; + } + + public bool SetCicmMetadata(CICMMetadataType metadata) + { + // Not supported + return false; + } + /// /// VDI disk image header, little-endian /// diff --git a/DiscImageChef.DiscImages/VHD.cs b/DiscImageChef.DiscImages/VHD.cs index 5e632664f..2689f338b 100644 --- a/DiscImageChef.DiscImages/VHD.cs +++ b/DiscImageChef.DiscImages/VHD.cs @@ -41,6 +41,7 @@ using DiscImageChef.CommonTypes; using DiscImageChef.Console; using DiscImageChef.Filters; using DiscImageChef.Interop; +using Schemas; using PlatformID = DiscImageChef.Interop.PlatformID; using Version = System.Version; @@ -1092,6 +1093,9 @@ namespace DiscImageChef.DiscImages return null; } + public List DumpHardware => null; + public CICMMetadataType CicmMetadata => null; + public IEnumerable SupportedMediaTags => new MediaTagType[] { }; public IEnumerable SupportedSectorTags => new SectorTagType[] { }; public IEnumerable SupportedMediaTypes => @@ -1344,6 +1348,18 @@ namespace DiscImageChef.DiscImages return false; } + public bool SetDumpHardware(List dumpHardware) + { + // Not supported + return false; + } + + public bool SetCicmMetadata(CICMMetadataType metadata) + { + // Not supported + return false; + } + static uint VhdChecksum(IEnumerable data) { uint checksum = data.Aggregate(0, (current, b) => current + b); diff --git a/DiscImageChef.DiscImages/VHDX.cs b/DiscImageChef.DiscImages/VHDX.cs index f954f23e3..ec35c4f81 100644 --- a/DiscImageChef.DiscImages/VHDX.cs +++ b/DiscImageChef.DiscImages/VHDX.cs @@ -39,30 +39,31 @@ using System.Text; using DiscImageChef.CommonTypes; using DiscImageChef.Console; using DiscImageChef.Filters; +using Schemas; namespace DiscImageChef.DiscImages { public class Vhdx : IMediaImage { - const ulong VHDX_SIGNATURE = 0x656C696678646876; - const uint VHDX_HEADER_SIG = 0x64616568; - const uint VHDX_REGION_SIG = 0x69676572; + const ulong VHDX_SIGNATURE = 0x656C696678646876; + const uint VHDX_HEADER_SIG = 0x64616568; + const uint VHDX_REGION_SIG = 0x69676572; const ulong VHDX_METADATA_SIG = 0x617461646174656D; - const string PARENT_LINKAGE_KEY = "parent_linkage"; - const string PARENT_LINKAGE2_KEY = "parent_linkage2"; - const string RELATIVE_PATH_KEY = "relative_path"; - const string VOLUME_PATH_KEY = "volume_path"; + const string PARENT_LINKAGE_KEY = "parent_linkage"; + const string PARENT_LINKAGE2_KEY = "parent_linkage2"; + const string RELATIVE_PATH_KEY = "relative_path"; + const string VOLUME_PATH_KEY = "volume_path"; const string ABSOLUTE_WIN32_PATH_KEY = "absolute_win32_path"; const uint REGION_FLAGS_REQUIRED = 0x01; - const uint METADATA_FLAGS_USER = 0x01; - const uint METADATA_FLAGS_VIRTUAL = 0x02; + const uint METADATA_FLAGS_USER = 0x01; + const uint METADATA_FLAGS_VIRTUAL = 0x02; const uint METADATA_FLAGS_REQUIRED = 0x04; const uint FILE_FLAGS_LEAVE_ALLOCATED = 0x01; - const uint FILE_FLAGS_HAS_PARENT = 0x02; + const uint FILE_FLAGS_HAS_PARENT = 0x02; /// Block has never been stored on this image, check parent const ulong PAYLOAD_BLOCK_NOT_PRESENT = 0x00; @@ -78,80 +79,80 @@ namespace DiscImageChef.DiscImages const ulong PAYLOAD_BLOCK_PARTIALLY_PRESENT = 0x07; const ulong SECTOR_BITMAP_NOT_PRESENT = 0x00; - const ulong SECTOR_BITMAP_PRESENT = 0x06; + const ulong SECTOR_BITMAP_PRESENT = 0x06; const ulong BAT_FILE_OFFSET_MASK = 0xFFFFFFFFFFFC0000; - const ulong BAT_FLAGS_MASK = 0x7; - const ulong BAT_RESERVED_MASK = 0x3FFF8; + const ulong BAT_FLAGS_MASK = 0x7; + const ulong BAT_RESERVED_MASK = 0x3FFF8; - const int MAX_CACHE_SIZE = 16777216; - readonly Guid batGuid = new Guid("2DC27766-F623-4200-9D64-115E9BFD4A08"); - readonly Guid fileParametersGuid = new Guid("CAA16737-FA36-4D43-B3B6-33F0AA44E76B"); - readonly Guid logicalSectorSizeGuid = new Guid("8141BF1D-A96F-4709-BA47-F233A8FAAB5F"); - readonly Guid metadataGuid = new Guid("8B7CA206-4790-4B9A-B8FE-575F050F886E"); - readonly Guid page83DataGuid = new Guid("BECA12AB-B2E6-4523-93EF-C309E000C746"); - readonly Guid parentLocatorGuid = new Guid("A8D35F2D-B30B-454D-ABF7-D3D84834AB0C"); - readonly Guid parentTypeVhdxGuid = new Guid("B04AEFB7-D19E-4A81-B789-25B8E9445913"); + const int MAX_CACHE_SIZE = 16777216; + readonly Guid batGuid = new Guid("2DC27766-F623-4200-9D64-115E9BFD4A08"); + readonly Guid fileParametersGuid = new Guid("CAA16737-FA36-4D43-B3B6-33F0AA44E76B"); + readonly Guid logicalSectorSizeGuid = new Guid("8141BF1D-A96F-4709-BA47-F233A8FAAB5F"); + readonly Guid metadataGuid = new Guid("8B7CA206-4790-4B9A-B8FE-575F050F886E"); + readonly Guid page83DataGuid = new Guid("BECA12AB-B2E6-4523-93EF-C309E000C746"); + readonly Guid parentLocatorGuid = new Guid("A8D35F2D-B30B-454D-ABF7-D3D84834AB0C"); + readonly Guid parentTypeVhdxGuid = new Guid("B04AEFB7-D19E-4A81-B789-25B8E9445913"); readonly Guid physicalSectorSizeGuid = new Guid("CDA348C7-445D-4471-9CC9-E9885251C556"); - readonly Guid virtualDiskSizeGuid = new Guid("2FA54224-CD1B-4876-B211-5DBED83BF4B8"); + readonly Guid virtualDiskSizeGuid = new Guid("2FA54224-CD1B-4876-B211-5DBED83BF4B8"); long batOffset; - ulong[] blockAllocationTable; + ulong[] blockAllocationTable; Dictionary blockCache; - long chunkRatio; - ulong dataBlocks; - bool hasParent; - ImageInfo imageInfo; - Stream imageStream; - uint logicalSectorSize; - int maxBlockCache; - int maxSectorCache; - long metadataOffset; - Guid page83Data; + long chunkRatio; + ulong dataBlocks; + bool hasParent; + ImageInfo imageInfo; + Stream imageStream; + uint logicalSectorSize; + int maxBlockCache; + int maxSectorCache; + long metadataOffset; + Guid page83Data; IMediaImage parentImage; - uint physicalSectorSize; - byte[] sectorBitmap; - ulong[] sectorBitmapPointers; + uint physicalSectorSize; + byte[] sectorBitmap; + ulong[] sectorBitmapPointers; Dictionary sectorCache; - VhdxFileParameters vFileParms; - VhdxHeader vHdr; + VhdxFileParameters vFileParms; + VhdxHeader vHdr; VhdxIdentifier vhdxId; - ulong virtualDiskSize; - VhdxMetadataTableHeader vMetHdr; + ulong virtualDiskSize; + VhdxMetadataTableHeader vMetHdr; VhdxMetadataTableEntry[] vMets; - VhdxParentLocatorHeader vParHdr; + VhdxParentLocatorHeader vParHdr; VhdxParentLocatorEntry[] vPars; - VhdxRegionTableHeader vRegHdr; - VhdxRegionTableEntry[] vRegs; + VhdxRegionTableHeader vRegHdr; + VhdxRegionTableEntry[] vRegs; public Vhdx() { imageInfo = new ImageInfo { - ReadableSectorTags = new List(), - ReadableMediaTags = new List(), - HasPartitions = false, - HasSessions = false, - Version = null, - Application = null, - ApplicationVersion = null, - Creator = null, - Comments = null, - MediaManufacturer = null, - MediaModel = null, - MediaSerialNumber = null, - MediaBarcode = null, - MediaPartNumber = null, - MediaSequence = 0, - LastMediaSequence = 0, - DriveManufacturer = null, - DriveModel = null, - DriveSerialNumber = null, + ReadableSectorTags = new List(), + ReadableMediaTags = new List(), + HasPartitions = false, + HasSessions = false, + Version = null, + Application = null, + ApplicationVersion = null, + Creator = null, + Comments = null, + MediaManufacturer = null, + MediaModel = null, + MediaSerialNumber = null, + MediaBarcode = null, + MediaPartNumber = null, + MediaSequence = 0, + LastMediaSequence = 0, + DriveManufacturer = null, + DriveModel = null, + DriveSerialNumber = null, DriveFirmwareRevision = null }; } @@ -159,7 +160,7 @@ namespace DiscImageChef.DiscImages public ImageInfo Info => imageInfo; public string Name => "Microsoft VHDX"; - public Guid Id => new Guid("536B141B-D09C-4799-AB70-34631286EB9D"); + public Guid Id => new Guid("536B141B-D09C-4799-AB70-34631286EB9D"); public string Format => "VHDX"; @@ -181,7 +182,7 @@ namespace DiscImageChef.DiscImages byte[] vhdxIdB = new byte[Marshal.SizeOf(vhdxId)]; stream.Read(vhdxIdB, 0, Marshal.SizeOf(vhdxId)); - vhdxId = new VhdxIdentifier(); + vhdxId = new VhdxIdentifier(); IntPtr idPtr = Marshal.AllocHGlobal(Marshal.SizeOf(vhdxId)); Marshal.Copy(vhdxIdB, 0, idPtr, Marshal.SizeOf(vhdxId)); vhdxId = (VhdxIdentifier)Marshal.PtrToStructure(idPtr, typeof(VhdxIdentifier)); @@ -199,7 +200,7 @@ namespace DiscImageChef.DiscImages byte[] vhdxIdB = new byte[Marshal.SizeOf(vhdxId)]; stream.Read(vhdxIdB, 0, Marshal.SizeOf(vhdxId)); - vhdxId = new VhdxIdentifier(); + vhdxId = new VhdxIdentifier(); IntPtr idPtr = Marshal.AllocHGlobal(Marshal.SizeOf(vhdxId)); Marshal.Copy(vhdxIdB, 0, idPtr, Marshal.SizeOf(vhdxId)); vhdxId = (VhdxIdentifier)Marshal.PtrToStructure(idPtr, typeof(VhdxIdentifier)); @@ -212,7 +213,7 @@ namespace DiscImageChef.DiscImages stream.Seek(64 * 1024, SeekOrigin.Begin); byte[] vHdrB = new byte[Marshal.SizeOf(vHdr)]; stream.Read(vHdrB, 0, Marshal.SizeOf(vHdr)); - vHdr = new VhdxHeader(); + vHdr = new VhdxHeader(); IntPtr headerPtr = Marshal.AllocHGlobal(Marshal.SizeOf(vHdr)); Marshal.Copy(vHdrB, 0, headerPtr, Marshal.SizeOf(vHdr)); vHdr = (VhdxHeader)Marshal.PtrToStructure(headerPtr, typeof(VhdxHeader)); @@ -223,7 +224,7 @@ namespace DiscImageChef.DiscImages stream.Seek(128 * 1024, SeekOrigin.Begin); vHdrB = new byte[Marshal.SizeOf(vHdr)]; stream.Read(vHdrB, 0, Marshal.SizeOf(vHdr)); - vHdr = new VhdxHeader(); + vHdr = new VhdxHeader(); headerPtr = Marshal.AllocHGlobal(Marshal.SizeOf(vHdr)); Marshal.Copy(vHdrB, 0, headerPtr, Marshal.SizeOf(vHdr)); vHdr = (VhdxHeader)Marshal.PtrToStructure(headerPtr, typeof(VhdxHeader)); @@ -235,7 +236,7 @@ namespace DiscImageChef.DiscImages stream.Seek(192 * 1024, SeekOrigin.Begin); byte[] vRegTableB = new byte[Marshal.SizeOf(vRegHdr)]; stream.Read(vRegTableB, 0, Marshal.SizeOf(vRegHdr)); - vRegHdr = new VhdxRegionTableHeader(); + vRegHdr = new VhdxRegionTableHeader(); IntPtr vRegTabPtr = Marshal.AllocHGlobal(Marshal.SizeOf(vRegHdr)); Marshal.Copy(vRegTableB, 0, vRegTabPtr, Marshal.SizeOf(vRegHdr)); vRegHdr = (VhdxRegionTableHeader)Marshal.PtrToStructure(vRegTabPtr, typeof(VhdxRegionTableHeader)); @@ -246,7 +247,7 @@ namespace DiscImageChef.DiscImages stream.Seek(256 * 1024, SeekOrigin.Begin); vRegTableB = new byte[Marshal.SizeOf(vRegHdr)]; stream.Read(vRegTableB, 0, Marshal.SizeOf(vRegHdr)); - vRegHdr = new VhdxRegionTableHeader(); + vRegHdr = new VhdxRegionTableHeader(); vRegTabPtr = Marshal.AllocHGlobal(Marshal.SizeOf(vRegHdr)); Marshal.Copy(vRegTableB, 0, vRegTabPtr, Marshal.SizeOf(vRegHdr)); vRegHdr = (VhdxRegionTableHeader)Marshal.PtrToStructure(vRegTabPtr, typeof(VhdxRegionTableHeader)); @@ -261,14 +262,15 @@ namespace DiscImageChef.DiscImages { byte[] vRegB = new byte[Marshal.SizeOf(vRegs[i])]; stream.Read(vRegB, 0, Marshal.SizeOf(vRegs[i])); - vRegs[i] = new VhdxRegionTableEntry(); + vRegs[i] = new VhdxRegionTableEntry(); IntPtr vRegPtr = Marshal.AllocHGlobal(Marshal.SizeOf(vRegs[i])); Marshal.Copy(vRegB, 0, vRegPtr, Marshal.SizeOf(vRegs[i])); vRegs[i] = (VhdxRegionTableEntry)Marshal.PtrToStructure(vRegPtr, typeof(VhdxRegionTableEntry)); Marshal.FreeHGlobal(vRegPtr); - if(vRegs[i].guid == batGuid) batOffset = (long)vRegs[i].offset; - else if(vRegs[i].guid == metadataGuid) metadataOffset = (long)vRegs[i].offset; + if(vRegs[i].guid == batGuid) batOffset = (long)vRegs[i].offset; + else if(vRegs[i].guid == metadataGuid) + metadataOffset = (long)vRegs[i].offset; else if((vRegs[i].flags & REGION_FLAGS_REQUIRED) == REGION_FLAGS_REQUIRED) throw new ImageNotSupportedException($"Found unsupported and required region Guid {vRegs[i].guid}, not proceeding with image."); @@ -283,7 +285,7 @@ namespace DiscImageChef.DiscImages stream.Seek(metadataOffset, SeekOrigin.Begin); byte[] metTableB = new byte[Marshal.SizeOf(vMetHdr)]; stream.Read(metTableB, 0, Marshal.SizeOf(vMetHdr)); - vMetHdr = new VhdxMetadataTableHeader(); + vMetHdr = new VhdxMetadataTableHeader(); IntPtr metTablePtr = Marshal.AllocHGlobal(Marshal.SizeOf(vMetHdr)); Marshal.Copy(metTableB, 0, metTablePtr, Marshal.SizeOf(vMetHdr)); vMetHdr = (VhdxMetadataTableHeader)Marshal.PtrToStructure(metTablePtr, typeof(VhdxMetadataTableHeader)); @@ -294,18 +296,23 @@ namespace DiscImageChef.DiscImages { byte[] vMetB = new byte[Marshal.SizeOf(vMets[i])]; stream.Read(vMetB, 0, Marshal.SizeOf(vMets[i])); - vMets[i] = new VhdxMetadataTableEntry(); + vMets[i] = new VhdxMetadataTableEntry(); IntPtr vMetPtr = Marshal.AllocHGlobal(Marshal.SizeOf(vMets[i])); Marshal.Copy(vMetB, 0, vMetPtr, Marshal.SizeOf(vMets[i])); vMets[i] = (VhdxMetadataTableEntry)Marshal.PtrToStructure(vMetPtr, typeof(VhdxMetadataTableEntry)); Marshal.FreeHGlobal(vMetPtr); - if(vMets[i].itemId == fileParametersGuid) fileParamsOff = vMets[i].offset; - else if(vMets[i].itemId == virtualDiskSizeGuid) vdSizeOff = vMets[i].offset; - else if(vMets[i].itemId == page83DataGuid) p83Off = vMets[i].offset; - else if(vMets[i].itemId == logicalSectorSizeGuid) logOff = vMets[i].offset; - else if(vMets[i].itemId == physicalSectorSizeGuid) physOff = vMets[i].offset; - else if(vMets[i].itemId == parentLocatorGuid) parentOff = vMets[i].offset; + if(vMets[i].itemId == fileParametersGuid) fileParamsOff = vMets[i].offset; + else if(vMets[i].itemId == virtualDiskSizeGuid) + vdSizeOff = vMets[i].offset; + else if(vMets[i].itemId == page83DataGuid) + p83Off = vMets[i].offset; + else if(vMets[i].itemId == logicalSectorSizeGuid) + logOff = vMets[i].offset; + else if(vMets[i].itemId == physicalSectorSizeGuid) + physOff = vMets[i].offset; + else if(vMets[i].itemId == parentLocatorGuid) + parentOff = vMets[i].offset; else if((vMets[i].flags & METADATA_FLAGS_REQUIRED) == METADATA_FLAGS_REQUIRED) throw new ImageNotSupportedException($"Found unsupported and required metadata Guid {vMets[i].itemId}, not proceeding with image."); @@ -321,7 +328,7 @@ namespace DiscImageChef.DiscImages vFileParms = new VhdxFileParameters { blockSize = BitConverter.ToUInt32(tmp, 0), - flags = BitConverter.ToUInt32(tmp, 4) + flags = BitConverter.ToUInt32(tmp, 4) }; } else throw new Exception("File parameters not found."); @@ -366,7 +373,7 @@ namespace DiscImageChef.DiscImages stream.Seek(parentOff + metadataOffset, SeekOrigin.Begin); byte[] vParHdrB = new byte[Marshal.SizeOf(vMetHdr)]; stream.Read(vParHdrB, 0, Marshal.SizeOf(vMetHdr)); - vParHdr = new VhdxParentLocatorHeader(); + vParHdr = new VhdxParentLocatorHeader(); IntPtr vParHdrPtr = Marshal.AllocHGlobal(Marshal.SizeOf(vMetHdr)); Marshal.Copy(vParHdrB, 0, vParHdrPtr, Marshal.SizeOf(vMetHdr)); vParHdr = (VhdxParentLocatorHeader)Marshal.PtrToStructure(vParHdrPtr, typeof(VhdxParentLocatorHeader)); @@ -381,7 +388,7 @@ namespace DiscImageChef.DiscImages { byte[] vParB = new byte[Marshal.SizeOf(vPars[i])]; stream.Read(vParB, 0, Marshal.SizeOf(vPars[i])); - vPars[i] = new VhdxParentLocatorEntry(); + vPars[i] = new VhdxParentLocatorEntry(); IntPtr vParPtr = Marshal.AllocHGlobal(Marshal.SizeOf(vPars[i])); Marshal.Copy(vParB, 0, vParPtr, Marshal.SizeOf(vPars[i])); vPars[i] = (VhdxParentLocatorEntry)Marshal.PtrToStructure(vParPtr, typeof(VhdxParentLocatorEntry)); @@ -392,9 +399,9 @@ namespace DiscImageChef.DiscImages throw new Exception("Parent locator not found."); if((vFileParms.flags & FILE_FLAGS_HAS_PARENT) == FILE_FLAGS_HAS_PARENT && - vParHdr.locatorType == parentTypeVhdxGuid) + vParHdr.locatorType == parentTypeVhdxGuid) { - parentImage = new Vhdx(); + parentImage = new Vhdx(); bool parentWorks = false; foreach(VhdxParentLocatorEntry parentEntry in vPars) @@ -440,7 +447,8 @@ namespace DiscImageChef.DiscImages // ignored } } - else if(string.Compare(entryType, VOLUME_PATH_KEY, StringComparison.OrdinalIgnoreCase) == 0 || + else if(string.Compare(entryType, VOLUME_PATH_KEY, StringComparison.OrdinalIgnoreCase) == + 0 || string.Compare(entryType, ABSOLUTE_WIN32_PATH_KEY, StringComparison.OrdinalIgnoreCase) == 0) { stream.Seek(parentEntry.valueOffset + metadataOffset, SeekOrigin.Begin); @@ -470,14 +478,14 @@ namespace DiscImageChef.DiscImages } chunkRatio = (long)(Math.Pow(2, 23) * logicalSectorSize / vFileParms.blockSize); - dataBlocks = virtualDiskSize / vFileParms.blockSize; - if(virtualDiskSize % vFileParms.blockSize > 0) dataBlocks++; + dataBlocks = virtualDiskSize / vFileParms.blockSize; + if(virtualDiskSize % vFileParms.blockSize > 0) dataBlocks++; long batEntries; if(hasParent) { long sectorBitmapBlocks = (long)dataBlocks / chunkRatio; - if(dataBlocks % (ulong)chunkRatio > 0) sectorBitmapBlocks++; + if(dataBlocks % (ulong)chunkRatio > 0) sectorBitmapBlocks++; sectorBitmapPointers = new ulong[sectorBitmapBlocks]; batEntries = sectorBitmapBlocks * (chunkRatio - 1); @@ -486,21 +494,21 @@ namespace DiscImageChef.DiscImages DicConsole.DebugWriteLine("VHDX plugin", "Reading BAT"); - long readChunks = 0; + long readChunks = 0; blockAllocationTable = new ulong[dataBlocks]; - byte[] batB = new byte[batEntries * 8]; + byte[] batB = new byte[batEntries * 8]; stream.Seek(batOffset, SeekOrigin.Begin); stream.Read(batB, 0, batB.Length); ulong skipSize = 0; for(ulong i = 0; i < dataBlocks; i++) - if(readChunks == chunkRatio) + if(readChunks == chunkRatio) { if(hasParent) sectorBitmapPointers[skipSize / 8] = BitConverter.ToUInt64(batB, (int)(i * 8 + skipSize)); - readChunks = 0; - skipSize += 8; + readChunks = 0; + skipSize += 8; } else { @@ -537,44 +545,33 @@ namespace DiscImageChef.DiscImages sectorBmpMs.Close(); } - maxBlockCache = (int)(MAX_CACHE_SIZE / vFileParms.blockSize); + maxBlockCache = (int)(MAX_CACHE_SIZE / vFileParms.blockSize); maxSectorCache = (int)(MAX_CACHE_SIZE / logicalSectorSize); imageStream = stream; sectorCache = new Dictionary(); - blockCache = new Dictionary(); + blockCache = new Dictionary(); - imageInfo.CreationTime = imageFilter.GetCreationTime(); + imageInfo.CreationTime = imageFilter.GetCreationTime(); imageInfo.LastModificationTime = imageFilter.GetLastWriteTime(); - imageInfo.MediaTitle = Path.GetFileNameWithoutExtension(imageFilter.GetFilename()); - imageInfo.SectorSize = logicalSectorSize; - imageInfo.XmlMediaType = XmlMediaType.BlockMedia; - imageInfo.MediaType = MediaType.GENERIC_HDD; - imageInfo.ImageSize = virtualDiskSize; - imageInfo.Sectors = imageInfo.ImageSize / imageInfo.SectorSize; - imageInfo.DriveSerialNumber = page83Data.ToString(); + imageInfo.MediaTitle = Path.GetFileNameWithoutExtension(imageFilter.GetFilename()); + imageInfo.SectorSize = logicalSectorSize; + imageInfo.XmlMediaType = XmlMediaType.BlockMedia; + imageInfo.MediaType = MediaType.GENERIC_HDD; + imageInfo.ImageSize = virtualDiskSize; + imageInfo.Sectors = imageInfo.ImageSize / imageInfo.SectorSize; + imageInfo.DriveSerialNumber = page83Data.ToString(); // TODO: Separate image application from version, need several samples. - imageInfo.Cylinders = (uint)(imageInfo.Sectors / 16 / 63); - imageInfo.Heads = 16; + imageInfo.Cylinders = (uint)(imageInfo.Sectors / 16 / 63); + imageInfo.Heads = 16; imageInfo.SectorsPerTrack = 63; return true; } - bool CheckBitmap(ulong sectorAddress) - { - long index = (long)(sectorAddress / 8); - int shift = (int)(sectorAddress % 8); - byte val = (byte)(1 << shift); - - if(index > sectorBitmap.LongLength) return false; - - return (sectorBitmap[index] & val) == val; - } - public byte[] ReadSector(ulong sectorAddress) { if(sectorAddress > imageInfo.Sectors - 1) @@ -583,10 +580,10 @@ namespace DiscImageChef.DiscImages if(sectorCache.TryGetValue(sectorAddress, out byte[] sector)) return sector; - ulong index = sectorAddress * logicalSectorSize / vFileParms.blockSize; + ulong index = sectorAddress * logicalSectorSize / vFileParms.blockSize; ulong secOff = sectorAddress * logicalSectorSize % vFileParms.blockSize; - ulong blkPtr = blockAllocationTable[index]; + ulong blkPtr = blockAllocationTable[index]; ulong blkFlags = blkPtr & BAT_FLAGS_MASK; if((blkPtr & BAT_RESERVED_MASK) != 0) @@ -649,13 +646,6 @@ namespace DiscImageChef.DiscImages return ms.ToArray(); } - static uint VhdxChecksum(IEnumerable data) - { - uint checksum = data.Aggregate(0, (current, b) => current + b); - - return ~checksum; - } - public byte[] ReadDiskTag(MediaTagType tag) { throw new FeatureUnsupportedImageException("Feature not supported by image format"); @@ -732,7 +722,7 @@ namespace DiscImageChef.DiscImages } public bool? VerifySectors(ulong sectorAddress, uint length, out List failingLbas, - out List unknownLbas) + out List unknownLbas) { failingLbas = new List(); unknownLbas = new List(); @@ -742,7 +732,7 @@ namespace DiscImageChef.DiscImages } public bool? VerifySectors(ulong sectorAddress, uint length, uint track, out List failingLbas, - out List unknownLbas) + out List unknownLbas) { throw new FeatureUnsupportedImageException("Feature not supported by image format"); } @@ -752,6 +742,27 @@ namespace DiscImageChef.DiscImages return null; } + public List DumpHardware => null; + public CICMMetadataType CicmMetadata => null; + + bool CheckBitmap(ulong sectorAddress) + { + long index = (long)(sectorAddress / 8); + int shift = (int)(sectorAddress % 8); + byte val = (byte)(1 << shift); + + if(index > sectorBitmap.LongLength) return false; + + return (sectorBitmap[index] & val) == val; + } + + static uint VhdxChecksum(IEnumerable data) + { + uint checksum = data.Aggregate(0, (current, b) => current + b); + + return ~checksum; + } + [StructLayout(LayoutKind.Sequential, Pack = 1)] struct VhdxIdentifier { @@ -762,11 +773,12 @@ namespace DiscImageChef.DiscImages /// /// UTF-16 string containing creator /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)] public byte[] creator; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)] + public byte[] creator; } -#pragma warning disable 649 -#pragma warning disable 169 + #pragma warning disable 649 + #pragma warning disable 169 struct VhdxHeader { /// @@ -809,10 +821,11 @@ namespace DiscImageChef.DiscImages /// Offset from image start to the log /// public ulong LogOffset; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4016)] public byte[] Reserved; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4016)] + public byte[] Reserved; } -#pragma warning restore 649 -#pragma warning restore 169 + #pragma warning restore 649 + #pragma warning restore 169 [StructLayout(LayoutKind.Sequential, Pack = 1)] struct VhdxRegionTableHeader @@ -874,7 +887,8 @@ namespace DiscImageChef.DiscImages /// /// Reserved /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)] public uint[] reserved2; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)] + public uint[] reserved2; } [StructLayout(LayoutKind.Sequential, Pack = 1)] @@ -921,7 +935,7 @@ namespace DiscImageChef.DiscImages /// /// Type of parent virtual disk /// - public Guid locatorType; + public Guid locatorType; public ushort reserved; /// /// How many KVPs are in this parent locator diff --git a/DiscImageChef.DiscImages/VMware.cs b/DiscImageChef.DiscImages/VMware.cs index 554c3acd1..040bd7cec 100644 --- a/DiscImageChef.DiscImages/VMware.cs +++ b/DiscImageChef.DiscImages/VMware.cs @@ -40,6 +40,7 @@ using System.Text.RegularExpressions; using DiscImageChef.CommonTypes; using DiscImageChef.Console; using DiscImageChef.Filters; +using Schemas; namespace DiscImageChef.DiscImages { @@ -858,6 +859,9 @@ namespace DiscImageChef.DiscImages return null; } + public List DumpHardware => null; + public CICMMetadataType CicmMetadata => null; + public IEnumerable SupportedMediaTags => new MediaTagType[] { }; public IEnumerable SupportedSectorTags => new SectorTagType[] { }; public IEnumerable SupportedMediaTypes => @@ -1163,6 +1167,18 @@ namespace DiscImageChef.DiscImages return false; } + public bool SetDumpHardware(List dumpHardware) + { + // Not supported + return false; + } + + public bool SetCicmMetadata(CICMMetadataType metadata) + { + // Not supported + return false; + } + [StructLayout(LayoutKind.Sequential, Pack = 1)] struct VMwareExtentHeader { diff --git a/DiscImageChef.DiscImages/Virtual98.cs b/DiscImageChef.DiscImages/Virtual98.cs index c5f40dfde..daaf566c5 100644 --- a/DiscImageChef.DiscImages/Virtual98.cs +++ b/DiscImageChef.DiscImages/Virtual98.cs @@ -39,6 +39,7 @@ using System.Text; using DiscImageChef.CommonTypes; using DiscImageChef.Console; using DiscImageChef.Filters; +using Schemas; namespace DiscImageChef.DiscImages { @@ -296,6 +297,9 @@ namespace DiscImageChef.DiscImages return null; } + public List DumpHardware => null; + public CICMMetadataType CicmMetadata => null; + public IEnumerable SupportedMediaTags => new MediaTagType[] { }; public IEnumerable SupportedSectorTags => new SectorTagType[] { }; public IEnumerable SupportedMediaTypes => @@ -322,7 +326,7 @@ namespace DiscImageChef.DiscImages if(sectors > uint.MaxValue) { - ErrorMessage = $"Too many sectors"; + ErrorMessage = "Too many sectors"; return false; } @@ -536,6 +540,18 @@ namespace DiscImageChef.DiscImages return false; } + public bool SetDumpHardware(List dumpHardware) + { + // Not supported + return false; + } + + public bool SetCicmMetadata(CICMMetadataType metadata) + { + // Not supported + return false; + } + [StructLayout(LayoutKind.Sequential, Pack = 1)] struct Virtual98Header { diff --git a/DiscImageChef.DiscImages/ZZZRawImage.cs b/DiscImageChef.DiscImages/ZZZRawImage.cs index 059bd857a..5777a460b 100644 --- a/DiscImageChef.DiscImages/ZZZRawImage.cs +++ b/DiscImageChef.DiscImages/ZZZRawImage.cs @@ -41,6 +41,7 @@ using DiscImageChef.Decoders.CD; using DiscImageChef.Decoders.DVD; using DiscImageChef.Decoders.SCSI; using DiscImageChef.Filters; +using Schemas; using DMI = DiscImageChef.Decoders.Xbox.DMI; namespace DiscImageChef.DiscImages @@ -422,11 +423,10 @@ namespace DiscImageChef.DiscImages mediaTags = new Dictionary(); foreach((MediaTagType tag, string name) sidecar in readWriteSidecars) - { try { FiltersList filters = new FiltersList(); - IFilter filter = filters.GetFilter(basename + sidecar.name); + IFilter filter = filters.GetFilter(basename + sidecar.name); if(filter == null || !filter.IsOpened()) continue; DicConsole.DebugWriteLine("ZZZRawImage Plugin", "Found media tag {0}", sidecar.tag); @@ -434,8 +434,7 @@ namespace DiscImageChef.DiscImages filter.GetDataForkStream().Read(data, 0, data.Length); mediaTags.Add(sidecar.tag, data); } - catch(IOException e) { continue; } - } + catch(IOException e) { } // If there are INQUIRY and IDENTIFY tags, it's ATAPI if(mediaTags.ContainsKey(MediaTagType.SCSI_INQUIRY)) @@ -939,7 +938,7 @@ namespace DiscImageChef.DiscImages if(decMode.HasValue) { mediumType = (byte)decMode.Value.Header.MediumType; - if(decMode.Value.Header.BlockDescriptors != null && + if(decMode.Value.Header.BlockDescriptors != null && decMode.Value.Header.BlockDescriptors.Length >= 1) densityCode = (byte)decMode.Value.Header.BlockDescriptors[0].Density; @@ -1110,6 +1109,9 @@ namespace DiscImageChef.DiscImages return null; } + public List DumpHardware => null; + public CICMMetadataType CicmMetadata { get; private set; } + public List GetSessionTracks(Session session) { if(imageInfo.XmlMediaType != XmlMediaType.OpticalDisc) @@ -1310,7 +1312,7 @@ namespace DiscImageChef.DiscImages return false; } - basepath = Path.Combine(Path.GetDirectoryName(path), Path.GetFileNameWithoutExtension(path)); + basepath = Path.Combine(Path.GetDirectoryName(path), Path.GetFileNameWithoutExtension(path)); mediaTags = new Dictionary(); IsWriting = true; @@ -1336,6 +1338,18 @@ namespace DiscImageChef.DiscImages return false; } + public bool SetDumpHardware(List dumpHardware) + { + // Not supported + return false; + } + + public bool SetCicmMetadata(CICMMetadataType metadata) + { + // Not supported + return false; + } + public bool WriteMediaTag(byte[] data, MediaTagType tag) { if(!SupportedMediaTags.Contains(tag)) diff --git a/DiscImageChef/Commands/ConvertImage.cs b/DiscImageChef/Commands/ConvertImage.cs index 20764b074..b59742743 100644 --- a/DiscImageChef/Commands/ConvertImage.cs +++ b/DiscImageChef/Commands/ConvertImage.cs @@ -38,6 +38,7 @@ using DiscImageChef.Console; using DiscImageChef.Core; using DiscImageChef.DiscImages; using DiscImageChef.Filters; +using Schemas; using Version = DiscImageChef.Interop.Version; namespace DiscImageChef.Commands @@ -249,6 +250,9 @@ namespace DiscImageChef.Commands try { tracks = inputFormat.Tracks; } catch(Exception) { tracks = null; } + CICMMetadataType cicmMetadata = inputFormat.CicmMetadata; + List dumpHardware = inputFormat.DumpHardware; + if(tracks != null) if(!outputFormat.SetTracks(tracks)) { @@ -510,6 +514,17 @@ namespace DiscImageChef.Commands track.TrackSequence, track.TrackSequence / (double)tracks.Count); sector = inputFormat.ReadSectorTag(track.TrackStartSector, tag); result = outputFormat.WriteSectorTag(sector, track.TrackStartSector, tag); + if(!result) + if(options.Force) + DicConsole.ErrorWriteLine("Error {0} writing tag, continuing...", + outputFormat.ErrorMessage); + else + { + DicConsole.ErrorWriteLine("Error {0} writing tag, not continuing...", + outputFormat.ErrorMessage); + return; + } + continue; } @@ -542,11 +557,11 @@ namespace DiscImageChef.Commands if(!result) if(options.Force) - DicConsole.ErrorWriteLine("Error {0} writing sector {1}, continuing...", + DicConsole.ErrorWriteLine("Error {0} writing tag for sector {1}, continuing...", outputFormat.ErrorMessage, doneSectors); else { - DicConsole.ErrorWriteLine("Error {0} writing sector {1}, not continuing...", + DicConsole.ErrorWriteLine("Error {0} writing tag for sector {1}, not continuing...", outputFormat.ErrorMessage, doneSectors); return; } @@ -573,6 +588,11 @@ namespace DiscImageChef.Commands } } + if(dumpHardware != null && outputFormat.SetDumpHardware(dumpHardware)) + DicConsole.WriteLine("Written dump hardware list to output image."); + if(cicmMetadata != null && outputFormat.SetCicmMetadata(cicmMetadata)) + DicConsole.WriteLine("Written CICM XML metadata to output image."); + DicConsole.WriteLine("Closing output image."); if(!outputFormat.Close()) diff --git a/DiscImageChef/Commands/CreateSidecar.cs b/DiscImageChef/Commands/CreateSidecar.cs index 5e87cce1e..ac66ff304 100644 --- a/DiscImageChef/Commands/CreateSidecar.cs +++ b/DiscImageChef/Commands/CreateSidecar.cs @@ -48,13 +48,13 @@ namespace DiscImageChef.Commands { internal static void DoSidecar(CreateSidecarOptions options) { - Sidecar.InitProgressEvent += Progress.InitProgress; - Sidecar.UpdateProgressEvent += Progress.UpdateProgress; - Sidecar.EndProgressEvent += Progress.EndProgress; - Sidecar.InitProgressEvent2 += Progress.InitProgress2; + Sidecar.InitProgressEvent += Progress.InitProgress; + Sidecar.UpdateProgressEvent += Progress.UpdateProgress; + Sidecar.EndProgressEvent += Progress.EndProgress; + Sidecar.InitProgressEvent2 += Progress.InitProgress2; Sidecar.UpdateProgressEvent2 += Progress.UpdateProgress2; - Sidecar.EndProgressEvent2 += Progress.EndProgress2; - Sidecar.UpdateStatusEvent += Progress.UpdateStatus; + Sidecar.EndProgressEvent2 += Progress.EndProgress2; + Sidecar.UpdateStatusEvent += Progress.UpdateStatus; Encoding encoding = null; @@ -79,7 +79,7 @@ namespace DiscImageChef.Commands } FiltersList filtersList = new FiltersList(); - IFilter inputFilter = filtersList.GetFilter(options.InputFile); + IFilter inputFilter = filtersList.GetFilter(options.InputFile); if(inputFilter == null) { @@ -123,8 +123,7 @@ namespace DiscImageChef.Commands Core.Statistics.AddMediaFormat(imageFormat.Format); Core.Statistics.AddFilter(inputFilter.Name); - CICMMetadataType sidecar = - Sidecar.Create(imageFormat, options.InputFile, inputFilter.Id, encoding); + CICMMetadataType sidecar = Sidecar.Create(imageFormat, options.InputFile, inputFilter.Id, encoding); DicConsole.WriteLine("Writing metadata sidecar"); @@ -153,9 +152,9 @@ namespace DiscImageChef.Commands return; } - string[] contents = Directory.GetFiles(options.InputFile, "*", SearchOption.TopDirectoryOnly); - List files = contents.Where(file => new FileInfo(file).Length % options.BlockSize == 0) - .ToList(); + string[] contents = Directory.GetFiles(options.InputFile, "*", SearchOption.TopDirectoryOnly); + List files = contents.Where(file => new FileInfo(file).Length % options.BlockSize == 0) + .ToList(); files.Sort(StringComparer.CurrentCultureIgnoreCase); @@ -175,7 +174,8 @@ namespace DiscImageChef.Commands Core.Statistics.AddCommand("create-sidecar"); } - else DicConsole.ErrorWriteLine("The specified input file cannot be found."); + else + DicConsole.ErrorWriteLine("The specified input file cannot be found."); } } } \ No newline at end of file