public static SCSI MapScsi(scsiType oldScsi) { if (oldScsi == null) { return(null); } SCSI newScsi = new SCSI { Inquiry = Inquiry.MapInquiry(oldScsi.Inquiry), SupportsModeSense6 = oldScsi.SupportsModeSense6, SupportsModeSense10 = oldScsi.SupportsModeSense10, SupportsModeSubpages = oldScsi.SupportsModeSubpages, ModeSense = Mode.MapMode(oldScsi.ModeSense), MultiMediaDevice = MMC.MMC.MapMmc(oldScsi.MultiMediaDevice), ReadCapabilities = TestedMedia.MapTestedMedia(oldScsi.ReadCapabilities), SequentialDevice = SSC.SSC.MapSsc(oldScsi.SequentialDevice), ModeSense6Data = oldScsi.ModeSense6Data, ModeSense10Data = oldScsi.ModeSense10Data }; if (oldScsi.EVPDPages != null) { newScsi.EVPDPages = new List <Page>(oldScsi.EVPDPages.Select(Page.MapPage)); } if (oldScsi.RemovableMedias == null) { return(newScsi); } { newScsi.RemovableMedias = new List <TestedMedia>(oldScsi.RemovableMedias.Select(TestedMedia.MapTestedMedia)); } return(newScsi); }
protected void Page_Load(object sender, EventArgs e) { try { string manufacturer = Request.QueryString["manufacturer"]; string model = Request.QueryString["model"]; string revision = Request.QueryString["revision"]; // Strip non-ascii, strip slashes and question marks if (manufacturer != null) { manufacturer = Encoding .ASCII.GetString(Encoding.Convert(Encoding.UTF8, Encoding.ASCII, Encoding.UTF8.GetBytes(manufacturer))).Replace('/', '_') .Replace('\\', '_').Replace('?', '_'); } if (model != null) { model = Encoding .ASCII.GetString(Encoding.Convert(Encoding.UTF8, Encoding.ASCII, Encoding.UTF8.GetBytes(model))) .Replace('/', '_').Replace('\\', '_').Replace('?', '_'); } if (revision != null) { revision = Encoding .ASCII.GetString(Encoding.Convert(Encoding.UTF8, Encoding.ASCII, Encoding.UTF8.GetBytes(revision))).Replace('/', '_') .Replace('\\', '_').Replace('?', '_'); } string xmlFile = null; if (!string.IsNullOrWhiteSpace(manufacturer) && !string.IsNullOrWhiteSpace(model) && !string.IsNullOrWhiteSpace(revision)) { xmlFile = manufacturer + "_" + model + "_" + revision + ".xml"; } else if (!string.IsNullOrWhiteSpace(manufacturer) && !string.IsNullOrWhiteSpace(model)) { xmlFile = manufacturer + "_" + model + ".xml"; } else if (!string.IsNullOrWhiteSpace(model) && !string.IsNullOrWhiteSpace(revision)) { xmlFile = model + "_" + revision + ".xml"; } else if (!string.IsNullOrWhiteSpace(model)) { xmlFile = model + ".xml"; } if (xmlFile == null || !File.Exists(Path.Combine(HostingEnvironment.MapPath("~") ?? throw new InvalidOperationException(), "Reports", xmlFile))) { content.InnerHtml = "<b>Could not find the specified report</b>"; return; } lblManufacturer.Text = Request.QueryString["manufacturer"]; lblModel.Text = Request.QueryString["model"]; lblRevision.Text = Request.QueryString["revision"]; DeviceReport report = new DeviceReport(); XmlSerializer xs = new XmlSerializer(report.GetType()); StreamReader sr = new StreamReader(Path.Combine(HostingEnvironment.MapPath("~") ?? throw new InvalidOperationException(), "Reports", xmlFile)); report = (DeviceReport)xs.Deserialize(sr); sr.Close(); if (report.USB != null) { GetUsbDescriptions(report.USB.VendorID, report.USB.ProductID, out string usbVendorDescription, out string usbProductDescription); lblUsbManufacturer.Text = HttpUtility.HtmlEncode(report.USB.Manufacturer); lblUsbProduct.Text = HttpUtility.HtmlEncode(report.USB.Product); lblUsbVendor.Text = $"0x{report.USB.VendorID:x4}"; if (usbVendorDescription != null) { lblUsbVendorDescription.Text = $"({HttpUtility.HtmlEncode(usbVendorDescription)})"; } lblUsbProductId.Text = $"0x{report.USB.ProductID:x4}"; if (usbProductDescription != null) { lblUsbProductDescription.Text = $"({HttpUtility.HtmlEncode(usbProductDescription)})"; } } else { divUsb.Visible = false; } if (report.FireWire != null) { lblFirewireManufacturer.Text = HttpUtility.HtmlEncode(report.FireWire.Manufacturer); lblFirewireProduct.Text = HttpUtility.HtmlEncode(report.FireWire.Product); lblFirewireVendor.Text = $"0x{report.FireWire.VendorID:x8}"; lblFirewireProductId.Text = $"0x{report.FireWire.ProductID:x8}"; } else { divFirewire.Visible = false; } if (report.PCMCIA != null) { lblPcmciaManufacturer.Text = HttpUtility.HtmlEncode(report.PCMCIA.Manufacturer); lblPcmciaProduct.Text = HttpUtility.HtmlEncode(report.PCMCIA.ProductName); lblPcmciaManufacturerCode.Text = $"0x{report.PCMCIA.ManufacturerCode:x4}"; lblPcmciaCardCode.Text = $"0x{report.PCMCIA.CardCode:x4}"; lblPcmciaCompliance.Text = HttpUtility.HtmlEncode(report.PCMCIA.Compliance); Tuple[] tuples = CIS.GetTuples(report.PCMCIA.CIS); if (tuples != null) { Dictionary <string, string> decodedTuples = new Dictionary <string, string>(); foreach (Tuple tuple in tuples) { switch (tuple.Code) { case TupleCodes.CISTPL_NULL: case TupleCodes.CISTPL_END: case TupleCodes.CISTPL_MANFID: case TupleCodes.CISTPL_VERS_1: break; case TupleCodes.CISTPL_DEVICEGEO: case TupleCodes.CISTPL_DEVICEGEO_A: DeviceGeometryTuple geom = CIS.DecodeDeviceGeometryTuple(tuple.Data); if (geom?.Geometries != null) { foreach (DeviceGeometry geometry in geom.Geometries) { decodedTuples.Add("Device width", $"{(1 << (geometry.CardInterface - 1)) * 8} bits"); decodedTuples.Add("Erase block", $"{(1 << (geometry.EraseBlockSize - 1)) * (1 << (geometry.Interleaving - 1))} bytes"); decodedTuples.Add("Read block", $"{(1 << (geometry.ReadBlockSize - 1)) * (1 << (geometry.Interleaving - 1))} bytes"); decodedTuples.Add("Write block", $"{(1 << (geometry.WriteBlockSize - 1)) * (1 << (geometry.Interleaving - 1))} bytes"); decodedTuples.Add("Partition alignment", $"{(1 << (geometry.EraseBlockSize - 1)) * (1 << (geometry.Interleaving - 1)) * (1 << (geometry.Partitions - 1))} bytes"); } } break; case TupleCodes.CISTPL_ALTSTR: case TupleCodes.CISTPL_BAR: case TupleCodes.CISTPL_BATTERY: case TupleCodes.CISTPL_BYTEORDER: case TupleCodes.CISTPL_CFTABLE_ENTRY: case TupleCodes.CISTPL_CFTABLE_ENTRY_CB: case TupleCodes.CISTPL_CHECKSUM: case TupleCodes.CISTPL_CONFIG: case TupleCodes.CISTPL_CONFIG_CB: case TupleCodes.CISTPL_DATE: case TupleCodes.CISTPL_DEVICE: case TupleCodes.CISTPL_DEVICE_A: case TupleCodes.CISTPL_DEVICE_OA: case TupleCodes.CISTPL_DEVICE_OC: case TupleCodes.CISTPL_EXTDEVIC: case TupleCodes.CISTPL_FORMAT: case TupleCodes.CISTPL_FORMAT_A: case TupleCodes.CISTPL_FUNCE: case TupleCodes.CISTPL_FUNCID: case TupleCodes.CISTPL_GEOMETRY: case TupleCodes.CISTPL_INDIRECT: case TupleCodes.CISTPL_JEDEC_A: case TupleCodes.CISTPL_JEDEC_C: case TupleCodes.CISTPL_LINKTARGET: case TupleCodes.CISTPL_LONGLINK_A: case TupleCodes.CISTPL_LONGLINK_C: case TupleCodes.CISTPL_LONGLINK_CB: case TupleCodes.CISTPL_LONGLINK_MFC: case TupleCodes.CISTPL_NO_LINK: case TupleCodes.CISTPL_ORG: case TupleCodes.CISTPL_PWR_MGMNT: case TupleCodes.CISTPL_SPCL: case TupleCodes.CISTPL_SWIL: case TupleCodes.CISTPL_VERS_2: decodedTuples.Add("Undecoded tuple ID", tuple.Code.ToString()); break; default: decodedTuples.Add("Unknown tuple ID", $"0x{(byte)tuple.Code:X2}"); break; } } if (decodedTuples.Count > 0) { repPcmciaTuples.DataSource = decodedTuples; repPcmciaTuples.DataBind(); } else { repPcmciaTuples.Visible = false; } } else { repPcmciaTuples.Visible = false; } } else { divPcmcia.Visible = false; } bool removable = true; testedMediaType[] testedMedia = null; bool ata = false; bool atapi = false; bool sscMedia = false; if (report.ATA != null || report.ATAPI != null) { ata = true; List <string> ataOneValue = new List <string>(); Dictionary <string, string> ataTwoValue = new Dictionary <string, string>(); ataType ataReport; if (report.ATAPI != null) { lblAtapi.Text = "PI"; ataReport = report.ATAPI; atapi = true; } else { ataReport = report.ATA; } bool cfa = report.CompactFlashSpecified && report.CompactFlash; if (atapi && !cfa) { lblAtaDeviceType.Text = "ATAPI device"; } else if (!atapi && cfa) { lblAtaDeviceType.Text = "CompactFlash device"; } else { lblAtaDeviceType.Text = "ATA device"; } Ata.Report(ataReport, cfa, atapi, ref removable, ref ataOneValue, ref ataTwoValue, ref testedMedia); repAtaOne.DataSource = ataOneValue; repAtaOne.DataBind(); repAtaTwo.DataSource = ataTwoValue; repAtaTwo.DataBind(); } else { divAta.Visible = false; } if (report.SCSI != null) { List <string> scsiOneValue = new List <string>(); Dictionary <string, string> modePages = new Dictionary <string, string>(); Dictionary <string, string> evpdPages = new Dictionary <string, string>(); lblScsiVendor.Text = VendorString.Prettify(report.SCSI.Inquiry.VendorIdentification) != report.SCSI.Inquiry.VendorIdentification ? $"{report.SCSI.Inquiry.VendorIdentification} ({VendorString.Prettify(report.SCSI.Inquiry.VendorIdentification)})" : report.SCSI.Inquiry.VendorIdentification; lblScsiProduct.Text = report.SCSI.Inquiry.ProductIdentification; lblScsiRevision.Text = report.SCSI.Inquiry.ProductRevisionLevel; scsiOneValue.AddRange(ScsiInquiry.Report(report.SCSI.Inquiry)); if (report.SCSI.SupportsModeSense6) { scsiOneValue.Add("Device supports MODE SENSE (6)"); } if (report.SCSI.SupportsModeSense10) { scsiOneValue.Add("Device supports MODE SENSE (10)"); } if (report.SCSI.SupportsModeSubpages) { scsiOneValue.Add("Device supports MODE SENSE subpages"); } if (report.SCSI.ModeSense != null) { ScsiModeSense.Report(report.SCSI.ModeSense, report.SCSI.Inquiry.VendorIdentification, report.SCSI.Inquiry.PeripheralDeviceType, ref scsiOneValue, ref modePages); } if (modePages.Count > 0) { repModeSense.DataSource = modePages; repModeSense.DataBind(); } else { divScsiModeSense.Visible = false; } if (report.SCSI.EVPDPages != null) { ScsiEvpd.Report(report.SCSI.EVPDPages, report.SCSI.Inquiry.VendorIdentification, ref evpdPages); } if (evpdPages.Count > 0) { repEvpd.DataSource = evpdPages; repEvpd.DataBind(); } else { divScsiEvpd.Visible = false; } divScsiMmcMode.Visible = false; divScsiMmcFeatures.Visible = false; divScsiSsc.Visible = false; if (report.SCSI.MultiMediaDevice != null) { testedMedia = report.SCSI.MultiMediaDevice.TestedMedia; if (report.SCSI.MultiMediaDevice.ModeSense2A != null) { List <string> mmcModeOneValue = new List <string>(); ScsiMmcMode.Report(report.SCSI.MultiMediaDevice.ModeSense2A, ref mmcModeOneValue); if (mmcModeOneValue.Count > 0) { divScsiMmcMode.Visible = true; repScsiMmcMode.DataSource = mmcModeOneValue; repScsiMmcMode.DataBind(); } } if (report.SCSI.MultiMediaDevice.Features != null) { List <string> mmcFeaturesOneValue = new List <string>(); ScsiMmcFeatures.Report(report.SCSI.MultiMediaDevice.Features, ref mmcFeaturesOneValue); if (mmcFeaturesOneValue.Count > 0) { divScsiMmcFeatures.Visible = true; repScsiMmcFeatures.DataSource = mmcFeaturesOneValue; repScsiMmcFeatures.DataBind(); } } } else if (report.SCSI.SequentialDevice != null) { divScsiSsc.Visible = true; lblScsiSscGranularity.Text = report.SCSI.SequentialDevice.BlockSizeGranularitySpecified ? report.SCSI.SequentialDevice.BlockSizeGranularity.ToString() : "Unspecified"; lblScsiSscMaxBlock.Text = report.SCSI.SequentialDevice.MaxBlockLengthSpecified ? report.SCSI.SequentialDevice.MaxBlockLength.ToString() : "Unspecified"; lblScsiSscMinBlock.Text = report.SCSI.SequentialDevice.MinBlockLengthSpecified ? report.SCSI.SequentialDevice.MinBlockLength.ToString() : "Unspecified"; if (report.SCSI.SequentialDevice.SupportedDensities != null) { repScsiSscDensities.DataSource = report.SCSI.SequentialDevice.SupportedDensities; repScsiSscDensities.DataBind(); } else { repScsiSscDensities.Visible = false; } if (report.SCSI.SequentialDevice.SupportedMediaTypes != null) { repScsiSscMedias.DataSource = report.SCSI.SequentialDevice.SupportedMediaTypes; repScsiSscMedias.DataBind(); } else { repScsiSscMedias.Visible = false; } if (report.SCSI.SequentialDevice.TestedMedia != null) { List <string> mediaOneValue = new List <string>(); SscTestedMedia.Report(report.SCSI.SequentialDevice.TestedMedia, ref mediaOneValue); if (mediaOneValue.Count > 0) { sscMedia = true; repTestedMedia.DataSource = mediaOneValue; repTestedMedia.DataBind(); } else { divTestedMedia.Visible = false; } } else { divTestedMedia.Visible = false; } } else if (report.SCSI.ReadCapabilities != null) { removable = false; scsiOneValue.Add(""); if (report.SCSI.ReadCapabilities.BlocksSpecified && report.SCSI.ReadCapabilities.BlockSizeSpecified) { scsiOneValue .Add($"Device has {report.SCSI.ReadCapabilities.Blocks} blocks of {report.SCSI.ReadCapabilities.BlockSize} bytes each"); if (report.SCSI.ReadCapabilities.Blocks * report.SCSI.ReadCapabilities.BlockSize / 1024 / 1024 > 1000000) { scsiOneValue .Add($"Device size: {report.SCSI.ReadCapabilities.Blocks * report.SCSI.ReadCapabilities.BlockSize} bytes, {report.SCSI.ReadCapabilities.Blocks * report.SCSI.ReadCapabilities.BlockSize / 1000 / 1000 / 1000 / 1000} Tb, {(double)(report.SCSI.ReadCapabilities.Blocks * report.SCSI.ReadCapabilities.BlockSize) / 1024 / 1024 / 1024 / 1024:F2} TiB"); } else if (report.SCSI.ReadCapabilities.Blocks * report.SCSI.ReadCapabilities.BlockSize / 1024 / 1024 > 1000) { scsiOneValue .Add($"Device size: {report.SCSI.ReadCapabilities.Blocks * report.SCSI.ReadCapabilities.BlockSize} bytes, {report.SCSI.ReadCapabilities.Blocks * report.SCSI.ReadCapabilities.BlockSize / 1000 / 1000 / 1000} Gb, {(double)(report.SCSI.ReadCapabilities.Blocks * report.SCSI.ReadCapabilities.BlockSize) / 1024 / 1024 / 1024:F2} GiB"); } else { scsiOneValue .Add($"Device size: {report.SCSI.ReadCapabilities.Blocks * report.SCSI.ReadCapabilities.BlockSize} bytes, {report.SCSI.ReadCapabilities.Blocks * report.SCSI.ReadCapabilities.BlockSize / 1000 / 1000} Mb, {(double)(report.SCSI.ReadCapabilities.Blocks * report.SCSI.ReadCapabilities.BlockSize) / 1024 / 1024:F2} MiB"); } } if (report.SCSI.ReadCapabilities.MediumTypeSpecified) { scsiOneValue.Add($"Medium type code: {report.SCSI.ReadCapabilities.MediumType:X2}h"); } if (report.SCSI.ReadCapabilities.DensitySpecified) { scsiOneValue.Add($"Density code: {report.SCSI.ReadCapabilities.Density:X2}h"); } if ((report.SCSI.ReadCapabilities.SupportsReadLong || report.SCSI.ReadCapabilities.SupportsReadLong16) && report.SCSI.ReadCapabilities.LongBlockSizeSpecified) { scsiOneValue.Add($"Long block size: {report.SCSI.ReadCapabilities.LongBlockSize} bytes"); } if (report.SCSI.ReadCapabilities.SupportsReadCapacity) { scsiOneValue.Add("Device supports READ CAPACITY (10) command."); } if (report.SCSI.ReadCapabilities.SupportsReadCapacity16) { scsiOneValue.Add("Device supports READ CAPACITY (16) command."); } if (report.SCSI.ReadCapabilities.SupportsRead) { scsiOneValue.Add("Device supports READ (6) command."); } if (report.SCSI.ReadCapabilities.SupportsRead10) { scsiOneValue.Add("Device supports READ (10) command."); } if (report.SCSI.ReadCapabilities.SupportsRead12) { scsiOneValue.Add("Device supports READ (12) command."); } if (report.SCSI.ReadCapabilities.SupportsRead16) { scsiOneValue.Add("Device supports READ (16) command."); } if (report.SCSI.ReadCapabilities.SupportsReadLong) { scsiOneValue.Add("Device supports READ LONG (10) command."); } if (report.SCSI.ReadCapabilities.SupportsReadLong16) { scsiOneValue.Add("Device supports READ LONG (16) command."); } } else { testedMedia = report.SCSI.RemovableMedias; } repScsi.DataSource = scsiOneValue; repScsi.DataBind(); } else { divScsi.Visible = false; } if (report.MultiMediaCard != null) { List <string> mmcOneValue = new List <string>(); if (report.MultiMediaCard.CID != null) { mmcOneValue.Add(Decoders.MMC.Decoders.PrettifyCID(report.MultiMediaCard.CID) .Replace("\n", "<br/>")); mmcOneValue.Add(""); } if (report.MultiMediaCard.CSD != null) { mmcOneValue.Add(Decoders.MMC.Decoders.PrettifyCSD(report.MultiMediaCard.CSD) .Replace("\n", "<br/>")); mmcOneValue.Add(""); } if (report.MultiMediaCard.ExtendedCSD != null) { mmcOneValue.Add(Decoders.MMC.Decoders.PrettifyExtendedCSD(report.MultiMediaCard.ExtendedCSD) .Replace("\n", "<br/>")); mmcOneValue.Add(""); } if (report.MultiMediaCard.OCR != null) { mmcOneValue.Add(Decoders.MMC.Decoders.PrettifyCSD(report.MultiMediaCard.OCR) .Replace("\n", "<br/>")); mmcOneValue.Add(""); } repMMC.DataSource = mmcOneValue; repMMC.DataBind(); } else { divMMC.Visible = false; } if (report.SecureDigital != null) { List <string> sdOneValue = new List <string>(); if (report.SecureDigital.CID != null) { sdOneValue.Add(Decoders.SecureDigital.Decoders.PrettifyCID(report.SecureDigital.CID) .Replace("\n", "<br/>")); sdOneValue.Add(""); } if (report.SecureDigital.CSD != null) { sdOneValue.Add(Decoders.SecureDigital.Decoders.PrettifyCSD(report.SecureDigital.CSD) .Replace("\n", "<br/>")); sdOneValue.Add(""); } if (report.SecureDigital.SCR != null) { sdOneValue.Add(Decoders.SecureDigital.Decoders.PrettifySCR(report.SecureDigital.SCR) .Replace("\n", "<br/>")); sdOneValue.Add(""); } if (report.SecureDigital.OCR != null) { sdOneValue.Add(Decoders.SecureDigital.Decoders.PrettifyCSD(report.SecureDigital.OCR) .Replace("\n", "<br/>")); sdOneValue.Add(""); } repSD.DataSource = sdOneValue; repSD.DataBind(); } else { divSD.Visible = false; } if (removable && !sscMedia && testedMedia != null) { List <string> mediaOneValue = new List <string>(); TestedMedia.Report(testedMedia, ata, ref mediaOneValue); if (mediaOneValue.Count > 0) { divTestedMedia.Visible = true; repTestedMedia.DataSource = mediaOneValue; repTestedMedia.DataBind(); } else { divTestedMedia.Visible = false; } } else { divTestedMedia.Visible &= sscMedia; } } catch (Exception) { content.InnerHtml = "<b>Could not load device report</b>"; #if DEBUG throw; #endif } }
/// <summary>Creates a report of an ATA device</summary> public TestedMedia ReportAta(Identify.IdentifyDevice ataId) { var capabilities = new TestedMedia(); if (ataId.UnformattedBPT != 0) { capabilities.UnformattedBPT = ataId.UnformattedBPT; } if (ataId.UnformattedBPS != 0) { capabilities.UnformattedBPS = ataId.UnformattedBPS; } if (ataId.Cylinders > 0 && ataId.Heads > 0 && ataId.SectorsPerTrack > 0) { capabilities.CHS = new Chs { Cylinders = ataId.Cylinders, Heads = ataId.Heads, Sectors = ataId.SectorsPerTrack }; capabilities.Blocks = (ulong)(ataId.Cylinders * ataId.Heads * ataId.SectorsPerTrack); } if (ataId.CurrentCylinders > 0 && ataId.CurrentHeads > 0 && ataId.CurrentSectorsPerTrack > 0) { capabilities.CurrentCHS = new Chs { Cylinders = ataId.CurrentCylinders, Heads = ataId.CurrentHeads, Sectors = ataId.CurrentSectorsPerTrack }; capabilities.Blocks = (ulong)(ataId.CurrentCylinders * ataId.CurrentHeads * ataId.CurrentSectorsPerTrack); } if (ataId.Capabilities.HasFlag(Identify.CapabilitiesBit.LBASupport)) { capabilities.LBASectors = ataId.LBASectors; capabilities.Blocks = ataId.LBASectors; } if (ataId.CommandSet2.HasFlag(Identify.CommandSetBit2.LBA48)) { capabilities.LBA48Sectors = ataId.LBA48Sectors; capabilities.Blocks = ataId.LBA48Sectors; } if (ataId.NominalRotationRate != 0x0000 && ataId.NominalRotationRate != 0xFFFF) { if (ataId.NominalRotationRate == 0x0001) { capabilities.SolidStateDevice = true; } else { capabilities.SolidStateDevice = false; capabilities.NominalRotationRate = ataId.NominalRotationRate; } } uint logicalSectorSize; uint physicalSectorSize; if ((ataId.PhysLogSectorSize & 0x8000) == 0x0000 && (ataId.PhysLogSectorSize & 0x4000) == 0x4000) { if ((ataId.PhysLogSectorSize & 0x1000) == 0x1000) { if (ataId.LogicalSectorWords <= 255 || ataId.LogicalAlignment == 0xFFFF) { logicalSectorSize = 512; } else { logicalSectorSize = ataId.LogicalSectorWords * 2; } } else { logicalSectorSize = 512; } if ((ataId.PhysLogSectorSize & 0x2000) == 0x2000) { physicalSectorSize = logicalSectorSize * (uint)Math.Pow(2, ataId.PhysLogSectorSize & 0xF); } else { physicalSectorSize = logicalSectorSize; } } else { logicalSectorSize = 512; physicalSectorSize = 512; } capabilities.BlockSize = logicalSectorSize; if (physicalSectorSize != logicalSectorSize) { capabilities.PhysicalBlockSize = physicalSectorSize; if ((ataId.LogicalAlignment & 0x8000) == 0x0000 && (ataId.LogicalAlignment & 0x4000) == 0x4000) { capabilities.LogicalAlignment = (ushort)(ataId.LogicalAlignment & 0x3FFF); } } if (ataId.EccBytes != 0x0000 && ataId.EccBytes != 0xFFFF) { capabilities.LongBlockSize = logicalSectorSize + ataId.EccBytes; } if (ataId.UnformattedBPS > logicalSectorSize && (!(ataId.EccBytes != 0x0000 && ataId.EccBytes != 0xFFFF) || capabilities.LongBlockSize == 516)) { capabilities.LongBlockSize = ataId.UnformattedBPS; } if (ataId.CommandSet3.HasFlag(Identify.CommandSetBit3.MustBeSet) && !ataId.CommandSet3.HasFlag(Identify.CommandSetBit3.MustBeClear) && ataId.EnabledCommandSet3.HasFlag(Identify.CommandSetBit3.MediaSerial)) { capabilities.CanReadMediaSerial = true; if (!string.IsNullOrWhiteSpace(ataId.MediaManufacturer)) { capabilities.Manufacturer = ataId.MediaManufacturer; } } ulong checkCorrectRead = 0; bool sense; DicConsole.WriteLine("Trying READ SECTOR(S) in CHS mode..."); sense = _dev.Read(out byte[] readBuf, out AtaErrorRegistersChs errorChs, false, 0, 0, 1, 1, _dev.Timeout, out _); capabilities.SupportsReadSectors = !sense && (errorChs.Status & 0x01) != 0x01 && errorChs.Error == 0 && readBuf.Length > 0; DicConsole.DebugWriteLine("ATA Report", "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, errorChs.Status, errorChs.Error, readBuf.Length); capabilities.ReadSectorsData = readBuf; DicConsole.WriteLine("Trying READ SECTOR(S) RETRY in CHS mode..."); sense = _dev.Read(out readBuf, out errorChs, true, 0, 0, 1, 1, _dev.Timeout, out _); capabilities.SupportsReadRetry = !sense && (errorChs.Status & 0x01) != 0x01 && errorChs.Error == 0 && readBuf.Length > 0; DicConsole.DebugWriteLine("ATA Report", "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, errorChs.Status, errorChs.Error, readBuf.Length); capabilities.ReadSectorsRetryData = readBuf; DicConsole.WriteLine("Trying READ DMA in CHS mode..."); sense = _dev.ReadDma(out readBuf, out errorChs, false, 0, 0, 1, 1, _dev.Timeout, out _); capabilities.SupportsReadDma = !sense && (errorChs.Status & 0x01) != 0x01 && errorChs.Error == 0 && readBuf.Length > 0; DicConsole.DebugWriteLine("ATA Report", "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, errorChs.Status, errorChs.Error, readBuf.Length); capabilities.ReadDmaData = readBuf; DicConsole.WriteLine("Trying READ DMA RETRY in CHS mode..."); sense = _dev.ReadDma(out readBuf, out errorChs, true, 0, 0, 1, 1, _dev.Timeout, out _); capabilities.SupportsReadDmaRetry = !sense && (errorChs.Status & 0x01) != 0x01 && errorChs.Error == 0 && readBuf.Length > 0; DicConsole.DebugWriteLine("ATA Report", "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, errorChs.Status, errorChs.Error, readBuf.Length); capabilities.ReadDmaRetryData = readBuf; DicConsole.WriteLine("Trying SEEK in CHS mode..."); sense = _dev.Seek(out errorChs, 0, 0, 1, _dev.Timeout, out _); capabilities.SupportsSeek = !sense && (errorChs.Status & 0x01) != 0x01 && errorChs.Error == 0; DicConsole.DebugWriteLine("ATA Report", "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}", sense, errorChs.Status, errorChs.Error); DicConsole.WriteLine("Trying READ SECTOR(S) in LBA mode..."); sense = _dev.Read(out readBuf, out AtaErrorRegistersLba28 errorLba, false, 0, 1, _dev.Timeout, out _); capabilities.SupportsReadLba = !sense && (errorLba.Status & 0x01) != 0x01 && errorLba.Error == 0 && readBuf.Length > 0; DicConsole.DebugWriteLine("ATA Report", "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, errorLba.Status, errorLba.Error, readBuf.Length); capabilities.ReadLbaData = readBuf; DicConsole.WriteLine("Trying READ SECTOR(S) RETRY in LBA mode..."); sense = _dev.Read(out readBuf, out errorLba, true, 0, 1, _dev.Timeout, out _); capabilities.SupportsReadRetryLba = !sense && (errorLba.Status & 0x01) != 0x01 && errorLba.Error == 0 && readBuf.Length > 0; DicConsole.DebugWriteLine("ATA Report", "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, errorLba.Status, errorLba.Error, readBuf.Length); capabilities.ReadRetryLbaData = readBuf; DicConsole.WriteLine("Trying READ DMA in LBA mode..."); sense = _dev.ReadDma(out readBuf, out errorLba, false, 0, 1, _dev.Timeout, out _); capabilities.SupportsReadDmaLba = !sense && (errorLba.Status & 0x01) != 0x01 && errorLba.Error == 0 && readBuf.Length > 0; DicConsole.DebugWriteLine("ATA Report", "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, errorLba.Status, errorLba.Error, readBuf.Length); capabilities.ReadDmaLbaData = readBuf; DicConsole.WriteLine("Trying READ DMA RETRY in LBA mode..."); sense = _dev.ReadDma(out readBuf, out errorLba, true, 0, 1, _dev.Timeout, out _); capabilities.SupportsReadDmaRetryLba = !sense && (errorLba.Status & 0x01) != 0x01 && errorLba.Error == 0 && readBuf.Length > 0; DicConsole.DebugWriteLine("ATA Report", "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, errorLba.Status, errorLba.Error, readBuf.Length); capabilities.ReadDmaRetryLbaData = readBuf; DicConsole.WriteLine("Trying SEEK in LBA mode..."); sense = _dev.Seek(out errorLba, 0, _dev.Timeout, out _); capabilities.SupportsSeekLba = !sense && (errorLba.Status & 0x01) != 0x01 && errorLba.Error == 0; DicConsole.DebugWriteLine("ATA Report", "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}", sense, errorLba.Status, errorLba.Error); DicConsole.WriteLine("Trying READ SECTOR(S) in LBA48 mode..."); sense = _dev.Read(out readBuf, out AtaErrorRegistersLba48 errorLba48, 0, 1, _dev.Timeout, out _); capabilities.SupportsReadLba48 = !sense && (errorLba48.Status & 0x01) != 0x01 && errorLba48.Error == 0 && readBuf.Length > 0; DicConsole.DebugWriteLine("ATA Report", "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, errorLba48.Status, errorLba48.Error, readBuf.Length); capabilities.ReadLba48Data = readBuf; DicConsole.WriteLine("Trying READ DMA in LBA48 mode..."); sense = _dev.ReadDma(out readBuf, out errorLba48, 0, 1, _dev.Timeout, out _); capabilities.SupportsReadDmaLba48 = !sense && (errorLba48.Status & 0x01) != 0x01 && errorLba48.Error == 0 && readBuf.Length > 0; DicConsole.DebugWriteLine("ATA Report", "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, errorLba48.Status, errorLba48.Error, readBuf.Length); capabilities.ReadDmaLba48Data = readBuf; // Send SET FEATURES before sending READ LONG commands, retrieve IDENTIFY again and // check if ECC size changed. Sector is set to 1 because without it most drives just return // CORRECTABLE ERROR for this command. _dev.SetFeatures(out _, AtaFeatures.EnableReadLongVendorLength, 0, 0, 1, 0, _dev.Timeout, out _); _dev.AtaIdentify(out byte[] buffer, out _, _dev.Timeout, out _); if (Identify.Decode(buffer).HasValue) { ataId = Identify.Decode(buffer).Value; if (ataId.EccBytes != 0x0000 && ataId.EccBytes != 0xFFFF) { capabilities.LongBlockSize = logicalSectorSize + ataId.EccBytes; } if (ataId.UnformattedBPS > logicalSectorSize && (!(ataId.EccBytes != 0x0000 && ataId.EccBytes != 0xFFFF) || capabilities.LongBlockSize == 516)) { capabilities.LongBlockSize = ataId.UnformattedBPS; } } DicConsole.WriteLine("Trying READ LONG in CHS mode..."); sense = _dev.ReadLong(out readBuf, out errorChs, false, 0, 0, 1, capabilities.LongBlockSize ?? 0, _dev.Timeout, out _); capabilities.SupportsReadLong = !sense && (errorChs.Status & 0x01) != 0x01 && errorChs.Error == 0 && readBuf.Length > 0 && BitConverter.ToUInt64(readBuf, 0) != checkCorrectRead; DicConsole.DebugWriteLine("ATA Report", "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, errorChs.Status, errorChs.Error, readBuf.Length); capabilities.ReadLongData = readBuf; DicConsole.WriteLine("Trying READ LONG RETRY in CHS mode..."); sense = _dev.ReadLong(out readBuf, out errorChs, true, 0, 0, 1, capabilities.LongBlockSize ?? 0, _dev.Timeout, out _); capabilities.SupportsReadLongRetry = !sense && (errorChs.Status & 0x01) != 0x01 && errorChs.Error == 0 && readBuf.Length > 0 && BitConverter.ToUInt64(readBuf, 0) != checkCorrectRead; DicConsole.DebugWriteLine("ATA Report", "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, errorChs.Status, errorChs.Error, readBuf.Length); capabilities.ReadLongRetryData = readBuf; DicConsole.WriteLine("Trying READ LONG in LBA mode..."); sense = _dev.ReadLong(out readBuf, out errorLba, false, 0, capabilities.LongBlockSize ?? 0, _dev.Timeout, out _); capabilities.SupportsReadLongLba = !sense && (errorLba.Status & 0x01) != 0x01 && errorLba.Error == 0 && readBuf.Length > 0 && BitConverter.ToUInt64(readBuf, 0) != checkCorrectRead; DicConsole.DebugWriteLine("ATA Report", "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, errorLba.Status, errorLba.Error, readBuf.Length); capabilities.ReadLongLbaData = readBuf; DicConsole.WriteLine("Trying READ LONG RETRY in LBA mode..."); sense = _dev.ReadLong(out readBuf, out errorLba, true, 0, capabilities.LongBlockSize ?? 0, _dev.Timeout, out _); capabilities.SupportsReadLongRetryLba = !sense && (errorLba.Status & 0x01) != 0x01 && errorLba.Error == 0 && readBuf.Length > 0 && BitConverter.ToUInt64(readBuf, 0) != checkCorrectRead; DicConsole.DebugWriteLine("ATA Report", "Sense = {0}, Status = 0x{1:X2}, Error = 0x{2:X2}, Length = {3}", sense, errorLba.Status, errorLba.Error, readBuf.Length); capabilities.ReadLongRetryLbaData = readBuf; return(capabilities); }
public TestedMedia ReportScsi() { var capabilities = new TestedMedia { MediaIsRecognized = true }; AaruConsole.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]); } AaruConsole.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; AaruConsole.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); capabilities.ModeSense10Data = buffer; } AaruConsole.WriteLine("Querying SCSI MODE SENSE..."); sense = _dev.ModeSense(out buffer, out senseBuffer, _dev.Timeout, out _); if (!sense && !_dev.Error) { decMode ??= Modes.DecodeMode6(buffer, _dev.ScsiType); capabilities.ModeSense6Data = buffer; } if (decMode.HasValue) { capabilities.MediumType = (byte)decMode.Value.Header.MediumType; if (decMode.Value.Header.BlockDescriptors?.Length > 0) { capabilities.Density = (byte)decMode.Value.Header.BlockDescriptors[0].Density; } } AaruConsole.WriteLine("Trying SCSI READ (6)..."); capabilities.SupportsRead6 = !_dev.Read6(out buffer, out senseBuffer, 0, capabilities.BlockSize ?? 512, _dev.Timeout, out _); AaruConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !capabilities.SupportsRead6); capabilities.Read6Data = buffer; AaruConsole.WriteLine("Trying SCSI READ (10)..."); capabilities.SupportsRead10 = !_dev.Read10(out buffer, out senseBuffer, 0, false, false, false, false, 0, capabilities.BlockSize ?? 512, 0, 1, _dev.Timeout, out _); AaruConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !capabilities.SupportsRead10); capabilities.Read10Data = buffer; AaruConsole.WriteLine("Trying SCSI READ (12)..."); capabilities.SupportsRead12 = !_dev.Read12(out buffer, out senseBuffer, 0, false, false, false, false, 0, capabilities.BlockSize ?? 512, 0, 1, false, _dev.Timeout, out _); AaruConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !capabilities.SupportsRead12); capabilities.Read12Data = buffer; AaruConsole.WriteLine("Trying SCSI READ (16)..."); capabilities.SupportsRead16 = !_dev.Read16(out buffer, out senseBuffer, 0, false, false, false, 0, capabilities.BlockSize ?? 512, 0, 1, false, _dev.Timeout, out _); AaruConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !capabilities.SupportsRead16); capabilities.Read16Data = buffer; capabilities.LongBlockSize = capabilities.BlockSize; AaruConsole.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?.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 (ushort testSize in new ushort[] { // Long sector sizes for floppies 514, // Long sector sizes for SuperDisk 536, 558, // Long sector sizes for 512-byte magneto-opticals 600, 610, 630 }) { sense = _dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, testSize, _dev.Timeout, out _); if (sense || _dev.Error) { continue; } capabilities.SupportsReadLong = true; capabilities.LongBlockSize = testSize; break; } } else if (capabilities.BlockSize == 1024) { foreach (ushort testSize in new ushort[] { // Long sector sizes for floppies 1026, // Long sector sizes for 1024-byte magneto-opticals 1200 }) { sense = _dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, testSize, _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); }
static TestedMedia ClearBinaries(TestedMedia media) { if (media is null) { return(null); } media.AdipData = null; media.AtipData = null; media.BluBcaData = null; media.BluDdsData = null; media.BluDiData = null; media.BluPacData = null; media.BluSaiData = null; media.C2PointersData = null; media.CmiData = null; media.CorrectedSubchannelData = null; media.CorrectedSubchannelWithC2Data = null; media.DcbData = null; media.DmiData = null; media.DvdAacsData = null; media.DvdBcaData = null; media.DvdDdsData = null; media.DvdLayerData = null; media.DvdSaiData = null; media.EmbossedPfiData = null; media.FullTocData = null; media.HdCmiData = null; media.HLDTSTReadRawDVDData = null; media.IdentifyData = null; media.LeadInData = null; media.LeadOutData = null; media.ModeSense6Data = null; media.ModeSense10Data = null; media.NecReadCddaData = null; media.PfiData = null; media.PioneerReadCddaData = null; media.PioneerReadCddaMsfData = null; media.PlextorReadCddaData = null; media.PlextorReadRawDVDData = null; media.PmaData = null; media.PQSubchannelData = null; media.PQSubchannelWithC2Data = null; media.PriData = null; media.Read6Data = null; media.Read10Data = null; media.Read12Data = null; media.Read16Data = null; media.ReadCdData = null; media.ReadCdFullData = null; media.ReadCdMsfData = null; media.ReadCdMsfFullData = null; media.ReadDmaData = null; media.ReadDmaLba48Data = null; media.ReadDmaLbaData = null; media.ReadDmaRetryData = null; media.ReadLba48Data = null; media.ReadLbaData = null; media.ReadLong10Data = null; media.ReadLong16Data = null; media.ReadLongData = null; media.ReadLongLbaData = null; media.ReadLongRetryData = null; media.ReadLongRetryLbaData = null; media.ReadRetryLbaData = null; media.ReadSectorsData = null; media.ReadSectorsRetryData = null; media.RWSubchannelData = null; media.RWSubchannelWithC2Data = null; media.TocData = null; media.Track1PregapData = null; return(media); }
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) { 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, dev.Timeout, out _); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.SupportsRead6); if (debug) { mediaTest.Read6Data = 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, dev.Timeout, out _); DicConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.SupportsRead10); if (debug) { mediaTest.Read10Data = 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) { mediaTest.Read12Data = 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) { mediaTest.Read16Data = 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) { 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, 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 ReportScsiMedia() { var mediaTest = new TestedMedia(); AaruConsole.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]); } AaruConsole.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; AaruConsole.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); mediaTest.ModeSense10Data = buffer; } AaruConsole.WriteLine("Querying SCSI MODE SENSE..."); sense = _dev.ModeSense(out buffer, out senseBuffer, _dev.Timeout, out _); if (!sense && !_dev.Error) { decMode ??= Modes.DecodeMode6(buffer, _dev.ScsiType); mediaTest.ModeSense6Data = buffer; } if (decMode.HasValue) { mediaTest.MediumType = (byte)decMode.Value.Header.MediumType; if (decMode.Value.Header.BlockDescriptors?.Length > 0) { mediaTest.Density = (byte)decMode.Value.Header.BlockDescriptors[0].Density; } } AaruConsole.WriteLine("Trying SCSI READ (6)..."); mediaTest.SupportsRead6 = !_dev.Read6(out buffer, out senseBuffer, 0, mediaTest.BlockSize ?? 512, _dev.Timeout, out _); AaruConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.SupportsRead6); mediaTest.Read6Data = buffer; AaruConsole.WriteLine("Trying SCSI READ (10)..."); mediaTest.SupportsRead10 = !_dev.Read10(out buffer, out senseBuffer, 0, false, false, false, false, 0, mediaTest.BlockSize ?? 512, 0, 1, _dev.Timeout, out _); AaruConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.SupportsRead10); mediaTest.Read10Data = buffer; AaruConsole.WriteLine("Trying SCSI READ (12)..."); mediaTest.SupportsRead12 = !_dev.Read12(out buffer, out senseBuffer, 0, false, false, false, false, 0, mediaTest.BlockSize ?? 512, 0, 1, false, _dev.Timeout, out _); AaruConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.SupportsRead12); mediaTest.Read12Data = buffer; AaruConsole.WriteLine("Trying SCSI READ (16)..."); mediaTest.SupportsRead16 = !_dev.Read16(out buffer, out senseBuffer, 0, false, false, false, 0, mediaTest.BlockSize ?? 512, 0, 1, false, _dev.Timeout, out _); AaruConsole.DebugWriteLine("SCSI Report", "Sense = {0}", !mediaTest.SupportsRead16); mediaTest.Read16Data = buffer; mediaTest.LongBlockSize = mediaTest.BlockSize; AaruConsole.WriteLine("Trying SCSI READ LONG (10)..."); sense = _dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 0xFFFF, _dev.Timeout, out _); if (sense && !_dev.Error) { DecodedSense?decSense = Sense.Decode(senseBuffer); if (decSense?.SenseKey == SenseKeys.IllegalRequest && decSense.Value.ASC == 0x24 && decSense.Value.ASCQ == 0x00) { mediaTest.SupportsReadLong = true; bool valid = decSense?.Fixed?.InformationValid == true; bool ili = decSense?.Fixed?.ILI == true; uint information = decSense?.Fixed?.Information ?? 0; if (decSense?.Descriptor.HasValue == true && decSense.Value.Descriptor.Value.Descriptors.TryGetValue(0, out byte[] desc00))