diff --git a/DiscImageChef.Core/Devices/Dumping/ATA.cs b/DiscImageChef.Core/Devices/Dumping/ATA.cs index 680e4cb9..e685738b 100644 --- a/DiscImageChef.Core/Devices/Dumping/ATA.cs +++ b/DiscImageChef.Core/Devices/Dumping/ATA.cs @@ -81,7 +81,9 @@ namespace DiscImageChef.Core.Devices.Dumping DumpLog dumpLog, Encoding encoding, string outputPrefix, string outputPath, Dictionary - formatOptions, CICMMetadataType preSidecar, uint skip) + formatOptions, CICMMetadataType preSidecar, uint skip, + bool + nometadata) { bool aborted; @@ -115,11 +117,10 @@ namespace DiscImageChef.Core.Devices.Dumping DateTime start; DateTime end; - double totalDuration = 0; - double totalChkDuration = 0; - double currentSpeed = 0; - double maxSpeed = double.MinValue; - double minSpeed = double.MaxValue; + double totalDuration = 0; + double currentSpeed = 0; + double maxSpeed = double.MinValue; + double minSpeed = double.MaxValue; aborted = false; System.Console.CancelKeyPress += (sender, e) => e.Cancel = aborted = true; @@ -450,149 +451,165 @@ namespace DiscImageChef.Core.Devices.Dumping return; } - dumpLog.WriteLine("Creating sidecar."); - FiltersList filters = new FiltersList(); - IFilter filter = filters.GetFilter(outputPath); - IMediaImage inputPlugin = ImageFormat.Detect(filter); - if(!inputPlugin.Open(filter)) throw new ArgumentException("Could not open created image."); - - DateTime chkStart = DateTime.UtcNow; - CICMMetadataType sidecar = Sidecar.Create(inputPlugin, outputPath, filter.Id, encoding); - if(preSidecar != null) + double totalChkDuration = 0; + if(!nometadata) { - preSidecar.BlockMedia = sidecar.BlockMedia; - sidecar = preSidecar; - } + dumpLog.WriteLine("Creating sidecar."); + FiltersList filters = new FiltersList(); + IFilter filter = filters.GetFilter(outputPath); + IMediaImage inputPlugin = ImageFormat.Detect(filter); + if(!inputPlugin.Open(filter)) throw new ArgumentException("Could not open created image."); - if(dev.IsUsb) - { - dumpLog.WriteLine("Reading USB descriptors."); - ret = outputPlugin.WriteMediaTag(dev.UsbDescriptors, MediaTagType.USB_Descriptors); - - if(ret) - sidecar.BlockMedia[0].USB = new USBType - { - ProductID = dev.UsbProductId, - VendorID = dev.UsbVendorId, - Descriptors = new DumpType - { - Image = outputPath, - Size = dev.UsbDescriptors.Length, - Checksums = Checksum.GetChecksums(dev.UsbDescriptors).ToArray() - } - }; - } - - if(dev.IsPcmcia) - { - dumpLog.WriteLine("Reading PCMCIA CIS."); - ret = outputPlugin.WriteMediaTag(dev.Cis, MediaTagType.PCMCIA_CIS); - - if(ret) - sidecar.BlockMedia[0].PCMCIA = new PCMCIAType - { - CIS = new DumpType - { - Image = outputPath, - Size = dev.Cis.Length, - Checksums = Checksum.GetChecksums(dev.Cis).ToArray() - } - }; - - dumpLog.WriteLine("Decoding PCMCIA CIS."); - Tuple[] tuples = CIS.GetTuples(dev.Cis); - if(tuples != null) - foreach(Tuple tuple in tuples) - switch(tuple.Code) - { - case TupleCodes.CISTPL_MANFID: - ManufacturerIdentificationTuple manfid = - CIS.DecodeManufacturerIdentificationTuple(tuple); - - if(manfid != null) - { - 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; - } - - break; - case TupleCodes.CISTPL_VERS_1: - Level1VersionTuple vers = CIS.DecodeLevel1VersionTuple(tuple); - - if(vers != null) - { - sidecar.BlockMedia[0].PCMCIA.Manufacturer = vers.Manufacturer; - sidecar.BlockMedia[0].PCMCIA.ProductName = vers.Product; - sidecar.BlockMedia[0].PCMCIA.Compliance = - $"{vers.MajorVersion}.{vers.MinorVersion}"; - sidecar.BlockMedia[0].PCMCIA.AdditionalInformation = - vers.AdditionalInformation; - } - - break; - } - } - - ret = outputPlugin.WriteMediaTag(ataIdentify, MediaTagType.ATA_IDENTIFY); - - if(ret) - sidecar.BlockMedia[0].ATA = new ATAType + DateTime chkStart = DateTime.UtcNow; + CICMMetadataType sidecar = Sidecar.Create(inputPlugin, outputPath, filter.Id, encoding); + if(preSidecar != null) { - Identify = new DumpType + preSidecar.BlockMedia = sidecar.BlockMedia; + sidecar = preSidecar; + } + + if(dev.IsUsb) + { + dumpLog.WriteLine("Reading USB descriptors."); + ret = outputPlugin.WriteMediaTag(dev.UsbDescriptors, MediaTagType.USB_Descriptors); + + if(ret) + sidecar.BlockMedia[0].USB = new USBType + { + ProductID = dev.UsbProductId, + VendorID = dev.UsbVendorId, + Descriptors = new DumpType + { + Image = outputPath, + Size = dev.UsbDescriptors.Length, + Checksums = Checksum.GetChecksums(dev.UsbDescriptors).ToArray() + } + }; + } + + if(dev.IsPcmcia) + { + dumpLog.WriteLine("Reading PCMCIA CIS."); + ret = outputPlugin.WriteMediaTag(dev.Cis, MediaTagType.PCMCIA_CIS); + + if(ret) + sidecar.BlockMedia[0].PCMCIA = new PCMCIAType + { + CIS = new DumpType + { + Image = outputPath, + Size = dev.Cis.Length, + Checksums = Checksum.GetChecksums(dev.Cis).ToArray() + } + }; + + dumpLog.WriteLine("Decoding PCMCIA CIS."); + Tuple[] tuples = CIS.GetTuples(dev.Cis); + if(tuples != null) + foreach(Tuple tuple in tuples) + switch(tuple.Code) + { + case TupleCodes.CISTPL_MANFID: + ManufacturerIdentificationTuple manfid = + CIS.DecodeManufacturerIdentificationTuple(tuple); + + if(manfid != null) + { + 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; + } + + break; + case TupleCodes.CISTPL_VERS_1: + Level1VersionTuple vers = CIS.DecodeLevel1VersionTuple(tuple); + + if(vers != null) + { + sidecar.BlockMedia[0].PCMCIA.Manufacturer = vers.Manufacturer; + sidecar.BlockMedia[0].PCMCIA.ProductName = vers.Product; + sidecar.BlockMedia[0].PCMCIA.Compliance = + $"{vers.MajorVersion}.{vers.MinorVersion}"; + sidecar.BlockMedia[0].PCMCIA.AdditionalInformation = + vers.AdditionalInformation; + } + + break; + } + } + + ret = outputPlugin.WriteMediaTag(ataIdentify, MediaTagType.ATA_IDENTIFY); + + if(ret) + sidecar.BlockMedia[0].ATA = new ATAType { - Image = outputPath, - Size = cmdBuf.Length, - Checksums = Checksum.GetChecksums(cmdBuf).ToArray() - } - }; + Identify = new DumpType + { + Image = outputPath, + Size = cmdBuf.Length, + Checksums = Checksum.GetChecksums(cmdBuf).ToArray() + } + }; - DateTime chkEnd = DateTime.UtcNow; + DateTime chkEnd = DateTime.UtcNow; - totalChkDuration = (chkEnd - chkStart).TotalMilliseconds; - dumpLog.WriteLine("Sidecar created in {0} seconds.", (chkEnd - chkStart).TotalSeconds); - dumpLog.WriteLine("Average checksum speed {0:F3} KiB/sec.", - (double)blockSize * (double)(blocks + 1) / 1024 / (totalChkDuration / 1000)); + totalChkDuration = (chkEnd - chkStart).TotalMilliseconds; + dumpLog.WriteLine("Sidecar created in {0} seconds.", (chkEnd - chkStart).TotalSeconds); + dumpLog.WriteLine("Average checksum speed {0:F3} KiB/sec.", + (double)blockSize * (double)(blocks + 1) / 1024 / (totalChkDuration / 1000)); - List<(ulong start, string type)> filesystems = new List<(ulong start, string type)>(); - if(sidecar.BlockMedia[0].FileSystemInformation != null) - filesystems.AddRange(from partition in sidecar.BlockMedia[0].FileSystemInformation - where partition.FileSystems != null - from fileSystem in partition.FileSystems - select ((ulong)partition.StartSector, fileSystem.Type)); + List<(ulong start, string type)> filesystems = new List<(ulong start, string type)>(); + if(sidecar.BlockMedia[0].FileSystemInformation != null) + filesystems.AddRange(from partition in sidecar.BlockMedia[0].FileSystemInformation + where partition.FileSystems != null + from fileSystem in partition.FileSystems + select ((ulong)partition.StartSector, fileSystem.Type)); - if(filesystems.Count > 0) - foreach(var filesystem in filesystems.Select(o => new {o.start, o.type}).Distinct()) - dumpLog.WriteLine("Found filesystem {0} at sector {1}", filesystem.type, filesystem.start); + if(filesystems.Count > 0) + foreach(var filesystem in filesystems.Select(o => new {o.start, o.type}).Distinct()) + dumpLog.WriteLine("Found filesystem {0} at sector {1}", filesystem.type, + filesystem.start); - DicConsole.WriteLine(); - string xmlDskTyp, xmlDskSubTyp; - if(dev.IsCompactFlash) - Metadata.MediaType.MediaTypeToString(MediaType.CompactFlash, out xmlDskTyp, out xmlDskSubTyp); - else if(dev.IsPcmcia) - Metadata.MediaType.MediaTypeToString(MediaType.PCCardTypeI, out xmlDskTyp, out xmlDskSubTyp); - else - Metadata.MediaType.MediaTypeToString(MediaType.GENERIC_HDD, out xmlDskTyp, out xmlDskSubTyp); - sidecar.BlockMedia[0].DiskType = xmlDskTyp; - sidecar.BlockMedia[0].DiskSubType = xmlDskSubTyp; - sidecar.BlockMedia[0].Interface = "ATA"; - sidecar.BlockMedia[0].LogicalBlocks = (long)blocks; - sidecar.BlockMedia[0].PhysicalBlockSize = (int)physicalsectorsize; - sidecar.BlockMedia[0].LogicalBlockSize = (int)blockSize; - sidecar.BlockMedia[0].Manufacturer = dev.Manufacturer; - sidecar.BlockMedia[0].Model = dev.Model; - sidecar.BlockMedia[0].Serial = dev.Serial; - sidecar.BlockMedia[0].Size = (long)(blocks * blockSize); - if(cylinders > 0 && heads > 0 && sectors > 0) - { - sidecar.BlockMedia[0].Cylinders = cylinders; - sidecar.BlockMedia[0].CylindersSpecified = true; - sidecar.BlockMedia[0].Heads = heads; - sidecar.BlockMedia[0].HeadsSpecified = true; - sidecar.BlockMedia[0].SectorsPerTrack = sectors; - sidecar.BlockMedia[0].SectorsPerTrackSpecified = true; + DicConsole.WriteLine(); + string xmlDskTyp, xmlDskSubTyp; + if(dev.IsCompactFlash) + Metadata.MediaType.MediaTypeToString(MediaType.CompactFlash, out xmlDskTyp, + out xmlDskSubTyp); + else if(dev.IsPcmcia) + Metadata.MediaType.MediaTypeToString(MediaType.PCCardTypeI, out xmlDskTyp, + out xmlDskSubTyp); + else + Metadata.MediaType.MediaTypeToString(MediaType.GENERIC_HDD, out xmlDskTyp, + out xmlDskSubTyp); + sidecar.BlockMedia[0].DiskType = xmlDskTyp; + sidecar.BlockMedia[0].DiskSubType = xmlDskSubTyp; + sidecar.BlockMedia[0].Interface = "ATA"; + sidecar.BlockMedia[0].LogicalBlocks = (long)blocks; + sidecar.BlockMedia[0].PhysicalBlockSize = (int)physicalsectorsize; + sidecar.BlockMedia[0].LogicalBlockSize = (int)blockSize; + sidecar.BlockMedia[0].Manufacturer = dev.Manufacturer; + sidecar.BlockMedia[0].Model = dev.Model; + sidecar.BlockMedia[0].Serial = dev.Serial; + sidecar.BlockMedia[0].Size = (long)(blocks * blockSize); + if(cylinders > 0 && heads > 0 && sectors > 0) + { + sidecar.BlockMedia[0].Cylinders = cylinders; + sidecar.BlockMedia[0].CylindersSpecified = true; + sidecar.BlockMedia[0].Heads = heads; + sidecar.BlockMedia[0].HeadsSpecified = true; + sidecar.BlockMedia[0].SectorsPerTrack = sectors; + sidecar.BlockMedia[0].SectorsPerTrackSpecified = true; + } + + DicConsole.WriteLine("Writing metadata sidecar"); + + FileStream xmlFs = new FileStream(outputPrefix + ".cicm.xml", FileMode.Create); + + XmlSerializer xmlSer = new XmlSerializer(typeof(CICMMetadataType)); + xmlSer.Serialize(xmlFs, sidecar); + xmlFs.Close(); } DicConsole.WriteLine(); @@ -608,17 +625,6 @@ namespace DiscImageChef.Core.Devices.Dumping DicConsole.WriteLine("{0} sectors could not be read.", resume.BadBlocks.Count); if(resume.BadBlocks.Count > 0) resume.BadBlocks.Sort(); DicConsole.WriteLine(); - - if(!aborted) - { - DicConsole.WriteLine("Writing metadata sidecar"); - - FileStream xmlFs = new FileStream(outputPrefix + ".cicm.xml", FileMode.Create); - - XmlSerializer xmlSer = new XmlSerializer(typeof(CICMMetadataType)); - xmlSer.Serialize(xmlFs, sidecar); - xmlFs.Close(); - } } if(dev.IsCompactFlash) Statistics.AddMedia(MediaType.CompactFlash, true); diff --git a/DiscImageChef.Core/Devices/Dumping/CompactDisc.cs b/DiscImageChef.Core/Devices/Dumping/CompactDisc.cs index a18c93fe..52dc7d5f 100644 --- a/DiscImageChef.Core/Devices/Dumping/CompactDisc.cs +++ b/DiscImageChef.Core/Devices/Dumping/CompactDisc.cs @@ -91,7 +91,7 @@ namespace DiscImageChef.Core.Devices.Dumping string outputPrefix, string outputPath, Dictionary formatOptions, CICMMetadataType - preSidecar, uint skip) + preSidecar, uint skip, bool nometadata) { uint subSize; DateTime start; @@ -920,50 +920,62 @@ namespace DiscImageChef.Core.Devices.Dumping return; } - dumpLog.WriteLine("Creating sidecar."); - FiltersList filters = new FiltersList(); - IFilter filter = filters.GetFilter(outputPath); - IMediaImage inputPlugin = ImageFormat.Detect(filter); - if(!inputPlugin.Open(filter)) throw new ArgumentException("Could not open created image."); - - DateTime chkStart = DateTime.UtcNow; - CICMMetadataType sidecar = Sidecar.Create(inputPlugin, outputPath, filter.Id, encoding); - end = DateTime.UtcNow; - - double totalChkDuration = (end - chkStart).TotalMilliseconds; - dumpLog.WriteLine("Sidecar created in {0} seconds.", (end - chkStart).TotalSeconds); - dumpLog.WriteLine("Average checksum speed {0:F3} KiB/sec.", - (double)blockSize * (double)(blocks + 1) / 1024 / (totalChkDuration / 1000)); - - if(preSidecar != null) + double totalChkDuration = 0; + if(!nometadata) { - preSidecar.OpticalDisc = sidecar.OpticalDisc; - sidecar = preSidecar; + dumpLog.WriteLine("Creating sidecar."); + FiltersList filters = new FiltersList(); + IFilter filter = filters.GetFilter(outputPath); + IMediaImage inputPlugin = ImageFormat.Detect(filter); + if(!inputPlugin.Open(filter)) throw new ArgumentException("Could not open created image."); + + DateTime chkStart = DateTime.UtcNow; + CICMMetadataType sidecar = Sidecar.Create(inputPlugin, outputPath, filter.Id, encoding); + end = DateTime.UtcNow; + + totalChkDuration = (end - chkStart).TotalMilliseconds; + dumpLog.WriteLine("Sidecar created in {0} seconds.", (end - chkStart).TotalSeconds); + dumpLog.WriteLine("Average checksum speed {0:F3} KiB/sec.", + (double)blockSize * (double)(blocks + 1) / 1024 / (totalChkDuration / 1000)); + + if(preSidecar != null) + { + preSidecar.OpticalDisc = sidecar.OpticalDisc; + sidecar = preSidecar; + } + + List<(ulong start, string type)> filesystems = new List<(ulong start, string type)>(); + if(sidecar.OpticalDisc[0].Track != null) + filesystems.AddRange(from xmlTrack in sidecar.OpticalDisc[0].Track + where xmlTrack.FileSystemInformation != null + from partition in xmlTrack.FileSystemInformation + where partition.FileSystems != null + from fileSystem in partition.FileSystems + select ((ulong)partition.StartSector, fileSystem.Type)); + + if(filesystems.Count > 0) + foreach(var filesystem in filesystems.Select(o => new {o.start, o.type}).Distinct()) + dumpLog.WriteLine("Found filesystem {0} at sector {1}", filesystem.type, filesystem.start); + + sidecar.OpticalDisc[0].Dimensions = Dimensions.DimensionsFromMediaType(dskType); + Metadata.MediaType.MediaTypeToString(dskType, out string xmlDskTyp, out string xmlDskSubTyp); + sidecar.OpticalDisc[0].DiscType = xmlDskTyp; + sidecar.OpticalDisc[0].DiscSubType = xmlDskSubTyp; + sidecar.OpticalDisc[0].DumpHardwareArray = resume.Tries.ToArray(); + + foreach(KeyValuePair tag in mediaTags) + if(outputPlugin.SupportedMediaTags.Contains(tag.Key)) + Mmc.AddMediaTagToSidecar(outputPath, tag, ref sidecar); + + DicConsole.WriteLine("Writing metadata sidecar"); + + FileStream xmlFs = new FileStream(outputPrefix + ".cicm.xml", FileMode.Create); + + XmlSerializer xmlSer = new XmlSerializer(typeof(CICMMetadataType)); + xmlSer.Serialize(xmlFs, sidecar); + xmlFs.Close(); } - List<(ulong start, string type)> filesystems = new List<(ulong start, string type)>(); - if(sidecar.OpticalDisc[0].Track != null) - filesystems.AddRange(from xmlTrack in sidecar.OpticalDisc[0].Track - where xmlTrack.FileSystemInformation != null - from partition in xmlTrack.FileSystemInformation - where partition.FileSystems != null - from fileSystem in partition.FileSystems - select ((ulong)partition.StartSector, fileSystem.Type)); - - if(filesystems.Count > 0) - foreach(var filesystem in filesystems.Select(o => new {o.start, o.type}).Distinct()) - dumpLog.WriteLine("Found filesystem {0} at sector {1}", filesystem.type, filesystem.start); - - sidecar.OpticalDisc[0].Dimensions = Dimensions.DimensionsFromMediaType(dskType); - Metadata.MediaType.MediaTypeToString(dskType, out string xmlDskTyp, out string xmlDskSubTyp); - sidecar.OpticalDisc[0].DiscType = xmlDskTyp; - sidecar.OpticalDisc[0].DiscSubType = xmlDskSubTyp; - sidecar.OpticalDisc[0].DumpHardwareArray = resume.Tries.ToArray(); - - foreach(KeyValuePair tag in mediaTags) - if(outputPlugin.SupportedMediaTags.Contains(tag.Key)) - Mmc.AddMediaTagToSidecar(outputPath, tag, ref sidecar); - DicConsole.WriteLine(); DicConsole.WriteLine("Took a total of {0:F3} seconds ({1:F3} processing commands, {2:F3} checksumming, {3:F3} writing, {4:F3} closing).", @@ -977,17 +989,6 @@ namespace DiscImageChef.Core.Devices.Dumping DicConsole.WriteLine("{0} sectors could not be read.", resume.BadBlocks.Count); DicConsole.WriteLine(); - if(!aborted) - { - DicConsole.WriteLine("Writing metadata sidecar"); - - FileStream xmlFs = new FileStream(outputPrefix + ".cicm.xml", FileMode.Create); - - XmlSerializer xmlSer = new XmlSerializer(typeof(CICMMetadataType)); - xmlSer.Serialize(xmlFs, sidecar); - xmlFs.Close(); - } - Statistics.AddMedia(dskType, true); } } diff --git a/DiscImageChef.Core/Devices/Dumping/MMC.cs b/DiscImageChef.Core/Devices/Dumping/MMC.cs index 78238bb4..2eba8c42 100644 --- a/DiscImageChef.Core/Devices/Dumping/MMC.cs +++ b/DiscImageChef.Core/Devices/Dumping/MMC.cs @@ -84,7 +84,7 @@ namespace DiscImageChef.Core.Devices.Dumping string outputPrefix, string outputPath, Dictionary formatOptions, CICMMetadataType - preSidecar, uint skip) + preSidecar, uint skip, bool nometadata) { bool sense; ulong blocks; @@ -200,7 +200,7 @@ namespace DiscImageChef.Core.Devices.Dumping { CompactDisc.Dump(dev, devicePath, outputPlugin, retryPasses, force, dumpRaw, persistent, stopOnError, ref dskType, ref resume, ref dumpLog, dumpLeadIn, encoding, outputPrefix, outputPath, - formatOptions, preSidecar, skip); + formatOptions, preSidecar, skip, nometadata); return; } @@ -602,13 +602,13 @@ namespace DiscImageChef.Core.Devices.Dumping { Xgd.Dump(dev, devicePath, outputPlugin, retryPasses, force, dumpRaw, persistent, stopOnError, mediaTags, ref dskType, ref resume, ref dumpLog, encoding, outputPrefix, outputPath, formatOptions, - preSidecar, skip); + preSidecar, skip, nometadata); return; } Sbc.Dump(dev, devicePath, outputPlugin, retryPasses, force, dumpRaw, persistent, stopOnError, mediaTags, ref dskType, true, ref resume, ref dumpLog, encoding, outputPrefix, outputPath, formatOptions, - preSidecar, skip); + preSidecar, skip, nometadata); } internal static void AddMediaTagToSidecar(string outputPath, diff --git a/DiscImageChef.Core/Devices/Dumping/NVMe.cs b/DiscImageChef.Core/Devices/Dumping/NVMe.cs index 4342035e..52dac8b3 100644 --- a/DiscImageChef.Core/Devices/Dumping/NVMe.cs +++ b/DiscImageChef.Core/Devices/Dumping/NVMe.cs @@ -50,7 +50,7 @@ namespace DiscImageChef.Core.Devices.Dumping DumpLog dumpLog, Encoding encoding, string outputPrefix, string outputPath, Dictionary - formatOptions, CICMMetadataType preSidecar, uint skip) + formatOptions, CICMMetadataType preSidecar, uint skip, bool nometadata) { throw new NotImplementedException("NVMe devices not yet supported."); } diff --git a/DiscImageChef.Core/Devices/Dumping/SBC.cs b/DiscImageChef.Core/Devices/Dumping/SBC.cs index 1d901638..c136f37a 100644 --- a/DiscImageChef.Core/Devices/Dumping/SBC.cs +++ b/DiscImageChef.Core/Devices/Dumping/SBC.cs @@ -87,7 +87,7 @@ namespace DiscImageChef.Core.Devices.Dumping string outputPath, Dictionary formatOptions, CICMMetadataType preSidecar, - uint skip) + uint skip, bool nometadata) { bool sense; ulong blocks; @@ -101,7 +101,6 @@ namespace DiscImageChef.Core.Devices.Dumping DateTime start; DateTime end; double totalDuration = 0; - double totalChkDuration = 0; double currentSpeed = 0; double maxSpeed = double.MinValue; double minSpeed = double.MaxValue; @@ -674,213 +673,225 @@ namespace DiscImageChef.Core.Devices.Dumping return; } - dumpLog.WriteLine("Creating sidecar."); - FiltersList filters = new FiltersList(); - IFilter filter = filters.GetFilter(outputPath); - IMediaImage inputPlugin = ImageFormat.Detect(filter); - if(!inputPlugin.Open(filter)) throw new ArgumentException("Could not open created image."); - - DateTime chkStart = DateTime.UtcNow; - CICMMetadataType sidecar = Sidecar.Create(inputPlugin, outputPath, filter.Id, encoding); - end = DateTime.UtcNow; - - totalChkDuration = (end - chkStart).TotalMilliseconds; - dumpLog.WriteLine("Sidecar created in {0} seconds.", (end - chkStart).TotalSeconds); - dumpLog.WriteLine("Average checksum speed {0:F3} KiB/sec.", - (double)blockSize * (double)(blocks + 1) / 1024 / (totalChkDuration / 1000)); - - if(opticalDisc) + double totalChkDuration = 0; + if(!nometadata) { - if(preSidecar != null) + dumpLog.WriteLine("Creating sidecar."); + FiltersList filters = new FiltersList(); + IFilter filter = filters.GetFilter(outputPath); + IMediaImage inputPlugin = ImageFormat.Detect(filter); + if(!inputPlugin.Open(filter)) throw new ArgumentException("Could not open created image."); + + DateTime chkStart = DateTime.UtcNow; + CICMMetadataType sidecar = Sidecar.Create(inputPlugin, outputPath, filter.Id, encoding); + end = DateTime.UtcNow; + + totalChkDuration = (end - chkStart).TotalMilliseconds; + dumpLog.WriteLine("Sidecar created in {0} seconds.", (end - chkStart).TotalSeconds); + dumpLog.WriteLine("Average checksum speed {0:F3} KiB/sec.", + (double)blockSize * (double)(blocks + 1) / 1024 / (totalChkDuration / 1000)); + + if(opticalDisc) { - preSidecar.OpticalDisc = sidecar.OpticalDisc; - sidecar = preSidecar; - } - - List<(ulong start, string type)> filesystems = new List<(ulong start, string type)>(); - if(sidecar.OpticalDisc[0].Track != null) - filesystems.AddRange(from xmlTrack in sidecar.OpticalDisc[0].Track - where xmlTrack.FileSystemInformation != null - from partition in xmlTrack.FileSystemInformation - where partition.FileSystems != null - from fileSystem in partition.FileSystems - select ((ulong)partition.StartSector, fileSystem.Type)); - - if(filesystems.Count > 0) - foreach(var filesystem in filesystems.Select(o => new {o.start, o.type}).Distinct()) - dumpLog.WriteLine("Found filesystem {0} at sector {1}", filesystem.type, filesystem.start); - // TODO: Implement layers - sidecar.OpticalDisc[0].Dimensions = Dimensions.DimensionsFromMediaType(dskType); - Metadata.MediaType.MediaTypeToString(dskType, out string xmlDskTyp, out string xmlDskSubTyp); - sidecar.OpticalDisc[0].DiscType = xmlDskTyp; - sidecar.OpticalDisc[0].DiscSubType = xmlDskSubTyp; - sidecar.OpticalDisc[0].DumpHardwareArray = resume.Tries.ToArray(); - - foreach(KeyValuePair tag in mediaTags) - if(outputPlugin.SupportedMediaTags.Contains(tag.Key)) - Mmc.AddMediaTagToSidecar(outputPath, tag, ref sidecar); - } - else - { - if(preSidecar != null) - { - preSidecar.BlockMedia = sidecar.BlockMedia; - sidecar = preSidecar; - } - - // All USB flash drives report as removable, even if the media is not removable - if(!dev.IsRemovable || dev.IsUsb) - { - if(dev.IsUsb) - if(outputPlugin.SupportedMediaTags.Contains(MediaTagType.USB_Descriptors)) - sidecar.BlockMedia[0].USB = new USBType - { - ProductID = dev.UsbProductId, - VendorID = dev.UsbVendorId, - Descriptors = new DumpType - { - Image = outputPath, - Size = dev.UsbDescriptors.Length, - Checksums = Checksum.GetChecksums(dev.UsbDescriptors).ToArray() - } - }; - - byte[] cmdBuf; - if(dev.Type == DeviceType.ATAPI) + if(preSidecar != null) { - sense = dev.AtapiIdentify(out cmdBuf, out _); - if(!sense) - if(outputPlugin.SupportedMediaTags.Contains(MediaTagType.ATAPI_IDENTIFY)) - sidecar.BlockMedia[0].ATA = new ATAType + preSidecar.OpticalDisc = sidecar.OpticalDisc; + sidecar = preSidecar; + } + + List<(ulong start, string type)> filesystems = new List<(ulong start, string type)>(); + if(sidecar.OpticalDisc[0].Track != null) + filesystems.AddRange(from xmlTrack in sidecar.OpticalDisc[0].Track + where xmlTrack.FileSystemInformation != null + from partition in xmlTrack.FileSystemInformation + where partition.FileSystems != null + from fileSystem in partition.FileSystems + select ((ulong)partition.StartSector, fileSystem.Type)); + + if(filesystems.Count > 0) + foreach(var filesystem in filesystems.Select(o => new {o.start, o.type}).Distinct()) + dumpLog.WriteLine("Found filesystem {0} at sector {1}", filesystem.type, filesystem.start); + // TODO: Implement layers + sidecar.OpticalDisc[0].Dimensions = Dimensions.DimensionsFromMediaType(dskType); + Metadata.MediaType.MediaTypeToString(dskType, out string xmlDskTyp, out string xmlDskSubTyp); + sidecar.OpticalDisc[0].DiscType = xmlDskTyp; + sidecar.OpticalDisc[0].DiscSubType = xmlDskSubTyp; + sidecar.OpticalDisc[0].DumpHardwareArray = resume.Tries.ToArray(); + + foreach(KeyValuePair tag in mediaTags) + if(outputPlugin.SupportedMediaTags.Contains(tag.Key)) + Mmc.AddMediaTagToSidecar(outputPath, tag, ref sidecar); + } + else + { + if(preSidecar != null) + { + preSidecar.BlockMedia = sidecar.BlockMedia; + sidecar = preSidecar; + } + + // All USB flash drives report as removable, even if the media is not removable + if(!dev.IsRemovable || dev.IsUsb) + { + if(dev.IsUsb) + if(outputPlugin.SupportedMediaTags.Contains(MediaTagType.USB_Descriptors)) + sidecar.BlockMedia[0].USB = new USBType { - Identify = new DumpType + ProductID = dev.UsbProductId, + VendorID = dev.UsbVendorId, + Descriptors = new DumpType + { + Image = outputPath, + Size = dev.UsbDescriptors.Length, + Checksums = Checksum.GetChecksums(dev.UsbDescriptors).ToArray() + } + }; + + byte[] cmdBuf; + if(dev.Type == DeviceType.ATAPI) + { + sense = dev.AtapiIdentify(out cmdBuf, out _); + if(!sense) + if(outputPlugin.SupportedMediaTags.Contains(MediaTagType.ATAPI_IDENTIFY)) + sidecar.BlockMedia[0].ATA = new ATAType + { + Identify = new DumpType + { + Image = outputPath, + Size = cmdBuf.Length, + Checksums = Checksum.GetChecksums(cmdBuf).ToArray() + } + }; + } + + sense = dev.ScsiInquiry(out cmdBuf, out _); + if(!sense) + { + if(outputPlugin.SupportedMediaTags.Contains(MediaTagType.SCSI_INQUIRY)) + sidecar.BlockMedia[0].SCSI = new SCSIType + { + Inquiry = new DumpType { Image = outputPath, Size = cmdBuf.Length, Checksums = Checksum.GetChecksums(cmdBuf).ToArray() } }; - } - sense = dev.ScsiInquiry(out cmdBuf, out _); - if(!sense) - { - if(outputPlugin.SupportedMediaTags.Contains(MediaTagType.SCSI_INQUIRY)) - sidecar.BlockMedia[0].SCSI = new SCSIType + // TODO: SCSI Extended Vendor Page descriptors + /* + dumpLog.WriteLine("Reading SCSI Extended Vendor Page Descriptors."); + sense = dev.ScsiInquiry(out cmdBuf, out _, 0x00); + if(!sense) { - Inquiry = new DumpType + byte[] pages = EVPD.DecodePage00(cmdBuf); + + if(pages != null) { - Image = outputPath, - Size = cmdBuf.Length, - Checksums = Checksum.GetChecksums(cmdBuf).ToArray() - } - }; - - // TODO: SCSI Extended Vendor Page descriptors - /* - dumpLog.WriteLine("Reading SCSI Extended Vendor Page Descriptors."); - sense = dev.ScsiInquiry(out cmdBuf, out _, 0x00); - if(!sense) - { - byte[] pages = EVPD.DecodePage00(cmdBuf); - - if(pages != null) - { - List evpds = new List(); - foreach(byte page in pages) - { - dumpLog.WriteLine("Requesting page {0:X2}h.", page); - sense = dev.ScsiInquiry(out cmdBuf, out _, page); - if(sense) continue; - - EVPDType evpd = new EVPDType + List evpds = new List(); + foreach(byte page in pages) { - Image = $"{outputPrefix}.evpd_{page:X2}h.bin", - Checksums = Checksum.GetChecksums(cmdBuf).ToArray(), - Size = cmdBuf.Length - }; - evpd.Checksums = Checksum.GetChecksums(cmdBuf).ToArray(); - DataFile.WriteTo("SCSI Dump", evpd.Image, cmdBuf); - evpds.Add(evpd); + dumpLog.WriteLine("Requesting page {0:X2}h.", page); + sense = dev.ScsiInquiry(out cmdBuf, out _, page); + if(sense) continue; + + EVPDType evpd = new EVPDType + { + Image = $"{outputPrefix}.evpd_{page:X2}h.bin", + Checksums = Checksum.GetChecksums(cmdBuf).ToArray(), + Size = cmdBuf.Length + }; + evpd.Checksums = Checksum.GetChecksums(cmdBuf).ToArray(); + DataFile.WriteTo("SCSI Dump", evpd.Image, cmdBuf); + evpds.Add(evpd); + } + + if(evpds.Count > 0) sidecar.BlockMedia[0].SCSI.EVPD = evpds.ToArray(); } - - if(evpds.Count > 0) sidecar.BlockMedia[0].SCSI.EVPD = evpds.ToArray(); } - } - */ + */ - dumpLog.WriteLine("Requesting MODE SENSE (10)."); - sense = dev.ModeSense10(out cmdBuf, out _, false, true, ScsiModeSensePageControl.Current, 0x3F, - 0xFF, 5, out _); - if(!sense || dev.Error) + dumpLog.WriteLine("Requesting MODE SENSE (10)."); sense = dev.ModeSense10(out cmdBuf, out _, false, true, ScsiModeSensePageControl.Current, - 0x3F, 0x00, 5, out _); + 0x3F, 0xFF, 5, out _); + if(!sense || dev.Error) + sense = dev.ModeSense10(out cmdBuf, out _, false, true, + ScsiModeSensePageControl.Current, 0x3F, 0x00, 5, out _); - decMode = null; + decMode = null; - if(!sense && !dev.Error) - if(Modes.DecodeMode10(cmdBuf, dev.ScsiType).HasValue) - if(outputPlugin.SupportedMediaTags.Contains(MediaTagType.SCSI_MODESENSE_10)) - sidecar.BlockMedia[0].SCSI.ModeSense10 = new DumpType - { - Image = outputPath, - Size = cmdBuf.Length, - Checksums = Checksum.GetChecksums(cmdBuf).ToArray() - }; + if(!sense && !dev.Error) + if(Modes.DecodeMode10(cmdBuf, dev.ScsiType).HasValue) + if(outputPlugin.SupportedMediaTags.Contains(MediaTagType.SCSI_MODESENSE_10)) + sidecar.BlockMedia[0].SCSI.ModeSense10 = new DumpType + { + Image = outputPath, + Size = cmdBuf.Length, + Checksums = Checksum.GetChecksums(cmdBuf).ToArray() + }; - dumpLog.WriteLine("Requesting MODE SENSE (6)."); - sense = dev.ModeSense6(out cmdBuf, out _, false, ScsiModeSensePageControl.Current, 0x3F, 0x00, - 5, out _); - if(sense || dev.Error) + dumpLog.WriteLine("Requesting MODE SENSE (6)."); sense = dev.ModeSense6(out cmdBuf, out _, false, ScsiModeSensePageControl.Current, 0x3F, 0x00, 5, out _); - if(sense || dev.Error) sense = dev.ModeSense(out cmdBuf, out _, 5, out _); + if(sense || dev.Error) + sense = dev.ModeSense6(out cmdBuf, out _, false, ScsiModeSensePageControl.Current, 0x3F, + 0x00, 5, out _); + if(sense || dev.Error) sense = dev.ModeSense(out cmdBuf, out _, 5, out _); - if(!sense && !dev.Error) - if(Modes.DecodeMode6(cmdBuf, dev.ScsiType).HasValue) - if(outputPlugin.SupportedMediaTags.Contains(MediaTagType.SCSI_MODESENSE_6)) - sidecar.BlockMedia[0].SCSI.ModeSense = new DumpType - { - Image = outputPath, - Size = cmdBuf.Length, - Checksums = Checksum.GetChecksums(cmdBuf).ToArray() - }; + if(!sense && !dev.Error) + if(Modes.DecodeMode6(cmdBuf, dev.ScsiType).HasValue) + if(outputPlugin.SupportedMediaTags.Contains(MediaTagType.SCSI_MODESENSE_6)) + sidecar.BlockMedia[0].SCSI.ModeSense = new DumpType + { + Image = outputPath, + Size = cmdBuf.Length, + Checksums = Checksum.GetChecksums(cmdBuf).ToArray() + }; + } } + + List<(ulong start, string type)> filesystems = new List<(ulong start, string type)>(); + if(sidecar.BlockMedia[0].FileSystemInformation != null) + filesystems.AddRange(from partition in sidecar.BlockMedia[0].FileSystemInformation + where partition.FileSystems != null + from fileSystem in partition.FileSystems + select ((ulong)partition.StartSector, fileSystem.Type)); + + if(filesystems.Count > 0) + foreach(var filesystem in filesystems.Select(o => new {o.start, o.type}).Distinct()) + dumpLog.WriteLine("Found filesystem {0} at sector {1}", filesystem.type, filesystem.start); + sidecar.BlockMedia[0].Dimensions = Dimensions.DimensionsFromMediaType(dskType); + Metadata.MediaType.MediaTypeToString(dskType, out string xmlDskTyp, out string xmlDskSubTyp); + sidecar.BlockMedia[0].DiskType = xmlDskTyp; + sidecar.BlockMedia[0].DiskSubType = xmlDskSubTyp; + // TODO: Implement device firmware revision + if(!dev.IsRemovable || dev.IsUsb) + if(dev.Type == DeviceType.ATAPI) + sidecar.BlockMedia[0].Interface = "ATAPI"; + else if(dev.IsUsb) + sidecar.BlockMedia[0].Interface = "USB"; + else if(dev.IsFireWire) + sidecar.BlockMedia[0].Interface = "FireWire"; + else + sidecar.BlockMedia[0].Interface = "SCSI"; + sidecar.BlockMedia[0].LogicalBlocks = (long)blocks; + sidecar.BlockMedia[0].PhysicalBlockSize = (int)physicalBlockSize; + sidecar.BlockMedia[0].LogicalBlockSize = (int)logicalBlockSize; + sidecar.BlockMedia[0].Manufacturer = dev.Manufacturer; + sidecar.BlockMedia[0].Model = dev.Model; + sidecar.BlockMedia[0].Serial = dev.Serial; + sidecar.BlockMedia[0].Size = (long)(blocks * blockSize); + + if(dev.IsRemovable) sidecar.BlockMedia[0].DumpHardwareArray = resume.Tries.ToArray(); } - List<(ulong start, string type)> filesystems = new List<(ulong start, string type)>(); - if(sidecar.BlockMedia[0].FileSystemInformation != null) - filesystems.AddRange(from partition in sidecar.BlockMedia[0].FileSystemInformation - where partition.FileSystems != null - from fileSystem in partition.FileSystems - select ((ulong)partition.StartSector, fileSystem.Type)); + DicConsole.WriteLine("Writing metadata sidecar"); - if(filesystems.Count > 0) - foreach(var filesystem in filesystems.Select(o => new {o.start, o.type}).Distinct()) - dumpLog.WriteLine("Found filesystem {0} at sector {1}", filesystem.type, filesystem.start); - sidecar.BlockMedia[0].Dimensions = Dimensions.DimensionsFromMediaType(dskType); - Metadata.MediaType.MediaTypeToString(dskType, out string xmlDskTyp, out string xmlDskSubTyp); - sidecar.BlockMedia[0].DiskType = xmlDskTyp; - sidecar.BlockMedia[0].DiskSubType = xmlDskSubTyp; - // TODO: Implement device firmware revision - if(!dev.IsRemovable || dev.IsUsb) - if(dev.Type == DeviceType.ATAPI) - sidecar.BlockMedia[0].Interface = "ATAPI"; - else if(dev.IsUsb) - sidecar.BlockMedia[0].Interface = "USB"; - else if(dev.IsFireWire) - sidecar.BlockMedia[0].Interface = "FireWire"; - else - sidecar.BlockMedia[0].Interface = "SCSI"; - sidecar.BlockMedia[0].LogicalBlocks = (long)blocks; - sidecar.BlockMedia[0].PhysicalBlockSize = (int)physicalBlockSize; - sidecar.BlockMedia[0].LogicalBlockSize = (int)logicalBlockSize; - sidecar.BlockMedia[0].Manufacturer = dev.Manufacturer; - sidecar.BlockMedia[0].Model = dev.Model; - sidecar.BlockMedia[0].Serial = dev.Serial; - sidecar.BlockMedia[0].Size = (long)(blocks * blockSize); + FileStream xmlFs = new FileStream(outputPrefix + ".cicm.xml", FileMode.Create); - if(dev.IsRemovable) sidecar.BlockMedia[0].DumpHardwareArray = resume.Tries.ToArray(); + XmlSerializer xmlSer = new XmlSerializer(typeof(CICMMetadataType)); + xmlSer.Serialize(xmlFs, sidecar); + xmlFs.Close(); } DicConsole.WriteLine(); @@ -895,17 +906,6 @@ namespace DiscImageChef.Core.Devices.Dumping DicConsole.WriteLine("{0} sectors could not be read.", resume.BadBlocks.Count); DicConsole.WriteLine(); - if(!aborted) - { - DicConsole.WriteLine("Writing metadata sidecar"); - - FileStream xmlFs = new FileStream(outputPrefix + ".cicm.xml", FileMode.Create); - - XmlSerializer xmlSer = new XmlSerializer(typeof(CICMMetadataType)); - xmlSer.Serialize(xmlFs, sidecar); - xmlFs.Close(); - } - Statistics.AddMedia(dskType, true); } } diff --git a/DiscImageChef.Core/Devices/Dumping/SCSI.cs b/DiscImageChef.Core/Devices/Dumping/SCSI.cs index a9decb0a..347d5816 100644 --- a/DiscImageChef.Core/Devices/Dumping/SCSI.cs +++ b/DiscImageChef.Core/Devices/Dumping/SCSI.cs @@ -79,7 +79,7 @@ namespace DiscImageChef.Core.Devices.Dumping string outputPath, Dictionary formatOptions, CICMMetadataType - preSidecar, uint skip) + preSidecar, uint skip, bool nometadata) { MediaType dskType = MediaType.Unknown; int resets = 0; @@ -212,12 +212,12 @@ namespace DiscImageChef.Core.Devices.Dumping case PeripheralDeviceTypes.MultiMediaDevice: Mmc.Dump(dev, devicePath, outputPlugin, retryPasses, force, dumpRaw, persistent, stopOnError, ref dskType, ref resume, ref dumpLog, dumpLeadIn, encoding, outputPrefix, outputPath, - formatOptions, preSidecar, skip); + formatOptions, preSidecar, skip, nometadata); return; default: Sbc.Dump(dev, devicePath, outputPlugin, retryPasses, force, dumpRaw, persistent, stopOnError, null, ref dskType, false, ref resume, ref dumpLog, encoding, outputPrefix, outputPath, - formatOptions, preSidecar, skip); + formatOptions, preSidecar, skip, nometadata); break; } } diff --git a/DiscImageChef.Core/Devices/Dumping/SecureDigital.cs b/DiscImageChef.Core/Devices/Dumping/SecureDigital.cs index f03ab402..359a1743 100644 --- a/DiscImageChef.Core/Devices/Dumping/SecureDigital.cs +++ b/DiscImageChef.Core/Devices/Dumping/SecureDigital.cs @@ -79,7 +79,7 @@ namespace DiscImageChef.Core.Devices.Dumping DumpLog dumpLog, Encoding encoding, string outputPrefix, string outputPath, Dictionary - formatOptions, CICMMetadataType preSidecar, uint skip) + formatOptions, CICMMetadataType preSidecar, uint skip, bool nometadata) { bool aborted; @@ -196,7 +196,6 @@ namespace DiscImageChef.Core.Devices.Dumping DateTime start; DateTime end; double totalDuration = 0; - double totalChkDuration = 0; double currentSpeed = 0; double maxSpeed = double.MinValue; double minSpeed = double.MaxValue; @@ -417,187 +416,199 @@ namespace DiscImageChef.Core.Devices.Dumping return; } - dumpLog.WriteLine("Creating sidecar."); - FiltersList filters = new FiltersList(); - IFilter filter = filters.GetFilter(outputPath); - IMediaImage inputPlugin = ImageFormat.Detect(filter); - if(!inputPlugin.Open(filter)) throw new ArgumentException("Could not open created image."); - - DateTime chkStart = DateTime.UtcNow; - CICMMetadataType sidecar = Sidecar.Create(inputPlugin, outputPath, filter.Id, encoding); - - if(preSidecar != null) + double totalChkDuration = 0; + if(!nometadata) { - preSidecar.BlockMedia = sidecar.BlockMedia; - sidecar = preSidecar; - } + dumpLog.WriteLine("Creating sidecar."); + FiltersList filters = new FiltersList(); + IFilter filter = filters.GetFilter(outputPath); + IMediaImage inputPlugin = ImageFormat.Detect(filter); + if(!inputPlugin.Open(filter)) throw new ArgumentException("Could not open created image."); - switch(dev.Type) - { - case DeviceType.MMC: - sidecar.BlockMedia[0].MultiMediaCard = new MultiMediaCardType(); - break; - case DeviceType.SecureDigital: - sidecar.BlockMedia[0].SecureDigital = new SecureDigitalType(); - break; - } + DateTime chkStart = DateTime.UtcNow; + CICMMetadataType sidecar = Sidecar.Create(inputPlugin, outputPath, filter.Id, encoding); - DumpType cidDump = null; - DumpType csdDump = null; - DumpType ocrDump = null; - - if(cid != null) - { - cidDump = new DumpType + if(preSidecar != null) { - Image = outputPath, - Size = cid.Length, - Checksums = Checksum.GetChecksums(cid).ToArray() - }; - - ret = - outputPlugin.WriteMediaTag(cid, - dev.Type == DeviceType.SecureDigital - ? MediaTagType.SD_CID - : MediaTagType.MMC_CID); - - // Cannot write CID to image - if(!ret && !force) - { - dumpLog.WriteLine("Cannot write CID to output image."); - throw new ArgumentException(outputPlugin.ErrorMessage); + preSidecar.BlockMedia = sidecar.BlockMedia; + sidecar = preSidecar; } - } - if(csd != null) - { - csdDump = new DumpType + switch(dev.Type) { - Image = outputPath, - Size = csd.Length, - Checksums = Checksum.GetChecksums(csd).ToArray() - }; - - ret = - outputPlugin.WriteMediaTag(csd, - dev.Type == DeviceType.SecureDigital - ? MediaTagType.SD_CSD - : MediaTagType.MMC_CSD); - - // Cannot write CSD to image - if(!ret && !force) - { - dumpLog.WriteLine("Cannot write CSD to output image."); - throw new ArgumentException(outputPlugin.ErrorMessage); + case DeviceType.MMC: + sidecar.BlockMedia[0].MultiMediaCard = new MultiMediaCardType(); + break; + case DeviceType.SecureDigital: + sidecar.BlockMedia[0].SecureDigital = new SecureDigitalType(); + break; } - } - if(ecsd != null) - { - sidecar.BlockMedia[0].MultiMediaCard.ExtendedCSD = new DumpType + DumpType cidDump = null; + DumpType csdDump = null; + DumpType ocrDump = null; + + if(cid != null) { - Image = outputPath, - Size = ecsd.Length, - Checksums = Checksum.GetChecksums(ecsd).ToArray() - }; + cidDump = new DumpType + { + Image = outputPath, + Size = cid.Length, + Checksums = Checksum.GetChecksums(cid).ToArray() + }; - ret = outputPlugin.WriteMediaTag(ecsd, MediaTagType.MMC_ExtendedCSD); + ret = + outputPlugin.WriteMediaTag(cid, + dev.Type == DeviceType.SecureDigital + ? MediaTagType.SD_CID + : MediaTagType.MMC_CID); - // Cannot write Extended CSD to image - if(!ret && !force) - { - dumpLog.WriteLine("Cannot write Extended CSD to output image."); - throw new ArgumentException(outputPlugin.ErrorMessage); + // Cannot write CID to image + if(!ret && !force) + { + dumpLog.WriteLine("Cannot write CID to output image."); + throw new ArgumentException(outputPlugin.ErrorMessage); + } } - } - if(ocr != null) - { - ocrDump = new DumpType + if(csd != null) { - Image = outputPath, - Size = ocr.Length, - Checksums = Checksum.GetChecksums(ocr).ToArray() - }; + csdDump = new DumpType + { + Image = outputPath, + Size = csd.Length, + Checksums = Checksum.GetChecksums(csd).ToArray() + }; - ret = - outputPlugin.WriteMediaTag(ocr, - dev.Type == DeviceType.SecureDigital - ? MediaTagType.SD_OCR - : MediaTagType.MMC_OCR); + ret = + outputPlugin.WriteMediaTag(csd, + dev.Type == DeviceType.SecureDigital + ? MediaTagType.SD_CSD + : MediaTagType.MMC_CSD); - // Cannot write OCR to image - if(!ret && !force) - { - dumpLog.WriteLine("Cannot write OCR to output image."); - throw new ArgumentException(outputPlugin.ErrorMessage); + // Cannot write CSD to image + if(!ret && !force) + { + dumpLog.WriteLine("Cannot write CSD to output image."); + throw new ArgumentException(outputPlugin.ErrorMessage); + } } - } - if(scr != null) - { - sidecar.BlockMedia[0].SecureDigital.SCR = new DumpType + if(ecsd != null) { - Image = outputPath, - Size = scr.Length, - Checksums = Checksum.GetChecksums(scr).ToArray() - }; + sidecar.BlockMedia[0].MultiMediaCard.ExtendedCSD = new DumpType + { + Image = outputPath, + Size = ecsd.Length, + Checksums = Checksum.GetChecksums(ecsd).ToArray() + }; - ret = outputPlugin.WriteMediaTag(scr, MediaTagType.SD_SCR); + ret = outputPlugin.WriteMediaTag(ecsd, MediaTagType.MMC_ExtendedCSD); - // Cannot write SCR to image - if(!ret && !force) - { - dumpLog.WriteLine("Cannot write SCR to output image."); - throw new ArgumentException(outputPlugin.ErrorMessage); + // Cannot write Extended CSD to image + if(!ret && !force) + { + dumpLog.WriteLine("Cannot write Extended CSD to output image."); + throw new ArgumentException(outputPlugin.ErrorMessage); + } } + + if(ocr != null) + { + ocrDump = new DumpType + { + Image = outputPath, + Size = ocr.Length, + Checksums = Checksum.GetChecksums(ocr).ToArray() + }; + + ret = + outputPlugin.WriteMediaTag(ocr, + dev.Type == DeviceType.SecureDigital + ? MediaTagType.SD_OCR + : MediaTagType.MMC_OCR); + + // Cannot write OCR to image + if(!ret && !force) + { + dumpLog.WriteLine("Cannot write OCR to output image."); + throw new ArgumentException(outputPlugin.ErrorMessage); + } + } + + if(scr != null) + { + sidecar.BlockMedia[0].SecureDigital.SCR = new DumpType + { + Image = outputPath, + Size = scr.Length, + Checksums = Checksum.GetChecksums(scr).ToArray() + }; + + ret = outputPlugin.WriteMediaTag(scr, MediaTagType.SD_SCR); + + // Cannot write SCR to image + if(!ret && !force) + { + dumpLog.WriteLine("Cannot write SCR to output image."); + throw new ArgumentException(outputPlugin.ErrorMessage); + } + } + + switch(dev.Type) + { + case DeviceType.MMC: + sidecar.BlockMedia[0].MultiMediaCard.CID = cidDump; + sidecar.BlockMedia[0].MultiMediaCard.CSD = csdDump; + sidecar.BlockMedia[0].MultiMediaCard.OCR = ocrDump; + break; + case DeviceType.SecureDigital: + sidecar.BlockMedia[0].SecureDigital.CID = cidDump; + sidecar.BlockMedia[0].SecureDigital.CSD = csdDump; + sidecar.BlockMedia[0].SecureDigital.OCR = ocrDump; + break; + } + + end = DateTime.UtcNow; + + totalChkDuration = (end - chkStart).TotalMilliseconds; + dumpLog.WriteLine("Sidecar created in {0} seconds.", (end - chkStart).TotalSeconds); + dumpLog.WriteLine("Average checksum speed {0:F3} KiB/sec.", + (double)blockSize * (double)(blocks + 1) / 1024 / (totalChkDuration / 1000)); + + string xmlDskTyp = null, xmlDskSubTyp = null; + switch(dev.Type) + { + case DeviceType.MMC: + Metadata.MediaType.MediaTypeToString(MediaType.MMC, out xmlDskTyp, out xmlDskSubTyp); + sidecar.BlockMedia[0].Dimensions = Dimensions.DimensionsFromMediaType(MediaType.MMC); + break; + case DeviceType.SecureDigital: + Metadata.MediaType.MediaTypeToString(MediaType.SecureDigital, out xmlDskTyp, out xmlDskSubTyp); + sidecar.BlockMedia[0].Dimensions = Dimensions.DimensionsFromMediaType(MediaType.SecureDigital); + break; + } + + sidecar.BlockMedia[0].DiskType = xmlDskTyp; + sidecar.BlockMedia[0].DiskSubType = xmlDskSubTyp; + // TODO: Implement device firmware revision + sidecar.BlockMedia[0].LogicalBlocks = (long)blocks; + sidecar.BlockMedia[0].PhysicalBlockSize = physicalBlockSize > 0 ? physicalBlockSize : (int)blockSize; + sidecar.BlockMedia[0].LogicalBlockSize = (int)blockSize; + sidecar.BlockMedia[0].Manufacturer = dev.Manufacturer; + sidecar.BlockMedia[0].Model = dev.Model; + sidecar.BlockMedia[0].Serial = dev.Serial; + sidecar.BlockMedia[0].Size = (long)(blocks * blockSize); + + DicConsole.WriteLine("Writing metadata sidecar"); + + FileStream xmlFs = new FileStream(outputPrefix + ".cicm.xml", FileMode.Create); + + XmlSerializer xmlSer = new XmlSerializer(typeof(CICMMetadataType)); + xmlSer.Serialize(xmlFs, sidecar); + xmlFs.Close(); } - switch(dev.Type) - { - case DeviceType.MMC: - sidecar.BlockMedia[0].MultiMediaCard.CID = cidDump; - sidecar.BlockMedia[0].MultiMediaCard.CSD = csdDump; - sidecar.BlockMedia[0].MultiMediaCard.OCR = ocrDump; - break; - case DeviceType.SecureDigital: - sidecar.BlockMedia[0].SecureDigital.CID = cidDump; - sidecar.BlockMedia[0].SecureDigital.CSD = csdDump; - sidecar.BlockMedia[0].SecureDigital.OCR = ocrDump; - break; - } - - end = DateTime.UtcNow; - - totalChkDuration = (end - chkStart).TotalMilliseconds; - dumpLog.WriteLine("Sidecar created in {0} seconds.", (end - chkStart).TotalSeconds); - dumpLog.WriteLine("Average checksum speed {0:F3} KiB/sec.", - (double)blockSize * (double)(blocks + 1) / 1024 / (totalChkDuration / 1000)); - - string xmlDskTyp = null, xmlDskSubTyp = null; - switch(dev.Type) - { - case DeviceType.MMC: - Metadata.MediaType.MediaTypeToString(MediaType.MMC, out xmlDskTyp, out xmlDskSubTyp); - sidecar.BlockMedia[0].Dimensions = Dimensions.DimensionsFromMediaType(MediaType.MMC); - break; - case DeviceType.SecureDigital: - Metadata.MediaType.MediaTypeToString(MediaType.SecureDigital, out xmlDskTyp, out xmlDskSubTyp); - sidecar.BlockMedia[0].Dimensions = Dimensions.DimensionsFromMediaType(MediaType.SecureDigital); - break; - } - - sidecar.BlockMedia[0].DiskType = xmlDskTyp; - sidecar.BlockMedia[0].DiskSubType = xmlDskSubTyp; - // TODO: Implement device firmware revision - sidecar.BlockMedia[0].LogicalBlocks = (long)blocks; - sidecar.BlockMedia[0].PhysicalBlockSize = physicalBlockSize > 0 ? physicalBlockSize : (int)blockSize; - sidecar.BlockMedia[0].LogicalBlockSize = (int)blockSize; - sidecar.BlockMedia[0].Manufacturer = dev.Manufacturer; - sidecar.BlockMedia[0].Model = dev.Model; - sidecar.BlockMedia[0].Serial = dev.Serial; - sidecar.BlockMedia[0].Size = (long)(blocks * blockSize); - DicConsole.WriteLine(); DicConsole.WriteLine("Took a total of {0:F3} seconds ({1:F3} processing commands, {2:F3} checksumming, {3:F3} writing, {4:F3} closing).", @@ -612,17 +623,6 @@ namespace DiscImageChef.Core.Devices.Dumping if(resume.BadBlocks.Count > 0) resume.BadBlocks.Sort(); DicConsole.WriteLine(); - if(!aborted) - { - DicConsole.WriteLine("Writing metadata sidecar"); - - FileStream xmlFs = new FileStream(outputPrefix + ".cicm.xml", FileMode.Create); - - XmlSerializer xmlSer = new XmlSerializer(typeof(CICMMetadataType)); - xmlSer.Serialize(xmlFs, sidecar); - xmlFs.Close(); - } - switch(dev.Type) { case DeviceType.MMC: diff --git a/DiscImageChef.Core/Devices/Dumping/XGD.cs b/DiscImageChef.Core/Devices/Dumping/XGD.cs index 3b8a2507..e665dd66 100644 --- a/DiscImageChef.Core/Devices/Dumping/XGD.cs +++ b/DiscImageChef.Core/Devices/Dumping/XGD.cs @@ -88,7 +88,7 @@ namespace DiscImageChef.Core.Devices.Dumping ref DumpLog dumpLog, Encoding encoding, string outputPrefix, string outputPath, Dictionary formatOptions, - CICMMetadataType preSidecar, uint skip) + CICMMetadataType preSidecar, uint skip, bool nometadata) { bool sense; ulong blocks; @@ -97,7 +97,6 @@ namespace DiscImageChef.Core.Devices.Dumping DateTime start; DateTime end; double totalDuration = 0; - double totalChkDuration = 0; double currentSpeed = 0; double maxSpeed = double.MinValue; double minSpeed = double.MaxValue; @@ -809,60 +808,72 @@ namespace DiscImageChef.Core.Devices.Dumping return; } - dumpLog.WriteLine("Creating sidecar."); - FiltersList filters = new FiltersList(); - IFilter filter = filters.GetFilter(outputPath); - IMediaImage inputPlugin = ImageFormat.Detect(filter); - if(!inputPlugin.Open(filter)) throw new ArgumentException("Could not open created image."); - - DateTime chkStart = DateTime.UtcNow; - CICMMetadataType sidecar = Sidecar.Create(inputPlugin, outputPath, filter.Id, encoding); - end = DateTime.UtcNow; - - if(preSidecar != null) + double totalChkDuration = 0; + if(!nometadata) { - preSidecar.OpticalDisc = sidecar.OpticalDisc; - sidecar = preSidecar; - } + dumpLog.WriteLine("Creating sidecar."); + FiltersList filters = new FiltersList(); + IFilter filter = filters.GetFilter(outputPath); + IMediaImage inputPlugin = ImageFormat.Detect(filter); + if(!inputPlugin.Open(filter)) throw new ArgumentException("Could not open created image."); - totalChkDuration = (end - chkStart).TotalMilliseconds; - dumpLog.WriteLine("Sidecar created in {0} seconds.", (end - chkStart).TotalSeconds); - dumpLog.WriteLine("Average checksum speed {0:F3} KiB/sec.", - (double)BLOCK_SIZE * (double)(blocks + 1) / 1024 / (totalChkDuration / 1000)); + DateTime chkStart = DateTime.UtcNow; + CICMMetadataType sidecar = Sidecar.Create(inputPlugin, outputPath, filter.Id, encoding); + end = DateTime.UtcNow; - foreach(KeyValuePair tag in mediaTags) - Mmc.AddMediaTagToSidecar(outputPath, tag, ref sidecar); + if(preSidecar != null) + { + preSidecar.OpticalDisc = sidecar.OpticalDisc; + sidecar = preSidecar; + } - List<(ulong start, string type)> filesystems = new List<(ulong start, string type)>(); - if(sidecar.OpticalDisc[0].Track != null) - filesystems.AddRange(from xmlTrack in sidecar.OpticalDisc[0].Track - where xmlTrack.FileSystemInformation != null - from partition in xmlTrack.FileSystemInformation - where partition.FileSystems != null - from fileSystem in partition.FileSystems - select ((ulong)partition.StartSector, fileSystem.Type)); + totalChkDuration = (end - chkStart).TotalMilliseconds; + dumpLog.WriteLine("Sidecar created in {0} seconds.", (end - chkStart).TotalSeconds); + dumpLog.WriteLine("Average checksum speed {0:F3} KiB/sec.", + (double)BLOCK_SIZE * (double)(blocks + 1) / 1024 / (totalChkDuration / 1000)); - if(filesystems.Count > 0) - foreach(var filesystem in filesystems.Select(o => new {o.start, o.type}).Distinct()) - dumpLog.WriteLine("Found filesystem {0} at sector {1}", filesystem.type, filesystem.start); - - sidecar.OpticalDisc[0].Layers = new LayersType - { - type = LayersTypeType.OTP, - typeSpecified = true, - Sectors = new SectorsType[1] - }; - sidecar.OpticalDisc[0].Layers.Sectors[0] = new SectorsType {Value = (long)layerBreak}; - sidecar.OpticalDisc[0].Sessions = 1; - sidecar.OpticalDisc[0].Dimensions = Dimensions.DimensionsFromMediaType(dskType); - Metadata.MediaType.MediaTypeToString(dskType, out string xmlDskTyp, out string xmlDskSubTyp); - sidecar.OpticalDisc[0].DiscType = xmlDskTyp; - sidecar.OpticalDisc[0].DiscSubType = xmlDskSubTyp; - - foreach(KeyValuePair tag in mediaTags) - if(outputPlugin.SupportedMediaTags.Contains(tag.Key)) + foreach(KeyValuePair tag in mediaTags) Mmc.AddMediaTagToSidecar(outputPath, tag, ref sidecar); + List<(ulong start, string type)> filesystems = new List<(ulong start, string type)>(); + if(sidecar.OpticalDisc[0].Track != null) + filesystems.AddRange(from xmlTrack in sidecar.OpticalDisc[0].Track + where xmlTrack.FileSystemInformation != null + from partition in xmlTrack.FileSystemInformation + where partition.FileSystems != null + from fileSystem in partition.FileSystems + select ((ulong)partition.StartSector, fileSystem.Type)); + + if(filesystems.Count > 0) + foreach(var filesystem in filesystems.Select(o => new {o.start, o.type}).Distinct()) + dumpLog.WriteLine("Found filesystem {0} at sector {1}", filesystem.type, filesystem.start); + + sidecar.OpticalDisc[0].Layers = new LayersType + { + type = LayersTypeType.OTP, + typeSpecified = true, + Sectors = new SectorsType[1] + }; + sidecar.OpticalDisc[0].Layers.Sectors[0] = new SectorsType {Value = (long)layerBreak}; + sidecar.OpticalDisc[0].Sessions = 1; + sidecar.OpticalDisc[0].Dimensions = Dimensions.DimensionsFromMediaType(dskType); + Metadata.MediaType.MediaTypeToString(dskType, out string xmlDskTyp, out string xmlDskSubTyp); + sidecar.OpticalDisc[0].DiscType = xmlDskTyp; + sidecar.OpticalDisc[0].DiscSubType = xmlDskSubTyp; + + foreach(KeyValuePair tag in mediaTags) + if(outputPlugin.SupportedMediaTags.Contains(tag.Key)) + Mmc.AddMediaTagToSidecar(outputPath, tag, ref sidecar); + + DicConsole.WriteLine("Writing metadata sidecar"); + + FileStream xmlFs = new FileStream(outputPrefix + ".cicm.xml", FileMode.Create); + + XmlSerializer xmlSer = new XmlSerializer(typeof(CICMMetadataType)); + xmlSer.Serialize(xmlFs, sidecar); + xmlFs.Close(); + } + DicConsole.WriteLine(); DicConsole.WriteLine("Took a total of {0:F3} seconds ({1:F3} processing commands, {2:F3} checksumming, {3:F3} writing, {4:F3} closing).", (end - start).TotalSeconds, totalDuration / 1000, @@ -875,17 +886,6 @@ namespace DiscImageChef.Core.Devices.Dumping DicConsole.WriteLine("{0} sectors could not be read.", resume.BadBlocks.Count); DicConsole.WriteLine(); - if(!aborted) - { - DicConsole.WriteLine("Writing metadata sidecar"); - - FileStream xmlFs = new FileStream(outputPrefix + ".cicm.xml", FileMode.Create); - - XmlSerializer xmlSer = new XmlSerializer(typeof(CICMMetadataType)); - xmlSer.Serialize(xmlFs, sidecar); - xmlFs.Close(); - } - Statistics.AddMedia(dskType, true); } } diff --git a/DiscImageChef/Commands/DumpMedia.cs b/DiscImageChef/Commands/DumpMedia.cs index 70e8175b..6dcc3b6c 100644 --- a/DiscImageChef/Commands/DumpMedia.cs +++ b/DiscImageChef/Commands/DumpMedia.cs @@ -77,6 +77,7 @@ namespace DiscImageChef.Commands DicConsole.DebugWriteLine("Dump-Media command", "--options={0}", options.Options); DicConsole.DebugWriteLine("Dump-Media command", "--cicm-xml={0}", options.CicmXml); DicConsole.DebugWriteLine("Dump-Media command", "--skip={0}", options.Skip); + DicConsole.DebugWriteLine("Dump-Media command", "--no-metadata={0}", options.NoMetadata); Dictionary parsedOptions = Options.Parse(options.Options); DicConsole.DebugWriteLine("Dump-Media command", "Parsed options:"); @@ -206,24 +207,26 @@ namespace DiscImageChef.Commands case DeviceType.ATA: Ata.Dump(dev, options.DevicePath, outputFormat, options.RetryPasses, options.Force, options.Raw, options.Persistent, options.StopOnError, ref resume, ref dumpLog, encoding, outputPrefix, - options.OutputFile, parsedOptions, sidecar, options.Skip); + options.OutputFile, parsedOptions, sidecar, (uint)options.Skip, options.NoMetadata); break; case DeviceType.MMC: case DeviceType.SecureDigital: SecureDigital.Dump(dev, options.DevicePath, outputFormat, options.RetryPasses, options.Force, options.Raw, options.Persistent, options.StopOnError, ref resume, ref dumpLog, - encoding, outputPrefix, options.OutputFile, parsedOptions, sidecar, options.Skip); + encoding, outputPrefix, options.OutputFile, parsedOptions, sidecar, (uint)options.Skip, + options.NoMetadata); break; case DeviceType.NVMe: NvMe.Dump(dev, options.DevicePath, outputFormat, options.RetryPasses, options.Force, options.Raw, options.Persistent, options.StopOnError, ref resume, ref dumpLog, encoding, outputPrefix, - options.OutputFile, parsedOptions, sidecar, options.Skip); + options.OutputFile, parsedOptions, sidecar, (uint)options.Skip, options.NoMetadata); break; case DeviceType.ATAPI: case DeviceType.SCSI: Scsi.Dump(dev, options.DevicePath, outputFormat, options.RetryPasses, options.Force, options.Raw, options.Persistent, options.StopOnError, ref resume, ref dumpLog, options.LeadIn, - encoding, outputPrefix, options.OutputFile, parsedOptions, sidecar, options.Skip); + encoding, outputPrefix, options.OutputFile, parsedOptions, sidecar, (uint)options.Skip, + options.NoMetadata); break; default: dumpLog.WriteLine("Unknown device type."); diff --git a/DiscImageChef/Options.cs b/DiscImageChef/Options.cs index 2aeb8ce2..980b3944 100644 --- a/DiscImageChef/Options.cs +++ b/DiscImageChef/Options.cs @@ -310,7 +310,10 @@ namespace DiscImageChef public string CicmXml { get; set; } [Option('k', "skip", Default = 512, HelpText = "When an unreadable sector is found skip this many sectors.")] - public uint Skip { get; set; } + public int Skip { get; set; } + + [Option("no-metadata", Default = false, HelpText = "Disables creating CICM XML sidecar.")] + public bool NoMetadata { get; set; } } [Verb("device-report", HelpText = "Tests the device capabilities and creates an XML report of them.")]