From d05fd468829707db7acfb26e87846526fef9918f Mon Sep 17 00:00:00 2001 From: Natalia Portillo Date: Tue, 10 Apr 2018 03:37:52 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9BReturn=20drive=20to=20previous=20er?= =?UTF-8?q?ror=20correction=20status,=20fixes=20#171.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Devices/Dumping/CompactDisc.cs | 55 +++++- DiscImageChef.Core/Devices/Dumping/SBC.cs | 82 ++++++++- DiscImageChef.Core/Devices/Dumping/XGD.cs | 157 ++++++++++-------- 3 files changed, 215 insertions(+), 79 deletions(-) diff --git a/DiscImageChef.Core/Devices/Dumping/CompactDisc.cs b/DiscImageChef.Core/Devices/Dumping/CompactDisc.cs index 9e2198b5..e1e619ad 100644 --- a/DiscImageChef.Core/Devices/Dumping/CompactDisc.cs +++ b/DiscImageChef.Core/Devices/Dumping/CompactDisc.cs @@ -963,7 +963,54 @@ namespace DiscImageChef.Core.Devices.Dumping if(persistent) { - Modes.ModePage_01_MMC pgMmc = + Modes.ModePage_01_MMC pgMmc; + + sense = dev.ModeSense6(out readBuffer, out _, false, ScsiModeSensePageControl.Current, 0x01, + dev.Timeout, out _); + if(sense) + { + sense = dev.ModeSense10(out readBuffer, out _, false, ScsiModeSensePageControl.Current, + 0x01, dev.Timeout, out _); + + if(!sense) + { + Modes.DecodedMode? dcMode10 = + Modes.DecodeMode10(readBuffer, PeripheralDeviceTypes.MultiMediaDevice); + + if(dcMode10.HasValue) + { + foreach(Modes.ModePage modePage in dcMode10.Value.Pages) + if(modePage.Page == 0x01 && modePage.Subpage == 0x00) currentModePage = modePage; + } + } + } + else + { + Modes.DecodedMode? dcMode6 = + Modes.DecodeMode6(readBuffer, PeripheralDeviceTypes.MultiMediaDevice); + + if(dcMode6.HasValue) + { + foreach(Modes.ModePage modePage in dcMode6.Value.Pages) + if(modePage.Page == 0x01 && modePage.Subpage == 0x00) + currentModePage = modePage; + } + } + + if(currentModePage == null) + { + + pgMmc = + new Modes.ModePage_01_MMC {PS = false, ReadRetryCount = 32, Parameter = 0x00}; + currentModePage = new Modes.ModePage + { + Page = 0x01, + Subpage = 0x00, + PageResponse = Modes.EncodeModePage_01_MMC(pgMmc) + }; + } + + pgMmc = new Modes.ModePage_01_MMC {PS = false, ReadRetryCount = 255, Parameter = 0x20}; Modes.DecodedMode md = new Modes.DecodedMode { @@ -981,7 +1028,7 @@ namespace DiscImageChef.Core.Devices.Dumping md6 = Modes.EncodeMode6(md, dev.ScsiType); md10 = Modes.EncodeMode10(md, dev.ScsiType); - dumpLog.WriteLine("Sending MODE SELECT to drive."); + dumpLog.WriteLine("Sending MODE SELECT to drive (return damaged blocks)."); sense = dev.ModeSelect(md6, out senseBuf, true, false, dev.Timeout, out _); if(sense) sense = dev.ModeSelect10(md10, out senseBuf, true, false, dev.Timeout, out _); @@ -1083,7 +1130,7 @@ namespace DiscImageChef.Core.Devices.Dumping md6 = Modes.EncodeMode6(md, dev.ScsiType); md10 = Modes.EncodeMode10(md, dev.ScsiType); - dumpLog.WriteLine("Sending MODE SELECT to drive."); + dumpLog.WriteLine("Sending MODE SELECT to drive (ignore error correction)."); sense = dev.ModeSelect(md6, out senseBuf, true, false, dev.Timeout, out _); if(sense) sense = dev.ModeSelect10(md10, out senseBuf, true, false, dev.Timeout, out _); @@ -1142,7 +1189,7 @@ namespace DiscImageChef.Core.Devices.Dumping md6 = Modes.EncodeMode6(md, dev.ScsiType); md10 = Modes.EncodeMode10(md, dev.ScsiType); - dumpLog.WriteLine("Sending MODE SELECT to drive."); + dumpLog.WriteLine("Sending MODE SELECT to drive (return device to previous status)."); sense = dev.ModeSelect(md6, out senseBuf, true, false, dev.Timeout, out _); if(sense) dev.ModeSelect10(md10, out senseBuf, true, false, dev.Timeout, out _); } diff --git a/DiscImageChef.Core/Devices/Dumping/SBC.cs b/DiscImageChef.Core/Devices/Dumping/SBC.cs index af9709ef..7d5f0971 100644 --- a/DiscImageChef.Core/Devices/Dumping/SBC.cs +++ b/DiscImageChef.Core/Devices/Dumping/SBC.cs @@ -465,9 +465,83 @@ namespace DiscImageChef.Core.Devices.Dumping if(persistent) { + Modes.ModePage_01_MMC pgMmc; + Modes.ModePage_01 pg; + + sense = dev.ModeSense6(out readBuffer, out _, false, ScsiModeSensePageControl.Current, 0x01, + dev.Timeout, out _); + if(sense) + { + sense = dev.ModeSense10(out readBuffer, out _, false, ScsiModeSensePageControl.Current, + 0x01, dev.Timeout, out _); + + if(!sense) + { + Modes.DecodedMode? dcMode10 = + Modes.DecodeMode10(readBuffer, dev.ScsiType); + + if(dcMode10.HasValue) + { + foreach(Modes.ModePage modePage in dcMode10.Value.Pages) + if(modePage.Page == 0x01 && modePage.Subpage == 0x00) currentModePage = modePage; + } + } + } + else + { + Modes.DecodedMode? dcMode6 = + Modes.DecodeMode6(readBuffer, dev.ScsiType); + + if(dcMode6.HasValue) + { + foreach(Modes.ModePage modePage in dcMode6.Value.Pages) + if(modePage.Page == 0x01 && modePage.Subpage == 0x00) + currentModePage = modePage; + } + } + + if(currentModePage == null) + { + if(dev.ScsiType == PeripheralDeviceTypes.MultiMediaDevice) + { + + pgMmc = new Modes.ModePage_01_MMC {PS = false, ReadRetryCount = 32, Parameter = 0x00}; + currentModePage = new Modes.ModePage + { + Page = 0x01, + Subpage = 0x00, + PageResponse = Modes.EncodeModePage_01_MMC(pgMmc) + }; + } + else + { + pg = new Modes.ModePage_01 + { + PS = false, + AWRE = true, + ARRE = true, + TB = false, + RC = false, + EER = true, + PER = false, + DTE = true, + DCR = false, + ReadRetryCount = 32 + }; + + currentModePage = + new Modes.ModePage + { + Page = 0x01, + Subpage = 0x00, + PageResponse = Modes.EncodeModePage_01(pg) + } ; + } + } + if(dev.ScsiType == PeripheralDeviceTypes.MultiMediaDevice) { - Modes.ModePage_01_MMC pgMmc = + pgMmc = new Modes.ModePage_01_MMC {PS = false, ReadRetryCount = 255, Parameter = 0x20}; Modes.DecodedMode md = new Modes.DecodedMode { @@ -487,7 +561,7 @@ namespace DiscImageChef.Core.Devices.Dumping } else { - Modes.ModePage_01 pg = new Modes.ModePage_01 + pg = new Modes.ModePage_01 { PS = false, AWRE = false, @@ -517,7 +591,7 @@ namespace DiscImageChef.Core.Devices.Dumping md10 = Modes.EncodeMode10(md, dev.ScsiType); } - dumpLog.WriteLine("Sending MODE SELECT to drive."); + dumpLog.WriteLine("Sending MODE SELECT to drive (return damaged blocks)."); sense = dev.ModeSelect(md6, out byte[] senseBuf, true, false, dev.Timeout, out _); if(sense) sense = dev.ModeSelect10(md10, out senseBuf, true, false, dev.Timeout, out _); @@ -578,7 +652,7 @@ namespace DiscImageChef.Core.Devices.Dumping md6 = Modes.EncodeMode6(md, dev.ScsiType); md10 = Modes.EncodeMode10(md, dev.ScsiType); - dumpLog.WriteLine("Sending MODE SELECT to drive."); + dumpLog.WriteLine("Sending MODE SELECT to drive (return device to previous status)."); sense = dev.ModeSelect(md6, out _, true, false, dev.Timeout, out _); if(sense) dev.ModeSelect10(md10, out _, true, false, dev.Timeout, out _); } diff --git a/DiscImageChef.Core/Devices/Dumping/XGD.cs b/DiscImageChef.Core/Devices/Dumping/XGD.cs index 65009a8e..27531f9a 100644 --- a/DiscImageChef.Core/Devices/Dumping/XGD.cs +++ b/DiscImageChef.Core/Devices/Dumping/XGD.cs @@ -702,7 +702,91 @@ namespace DiscImageChef.Core.Devices.Dumping bool runningPersistent = false; resume.BadBlocks = tmpList; + Modes.ModePage? currentModePage = null; + byte[] md6; + byte[] md10; + if(persistent) + { + Modes.ModePage_01_MMC pgMmc; + + sense = dev.ModeSense6(out readBuffer, out _, false, ScsiModeSensePageControl.Current, 0x01, + dev.Timeout, out _); + if(sense) + { + sense = dev.ModeSense10(out readBuffer, out _, false, ScsiModeSensePageControl.Current, + 0x01, dev.Timeout, out _); + + if(!sense) + { + Modes.DecodedMode? dcMode10 = + Modes.DecodeMode10(readBuffer, PeripheralDeviceTypes.MultiMediaDevice); + + if(dcMode10.HasValue) + { + foreach(Modes.ModePage modePage in dcMode10.Value.Pages) + if(modePage.Page == 0x01 && modePage.Subpage == 0x00) currentModePage = modePage; + } + } + } + else + { + Modes.DecodedMode? dcMode6 = + Modes.DecodeMode6(readBuffer, PeripheralDeviceTypes.MultiMediaDevice); + + if(dcMode6.HasValue) + { + foreach(Modes.ModePage modePage in dcMode6.Value.Pages) + if(modePage.Page == 0x01 && modePage.Subpage == 0x00) + currentModePage = modePage; + } + } + + if(currentModePage == null) + { + + pgMmc = + new Modes.ModePage_01_MMC {PS = false, ReadRetryCount = 0x20, Parameter = 0x00}; + currentModePage = new Modes.ModePage + { + Page = 0x01, + Subpage = 0x00, + PageResponse = Modes.EncodeModePage_01_MMC(pgMmc) + }; + } + + pgMmc = + new Modes.ModePage_01_MMC {PS = false, ReadRetryCount = 255, Parameter = 0x20}; + Modes.DecodedMode md = new Modes.DecodedMode + { + Header = new Modes.ModeHeader(), + Pages = new[] + { + new Modes.ModePage + { + Page = 0x01, + Subpage = 0x00, + PageResponse = Modes.EncodeModePage_01_MMC(pgMmc) + } + } + }; + md6 = Modes.EncodeMode6(md, dev.ScsiType); + md10 = Modes.EncodeMode10(md, dev.ScsiType); + + dumpLog.WriteLine("Sending MODE SELECT to drive (return damaged blocks)."); + sense = dev.ModeSelect(md6, out senseBuf, true, false, dev.Timeout, out _); + if(sense) sense = dev.ModeSelect10(md10, out senseBuf, true, false, dev.Timeout, out _); + + if(sense) + { + DicConsole + .WriteLine("Drive did not accept MODE SELECT command for persistent error reading, try another drive."); + DicConsole.DebugWriteLine("Error: {0}", Sense.PrettifySense(senseBuf)); + dumpLog.WriteLine("Drive did not accept MODE SELECT command for persistent error reading, try another drive."); + } + else runningPersistent = true; + } + repeatRetry: ulong[] tmpArray = resume.BadBlocks.ToArray(); foreach(ulong badSector in tmpArray) @@ -741,76 +825,7 @@ namespace DiscImageChef.Core.Devices.Dumping goto repeatRetry; } - Modes.ModePage? currentModePage = null; - byte[] md6; - byte[] md10; - - if(!runningPersistent && persistent) - { - if(dev.ScsiType == PeripheralDeviceTypes.MultiMediaDevice) - { - Modes.ModePage_01_MMC pgMmc = - new Modes.ModePage_01_MMC {PS = false, ReadRetryCount = 255, Parameter = 0x20}; - Modes.DecodedMode md = new Modes.DecodedMode - { - Header = new Modes.ModeHeader(), - Pages = new[] - { - new Modes.ModePage - { - Page = 0x01, - Subpage = 0x00, - PageResponse = Modes.EncodeModePage_01_MMC(pgMmc) - } - } - }; - md6 = Modes.EncodeMode6(md, dev.ScsiType); - md10 = Modes.EncodeMode10(md, dev.ScsiType); - } - else - { - Modes.ModePage_01 pg = new Modes.ModePage_01 - { - PS = false, - AWRE = false, - ARRE = false, - TB = true, - RC = false, - EER = true, - PER = false, - DTE = false, - DCR = false, - ReadRetryCount = 255 - }; - Modes.DecodedMode md = new Modes.DecodedMode - { - Header = new Modes.ModeHeader(), - Pages = new[] - { - new Modes.ModePage - { - Page = 0x01, - Subpage = 0x00, - PageResponse = Modes.EncodeModePage_01(pg) - } - } - }; - md6 = Modes.EncodeMode6(md, dev.ScsiType); - md10 = Modes.EncodeMode10(md, dev.ScsiType); - } - - dumpLog.WriteLine("Sending MODE SELECT to drive."); - sense = dev.ModeSelect(md6, out senseBuf, true, false, dev.Timeout, out _); - if(sense) sense = dev.ModeSelect10(md10, out senseBuf, true, false, dev.Timeout, out _); - - runningPersistent = true; - if(!sense && !dev.Error) - { - pass--; - goto repeatRetry; - } - } - else if(runningPersistent && persistent && currentModePage.HasValue) + if(runningPersistent && currentModePage.HasValue) { Modes.DecodedMode md = new Modes.DecodedMode { @@ -820,7 +835,7 @@ namespace DiscImageChef.Core.Devices.Dumping md6 = Modes.EncodeMode6(md, dev.ScsiType); md10 = Modes.EncodeMode10(md, dev.ScsiType); - dumpLog.WriteLine("Sending MODE SELECT to drive."); + dumpLog.WriteLine("Sending MODE SELECT to drive (return device to previous status)."); sense = dev.ModeSelect(md6, out senseBuf, true, false, dev.Timeout, out _); if(sense) dev.ModeSelect10(md10, out senseBuf, true, false, dev.Timeout, out _); }