2017-05-28 21:01:17 +01:00
|
|
|
|
// /***************************************************************************
|
|
|
|
|
|
// The Disc Image Chef
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
|
//
|
2017-12-19 03:50:57 +00:00
|
|
|
|
// Filename : General.cs
|
|
|
|
|
|
// Author(s) : Natalia Portillo <claunia@claunia.com>
|
2017-05-28 21:01:17 +01:00
|
|
|
|
//
|
2017-12-19 03:50:57 +00:00
|
|
|
|
// Component : Core algorithms.
|
2017-05-28 21:01:17 +01:00
|
|
|
|
//
|
|
|
|
|
|
// --[ Description ] ----------------------------------------------------------
|
|
|
|
|
|
//
|
2017-12-19 03:50:57 +00:00
|
|
|
|
// Creates reports from SCSI devices.
|
2017-05-28 21:01:17 +01:00
|
|
|
|
//
|
|
|
|
|
|
// --[ License ] --------------------------------------------------------------
|
|
|
|
|
|
//
|
|
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
|
|
|
|
// it under the terms of the GNU General Public License as
|
|
|
|
|
|
// published by the Free Software Foundation, either version 3 of the
|
|
|
|
|
|
// License, or (at your option) any later version.
|
|
|
|
|
|
//
|
|
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
|
// GNU General Public License for more details.
|
|
|
|
|
|
//
|
|
|
|
|
|
// You should have received a copy of the GNU General Public License
|
|
|
|
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
//
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
2017-12-19 03:50:57 +00:00
|
|
|
|
// Copyright © 2011-2018 Natalia Portillo
|
2017-05-28 21:01:17 +01:00
|
|
|
|
// ****************************************************************************/
|
2017-12-19 03:50:57 +00:00
|
|
|
|
|
2017-05-28 21:01:17 +01:00
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using System.IO;
|
2017-12-21 07:08:26 +00:00
|
|
|
|
using System.Linq;
|
2017-12-21 14:30:38 +00:00
|
|
|
|
using System.Threading;
|
2017-05-28 21:01:17 +01:00
|
|
|
|
using DiscImageChef.Console;
|
2017-12-21 14:30:38 +00:00
|
|
|
|
using DiscImageChef.Decoders.SCSI;
|
2017-05-28 21:01:17 +01:00
|
|
|
|
using DiscImageChef.Devices;
|
|
|
|
|
|
using DiscImageChef.Metadata;
|
|
|
|
|
|
|
|
|
|
|
|
namespace DiscImageChef.Core.Devices.Report.SCSI
|
|
|
|
|
|
{
|
2017-12-23 01:46:08 +00:00
|
|
|
|
/// <summary>
|
2017-12-23 17:41:23 +00:00
|
|
|
|
/// Implements creating a report of SCSI and ATAPI devices
|
2017-12-23 01:46:08 +00:00
|
|
|
|
/// </summary>
|
2017-05-28 21:01:17 +01:00
|
|
|
|
public static class General
|
|
|
|
|
|
{
|
2017-12-23 01:46:08 +00:00
|
|
|
|
/// <summary>
|
2017-12-23 17:41:23 +00:00
|
|
|
|
/// Creates a report of SCSI and ATAPI devices, and if appropiate calls the report creators for MultiMedia and
|
|
|
|
|
|
/// Streaming devices
|
2017-12-23 01:46:08 +00:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="dev">Device</param>
|
|
|
|
|
|
/// <param name="report">Device report</param>
|
|
|
|
|
|
/// <param name="debug">If debug is enabled</param>
|
|
|
|
|
|
/// <param name="removable">If device is removable</param>
|
2017-05-28 21:01:17 +01:00
|
|
|
|
public static void Report(Device dev, ref DeviceReport report, bool debug, ref bool removable)
|
|
|
|
|
|
{
|
2017-12-19 20:33:03 +00:00
|
|
|
|
if(report == null) return;
|
2017-05-28 21:01:17 +01:00
|
|
|
|
|
|
|
|
|
|
bool sense;
|
2017-12-21 23:00:30 +00:00
|
|
|
|
const uint TIMEOUT = 5;
|
2017-05-28 21:01:17 +01:00
|
|
|
|
ConsoleKeyInfo pressedKey;
|
|
|
|
|
|
|
2017-12-20 17:15:26 +00:00
|
|
|
|
if(dev.IsUsb) Usb.Report(dev, ref report, debug, ref removable);
|
2017-05-28 21:01:17 +01:00
|
|
|
|
|
2017-12-21 23:00:30 +00:00
|
|
|
|
if(dev.IsFireWire) FireWire.Report(dev, ref report, ref removable);
|
2017-05-28 21:01:17 +01:00
|
|
|
|
|
2017-12-21 23:00:30 +00:00
|
|
|
|
if(dev.IsPcmcia) Pcmcia.Report(dev, ref report);
|
2017-06-03 01:26:43 +01:00
|
|
|
|
|
2017-12-20 17:15:26 +00:00
|
|
|
|
if(!dev.IsUsb && !dev.IsFireWire && dev.IsRemovable)
|
2017-05-28 21:01:17 +01:00
|
|
|
|
{
|
|
|
|
|
|
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;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-12-23 01:46:08 +00:00
|
|
|
|
if(dev.Type == DeviceType.ATAPI) Atapi.Report(dev, ref report, debug);
|
2017-05-28 21:01:17 +01:00
|
|
|
|
|
|
|
|
|
|
DicConsole.WriteLine("Querying SCSI INQUIRY...");
|
2017-12-21 23:00:30 +00:00
|
|
|
|
sense = dev.ScsiInquiry(out byte[] buffer, out byte[] senseBuffer);
|
2017-05-28 21:01:17 +01:00
|
|
|
|
|
|
|
|
|
|
report.SCSI = new scsiType();
|
|
|
|
|
|
|
2017-12-21 14:30:38 +00:00
|
|
|
|
if(!sense && Inquiry.Decode(buffer).HasValue)
|
2017-05-28 21:01:17 +01:00
|
|
|
|
{
|
2017-12-21 14:30:38 +00:00
|
|
|
|
Inquiry.SCSIInquiry inq = Inquiry.Decode(buffer).Value;
|
2017-05-28 21:01:17 +01:00
|
|
|
|
|
|
|
|
|
|
List<ushort> versionDescriptors = new List<ushort>();
|
|
|
|
|
|
report.SCSI.Inquiry = new scsiInquiryType();
|
|
|
|
|
|
|
|
|
|
|
|
if(inq.DeviceTypeModifier != 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
report.SCSI.Inquiry.DeviceTypeModifier = inq.DeviceTypeModifier;
|
|
|
|
|
|
report.SCSI.Inquiry.DeviceTypeModifierSpecified = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
if(inq.ISOVersion != 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
report.SCSI.Inquiry.ISOVersion = inq.ISOVersion;
|
|
|
|
|
|
report.SCSI.Inquiry.ISOVersionSpecified = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
if(inq.ECMAVersion != 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
report.SCSI.Inquiry.ECMAVersion = inq.ECMAVersion;
|
|
|
|
|
|
report.SCSI.Inquiry.ECMAVersionSpecified = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
if(inq.ANSIVersion != 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
report.SCSI.Inquiry.ANSIVersion = inq.ANSIVersion;
|
|
|
|
|
|
report.SCSI.Inquiry.ANSIVersionSpecified = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
if(inq.ResponseDataFormat != 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
report.SCSI.Inquiry.ResponseDataFormat = inq.ResponseDataFormat;
|
|
|
|
|
|
report.SCSI.Inquiry.ResponseDataFormatSpecified = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
if(!string.IsNullOrWhiteSpace(StringHandlers.CToString(inq.VendorIdentification)))
|
|
|
|
|
|
{
|
2017-12-19 20:33:03 +00:00
|
|
|
|
report.SCSI.Inquiry.VendorIdentification =
|
|
|
|
|
|
StringHandlers.CToString(inq.VendorIdentification).Trim();
|
2017-05-28 21:01:17 +01:00
|
|
|
|
if(!string.IsNullOrWhiteSpace(report.SCSI.Inquiry.VendorIdentification))
|
|
|
|
|
|
report.SCSI.Inquiry.VendorIdentificationSpecified = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
if(!string.IsNullOrWhiteSpace(StringHandlers.CToString(inq.ProductIdentification)))
|
|
|
|
|
|
{
|
2017-12-19 20:33:03 +00:00
|
|
|
|
report.SCSI.Inquiry.ProductIdentification =
|
|
|
|
|
|
StringHandlers.CToString(inq.ProductIdentification).Trim();
|
2017-05-28 21:01:17 +01:00
|
|
|
|
if(!string.IsNullOrWhiteSpace(report.SCSI.Inquiry.ProductIdentification))
|
|
|
|
|
|
report.SCSI.Inquiry.ProductIdentificationSpecified = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
if(!string.IsNullOrWhiteSpace(StringHandlers.CToString(inq.ProductRevisionLevel)))
|
|
|
|
|
|
{
|
2017-12-19 20:33:03 +00:00
|
|
|
|
report.SCSI.Inquiry.ProductRevisionLevel =
|
|
|
|
|
|
StringHandlers.CToString(inq.ProductRevisionLevel).Trim();
|
2017-05-28 21:01:17 +01:00
|
|
|
|
if(!string.IsNullOrWhiteSpace(report.SCSI.Inquiry.ProductRevisionLevel))
|
|
|
|
|
|
report.SCSI.Inquiry.ProductRevisionLevelSpecified = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
if(inq.VersionDescriptors != null)
|
|
|
|
|
|
{
|
2017-12-21 07:08:26 +00:00
|
|
|
|
versionDescriptors.AddRange(inq.VersionDescriptors.Where(descriptor => descriptor != 0));
|
2017-05-28 21:01:17 +01:00
|
|
|
|
|
|
|
|
|
|
if(versionDescriptors.Count > 0)
|
|
|
|
|
|
report.SCSI.Inquiry.VersionDescriptors = versionDescriptors.ToArray();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-12-21 14:30:38 +00:00
|
|
|
|
report.SCSI.Inquiry.PeripheralQualifier = (PeripheralQualifiers)inq.PeripheralQualifier;
|
2017-12-23 17:41:23 +00:00
|
|
|
|
report.SCSI.Inquiry.PeripheralDeviceType = (PeripheralDeviceTypes)inq.PeripheralDeviceType;
|
2017-12-21 14:30:38 +00:00
|
|
|
|
report.SCSI.Inquiry.AsymmetricalLUNAccess = (TGPSValues)inq.TPGS;
|
|
|
|
|
|
report.SCSI.Inquiry.SPIClocking = (SPIClocking)inq.Clocking;
|
2017-05-28 21:01:17 +01:00
|
|
|
|
|
|
|
|
|
|
report.SCSI.Inquiry.AccessControlCoordinator = inq.ACC;
|
|
|
|
|
|
report.SCSI.Inquiry.ACKRequests = inq.ACKREQQ;
|
|
|
|
|
|
report.SCSI.Inquiry.AERCSupported = inq.AERC;
|
|
|
|
|
|
report.SCSI.Inquiry.Address16 = inq.Addr16;
|
|
|
|
|
|
report.SCSI.Inquiry.Address32 = inq.Addr32;
|
|
|
|
|
|
report.SCSI.Inquiry.BasicQueueing = inq.BQue;
|
|
|
|
|
|
report.SCSI.Inquiry.EnclosureServices = inq.EncServ;
|
|
|
|
|
|
report.SCSI.Inquiry.HierarchicalLUN = inq.HiSup;
|
|
|
|
|
|
report.SCSI.Inquiry.IUS = inq.IUS;
|
|
|
|
|
|
report.SCSI.Inquiry.LinkedCommands = inq.Linked;
|
|
|
|
|
|
report.SCSI.Inquiry.MediumChanger = inq.MChngr;
|
|
|
|
|
|
report.SCSI.Inquiry.MultiPortDevice = inq.MultiP;
|
|
|
|
|
|
report.SCSI.Inquiry.NormalACA = inq.NormACA;
|
|
|
|
|
|
report.SCSI.Inquiry.Protection = inq.Protect;
|
|
|
|
|
|
report.SCSI.Inquiry.QAS = inq.QAS;
|
|
|
|
|
|
report.SCSI.Inquiry.RelativeAddressing = inq.RelAddr;
|
|
|
|
|
|
report.SCSI.Inquiry.Removable = inq.RMB;
|
|
|
|
|
|
report.SCSI.Inquiry.TaggedCommandQueue = inq.CmdQue;
|
|
|
|
|
|
report.SCSI.Inquiry.TerminateTaskSupported = inq.TrmTsk;
|
|
|
|
|
|
report.SCSI.Inquiry.ThirdPartyCopy = inq.ThreePC;
|
|
|
|
|
|
report.SCSI.Inquiry.TranferDisable = inq.TranDis;
|
|
|
|
|
|
report.SCSI.Inquiry.SoftReset = inq.SftRe;
|
|
|
|
|
|
report.SCSI.Inquiry.StorageArrayController = inq.SCCS;
|
|
|
|
|
|
report.SCSI.Inquiry.SyncTransfer = inq.Sync;
|
|
|
|
|
|
report.SCSI.Inquiry.WideBus16 = inq.WBus16;
|
|
|
|
|
|
report.SCSI.Inquiry.WideBus32 = inq.WBus32;
|
2017-09-05 15:47:36 +01:00
|
|
|
|
|
2017-12-19 20:33:03 +00:00
|
|
|
|
if(debug) report.SCSI.Inquiry.Data = buffer;
|
2017-05-28 21:01:17 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DicConsole.WriteLine("Querying list of SCSI EVPDs...");
|
|
|
|
|
|
sense = dev.ScsiInquiry(out buffer, out senseBuffer, 0x00);
|
|
|
|
|
|
|
|
|
|
|
|
if(!sense)
|
|
|
|
|
|
{
|
2017-12-21 14:30:38 +00:00
|
|
|
|
byte[] evpdPages = EVPD.DecodePage00(buffer);
|
2017-05-28 21:01:17 +01:00
|
|
|
|
if(evpdPages != null && evpdPages.Length > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
List<pageType> evpds = new List<pageType>();
|
2017-12-23 17:41:23 +00:00
|
|
|
|
foreach(byte page in evpdPages.Where(page => page != 0x80))
|
|
|
|
|
|
{
|
2017-12-21 07:08:26 +00:00
|
|
|
|
DicConsole.WriteLine("Querying SCSI EVPD {0:X2}h...", page);
|
|
|
|
|
|
sense = dev.ScsiInquiry(out buffer, out senseBuffer, page);
|
|
|
|
|
|
if(sense) continue;
|
|
|
|
|
|
|
2017-12-21 23:00:30 +00:00
|
|
|
|
pageType evpd = new pageType {page = page, value = buffer};
|
2017-12-21 07:08:26 +00:00
|
|
|
|
evpds.Add(evpd);
|
|
|
|
|
|
}
|
2017-12-19 20:33:03 +00:00
|
|
|
|
|
|
|
|
|
|
if(evpds.Count > 0) report.SCSI.EVPDPages = evpds.ToArray();
|
2017-05-28 21:01:17 +01:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if(removable)
|
|
|
|
|
|
{
|
2017-12-23 17:41:23 +00:00
|
|
|
|
switch(dev.ScsiType)
|
|
|
|
|
|
{
|
2017-12-21 14:30:38 +00:00
|
|
|
|
case PeripheralDeviceTypes.MultiMediaDevice:
|
2017-12-21 23:00:30 +00:00
|
|
|
|
dev.AllowMediumRemoval(out senseBuffer, TIMEOUT, out _);
|
|
|
|
|
|
dev.EjectTray(out senseBuffer, TIMEOUT, out _);
|
2017-12-21 04:43:29 +00:00
|
|
|
|
break;
|
2017-12-21 14:30:38 +00:00
|
|
|
|
case PeripheralDeviceTypes.SequentialAccess:
|
2017-12-21 23:00:30 +00:00
|
|
|
|
dev.SpcAllowMediumRemoval(out senseBuffer, TIMEOUT, out _);
|
2017-12-21 04:43:29 +00:00
|
|
|
|
DicConsole.WriteLine("Asking drive to unload tape (can take a few minutes)...");
|
2017-12-21 23:00:30 +00:00
|
|
|
|
dev.Unload(out senseBuffer, TIMEOUT, out _);
|
2017-12-21 04:43:29 +00:00
|
|
|
|
break;
|
2017-05-28 21:01:17 +01:00
|
|
|
|
}
|
2017-12-21 23:00:30 +00:00
|
|
|
|
|
2017-05-28 21:01:17 +01:00
|
|
|
|
DicConsole.WriteLine("Please remove any media from the device and press any key when it is out.");
|
|
|
|
|
|
System.Console.ReadKey(true);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-12-21 14:30:38 +00:00
|
|
|
|
Modes.DecodedMode? decMode = null;
|
|
|
|
|
|
PeripheralDeviceTypes devType = dev.ScsiType;
|
2017-05-28 21:01:17 +01:00
|
|
|
|
|
|
|
|
|
|
DicConsole.WriteLine("Querying all mode pages and subpages using SCSI MODE SENSE (10)...");
|
2017-12-19 20:33:03 +00:00
|
|
|
|
sense = dev.ModeSense10(out byte[] mode10Buffer, out senseBuffer, false, true,
|
2017-12-21 23:00:30 +00:00
|
|
|
|
ScsiModeSensePageControl.Default, 0x3F, 0xFF, TIMEOUT, out _);
|
2017-05-28 21:01:17 +01:00
|
|
|
|
if(sense || dev.Error)
|
|
|
|
|
|
{
|
|
|
|
|
|
DicConsole.WriteLine("Querying all mode pages using SCSI MODE SENSE (10)...");
|
2017-12-19 20:33:03 +00:00
|
|
|
|
sense = dev.ModeSense10(out mode10Buffer, out senseBuffer, false, true,
|
2017-12-21 23:00:30 +00:00
|
|
|
|
ScsiModeSensePageControl.Default, 0x3F, 0x00, TIMEOUT, out _);
|
2017-12-16 23:18:41 +00:00
|
|
|
|
if(!sense && !dev.Error)
|
2017-05-28 21:01:17 +01:00
|
|
|
|
{
|
|
|
|
|
|
report.SCSI.SupportsModeSense10 = true;
|
|
|
|
|
|
report.SCSI.SupportsModeSubpages = false;
|
2017-12-21 14:30:38 +00:00
|
|
|
|
decMode = Modes.DecodeMode10(mode10Buffer, devType);
|
2017-05-28 21:01:17 +01:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
report.SCSI.SupportsModeSense10 = true;
|
|
|
|
|
|
report.SCSI.SupportsModeSubpages = true;
|
2017-12-21 14:30:38 +00:00
|
|
|
|
decMode = Modes.DecodeMode10(mode10Buffer, devType);
|
2017-05-28 21:01:17 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DicConsole.WriteLine("Querying all mode pages and subpages using SCSI MODE SENSE (6)...");
|
2017-12-19 20:33:03 +00:00
|
|
|
|
sense = dev.ModeSense6(out byte[] mode6Buffer, out senseBuffer, false, ScsiModeSensePageControl.Default,
|
2017-12-21 23:00:30 +00:00
|
|
|
|
0x3F, 0xFF, TIMEOUT, out _);
|
2017-05-28 21:01:17 +01:00
|
|
|
|
if(sense || dev.Error)
|
|
|
|
|
|
{
|
|
|
|
|
|
DicConsole.WriteLine("Querying all mode pages using SCSI MODE SENSE (6)...");
|
2017-12-19 20:33:03 +00:00
|
|
|
|
sense = dev.ModeSense6(out mode6Buffer, out senseBuffer, false, ScsiModeSensePageControl.Default, 0x3F,
|
2017-12-21 23:00:30 +00:00
|
|
|
|
0x00, TIMEOUT, out _);
|
2017-05-28 21:01:17 +01:00
|
|
|
|
if(sense || dev.Error)
|
|
|
|
|
|
{
|
|
|
|
|
|
DicConsole.WriteLine("Querying SCSI MODE SENSE (6)...");
|
2017-12-21 23:00:30 +00:00
|
|
|
|
sense = dev.ModeSense(out mode6Buffer, out senseBuffer, TIMEOUT, out _);
|
2017-05-28 21:01:17 +01:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2017-12-19 20:33:03 +00:00
|
|
|
|
else report.SCSI.SupportsModeSubpages = true;
|
2017-05-28 21:01:17 +01:00
|
|
|
|
|
2017-12-23 17:41:23 +00:00
|
|
|
|
if(!sense && !dev.Error && !decMode.HasValue) decMode = Modes.DecodeMode6(mode6Buffer, devType);
|
2017-05-28 21:01:17 +01:00
|
|
|
|
|
2017-12-20 17:26:28 +00:00
|
|
|
|
report.SCSI.SupportsModeSense6 |= !sense && !dev.Error;
|
2017-05-28 21:01:17 +01:00
|
|
|
|
|
2017-12-21 14:30:38 +00:00
|
|
|
|
Modes.ModePage_2A? cdromMode = null;
|
2017-05-28 21:01:17 +01:00
|
|
|
|
|
2017-12-19 20:33:03 +00:00
|
|
|
|
if(debug && report.SCSI.SupportsModeSense6) report.SCSI.ModeSense6Data = mode6Buffer;
|
|
|
|
|
|
if(debug && report.SCSI.SupportsModeSense10) report.SCSI.ModeSense10Data = mode10Buffer;
|
2017-09-05 15:47:36 +01:00
|
|
|
|
|
2017-05-28 21:01:17 +01:00
|
|
|
|
if(decMode.HasValue)
|
|
|
|
|
|
{
|
2017-12-21 23:00:30 +00:00
|
|
|
|
report.SCSI.ModeSense = new modeType
|
|
|
|
|
|
{
|
|
|
|
|
|
BlankCheckEnabled = decMode.Value.Header.EBC,
|
|
|
|
|
|
DPOandFUA = decMode.Value.Header.DPOFUA,
|
|
|
|
|
|
WriteProtected = decMode.Value.Header.WriteProtected
|
|
|
|
|
|
};
|
2017-05-28 21:01:17 +01:00
|
|
|
|
|
|
|
|
|
|
if(decMode.Value.Header.BufferedMode > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
report.SCSI.ModeSense.BufferedMode = decMode.Value.Header.BufferedMode;
|
|
|
|
|
|
report.SCSI.ModeSense.BufferedModeSpecified = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if(decMode.Value.Header.Speed > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
report.SCSI.ModeSense.Speed = decMode.Value.Header.Speed;
|
|
|
|
|
|
report.SCSI.ModeSense.SpeedSpecified = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if(decMode.Value.Pages != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
List<modePageType> modePages = new List<modePageType>();
|
2017-12-21 14:30:38 +00:00
|
|
|
|
foreach(Modes.ModePage page in decMode.Value.Pages)
|
2017-05-28 21:01:17 +01:00
|
|
|
|
{
|
2017-12-21 23:00:30 +00:00
|
|
|
|
modePageType modePage = new modePageType
|
|
|
|
|
|
{
|
|
|
|
|
|
page = page.Page,
|
|
|
|
|
|
subpage = page.Subpage,
|
|
|
|
|
|
value = page.PageResponse
|
|
|
|
|
|
};
|
2017-05-28 21:01:17 +01:00
|
|
|
|
modePages.Add(modePage);
|
|
|
|
|
|
|
2017-12-23 17:41:23 +00:00
|
|
|
|
if(modePage.page == 0x2A && modePage.subpage == 0x00)
|
|
|
|
|
|
cdromMode = Modes.DecodeModePage_2A(page.PageResponse);
|
2017-05-28 21:01:17 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2017-12-19 20:33:03 +00:00
|
|
|
|
if(modePages.Count > 0) report.SCSI.ModeSense.ModePages = modePages.ToArray();
|
2017-05-28 21:01:17 +01:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-12-23 17:41:23 +00:00
|
|
|
|
switch(dev.ScsiType)
|
|
|
|
|
|
{
|
|
|
|
|
|
case PeripheralDeviceTypes.MultiMediaDevice:
|
|
|
|
|
|
Mmc.Report(dev, ref report, debug, ref cdromMode);
|
2017-12-21 04:43:29 +00:00
|
|
|
|
break;
|
2017-12-23 17:41:23 +00:00
|
|
|
|
case PeripheralDeviceTypes.SequentialAccess:
|
|
|
|
|
|
Ssc.Report(dev, ref report, debug);
|
2017-12-21 04:43:29 +00:00
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
|
|
if(removable)
|
2017-05-28 21:01:17 +01:00
|
|
|
|
{
|
2017-12-21 04:43:29 +00:00
|
|
|
|
List<testedMediaType> mediaTests = new List<testedMediaType>();
|
|
|
|
|
|
|
2017-05-28 21:01:17 +01:00
|
|
|
|
pressedKey = new ConsoleKeyInfo();
|
2017-12-21 04:43:29 +00:00
|
|
|
|
while(pressedKey.Key != ConsoleKey.N)
|
2017-05-28 21:01:17 +01:00
|
|
|
|
{
|
2017-12-21 04:43:29 +00:00
|
|
|
|
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();
|
|
|
|
|
|
}
|
2017-05-28 21:01:17 +01:00
|
|
|
|
|
2017-12-21 06:06:19 +00:00
|
|
|
|
if(pressedKey.Key != ConsoleKey.Y) continue;
|
2017-12-21 04:43:29 +00:00
|
|
|
|
|
2017-12-21 06:06:19 +00:00
|
|
|
|
DicConsole.WriteLine("Please insert it in the drive and press any key when it is ready.");
|
|
|
|
|
|
System.Console.ReadKey(true);
|
2017-12-21 04:43:29 +00:00
|
|
|
|
|
2017-12-21 06:06:19 +00:00
|
|
|
|
testedMediaType mediaTest = new testedMediaType();
|
|
|
|
|
|
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();
|
2017-12-21 04:43:29 +00:00
|
|
|
|
|
2017-12-21 06:06:19 +00:00
|
|
|
|
mediaTest.ManufacturerSpecified = true;
|
|
|
|
|
|
mediaTest.ModelSpecified = true;
|
|
|
|
|
|
mediaTest.MediaIsRecognized = true;
|
2017-05-28 21:01:17 +01:00
|
|
|
|
|
2017-12-21 23:00:30 +00:00
|
|
|
|
sense = dev.ScsiTestUnitReady(out senseBuffer, TIMEOUT, out _);
|
2017-12-21 06:06:19 +00:00
|
|
|
|
if(sense)
|
|
|
|
|
|
{
|
2017-12-21 14:30:38 +00:00
|
|
|
|
FixedSense? decSense = Sense.DecodeFixed(senseBuffer);
|
2017-12-21 06:06:19 +00:00
|
|
|
|
if(decSense.HasValue)
|
|
|
|
|
|
if(decSense.Value.ASC == 0x3A)
|
|
|
|
|
|
{
|
|
|
|
|
|
int leftRetries = 20;
|
|
|
|
|
|
while(leftRetries > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
DicConsole.Write("\rWaiting for drive to become ready");
|
2017-12-21 14:30:38 +00:00
|
|
|
|
Thread.Sleep(2000);
|
2017-12-21 23:00:30 +00:00
|
|
|
|
sense = dev.ScsiTestUnitReady(out senseBuffer, TIMEOUT, out _);
|
2017-12-21 06:06:19 +00:00
|
|
|
|
if(!sense) break;
|
2017-12-21 04:43:29 +00:00
|
|
|
|
|
2017-12-21 06:06:19 +00:00
|
|
|
|
leftRetries--;
|
|
|
|
|
|
}
|
2017-05-28 21:01:17 +01:00
|
|
|
|
|
2017-12-21 06:06:19 +00:00
|
|
|
|
mediaTest.MediaIsRecognized &= !sense;
|
2017-05-28 21:01:17 +01:00
|
|
|
|
}
|
2017-12-21 06:06:19 +00:00
|
|
|
|
else if(decSense.Value.ASC == 0x04 && decSense.Value.ASCQ == 0x01)
|
2017-05-28 21:01:17 +01:00
|
|
|
|
{
|
2017-12-21 06:06:19 +00:00
|
|
|
|
int leftRetries = 20;
|
|
|
|
|
|
while(leftRetries > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
DicConsole.Write("\rWaiting for drive to become ready");
|
2017-12-21 14:30:38 +00:00
|
|
|
|
Thread.Sleep(2000);
|
2017-12-21 23:00:30 +00:00
|
|
|
|
sense = dev.ScsiTestUnitReady(out senseBuffer, TIMEOUT, out _);
|
2017-12-21 06:06:19 +00:00
|
|
|
|
if(!sense) break;
|
2017-05-28 21:01:17 +01:00
|
|
|
|
|
2017-12-21 06:06:19 +00:00
|
|
|
|
leftRetries--;
|
|
|
|
|
|
}
|
2017-05-28 21:01:17 +01:00
|
|
|
|
|
2017-12-21 06:06:19 +00:00
|
|
|
|
mediaTest.MediaIsRecognized &= !sense;
|
2017-05-28 21:01:17 +01:00
|
|
|
|
}
|
2017-12-21 06:06:19 +00:00
|
|
|
|
else mediaTest.MediaIsRecognized = false;
|
|
|
|
|
|
else mediaTest.MediaIsRecognized = false;
|
|
|
|
|
|
}
|
2017-05-28 21:01:17 +01:00
|
|
|
|
|
2017-12-21 06:06:19 +00:00
|
|
|
|
if(mediaTest.MediaIsRecognized)
|
|
|
|
|
|
{
|
|
|
|
|
|
mediaTest.SupportsReadCapacitySpecified = true;
|
|
|
|
|
|
mediaTest.SupportsReadCapacity16Specified = true;
|
2017-05-28 21:01:17 +01:00
|
|
|
|
|
2017-12-21 06:06:19 +00:00
|
|
|
|
DicConsole.WriteLine("Querying SCSI READ CAPACITY...");
|
2017-12-21 23:00:30 +00:00
|
|
|
|
sense = dev.ReadCapacity(out buffer, out senseBuffer, TIMEOUT, out _);
|
2017-12-21 06:06:19 +00:00
|
|
|
|
if(!sense && !dev.Error)
|
|
|
|
|
|
{
|
|
|
|
|
|
mediaTest.SupportsReadCapacity = true;
|
|
|
|
|
|
mediaTest.Blocks =
|
2017-12-23 17:41:23 +00:00
|
|
|
|
(ulong)((buffer[0] << 24) + (buffer[1] << 16) + (buffer[2] << 8) + buffer[3]) +
|
|
|
|
|
|
1;
|
2017-12-21 06:06:19 +00:00
|
|
|
|
mediaTest.BlockSize =
|
|
|
|
|
|
(uint)((buffer[4] << 24) + (buffer[5] << 16) + (buffer[6] << 8) + buffer[7]);
|
|
|
|
|
|
mediaTest.BlocksSpecified = true;
|
|
|
|
|
|
mediaTest.BlockSizeSpecified = true;
|
|
|
|
|
|
}
|
2017-05-28 21:01:17 +01:00
|
|
|
|
|
2017-12-21 06:06:19 +00:00
|
|
|
|
DicConsole.WriteLine("Querying SCSI READ CAPACITY (16)...");
|
2017-12-21 23:00:30 +00:00
|
|
|
|
sense = dev.ReadCapacity16(out buffer, out buffer, TIMEOUT, out _);
|
2017-12-21 06:06:19 +00:00
|
|
|
|
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 =
|
2017-12-23 17:41:23 +00:00
|
|
|
|
(uint)((buffer[8] << 24) + (buffer[9] << 16) + (buffer[10] << 8) + buffer[11]);
|
2017-12-21 06:06:19 +00:00
|
|
|
|
mediaTest.BlocksSpecified = true;
|
|
|
|
|
|
mediaTest.BlockSizeSpecified = true;
|
|
|
|
|
|
}
|
2017-05-28 21:01:17 +01:00
|
|
|
|
|
2017-12-21 06:06:19 +00:00
|
|
|
|
decMode = null;
|
2017-05-28 21:01:17 +01:00
|
|
|
|
|
2017-12-21 06:06:19 +00:00
|
|
|
|
DicConsole.WriteLine("Querying SCSI MODE SENSE (10)...");
|
|
|
|
|
|
sense = dev.ModeSense10(out buffer, out senseBuffer, false, true,
|
2017-12-23 17:41:23 +00:00
|
|
|
|
ScsiModeSensePageControl.Current, 0x3F, 0x00, TIMEOUT, out _);
|
2017-12-21 06:06:19 +00:00
|
|
|
|
if(!sense && !dev.Error)
|
|
|
|
|
|
{
|
|
|
|
|
|
report.SCSI.SupportsModeSense10 = true;
|
2017-12-21 14:30:38 +00:00
|
|
|
|
decMode = Modes.DecodeMode10(buffer, dev.ScsiType);
|
2017-12-21 06:06:19 +00:00
|
|
|
|
if(debug) mediaTest.ModeSense10Data = buffer;
|
|
|
|
|
|
}
|
2017-05-28 21:01:17 +01:00
|
|
|
|
|
2017-12-21 06:06:19 +00:00
|
|
|
|
DicConsole.WriteLine("Querying SCSI MODE SENSE...");
|
2017-12-21 23:00:30 +00:00
|
|
|
|
sense = dev.ModeSense(out buffer, out senseBuffer, TIMEOUT, out _);
|
2017-12-21 06:06:19 +00:00
|
|
|
|
if(!sense && !dev.Error)
|
|
|
|
|
|
{
|
|
|
|
|
|
report.SCSI.SupportsModeSense6 = true;
|
2017-12-23 17:41:23 +00:00
|
|
|
|
if(!decMode.HasValue) decMode = Modes.DecodeMode6(buffer, dev.ScsiType);
|
2017-12-21 06:06:19 +00:00
|
|
|
|
if(debug) mediaTest.ModeSense6Data = buffer;
|
|
|
|
|
|
}
|
2017-12-21 04:43:29 +00:00
|
|
|
|
|
2017-12-21 06:06:19 +00:00
|
|
|
|
if(decMode.HasValue)
|
|
|
|
|
|
{
|
|
|
|
|
|
mediaTest.MediumType = (byte)decMode.Value.Header.MediumType;
|
|
|
|
|
|
mediaTest.MediumTypeSpecified = true;
|
|
|
|
|
|
if(decMode.Value.Header.BlockDescriptors != null &&
|
|
|
|
|
|
decMode.Value.Header.BlockDescriptors.Length > 0)
|
2017-05-28 21:01:17 +01:00
|
|
|
|
{
|
2017-12-21 06:06:19 +00:00
|
|
|
|
mediaTest.Density = (byte)decMode.Value.Header.BlockDescriptors[0].Density;
|
|
|
|
|
|
mediaTest.DensitySpecified = true;
|
2017-05-28 21:01:17 +01:00
|
|
|
|
}
|
2017-12-21 06:06:19 +00:00
|
|
|
|
}
|
2017-05-28 21:01:17 +01:00
|
|
|
|
|
2017-12-21 06:06:19 +00:00
|
|
|
|
mediaTest.SupportsReadSpecified = true;
|
|
|
|
|
|
mediaTest.SupportsRead10Specified = true;
|
|
|
|
|
|
mediaTest.SupportsRead12Specified = true;
|
|
|
|
|
|
mediaTest.SupportsRead16Specified = true;
|
|
|
|
|
|
mediaTest.SupportsReadLongSpecified = true;
|
|
|
|
|
|
|
|
|
|
|
|
DicConsole.WriteLine("Trying SCSI READ (6)...");
|
2017-12-23 17:41:23 +00:00
|
|
|
|
mediaTest.SupportsRead =
|
|
|
|
|
|
!dev.Read6(out buffer, out senseBuffer, 0, mediaTest.BlockSize, TIMEOUT, out _);
|
2017-12-21 06:06:19 +00:00
|
|
|
|
DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.SupportsRead);
|
|
|
|
|
|
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,
|
2017-12-21 23:00:30 +00:00
|
|
|
|
mediaTest.BlockSize, 0, 1, TIMEOUT, out _);
|
2017-12-21 06:06:19 +00:00
|
|
|
|
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,
|
2017-12-21 23:00:30 +00:00
|
|
|
|
mediaTest.BlockSize, 0, 1, false, TIMEOUT, out _);
|
2017-12-21 06:06:19 +00:00
|
|
|
|
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,
|
2017-12-21 23:00:30 +00:00
|
|
|
|
mediaTest.BlockSize, 0, 1, false, TIMEOUT, out _);
|
2017-12-21 06:06:19 +00:00
|
|
|
|
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)...");
|
2017-12-21 23:00:30 +00:00
|
|
|
|
sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 0xFFFF, TIMEOUT,
|
|
|
|
|
|
out _);
|
2017-12-21 06:06:19 +00:00
|
|
|
|
if(sense && !dev.Error)
|
|
|
|
|
|
{
|
2017-12-21 14:30:38 +00:00
|
|
|
|
FixedSense? decSense = Sense.DecodeFixed(senseBuffer);
|
2017-12-21 06:06:19 +00:00
|
|
|
|
if(decSense.HasValue)
|
2017-12-21 14:30:38 +00:00
|
|
|
|
if(decSense.Value.SenseKey == SenseKeys.IllegalRequest &&
|
2017-12-21 06:06:19 +00:00
|
|
|
|
decSense.Value.ASC == 0x24 && decSense.Value.ASCQ == 0x00)
|
2017-05-28 21:01:17 +01:00
|
|
|
|
{
|
2017-12-21 06:06:19 +00:00
|
|
|
|
mediaTest.SupportsReadLong = true;
|
|
|
|
|
|
if(decSense.Value.InformationValid && decSense.Value.ILI)
|
2017-05-28 21:01:17 +01:00
|
|
|
|
{
|
2017-12-21 06:06:19 +00:00
|
|
|
|
mediaTest.LongBlockSize =
|
|
|
|
|
|
0xFFFF - (decSense.Value.Information & 0xFFFF);
|
2017-05-28 21:01:17 +01:00
|
|
|
|
mediaTest.LongBlockSizeSpecified = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2017-12-21 06:06:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if(mediaTest.SupportsReadLong && mediaTest.LongBlockSize == mediaTest.BlockSize)
|
|
|
|
|
|
if(mediaTest.BlockSize == 512)
|
2018-06-20 22:22:21 +01:00
|
|
|
|
foreach(int i in new[]
|
2017-12-21 06:06:19 +00:00
|
|
|
|
{
|
|
|
|
|
|
// Long sector sizes for floppies
|
|
|
|
|
|
514,
|
|
|
|
|
|
// Long sector sizes for SuperDisk
|
|
|
|
|
|
536, 558,
|
|
|
|
|
|
// Long sector sizes for 512-byte magneto-opticals
|
|
|
|
|
|
600, 610, 630
|
|
|
|
|
|
})
|
|
|
|
|
|
{
|
2018-06-20 22:22:21 +01:00
|
|
|
|
ushort testSize = (ushort)i;
|
2017-12-21 06:06:19 +00:00
|
|
|
|
sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0,
|
2017-12-21 23:00:30 +00:00
|
|
|
|
testSize, TIMEOUT, out _);
|
2017-12-21 06:06:19 +00:00
|
|
|
|
if(sense || dev.Error) continue;
|
|
|
|
|
|
|
|
|
|
|
|
mediaTest.SupportsReadLong = true;
|
|
|
|
|
|
mediaTest.LongBlockSize = testSize;
|
|
|
|
|
|
mediaTest.LongBlockSizeSpecified = true;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if(mediaTest.BlockSize == 1024)
|
2018-06-20 22:22:21 +01:00
|
|
|
|
foreach(int i in new[]
|
2017-05-28 21:01:17 +01:00
|
|
|
|
{
|
2017-12-21 06:06:19 +00:00
|
|
|
|
// Long sector sizes for floppies
|
|
|
|
|
|
1026,
|
|
|
|
|
|
// Long sector sizes for 1024-byte magneto-opticals
|
|
|
|
|
|
1200
|
|
|
|
|
|
})
|
|
|
|
|
|
{
|
2018-06-20 22:22:21 +01:00
|
|
|
|
ushort testSize = (ushort)i;
|
2017-12-21 06:06:19 +00:00
|
|
|
|
sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0,
|
2018-06-20 22:22:21 +01:00
|
|
|
|
(ushort)i, TIMEOUT, out _);
|
2017-12-21 06:06:19 +00:00
|
|
|
|
if(sense || dev.Error) continue;
|
|
|
|
|
|
|
|
|
|
|
|
mediaTest.SupportsReadLong = true;
|
|
|
|
|
|
mediaTest.LongBlockSize = testSize;
|
|
|
|
|
|
mediaTest.LongBlockSizeSpecified = true;
|
|
|
|
|
|
break;
|
2017-05-28 21:01:17 +01:00
|
|
|
|
}
|
2017-12-21 06:06:19 +00:00
|
|
|
|
else if(mediaTest.BlockSize == 2048)
|
|
|
|
|
|
{
|
|
|
|
|
|
sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 2380,
|
2017-12-21 23:00:30 +00:00
|
|
|
|
TIMEOUT, out _);
|
2017-12-21 06:06:19 +00:00
|
|
|
|
if(!sense && !dev.Error)
|
2017-12-19 20:33:03 +00:00
|
|
|
|
{
|
2017-12-21 06:06:19 +00:00
|
|
|
|
mediaTest.SupportsReadLong = true;
|
|
|
|
|
|
mediaTest.LongBlockSize = 2380;
|
|
|
|
|
|
mediaTest.LongBlockSizeSpecified = true;
|
2017-05-28 21:01:17 +01:00
|
|
|
|
}
|
2017-12-21 06:06:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
else if(mediaTest.BlockSize == 4096)
|
2017-05-28 21:01:17 +01:00
|
|
|
|
{
|
2017-12-21 06:06:19 +00:00
|
|
|
|
sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 4760,
|
2017-12-21 23:00:30 +00:00
|
|
|
|
TIMEOUT, out _);
|
2017-12-21 06:06:19 +00:00
|
|
|
|
if(!sense && !dev.Error)
|
2017-05-28 21:01:17 +01:00
|
|
|
|
{
|
2017-12-21 06:06:19 +00:00
|
|
|
|
mediaTest.SupportsReadLong = true;
|
|
|
|
|
|
mediaTest.LongBlockSize = 4760;
|
|
|
|
|
|
mediaTest.LongBlockSizeSpecified = true;
|
2017-05-28 21:01:17 +01:00
|
|
|
|
}
|
2017-12-21 06:06:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
else if(mediaTest.BlockSize == 8192)
|
|
|
|
|
|
{
|
|
|
|
|
|
sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 9424,
|
2017-12-21 23:00:30 +00:00
|
|
|
|
TIMEOUT, out _);
|
2017-12-21 06:06:19 +00:00
|
|
|
|
if(!sense && !dev.Error)
|
|
|
|
|
|
{
|
|
|
|
|
|
mediaTest.SupportsReadLong = true;
|
|
|
|
|
|
mediaTest.LongBlockSize = 9424;
|
|
|
|
|
|
mediaTest.LongBlockSizeSpecified = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2017-05-28 21:01:17 +01:00
|
|
|
|
|
2017-12-21 06:06:19 +00:00
|
|
|
|
if(mediaTest.SupportsReadLong && 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)
|
|
|
|
|
|
{
|
2017-12-23 17:41:23 +00:00
|
|
|
|
for(ushort i = (ushort)mediaTest.BlockSize;; i++)
|
2017-05-28 21:01:17 +01:00
|
|
|
|
{
|
2017-12-21 06:06:19 +00:00
|
|
|
|
DicConsole.Write("\rTrying to READ LONG with a size of {0} bytes...", i);
|
|
|
|
|
|
sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, i,
|
2017-12-21 23:00:30 +00:00
|
|
|
|
TIMEOUT, out _);
|
2017-12-21 06:06:19 +00:00
|
|
|
|
if(!sense)
|
2017-05-28 21:01:17 +01:00
|
|
|
|
{
|
2017-12-21 06:06:19 +00:00
|
|
|
|
mediaTest.LongBlockSize = i;
|
|
|
|
|
|
mediaTest.LongBlockSizeSpecified = true;
|
|
|
|
|
|
break;
|
2017-05-28 21:01:17 +01:00
|
|
|
|
}
|
2017-06-04 01:26:31 +01:00
|
|
|
|
|
2017-12-21 06:06:19 +00:00
|
|
|
|
if(i == ushort.MaxValue) break;
|
2017-05-28 21:01:17 +01:00
|
|
|
|
}
|
2017-12-19 20:33:03 +00:00
|
|
|
|
|
2017-12-21 06:06:19 +00:00
|
|
|
|
DicConsole.WriteLine();
|
2017-05-28 21:01:17 +01:00
|
|
|
|
}
|
2017-12-21 06:06:19 +00:00
|
|
|
|
}
|
2017-05-28 21:01:17 +01:00
|
|
|
|
|
2017-12-21 06:06:19 +00:00
|
|
|
|
if(debug && mediaTest.SupportsReadLong && mediaTest.LongBlockSizeSpecified &&
|
|
|
|
|
|
mediaTest.LongBlockSize != mediaTest.BlockSize)
|
|
|
|
|
|
{
|
|
|
|
|
|
sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0,
|
2017-12-21 23:00:30 +00:00
|
|
|
|
(ushort)mediaTest.LongBlockSize, TIMEOUT, out _);
|
2017-12-21 06:06:19 +00:00
|
|
|
|
if(!sense)
|
|
|
|
|
|
DataFile.WriteTo("SCSI Report", "readlong10",
|
|
|
|
|
|
"_debug_" + mediaTest.MediumTypeName + ".bin", "read results",
|
|
|
|
|
|
buffer);
|
2017-06-03 19:26:48 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2017-12-21 06:06:19 +00:00
|
|
|
|
mediaTest.CanReadMediaSerialSpecified = true;
|
|
|
|
|
|
DicConsole.WriteLine("Trying SCSI READ MEDIA SERIAL NUMBER...");
|
|
|
|
|
|
mediaTest.CanReadMediaSerial =
|
2017-12-21 23:00:30 +00:00
|
|
|
|
!dev.ReadMediaSerialNumber(out buffer, out senseBuffer, TIMEOUT, out _);
|
2017-05-28 21:01:17 +01:00
|
|
|
|
}
|
2017-12-21 06:06:19 +00:00
|
|
|
|
|
|
|
|
|
|
mediaTests.Add(mediaTest);
|
2017-05-28 21:01:17 +01:00
|
|
|
|
}
|
2017-12-21 04:43:29 +00:00
|
|
|
|
|
|
|
|
|
|
report.SCSI.RemovableMedias = mediaTests.ToArray();
|
2017-05-28 21:01:17 +01:00
|
|
|
|
}
|
2017-12-21 04:43:29 +00:00
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
report.SCSI.ReadCapabilities = new testedMediaType();
|
|
|
|
|
|
report.SCSI.ReadCapabilitiesSpecified = true;
|
|
|
|
|
|
report.SCSI.ReadCapabilities.MediaIsRecognized = true;
|
2017-12-19 20:33:03 +00:00
|
|
|
|
|
2017-12-21 04:43:29 +00:00
|
|
|
|
report.SCSI.ReadCapabilities.SupportsReadCapacitySpecified = true;
|
|
|
|
|
|
report.SCSI.ReadCapabilities.SupportsReadCapacity16Specified = true;
|
2017-05-28 21:01:17 +01:00
|
|
|
|
|
2017-12-21 04:43:29 +00:00
|
|
|
|
DicConsole.WriteLine("Querying SCSI READ CAPACITY...");
|
2017-12-21 23:00:30 +00:00
|
|
|
|
sense = dev.ReadCapacity(out buffer, out senseBuffer, TIMEOUT, out _);
|
2017-12-21 04:43:29 +00:00
|
|
|
|
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]);
|
|
|
|
|
|
report.SCSI.ReadCapabilities.BlocksSpecified = true;
|
|
|
|
|
|
report.SCSI.ReadCapabilities.BlockSizeSpecified = true;
|
|
|
|
|
|
}
|
2017-05-28 21:01:17 +01:00
|
|
|
|
|
2017-12-21 04:43:29 +00:00
|
|
|
|
DicConsole.WriteLine("Querying SCSI READ CAPACITY (16)...");
|
2017-12-21 23:00:30 +00:00
|
|
|
|
sense = dev.ReadCapacity16(out buffer, out buffer, TIMEOUT, out _);
|
2017-12-21 04:43:29 +00:00
|
|
|
|
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]);
|
|
|
|
|
|
report.SCSI.ReadCapabilities.BlocksSpecified = true;
|
|
|
|
|
|
report.SCSI.ReadCapabilities.BlockSizeSpecified = true;
|
|
|
|
|
|
}
|
2017-05-28 21:01:17 +01:00
|
|
|
|
|
2017-12-21 04:43:29 +00:00
|
|
|
|
decMode = null;
|
2017-05-28 21:01:17 +01:00
|
|
|
|
|
2017-12-21 04:43:29 +00:00
|
|
|
|
DicConsole.WriteLine("Querying SCSI MODE SENSE (10)...");
|
2017-12-23 17:41:23 +00:00
|
|
|
|
sense = dev.ModeSense10(out buffer, out senseBuffer, false, true,
|
|
|
|
|
|
ScsiModeSensePageControl.Current, 0x3F, 0x00, TIMEOUT, out _);
|
2017-12-21 04:43:29 +00:00
|
|
|
|
if(!sense && !dev.Error)
|
|
|
|
|
|
{
|
|
|
|
|
|
report.SCSI.SupportsModeSense10 = true;
|
2017-12-21 14:30:38 +00:00
|
|
|
|
decMode = Modes.DecodeMode10(buffer, dev.ScsiType);
|
2017-12-21 04:43:29 +00:00
|
|
|
|
if(debug) report.SCSI.ReadCapabilities.ModeSense10Data = buffer;
|
|
|
|
|
|
}
|
2017-05-28 21:01:17 +01:00
|
|
|
|
|
2017-12-21 04:43:29 +00:00
|
|
|
|
DicConsole.WriteLine("Querying SCSI MODE SENSE...");
|
2017-12-21 23:00:30 +00:00
|
|
|
|
sense = dev.ModeSense(out buffer, out senseBuffer, TIMEOUT, out _);
|
2017-12-21 04:43:29 +00:00
|
|
|
|
if(!sense && !dev.Error)
|
|
|
|
|
|
{
|
|
|
|
|
|
report.SCSI.SupportsModeSense6 = true;
|
2017-12-21 14:30:38 +00:00
|
|
|
|
if(!decMode.HasValue) decMode = Modes.DecodeMode6(buffer, dev.ScsiType);
|
2017-12-21 04:43:29 +00:00
|
|
|
|
if(debug) report.SCSI.ReadCapabilities.ModeSense6Data = buffer;
|
|
|
|
|
|
}
|
2017-05-28 21:01:17 +01:00
|
|
|
|
|
2017-12-21 04:43:29 +00:00
|
|
|
|
if(decMode.HasValue)
|
|
|
|
|
|
{
|
|
|
|
|
|
report.SCSI.ReadCapabilities.MediumType = (byte)decMode.Value.Header.MediumType;
|
|
|
|
|
|
report.SCSI.ReadCapabilities.MediumTypeSpecified = true;
|
|
|
|
|
|
if(decMode.Value.Header.BlockDescriptors != null &&
|
|
|
|
|
|
decMode.Value.Header.BlockDescriptors.Length > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
report.SCSI.ReadCapabilities.Density =
|
|
|
|
|
|
(byte)decMode.Value.Header.BlockDescriptors[0].Density;
|
|
|
|
|
|
report.SCSI.ReadCapabilities.DensitySpecified = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2017-05-28 21:01:17 +01:00
|
|
|
|
|
2017-12-21 04:43:29 +00:00
|
|
|
|
report.SCSI.ReadCapabilities.SupportsReadSpecified = true;
|
|
|
|
|
|
report.SCSI.ReadCapabilities.SupportsRead10Specified = true;
|
|
|
|
|
|
report.SCSI.ReadCapabilities.SupportsRead12Specified = true;
|
|
|
|
|
|
report.SCSI.ReadCapabilities.SupportsRead16Specified = true;
|
|
|
|
|
|
report.SCSI.ReadCapabilities.SupportsReadLongSpecified = true;
|
|
|
|
|
|
|
|
|
|
|
|
DicConsole.WriteLine("Trying SCSI READ (6)...");
|
2017-12-23 17:41:23 +00:00
|
|
|
|
report.SCSI.ReadCapabilities.SupportsRead =
|
|
|
|
|
|
!dev.Read6(out buffer, out senseBuffer, 0, report.SCSI.ReadCapabilities.BlockSize, TIMEOUT,
|
|
|
|
|
|
out _);
|
|
|
|
|
|
DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}",
|
|
|
|
|
|
!report.SCSI.ReadCapabilities.SupportsRead);
|
2017-12-21 04:43:29 +00:00
|
|
|
|
if(debug)
|
|
|
|
|
|
DataFile.WriteTo("SCSI Report", "read6",
|
2017-12-23 17:41:23 +00:00
|
|
|
|
"_debug_" + report.SCSI.Inquiry.ProductIdentification + ".bin",
|
|
|
|
|
|
"read results", buffer);
|
2017-12-21 04:43:29 +00:00
|
|
|
|
|
|
|
|
|
|
DicConsole.WriteLine("Trying SCSI READ (10)...");
|
|
|
|
|
|
report.SCSI.ReadCapabilities.SupportsRead10 =
|
|
|
|
|
|
!dev.Read10(out buffer, out senseBuffer, 0, false, true, false, false, 0,
|
2017-12-21 23:00:30 +00:00
|
|
|
|
report.SCSI.ReadCapabilities.BlockSize, 0, 1, TIMEOUT, out _);
|
2017-12-21 04:43:29 +00:00
|
|
|
|
DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}",
|
|
|
|
|
|
!report.SCSI.ReadCapabilities.SupportsRead10);
|
|
|
|
|
|
if(debug)
|
|
|
|
|
|
DataFile.WriteTo("SCSI Report", "read10",
|
2017-12-23 17:41:23 +00:00
|
|
|
|
"_debug_" + report.SCSI.Inquiry.ProductIdentification + ".bin",
|
|
|
|
|
|
"read results", buffer);
|
2017-12-21 04:43:29 +00:00
|
|
|
|
|
|
|
|
|
|
DicConsole.WriteLine("Trying SCSI READ (12)...");
|
|
|
|
|
|
report.SCSI.ReadCapabilities.SupportsRead12 =
|
|
|
|
|
|
!dev.Read12(out buffer, out senseBuffer, 0, false, true, false, false, 0,
|
2017-12-21 23:00:30 +00:00
|
|
|
|
report.SCSI.ReadCapabilities.BlockSize, 0, 1, false, TIMEOUT, out _);
|
2017-12-21 04:43:29 +00:00
|
|
|
|
DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}",
|
|
|
|
|
|
!report.SCSI.ReadCapabilities.SupportsRead12);
|
|
|
|
|
|
if(debug)
|
|
|
|
|
|
DataFile.WriteTo("SCSI Report", "read12",
|
2017-12-23 17:41:23 +00:00
|
|
|
|
"_debug_" + report.SCSI.Inquiry.ProductIdentification + ".bin",
|
|
|
|
|
|
"read results", buffer);
|
2017-12-21 04:43:29 +00:00
|
|
|
|
|
|
|
|
|
|
DicConsole.WriteLine("Trying SCSI READ (16)...");
|
|
|
|
|
|
report.SCSI.ReadCapabilities.SupportsRead16 =
|
|
|
|
|
|
!dev.Read16(out buffer, out senseBuffer, 0, false, true, false, 0,
|
2017-12-21 23:00:30 +00:00
|
|
|
|
report.SCSI.ReadCapabilities.BlockSize, 0, 1, false, TIMEOUT, out _);
|
2017-12-21 04:43:29 +00:00
|
|
|
|
DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}",
|
|
|
|
|
|
!report.SCSI.ReadCapabilities.SupportsRead16);
|
|
|
|
|
|
if(debug)
|
|
|
|
|
|
DataFile.WriteTo("SCSI Report", "read16",
|
2017-12-23 17:41:23 +00:00
|
|
|
|
"_debug_" + report.SCSI.Inquiry.ProductIdentification + ".bin",
|
|
|
|
|
|
"read results", buffer);
|
2017-12-21 04:43:29 +00:00
|
|
|
|
|
|
|
|
|
|
report.SCSI.ReadCapabilities.LongBlockSize = report.SCSI.ReadCapabilities.BlockSize;
|
|
|
|
|
|
DicConsole.WriteLine("Trying SCSI READ LONG (10)...");
|
2017-12-21 23:00:30 +00:00
|
|
|
|
sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 0xFFFF, TIMEOUT, out _);
|
2017-12-21 04:43:29 +00:00
|
|
|
|
if(sense && !dev.Error)
|
2017-05-28 21:01:17 +01:00
|
|
|
|
{
|
2017-12-21 14:30:38 +00:00
|
|
|
|
FixedSense? decSense = Sense.DecodeFixed(senseBuffer);
|
2017-12-21 04:43:29 +00:00
|
|
|
|
if(decSense.HasValue)
|
2017-12-23 17:41:23 +00:00
|
|
|
|
if(decSense.Value.SenseKey == SenseKeys.IllegalRequest && decSense.Value.ASC == 0x24 &&
|
|
|
|
|
|
decSense.Value.ASCQ == 0x00)
|
2017-12-21 04:43:29 +00:00
|
|
|
|
{
|
|
|
|
|
|
report.SCSI.ReadCapabilities.SupportsReadLong = true;
|
|
|
|
|
|
if(decSense.Value.InformationValid && decSense.Value.ILI)
|
|
|
|
|
|
{
|
|
|
|
|
|
report.SCSI.ReadCapabilities.LongBlockSize =
|
|
|
|
|
|
0xFFFF - (decSense.Value.Information & 0xFFFF);
|
|
|
|
|
|
report.SCSI.ReadCapabilities.LongBlockSizeSpecified = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2017-05-28 21:01:17 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2017-12-23 17:41:23 +00:00
|
|
|
|
if(report.SCSI.ReadCapabilities.SupportsReadLong &&
|
|
|
|
|
|
report.SCSI.ReadCapabilities.LongBlockSize == report.SCSI.ReadCapabilities.BlockSize)
|
2017-12-21 04:43:29 +00:00
|
|
|
|
if(report.SCSI.ReadCapabilities.BlockSize == 512)
|
2018-06-20 22:22:21 +01:00
|
|
|
|
foreach(int i in new[]
|
2017-12-21 04:43:29 +00:00
|
|
|
|
{
|
|
|
|
|
|
// Long sector sizes for floppies
|
|
|
|
|
|
514,
|
|
|
|
|
|
// Long sector sizes for SuperDisk
|
|
|
|
|
|
536, 558,
|
|
|
|
|
|
// Long sector sizes for 512-byte magneto-opticals
|
|
|
|
|
|
600, 610, 630
|
|
|
|
|
|
})
|
|
|
|
|
|
{
|
2018-06-20 22:22:21 +01:00
|
|
|
|
ushort testSize = (ushort)i;
|
|
|
|
|
|
sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, (ushort)i,
|
2017-12-23 17:41:23 +00:00
|
|
|
|
TIMEOUT, out _);
|
2017-12-21 06:06:19 +00:00
|
|
|
|
if(sense || dev.Error) continue;
|
|
|
|
|
|
|
|
|
|
|
|
report.SCSI.ReadCapabilities.SupportsReadLong = true;
|
|
|
|
|
|
report.SCSI.ReadCapabilities.LongBlockSize = testSize;
|
|
|
|
|
|
report.SCSI.ReadCapabilities.LongBlockSizeSpecified = true;
|
|
|
|
|
|
break;
|
2017-12-21 04:43:29 +00:00
|
|
|
|
}
|
|
|
|
|
|
else if(report.SCSI.ReadCapabilities.BlockSize == 1024)
|
2018-06-20 22:22:21 +01:00
|
|
|
|
foreach(int i in new[]
|
2017-12-21 04:43:29 +00:00
|
|
|
|
{
|
|
|
|
|
|
// Long sector sizes for floppies
|
|
|
|
|
|
1026,
|
|
|
|
|
|
// Long sector sizes for 1024-byte magneto-opticals
|
|
|
|
|
|
1200
|
|
|
|
|
|
})
|
|
|
|
|
|
{
|
2018-06-20 22:22:21 +01:00
|
|
|
|
ushort testSize = (ushort)i;
|
|
|
|
|
|
sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, (ushort)i,
|
2017-12-23 17:41:23 +00:00
|
|
|
|
TIMEOUT, out _);
|
2017-12-21 06:06:19 +00:00
|
|
|
|
if(sense || dev.Error) continue;
|
|
|
|
|
|
|
|
|
|
|
|
report.SCSI.ReadCapabilities.SupportsReadLong = true;
|
|
|
|
|
|
report.SCSI.ReadCapabilities.LongBlockSize = testSize;
|
|
|
|
|
|
report.SCSI.ReadCapabilities.LongBlockSizeSpecified = true;
|
|
|
|
|
|
break;
|
2017-12-21 04:43:29 +00:00
|
|
|
|
}
|
|
|
|
|
|
else if(report.SCSI.ReadCapabilities.BlockSize == 2048)
|
2017-05-28 21:01:17 +01:00
|
|
|
|
{
|
2017-12-21 23:00:30 +00:00
|
|
|
|
sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 2380, TIMEOUT,
|
|
|
|
|
|
out _);
|
2017-12-21 04:43:29 +00:00
|
|
|
|
if(!sense && !dev.Error)
|
2017-05-28 21:01:17 +01:00
|
|
|
|
{
|
2017-12-21 04:43:29 +00:00
|
|
|
|
report.SCSI.ReadCapabilities.SupportsReadLong = true;
|
|
|
|
|
|
report.SCSI.ReadCapabilities.LongBlockSize = 2380;
|
2017-05-28 21:01:17 +01:00
|
|
|
|
report.SCSI.ReadCapabilities.LongBlockSizeSpecified = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2017-12-21 04:43:29 +00:00
|
|
|
|
else if(report.SCSI.ReadCapabilities.BlockSize == 4096)
|
2017-12-16 23:31:44 +00:00
|
|
|
|
{
|
2017-12-21 23:00:30 +00:00
|
|
|
|
sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 4760, TIMEOUT,
|
|
|
|
|
|
out _);
|
2017-05-28 21:01:17 +01:00
|
|
|
|
if(!sense && !dev.Error)
|
|
|
|
|
|
{
|
|
|
|
|
|
report.SCSI.ReadCapabilities.SupportsReadLong = true;
|
2017-12-21 04:43:29 +00:00
|
|
|
|
report.SCSI.ReadCapabilities.LongBlockSize = 4760;
|
2017-05-28 21:01:17 +01:00
|
|
|
|
report.SCSI.ReadCapabilities.LongBlockSizeSpecified = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2017-12-21 04:43:29 +00:00
|
|
|
|
else if(report.SCSI.ReadCapabilities.BlockSize == 8192)
|
2017-05-28 21:01:17 +01:00
|
|
|
|
{
|
2017-12-21 23:00:30 +00:00
|
|
|
|
sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 9424, TIMEOUT,
|
|
|
|
|
|
out _);
|
2017-12-16 23:31:44 +00:00
|
|
|
|
if(!sense && !dev.Error)
|
|
|
|
|
|
{
|
|
|
|
|
|
report.SCSI.ReadCapabilities.SupportsReadLong = true;
|
2017-12-21 04:43:29 +00:00
|
|
|
|
report.SCSI.ReadCapabilities.LongBlockSize = 9424;
|
2017-12-16 23:31:44 +00:00
|
|
|
|
report.SCSI.ReadCapabilities.LongBlockSizeSpecified = true;
|
|
|
|
|
|
}
|
2017-05-28 21:01:17 +01:00
|
|
|
|
}
|
2017-12-21 04:43:29 +00:00
|
|
|
|
|
2017-12-23 17:41:23 +00:00
|
|
|
|
if(report.SCSI.ReadCapabilities.SupportsReadLong &&
|
|
|
|
|
|
report.SCSI.ReadCapabilities.LongBlockSize == report.SCSI.ReadCapabilities.BlockSize)
|
2017-05-28 21:01:17 +01:00
|
|
|
|
{
|
2017-12-21 04:43:29 +00:00
|
|
|
|
pressedKey = new ConsoleKeyInfo();
|
|
|
|
|
|
while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N)
|
2017-05-28 21:01:17 +01:00
|
|
|
|
{
|
2017-12-21 04:43:29 +00:00
|
|
|
|
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();
|
2017-05-28 21:01:17 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2017-12-21 04:43:29 +00:00
|
|
|
|
if(pressedKey.Key == ConsoleKey.Y)
|
2017-05-28 21:01:17 +01:00
|
|
|
|
{
|
2017-12-23 17:41:23 +00:00
|
|
|
|
for(ushort i = (ushort)report.SCSI.ReadCapabilities.BlockSize;; i++)
|
2017-05-28 21:01:17 +01:00
|
|
|
|
{
|
2017-12-21 04:43:29 +00:00
|
|
|
|
DicConsole.Write("\rTrying to READ LONG with a size of {0} bytes...", i);
|
2017-12-21 23:00:30 +00:00
|
|
|
|
sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, i, TIMEOUT,
|
|
|
|
|
|
out _);
|
2017-12-21 04:43:29 +00:00
|
|
|
|
if(!sense)
|
2017-05-28 21:01:17 +01:00
|
|
|
|
{
|
2017-12-21 04:43:29 +00:00
|
|
|
|
if(debug)
|
|
|
|
|
|
{
|
|
|
|
|
|
FileStream bingo =
|
2017-12-23 17:41:23 +00:00
|
|
|
|
new FileStream($"{dev.Model}_readlong.bin", FileMode.Create);
|
2017-12-21 04:43:29 +00:00
|
|
|
|
bingo.Write(buffer, 0, buffer.Length);
|
|
|
|
|
|
bingo.Close();
|
|
|
|
|
|
}
|
|
|
|
|
|
report.SCSI.ReadCapabilities.LongBlockSize = i;
|
|
|
|
|
|
report.SCSI.ReadCapabilities.LongBlockSizeSpecified = true;
|
|
|
|
|
|
break;
|
2017-05-28 21:01:17 +01:00
|
|
|
|
}
|
2017-12-21 04:43:29 +00:00
|
|
|
|
|
|
|
|
|
|
if(i == ushort.MaxValue) break;
|
2017-05-28 21:01:17 +01:00
|
|
|
|
}
|
2017-06-04 01:26:31 +01:00
|
|
|
|
|
2017-12-21 04:43:29 +00:00
|
|
|
|
DicConsole.WriteLine();
|
2017-05-28 21:01:17 +01:00
|
|
|
|
}
|
2017-12-21 04:43:29 +00:00
|
|
|
|
}
|
2017-12-19 20:33:03 +00:00
|
|
|
|
|
2017-12-21 04:43:29 +00:00
|
|
|
|
if(debug && report.SCSI.ReadCapabilities.SupportsReadLong &&
|
|
|
|
|
|
report.SCSI.ReadCapabilities.LongBlockSizeSpecified &&
|
|
|
|
|
|
report.SCSI.ReadCapabilities.LongBlockSize != report.SCSI.ReadCapabilities.BlockSize)
|
|
|
|
|
|
{
|
|
|
|
|
|
sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0,
|
2017-12-23 17:41:23 +00:00
|
|
|
|
(ushort)report.SCSI.ReadCapabilities.LongBlockSize, TIMEOUT, out _);
|
2017-12-21 04:43:29 +00:00
|
|
|
|
if(!sense)
|
|
|
|
|
|
DataFile.WriteTo("SCSI Report", "readlong10",
|
|
|
|
|
|
"_debug_" + report.SCSI.Inquiry.ProductIdentification + ".bin",
|
|
|
|
|
|
"read results", buffer);
|
2017-05-28 21:01:17 +01:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2017-06-03 19:26:48 +01:00
|
|
|
|
|
2017-12-21 04:43:29 +00:00
|
|
|
|
break;
|
2017-05-28 21:01:17 +01:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2017-12-19 20:33:03 +00:00
|
|
|
|
}
|