From 8bcf346653d24318890d2e19a19905c5368783c7 Mon Sep 17 00:00:00 2001 From: Natalia Portillo Date: Sat, 20 Apr 2019 19:21:00 +0100 Subject: [PATCH] Make Sidecar class abortable. --- DiscImageChef.Core/Devices/Dumping/ATA.cs | 3 +- .../Devices/Dumping/CompactDisc.cs | 3 +- DiscImageChef.Core/Devices/Dumping/Dump.cs | 2 + .../Devices/Dumping/PlayStationPortable.cs | 5 +-- DiscImageChef.Core/Devices/Dumping/SBC.cs | 3 +- .../Devices/Dumping/SecureDigital.cs | 3 +- DiscImageChef.Core/Devices/Dumping/XGD.cs | 3 +- DiscImageChef.Core/Sidecar/BlockMedia.cs | 32 +++++++++++++++ DiscImageChef.Core/Sidecar/BlockTape.cs | 10 +++++ DiscImageChef.Core/Sidecar/OpticalDisc.cs | 40 +++++++++++++++++++ DiscImageChef.Core/Sidecar/Sidecar.cs | 14 ++++++- .../Forms/frmImageSidecar.xeto.cs | 6 ++- DiscImageChef/Commands/CreateSidecar.cs | 5 +++ 13 files changed, 113 insertions(+), 16 deletions(-) diff --git a/DiscImageChef.Core/Devices/Dumping/ATA.cs b/DiscImageChef.Core/Devices/Dumping/ATA.cs index d497544f9..4695906a0 100644 --- a/DiscImageChef.Core/Devices/Dumping/ATA.cs +++ b/DiscImageChef.Core/Devices/Dumping/ATA.cs @@ -524,9 +524,8 @@ namespace DiscImageChef.Core.Devices.Dumping } DateTime chkStart = DateTime.UtcNow; - Sidecar sidecarClass = new Sidecar(inputPlugin, outputPath, filter.Id, encoding) + sidecarClass = new Sidecar(inputPlugin, outputPath, filter.Id, encoding) { - // TODO: Be able to cancel hashing InitProgressEvent += InitProgress, UpdateProgressEvent += UpdateProgress, EndProgressEvent += EndProgress, diff --git a/DiscImageChef.Core/Devices/Dumping/CompactDisc.cs b/DiscImageChef.Core/Devices/Dumping/CompactDisc.cs index 91140143a..8a390e25b 100644 --- a/DiscImageChef.Core/Devices/Dumping/CompactDisc.cs +++ b/DiscImageChef.Core/Devices/Dumping/CompactDisc.cs @@ -1844,9 +1844,8 @@ namespace DiscImageChef.Core.Devices.Dumping } DateTime chkStart = DateTime.UtcNow; - Sidecar sidecarClass = new Sidecar(inputPlugin, outputPath, filter.Id, encoding) + sidecarClass = new Sidecar(inputPlugin, outputPath, filter.Id, encoding) { - // TODO: Be able to cancel hashing InitProgressEvent += InitProgress, UpdateProgressEvent += UpdateProgress, EndProgressEvent += EndProgress, diff --git a/DiscImageChef.Core/Devices/Dumping/Dump.cs b/DiscImageChef.Core/Devices/Dumping/Dump.cs index 08d820256..97c7d961c 100644 --- a/DiscImageChef.Core/Devices/Dumping/Dump.cs +++ b/DiscImageChef.Core/Devices/Dumping/Dump.cs @@ -34,6 +34,7 @@ namespace DiscImageChef.Core.Devices.Dumping bool aborted; bool dumpFirstTrackPregap; Resume resume; + Sidecar sidecarClass; uint skip; /// @@ -141,6 +142,7 @@ namespace DiscImageChef.Core.Devices.Dumping public void Abort() { aborted = true; + sidecarClass?.Abort(); } /// diff --git a/DiscImageChef.Core/Devices/Dumping/PlayStationPortable.cs b/DiscImageChef.Core/Devices/Dumping/PlayStationPortable.cs index 9841aa9e1..f4667f9e2 100644 --- a/DiscImageChef.Core/Devices/Dumping/PlayStationPortable.cs +++ b/DiscImageChef.Core/Devices/Dumping/PlayStationPortable.cs @@ -594,7 +594,7 @@ namespace DiscImageChef.Core.Devices.Dumping } DateTime chkStart = DateTime.UtcNow; - Sidecar sidecarClass = new Sidecar(inputPlugin, outputPath, filter.Id, encoding) + sidecarClass = new Sidecar(inputPlugin, outputPath, filter.Id, encoding) { // TODO: Be able to cancel hashing InitProgressEvent += InitProgress, @@ -1073,9 +1073,8 @@ namespace DiscImageChef.Core.Devices.Dumping } DateTime chkStart = DateTime.UtcNow; - Sidecar sidecarClass = new Sidecar(inputPlugin, outputPath, filter.Id, encoding) + sidecarClass = new Sidecar(inputPlugin, outputPath, filter.Id, encoding) { - // TODO: Be able to cancel hashing InitProgressEvent += InitProgress, UpdateProgressEvent += UpdateProgress, EndProgressEvent += EndProgress, diff --git a/DiscImageChef.Core/Devices/Dumping/SBC.cs b/DiscImageChef.Core/Devices/Dumping/SBC.cs index 29073b114..9e8b64cf1 100644 --- a/DiscImageChef.Core/Devices/Dumping/SBC.cs +++ b/DiscImageChef.Core/Devices/Dumping/SBC.cs @@ -829,9 +829,8 @@ namespace DiscImageChef.Core.Devices.Dumping } DateTime chkStart = DateTime.UtcNow; - Sidecar sidecarClass = new Sidecar(inputPlugin, outputPath, filter.Id, encoding) + sidecarClass = new Sidecar(inputPlugin, outputPath, filter.Id, encoding) { - // TODO: Be able to cancel hashing InitProgressEvent += InitProgress, UpdateProgressEvent += UpdateProgress, EndProgressEvent += EndProgress, diff --git a/DiscImageChef.Core/Devices/Dumping/SecureDigital.cs b/DiscImageChef.Core/Devices/Dumping/SecureDigital.cs index 7e7b89c10..931b3e26b 100644 --- a/DiscImageChef.Core/Devices/Dumping/SecureDigital.cs +++ b/DiscImageChef.Core/Devices/Dumping/SecureDigital.cs @@ -479,9 +479,8 @@ namespace DiscImageChef.Core.Devices.Dumping if(!inputPlugin.Open(filter)) StoppingErrorMessage?.Invoke("Could not open created image."); DateTime chkStart = DateTime.UtcNow; - Sidecar sidecarClass = new Sidecar(inputPlugin, outputPath, filter.Id, encoding) + sidecarClass = new Sidecar(inputPlugin, outputPath, filter.Id, encoding) { - // TODO: Be able to cancel hashing InitProgressEvent += InitProgress, UpdateProgressEvent += UpdateProgress, EndProgressEvent += EndProgress, diff --git a/DiscImageChef.Core/Devices/Dumping/XGD.cs b/DiscImageChef.Core/Devices/Dumping/XGD.cs index a77860413..053f3d510 100644 --- a/DiscImageChef.Core/Devices/Dumping/XGD.cs +++ b/DiscImageChef.Core/Devices/Dumping/XGD.cs @@ -929,9 +929,8 @@ namespace DiscImageChef.Core.Devices.Dumping } DateTime chkStart = DateTime.UtcNow; - Sidecar sidecarClass = new Sidecar(inputPlugin, outputPath, filter.Id, encoding) + sidecarClass = new Sidecar(inputPlugin, outputPath, filter.Id, encoding) { - // TODO: Be able to cancel hashing InitProgressEvent += InitProgress, UpdateProgressEvent += UpdateProgress, EndProgressEvent += EndProgress, diff --git a/DiscImageChef.Core/Sidecar/BlockMedia.cs b/DiscImageChef.Core/Sidecar/BlockMedia.cs index c4ac2b05b..183f0b0dc 100644 --- a/DiscImageChef.Core/Sidecar/BlockMedia.cs +++ b/DiscImageChef.Core/Sidecar/BlockMedia.cs @@ -66,6 +66,8 @@ namespace DiscImageChef.Core PluginBase plugins, List imgChecksums, ref CICMMetadataType sidecar, Encoding encoding) { + if(aborted) return; + sidecar.BlockMedia = new[] { new BlockMediaType @@ -95,6 +97,9 @@ namespace DiscImageChef.Core } foreach(MediaTagType tagType in image.Info.ReadableMediaTags) + { + if(aborted) return; + switch(tagType) { case MediaTagType.ATAPI_IDENTIFY: @@ -276,6 +281,7 @@ namespace DiscImageChef.Core }; break; } + } // 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") && @@ -295,6 +301,12 @@ namespace DiscImageChef.Core InitProgress2(); while(doneSectors < sectors) { + if(aborted) + { + EndProgress2(); + return; + } + byte[] sector; if(sectors - doneSectors >= sectorsToRead) @@ -337,6 +349,8 @@ namespace DiscImageChef.Core UpdateStatus("Checking filesystems..."); + if(aborted) return; + List partitions = Partitions.GetAll(image); Partitions.AddSchemesToStats(partitions); @@ -346,6 +360,8 @@ namespace DiscImageChef.Core sidecar.BlockMedia[0].FileSystemInformation = new PartitionType[partitions.Count]; for(int i = 0; i < partitions.Count; i++) { + if(aborted) return; + sidecar.BlockMedia[0].FileSystemInformation[i] = new PartitionType { Description = partitions[i].Description, @@ -360,6 +376,8 @@ namespace DiscImageChef.Core foreach(IFilesystem plugin in plugins.PluginsList.Values) try { + if(aborted) return; + if(!plugin.Identify(image, partitions[i])) continue; plugin.GetInformation(image, partitions[i], out _, encoding); @@ -378,6 +396,8 @@ namespace DiscImageChef.Core } else { + if(aborted) return; + sidecar.BlockMedia[0].FileSystemInformation[0] = new PartitionType {StartSector = 0, EndSector = (int)(image.Info.Sectors - 1)}; @@ -393,6 +413,8 @@ namespace DiscImageChef.Core foreach(IFilesystem plugin in plugins.PluginsList.Values) try { + if(aborted) return; + if(!plugin.Identify(image, wholePart)) continue; plugin.GetInformation(image, wholePart, out _, encoding); @@ -565,6 +587,8 @@ namespace DiscImageChef.Core string scpFilePath = Path.Combine(Path.GetDirectoryName(imagePath), Path.GetFileNameWithoutExtension(imagePath) + ".scp"); + if(aborted) return; + if(File.Exists(scpFilePath)) { SuperCardPro scpImage = new SuperCardPro(); @@ -586,6 +610,8 @@ namespace DiscImageChef.Core for(byte t = scpImage.Header.start; t <= scpImage.Header.end; t++) { + if(aborted) return; + BlockTrackType scpBlockTrackType = new BlockTrackType { Cylinder = t / image.Info.Heads, @@ -642,6 +668,7 @@ namespace DiscImageChef.Core string basename = Path.Combine(Path.GetDirectoryName(imagePath), Path.GetFileNameWithoutExtension(imagePath)); bool kfDir = false; + if(aborted) return; if(Directory.Exists(basename)) { @@ -674,6 +701,8 @@ namespace DiscImageChef.Core foreach(KeyValuePair kvp in kfImage.tracks) { + if(aborted) return; + BlockTrackType kfBlockTrackType = new BlockTrackType { Cylinder = kvp.Key / image.Info.Heads, @@ -729,6 +758,7 @@ namespace DiscImageChef.Core string dfiFilePath = Path.Combine(Path.GetDirectoryName(imagePath), Path.GetFileNameWithoutExtension(imagePath) + ".dfi"); + if(aborted) return; if(!File.Exists(dfiFilePath)) return; DiscFerret dfiImage = new DiscFerret(); @@ -749,6 +779,8 @@ namespace DiscImageChef.Core foreach(int t in dfiImage.TrackOffsets.Keys) { + if(aborted) return; + BlockTrackType dfiBlockTrackType = new BlockTrackType { Cylinder = t / image.Info.Heads, diff --git a/DiscImageChef.Core/Sidecar/BlockTape.cs b/DiscImageChef.Core/Sidecar/BlockTape.cs index 6b7ddfeb9..3daa6c592 100644 --- a/DiscImageChef.Core/Sidecar/BlockTape.cs +++ b/DiscImageChef.Core/Sidecar/BlockTape.cs @@ -77,6 +77,8 @@ namespace DiscImageChef.Core } }; + if(aborted) return sidecar; + long currentBlock = 0; long totalSize = 0; Checksum tapeWorker = new Checksum(); @@ -84,6 +86,8 @@ namespace DiscImageChef.Core for(int i = 0; i < files.Count; i++) { + if(aborted) return sidecar; + fs = new FileStream(files[i], FileMode.Open, FileAccess.Read); Checksum fileWorker = new Checksum(); TapeFileType tapeFile = new TapeFileType @@ -107,6 +111,12 @@ namespace DiscImageChef.Core InitProgress2(); while(doneSectors < sectors) { + if(aborted) + { + EndProgress2(); + return sidecar; + } + byte[] sector; if(sectors - doneSectors >= SECTORS_TO_READ) diff --git a/DiscImageChef.Core/Sidecar/OpticalDisc.cs b/DiscImageChef.Core/Sidecar/OpticalDisc.cs index d7ebd2a3f..ee5288236 100644 --- a/DiscImageChef.Core/Sidecar/OpticalDisc.cs +++ b/DiscImageChef.Core/Sidecar/OpticalDisc.cs @@ -66,6 +66,8 @@ namespace DiscImageChef.Core FileInfo fi, PluginBase plugins, List imgChecksums, ref CICMMetadataType sidecar, Encoding encoding) { + if(aborted) return; + sidecar.OpticalDisc = new[] { new OpticalDiscType @@ -97,6 +99,9 @@ namespace DiscImageChef.Core MediaType dskType = image.Info.MediaType; foreach(MediaTagType tagType in image.Info.ReadableMediaTags) + { + if(aborted) return; + switch(tagType) { case MediaTagType.CD_ATIP: @@ -332,6 +337,7 @@ namespace DiscImageChef.Core }; break; } + } try { @@ -352,6 +358,8 @@ namespace DiscImageChef.Core if(sidecar.OpticalDisc[0].Dimensions == null && image.Info.MediaType != MediaType.Unknown) sidecar.OpticalDisc[0].Dimensions = Dimensions.DimensionsFromMediaType(image.Info.MediaType); + if(aborted) return; + InitProgress(); UpdateStatus("Checking filesystems"); @@ -360,6 +368,12 @@ namespace DiscImageChef.Core foreach(Track trk in tracks) { + if(aborted) + { + EndProgress(); + return; + } + TrackType xmlTrk = new TrackType(); switch(trk.TrackType) { @@ -457,6 +471,13 @@ namespace DiscImageChef.Core InitProgress2(); while(doneSectors < sectors) { + if(aborted) + { + EndProgress(); + EndProgress2(); + return; + } + byte[] sector; if(sectors - doneSectors >= sectorsToRead) @@ -525,6 +546,13 @@ namespace DiscImageChef.Core InitProgress2(); while(doneSectors < sectors) { + if(aborted) + { + EndProgress(); + EndProgress2(); + return; + } + byte[] sector; if(sectors - doneSectors >= sectorsToRead) @@ -582,6 +610,12 @@ namespace DiscImageChef.Core foreach(IFilesystem plugin in plugins.PluginsList.Values) try { + if(aborted) + { + EndProgress(); + return; + } + if(!plugin.Identify(image, trkPartitions[i])) continue; plugin.GetInformation(image, trkPartitions[i], out _, encoding); @@ -633,6 +667,12 @@ namespace DiscImageChef.Core foreach(IFilesystem plugin in plugins.PluginsList.Values) try { + if(aborted) + { + EndProgress(); + return; + } + if(!plugin.Identify(image, xmlPart)) continue; plugin.GetInformation(image, xmlPart, out _, encoding); diff --git a/DiscImageChef.Core/Sidecar/Sidecar.cs b/DiscImageChef.Core/Sidecar/Sidecar.cs index d7d753ae8..cbd9699a6 100644 --- a/DiscImageChef.Core/Sidecar/Sidecar.cs +++ b/DiscImageChef.Core/Sidecar/Sidecar.cs @@ -47,17 +47,19 @@ namespace DiscImageChef.Core readonly Encoding encoding; readonly FileInfo fi; readonly Guid filterId; - FileStream fs; readonly IMediaImage image; readonly string imagePath; readonly Checksum imgChkWorker; readonly PluginBase plugins; + bool aborted; + FileStream fs; CICMMetadataType sidecar; public Sidecar() { plugins = GetPluginBase.Instance; imgChkWorker = new Checksum(); + aborted = false; } /// Image @@ -78,6 +80,7 @@ namespace DiscImageChef.Core fs = new FileStream(imagePath, FileMode.Open, FileAccess.Read); imgChkWorker = new Checksum(); + aborted = false; } /// @@ -94,6 +97,8 @@ namespace DiscImageChef.Core InitProgress(); while(position < fi.Length - 1048576) { + if(aborted) return sidecar; + data = new byte[1048576]; fs.Read(data, 0, 1048576); @@ -124,6 +129,8 @@ namespace DiscImageChef.Core sidecar.AudioMedia = null; sidecar.LinearMedia = null; + if(aborted) return sidecar; + switch(image.Info.XmlMediaType) { case XmlMediaType.OpticalDisc: @@ -151,5 +158,10 @@ namespace DiscImageChef.Core return sidecar; } + + public void Abort() + { + aborted = true; + } } } \ No newline at end of file diff --git a/DiscImageChef.Gui/Forms/frmImageSidecar.xeto.cs b/DiscImageChef.Gui/Forms/frmImageSidecar.xeto.cs index 2ecbd136d..e182c8207 100644 --- a/DiscImageChef.Gui/Forms/frmImageSidecar.xeto.cs +++ b/DiscImageChef.Gui/Forms/frmImageSidecar.xeto.cs @@ -68,6 +68,8 @@ namespace DiscImageChef.Gui.Forms new Thread(DoWork).Start(); } + Sidecar sidecarClass; + void DoWork() { // Prepare UI @@ -81,7 +83,7 @@ namespace DiscImageChef.Gui.Forms btnDestination.Visible = false; }); - Sidecar sidecarClass = new Sidecar(inputFormat, imageSource, filterId, encoding); + sidecarClass = new Sidecar(inputFormat, imageSource, filterId, encoding); CICMMetadataType sidecar = sidecarClass.Create(); DicConsole.WriteLine("Writing metadata sidecar"); @@ -109,7 +111,7 @@ namespace DiscImageChef.Gui.Forms protected void OnBtnStop(object sender, EventArgs e) { - throw new NotImplementedException(); + sidecarClass.Abort(); } void OnBtnDestinationClick(object sender, EventArgs e) diff --git a/DiscImageChef/Commands/CreateSidecar.cs b/DiscImageChef/Commands/CreateSidecar.cs index 5eaaa13c5..76d5dc7ee 100644 --- a/DiscImageChef/Commands/CreateSidecar.cs +++ b/DiscImageChef/Commands/CreateSidecar.cs @@ -190,6 +190,11 @@ namespace DiscImageChef.Commands sidecarClass.UpdateProgressEvent2 += Progress.UpdateProgress2; sidecarClass.EndProgressEvent2 += Progress.EndProgress2; sidecarClass.UpdateStatusEvent += Progress.UpdateStatus; + System.Console.CancelKeyPress += (sender, e) => + { + e.Cancel = true; + sidecarClass.Abort(); + }; CICMMetadataType sidecar = sidecarClass.Create(); DicConsole.WriteLine("Writing metadata sidecar");