diff --git a/DiscImageChef.Core/Devices/Report/SCSI/General.cs b/DiscImageChef.Core/Devices/Report/SCSI/General.cs
index 386273906..eeaf495b6 100644
--- a/DiscImageChef.Core/Devices/Report/SCSI/General.cs
+++ b/DiscImageChef.Core/Devices/Report/SCSI/General.cs
@@ -32,115 +32,69 @@
using System;
using System.Collections.Generic;
-using System.IO;
using System.Linq;
-using System.Threading;
using DiscImageChef.CommonTypes.Metadata;
using DiscImageChef.Console;
using DiscImageChef.Decoders.SCSI;
using DiscImageChef.Devices;
-namespace DiscImageChef.Core.Devices.Report.SCSI
+namespace DiscImageChef.Core.Devices.Report
{
- ///
- /// Implements creating a report of SCSI and ATAPI devices
- ///
- public static class General
+ public partial class DeviceReport
{
- ///
- /// Creates a report of SCSI and ATAPI devices, and if appropiate calls the report creators for MultiMedia and
- /// Streaming devices
- ///
- /// Device
- /// Device report
- /// If debug is enabled
- /// If device is removable
- public static void Report(Device dev, ref DeviceReportV2 report, bool debug, ref bool removable)
+ public Scsi ReportScsiInquiry()
{
- if(report == null) return;
-
- bool sense;
- const uint TIMEOUT = 5;
- ConsoleKeyInfo pressedKey;
-
- if(!dev.IsUsb && !dev.IsFireWire && dev.IsRemovable)
- {
- pressedKey = new ConsoleKeyInfo();
- while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N)
- {
- DicConsole.Write("Is the media removable from the reading/writing elements (flash memories ARE NOT removable)? (Y/N): ");
- pressedKey = System.Console.ReadKey();
- DicConsole.WriteLine();
- }
-
- removable = pressedKey.Key == ConsoleKey.Y;
- }
-
DicConsole.WriteLine("Querying SCSI INQUIRY...");
- sense = dev.ScsiInquiry(out byte[] buffer, out byte[] senseBuffer);
+ bool sense = dev.ScsiInquiry(out byte[] buffer, out byte[] senseBuffer);
- report.SCSI = new Scsi();
+ Scsi report = new Scsi();
- if(!sense && Inquiry.Decode(buffer).HasValue)
- {
- report.SCSI.Inquiry = Inquiry.Decode(buffer);
+ if(sense || !Inquiry.Decode(buffer).HasValue) return null;
- if(debug) report.SCSI.InquiryData = buffer;
- }
+ report.Inquiry = Inquiry.Decode(buffer);
+ if(debug) report.InquiryData = buffer;
+
+ return report;
+ }
+
+ public ScsiPage[] ReportEvpdPages()
+ {
DicConsole.WriteLine("Querying list of SCSI EVPDs...");
- sense = dev.ScsiInquiry(out buffer, out senseBuffer, 0x00);
+ bool sense = dev.ScsiInquiry(out byte[] buffer, out _, 0x00);
- if(!sense)
+ if(sense) return null;
+
+ byte[] evpdPages = EVPD.DecodePage00(buffer);
+ if(evpdPages == null || evpdPages.Length <= 0) return null;
+
+ List evpds = new List();
+ foreach(byte page in evpdPages.Where(page => page != 0x80))
{
- byte[] evpdPages = EVPD.DecodePage00(buffer);
- if(evpdPages != null && evpdPages.Length > 0)
- {
- List evpds = new List();
- foreach(byte page in evpdPages.Where(page => page != 0x80))
- {
- DicConsole.WriteLine("Querying SCSI EVPD {0:X2}h...", page);
- sense = dev.ScsiInquiry(out buffer, out senseBuffer, page);
- if(sense) continue;
+ DicConsole.WriteLine("Querying SCSI EVPD {0:X2}h...", page);
+ sense = dev.ScsiInquiry(out buffer, out _, page);
+ if(sense) continue;
- ScsiPage evpd = new ScsiPage {page = page, value = buffer};
- evpds.Add(evpd);
- }
-
- if(evpds.Count > 0) report.SCSI.EVPDPages = evpds.ToArray();
- }
+ ScsiPage evpd = new ScsiPage {page = page, value = buffer};
+ evpds.Add(evpd);
}
- if(removable)
- {
- switch(dev.ScsiType)
- {
- case PeripheralDeviceTypes.MultiMediaDevice:
- dev.AllowMediumRemoval(out senseBuffer, TIMEOUT, out _);
- dev.EjectTray(out senseBuffer, TIMEOUT, out _);
- break;
- case PeripheralDeviceTypes.SequentialAccess:
- dev.SpcAllowMediumRemoval(out senseBuffer, TIMEOUT, out _);
- DicConsole.WriteLine("Asking drive to unload tape (can take a few minutes)...");
- dev.Unload(out senseBuffer, TIMEOUT, out _);
- break;
- }
-
- DicConsole.WriteLine("Please remove any media from the device and press any key when it is out.");
- System.Console.ReadKey(true);
- }
+ return evpds.Count > 0 ? evpds.ToArray() : null;
+ }
+ public void ReportScsiModes(ref DeviceReportV2 report, ref Modes.ModePage_2A? cdromMode)
+ {
Modes.DecodedMode? decMode = null;
PeripheralDeviceTypes devType = dev.ScsiType;
DicConsole.WriteLine("Querying all mode pages and subpages using SCSI MODE SENSE (10)...");
- sense = dev.ModeSense10(out byte[] mode10Buffer, out senseBuffer, false, true,
- ScsiModeSensePageControl.Default, 0x3F, 0xFF, TIMEOUT, out _);
+ bool sense = dev.ModeSense10(out byte[] mode10Buffer, out _, false, true, ScsiModeSensePageControl.Default,
+ 0x3F, 0xFF, dev.Timeout, out _);
if(sense || dev.Error)
{
DicConsole.WriteLine("Querying all mode pages using SCSI MODE SENSE (10)...");
- sense = dev.ModeSense10(out mode10Buffer, out senseBuffer, false, true,
- ScsiModeSensePageControl.Default, 0x3F, 0x00, TIMEOUT, out _);
+ sense = dev.ModeSense10(out mode10Buffer, out _, false, true, ScsiModeSensePageControl.Default, 0x3F,
+ 0x00, dev.Timeout, out _);
if(!sense && !dev.Error)
{
report.SCSI.SupportsModeSense10 = true;
@@ -156,17 +110,17 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
}
DicConsole.WriteLine("Querying all mode pages and subpages using SCSI MODE SENSE (6)...");
- sense = dev.ModeSense6(out byte[] mode6Buffer, out senseBuffer, false, ScsiModeSensePageControl.Default,
- 0x3F, 0xFF, TIMEOUT, out _);
+ sense = dev.ModeSense6(out byte[] mode6Buffer, out _, false, ScsiModeSensePageControl.Default, 0x3F, 0xFF,
+ dev.Timeout, out _);
if(sense || dev.Error)
{
DicConsole.WriteLine("Querying all mode pages using SCSI MODE SENSE (6)...");
- sense = dev.ModeSense6(out mode6Buffer, out senseBuffer, false, ScsiModeSensePageControl.Default, 0x3F,
- 0x00, TIMEOUT, out _);
+ sense = dev.ModeSense6(out mode6Buffer, out _, false, ScsiModeSensePageControl.Default, 0x3F, 0x00,
+ dev.Timeout, out _);
if(sense || dev.Error)
{
DicConsole.WriteLine("Querying SCSI MODE SENSE (6)...");
- sense = dev.ModeSense(out mode6Buffer, out senseBuffer, TIMEOUT, out _);
+ sense = dev.ModeSense(out mode6Buffer, out _, dev.Timeout, out _);
}
}
else report.SCSI.SupportsModeSubpages = true;
@@ -175,604 +129,371 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
report.SCSI.SupportsModeSense6 |= !sense && !dev.Error;
- Modes.ModePage_2A? cdromMode = null;
+ cdromMode = null;
if(debug && report.SCSI.SupportsModeSense6) report.SCSI.ModeSense6Data = mode6Buffer;
if(debug && report.SCSI.SupportsModeSense10) report.SCSI.ModeSense10Data = mode10Buffer;
+ if(!decMode.HasValue) return;
+
+ report.SCSI.ModeSense = new ScsiMode
+ {
+ BlankCheckEnabled = decMode.Value.Header.EBC,
+ DPOandFUA = decMode.Value.Header.DPOFUA,
+ WriteProtected = decMode.Value.Header.WriteProtected
+ };
+
+ if(decMode.Value.Header.BufferedMode > 0)
+ report.SCSI.ModeSense.BufferedMode = decMode.Value.Header.BufferedMode;
+
+ if(decMode.Value.Header.Speed > 0) report.SCSI.ModeSense.Speed = decMode.Value.Header.Speed;
+
+ if(decMode.Value.Pages == null) return;
+
+ List modePages = new List();
+ foreach(Modes.ModePage page in decMode.Value.Pages)
+ {
+ ScsiPage modePage = new ScsiPage {page = page.Page, subpage = page.Subpage, value = page.PageResponse};
+ modePages.Add(modePage);
+
+ if(modePage.page == 0x2A && modePage.subpage == 0x00)
+ cdromMode = Modes.DecodeModePage_2A(page.PageResponse);
+ }
+
+ if(modePages.Count > 0) report.SCSI.ModeSense.ModePages = modePages.ToArray();
+ }
+
+ public TestedMedia ReportScsiMedia()
+ {
+ TestedMedia mediaTest = new TestedMedia();
+ DicConsole.WriteLine("Querying SCSI READ CAPACITY...");
+ bool sense = dev.ReadCapacity(out byte[] buffer, out byte[] senseBuffer, dev.Timeout, out _);
+ if(!sense && !dev.Error)
+ {
+ mediaTest.SupportsReadCapacity = true;
+ mediaTest.Blocks =
+ (ulong)((buffer[0] << 24) + (buffer[1] << 16) + (buffer[2] << 8) + buffer[3]) + 1;
+ mediaTest.BlockSize =
+ (uint)((buffer[4] << 24) + (buffer[5] << 16) + (buffer[6] << 8) + buffer[7]);
+ }
+
+ DicConsole.WriteLine("Querying SCSI READ CAPACITY (16)...");
+ sense = dev.ReadCapacity16(out buffer, out buffer, dev.Timeout, out _);
+ if(!sense && !dev.Error)
+ {
+ mediaTest.SupportsReadCapacity16 = true;
+ byte[] temp = new byte[8];
+ Array.Copy(buffer, 0, temp, 0, 8);
+ Array.Reverse(temp);
+ mediaTest.Blocks = BitConverter.ToUInt64(temp, 0) + 1;
+ mediaTest.BlockSize = (uint)((buffer[8] << 24) + (buffer[9] << 16) + (buffer[10] << 8) + buffer[11]);
+ }
+
+ Modes.DecodedMode? decMode = null;
+
+ DicConsole.WriteLine("Querying SCSI MODE SENSE (10)...");
+ sense = dev.ModeSense10(out buffer, out senseBuffer, false, true, ScsiModeSensePageControl.Current, 0x3F,
+ 0x00, dev.Timeout, out _);
+ if(!sense && !dev.Error)
+ {
+ decMode = Modes.DecodeMode10(buffer, dev.ScsiType);
+ if(debug) mediaTest.ModeSense10Data = buffer;
+ }
+
+ DicConsole.WriteLine("Querying SCSI MODE SENSE...");
+ sense = dev.ModeSense(out buffer, out senseBuffer, dev.Timeout, out _);
+ if(!sense && !dev.Error)
+ {
+ if(!decMode.HasValue) decMode = Modes.DecodeMode6(buffer, dev.ScsiType);
+ if(debug) mediaTest.ModeSense6Data = buffer;
+ }
+
if(decMode.HasValue)
{
- report.SCSI.ModeSense = new ScsiMode
- {
- BlankCheckEnabled = decMode.Value.Header.EBC,
- DPOandFUA = decMode.Value.Header.DPOFUA,
- WriteProtected = decMode.Value.Header.WriteProtected
- };
-
- if(decMode.Value.Header.BufferedMode > 0)
- report.SCSI.ModeSense.BufferedMode = decMode.Value.Header.BufferedMode;
-
- if(decMode.Value.Header.Speed > 0) report.SCSI.ModeSense.Speed = decMode.Value.Header.Speed;
-
- if(decMode.Value.Pages != null)
- {
- List modePages = new List();
- foreach(Modes.ModePage page in decMode.Value.Pages)
- {
- ScsiPage modePage = new ScsiPage
- {
- page = page.Page, subpage = page.Subpage, value = page.PageResponse
- };
- modePages.Add(modePage);
-
- if(modePage.page == 0x2A && modePage.subpage == 0x00)
- cdromMode = Modes.DecodeModePage_2A(page.PageResponse);
- }
-
- if(modePages.Count > 0) report.SCSI.ModeSense.ModePages = modePages.ToArray();
- }
+ mediaTest.MediumType = (byte)decMode.Value.Header.MediumType;
+ if(decMode.Value.Header.BlockDescriptors != null && decMode.Value.Header.BlockDescriptors.Length > 0)
+ mediaTest.Density = (byte)decMode.Value.Header.BlockDescriptors[0].Density;
}
- string productIdentification = null;
- if(!string.IsNullOrWhiteSpace(StringHandlers.CToString(report.SCSI.Inquiry?.ProductIdentification)))
- productIdentification = StringHandlers.CToString(report.SCSI.Inquiry?.ProductIdentification).Trim();
+ DicConsole.WriteLine("Trying SCSI READ (6)...");
+ mediaTest.SupportsRead6 = !dev.Read6(out buffer, out senseBuffer, 0,
+ mediaTest.BlockSize ?? 512, dev.Timeout, out _);
+ DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.SupportsRead6);
+ if(debug)
+ DataFile.WriteTo("SCSI Report", "read6", "_debug_" + mediaTest.MediumTypeName + ".bin", "read results",
+ buffer);
- switch(dev.ScsiType)
+ DicConsole.WriteLine("Trying SCSI READ (10)...");
+ mediaTest.SupportsRead10 = !dev.Read10(out buffer, out senseBuffer, 0, false, true, false, false, 0,
+ mediaTest.BlockSize ?? 512, 0, 1, dev.Timeout, out _);
+ DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.SupportsRead10);
+ if(debug)
+ DataFile.WriteTo("SCSI Report", "read10", "_debug_" + mediaTest.MediumTypeName + ".bin", "read results",
+ buffer);
+
+ DicConsole.WriteLine("Trying SCSI READ (12)...");
+ mediaTest.SupportsRead12 = !dev.Read12(out buffer, out senseBuffer, 0, false, true, false, false, 0,
+ mediaTest.BlockSize ?? 512, 0, 1, false, dev.Timeout, out _);
+ DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.SupportsRead12);
+ if(debug)
+ DataFile.WriteTo("SCSI Report", "read12", "_debug_" + mediaTest.MediumTypeName + ".bin", "read results",
+ buffer);
+
+ DicConsole.WriteLine("Trying SCSI READ (16)...");
+ mediaTest.SupportsRead16 = !dev.Read16(out buffer, out senseBuffer, 0, false, true, false, 0,
+ mediaTest.BlockSize ?? 512, 0, 1, false, dev.Timeout, out _);
+ DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.SupportsRead16);
+ if(debug)
+ DataFile.WriteTo("SCSI Report", "read16", "_debug_" + mediaTest.MediumTypeName + ".bin", "read results",
+ buffer);
+
+ mediaTest.LongBlockSize = mediaTest.BlockSize;
+ DicConsole.WriteLine("Trying SCSI READ LONG (10)...");
+ sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 0xFFFF, dev.Timeout, out _);
+ if(sense && !dev.Error)
{
- case PeripheralDeviceTypes.MultiMediaDevice:
- Mmc.Report(dev, ref report, debug, ref cdromMode, productIdentification);
- break;
- case PeripheralDeviceTypes.SequentialAccess:
- Ssc.Report(dev, ref report, debug);
- break;
- default:
- if(removable)
+ FixedSense? decSense = Sense.DecodeFixed(senseBuffer);
+ if(decSense.HasValue)
+ if(decSense.Value.SenseKey == SenseKeys.IllegalRequest && decSense.Value.ASC == 0x24 &&
+ decSense.Value.ASCQ == 0x00)
{
- List mediaTests = new List();
-
- pressedKey = new ConsoleKeyInfo();
- while(pressedKey.Key != ConsoleKey.N)
- {
- pressedKey = new ConsoleKeyInfo();
- while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N)
- {
- DicConsole.Write("Do you have media that you can insert in the drive? (Y/N): ");
- pressedKey = System.Console.ReadKey();
- DicConsole.WriteLine();
- }
-
- if(pressedKey.Key != ConsoleKey.Y) continue;
-
- DicConsole.WriteLine("Please insert it in the drive and press any key when it is ready.");
- System.Console.ReadKey(true);
-
- TestedMedia mediaTest = new TestedMedia();
- DicConsole.Write("Please write a description of the media type and press enter: ");
- mediaTest.MediumTypeName = System.Console.ReadLine();
- DicConsole.Write("Please write the media manufacturer and press enter: ");
- mediaTest.Manufacturer = System.Console.ReadLine();
- DicConsole.Write("Please write the media model and press enter: ");
- mediaTest.Model = System.Console.ReadLine();
-
- mediaTest.MediaIsRecognized = true;
-
- sense = dev.ScsiTestUnitReady(out senseBuffer, TIMEOUT, out _);
- if(sense)
- {
- FixedSense? decSense = Sense.DecodeFixed(senseBuffer);
- if(decSense.HasValue)
- if(decSense.Value.ASC == 0x3A)
- {
- int leftRetries = 20;
- while(leftRetries > 0)
- {
- DicConsole.Write("\rWaiting for drive to become ready");
- Thread.Sleep(2000);
- sense = dev.ScsiTestUnitReady(out senseBuffer, TIMEOUT, out _);
- if(!sense) break;
-
- leftRetries--;
- }
-
- mediaTest.MediaIsRecognized &= !sense;
- }
- else if(decSense.Value.ASC == 0x04 && decSense.Value.ASCQ == 0x01)
- {
- int leftRetries = 20;
- while(leftRetries > 0)
- {
- DicConsole.Write("\rWaiting for drive to become ready");
- Thread.Sleep(2000);
- sense = dev.ScsiTestUnitReady(out senseBuffer, TIMEOUT, out _);
- if(!sense) break;
-
- leftRetries--;
- }
-
- mediaTest.MediaIsRecognized &= !sense;
- }
- else mediaTest.MediaIsRecognized = false;
- else mediaTest.MediaIsRecognized = false;
- }
-
- if(mediaTest.MediaIsRecognized)
- {
- DicConsole.WriteLine("Querying SCSI READ CAPACITY...");
- sense = dev.ReadCapacity(out buffer, out senseBuffer, TIMEOUT, out _);
- if(!sense && !dev.Error)
- {
- mediaTest.SupportsReadCapacity = true;
- mediaTest.Blocks =
- (ulong)((buffer[0] << 24) + (buffer[1] << 16) + (buffer[2] << 8) + buffer[3]) +
- 1;
- mediaTest.BlockSize =
- (uint)((buffer[4] << 24) + (buffer[5] << 16) + (buffer[6] << 8) + buffer[7]);
- }
-
- DicConsole.WriteLine("Querying SCSI READ CAPACITY (16)...");
- sense = dev.ReadCapacity16(out buffer, out buffer, TIMEOUT, out _);
- if(!sense && !dev.Error)
- {
- mediaTest.SupportsReadCapacity16 = true;
- byte[] temp = new byte[8];
- Array.Copy(buffer, 0, temp, 0, 8);
- Array.Reverse(temp);
- mediaTest.Blocks = BitConverter.ToUInt64(temp, 0) + 1;
- mediaTest.BlockSize =
- (uint)((buffer[8] << 24) + (buffer[9] << 16) + (buffer[10] << 8) + buffer[11]);
- }
-
- decMode = null;
-
- DicConsole.WriteLine("Querying SCSI MODE SENSE (10)...");
- sense = dev.ModeSense10(out buffer, out senseBuffer, false, true,
- ScsiModeSensePageControl.Current, 0x3F, 0x00, TIMEOUT, out _);
- if(!sense && !dev.Error)
- {
- report.SCSI.SupportsModeSense10 = true;
- decMode = Modes.DecodeMode10(buffer, dev.ScsiType);
- if(debug) mediaTest.ModeSense10Data = buffer;
- }
-
- DicConsole.WriteLine("Querying SCSI MODE SENSE...");
- sense = dev.ModeSense(out buffer, out senseBuffer, TIMEOUT, out _);
- if(!sense && !dev.Error)
- {
- report.SCSI.SupportsModeSense6 = true;
- if(!decMode.HasValue) decMode = Modes.DecodeMode6(buffer, dev.ScsiType);
- if(debug) mediaTest.ModeSense6Data = buffer;
- }
-
- if(decMode.HasValue)
- {
- mediaTest.MediumType = (byte)decMode.Value.Header.MediumType;
- if(decMode.Value.Header.BlockDescriptors != null &&
- decMode.Value.Header.BlockDescriptors.Length > 0)
- mediaTest.Density = (byte)decMode.Value.Header.BlockDescriptors[0].Density;
- }
-
- DicConsole.WriteLine("Trying SCSI READ (6)...");
- mediaTest.SupportsRead6 = !dev.Read6(out buffer, out senseBuffer, 0,
- mediaTest.BlockSize ?? 512, TIMEOUT, out _);
- DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.SupportsRead6);
- if(debug)
- DataFile.WriteTo("SCSI Report", "read6",
- "_debug_" + mediaTest.MediumTypeName + ".bin", "read results",
- buffer);
-
- DicConsole.WriteLine("Trying SCSI READ (10)...");
- mediaTest.SupportsRead10 =
- !dev.Read10(out buffer, out senseBuffer, 0, false, true, false, false, 0,
- mediaTest.BlockSize ?? 512, 0, 1, TIMEOUT, out _);
- DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.SupportsRead10);
- if(debug)
- DataFile.WriteTo("SCSI Report", "read10",
- "_debug_" + mediaTest.MediumTypeName + ".bin", "read results",
- buffer);
-
- DicConsole.WriteLine("Trying SCSI READ (12)...");
- mediaTest.SupportsRead12 =
- !dev.Read12(out buffer, out senseBuffer, 0, false, true, false, false, 0,
- mediaTest.BlockSize ?? 512, 0, 1, false, TIMEOUT, out _);
- DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.SupportsRead12);
- if(debug)
- DataFile.WriteTo("SCSI Report", "read12",
- "_debug_" + mediaTest.MediumTypeName + ".bin", "read results",
- buffer);
-
- DicConsole.WriteLine("Trying SCSI READ (16)...");
- mediaTest.SupportsRead16 =
- !dev.Read16(out buffer, out senseBuffer, 0, false, true, false, 0,
- mediaTest.BlockSize ?? 512, 0, 1, false, TIMEOUT, out _);
- DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.SupportsRead16);
- if(debug)
- DataFile.WriteTo("SCSI Report", "read16",
- "_debug_" + mediaTest.MediumTypeName + ".bin", "read results",
- buffer);
-
- mediaTest.LongBlockSize = mediaTest.BlockSize;
- DicConsole.WriteLine("Trying SCSI READ LONG (10)...");
- sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 0xFFFF, TIMEOUT,
- out _);
- if(sense && !dev.Error)
- {
- FixedSense? decSense = Sense.DecodeFixed(senseBuffer);
- if(decSense.HasValue)
- if(decSense.Value.SenseKey == SenseKeys.IllegalRequest &&
- decSense.Value.ASC == 0x24 &&
- decSense.Value.ASCQ == 0x00)
- {
- mediaTest.SupportsReadLong = true;
- if(decSense.Value.InformationValid && decSense.Value.ILI)
- mediaTest.LongBlockSize =
- 0xFFFF - (decSense.Value.Information & 0xFFFF);
- }
- }
-
- if(mediaTest.SupportsReadLong == true && mediaTest.LongBlockSize == mediaTest.BlockSize)
- if(mediaTest.BlockSize == 512)
- foreach(int i in new[]
- {
- // Long sector sizes for floppies
- 514,
- // Long sector sizes for SuperDisk
- 536, 558,
- // Long sector sizes for 512-byte magneto-opticals
- 600, 610, 630
- })
- {
- ushort testSize = (ushort)i;
- sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0,
- testSize, TIMEOUT, out _);
- if(sense || dev.Error) continue;
-
- mediaTest.SupportsReadLong = true;
- mediaTest.LongBlockSize = testSize;
- break;
- }
- else if(mediaTest.BlockSize == 1024)
- foreach(int i in new[]
- {
- // Long sector sizes for floppies
- 1026,
- // Long sector sizes for 1024-byte magneto-opticals
- 1200
- })
- {
- ushort testSize = (ushort)i;
- sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0,
- (ushort)i, TIMEOUT, out _);
- if(sense || dev.Error) continue;
-
- mediaTest.SupportsReadLong = true;
- mediaTest.LongBlockSize = testSize;
- break;
- }
- else if(mediaTest.BlockSize == 2048)
- {
- sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 2380,
- TIMEOUT, out _);
- if(!sense && !dev.Error)
- {
- mediaTest.SupportsReadLong = true;
- mediaTest.LongBlockSize = 2380;
- }
- }
- else if(mediaTest.BlockSize == 4096)
- {
- sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 4760,
- TIMEOUT, out _);
- if(!sense && !dev.Error)
- {
- mediaTest.SupportsReadLong = true;
- mediaTest.LongBlockSize = 4760;
- }
- }
- else if(mediaTest.BlockSize == 8192)
- {
- sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 9424,
- TIMEOUT, out _);
- if(!sense && !dev.Error)
- {
- mediaTest.SupportsReadLong = true;
- mediaTest.LongBlockSize = 9424;
- }
- }
-
- if(mediaTest.SupportsReadLong == true && mediaTest.LongBlockSize == mediaTest.BlockSize)
- {
- pressedKey = new ConsoleKeyInfo();
- while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N)
- {
- DicConsole
- .Write("Drive supports SCSI READ LONG but I cannot find the correct size. Do you want me to try? (This can take hours) (Y/N): ");
- pressedKey = System.Console.ReadKey();
- DicConsole.WriteLine();
- }
-
- if(pressedKey.Key == ConsoleKey.Y)
- {
- for(ushort i = (ushort)mediaTest.BlockSize;; i++)
- {
- DicConsole.Write("\rTrying to READ LONG with a size of {0} bytes...", i);
- sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, i,
- TIMEOUT, out _);
- if(!sense)
- {
- mediaTest.LongBlockSize = i;
- break;
- }
-
- if(i == ushort.MaxValue) break;
- }
-
- DicConsole.WriteLine();
- }
- }
-
- if(debug && mediaTest.SupportsReadLong == true &&
- mediaTest.LongBlockSize != mediaTest.BlockSize)
- {
- sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0,
- (ushort)mediaTest.LongBlockSize, TIMEOUT, out _);
- if(!sense)
- DataFile.WriteTo("SCSI Report", "readlong10",
- "_debug_" + mediaTest.MediumTypeName + ".bin", "read results",
- buffer);
- }
-
- DicConsole.WriteLine("Trying SCSI READ MEDIA SERIAL NUMBER...");
- mediaTest.CanReadMediaSerial =
- !dev.ReadMediaSerialNumber(out buffer, out senseBuffer, TIMEOUT, out _);
- }
-
- mediaTests.Add(mediaTest);
- }
-
- report.SCSI.RemovableMedias = mediaTests.ToArray();
+ mediaTest.SupportsReadLong = true;
+ if(decSense.Value.InformationValid && decSense.Value.ILI)
+ mediaTest.LongBlockSize = 0xFFFF - (decSense.Value.Information & 0xFFFF);
}
- else
- {
- report.SCSI.ReadCapabilities = new TestedMedia();
- report.SCSI.ReadCapabilities.MediaIsRecognized = true;
-
- DicConsole.WriteLine("Querying SCSI READ CAPACITY...");
- sense = dev.ReadCapacity(out buffer, out senseBuffer, TIMEOUT, out _);
- if(!sense && !dev.Error)
- {
- report.SCSI.ReadCapabilities.SupportsReadCapacity = true;
- report.SCSI.ReadCapabilities.Blocks =
- (ulong)((buffer[0] << 24) + (buffer[1] << 16) + (buffer[2] << 8) + buffer[3]) + 1;
- report.SCSI.ReadCapabilities.BlockSize =
- (uint)((buffer[4] << 24) + (buffer[5] << 16) + (buffer[6] << 8) + buffer[7]);
- }
-
- DicConsole.WriteLine("Querying SCSI READ CAPACITY (16)...");
- sense = dev.ReadCapacity16(out buffer, out buffer, TIMEOUT, out _);
- if(!sense && !dev.Error)
- {
- report.SCSI.ReadCapabilities.SupportsReadCapacity16 = true;
- byte[] temp = new byte[8];
- Array.Copy(buffer, 0, temp, 0, 8);
- Array.Reverse(temp);
- report.SCSI.ReadCapabilities.Blocks = BitConverter.ToUInt64(temp, 0) + 1;
- report.SCSI.ReadCapabilities.BlockSize =
- (uint)((buffer[8] << 24) + (buffer[9] << 16) + (buffer[10] << 8) + buffer[11]);
- }
-
- decMode = null;
-
- DicConsole.WriteLine("Querying SCSI MODE SENSE (10)...");
- sense = dev.ModeSense10(out buffer, out senseBuffer, false, true,
- ScsiModeSensePageControl.Current, 0x3F, 0x00, TIMEOUT, out _);
- if(!sense && !dev.Error)
- {
- report.SCSI.SupportsModeSense10 = true;
- decMode = Modes.DecodeMode10(buffer, dev.ScsiType);
- if(debug) report.SCSI.ReadCapabilities.ModeSense10Data = buffer;
- }
-
- DicConsole.WriteLine("Querying SCSI MODE SENSE...");
- sense = dev.ModeSense(out buffer, out senseBuffer, TIMEOUT, out _);
- if(!sense && !dev.Error)
- {
- report.SCSI.SupportsModeSense6 = true;
- if(!decMode.HasValue)
- decMode = Modes.DecodeMode6(buffer, dev.ScsiType);
- if(debug) report.SCSI.ReadCapabilities.ModeSense6Data = buffer;
- }
-
- if(decMode.HasValue)
- {
- report.SCSI.ReadCapabilities.MediumType = (byte)decMode.Value.Header.MediumType;
- if(decMode.Value.Header.BlockDescriptors != null &&
- decMode.Value.Header.BlockDescriptors.Length > 0)
- report.SCSI.ReadCapabilities.Density =
- (byte)decMode.Value.Header.BlockDescriptors[0].Density;
- }
-
- DicConsole.WriteLine("Trying SCSI READ (6)...");
- report.SCSI.ReadCapabilities.SupportsRead6 =
- !dev.Read6(out buffer, out senseBuffer, 0, report.SCSI.ReadCapabilities.BlockSize ?? 512,
- TIMEOUT, out _);
- DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}",
- !report.SCSI.ReadCapabilities.SupportsRead6);
- if(debug)
- DataFile.WriteTo("SCSI Report", "read6", "_debug_" + productIdentification + ".bin",
- "read results", buffer);
-
- DicConsole.WriteLine("Trying SCSI READ (10)...");
- report.SCSI.ReadCapabilities.SupportsRead10 =
- !dev.Read10(out buffer, out senseBuffer, 0, false, true, false, false, 0,
- report.SCSI.ReadCapabilities.BlockSize ?? 512, 0, 1, TIMEOUT, out _);
- DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}",
- !report.SCSI.ReadCapabilities.SupportsRead10);
- if(debug)
- DataFile.WriteTo("SCSI Report", "read10", "_debug_" + productIdentification + ".bin",
- "read results", buffer);
-
- DicConsole.WriteLine("Trying SCSI READ (12)...");
- report.SCSI.ReadCapabilities.SupportsRead12 =
- !dev.Read12(out buffer, out senseBuffer, 0, false, true, false, false, 0,
- report.SCSI.ReadCapabilities.BlockSize ?? 512, 0, 1, false, TIMEOUT, out _);
- DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}",
- !report.SCSI.ReadCapabilities.SupportsRead12);
- if(debug)
- DataFile.WriteTo("SCSI Report", "read12", "_debug_" + productIdentification + ".bin",
- "read results", buffer);
-
- DicConsole.WriteLine("Trying SCSI READ (16)...");
- report.SCSI.ReadCapabilities.SupportsRead16 =
- !dev.Read16(out buffer, out senseBuffer, 0, false, true, false, 0,
- report.SCSI.ReadCapabilities.BlockSize ?? 512, 0, 1, false, TIMEOUT, out _);
- DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}",
- !report.SCSI.ReadCapabilities.SupportsRead16);
- if(debug)
- DataFile.WriteTo("SCSI Report", "read16", "_debug_" + productIdentification + ".bin",
- "read results", buffer);
-
- report.SCSI.ReadCapabilities.LongBlockSize = report.SCSI.ReadCapabilities.BlockSize;
- DicConsole.WriteLine("Trying SCSI READ LONG (10)...");
- sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 0xFFFF, TIMEOUT, out _);
- if(sense && !dev.Error)
- {
- FixedSense? decSense = Sense.DecodeFixed(senseBuffer);
- if(decSense.HasValue)
- if(decSense.Value.SenseKey == SenseKeys.IllegalRequest && decSense.Value.ASC == 0x24 &&
- decSense.Value.ASCQ == 0x00)
- {
- report.SCSI.ReadCapabilities.SupportsReadLong = true;
- if(decSense.Value.InformationValid && decSense.Value.ILI)
- report.SCSI.ReadCapabilities.LongBlockSize =
- 0xFFFF - (decSense.Value.Information & 0xFFFF);
- }
- }
-
- if(report.SCSI.ReadCapabilities.SupportsReadLong == true &&
- report.SCSI.ReadCapabilities.LongBlockSize == report.SCSI.ReadCapabilities.BlockSize)
- if(report.SCSI.ReadCapabilities.BlockSize == 512)
- foreach(int i in new[]
- {
- // Long sector sizes for floppies
- 514,
- // Long sector sizes for SuperDisk
- 536, 558,
- // Long sector sizes for 512-byte magneto-opticals
- 600, 610, 630
- })
- {
- ushort testSize = (ushort)i;
- sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, (ushort)i,
- TIMEOUT, out _);
- if(sense || dev.Error) continue;
-
- report.SCSI.ReadCapabilities.SupportsReadLong = true;
- report.SCSI.ReadCapabilities.LongBlockSize = testSize;
- break;
- }
- else if(report.SCSI.ReadCapabilities.BlockSize == 1024)
- foreach(int i in new[]
- {
- // Long sector sizes for floppies
- 1026,
- // Long sector sizes for 1024-byte magneto-opticals
- 1200
- })
- {
- ushort testSize = (ushort)i;
- sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, (ushort)i,
- TIMEOUT, out _);
- if(sense || dev.Error) continue;
-
- report.SCSI.ReadCapabilities.SupportsReadLong = true;
- report.SCSI.ReadCapabilities.LongBlockSize = testSize;
- break;
- }
- else if(report.SCSI.ReadCapabilities.BlockSize == 2048)
- {
- sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 2380, TIMEOUT,
- out _);
- if(!sense && !dev.Error)
- {
- report.SCSI.ReadCapabilities.SupportsReadLong = true;
- report.SCSI.ReadCapabilities.LongBlockSize = 2380;
- }
- }
- else if(report.SCSI.ReadCapabilities.BlockSize == 4096)
- {
- sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 4760, TIMEOUT,
- out _);
- if(!sense && !dev.Error)
- {
- report.SCSI.ReadCapabilities.SupportsReadLong = true;
- report.SCSI.ReadCapabilities.LongBlockSize = 4760;
- }
- }
- else if(report.SCSI.ReadCapabilities.BlockSize == 8192)
- {
- sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 9424, TIMEOUT,
- out _);
- if(!sense && !dev.Error)
- {
- report.SCSI.ReadCapabilities.SupportsReadLong = true;
- report.SCSI.ReadCapabilities.LongBlockSize = 9424;
- }
- }
-
- if(report.SCSI.ReadCapabilities.SupportsReadLong == true &&
- report.SCSI.ReadCapabilities.LongBlockSize == report.SCSI.ReadCapabilities.BlockSize)
- {
- pressedKey = new ConsoleKeyInfo();
- while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N)
- {
- DicConsole
- .Write("Drive supports SCSI READ LONG but I cannot find the correct size. Do you want me to try? (This can take hours) (Y/N): ");
- pressedKey = System.Console.ReadKey();
- DicConsole.WriteLine();
- }
-
- if(pressedKey.Key == ConsoleKey.Y)
- {
- for(ushort i = (ushort)report.SCSI.ReadCapabilities.BlockSize;; i++)
- {
- DicConsole.Write("\rTrying to READ LONG with a size of {0} bytes...", i);
- sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, i, TIMEOUT,
- out _);
- if(!sense)
- {
- if(debug)
- {
- FileStream bingo =
- new FileStream($"{dev.Model}_readlong.bin", FileMode.Create);
- bingo.Write(buffer, 0, buffer.Length);
- bingo.Close();
- }
-
- report.SCSI.ReadCapabilities.LongBlockSize = i;
- break;
- }
-
- if(i == ushort.MaxValue) break;
- }
-
- DicConsole.WriteLine();
- }
- }
-
- if(debug && report.SCSI.ReadCapabilities.SupportsReadLong == true &&
- report.SCSI.ReadCapabilities.LongBlockSize !=
- report.SCSI.ReadCapabilities.BlockSize)
- {
- sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0,
- (ushort)report.SCSI.ReadCapabilities.LongBlockSize, TIMEOUT, out _);
- if(!sense)
- DataFile.WriteTo("SCSI Report", "readlong10",
- "_debug_" + productIdentification + ".bin", "read results", buffer);
- }
- }
-
- break;
}
+
+ if(mediaTest.SupportsReadLong == true && mediaTest.LongBlockSize == mediaTest.BlockSize)
+ if(mediaTest.BlockSize == 512)
+ foreach(int i in new[]
+ {
+ // Long sector sizes for floppies
+ 514,
+ // Long sector sizes for SuperDisk
+ 536, 558,
+ // Long sector sizes for 512-byte magneto-opticals
+ 600, 610, 630
+ })
+ {
+ ushort testSize = (ushort)i;
+ sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, testSize, dev.Timeout,
+ out _);
+ if(sense || dev.Error) continue;
+
+ mediaTest.SupportsReadLong = true;
+ mediaTest.LongBlockSize = testSize;
+ break;
+ }
+ else if(mediaTest.BlockSize == 1024)
+ foreach(int i in new[]
+ {
+ // Long sector sizes for floppies
+ 1026,
+ // Long sector sizes for 1024-byte magneto-opticals
+ 1200
+ })
+ {
+ ushort testSize = (ushort)i;
+ sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, (ushort)i, dev.Timeout,
+ out _);
+ if(sense || dev.Error) continue;
+
+ mediaTest.SupportsReadLong = true;
+ mediaTest.LongBlockSize = testSize;
+ break;
+ }
+ else if(mediaTest.BlockSize == 2048)
+ {
+ sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 2380, dev.Timeout, out _);
+ if(!sense && !dev.Error)
+ {
+ mediaTest.SupportsReadLong = true;
+ mediaTest.LongBlockSize = 2380;
+ }
+ }
+ else if(mediaTest.BlockSize == 4096)
+ {
+ sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 4760, dev.Timeout, out _);
+ if(!sense && !dev.Error)
+ {
+ mediaTest.SupportsReadLong = true;
+ mediaTest.LongBlockSize = 4760;
+ }
+ }
+ else if(mediaTest.BlockSize == 8192)
+ {
+ sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 9424, dev.Timeout, out _);
+ if(!sense && !dev.Error)
+ {
+ mediaTest.SupportsReadLong = true;
+ mediaTest.LongBlockSize = 9424;
+ }
+ }
+
+ DicConsole.WriteLine("Trying SCSI READ MEDIA SERIAL NUMBER...");
+ mediaTest.CanReadMediaSerial = !dev.ReadMediaSerialNumber(out buffer, out senseBuffer, dev.Timeout, out _);
+
+ return mediaTest;
+ }
+
+ public TestedMedia ReportScsi()
+ {
+ TestedMedia capabilities = new TestedMedia {MediaIsRecognized = true};
+
+ DicConsole.WriteLine("Querying SCSI READ CAPACITY...");
+ bool sense = dev.ReadCapacity(out byte[] buffer, out byte[] senseBuffer, dev.Timeout, out _);
+ if(!sense && !dev.Error)
+ {
+ capabilities.SupportsReadCapacity = true;
+ capabilities.Blocks =
+ (ulong)((buffer[0] << 24) + (buffer[1] << 16) + (buffer[2] << 8) + buffer[3]) + 1;
+ capabilities.BlockSize =
+ (uint)((buffer[4] << 24) + (buffer[5] << 16) + (buffer[6] << 8) + buffer[7]);
+ }
+
+ DicConsole.WriteLine("Querying SCSI READ CAPACITY (16)...");
+ sense = dev.ReadCapacity16(out buffer, out buffer, dev.Timeout, out _);
+ if(!sense && !dev.Error)
+ {
+ capabilities.SupportsReadCapacity16 = true;
+ byte[] temp = new byte[8];
+ Array.Copy(buffer, 0, temp, 0, 8);
+ Array.Reverse(temp);
+ capabilities.Blocks = BitConverter.ToUInt64(temp, 0) + 1;
+ capabilities.BlockSize = (uint)((buffer[8] << 24) + (buffer[9] << 16) + (buffer[10] << 8) + buffer[11]);
+ }
+
+ Modes.DecodedMode? decMode = null;
+
+ DicConsole.WriteLine("Querying SCSI MODE SENSE (10)...");
+ sense = dev.ModeSense10(out buffer, out senseBuffer, false, true, ScsiModeSensePageControl.Current, 0x3F,
+ 0x00, dev.Timeout, out _);
+ if(!sense && !dev.Error)
+ {
+ decMode = Modes.DecodeMode10(buffer, dev.ScsiType);
+ if(debug) capabilities.ModeSense10Data = buffer;
+ }
+
+ DicConsole.WriteLine("Querying SCSI MODE SENSE...");
+ sense = dev.ModeSense(out buffer, out senseBuffer, dev.Timeout, out _);
+ if(!sense && !dev.Error)
+ {
+ if(!decMode.HasValue) decMode = Modes.DecodeMode6(buffer, dev.ScsiType);
+ if(debug) capabilities.ModeSense6Data = buffer;
+ }
+
+ if(decMode.HasValue)
+ {
+ capabilities.MediumType = (byte)decMode.Value.Header.MediumType;
+ if(decMode.Value.Header.BlockDescriptors != null && decMode.Value.Header.BlockDescriptors.Length > 0)
+ capabilities.Density = (byte)decMode.Value.Header.BlockDescriptors[0].Density;
+ }
+
+ DicConsole.WriteLine("Trying SCSI READ (6)...");
+ capabilities.SupportsRead6 = !dev.Read6(out buffer, out senseBuffer, 0, capabilities.BlockSize ?? 512,
+ dev.Timeout, out _);
+ DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !capabilities.SupportsRead6);
+ if(debug) DataFile.WriteTo("SCSI Report", "read6", "_debug_" + dev.Model + ".bin", "read results", buffer);
+
+ DicConsole.WriteLine("Trying SCSI READ (10)...");
+ capabilities.SupportsRead10 = !dev.Read10(out buffer, out senseBuffer, 0, false, true, false, false, 0,
+ capabilities.BlockSize ?? 512, 0, 1, dev.Timeout, out _);
+ DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !capabilities.SupportsRead10);
+ if(debug) DataFile.WriteTo("SCSI Report", "read10", "_debug_" + dev.Model + ".bin", "read results", buffer);
+
+ DicConsole.WriteLine("Trying SCSI READ (12)...");
+ capabilities.SupportsRead12 = !dev.Read12(out buffer, out senseBuffer, 0, false, true, false, false, 0,
+ capabilities.BlockSize ?? 512, 0, 1, false, dev.Timeout, out _);
+ DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !capabilities.SupportsRead12);
+ if(debug) DataFile.WriteTo("SCSI Report", "read12", "_debug_" + dev.Model + ".bin", "read results", buffer);
+
+ DicConsole.WriteLine("Trying SCSI READ (16)...");
+ capabilities.SupportsRead16 = !dev.Read16(out buffer, out senseBuffer, 0, false, true, false, 0,
+ capabilities.BlockSize ?? 512, 0, 1, false, dev.Timeout, out _);
+ DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !capabilities.SupportsRead16);
+ if(debug) DataFile.WriteTo("SCSI Report", "read16", "_debug_" + dev.Model + ".bin", "read results", buffer);
+
+ capabilities.LongBlockSize = capabilities.BlockSize;
+ DicConsole.WriteLine("Trying SCSI READ LONG (10)...");
+ sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 0xFFFF, dev.Timeout, out _);
+ if(sense && !dev.Error)
+ {
+ FixedSense? decSense = Sense.DecodeFixed(senseBuffer);
+ if(decSense.HasValue)
+ if(decSense.Value.SenseKey == SenseKeys.IllegalRequest && decSense.Value.ASC == 0x24 &&
+ decSense.Value.ASCQ == 0x00)
+ {
+ capabilities.SupportsReadLong = true;
+ if(decSense.Value.InformationValid && decSense.Value.ILI)
+ capabilities.LongBlockSize = 0xFFFF - (decSense.Value.Information & 0xFFFF);
+ }
+ }
+
+ if(capabilities.SupportsReadLong != true || capabilities.LongBlockSize != capabilities.BlockSize)
+ return capabilities;
+
+ if(capabilities.BlockSize == 512)
+ foreach(int i in new[]
+ {
+ // Long sector sizes for floppies
+ 514,
+ // Long sector sizes for SuperDisk
+ 536, 558,
+ // Long sector sizes for 512-byte magneto-opticals
+ 600, 610, 630
+ })
+ {
+ ushort testSize = (ushort)i;
+ sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, (ushort)i, dev.Timeout, out _);
+ if(sense || dev.Error) continue;
+
+ capabilities.SupportsReadLong = true;
+ capabilities.LongBlockSize = testSize;
+ break;
+ }
+ else if(capabilities.BlockSize == 1024)
+ foreach(int i in new[]
+ {
+ // Long sector sizes for floppies
+ 1026,
+ // Long sector sizes for 1024-byte magneto-opticals
+ 1200
+ })
+ {
+ ushort testSize = (ushort)i;
+ sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, (ushort)i, dev.Timeout, out _);
+ if(sense || dev.Error) continue;
+
+ capabilities.SupportsReadLong = true;
+ capabilities.LongBlockSize = testSize;
+ break;
+ }
+ else if(capabilities.BlockSize == 2048)
+ {
+ sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 2380, dev.Timeout, out _);
+ if(sense || dev.Error) return capabilities;
+
+ capabilities.SupportsReadLong = true;
+ capabilities.LongBlockSize = 2380;
+ }
+ else if(capabilities.BlockSize == 4096)
+ {
+ sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 4760, dev.Timeout, out _);
+ if(sense || dev.Error) return capabilities;
+
+ capabilities.SupportsReadLong = true;
+ capabilities.LongBlockSize = 4760;
+ }
+ else if(capabilities.BlockSize == 8192)
+ {
+ sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 9424, dev.Timeout, out _);
+ if(sense || dev.Error) return capabilities;
+
+ capabilities.SupportsReadLong = true;
+ capabilities.LongBlockSize = 9424;
+ }
+
+ return capabilities;
}
}
}
\ No newline at end of file
diff --git a/DiscImageChef.Core/Devices/Report/SCSI/MMC.cs b/DiscImageChef.Core/Devices/Report/SCSI/MMC.cs
index c94a6e30e..e21800c65 100644
--- a/DiscImageChef.Core/Devices/Report/SCSI/MMC.cs
+++ b/DiscImageChef.Core/Devices/Report/SCSI/MMC.cs
@@ -46,7 +46,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
///
/// Implements creating a report for a SCSI MultiMedia device
///
- static class Mmc
+ public static class Mmc
{
///
/// Fills a SCSI device report with parameters and media tests specific to a MultiMedia device
@@ -55,8 +55,8 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
/// Device report
/// If debug is enabled
/// Decoded MODE PAGE 2Ah
- internal static void Report(Device dev, ref DeviceReportV2 report, bool debug, ref Modes.ModePage_2A? cdromMode,
- string productIdentification)
+ public static void Report(Device dev, ref DeviceReportV2 report, bool debug, Modes.ModePage_2A? cdromMode,
+ string productIdentification)
{
if(report == null) return;
diff --git a/DiscImageChef.Core/Devices/Report/SCSI/SSC.cs b/DiscImageChef.Core/Devices/Report/SCSI/SSC.cs
index ba23b2434..ab6a3f18b 100644
--- a/DiscImageChef.Core/Devices/Report/SCSI/SSC.cs
+++ b/DiscImageChef.Core/Devices/Report/SCSI/SSC.cs
@@ -44,7 +44,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
///
/// Implements creating a report for a SCSI Streaming device
///
- static class Ssc
+ public static class Ssc
{
///
/// Fills a SCSI device report with parameters and media tests specific to a Streaming device
@@ -52,7 +52,7 @@ namespace DiscImageChef.Core.Devices.Report.SCSI
/// Device
/// Device report
/// If debug is enabled
- internal static void Report(Device dev, ref DeviceReportV2 report, bool debug)
+ public static void Report(Device dev, ref DeviceReportV2 report, bool debug)
{
if(report == null) return;
diff --git a/DiscImageChef/Commands/DeviceReport.cs b/DiscImageChef/Commands/DeviceReport.cs
index 8ba0c7adf..6f3e1a321 100644
--- a/DiscImageChef/Commands/DeviceReport.cs
+++ b/DiscImageChef/Commands/DeviceReport.cs
@@ -33,12 +33,16 @@
using System;
using System.Collections.Generic;
using System.IO;
+using System.Threading;
using DiscImageChef.CommonTypes.Metadata;
using DiscImageChef.Console;
-using DiscImageChef.Core.Devices.Report.SCSI;
+using DiscImageChef.Core;
using DiscImageChef.Decoders.ATA;
+using DiscImageChef.Decoders.SCSI;
using DiscImageChef.Devices;
using Newtonsoft.Json;
+using Mmc = DiscImageChef.Core.Devices.Report.SCSI.Mmc;
+using Ssc = DiscImageChef.Core.Devices.Report.SCSI.Ssc;
namespace DiscImageChef.Commands
{
@@ -224,8 +228,7 @@ namespace DiscImageChef.Commands
case DeviceType.SecureDigital:
report.SecureDigital = reporter.MmcSdReport();
break;
- case DeviceType.NVMe:
- throw new NotImplementedException("NVMe devices not yet supported.");
+ case DeviceType.NVMe: throw new NotImplementedException("NVMe devices not yet supported.");
case DeviceType.ATAPI:
DicConsole.WriteLine("Querying ATAPI IDENTIFY...");
@@ -234,13 +237,261 @@ namespace DiscImageChef.Commands
if(!Identify.Decode(buffer).HasValue) return;
Identify.IdentifyDevice? atapiIdNullable = Identify.Decode(buffer);
- if(atapiIdNullable != null) report.ATAPI = new CommonTypes.Metadata.Ata {IdentifyDevice = atapiIdNullable};
+ if(atapiIdNullable != null) report.ATAPI = new Ata {IdentifyDevice = atapiIdNullable};
if(options.Debug) report.ATAPI.Identify = buffer;
goto case DeviceType.SCSI;
case DeviceType.SCSI:
- General.Report(dev, ref report, options.Debug, ref removable);
+ if(!dev.IsUsb && !dev.IsFireWire && dev.IsRemovable)
+ {
+ pressedKey = new ConsoleKeyInfo();
+ while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N)
+ {
+ DicConsole
+ .Write("Is the media removable from the reading/writing elements (flash memories ARE NOT removable)? (Y/N): ");
+ pressedKey = System.Console.ReadKey();
+ DicConsole.WriteLine();
+ }
+
+ removable = pressedKey.Key == ConsoleKey.Y;
+ }
+
+ if(removable)
+ {
+ switch(dev.ScsiType)
+ {
+ case PeripheralDeviceTypes.MultiMediaDevice:
+ dev.AllowMediumRemoval(out buffer, dev.Timeout, out _);
+ dev.EjectTray(out buffer, dev.Timeout, out _);
+ break;
+ case PeripheralDeviceTypes.SequentialAccess:
+ dev.SpcAllowMediumRemoval(out buffer, dev.Timeout, out _);
+ DicConsole.WriteLine("Asking drive to unload tape (can take a few minutes)...");
+ dev.Unload(out buffer, dev.Timeout, out _);
+ break;
+ }
+
+ DicConsole
+ .WriteLine("Please remove any media from the device and press any key when it is out.");
+ System.Console.ReadKey(true);
+ }
+
+ report.SCSI = reporter.ReportScsiInquiry();
+ if(report.SCSI == null) break;
+
+ report.SCSI.EVPDPages = reporter.ReportEvpdPages();
+
+ Modes.ModePage_2A? cdromMode = null;
+
+ reporter.ReportScsiModes(ref report, ref cdromMode);
+
+ string productIdentification = null;
+ if(!string.IsNullOrWhiteSpace(StringHandlers.CToString(report.SCSI.Inquiry?.ProductIdentification)))
+ productIdentification =
+ StringHandlers.CToString(report.SCSI.Inquiry?.ProductIdentification).Trim();
+
+ switch(dev.ScsiType)
+ {
+ case PeripheralDeviceTypes.MultiMediaDevice:
+ Mmc.Report(dev, ref report, options.Debug, cdromMode, productIdentification);
+ break;
+ case PeripheralDeviceTypes.SequentialAccess:
+ Ssc.Report(dev, ref report, options.Debug);
+ break;
+ default:
+ {
+ if(removable)
+ {
+ List mediaTests = new List();
+
+ pressedKey = new ConsoleKeyInfo();
+ while(pressedKey.Key != ConsoleKey.N)
+ {
+ pressedKey = new ConsoleKeyInfo();
+ while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N)
+ {
+ DicConsole.Write("Do you have media that you can insert in the drive? (Y/N): ");
+ pressedKey = System.Console.ReadKey();
+ DicConsole.WriteLine();
+ }
+
+ if(pressedKey.Key != ConsoleKey.Y) continue;
+
+ DicConsole
+ .WriteLine("Please insert it in the drive and press any key when it is ready.");
+ System.Console.ReadKey(true);
+
+ DicConsole.Write("Please write a description of the media type and press enter: ");
+ string mediumTypeName = System.Console.ReadLine();
+ DicConsole.Write("Please write the media manufacturer and press enter: ");
+ string manufacturer = System.Console.ReadLine();
+ DicConsole.Write("Please write the media model and press enter: ");
+ string model = System.Console.ReadLine();
+
+ bool mediaIsRecognized = true;
+
+ bool sense = dev.ScsiTestUnitReady(out byte[] senseBuffer, dev.Timeout, out _);
+ if(sense)
+ {
+ FixedSense? decSense = Sense.DecodeFixed(senseBuffer);
+ if(decSense.HasValue)
+ if(decSense.Value.ASC == 0x3A)
+ {
+ int leftRetries = 20;
+ while(leftRetries > 0)
+ {
+ DicConsole.Write("\rWaiting for drive to become ready");
+ Thread.Sleep(2000);
+ sense = dev.ScsiTestUnitReady(out senseBuffer, dev.Timeout, out _);
+ if(!sense) break;
+
+ leftRetries--;
+ }
+
+ mediaIsRecognized &= !sense;
+ }
+ else if(decSense.Value.ASC == 0x04 && decSense.Value.ASCQ == 0x01)
+ {
+ int leftRetries = 20;
+ while(leftRetries > 0)
+ {
+ DicConsole.Write("\rWaiting for drive to become ready");
+ Thread.Sleep(2000);
+ sense = dev.ScsiTestUnitReady(out senseBuffer, dev.Timeout, out _);
+ if(!sense) break;
+
+ leftRetries--;
+ }
+
+ mediaIsRecognized &= !sense;
+ }
+ else mediaIsRecognized = false;
+ else mediaIsRecognized = false;
+ }
+
+ TestedMedia mediaTest = new TestedMedia();
+
+ if(mediaIsRecognized)
+ {
+ mediaTest = reporter.ReportScsiMedia();
+
+ if(mediaTest.SupportsReadLong == true &&
+ mediaTest.LongBlockSize == mediaTest.BlockSize)
+ {
+ pressedKey = new ConsoleKeyInfo();
+ while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N)
+ {
+ DicConsole
+ .Write("Drive supports SCSI READ LONG but I cannot find the correct size. Do you want me to try? (This can take hours) (Y/N): ");
+ pressedKey = System.Console.ReadKey();
+ DicConsole.WriteLine();
+ }
+
+ if(pressedKey.Key == ConsoleKey.Y)
+ {
+ for(ushort i = (ushort)mediaTest.BlockSize;; i++)
+ {
+ DicConsole
+ .Write("\rTrying to READ LONG with a size of {0} bytes...", i);
+ sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0,
+ i, dev.Timeout, out _);
+ if(!sense)
+ {
+ mediaTest.LongBlockSize = i;
+ break;
+ }
+
+ if(i == ushort.MaxValue) break;
+ }
+
+ DicConsole.WriteLine();
+ }
+ }
+
+ if(options.Debug && mediaTest.SupportsReadLong == true &&
+ mediaTest.LongBlockSize != mediaTest.BlockSize)
+ {
+ sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0,
+ (ushort)mediaTest.LongBlockSize, dev.Timeout, out _);
+ if(!sense)
+ DataFile.WriteTo("SCSI Report", "readlong10",
+ "_debug_" + mediaTest.MediumTypeName + ".bin",
+ "read results", buffer);
+ }
+ }
+
+ mediaTest.MediumTypeName = mediumTypeName;
+ mediaTest.Manufacturer = manufacturer;
+ mediaTest.Model = model;
+
+ mediaTests.Add(mediaTest);
+ }
+
+ report.SCSI.RemovableMedias = mediaTests.ToArray();
+ }
+ else
+ {
+ report.SCSI.ReadCapabilities = reporter.ReportScsi();
+
+ if(report.SCSI.ReadCapabilities.SupportsReadLong == true &&
+ report.SCSI.ReadCapabilities.LongBlockSize ==
+ report.SCSI.ReadCapabilities.BlockSize)
+ {
+ pressedKey = new ConsoleKeyInfo();
+ while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N)
+ {
+ DicConsole
+ .Write("Drive supports SCSI READ LONG but I cannot find the correct size. Do you want me to try? (This can take hours) (Y/N): ");
+ pressedKey = System.Console.ReadKey();
+ DicConsole.WriteLine();
+ }
+
+ if(pressedKey.Key == ConsoleKey.Y)
+ {
+ for(ushort i = (ushort)report.SCSI.ReadCapabilities.BlockSize;; i++)
+ {
+ DicConsole.Write("\rTrying to READ LONG with a size of {0} bytes...", i);
+ bool sense = dev.ReadLong10(out buffer, out byte[] senseBuffer, false,
+ false, 0, i, dev.Timeout, out _);
+ if(!sense)
+ {
+ if(options.Debug)
+ {
+ FileStream bingo =
+ new FileStream($"{dev.Model}_readlong.bin", FileMode.Create);
+ bingo.Write(buffer, 0, buffer.Length);
+ bingo.Close();
+ }
+
+ report.SCSI.ReadCapabilities.LongBlockSize = i;
+ break;
+ }
+
+ if(i == ushort.MaxValue) break;
+ }
+
+ DicConsole.WriteLine();
+ }
+ }
+
+ if(options.Debug && report.SCSI.ReadCapabilities.SupportsReadLong == true &&
+ report.SCSI.ReadCapabilities.LongBlockSize !=
+ report.SCSI.ReadCapabilities.BlockSize)
+ {
+ bool sense = dev.ReadLong10(out buffer, out byte[] senseBuffer, false, false, 0,
+ (ushort)report.SCSI.ReadCapabilities.LongBlockSize,
+ dev.Timeout, out _);
+ if(!sense)
+ DataFile.WriteTo("SCSI Report", "readlong10", "_debug_" + dev.Model + ".bin",
+ "read results", buffer);
+ }
+ }
+
+ break;
+ }
+ }
+
break;
default: throw new NotSupportedException("Unknown device type.");
}