diff --git a/DiscImageChef.Core/Devices/Report/ATA.cs b/DiscImageChef.Core/Devices/Report/ATA.cs new file mode 100644 index 000000000..16b162b37 --- /dev/null +++ b/DiscImageChef.Core/Devices/Report/ATA.cs @@ -0,0 +1,961 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : ATA.cs +// Version : 1.0 +// Author(s) : Natalia Portillo +// +// Component : Component +// +// Revision : $Revision$ +// Last change by : $Author$ +// Date : $Date$ +// +// --[ Description ] ---------------------------------------------------------- +// +// Description +// +// --[ 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 . +// +// ---------------------------------------------------------------------------- +// Copyright (C) 2011-2015 Claunia.com +// ****************************************************************************/ +// //$Id$ +using System; +using System.Collections.Generic; +using DiscImageChef.Console; +using DiscImageChef.Devices; +using DiscImageChef.Metadata; + +namespace DiscImageChef.Core.Devices.Report +{ + public static class ATA + { + public static void Report(Device dev, ref DeviceReport report, bool debug, ref bool removable) + { + if(report == null) + return; + + Decoders.ATA.AtaErrorRegistersCHS errorRegs; + byte[] buffer; + double duration; + uint timeout = 5; + ConsoleKeyInfo pressedKey; + + if(dev.IsUSB) + USB.Report(dev, ref report, debug, ref removable); + + if(dev.IsFireWire) + FireWire.Report(dev, ref report, debug, ref removable); + + if(dev.IsPCMCIA) + PCMCIA.Report(dev, ref report, debug, ref removable); + + DicConsole.WriteLine("Querying ATA IDENTIFY..."); + + dev.AtaIdentify(out buffer, out errorRegs, timeout, out duration); + + if(Decoders.ATA.Identify.Decode(buffer).HasValue) + { + Decoders.ATA.Identify.IdentifyDevice ataId = Decoders.ATA.Identify.Decode(buffer).Value; + + if((ushort)ataId.GeneralConfiguration == 0x848A) + { + report.CompactFlash = true; + report.CompactFlashSpecified = true; + removable = false; + } + else if(!removable && ataId.GeneralConfiguration.HasFlag(Decoders.ATA.Identify.GeneralConfigurationBit.Removable)) + { + pressedKey = new ConsoleKeyInfo(); + while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N) + { + DicConsole.Write("Is the media removable from the reading/writing elements? (Y/N): "); + pressedKey = System.Console.ReadKey(); + DicConsole.WriteLine(); + } + + removable = pressedKey.Key == ConsoleKey.Y; + } + + if(removable) + { + DicConsole.WriteLine("Please remove any media from the device and press any key when it is out."); + System.Console.ReadKey(true); + DicConsole.WriteLine("Querying ATA IDENTIFY..."); + dev.AtaIdentify(out buffer, out errorRegs, timeout, out duration); + ataId = Decoders.ATA.Identify.Decode(buffer).Value; + } + + report.ATA = new ataType(); + + if(!string.IsNullOrWhiteSpace(ataId.AdditionalPID)) + { + report.ATA.AdditionalPID = ataId.AdditionalPID; + report.ATA.AdditionalPIDSpecified = true; + } + if(ataId.APIOSupported != 0) + { + report.ATA.APIOSupported = ataId.APIOSupported; + report.ATA.APIOSupportedSpecified = true; + } + if(ataId.BufferType != 0) + { + report.ATA.BufferType = ataId.BufferType; + report.ATA.BufferTypeSpecified = true; + } + if(ataId.BufferSize != 0) + { + report.ATA.BufferSize = ataId.BufferSize; + report.ATA.BufferSizeSpecified = true; + } + if(ataId.Capabilities != 0) + { + report.ATA.Capabilities = ataId.Capabilities; + report.ATA.CapabilitiesSpecified = true; + } + if(ataId.Capabilities2 != 0) + { + report.ATA.Capabilities2 = ataId.Capabilities2; + report.ATA.Capabilities2Specified = true; + } + if(ataId.Capabilities3 != 0) + { + report.ATA.Capabilities3 = ataId.Capabilities3; + report.ATA.Capabilities3Specified = true; + } + if(ataId.CFAPowerMode != 0) + { + report.ATA.CFAPowerMode = ataId.CFAPowerMode; + report.ATA.CFAPowerModeSpecified = true; + } + if(ataId.CommandSet != 0) + { + report.ATA.CommandSet = ataId.CommandSet; + report.ATA.CommandSetSpecified = true; + } + if(ataId.CommandSet2 != 0) + { + report.ATA.CommandSet2 = ataId.CommandSet2; + report.ATA.CommandSet2Specified = true; + } + if(ataId.CommandSet3 != 0) + { + report.ATA.CommandSet3 = ataId.CommandSet3; + report.ATA.CommandSet3Specified = true; + } + if(ataId.CommandSet4 != 0) + { + report.ATA.CommandSet4 = ataId.CommandSet4; + report.ATA.CommandSet4Specified = true; + } + if(ataId.CommandSet5 != 0) + { + report.ATA.CommandSet5 = ataId.CommandSet5; + report.ATA.CommandSet5Specified = true; + } + if(ataId.CurrentAAM != 0) + { + report.ATA.CurrentAAM = ataId.CurrentAAM; + report.ATA.CurrentAAMSpecified = true; + } + if(ataId.CurrentAPM != 0) + { + report.ATA.CurrentAPM = ataId.CurrentAPM; + report.ATA.CurrentAPMSpecified = true; + } + if(ataId.DataSetMgmt != 0) + { + report.ATA.DataSetMgmt = ataId.DataSetMgmt; + report.ATA.DataSetMgmtSpecified = true; + } + if(ataId.DataSetMgmtSize != 0) + { + report.ATA.DataSetMgmtSize = ataId.DataSetMgmtSize; + report.ATA.DataSetMgmtSizeSpecified = true; + } + if(ataId.DeviceFormFactor != 0) + { + report.ATA.DeviceFormFactor = ataId.DeviceFormFactor; + report.ATA.DeviceFormFactorSpecified = true; + } + if(ataId.DMAActive != 0) + { + report.ATA.DMAActive = ataId.DMAActive; + report.ATA.DMAActiveSpecified = true; + } + if(ataId.DMASupported != 0) + { + report.ATA.DMASupported = ataId.DMASupported; + report.ATA.DMASupportedSpecified = true; + } + if(ataId.DMATransferTimingMode != 0) + { + report.ATA.DMATransferTimingMode = ataId.DMATransferTimingMode; + report.ATA.DMATransferTimingModeSpecified = true; + } + if(ataId.EnhancedSecurityEraseTime != 0) + { + report.ATA.EnhancedSecurityEraseTime = ataId.EnhancedSecurityEraseTime; + report.ATA.EnhancedSecurityEraseTimeSpecified = true; + } + if(ataId.EnabledCommandSet != 0) + { + report.ATA.EnabledCommandSet = ataId.EnabledCommandSet; + report.ATA.EnabledCommandSetSpecified = true; + } + if(ataId.EnabledCommandSet2 != 0) + { + report.ATA.EnabledCommandSet2 = ataId.EnabledCommandSet2; + report.ATA.EnabledCommandSet2Specified = true; + } + if(ataId.EnabledCommandSet3 != 0) + { + report.ATA.EnabledCommandSet3 = ataId.EnabledCommandSet3; + report.ATA.EnabledCommandSet3Specified = true; + } + if(ataId.EnabledCommandSet4 != 0) + { + report.ATA.EnabledCommandSet4 = ataId.EnabledCommandSet4; + report.ATA.EnabledCommandSet4Specified = true; + } + if(ataId.EnabledSATAFeatures != 0) + { + report.ATA.EnabledSATAFeatures = ataId.EnabledSATAFeatures; + report.ATA.EnabledSATAFeaturesSpecified = true; + } + if(ataId.ExtendedUserSectors != 0) + { + report.ATA.ExtendedUserSectors = ataId.ExtendedUserSectors; + report.ATA.ExtendedUserSectorsSpecified = true; + } + if(ataId.FreeFallSensitivity != 0) + { + report.ATA.FreeFallSensitivity = ataId.FreeFallSensitivity; + report.ATA.FreeFallSensitivitySpecified = true; + } + if(!string.IsNullOrWhiteSpace(ataId.FirmwareRevision)) + { + report.ATA.FirmwareRevision = ataId.FirmwareRevision; + report.ATA.FirmwareRevisionSpecified = true; + } + if(ataId.GeneralConfiguration != 0) + { + report.ATA.GeneralConfiguration = ataId.GeneralConfiguration; + report.ATA.GeneralConfigurationSpecified = true; + } + if(ataId.HardwareResetResult != 0) + { + report.ATA.HardwareResetResult = ataId.HardwareResetResult; + report.ATA.HardwareResetResultSpecified = true; + } + if(ataId.InterseekDelay != 0) + { + report.ATA.InterseekDelay = ataId.InterseekDelay; + report.ATA.InterseekDelaySpecified = true; + } + if(ataId.MajorVersion != 0) + { + report.ATA.MajorVersion = ataId.MajorVersion; + report.ATA.MajorVersionSpecified = true; + } + if(ataId.MasterPasswordRevisionCode != 0) + { + report.ATA.MasterPasswordRevisionCode = ataId.MasterPasswordRevisionCode; + report.ATA.MasterPasswordRevisionCodeSpecified = true; + } + if(ataId.MaxDownloadMicroMode3 != 0) + { + report.ATA.MaxDownloadMicroMode3 = ataId.MaxDownloadMicroMode3; + report.ATA.MaxDownloadMicroMode3Specified = true; + } + if(ataId.MaxQueueDepth != 0) + { + report.ATA.MaxQueueDepth = ataId.MaxQueueDepth; + report.ATA.MaxQueueDepthSpecified = true; + } + if(ataId.MDMAActive != 0) + { + report.ATA.MDMAActive = ataId.MDMAActive; + report.ATA.MDMAActiveSpecified = true; + } + if(ataId.MDMASupported != 0) + { + report.ATA.MDMASupported = ataId.MDMASupported; + report.ATA.MDMASupportedSpecified = true; + } + if(ataId.MinDownloadMicroMode3 != 0) + { + report.ATA.MinDownloadMicroMode3 = ataId.MinDownloadMicroMode3; + report.ATA.MinDownloadMicroMode3Specified = true; + } + if(ataId.MinMDMACycleTime != 0) + { + report.ATA.MinMDMACycleTime = ataId.MinMDMACycleTime; + report.ATA.MinMDMACycleTimeSpecified = true; + } + if(ataId.MinorVersion != 0) + { + report.ATA.MinorVersion = ataId.MinorVersion; + report.ATA.MinorVersionSpecified = true; + } + if(ataId.MinPIOCycleTimeNoFlow != 0) + { + report.ATA.MinPIOCycleTimeNoFlow = ataId.MinPIOCycleTimeNoFlow; + report.ATA.MinPIOCycleTimeNoFlowSpecified = true; + } + if(ataId.MinPIOCycleTimeFlow != 0) + { + report.ATA.MinPIOCycleTimeFlow = ataId.MinPIOCycleTimeFlow; + report.ATA.MinPIOCycleTimeFlowSpecified = true; + } + if(!string.IsNullOrWhiteSpace(ataId.Model)) + { + report.ATA.Model = ataId.Model; + report.ATA.ModelSpecified = true; + } + if(ataId.MultipleMaxSectors != 0) + { + report.ATA.MultipleMaxSectors = ataId.MultipleMaxSectors; + report.ATA.MultipleMaxSectorsSpecified = true; + } + if(ataId.MultipleSectorNumber != 0) + { + report.ATA.MultipleSectorNumber = ataId.MultipleSectorNumber; + report.ATA.MultipleSectorNumberSpecified = true; + } + if(ataId.NVCacheCaps != 0) + { + report.ATA.NVCacheCaps = ataId.NVCacheCaps; + report.ATA.NVCacheCapsSpecified = true; + } + if(ataId.NVCacheSize != 0) + { + report.ATA.NVCacheSize = ataId.NVCacheSize; + report.ATA.NVCacheSizeSpecified = true; + } + if(ataId.NVCacheWriteSpeed != 0) + { + report.ATA.NVCacheWriteSpeed = ataId.NVCacheWriteSpeed; + report.ATA.NVCacheWriteSpeedSpecified = true; + } + if(ataId.NVEstimatedSpinUp != 0) + { + report.ATA.NVEstimatedSpinUp = ataId.NVEstimatedSpinUp; + report.ATA.NVEstimatedSpinUpSpecified = true; + } + if(ataId.PacketBusRelease != 0) + { + report.ATA.PacketBusRelease = ataId.PacketBusRelease; + report.ATA.PacketBusReleaseSpecified = true; + } + if(ataId.PIOTransferTimingMode != 0) + { + report.ATA.PIOTransferTimingMode = ataId.PIOTransferTimingMode; + report.ATA.PIOTransferTimingModeSpecified = true; + } + if(ataId.RecommendedAAM != 0) + { + report.ATA.RecommendedAAM = ataId.RecommendedAAM; + report.ATA.RecommendedAAMSpecified = true; + } + if(ataId.RecMDMACycleTime != 0) + { + report.ATA.RecommendedMDMACycleTime = ataId.RecMDMACycleTime; + report.ATA.RecommendedMDMACycleTimeSpecified = true; + } + if(ataId.RemovableStatusSet != 0) + { + report.ATA.RemovableStatusSet = ataId.RemovableStatusSet; + report.ATA.RemovableStatusSetSpecified = true; + } + if(ataId.SATACapabilities != 0) + { + report.ATA.SATACapabilities = ataId.SATACapabilities; + report.ATA.SATACapabilitiesSpecified = true; + } + if(ataId.SATACapabilities2 != 0) + { + report.ATA.SATACapabilities2 = ataId.SATACapabilities2; + report.ATA.SATACapabilities2Specified = true; + } + if(ataId.SATAFeatures != 0) + { + report.ATA.SATAFeatures = ataId.SATAFeatures; + report.ATA.SATAFeaturesSpecified = true; + } + if(ataId.SCTCommandTransport != 0) + { + report.ATA.SCTCommandTransport = ataId.SCTCommandTransport; + report.ATA.SCTCommandTransportSpecified = true; + } + if(ataId.SectorsPerCard != 0) + { + report.ATA.SectorsPerCard = ataId.SectorsPerCard; + report.ATA.SectorsPerCardSpecified = true; + } + if(ataId.SecurityEraseTime != 0) + { + report.ATA.SecurityEraseTime = ataId.SecurityEraseTime; + report.ATA.SecurityEraseTimeSpecified = true; + } + if(ataId.SecurityStatus != 0) + { + report.ATA.SecurityStatus = ataId.SecurityStatus; + report.ATA.SecurityStatusSpecified = true; + } + if(ataId.ServiceBusyClear != 0) + { + report.ATA.ServiceBusyClear = ataId.ServiceBusyClear; + report.ATA.ServiceBusyClearSpecified = true; + } + if(ataId.SpecificConfiguration != 0) + { + report.ATA.SpecificConfiguration = ataId.SpecificConfiguration; + report.ATA.SpecificConfigurationSpecified = true; + } + if(ataId.StreamAccessLatency != 0) + { + report.ATA.StreamAccessLatency = ataId.StreamAccessLatency; + report.ATA.StreamAccessLatencySpecified = true; + } + if(ataId.StreamMinReqSize != 0) + { + report.ATA.StreamMinReqSize = ataId.StreamMinReqSize; + report.ATA.StreamMinReqSizeSpecified = true; + } + if(ataId.StreamPerformanceGranularity != 0) + { + report.ATA.StreamPerformanceGranularity = ataId.StreamPerformanceGranularity; + report.ATA.StreamPerformanceGranularitySpecified = true; + } + if(ataId.StreamTransferTimeDMA != 0) + { + report.ATA.StreamTransferTimeDMA = ataId.StreamTransferTimeDMA; + report.ATA.StreamTransferTimeDMASpecified = true; + } + if(ataId.StreamTransferTimePIO != 0) + { + report.ATA.StreamTransferTimePIO = ataId.StreamTransferTimePIO; + report.ATA.StreamTransferTimePIOSpecified = true; + } + if(ataId.TransportMajorVersion != 0) + { + report.ATA.TransportMajorVersion = ataId.TransportMajorVersion; + report.ATA.TransportMajorVersionSpecified = true; + } + if(ataId.TransportMinorVersion != 0) + { + report.ATA.TransportMinorVersion = ataId.TransportMinorVersion; + report.ATA.TransportMinorVersionSpecified = true; + } + if(ataId.TrustedComputing != 0) + { + report.ATA.TrustedComputing = ataId.TrustedComputing; + report.ATA.TrustedComputingSpecified = true; + } + if(ataId.UDMAActive != 0) + { + report.ATA.UDMAActive = ataId.UDMAActive; + report.ATA.UDMAActiveSpecified = true; + } + if(ataId.UDMASupported != 0) + { + report.ATA.UDMASupported = ataId.UDMASupported; + report.ATA.UDMASupportedSpecified = true; + } + if(ataId.WRVMode != 0) + { + report.ATA.WRVMode = ataId.WRVMode; + report.ATA.WRVModeSpecified = true; + } + if(ataId.WRVSectorCountMode3 != 0) + { + report.ATA.WRVSectorCountMode3 = ataId.WRVSectorCountMode3; + report.ATA.WRVSectorCountMode3Specified = true; + } + if(ataId.WRVSectorCountMode2 != 0) + { + report.ATA.WRVSectorCountMode2 = ataId.WRVSectorCountMode2; + report.ATA.WRVSectorCountMode2Specified = true; + } + + if(removable) + { + List mediaTests = new List(); + + pressedKey = new ConsoleKeyInfo(); + while(pressedKey.Key != ConsoleKey.N) + { + pressedKey = new ConsoleKeyInfo(); + while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N) + { + DicConsole.Write("Do you have media that you can insert in the drive? (Y/N): "); + pressedKey = System.Console.ReadKey(); + DicConsole.WriteLine(); + } + + if(pressedKey.Key == ConsoleKey.Y) + { + DicConsole.WriteLine("Please insert it in the drive and press any key when it is ready."); + System.Console.ReadKey(true); + + 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 model and press enter: "); + mediaTest.Model = System.Console.ReadLine(); + + mediaTest.ManufacturerSpecified = true; + mediaTest.ModelSpecified = true; + mediaTest.MediaIsRecognized = true; + + DicConsole.WriteLine("Querying ATA IDENTIFY..."); + dev.AtaIdentify(out buffer, out errorRegs, timeout, out duration); + + if(Decoders.ATA.Identify.Decode(buffer).HasValue) + { + ataId = Decoders.ATA.Identify.Decode(buffer).Value; + + if(ataId.UnformattedBPT != 0) + { + mediaTest.UnformattedBPT = ataId.UnformattedBPT; + mediaTest.UnformattedBPTSpecified = true; + } + if(ataId.UnformattedBPS != 0) + { + mediaTest.UnformattedBPS = ataId.UnformattedBPS; + mediaTest.UnformattedBPSSpecified = true; + } + + if(ataId.Cylinders > 0 && ataId.Heads > 0 && ataId.SectorsPerTrack > 0) + { + mediaTest.CHS = new chsType(); + mediaTest.CHS.Cylinders = ataId.Cylinders; + mediaTest.CHS.Heads = ataId.Heads; + mediaTest.CHS.Sectors = ataId.SectorsPerTrack; + mediaTest.Blocks = (ulong)(ataId.Cylinders * ataId.Heads * ataId.SectorsPerTrack); + mediaTest.BlocksSpecified = true; + } + + if(ataId.CurrentCylinders > 0 && ataId.CurrentHeads > 0 && ataId.CurrentSectorsPerTrack > 0) + { + mediaTest.CurrentCHS = new chsType(); + mediaTest.CurrentCHS.Cylinders = ataId.CurrentCylinders; + mediaTest.CurrentCHS.Heads = ataId.CurrentHeads; + mediaTest.CurrentCHS.Sectors = ataId.CurrentSectorsPerTrack; + mediaTest.Blocks = (ulong)(ataId.CurrentCylinders * ataId.CurrentHeads * ataId.CurrentSectorsPerTrack); + mediaTest.BlocksSpecified = true; + } + + if(ataId.Capabilities.HasFlag(Decoders.ATA.Identify.CapabilitiesBit.LBASupport)) + { + mediaTest.LBASectors = ataId.LBASectors; + mediaTest.LBASectorsSpecified = true; + mediaTest.Blocks = ataId.LBASectors; + mediaTest.BlocksSpecified = true; + } + + if(ataId.CommandSet2.HasFlag(Decoders.ATA.Identify.CommandSetBit2.LBA48)) + { + mediaTest.LBA48Sectors = ataId.LBA48Sectors; + mediaTest.LBA48SectorsSpecified = true; + mediaTest.Blocks = ataId.LBA48Sectors; + mediaTest.BlocksSpecified = true; + } + + if(ataId.NominalRotationRate != 0x0000 && + ataId.NominalRotationRate != 0xFFFF) + { + if(ataId.NominalRotationRate == 0x0001) + { + mediaTest.SolidStateDevice = true; + mediaTest.SolidStateDeviceSpecified = true; + } + else + { + mediaTest.SolidStateDevice = false; + mediaTest.SolidStateDeviceSpecified = true; + mediaTest.NominalRotationRate = ataId.NominalRotationRate; + mediaTest.NominalRotationRateSpecified = true; + } + } + + uint logicalsectorsize = 0; + 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) + { +#pragma warning disable IDE0004 // Cast is necessary, otherwise incorrect value is created + physicalsectorsize = logicalsectorsize * (uint)Math.Pow(2, (double)(ataId.PhysLogSectorSize & 0xF)); +#pragma warning restore IDE0004 // Cast is necessary, otherwise incorrect value is created + } + else + physicalsectorsize = logicalsectorsize; + } + else + { + logicalsectorsize = 512; + physicalsectorsize = 512; + } + + mediaTest.BlockSize = logicalsectorsize; + mediaTest.BlockSizeSpecified = true; + if(physicalsectorsize != logicalsectorsize) + { + mediaTest.PhysicalBlockSize = physicalsectorsize; + mediaTest.PhysicalBlockSizeSpecified = true; + + if((ataId.LogicalAlignment & 0x8000) == 0x0000 && + (ataId.LogicalAlignment & 0x4000) == 0x4000) + { + mediaTest.LogicalAlignment = (ushort)(ataId.LogicalAlignment & 0x3FFF); + mediaTest.LogicalAlignmentSpecified = true; + } + } + + if(ataId.EccBytes != 0x0000 && ataId.EccBytes != 0xFFFF) + { + mediaTest.LongBlockSize = logicalsectorsize + ataId.EccBytes; + mediaTest.LongBlockSizeSpecified = true; + } + + if(ataId.CommandSet3.HasFlag(Decoders.ATA.Identify.CommandSetBit3.MustBeSet) && + !ataId.CommandSet3.HasFlag(Decoders.ATA.Identify.CommandSetBit3.MustBeClear) && + ataId.EnabledCommandSet3.HasFlag(Decoders.ATA.Identify.CommandSetBit3.MediaSerial)) + { + mediaTest.CanReadMediaSerial = true; + mediaTest.CanReadMediaSerialSpecified = true; + if(!string.IsNullOrWhiteSpace(ataId.MediaManufacturer)) + { + mediaTest.Manufacturer = ataId.MediaManufacturer; + mediaTest.ManufacturerSpecified = true; + } + } + + mediaTest.SupportsReadLbaSpecified = true; + mediaTest.SupportsReadRetryLbaSpecified = true; + mediaTest.SupportsReadDmaLbaSpecified = true; + mediaTest.SupportsReadDmaRetryLbaSpecified = true; + mediaTest.SupportsReadLongLbaSpecified = true; + mediaTest.SupportsReadLongRetryLbaSpecified = true; + mediaTest.SupportsSeekLbaSpecified = true; + + mediaTest.SupportsReadLba48Specified = true; + mediaTest.SupportsReadDmaLba48Specified = true; + + mediaTest.SupportsReadSpecified = true; + mediaTest.SupportsReadRetrySpecified = true; + mediaTest.SupportsReadDmaSpecified = true; + mediaTest.SupportsReadDmaRetrySpecified = true; + mediaTest.SupportsReadLongSpecified = true; + mediaTest.SupportsReadLongRetrySpecified = true; + mediaTest.SupportsSeekSpecified = true; + + Decoders.ATA.AtaErrorRegistersCHS errorChs; + Decoders.ATA.AtaErrorRegistersLBA28 errorLba; + Decoders.ATA.AtaErrorRegistersLBA48 errorLba48; + + byte[] readBuf; + ulong checkCorrectRead = BitConverter.ToUInt64(buffer, 0); + bool sense = true; + + DicConsole.WriteLine("Trying READ SECTOR(S) in CHS mode..."); + sense = dev.Read(out readBuf, out errorChs, false, 0, 0, 1, 1, timeout, out duration); + mediaTest.SupportsRead = (!sense && (errorChs.status & 0x01) != 0x01 && errorChs.error == 0 && readBuf.Length > 0); + DicConsole.WriteLine("Trying READ SECTOR(S) RETRY in CHS mode..."); + sense = dev.Read(out readBuf, out errorChs, true, 0, 0, 1, 1, timeout, out duration); + mediaTest.SupportsReadRetry = (!sense && (errorChs.status & 0x01) != 0x01 && errorChs.error == 0 && readBuf.Length > 0); + DicConsole.WriteLine("Trying READ DMA in CHS mode..."); + sense = dev.ReadDma(out readBuf, out errorChs, false, 0, 0, 1, 1, timeout, out duration); + mediaTest.SupportsReadDma = (!sense && (errorChs.status & 0x01) != 0x01 && errorChs.error == 0 && readBuf.Length > 0); + DicConsole.WriteLine("Trying READ DMA RETRY in CHS mode..."); + sense = dev.ReadDma(out readBuf, out errorChs, true, 0, 0, 1, 1, timeout, out duration); + mediaTest.SupportsReadDmaRetry = (!sense && (errorChs.status & 0x01) != 0x01 && errorChs.error == 0 && readBuf.Length > 0); + DicConsole.WriteLine("Trying READ LONG in CHS mode..."); + sense = dev.ReadLong(out readBuf, out errorChs, false, 0, 0, 1, mediaTest.LongBlockSize, timeout, out duration); + mediaTest.SupportsReadLong = (!sense && (errorChs.status & 0x01) != 0x01 && errorChs.error == 0 && readBuf.Length > 0 && BitConverter.ToUInt64(readBuf, 0) != checkCorrectRead); + DicConsole.WriteLine("Trying READ LONG RETRY in CHS mode..."); + sense = dev.ReadLong(out readBuf, out errorChs, true, 0, 0, 1, mediaTest.LongBlockSize, timeout, out duration); + mediaTest.SupportsReadLongRetry = (!sense && (errorChs.status & 0x01) != 0x01 && errorChs.error == 0 && readBuf.Length > 0 && BitConverter.ToUInt64(readBuf, 0) != checkCorrectRead); + DicConsole.WriteLine("Trying SEEK in CHS mode..."); + sense = dev.Seek(out errorChs, 0, 0, 1, timeout, out duration); + mediaTest.SupportsSeek = (!sense && (errorChs.status & 0x01) != 0x01 && errorChs.error == 0); + + DicConsole.WriteLine("Trying READ SECTOR(S) in LBA mode..."); + sense = dev.Read(out readBuf, out errorLba, false, 0, 1, timeout, out duration); + mediaTest.SupportsReadLba = (!sense && (errorLba.status & 0x01) != 0x01 && errorLba.error == 0 && readBuf.Length > 0); + DicConsole.WriteLine("Trying READ SECTOR(S) RETRY in LBA mode..."); + sense = dev.Read(out readBuf, out errorLba, true, 0, 1, timeout, out duration); + mediaTest.SupportsReadRetryLba = (!sense && (errorLba.status & 0x01) != 0x01 && errorLba.error == 0 && readBuf.Length > 0); + DicConsole.WriteLine("Trying READ DMA in LBA mode..."); + sense = dev.ReadDma(out readBuf, out errorLba, false, 0, 1, timeout, out duration); + mediaTest.SupportsReadDmaLba = (!sense && (errorLba.status & 0x01) != 0x01 && errorLba.error == 0 && readBuf.Length > 0); + DicConsole.WriteLine("Trying READ DMA RETRY in LBA mode..."); + sense = dev.ReadDma(out readBuf, out errorLba, true, 0, 1, timeout, out duration); + mediaTest.SupportsReadDmaRetryLba = (!sense && (errorLba.status & 0x01) != 0x01 && errorLba.error == 0 && readBuf.Length > 0); + DicConsole.WriteLine("Trying READ LONG in LBA mode..."); + sense = dev.ReadLong(out readBuf, out errorLba, false, 0, mediaTest.LongBlockSize, timeout, out duration); + mediaTest.SupportsReadLongLba = (!sense && (errorLba.status & 0x01) != 0x01 && errorLba.error == 0 && readBuf.Length > 0 && BitConverter.ToUInt64(readBuf, 0) != checkCorrectRead); + DicConsole.WriteLine("Trying READ LONG RETRY in LBA mode..."); + sense = dev.ReadLong(out readBuf, out errorLba, true, 0, mediaTest.LongBlockSize, timeout, out duration); + mediaTest.SupportsReadLongRetryLba = (!sense && (errorLba.status & 0x01) != 0x01 && errorLba.error == 0 && readBuf.Length > 0 && BitConverter.ToUInt64(readBuf, 0) != checkCorrectRead); + DicConsole.WriteLine("Trying SEEK in LBA mode..."); + sense = dev.Seek(out errorLba, 0, timeout, out duration); + mediaTest.SupportsSeekLba = (!sense && (errorLba.status & 0x01) != 0x01 && errorLba.error == 0); + + DicConsole.WriteLine("Trying READ SECTOR(S) in LBA48 mode..."); + sense = dev.Read(out readBuf, out errorLba48, 0, 1, timeout, out duration); + mediaTest.SupportsReadLba48 = (!sense && (errorLba48.status & 0x01) != 0x01 && errorLba48.error == 0 && readBuf.Length > 0); + DicConsole.WriteLine("Trying READ DMA in LBA48 mode..."); + sense = dev.ReadDma(out readBuf, out errorLba48, 0, 1, timeout, out duration); + mediaTest.SupportsReadDmaLba48 = (!sense && (errorLba48.status & 0x01) != 0x01 && errorLba48.error == 0 && readBuf.Length > 0); + } + else + mediaTest.MediaIsRecognized = false; + + mediaTests.Add(mediaTest); + } + } + report.ATA.RemovableMedias = mediaTests.ToArray(); + } + else + { + report.ATA.ReadCapabilities = new testedMediaType(); + + if(ataId.UnformattedBPT != 0) + { + report.ATA.ReadCapabilities.UnformattedBPT = ataId.UnformattedBPT; + report.ATA.ReadCapabilities.UnformattedBPTSpecified = true; + } + if(ataId.UnformattedBPS != 0) + { + report.ATA.ReadCapabilities.UnformattedBPS = ataId.UnformattedBPS; + report.ATA.ReadCapabilities.UnformattedBPSSpecified = true; + } + + if(ataId.Cylinders > 0 && ataId.Heads > 0 && ataId.SectorsPerTrack > 0) + { + report.ATA.ReadCapabilities.CHS = new chsType(); + report.ATA.ReadCapabilities.CHS.Cylinders = ataId.Cylinders; + report.ATA.ReadCapabilities.CHS.Heads = ataId.Heads; + report.ATA.ReadCapabilities.CHS.Sectors = ataId.SectorsPerTrack; + report.ATA.ReadCapabilities.Blocks = (ulong)(ataId.Cylinders * ataId.Heads * ataId.SectorsPerTrack); + report.ATA.ReadCapabilities.BlocksSpecified = true; + } + + if(ataId.CurrentCylinders > 0 && ataId.CurrentHeads > 0 && ataId.CurrentSectorsPerTrack > 0) + { + report.ATA.ReadCapabilities.CurrentCHS = new chsType(); + report.ATA.ReadCapabilities.CurrentCHS.Cylinders = ataId.CurrentCylinders; + report.ATA.ReadCapabilities.CurrentCHS.Heads = ataId.CurrentHeads; + report.ATA.ReadCapabilities.CurrentCHS.Sectors = ataId.CurrentSectorsPerTrack; + report.ATA.ReadCapabilities.Blocks = (ulong)(ataId.CurrentCylinders * ataId.CurrentHeads * ataId.CurrentSectorsPerTrack); + report.ATA.ReadCapabilities.BlocksSpecified = true; + } + + if(ataId.Capabilities.HasFlag(Decoders.ATA.Identify.CapabilitiesBit.LBASupport)) + { + report.ATA.ReadCapabilities.LBASectors = ataId.LBASectors; + report.ATA.ReadCapabilities.LBASectorsSpecified = true; + report.ATA.ReadCapabilities.Blocks = ataId.LBASectors; + report.ATA.ReadCapabilities.BlocksSpecified = true; + } + + if(ataId.CommandSet2.HasFlag(Decoders.ATA.Identify.CommandSetBit2.LBA48)) + { + report.ATA.ReadCapabilities.LBA48Sectors = ataId.LBA48Sectors; + report.ATA.ReadCapabilities.LBA48SectorsSpecified = true; + report.ATA.ReadCapabilities.Blocks = ataId.LBA48Sectors; + report.ATA.ReadCapabilities.BlocksSpecified = true; + } + + if(ataId.NominalRotationRate != 0x0000 && + ataId.NominalRotationRate != 0xFFFF) + { + if(ataId.NominalRotationRate == 0x0001) + { + report.ATA.ReadCapabilities.SolidStateDevice = true; + report.ATA.ReadCapabilities.SolidStateDeviceSpecified = true; + } + else + { + report.ATA.ReadCapabilities.SolidStateDevice = false; + report.ATA.ReadCapabilities.SolidStateDeviceSpecified = true; + report.ATA.ReadCapabilities.NominalRotationRate = ataId.NominalRotationRate; + report.ATA.ReadCapabilities.NominalRotationRateSpecified = true; + } + } + + uint logicalsectorsize = 0; + 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) + { +#pragma warning disable IDE0004 // Cast is necessary, otherwise incorrect value is created + physicalsectorsize = logicalsectorsize * (uint)Math.Pow(2, (double)(ataId.PhysLogSectorSize & 0xF)); +#pragma warning restore IDE0004 // Cast is necessary, otherwise incorrect value is created + } + else + physicalsectorsize = logicalsectorsize; + } + else + { + logicalsectorsize = 512; + physicalsectorsize = 512; + } + + report.ATA.ReadCapabilities.BlockSize = logicalsectorsize; + report.ATA.ReadCapabilities.BlockSizeSpecified = true; + if(physicalsectorsize != logicalsectorsize) + { + report.ATA.ReadCapabilities.PhysicalBlockSize = physicalsectorsize; + report.ATA.ReadCapabilities.PhysicalBlockSizeSpecified = true; + + if((ataId.LogicalAlignment & 0x8000) == 0x0000 && + (ataId.LogicalAlignment & 0x4000) == 0x4000) + { + report.ATA.ReadCapabilities.LogicalAlignment = (ushort)(ataId.LogicalAlignment & 0x3FFF); + report.ATA.ReadCapabilities.LogicalAlignmentSpecified = true; + } + } + + if(ataId.EccBytes != 0x0000 && ataId.EccBytes != 0xFFFF) + { + report.ATA.ReadCapabilities.LongBlockSize = logicalsectorsize + ataId.EccBytes; + report.ATA.ReadCapabilities.LongBlockSizeSpecified = true; + } + + if(ataId.CommandSet3.HasFlag(Decoders.ATA.Identify.CommandSetBit3.MustBeSet) && + !ataId.CommandSet3.HasFlag(Decoders.ATA.Identify.CommandSetBit3.MustBeClear) && + ataId.EnabledCommandSet3.HasFlag(Decoders.ATA.Identify.CommandSetBit3.MediaSerial)) + { + report.ATA.ReadCapabilities.CanReadMediaSerial = true; + report.ATA.ReadCapabilities.CanReadMediaSerialSpecified = true; + if(!string.IsNullOrWhiteSpace(ataId.MediaManufacturer)) + { + report.ATA.ReadCapabilities.Manufacturer = ataId.MediaManufacturer; + report.ATA.ReadCapabilities.ManufacturerSpecified = true; + } + } + + report.ATA.ReadCapabilities.SupportsReadLbaSpecified = true; + report.ATA.ReadCapabilities.SupportsReadRetryLbaSpecified = true; + report.ATA.ReadCapabilities.SupportsReadDmaLbaSpecified = true; + report.ATA.ReadCapabilities.SupportsReadDmaRetryLbaSpecified = true; + report.ATA.ReadCapabilities.SupportsReadLongLbaSpecified = true; + report.ATA.ReadCapabilities.SupportsReadLongRetryLbaSpecified = true; + report.ATA.ReadCapabilities.SupportsSeekLbaSpecified = true; + + report.ATA.ReadCapabilities.SupportsReadLba48Specified = true; + report.ATA.ReadCapabilities.SupportsReadDmaLba48Specified = true; + + report.ATA.ReadCapabilities.SupportsReadSpecified = true; + report.ATA.ReadCapabilities.SupportsReadRetrySpecified = true; + report.ATA.ReadCapabilities.SupportsReadDmaSpecified = true; + report.ATA.ReadCapabilities.SupportsReadDmaRetrySpecified = true; + report.ATA.ReadCapabilities.SupportsReadLongSpecified = true; + report.ATA.ReadCapabilities.SupportsReadLongRetrySpecified = true; + report.ATA.ReadCapabilities.SupportsSeekSpecified = true; + + Decoders.ATA.AtaErrorRegistersCHS errorChs; + Decoders.ATA.AtaErrorRegistersLBA28 errorLba; + Decoders.ATA.AtaErrorRegistersLBA48 errorLba48; + + byte[] readBuf; + ulong checkCorrectRead = BitConverter.ToUInt64(buffer, 0); + bool sense = true; + + DicConsole.WriteLine("Trying READ SECTOR(S) in CHS mode..."); + sense = dev.Read(out readBuf, out errorChs, false, 0, 0, 1, 1, timeout, out duration); + report.ATA.ReadCapabilities.SupportsRead = (!sense && (errorChs.status & 0x01) != 0x01 && errorChs.error == 0 && readBuf.Length > 0); + DicConsole.WriteLine("Trying READ SECTOR(S) RETRY in CHS mode..."); + sense = dev.Read(out readBuf, out errorChs, true, 0, 0, 1, 1, timeout, out duration); + report.ATA.ReadCapabilities.SupportsReadRetry = (!sense && (errorChs.status & 0x01) != 0x01 && errorChs.error == 0 && readBuf.Length > 0); + DicConsole.WriteLine("Trying READ DMA in CHS mode..."); + sense = dev.ReadDma(out readBuf, out errorChs, false, 0, 0, 1, 1, timeout, out duration); + report.ATA.ReadCapabilities.SupportsReadDma = (!sense && (errorChs.status & 0x01) != 0x01 && errorChs.error == 0 && readBuf.Length > 0); + DicConsole.WriteLine("Trying READ DMA RETRY in CHS mode..."); + sense = dev.ReadDma(out readBuf, out errorChs, true, 0, 0, 1, 1, timeout, out duration); + report.ATA.ReadCapabilities.SupportsReadDmaRetry = (!sense && (errorChs.status & 0x01) != 0x01 && errorChs.error == 0 && readBuf.Length > 0); + DicConsole.WriteLine("Trying READ LONG in CHS mode..."); + sense = dev.ReadLong(out readBuf, out errorChs, false, 0, 0, 1, report.ATA.ReadCapabilities.LongBlockSize, timeout, out duration); + report.ATA.ReadCapabilities.SupportsReadLong = (!sense && (errorChs.status & 0x01) != 0x01 && errorChs.error == 0 && readBuf.Length > 0 && BitConverter.ToUInt64(readBuf, 0) != checkCorrectRead); + DicConsole.WriteLine("Trying READ LONG RETRY in CHS mode..."); + sense = dev.ReadLong(out readBuf, out errorChs, true, 0, 0, 1, report.ATA.ReadCapabilities.LongBlockSize, timeout, out duration); + report.ATA.ReadCapabilities.SupportsReadLongRetry = (!sense && (errorChs.status & 0x01) != 0x01 && errorChs.error == 0 && readBuf.Length > 0 && BitConverter.ToUInt64(readBuf, 0) != checkCorrectRead); + DicConsole.WriteLine("Trying SEEK in CHS mode..."); + sense = dev.Seek(out errorChs, 0, 0, 1, timeout, out duration); + report.ATA.ReadCapabilities.SupportsSeek = (!sense && (errorChs.status & 0x01) != 0x01 && errorChs.error == 0); + + DicConsole.WriteLine("Trying READ SECTOR(S) in LBA mode..."); + sense = dev.Read(out readBuf, out errorLba, false, 0, 1, timeout, out duration); + report.ATA.ReadCapabilities.SupportsReadLba = (!sense && (errorLba.status & 0x01) != 0x01 && errorLba.error == 0 && readBuf.Length > 0); + DicConsole.WriteLine("Trying READ SECTOR(S) RETRY in LBA mode..."); + sense = dev.Read(out readBuf, out errorLba, true, 0, 1, timeout, out duration); + report.ATA.ReadCapabilities.SupportsReadRetryLba = (!sense && (errorLba.status & 0x01) != 0x01 && errorLba.error == 0 && readBuf.Length > 0); + DicConsole.WriteLine("Trying READ DMA in LBA mode..."); + sense = dev.ReadDma(out readBuf, out errorLba, false, 0, 1, timeout, out duration); + report.ATA.ReadCapabilities.SupportsReadDmaLba = (!sense && (errorLba.status & 0x01) != 0x01 && errorLba.error == 0 && readBuf.Length > 0); + DicConsole.WriteLine("Trying READ DMA RETRY in LBA mode..."); + sense = dev.ReadDma(out readBuf, out errorLba, true, 0, 1, timeout, out duration); + report.ATA.ReadCapabilities.SupportsReadDmaRetryLba = (!sense && (errorLba.status & 0x01) != 0x01 && errorLba.error == 0 && readBuf.Length > 0); + DicConsole.WriteLine("Trying READ LONG in LBA mode..."); + sense = dev.ReadLong(out readBuf, out errorLba, false, 0, report.ATA.ReadCapabilities.LongBlockSize, timeout, out duration); + report.ATA.ReadCapabilities.SupportsReadLongLba = (!sense && (errorLba.status & 0x01) != 0x01 && errorLba.error == 0 && readBuf.Length > 0 && BitConverter.ToUInt64(readBuf, 0) != checkCorrectRead); + DicConsole.WriteLine("Trying READ LONG RETRY in LBA mode..."); + sense = dev.ReadLong(out readBuf, out errorLba, true, 0, report.ATA.ReadCapabilities.LongBlockSize, timeout, out duration); + report.ATA.ReadCapabilities.SupportsReadLongRetryLba = (!sense && (errorLba.status & 0x01) != 0x01 && errorLba.error == 0 && readBuf.Length > 0 && BitConverter.ToUInt64(readBuf, 0) != checkCorrectRead); + DicConsole.WriteLine("Trying SEEK in LBA mode..."); + sense = dev.Seek(out errorLba, 0, timeout, out duration); + report.ATA.ReadCapabilities.SupportsSeekLba = (!sense && (errorLba.status & 0x01) != 0x01 && errorLba.error == 0); + + DicConsole.WriteLine("Trying READ SECTOR(S) in LBA48 mode..."); + sense = dev.Read(out readBuf, out errorLba48, 0, 1, timeout, out duration); + report.ATA.ReadCapabilities.SupportsReadLba48 = (!sense && (errorLba48.status & 0x01) != 0x01 && errorLba48.error == 0 && readBuf.Length > 0); + DicConsole.WriteLine("Trying READ DMA in LBA48 mode..."); + sense = dev.ReadDma(out readBuf, out errorLba48, 0, 1, timeout, out duration); + report.ATA.ReadCapabilities.SupportsReadDmaLba48 = (!sense && (errorLba48.status & 0x01) != 0x01 && errorLba48.error == 0 && readBuf.Length > 0); + } + } + } + } +} diff --git a/DiscImageChef.Core/Devices/Report/ATAPI.cs b/DiscImageChef.Core/Devices/Report/ATAPI.cs new file mode 100644 index 000000000..9ec42af62 --- /dev/null +++ b/DiscImageChef.Core/Devices/Report/ATAPI.cs @@ -0,0 +1,464 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : ATAPI.cs +// Version : 1.0 +// Author(s) : Natalia Portillo +// +// Component : Component +// +// Revision : $Revision$ +// Last change by : $Author$ +// Date : $Date$ +// +// --[ Description ] ---------------------------------------------------------- +// +// Description +// +// --[ 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 . +// +// ---------------------------------------------------------------------------- +// Copyright (C) 2011-2015 Claunia.com +// ****************************************************************************/ +// //$Id$ +using DiscImageChef.Console; +using DiscImageChef.Devices; +using DiscImageChef.Metadata; + +namespace DiscImageChef.Core.Devices.Report +{ + public static class ATAPI + { + public static void Report(Device dev, ref DeviceReport report, bool debug, ref bool removable) + { + if(report == null) + return; + + byte[] buffer; + double duration; + uint timeout = 5; + + DicConsole.WriteLine("Querying ATAPI IDENTIFY..."); + + Decoders.ATA.AtaErrorRegistersCHS errorRegs; + dev.AtapiIdentify(out buffer, out errorRegs, timeout, out duration); + + if(Decoders.ATA.Identify.Decode(buffer).HasValue) + { + Decoders.ATA.Identify.IdentifyDevice atapiId = Decoders.ATA.Identify.Decode(buffer).Value; + + report.ATAPI = new ataType(); + + if(!string.IsNullOrWhiteSpace(atapiId.AdditionalPID)) + { + report.ATAPI.AdditionalPID = atapiId.AdditionalPID; + report.ATAPI.AdditionalPIDSpecified = true; + } + if(atapiId.APIOSupported != 0) + { + report.ATAPI.APIOSupported = atapiId.APIOSupported; + report.ATAPI.APIOSupportedSpecified = true; + } + if(atapiId.ATAPIByteCount != 0) + { + report.ATAPI.ATAPIByteCount = atapiId.ATAPIByteCount; + report.ATAPI.ATAPIByteCountSpecified = true; + } + if(atapiId.BufferType != 0) + { + report.ATAPI.BufferType = atapiId.BufferType; + report.ATAPI.BufferTypeSpecified = true; + } + if(atapiId.BufferSize != 0) + { + report.ATAPI.BufferSize = atapiId.BufferSize; + report.ATAPI.BufferSizeSpecified = true; + } + if(atapiId.Capabilities != 0) + { + report.ATAPI.Capabilities = atapiId.Capabilities; + report.ATAPI.CapabilitiesSpecified = true; + } + if(atapiId.Capabilities2 != 0) + { + report.ATAPI.Capabilities2 = atapiId.Capabilities2; + report.ATAPI.Capabilities2Specified = true; + } + if(atapiId.Capabilities3 != 0) + { + report.ATAPI.Capabilities3 = atapiId.Capabilities3; + report.ATAPI.Capabilities3Specified = true; + } + if(atapiId.CFAPowerMode != 0) + { + report.ATAPI.CFAPowerMode = atapiId.CFAPowerMode; + report.ATAPI.CFAPowerModeSpecified = true; + } + if(atapiId.CommandSet != 0) + { + report.ATAPI.CommandSet = atapiId.CommandSet; + report.ATAPI.CommandSetSpecified = true; + } + if(atapiId.CommandSet2 != 0) + { + report.ATAPI.CommandSet2 = atapiId.CommandSet2; + report.ATAPI.CommandSet2Specified = true; + } + if(atapiId.CommandSet3 != 0) + { + report.ATAPI.CommandSet3 = atapiId.CommandSet3; + report.ATAPI.CommandSet3Specified = true; + } + if(atapiId.CommandSet4 != 0) + { + report.ATAPI.CommandSet4 = atapiId.CommandSet4; + report.ATAPI.CommandSet4Specified = true; + } + if(atapiId.CommandSet5 != 0) + { + report.ATAPI.CommandSet5 = atapiId.CommandSet5; + report.ATAPI.CommandSet5Specified = true; + } + if(atapiId.CurrentAAM != 0) + { + report.ATAPI.CurrentAAM = atapiId.CurrentAAM; + report.ATAPI.CurrentAAMSpecified = true; + } + if(atapiId.CurrentAPM != 0) + { + report.ATAPI.CurrentAPM = atapiId.CurrentAPM; + report.ATAPI.CurrentAPMSpecified = true; + } + if(atapiId.DataSetMgmt != 0) + { + report.ATAPI.DataSetMgmt = atapiId.DataSetMgmt; + report.ATAPI.DataSetMgmtSpecified = true; + } + if(atapiId.DataSetMgmtSize != 0) + { + report.ATAPI.DataSetMgmtSize = atapiId.DataSetMgmtSize; + report.ATAPI.DataSetMgmtSizeSpecified = true; + } + if(atapiId.DeviceFormFactor != 0) + { + report.ATAPI.DeviceFormFactor = atapiId.DeviceFormFactor; + report.ATAPI.DeviceFormFactorSpecified = true; + } + if(atapiId.DMAActive != 0) + { + report.ATAPI.DMAActive = atapiId.DMAActive; + report.ATAPI.DMAActiveSpecified = true; + } + if(atapiId.DMASupported != 0) + { + report.ATAPI.DMASupported = atapiId.DMASupported; + report.ATAPI.DMASupportedSpecified = true; + } + if(atapiId.DMATransferTimingMode != 0) + { + report.ATAPI.DMATransferTimingMode = atapiId.DMATransferTimingMode; + report.ATAPI.DMATransferTimingModeSpecified = true; + } + if(atapiId.EnhancedSecurityEraseTime != 0) + { + report.ATAPI.EnhancedSecurityEraseTime = atapiId.EnhancedSecurityEraseTime; + report.ATAPI.EnhancedSecurityEraseTimeSpecified = true; + } + if(atapiId.EnabledCommandSet != 0) + { + report.ATAPI.EnabledCommandSet = atapiId.EnabledCommandSet; + report.ATAPI.EnabledCommandSetSpecified = true; + } + if(atapiId.EnabledCommandSet2 != 0) + { + report.ATAPI.EnabledCommandSet2 = atapiId.EnabledCommandSet2; + report.ATAPI.EnabledCommandSet2Specified = true; + } + if(atapiId.EnabledCommandSet3 != 0) + { + report.ATAPI.EnabledCommandSet3 = atapiId.EnabledCommandSet3; + report.ATAPI.EnabledCommandSet3Specified = true; + } + if(atapiId.EnabledCommandSet4 != 0) + { + report.ATAPI.EnabledCommandSet4 = atapiId.EnabledCommandSet4; + report.ATAPI.EnabledCommandSet4Specified = true; + } + if(atapiId.EnabledSATAFeatures != 0) + { + report.ATAPI.EnabledSATAFeatures = atapiId.EnabledSATAFeatures; + report.ATAPI.EnabledSATAFeaturesSpecified = true; + } + if(atapiId.ExtendedUserSectors != 0) + { + report.ATAPI.ExtendedUserSectors = atapiId.ExtendedUserSectors; + report.ATAPI.ExtendedUserSectorsSpecified = true; + } + if(atapiId.FreeFallSensitivity != 0) + { + report.ATAPI.FreeFallSensitivity = atapiId.FreeFallSensitivity; + report.ATAPI.FreeFallSensitivitySpecified = true; + } + if(!string.IsNullOrWhiteSpace(atapiId.FirmwareRevision)) + { + report.ATAPI.FirmwareRevision = atapiId.FirmwareRevision; + report.ATAPI.FirmwareRevisionSpecified = true; + } + if(atapiId.GeneralConfiguration != 0) + { + report.ATAPI.GeneralConfiguration = atapiId.GeneralConfiguration; + report.ATAPI.GeneralConfigurationSpecified = true; + } + if(atapiId.HardwareResetResult != 0) + { + report.ATAPI.HardwareResetResult = atapiId.HardwareResetResult; + report.ATAPI.HardwareResetResultSpecified = true; + } + if(atapiId.InterseekDelay != 0) + { + report.ATAPI.InterseekDelay = atapiId.InterseekDelay; + report.ATAPI.InterseekDelaySpecified = true; + } + if(atapiId.MajorVersion != 0) + { + report.ATAPI.MajorVersion = atapiId.MajorVersion; + report.ATAPI.MajorVersionSpecified = true; + } + if(atapiId.MasterPasswordRevisionCode != 0) + { + report.ATAPI.MasterPasswordRevisionCode = atapiId.MasterPasswordRevisionCode; + report.ATAPI.MasterPasswordRevisionCodeSpecified = true; + } + if(atapiId.MaxDownloadMicroMode3 != 0) + { + report.ATAPI.MaxDownloadMicroMode3 = atapiId.MaxDownloadMicroMode3; + report.ATAPI.MaxDownloadMicroMode3Specified = true; + } + if(atapiId.MaxQueueDepth != 0) + { + report.ATAPI.MaxQueueDepth = atapiId.MaxQueueDepth; + report.ATAPI.MaxQueueDepthSpecified = true; + } + if(atapiId.MDMAActive != 0) + { + report.ATAPI.MDMAActive = atapiId.MDMAActive; + report.ATAPI.MDMAActiveSpecified = true; + } + if(atapiId.MDMASupported != 0) + { + report.ATAPI.MDMASupported = atapiId.MDMASupported; + report.ATAPI.MDMASupportedSpecified = true; + } + if(atapiId.MinDownloadMicroMode3 != 0) + { + report.ATAPI.MinDownloadMicroMode3 = atapiId.MinDownloadMicroMode3; + report.ATAPI.MinDownloadMicroMode3Specified = true; + } + if(atapiId.MinMDMACycleTime != 0) + { + report.ATAPI.MinMDMACycleTime = atapiId.MinMDMACycleTime; + report.ATAPI.MinMDMACycleTimeSpecified = true; + } + if(atapiId.MinorVersion != 0) + { + report.ATAPI.MinorVersion = atapiId.MinorVersion; + report.ATAPI.MinorVersionSpecified = true; + } + if(atapiId.MinPIOCycleTimeNoFlow != 0) + { + report.ATAPI.MinPIOCycleTimeNoFlow = atapiId.MinPIOCycleTimeNoFlow; + report.ATAPI.MinPIOCycleTimeNoFlowSpecified = true; + } + if(atapiId.MinPIOCycleTimeFlow != 0) + { + report.ATAPI.MinPIOCycleTimeFlow = atapiId.MinPIOCycleTimeFlow; + report.ATAPI.MinPIOCycleTimeFlowSpecified = true; + } + if(!string.IsNullOrWhiteSpace(atapiId.Model)) + { + report.ATAPI.Model = atapiId.Model; + report.ATAPI.ModelSpecified = true; + } + if(atapiId.MultipleMaxSectors != 0) + { + report.ATAPI.MultipleMaxSectors = atapiId.MultipleMaxSectors; + report.ATAPI.MultipleMaxSectorsSpecified = true; + } + if(atapiId.MultipleSectorNumber != 0) + { + report.ATAPI.MultipleSectorNumber = atapiId.MultipleSectorNumber; + report.ATAPI.MultipleSectorNumberSpecified = true; + } + if(atapiId.NVCacheCaps != 0) + { + report.ATAPI.NVCacheCaps = atapiId.NVCacheCaps; + report.ATAPI.NVCacheCapsSpecified = true; + } + if(atapiId.NVCacheSize != 0) + { + report.ATAPI.NVCacheSize = atapiId.NVCacheSize; + report.ATAPI.NVCacheSizeSpecified = true; + } + if(atapiId.NVCacheWriteSpeed != 0) + { + report.ATAPI.NVCacheWriteSpeed = atapiId.NVCacheWriteSpeed; + report.ATAPI.NVCacheWriteSpeedSpecified = true; + } + if(atapiId.NVEstimatedSpinUp != 0) + { + report.ATAPI.NVEstimatedSpinUp = atapiId.NVEstimatedSpinUp; + report.ATAPI.NVEstimatedSpinUpSpecified = true; + } + if(atapiId.PacketBusRelease != 0) + { + report.ATAPI.PacketBusRelease = atapiId.PacketBusRelease; + report.ATAPI.PacketBusReleaseSpecified = true; + } + if(atapiId.PIOTransferTimingMode != 0) + { + report.ATAPI.PIOTransferTimingMode = atapiId.PIOTransferTimingMode; + report.ATAPI.PIOTransferTimingModeSpecified = true; + } + if(atapiId.RecommendedAAM != 0) + { + report.ATAPI.RecommendedAAM = atapiId.RecommendedAAM; + report.ATAPI.RecommendedAAMSpecified = true; + } + if(atapiId.RecMDMACycleTime != 0) + { + report.ATAPI.RecommendedMDMACycleTime = atapiId.RecMDMACycleTime; + report.ATAPI.RecommendedMDMACycleTimeSpecified = true; + } + if(atapiId.RemovableStatusSet != 0) + { + report.ATAPI.RemovableStatusSet = atapiId.RemovableStatusSet; + report.ATAPI.RemovableStatusSetSpecified = true; + } + if(atapiId.SATACapabilities != 0) + { + report.ATAPI.SATACapabilities = atapiId.SATACapabilities; + report.ATAPI.SATACapabilitiesSpecified = true; + } + if(atapiId.SATACapabilities2 != 0) + { + report.ATAPI.SATACapabilities2 = atapiId.SATACapabilities2; + report.ATAPI.SATACapabilities2Specified = true; + } + if(atapiId.SATAFeatures != 0) + { + report.ATAPI.SATAFeatures = atapiId.SATAFeatures; + report.ATAPI.SATAFeaturesSpecified = true; + } + if(atapiId.SCTCommandTransport != 0) + { + report.ATAPI.SCTCommandTransport = atapiId.SCTCommandTransport; + report.ATAPI.SCTCommandTransportSpecified = true; + } + if(atapiId.SectorsPerCard != 0) + { + report.ATAPI.SectorsPerCard = atapiId.SectorsPerCard; + report.ATAPI.SectorsPerCardSpecified = true; + } + if(atapiId.SecurityEraseTime != 0) + { + report.ATAPI.SecurityEraseTime = atapiId.SecurityEraseTime; + report.ATAPI.SecurityEraseTimeSpecified = true; + } + if(atapiId.SecurityStatus != 0) + { + report.ATAPI.SecurityStatus = atapiId.SecurityStatus; + report.ATAPI.SecurityStatusSpecified = true; + } + if(atapiId.ServiceBusyClear != 0) + { + report.ATAPI.ServiceBusyClear = atapiId.ServiceBusyClear; + report.ATAPI.ServiceBusyClearSpecified = true; + } + if(atapiId.SpecificConfiguration != 0) + { + report.ATAPI.SpecificConfiguration = atapiId.SpecificConfiguration; + report.ATAPI.SpecificConfigurationSpecified = true; + } + if(atapiId.StreamAccessLatency != 0) + { + report.ATAPI.StreamAccessLatency = atapiId.StreamAccessLatency; + report.ATAPI.StreamAccessLatencySpecified = true; + } + if(atapiId.StreamMinReqSize != 0) + { + report.ATAPI.StreamMinReqSize = atapiId.StreamMinReqSize; + report.ATAPI.StreamMinReqSizeSpecified = true; + } + if(atapiId.StreamPerformanceGranularity != 0) + { + report.ATAPI.StreamPerformanceGranularity = atapiId.StreamPerformanceGranularity; + report.ATAPI.StreamPerformanceGranularitySpecified = true; + } + if(atapiId.StreamTransferTimeDMA != 0) + { + report.ATAPI.StreamTransferTimeDMA = atapiId.StreamTransferTimeDMA; + report.ATAPI.StreamTransferTimeDMASpecified = true; + } + if(atapiId.StreamTransferTimePIO != 0) + { + report.ATAPI.StreamTransferTimePIO = atapiId.StreamTransferTimePIO; + report.ATAPI.StreamTransferTimePIOSpecified = true; + } + if(atapiId.TransportMajorVersion != 0) + { + report.ATAPI.TransportMajorVersion = atapiId.TransportMajorVersion; + report.ATAPI.TransportMajorVersionSpecified = true; + } + if(atapiId.TransportMinorVersion != 0) + { + report.ATAPI.TransportMinorVersion = atapiId.TransportMinorVersion; + report.ATAPI.TransportMinorVersionSpecified = true; + } + if(atapiId.TrustedComputing != 0) + { + report.ATAPI.TrustedComputing = atapiId.TrustedComputing; + report.ATAPI.TrustedComputingSpecified = true; + } + if(atapiId.UDMAActive != 0) + { + report.ATAPI.UDMAActive = atapiId.UDMAActive; + report.ATAPI.UDMAActiveSpecified = true; + } + if(atapiId.UDMASupported != 0) + { + report.ATAPI.UDMASupported = atapiId.UDMASupported; + report.ATAPI.UDMASupportedSpecified = true; + } + if(atapiId.WRVMode != 0) + { + report.ATAPI.WRVMode = atapiId.WRVMode; + report.ATAPI.WRVModeSpecified = true; + } + if(atapiId.WRVSectorCountMode3 != 0) + { + report.ATAPI.WRVSectorCountMode3 = atapiId.WRVSectorCountMode3; + report.ATAPI.WRVSectorCountMode3Specified = true; + } + if(atapiId.WRVSectorCountMode2 != 0) + { + report.ATAPI.WRVSectorCountMode2 = atapiId.WRVSectorCountMode2; + report.ATAPI.WRVSectorCountMode2Specified = true; + } + } + } + } +} diff --git a/DiscImageChef.Core/Devices/Report/FireWire.cs b/DiscImageChef.Core/Devices/Report/FireWire.cs new file mode 100644 index 000000000..1ed931d9e --- /dev/null +++ b/DiscImageChef.Core/Devices/Report/FireWire.cs @@ -0,0 +1,81 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : FireWire.cs +// Version : 1.0 +// Author(s) : Natalia Portillo +// +// Component : Component +// +// Revision : $Revision$ +// Last change by : $Author$ +// Date : $Date$ +// +// --[ Description ] ---------------------------------------------------------- +// +// Description +// +// --[ 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 . +// +// ---------------------------------------------------------------------------- +// Copyright (C) 2011-2015 Claunia.com +// ****************************************************************************/ +// //$Id$ +using System; +using DiscImageChef.Console; +using DiscImageChef.Devices; +using DiscImageChef.Metadata; + +namespace DiscImageChef.Core.Devices.Report +{ + public static class FireWire + { + public static void Report(Device dev, ref DeviceReport report, bool debug, ref bool removable) + { + if(report == null) + return; + + ConsoleKeyInfo pressedKey = new ConsoleKeyInfo(); + while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N) + { + DicConsole.Write("Is the device natively FireWire (in case of doubt, press Y)? (Y/N): "); + pressedKey = System.Console.ReadKey(); + DicConsole.WriteLine(); + } + + if(pressedKey.Key == ConsoleKey.Y) + { + report.FireWire = new firewireType(); + report.FireWire.Manufacturer = dev.FireWireVendorName; + report.FireWire.Product = dev.FireWireModelName; + report.FireWire.ProductID = dev.FireWireModel; + report.FireWire.VendorID = dev.FireWireVendor; + + pressedKey = new ConsoleKeyInfo(); + while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N) + { + DicConsole.Write("Is the media removable from the reading/writing elements? (Y/N): "); + pressedKey = System.Console.ReadKey(); + DicConsole.WriteLine(); + } + + report.FireWire.RemovableMedia = pressedKey.Key == ConsoleKey.Y; + removable = report.FireWire.RemovableMedia; + } + } + } +} diff --git a/DiscImageChef.Core/Devices/Report/NVMe.cs b/DiscImageChef.Core/Devices/Report/NVMe.cs new file mode 100644 index 000000000..3cc834976 --- /dev/null +++ b/DiscImageChef.Core/Devices/Report/NVMe.cs @@ -0,0 +1,54 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : NVMe.cs +// Version : 1.0 +// Author(s) : Natalia Portillo +// +// Component : Component +// +// Revision : $Revision$ +// Last change by : $Author$ +// Date : $Date$ +// +// --[ Description ] ---------------------------------------------------------- +// +// Description +// +// --[ 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 . +// +// ---------------------------------------------------------------------------- +// Copyright (C) 2011-2015 Claunia.com +// ****************************************************************************/ +// //$Id$ +using System; +using DiscImageChef.Devices; +using DiscImageChef.Metadata; + +namespace DiscImageChef.Core.Devices.Report +{ + public static class NVMe + { + public static void Report(Device dev, ref DeviceReport report, bool debug, ref bool removable) + { + if(report == null) + return; + + throw new NotImplementedException("NVMe devices not yet supported."); + } + } +} diff --git a/DiscImageChef.Core/Devices/Report/PCMCIA.cs b/DiscImageChef.Core/Devices/Report/PCMCIA.cs new file mode 100644 index 000000000..fc772a385 --- /dev/null +++ b/DiscImageChef.Core/Devices/Report/PCMCIA.cs @@ -0,0 +1,83 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : PCMCIA.cs +// Version : 1.0 +// Author(s) : Natalia Portillo +// +// Component : Component +// +// Revision : $Revision$ +// Last change by : $Author$ +// Date : $Date$ +// +// --[ Description ] ---------------------------------------------------------- +// +// Description +// +// --[ 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 . +// +// ---------------------------------------------------------------------------- +// Copyright (C) 2011-2015 Claunia.com +// ****************************************************************************/ +// //$Id$ +using DiscImageChef.Decoders.PCMCIA; +using DiscImageChef.Devices; +using DiscImageChef.Metadata; + +namespace DiscImageChef.Core.Devices.Report +{ + public static class PCMCIA + { + public static void Report(Device dev, ref DeviceReport report, bool debug, ref bool removable) + { + report.PCMCIA = new pcmciaType(); + report.PCMCIA.CIS = dev.CIS; + Decoders.PCMCIA.Tuple[] tuples = CIS.GetTuples(dev.CIS); + if(tuples != null) + { + foreach(Decoders.PCMCIA.Tuple tuple in tuples) + { + if(tuple.Code == TupleCodes.CISTPL_MANFID) + { + ManufacturerIdentificationTuple manfid = CIS.DecodeManufacturerIdentificationTuple(tuple); + + if(manfid != null) + { + report.PCMCIA.ManufacturerCode = manfid.ManufacturerID; + report.PCMCIA.CardCode = manfid.CardID; + report.PCMCIA.ManufacturerCodeSpecified = true; + report.PCMCIA.CardCodeSpecified = true; + } + } + else if(tuple.Code == TupleCodes.CISTPL_VERS_1) + { + Level1VersionTuple vers = CIS.DecodeLevel1VersionTuple(tuple); + + if(vers != null) + { + report.PCMCIA.Manufacturer = vers.Manufacturer; + report.PCMCIA.ProductName = vers.Product; + report.PCMCIA.Compliance = string.Format("{0}.{1}", vers.MajorVersion, vers.MinorVersion); + report.PCMCIA.AdditionalInformation = vers.AdditionalInformation; + } + } + } + } + } + } +} diff --git a/DiscImageChef.Core/Devices/Report/SCSI/General.cs b/DiscImageChef.Core/Devices/Report/SCSI/General.cs new file mode 100644 index 000000000..ea7f46f65 --- /dev/null +++ b/DiscImageChef.Core/Devices/Report/SCSI/General.cs @@ -0,0 +1,792 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : SCSI.cs +// Version : 1.0 +// Author(s) : Natalia Portillo +// +// Component : Component +// +// Revision : $Revision$ +// Last change by : $Author$ +// Date : $Date$ +// +// --[ Description ] ---------------------------------------------------------- +// +// Description +// +// --[ 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 . +// +// ---------------------------------------------------------------------------- +// Copyright (C) 2011-2015 Claunia.com +// ****************************************************************************/ +// //$Id$ +using System; +using System.Collections.Generic; +using System.IO; +using DiscImageChef.Console; +using DiscImageChef.Devices; +using DiscImageChef.Metadata; + +namespace DiscImageChef.Core.Devices.Report.SCSI +{ + public static class General + { + public static void Report(Device dev, ref DeviceReport report, bool debug, ref bool removable) + { + if(report == null) + return; + + byte[] senseBuffer; + byte[] buffer; + double duration; + bool sense; + uint timeout = 5; + ConsoleKeyInfo pressedKey; + + if(dev.IsUSB) + USB.Report(dev, ref report, debug, ref removable); + + if(dev.IsFireWire) + FireWire.Report(dev, ref report, debug, ref removable); + + if(!dev.IsUSB && !dev.IsFireWire && dev.IsRemovable) + { + pressedKey = new ConsoleKeyInfo(); + while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N) + { + DicConsole.Write("Is the media removable from the reading/writing elements (flash memories ARE NOT removable)? (Y/N): "); + pressedKey = System.Console.ReadKey(); + DicConsole.WriteLine(); + } + + removable = pressedKey.Key == ConsoleKey.Y; + } + + if(dev.Type == DeviceType.ATAPI) + ATAPI.Report(dev, ref report, debug, ref removable); + + DicConsole.WriteLine("Querying SCSI INQUIRY..."); + sense = dev.ScsiInquiry(out buffer, out senseBuffer); + + report.SCSI = new scsiType(); + + if(!sense && Decoders.SCSI.Inquiry.Decode(buffer).HasValue) + { + Decoders.SCSI.Inquiry.SCSIInquiry inq = Decoders.SCSI.Inquiry.Decode(buffer).Value; + + List versionDescriptors = new List(); + 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))) + { + report.SCSI.Inquiry.VendorIdentification = StringHandlers.CToString(inq.VendorIdentification).Trim(); + if(!string.IsNullOrWhiteSpace(report.SCSI.Inquiry.VendorIdentification)) + report.SCSI.Inquiry.VendorIdentificationSpecified = true; + } + if(!string.IsNullOrWhiteSpace(StringHandlers.CToString(inq.ProductIdentification))) + { + report.SCSI.Inquiry.ProductIdentification = StringHandlers.CToString(inq.ProductIdentification).Trim(); + if(!string.IsNullOrWhiteSpace(report.SCSI.Inquiry.ProductIdentification)) + report.SCSI.Inquiry.ProductIdentificationSpecified = true; + } + if(!string.IsNullOrWhiteSpace(StringHandlers.CToString(inq.ProductRevisionLevel))) + { + report.SCSI.Inquiry.ProductRevisionLevel = StringHandlers.CToString(inq.ProductRevisionLevel).Trim(); + if(!string.IsNullOrWhiteSpace(report.SCSI.Inquiry.ProductRevisionLevel)) + report.SCSI.Inquiry.ProductRevisionLevelSpecified = true; + } + if(inq.VersionDescriptors != null) + { + foreach(ushort descriptor in inq.VersionDescriptors) + { + if(descriptor != 0) + versionDescriptors.Add(descriptor); + } + + if(versionDescriptors.Count > 0) + report.SCSI.Inquiry.VersionDescriptors = versionDescriptors.ToArray(); + } + + report.SCSI.Inquiry.PeripheralQualifier = (Decoders.SCSI.PeripheralQualifiers)inq.PeripheralQualifier; + report.SCSI.Inquiry.PeripheralDeviceType = (Decoders.SCSI.PeripheralDeviceTypes)inq.PeripheralDeviceType; + report.SCSI.Inquiry.AsymmetricalLUNAccess = (Decoders.SCSI.TGPSValues)inq.TPGS; + report.SCSI.Inquiry.SPIClocking = (Decoders.SCSI.SPIClocking)inq.Clocking; + + 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; + } + + DicConsole.WriteLine("Querying list of SCSI EVPDs..."); + sense = dev.ScsiInquiry(out buffer, out senseBuffer, 0x00); + + if(!sense) + { + byte[] evpdPages = Decoders.SCSI.EVPD.DecodePage00(buffer); + if(evpdPages != null && evpdPages.Length > 0) + { + List evpds = new List(); + foreach(byte page in evpdPages) + { + if(page != 0x80) + { + DicConsole.WriteLine("Querying SCSI EVPD {0:X2}h...", page); + sense = dev.ScsiInquiry(out buffer, out senseBuffer, page); + if(!sense) + { + pageType evpd = new pageType(); + evpd.page = page; + evpd.value = buffer; + evpds.Add(evpd); + } + } + } + if(evpds.Count > 0) + report.SCSI.EVPDPages = evpds.ToArray(); + } + } + + if(removable) + { + if(dev.SCSIType == Decoders.SCSI.PeripheralDeviceTypes.MultiMediaDevice) + { + dev.AllowMediumRemoval(out senseBuffer, timeout, out duration); + dev.EjectTray(out senseBuffer, timeout, out duration); + } + else if(dev.SCSIType == Decoders.SCSI.PeripheralDeviceTypes.SequentialAccess) + { + dev.SpcAllowMediumRemoval(out senseBuffer, timeout, out duration); + DicConsole.WriteLine("Asking drive to unload tape (can take a few minutes)..."); + dev.Unload(out senseBuffer, timeout, out duration); + } + DicConsole.WriteLine("Please remove any media from the device and press any key when it is out."); + System.Console.ReadKey(true); + } + + Decoders.SCSI.Modes.DecodedMode? decMode = null; + Decoders.SCSI.PeripheralDeviceTypes devType = dev.SCSIType; + + DicConsole.WriteLine("Querying all mode pages and subpages using SCSI MODE SENSE (10)..."); + sense = dev.ModeSense10(out buffer, out senseBuffer, false, true, ScsiModeSensePageControl.Default, 0x3F, 0xFF, timeout, out duration); + if(sense || dev.Error) + { + DicConsole.WriteLine("Querying all mode pages using SCSI MODE SENSE (10)..."); + sense = dev.ModeSense10(out buffer, out senseBuffer, false, true, ScsiModeSensePageControl.Default, 0x3F, 0x00, timeout, out duration); + if(!sense && dev.Error) + { + report.SCSI.SupportsModeSense10 = true; + report.SCSI.SupportsModeSubpages = false; + decMode = Decoders.SCSI.Modes.DecodeMode10(buffer, devType); + } + } + else + { + report.SCSI.SupportsModeSense10 = true; + report.SCSI.SupportsModeSubpages = true; + decMode = Decoders.SCSI.Modes.DecodeMode10(buffer, devType); + } + + DicConsole.WriteLine("Querying all mode pages and subpages using SCSI MODE SENSE (6)..."); + sense = dev.ModeSense6(out buffer, out senseBuffer, false, ScsiModeSensePageControl.Default, 0x3F, 0xFF, timeout, out duration); + if(sense || dev.Error) + { + DicConsole.WriteLine("Querying all mode pages using SCSI MODE SENSE (6)..."); + sense = dev.ModeSense6(out buffer, out senseBuffer, false, ScsiModeSensePageControl.Default, 0x3F, 0x00, timeout, out duration); + if(sense || dev.Error) + { + DicConsole.WriteLine("Querying SCSI MODE SENSE (6)..."); + sense = dev.ModeSense(out buffer, out senseBuffer, timeout, out duration); + } + } + else + report.SCSI.SupportsModeSubpages = true; + + if(!sense && !dev.Error && !decMode.HasValue) + decMode = Decoders.SCSI.Modes.DecodeMode6(buffer, devType); + + report.SCSI.SupportsModeSense6 |= (!sense && !dev.Error); + + Decoders.SCSI.Modes.ModePage_2A? cdromMode = null; + + if(decMode.HasValue) + { + report.SCSI.ModeSense = new modeType(); + report.SCSI.ModeSense.BlankCheckEnabled = decMode.Value.Header.EBC; + report.SCSI.ModeSense.DPOandFUA = decMode.Value.Header.DPOFUA; + report.SCSI.ModeSense.WriteProtected = decMode.Value.Header.WriteProtected; + + 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 modePages = new List(); + foreach(Decoders.SCSI.Modes.ModePage page in decMode.Value.Pages) + { + modePageType modePage = new modePageType(); + modePage.page = page.Page; + modePage.subpage = page.Subpage; + modePage.value = page.PageResponse; + modePages.Add(modePage); + + if(modePage.page == 0x2A && modePage.subpage == 0x00) + { + cdromMode = Decoders.SCSI.Modes.DecodeModePage_2A(page.PageResponse); + } + } + + if(modePages.Count > 0) + report.SCSI.ModeSense.ModePages = modePages.ToArray(); + } + } + + List mediaTypes = new List(); + + if(dev.SCSIType == Decoders.SCSI.PeripheralDeviceTypes.MultiMediaDevice) + MMC.Report(dev, ref report, debug, ref cdromMode, ref mediaTypes); + else if(dev.SCSIType == Decoders.SCSI.PeripheralDeviceTypes.SequentialAccess) + SSC.Report(dev, ref report); + else + { + if(removable) + { + List mediaTests = new List(); + + pressedKey = new ConsoleKeyInfo(); + while(pressedKey.Key != ConsoleKey.N) + { + pressedKey = new ConsoleKeyInfo(); + while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N) + { + DicConsole.Write("Do you have media that you can insert in the drive? (Y/N): "); + pressedKey = System.Console.ReadKey(); + DicConsole.WriteLine(); + } + + if(pressedKey.Key == ConsoleKey.Y) + { + DicConsole.WriteLine("Please insert it in the drive and press any key when it is ready."); + System.Console.ReadKey(true); + + 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(); + + mediaTest.ManufacturerSpecified = true; + mediaTest.ModelSpecified = true; + mediaTest.MediaIsRecognized = true; + + sense = dev.ScsiTestUnitReady(out senseBuffer, timeout, out duration); + if(sense) + { + Decoders.SCSI.FixedSense? decSense = Decoders.SCSI.Sense.DecodeFixed(senseBuffer); + if(decSense.HasValue) + { + if(decSense.Value.ASC == 0x3A) + { + int leftRetries = 20; + while(leftRetries > 0) + { + DicConsole.Write("\rWaiting for drive to become ready"); + System.Threading.Thread.Sleep(2000); + sense = dev.ScsiTestUnitReady(out senseBuffer, timeout, out duration); + if(!sense) + break; + + leftRetries--; + } + + mediaTest.MediaIsRecognized &= !sense; + } + else if(decSense.Value.ASC == 0x04 && decSense.Value.ASCQ == 0x01) + { + int leftRetries = 20; + while(leftRetries > 0) + { + DicConsole.Write("\rWaiting for drive to become ready"); + System.Threading.Thread.Sleep(2000); + sense = dev.ScsiTestUnitReady(out senseBuffer, timeout, out duration); + if(!sense) + break; + + leftRetries--; + } + + mediaTest.MediaIsRecognized &= !sense; + } + else + mediaTest.MediaIsRecognized = false; + } + else + mediaTest.MediaIsRecognized = false; + } + + if(mediaTest.MediaIsRecognized) + { + mediaTest.SupportsReadCapacitySpecified = true; + mediaTest.SupportsReadCapacity16Specified = true; + + DicConsole.WriteLine("Querying SCSI READ CAPACITY..."); + sense = dev.ReadCapacity(out buffer, out senseBuffer, timeout, out duration); + 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[5] << 24) + (buffer[5] << 16) + (buffer[6] << 8) + (buffer[7])); + mediaTest.BlocksSpecified = true; + mediaTest.BlockSizeSpecified = true; + } + + DicConsole.WriteLine("Querying SCSI READ CAPACITY (16)..."); + sense = dev.ReadCapacity16(out buffer, out buffer, timeout, out duration); + 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[5] << 24) + (buffer[5] << 16) + (buffer[6] << 8) + (buffer[7])); + mediaTest.BlocksSpecified = true; + mediaTest.BlockSizeSpecified = true; + } + + decMode = null; + + DicConsole.WriteLine("Querying SCSI MODE SENSE (10)..."); + sense = dev.ModeSense10(out buffer, out senseBuffer, false, true, ScsiModeSensePageControl.Current, 0x3F, 0x00, timeout, out duration); + if(!sense && !dev.Error) + { + report.SCSI.SupportsModeSense10 = true; + decMode = Decoders.SCSI.Modes.DecodeMode10(buffer, dev.SCSIType); + } + + DicConsole.WriteLine("Querying SCSI MODE SENSE..."); + sense = dev.ModeSense(out buffer, out senseBuffer, timeout, out duration); + if(!sense && !dev.Error) + { + report.SCSI.SupportsModeSense6 = true; + if(!decMode.HasValue) + decMode = Decoders.SCSI.Modes.DecodeMode6(buffer, dev.SCSIType); + } + + 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) + { + mediaTest.Density = (byte)decMode.Value.Header.BlockDescriptors[0].Density; + mediaTest.DensitySpecified = true; + } + } + + mediaTest.SupportsReadSpecified = true; + mediaTest.SupportsRead10Specified = true; + mediaTest.SupportsRead12Specified = true; + mediaTest.SupportsRead16Specified = true; + mediaTest.SupportsReadLongSpecified = true; + + DicConsole.WriteLine("Trying SCSI READ (6)..."); + mediaTest.SupportsRead = !dev.Read6(out buffer, out senseBuffer, 0, mediaTest.BlockSize, timeout, out duration); + DicConsole.WriteLine("Trying SCSI READ (10)..."); + mediaTest.SupportsRead10 = !dev.Read10(out buffer, out senseBuffer, 0, false, true, false, false, 0, mediaTest.BlockSize, 0, 1, timeout, out duration); + DicConsole.WriteLine("Trying SCSI READ (12)..."); + mediaTest.SupportsRead12 = !dev.Read12(out buffer, out senseBuffer, 0, false, true, false, false, 0, mediaTest.BlockSize, 0, 1, false, timeout, out duration); + DicConsole.WriteLine("Trying SCSI READ (16)..."); + mediaTest.SupportsRead16 = !dev.Read16(out buffer, out senseBuffer, 0, false, true, false, 0, mediaTest.BlockSize, 0, 1, false, timeout, out duration); + + mediaTest.LongBlockSize = mediaTest.BlockSize; + DicConsole.WriteLine("Trying SCSI READ LONG (10)..."); + sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 0xFFFF, timeout, out duration); + if(sense && !dev.Error) + { + Decoders.SCSI.FixedSense? decSense = Decoders.SCSI.Sense.DecodeFixed(senseBuffer); + if(decSense.HasValue) + { + if(decSense.Value.SenseKey == Decoders.SCSI.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); + mediaTest.LongBlockSizeSpecified = true; + } + } + } + } + + if(mediaTest.SupportsReadLong && mediaTest.LongBlockSize == mediaTest.BlockSize) + { + if(mediaTest.BlockSize == 512) + { + // Long sector sizes for 512-byte magneto-opticals + foreach(ushort testSize in new[] { 600, 610, 630 }) + { + sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, testSize, timeout, out duration); + if(!sense && !dev.Error) + { + mediaTest.SupportsReadLong = true; + mediaTest.LongBlockSize = testSize; + mediaTest.LongBlockSizeSpecified = true; + break; + } + } + } + else if(mediaTest.BlockSize == 1024) + { + sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 1200, timeout, out duration); + if(!sense && !dev.Error) + { + mediaTest.SupportsReadLong = true; + mediaTest.LongBlockSize = 1200; + mediaTest.LongBlockSizeSpecified = true; + } + } + else if(mediaTest.BlockSize == 2048) + { + sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 2380, timeout, out duration); + if(!sense && !dev.Error) + { + mediaTest.SupportsReadLong = true; + mediaTest.LongBlockSize = 2380; + mediaTest.LongBlockSizeSpecified = true; + } + } + else if(mediaTest.BlockSize == 4096) + { + sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 4760, timeout, out duration); + if(!sense && !dev.Error) + { + mediaTest.SupportsReadLong = true; + mediaTest.LongBlockSize = 4760; + mediaTest.LongBlockSizeSpecified = true; + } + } + else if(mediaTest.BlockSize == 8192) + { + sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 9424, timeout, out duration); + if(!sense && !dev.Error) + { + mediaTest.SupportsReadLong = true; + mediaTest.LongBlockSize = 9424; + mediaTest.LongBlockSizeSpecified = true; + } + } + } + + 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) + { + for(ushort i = (ushort)mediaTest.BlockSize; i < (ushort)mediaTest.BlockSize * 36; i++) + { + DicConsole.Write("\rTrying to READ LONG with a size of {0} bytes...", i); + sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, i, timeout, out duration); + if(!sense) + { + if(debug) + { + FileStream bingo = new FileStream(string.Format("{0}_readlong.bin", mediaTest.MediumTypeName), FileMode.Create); + bingo.Write(buffer, 0, buffer.Length); + bingo.Close(); + } + mediaTest.LongBlockSize = i; + mediaTest.LongBlockSizeSpecified = true; + break; + } + } + DicConsole.WriteLine(); + } + } + + mediaTest.CanReadMediaSerialSpecified = true; + DicConsole.WriteLine("Trying SCSI READ MEDIA SERIAL NUMBER..."); + mediaTest.CanReadMediaSerial = !dev.ReadMediaSerialNumber(out buffer, out senseBuffer, timeout, out duration); + } + mediaTests.Add(mediaTest); + } + } + report.SCSI.RemovableMedias = mediaTests.ToArray(); + } + else + { + report.SCSI.ReadCapabilities = new testedMediaType(); + report.SCSI.ReadCapabilitiesSpecified = true; + report.SCSI.ReadCapabilities.MediaIsRecognized = true; + + report.SCSI.ReadCapabilities.SupportsReadCapacitySpecified = true; + report.SCSI.ReadCapabilities.SupportsReadCapacity16Specified = true; + + DicConsole.WriteLine("Querying SCSI READ CAPACITY..."); + sense = dev.ReadCapacity(out buffer, out senseBuffer, timeout, out duration); + 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[5] << 24) + (buffer[5] << 16) + (buffer[6] << 8) + (buffer[7])); + report.SCSI.ReadCapabilities.BlocksSpecified = true; + report.SCSI.ReadCapabilities.BlockSizeSpecified = true; + } + + DicConsole.WriteLine("Querying SCSI READ CAPACITY (16)..."); + sense = dev.ReadCapacity16(out buffer, out buffer, timeout, out duration); + 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[5] << 24) + (buffer[5] << 16) + (buffer[6] << 8) + (buffer[7])); + report.SCSI.ReadCapabilities.BlocksSpecified = true; + report.SCSI.ReadCapabilities.BlockSizeSpecified = true; + } + + decMode = null; + + DicConsole.WriteLine("Querying SCSI MODE SENSE (10)..."); + sense = dev.ModeSense10(out buffer, out senseBuffer, false, true, ScsiModeSensePageControl.Current, 0x3F, 0x00, timeout, out duration); + if(!sense && !dev.Error) + { + report.SCSI.SupportsModeSense10 = true; + decMode = Decoders.SCSI.Modes.DecodeMode10(buffer, dev.SCSIType); + } + + DicConsole.WriteLine("Querying SCSI MODE SENSE..."); + sense = dev.ModeSense(out buffer, out senseBuffer, timeout, out duration); + if(!sense && !dev.Error) + { + report.SCSI.SupportsModeSense6 = true; + if(!decMode.HasValue) + decMode = Decoders.SCSI.Modes.DecodeMode6(buffer, dev.SCSIType); + } + + 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; + } + } + + 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)..."); + report.SCSI.ReadCapabilities.SupportsRead = !dev.Read6(out buffer, out senseBuffer, 0, report.SCSI.ReadCapabilities.BlockSize, timeout, out duration); + DicConsole.WriteLine("Trying SCSI READ (10)..."); + report.SCSI.ReadCapabilities.SupportsRead10 = !dev.Read10(out buffer, out senseBuffer, 0, false, true, false, false, 0, report.SCSI.ReadCapabilities.BlockSize, 0, 1, timeout, out duration); + DicConsole.WriteLine("Trying SCSI READ (12)..."); + report.SCSI.ReadCapabilities.SupportsRead12 = !dev.Read12(out buffer, out senseBuffer, 0, false, true, false, false, 0, report.SCSI.ReadCapabilities.BlockSize, 0, 1, false, timeout, out duration); + DicConsole.WriteLine("Trying SCSI READ (16)..."); + report.SCSI.ReadCapabilities.SupportsRead16 = !dev.Read16(out buffer, out senseBuffer, 0, false, true, false, 0, report.SCSI.ReadCapabilities.BlockSize, 0, 1, false, timeout, out duration); + + report.SCSI.ReadCapabilities.LongBlockSize = report.SCSI.ReadCapabilities.BlockSize; + DicConsole.WriteLine("Trying SCSI READ LONG (10)..."); + sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 0xFFFF, timeout, out duration); + if(sense && !dev.Error) + { + Decoders.SCSI.FixedSense? decSense = Decoders.SCSI.Sense.DecodeFixed(senseBuffer); + if(decSense.HasValue) + { + if(decSense.Value.SenseKey == Decoders.SCSI.SenseKeys.IllegalRequest && + decSense.Value.ASC == 0x24 && decSense.Value.ASCQ == 0x00) + { + report.SCSI.ReadCapabilities.SupportsReadLong = true; + if(decSense.Value.InformationValid && decSense.Value.ILI) + { + report.SCSI.ReadCapabilities.LongBlockSize = 0xFFFF - (decSense.Value.Information & 0xFFFF); + report.SCSI.ReadCapabilities.LongBlockSizeSpecified = true; + } + } + } + } + + if(report.SCSI.ReadCapabilities.SupportsReadLong && report.SCSI.ReadCapabilities.LongBlockSize == report.SCSI.ReadCapabilities.BlockSize) + { + if(report.SCSI.ReadCapabilities.BlockSize == 512) + { + // Long sector sizes for 512-byte magneto-opticals + foreach(ushort testSize in new[] { 600, 610, 630 }) + { + sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, testSize, timeout, out duration); + if(!sense && !dev.Error) + { + report.SCSI.ReadCapabilities.SupportsReadLong = true; + report.SCSI.ReadCapabilities.LongBlockSize = testSize; + report.SCSI.ReadCapabilities.LongBlockSizeSpecified = true; + break; + } + } + } + else if(report.SCSI.ReadCapabilities.BlockSize == 1024) + { + sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 1200, timeout, out duration); + if(!sense && !dev.Error) + { + report.SCSI.ReadCapabilities.SupportsReadLong = true; + report.SCSI.ReadCapabilities.LongBlockSize = 1200; + report.SCSI.ReadCapabilities.LongBlockSizeSpecified = true; + } + } + else if(report.SCSI.ReadCapabilities.BlockSize == 2048) + { + sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 2380, timeout, out duration); + if(!sense && !dev.Error) + { + report.SCSI.ReadCapabilities.SupportsReadLong = true; + report.SCSI.ReadCapabilities.LongBlockSize = 2380; + report.SCSI.ReadCapabilities.LongBlockSizeSpecified = true; + } + } + else if(report.SCSI.ReadCapabilities.BlockSize == 4096) + { + sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 4760, timeout, out duration); + if(!sense && !dev.Error) + { + report.SCSI.ReadCapabilities.SupportsReadLong = true; + report.SCSI.ReadCapabilities.LongBlockSize = 4760; + report.SCSI.ReadCapabilities.LongBlockSizeSpecified = true; + } + } + else if(report.SCSI.ReadCapabilities.BlockSize == 8192) + { + sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 9424, timeout, out duration); + if(!sense && !dev.Error) + { + report.SCSI.ReadCapabilities.SupportsReadLong = true; + report.SCSI.ReadCapabilities.LongBlockSize = 9424; + report.SCSI.ReadCapabilities.LongBlockSizeSpecified = true; + } + } + } + + if(report.SCSI.ReadCapabilities.SupportsReadLong && report.SCSI.ReadCapabilities.LongBlockSize == report.SCSI.ReadCapabilities.BlockSize) + { + pressedKey = new ConsoleKeyInfo(); + while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N) + { + DicConsole.Write("Drive supports SCSI READ LONG but I cannot find the correct size. Do you want me to try? (This can take hours) (Y/N): "); + pressedKey = System.Console.ReadKey(); + DicConsole.WriteLine(); + } + + if(pressedKey.Key == ConsoleKey.Y) + { + for(ushort i = (ushort)report.SCSI.ReadCapabilities.BlockSize; i < (ushort)report.SCSI.ReadCapabilities.BlockSize * 36; i++) + { + DicConsole.Write("\rTrying to READ LONG with a size of {0} bytes...", i); + sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, i, timeout, out duration); + if(!sense) + { + if(debug) + { + FileStream bingo = new FileStream(string.Format("{0}_readlong.bin", dev.Model), FileMode.Create); + bingo.Write(buffer, 0, buffer.Length); + bingo.Close(); + } + report.SCSI.ReadCapabilities.LongBlockSize = i; + report.SCSI.ReadCapabilities.LongBlockSizeSpecified = true; + break; + } + } + DicConsole.WriteLine(); + } + } + } + } + } + } +} diff --git a/DiscImageChef.Core/Devices/Report/SCSI/MMC.cs b/DiscImageChef.Core/Devices/Report/SCSI/MMC.cs new file mode 100644 index 000000000..6542cece5 --- /dev/null +++ b/DiscImageChef.Core/Devices/Report/SCSI/MMC.cs @@ -0,0 +1,1372 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : MMC.cs +// Version : 1.0 +// Author(s) : Natalia Portillo +// +// Component : Component +// +// Revision : $Revision$ +// Last change by : $Author$ +// Date : $Date$ +// +// --[ Description ] ---------------------------------------------------------- +// +// Description +// +// --[ 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 . +// +// ---------------------------------------------------------------------------- +// Copyright (C) 2011-2015 Claunia.com +// ****************************************************************************/ +// //$Id$ +using System; +using System.Collections.Generic; +using System.IO; +using DiscImageChef.Console; +using DiscImageChef.Devices; +using DiscImageChef.Metadata; + +namespace DiscImageChef.Core.Devices.Report.SCSI +{ + internal static class MMC + { + internal static void Report(Device dev, ref DeviceReport report, bool debug, ref Decoders.SCSI.Modes.ModePage_2A? cdromMode, ref List mediaTypes) + { + if(report == null) + return; + + byte[] senseBuffer; + byte[] buffer; + double duration; + bool sense; + uint timeout = 5; + ConsoleKeyInfo pressedKey; + Decoders.SCSI.Modes.DecodedMode? decMode = null; + + report.SCSI.MultiMediaDevice = new mmcType(); + + if(cdromMode.HasValue) + { + report.SCSI.MultiMediaDevice.ModeSense2A = new mmcModeType(); + if(cdromMode.Value.BufferSize != 0) + { + report.SCSI.MultiMediaDevice.ModeSense2A.BufferSize = cdromMode.Value.BufferSize; + report.SCSI.MultiMediaDevice.ModeSense2A.BufferSizeSpecified = true; + } + if(cdromMode.Value.CurrentSpeed != 0) + { + report.SCSI.MultiMediaDevice.ModeSense2A.CurrentSpeed = cdromMode.Value.CurrentSpeed; + report.SCSI.MultiMediaDevice.ModeSense2A.CurrentSpeedSpecified = true; + } + if(cdromMode.Value.CurrentWriteSpeed != 0) + { + report.SCSI.MultiMediaDevice.ModeSense2A.CurrentWriteSpeed = cdromMode.Value.CurrentWriteSpeed; + report.SCSI.MultiMediaDevice.ModeSense2A.CurrentWriteSpeedSpecified = true; + } + if(cdromMode.Value.CurrentWriteSpeedSelected != 0) + { + report.SCSI.MultiMediaDevice.ModeSense2A.CurrentWriteSpeedSelected = cdromMode.Value.CurrentWriteSpeedSelected; + report.SCSI.MultiMediaDevice.ModeSense2A.CurrentWriteSpeedSelectedSpecified = true; + } + if(cdromMode.Value.MaximumSpeed != 0) + { + report.SCSI.MultiMediaDevice.ModeSense2A.MaximumSpeed = cdromMode.Value.MaximumSpeed; + report.SCSI.MultiMediaDevice.ModeSense2A.MaximumSpeedSpecified = true; + } + if(cdromMode.Value.MaxWriteSpeed != 0) + { + report.SCSI.MultiMediaDevice.ModeSense2A.MaximumWriteSpeed = cdromMode.Value.MaxWriteSpeed; + report.SCSI.MultiMediaDevice.ModeSense2A.MaximumWriteSpeedSpecified = true; + } + if(cdromMode.Value.RotationControlSelected != 0) + { + report.SCSI.MultiMediaDevice.ModeSense2A.RotationControlSelected = cdromMode.Value.RotationControlSelected; + report.SCSI.MultiMediaDevice.ModeSense2A.RotationControlSelectedSpecified = true; + } + if(cdromMode.Value.SupportedVolumeLevels != 0) + { + report.SCSI.MultiMediaDevice.ModeSense2A.SupportedVolumeLevels = cdromMode.Value.SupportedVolumeLevels; + report.SCSI.MultiMediaDevice.ModeSense2A.SupportedVolumeLevelsSpecified = true; + } + + report.SCSI.MultiMediaDevice.ModeSense2A.AccurateCDDA = cdromMode.Value.AccurateCDDA; + report.SCSI.MultiMediaDevice.ModeSense2A.BCK = cdromMode.Value.BCK; + report.SCSI.MultiMediaDevice.ModeSense2A.BufferUnderRunProtection = cdromMode.Value.BUF; + report.SCSI.MultiMediaDevice.ModeSense2A.CanEject = cdromMode.Value.Eject; + report.SCSI.MultiMediaDevice.ModeSense2A.CanLockMedia = cdromMode.Value.Lock; + report.SCSI.MultiMediaDevice.ModeSense2A.CDDACommand = cdromMode.Value.CDDACommand; + report.SCSI.MultiMediaDevice.ModeSense2A.CompositeAudioVideo = cdromMode.Value.Composite; + report.SCSI.MultiMediaDevice.ModeSense2A.CSSandCPPMSupported = cdromMode.Value.CMRSupported == 1; + report.SCSI.MultiMediaDevice.ModeSense2A.DeterministicSlotChanger = cdromMode.Value.SDP; + report.SCSI.MultiMediaDevice.ModeSense2A.DigitalPort1 = cdromMode.Value.DigitalPort1; + report.SCSI.MultiMediaDevice.ModeSense2A.DigitalPort2 = cdromMode.Value.DigitalPort2; + report.SCSI.MultiMediaDevice.ModeSense2A.LeadInPW = cdromMode.Value.LeadInPW; + report.SCSI.MultiMediaDevice.ModeSense2A.LoadingMechanismType = cdromMode.Value.LoadingMechanism; + report.SCSI.MultiMediaDevice.ModeSense2A.LockStatus = cdromMode.Value.LockState; + report.SCSI.MultiMediaDevice.ModeSense2A.LSBF = cdromMode.Value.LSBF; + report.SCSI.MultiMediaDevice.ModeSense2A.PlaysAudio = cdromMode.Value.AudioPlay; + report.SCSI.MultiMediaDevice.ModeSense2A.PreventJumperStatus = cdromMode.Value.PreventJumper; + report.SCSI.MultiMediaDevice.ModeSense2A.RCK = cdromMode.Value.RCK; + report.SCSI.MultiMediaDevice.ModeSense2A.ReadsBarcode = cdromMode.Value.ReadBarcode; + report.SCSI.MultiMediaDevice.ModeSense2A.ReadsBothSides = cdromMode.Value.SCC; + report.SCSI.MultiMediaDevice.ModeSense2A.ReadsCDR = cdromMode.Value.ReadCDR; + report.SCSI.MultiMediaDevice.ModeSense2A.ReadsCDRW = cdromMode.Value.ReadCDRW; + report.SCSI.MultiMediaDevice.ModeSense2A.ReadsDeinterlavedSubchannel = cdromMode.Value.DeinterlaveSubchannel; + report.SCSI.MultiMediaDevice.ModeSense2A.ReadsDVDR = cdromMode.Value.ReadDVDR; + report.SCSI.MultiMediaDevice.ModeSense2A.ReadsDVDRAM = cdromMode.Value.ReadDVDRAM; + report.SCSI.MultiMediaDevice.ModeSense2A.ReadsDVDROM = cdromMode.Value.ReadDVDROM; + report.SCSI.MultiMediaDevice.ModeSense2A.ReadsISRC = cdromMode.Value.ISRC; + report.SCSI.MultiMediaDevice.ModeSense2A.ReadsMode2Form2 = cdromMode.Value.Mode2Form2; + report.SCSI.MultiMediaDevice.ModeSense2A.ReadsMode2Form1 = cdromMode.Value.Mode2Form1; + report.SCSI.MultiMediaDevice.ModeSense2A.ReadsPacketCDR = cdromMode.Value.Method2; + report.SCSI.MultiMediaDevice.ModeSense2A.ReadsSubchannel = cdromMode.Value.Subchannel; + report.SCSI.MultiMediaDevice.ModeSense2A.ReadsUPC = cdromMode.Value.UPC; + report.SCSI.MultiMediaDevice.ModeSense2A.ReturnsC2Pointers = cdromMode.Value.C2Pointer; + report.SCSI.MultiMediaDevice.ModeSense2A.SeparateChannelMute = cdromMode.Value.SeparateChannelMute; + report.SCSI.MultiMediaDevice.ModeSense2A.SeparateChannelVolume = cdromMode.Value.SeparateChannelVolume; + report.SCSI.MultiMediaDevice.ModeSense2A.SSS = cdromMode.Value.SSS; + report.SCSI.MultiMediaDevice.ModeSense2A.SupportsMultiSession = cdromMode.Value.MultiSession; + report.SCSI.MultiMediaDevice.ModeSense2A.TestWrite = cdromMode.Value.TestWrite; + report.SCSI.MultiMediaDevice.ModeSense2A.WritesCDR = cdromMode.Value.WriteCDR; + report.SCSI.MultiMediaDevice.ModeSense2A.WritesCDRW = cdromMode.Value.WriteCDRW; + report.SCSI.MultiMediaDevice.ModeSense2A.WritesDVDR = cdromMode.Value.WriteDVDR; + report.SCSI.MultiMediaDevice.ModeSense2A.WritesDVDRAM = cdromMode.Value.WriteDVDRAM; + report.SCSI.MultiMediaDevice.ModeSense2A.WriteSpeedPerformanceDescriptors = cdromMode.Value.WriteSpeedPerformanceDescriptors; + + mediaTypes.Add("CD-ROM"); + mediaTypes.Add("Audio CD"); + if(cdromMode.Value.ReadCDR) + mediaTypes.Add("CD-R"); + if(cdromMode.Value.ReadCDRW) + mediaTypes.Add("CD-RW"); + if(cdromMode.Value.ReadDVDROM) + mediaTypes.Add("DVD-ROM"); + if(cdromMode.Value.ReadDVDRAM) + mediaTypes.Add("DVD-RAM"); + if(cdromMode.Value.ReadDVDR) + mediaTypes.Add("DVD-R"); + } + + DicConsole.WriteLine("Querying MMC GET CONFIGURATION..."); + sense = dev.GetConfiguration(out buffer, out senseBuffer, timeout, out duration); + + if(!sense) + { + Decoders.SCSI.MMC.Features.SeparatedFeatures ftr = Decoders.SCSI.MMC.Features.Separate(buffer); + if(ftr.Descriptors != null && ftr.Descriptors.Length > 0) + { + report.SCSI.MultiMediaDevice.Features = new mmcFeaturesType(); + foreach(Decoders.SCSI.MMC.Features.FeatureDescriptor desc in ftr.Descriptors) + { + switch(desc.Code) + { + case 0x0001: + { + Decoders.SCSI.MMC.Feature_0001? ftr0001 = Decoders.SCSI.MMC.Features.Decode_0001(desc.Data); + if(ftr0001.HasValue) + { + report.SCSI.MultiMediaDevice.Features.PhysicalInterfaceStandard = ftr0001.Value.PhysicalInterfaceStandard; + report.SCSI.MultiMediaDevice.Features.PhysicalInterfaceStandardSpecified = true; + report.SCSI.MultiMediaDevice.Features.SupportsDeviceBusyEvent = ftr0001.Value.DBE; + } + } + break; + case 0x0003: + { + Decoders.SCSI.MMC.Feature_0003? ftr0003 = Decoders.SCSI.MMC.Features.Decode_0003(desc.Data); + if(ftr0003.HasValue) + { + report.SCSI.MultiMediaDevice.Features.LoadingMechanismType = ftr0003.Value.LoadingMechanismType; + report.SCSI.MultiMediaDevice.Features.LoadingMechanismTypeSpecified = true; + report.SCSI.MultiMediaDevice.Features.CanLoad = ftr0003.Value.Load; + report.SCSI.MultiMediaDevice.Features.CanEject = ftr0003.Value.Eject; + report.SCSI.MultiMediaDevice.Features.PreventJumper = ftr0003.Value.PreventJumper; + report.SCSI.MultiMediaDevice.Features.DBML = ftr0003.Value.DBML; + report.SCSI.MultiMediaDevice.Features.Locked = ftr0003.Value.Lock; + } + } + break; + case 0x0004: + { + Decoders.SCSI.MMC.Feature_0004? ftr0004 = Decoders.SCSI.MMC.Features.Decode_0004(desc.Data); + if(ftr0004.HasValue) + { + report.SCSI.MultiMediaDevice.Features.SupportsWriteProtectPAC = ftr0004.Value.DWP; + report.SCSI.MultiMediaDevice.Features.SupportsWriteInhibitDCB = ftr0004.Value.WDCB; + report.SCSI.MultiMediaDevice.Features.SupportsPWP = ftr0004.Value.SPWP; + report.SCSI.MultiMediaDevice.Features.SupportsSWPP = ftr0004.Value.SSWPP; + } + } + break; + case 0x0010: + { + Decoders.SCSI.MMC.Feature_0010? ftr0010 = Decoders.SCSI.MMC.Features.Decode_0010(desc.Data); + if(ftr0010.HasValue) + { + if(ftr0010.Value.LogicalBlockSize > 0) + { + report.SCSI.MultiMediaDevice.Features.LogicalBlockSize = ftr0010.Value.LogicalBlockSize; + report.SCSI.MultiMediaDevice.Features.LogicalBlockSizeSpecified = true; + } + if(ftr0010.Value.Blocking > 0) + { + report.SCSI.MultiMediaDevice.Features.BlocksPerReadableUnit = ftr0010.Value.Blocking; + report.SCSI.MultiMediaDevice.Features.BlocksPerReadableUnitSpecified = true; + } + report.SCSI.MultiMediaDevice.Features.ErrorRecoveryPage = ftr0010.Value.PP; + } + } + break; + case 0x001D: + report.SCSI.MultiMediaDevice.Features.MultiRead = true; + break; + case 0x001E: + { + report.SCSI.MultiMediaDevice.Features.CanReadCD = true; + Decoders.SCSI.MMC.Feature_001E? ftr001E = Decoders.SCSI.MMC.Features.Decode_001E(desc.Data); + if(ftr001E.HasValue) + { + report.SCSI.MultiMediaDevice.Features.SupportsDAP = ftr001E.Value.DAP; + report.SCSI.MultiMediaDevice.Features.SupportsC2 = ftr001E.Value.C2; + report.SCSI.MultiMediaDevice.Features.CanReadLeadInCDText = ftr001E.Value.CDText; + } + } + break; + case 0x001F: + { + report.SCSI.MultiMediaDevice.Features.CanReadDVD = true; + Decoders.SCSI.MMC.Feature_001F? ftr001F = Decoders.SCSI.MMC.Features.Decode_001F(desc.Data); + if(ftr001F.HasValue) + { + report.SCSI.MultiMediaDevice.Features.DVDMultiRead = ftr001F.Value.MULTI110; + report.SCSI.MultiMediaDevice.Features.CanReadAllDualRW = ftr001F.Value.DualRW; + report.SCSI.MultiMediaDevice.Features.CanReadAllDualR = ftr001F.Value.DualRW; + } + } + break; + case 0x0022: + report.SCSI.MultiMediaDevice.Features.CanEraseSector = true; + break; + case 0x0023: + { + report.SCSI.MultiMediaDevice.Features.CanFormat = true; + Decoders.SCSI.MMC.Feature_0023? ftr0023 = Decoders.SCSI.MMC.Features.Decode_0023(desc.Data); + if(ftr0023.HasValue) + { + report.SCSI.MultiMediaDevice.Features.CanFormatBDREWithoutSpare = ftr0023.Value.RENoSA; + report.SCSI.MultiMediaDevice.Features.CanExpandBDRESpareArea = ftr0023.Value.Expand; + report.SCSI.MultiMediaDevice.Features.CanFormatQCert = ftr0023.Value.QCert; + report.SCSI.MultiMediaDevice.Features.CanFormatCert = ftr0023.Value.Cert; + report.SCSI.MultiMediaDevice.Features.CanFormatFRF = ftr0023.Value.FRF; + report.SCSI.MultiMediaDevice.Features.CanFormatRRM = ftr0023.Value.RRM; + } + } + break; + case 0x0024: + report.SCSI.MultiMediaDevice.Features.CanReadSpareAreaInformation = true; + break; + case 0x0027: + report.SCSI.MultiMediaDevice.Features.CanWriteCDRWCAV = true; + break; + case 0x0028: + { + report.SCSI.MultiMediaDevice.Features.CanReadCDMRW = true; + Decoders.SCSI.MMC.Feature_0028? ftr0028 = Decoders.SCSI.MMC.Features.Decode_0028(desc.Data); + if(ftr0028.HasValue) + { + report.SCSI.MultiMediaDevice.Features.CanReadDVDPlusMRW = ftr0028.Value.DVDPRead; + report.SCSI.MultiMediaDevice.Features.CanWriteDVDPlusMRW = ftr0028.Value.DVDPWrite; + report.SCSI.MultiMediaDevice.Features.CanWriteCDMRW = ftr0028.Value.Write; + } + } + break; + case 0x002A: + { + report.SCSI.MultiMediaDevice.Features.CanReadDVDPlusRW = true; + Decoders.SCSI.MMC.Feature_002A? ftr002A = Decoders.SCSI.MMC.Features.Decode_002A(desc.Data); + if(ftr002A.HasValue) + { + report.SCSI.MultiMediaDevice.Features.CanWriteDVDPlusRW = ftr002A.Value.Write; + } + } + break; + case 0x002B: + { + report.SCSI.MultiMediaDevice.Features.CanReadDVDPlusR = true; + Decoders.SCSI.MMC.Feature_002B? ftr002B = Decoders.SCSI.MMC.Features.Decode_002B(desc.Data); + if(ftr002B.HasValue) + { + report.SCSI.MultiMediaDevice.Features.CanWriteDVDPlusR = ftr002B.Value.Write; + } + } + break; + case 0x002D: + { + report.SCSI.MultiMediaDevice.Features.CanWriteCDTAO = true; + Decoders.SCSI.MMC.Feature_002D? ftr002D = Decoders.SCSI.MMC.Features.Decode_002D(desc.Data); + if(ftr002D.HasValue) + { + report.SCSI.MultiMediaDevice.Features.BufferUnderrunFreeInTAO = ftr002D.Value.BUF; + report.SCSI.MultiMediaDevice.Features.CanWriteRawSubchannelInTAO = ftr002D.Value.RWRaw; + report.SCSI.MultiMediaDevice.Features.CanWritePackedSubchannelInTAO = ftr002D.Value.RWPack; + report.SCSI.MultiMediaDevice.Features.CanTestWriteInTAO = ftr002D.Value.TestWrite; + report.SCSI.MultiMediaDevice.Features.CanOverwriteTAOTrack = ftr002D.Value.CDRW; + report.SCSI.MultiMediaDevice.Features.CanWriteRWSubchannelInTAO = ftr002D.Value.RWSubchannel; + } + } + break; + case 0x002E: + { + report.SCSI.MultiMediaDevice.Features.CanWriteCDSAO = true; + Decoders.SCSI.MMC.Feature_002E? ftr002E = Decoders.SCSI.MMC.Features.Decode_002E(desc.Data); + if(ftr002E.HasValue) + { + report.SCSI.MultiMediaDevice.Features.BufferUnderrunFreeInSAO = ftr002E.Value.BUF; + report.SCSI.MultiMediaDevice.Features.CanWriteRawMultiSession = ftr002E.Value.RAWMS; + report.SCSI.MultiMediaDevice.Features.CanWriteRaw = ftr002E.Value.RAW; + report.SCSI.MultiMediaDevice.Features.CanTestWriteInSAO = ftr002E.Value.TestWrite; + report.SCSI.MultiMediaDevice.Features.CanOverwriteSAOTrack = ftr002E.Value.CDRW; + report.SCSI.MultiMediaDevice.Features.CanWriteRWSubchannelInSAO = ftr002E.Value.RW; + } + } + break; + case 0x002F: + { + report.SCSI.MultiMediaDevice.Features.CanWriteDVDR = true; + Decoders.SCSI.MMC.Feature_002F? ftr002F = Decoders.SCSI.MMC.Features.Decode_002F(desc.Data); + if(ftr002F.HasValue) + { + report.SCSI.MultiMediaDevice.Features.BufferUnderrunFreeInDVD = ftr002F.Value.BUF; + report.SCSI.MultiMediaDevice.Features.CanWriteDVDRDL = ftr002F.Value.RDL; + report.SCSI.MultiMediaDevice.Features.CanTestWriteDVD = ftr002F.Value.TestWrite; + report.SCSI.MultiMediaDevice.Features.CanWriteDVDRW = ftr002F.Value.DVDRW; + } + } + break; + case 0x0030: + report.SCSI.MultiMediaDevice.Features.CanReadDDCD = true; + break; + case 0x0031: + { + report.SCSI.MultiMediaDevice.Features.CanWriteDDCDR = true; + Decoders.SCSI.MMC.Feature_0031? ftr0031 = Decoders.SCSI.MMC.Features.Decode_0031(desc.Data); + if(ftr0031.HasValue) + report.SCSI.MultiMediaDevice.Features.CanTestWriteDDCDR = ftr0031.Value.TestWrite; + } + break; + case 0x0032: + report.SCSI.MultiMediaDevice.Features.CanWriteDDCDRW = true; + break; + case 0x0037: + report.SCSI.MultiMediaDevice.Features.CanWriteCDRW = true; + break; + case 0x0038: + report.SCSI.MultiMediaDevice.Features.CanPseudoOverwriteBDR = true; + break; + case 0x003A: + { + report.SCSI.MultiMediaDevice.Features.CanReadDVDPlusRWDL = true; + Decoders.SCSI.MMC.Feature_003A? ftr003A = Decoders.SCSI.MMC.Features.Decode_003A(desc.Data); + if(ftr003A.HasValue) + report.SCSI.MultiMediaDevice.Features.CanWriteDVDPlusRWDL = ftr003A.Value.Write; + } + break; + case 0x003B: + { + report.SCSI.MultiMediaDevice.Features.CanReadDVDPlusRDL = true; + Decoders.SCSI.MMC.Feature_003B? ftr003B = Decoders.SCSI.MMC.Features.Decode_003B(desc.Data); + if(ftr003B.HasValue) + report.SCSI.MultiMediaDevice.Features.CanWriteDVDPlusRDL = ftr003B.Value.Write; + } + break; + case 0x0040: + { + report.SCSI.MultiMediaDevice.Features.CanReadBD = true; + Decoders.SCSI.MMC.Feature_0040? ftr0040 = Decoders.SCSI.MMC.Features.Decode_0040(desc.Data); + if(ftr0040.HasValue) + { + report.SCSI.MultiMediaDevice.Features.CanReadBluBCA = ftr0040.Value.BCA; + report.SCSI.MultiMediaDevice.Features.CanReadBDRE2 = ftr0040.Value.RE2; + report.SCSI.MultiMediaDevice.Features.CanReadBDRE1 = ftr0040.Value.RE1; + report.SCSI.MultiMediaDevice.Features.CanReadOldBDRE = ftr0040.Value.OldRE; + report.SCSI.MultiMediaDevice.Features.CanReadBDR = ftr0040.Value.R; + report.SCSI.MultiMediaDevice.Features.CanReadOldBDR = ftr0040.Value.OldR; + report.SCSI.MultiMediaDevice.Features.CanReadBDROM = ftr0040.Value.ROM; + report.SCSI.MultiMediaDevice.Features.CanReadOldBDROM = ftr0040.Value.OldROM; + } + } + break; + case 0x0041: + { + report.SCSI.MultiMediaDevice.Features.CanWriteBD = true; + Decoders.SCSI.MMC.Feature_0041? ftr0041 = Decoders.SCSI.MMC.Features.Decode_0041(desc.Data); + if(ftr0041.HasValue) + { + report.SCSI.MultiMediaDevice.Features.CanWriteBDRE2 = ftr0041.Value.RE2; + report.SCSI.MultiMediaDevice.Features.CanWriteBDRE1 = ftr0041.Value.RE1; + report.SCSI.MultiMediaDevice.Features.CanReadOldBDRE = ftr0041.Value.OldRE; + report.SCSI.MultiMediaDevice.Features.CanReadBDR = ftr0041.Value.R; + report.SCSI.MultiMediaDevice.Features.CanReadOldBDR = ftr0041.Value.OldR; + } + } + break; + case 0x0050: + { + report.SCSI.MultiMediaDevice.Features.CanReadHDDVD = true; + Decoders.SCSI.MMC.Feature_0050? ftr0050 = Decoders.SCSI.MMC.Features.Decode_0050(desc.Data); + if(ftr0050.HasValue) + { + report.SCSI.MultiMediaDevice.Features.CanReadHDDVDR = ftr0050.Value.HDDVDR; + report.SCSI.MultiMediaDevice.Features.CanReadHDDVDRAM = ftr0050.Value.HDDVDRAM; + } + } + break; + case 0x0051: + { + Decoders.SCSI.MMC.Feature_0051? ftr0051 = Decoders.SCSI.MMC.Features.Decode_0051(desc.Data); + if(ftr0051.HasValue) + { + report.SCSI.MultiMediaDevice.Features.CanWriteHDDVDR = ftr0051.Value.HDDVDR; + report.SCSI.MultiMediaDevice.Features.CanWriteHDDVDRAM = ftr0051.Value.HDDVDRAM; + } + } + break; + case 0x0080: + report.SCSI.MultiMediaDevice.Features.SupportsHybridDiscs = true; + break; + case 0x0101: + report.SCSI.MultiMediaDevice.Features.SupportsModePage1Ch = true; + break; + case 0x0102: + { + report.SCSI.MultiMediaDevice.Features.EmbeddedChanger = true; + Decoders.SCSI.MMC.Feature_0102? ftr0102 = Decoders.SCSI.MMC.Features.Decode_0102(desc.Data); + if(ftr0102.HasValue) + { + report.SCSI.MultiMediaDevice.Features.ChangerIsSideChangeCapable = ftr0102.Value.SCC; + report.SCSI.MultiMediaDevice.Features.ChangerSupportsDiscPresent = ftr0102.Value.SDP; + report.SCSI.MultiMediaDevice.Features.ChangerSlots = (byte)(ftr0102.Value.HighestSlotNumber + 1); + } + } + break; + case 0x0103: + { + report.SCSI.MultiMediaDevice.Features.CanPlayCDAudio = true; + Decoders.SCSI.MMC.Feature_0103? ftr0103 = Decoders.SCSI.MMC.Features.Decode_0103(desc.Data); + if(ftr0103.HasValue) + { + report.SCSI.MultiMediaDevice.Features.CanAudioScan = ftr0103.Value.Scan; + report.SCSI.MultiMediaDevice.Features.CanMuteSeparateChannels = ftr0103.Value.SCM; + report.SCSI.MultiMediaDevice.Features.SupportsSeparateVolume = ftr0103.Value.SV; + if(ftr0103.Value.VolumeLevels > 0) + { + report.SCSI.MultiMediaDevice.Features.VolumeLevelsSpecified = true; + report.SCSI.MultiMediaDevice.Features.VolumeLevels = ftr0103.Value.VolumeLevels; + } + } + } + break; + case 0x0104: + report.SCSI.MultiMediaDevice.Features.CanUpgradeFirmware = true; + break; + case 0x0106: + { + report.SCSI.MultiMediaDevice.Features.SupportsCSS = true; + Decoders.SCSI.MMC.Feature_0106? ftr0106 = Decoders.SCSI.MMC.Features.Decode_0106(desc.Data); + if(ftr0106.HasValue) + { + if(ftr0106.Value.CSSVersion > 0) + { + report.SCSI.MultiMediaDevice.Features.CSSVersionSpecified = true; + report.SCSI.MultiMediaDevice.Features.CSSVersion = ftr0106.Value.CSSVersion; + } + } + } + break; + case 0x0108: + report.SCSI.MultiMediaDevice.Features.CanReportDriveSerial = true; + break; + case 0x0109: + report.SCSI.MultiMediaDevice.Features.CanReportMediaSerial = true; + break; + case 0x010B: + { + report.SCSI.MultiMediaDevice.Features.SupportsCPRM = true; + Decoders.SCSI.MMC.Feature_010B? ftr010B = Decoders.SCSI.MMC.Features.Decode_010B(desc.Data); + if(ftr010B.HasValue) + { + if(ftr010B.Value.CPRMVersion > 0) + { + report.SCSI.MultiMediaDevice.Features.CPRMVersionSpecified = true; + report.SCSI.MultiMediaDevice.Features.CPRMVersion = ftr010B.Value.CPRMVersion; + } + } + } + break; + case 0x010C: + { + Decoders.SCSI.MMC.Feature_010C? ftr010C = Decoders.SCSI.MMC.Features.Decode_010C(desc.Data); + if(ftr010C.HasValue) + { + string syear, smonth, sday, shour, sminute, ssecond; + byte[] temp; + + temp = new byte[4]; + temp[0] = (byte)((ftr010C.Value.Century & 0xFF00) >> 8); + temp[1] = (byte)(ftr010C.Value.Century & 0xFF); + temp[2] = (byte)((ftr010C.Value.Year & 0xFF00) >> 8); + temp[3] = (byte)(ftr010C.Value.Year & 0xFF); + syear = System.Text.Encoding.ASCII.GetString(temp); + temp = new byte[2]; + temp[0] = (byte)((ftr010C.Value.Month & 0xFF00) >> 8); + temp[1] = (byte)(ftr010C.Value.Month & 0xFF); + smonth = System.Text.Encoding.ASCII.GetString(temp); + temp = new byte[2]; + temp[0] = (byte)((ftr010C.Value.Day & 0xFF00) >> 8); + temp[1] = (byte)(ftr010C.Value.Day & 0xFF); + sday = System.Text.Encoding.ASCII.GetString(temp); + temp = new byte[2]; + temp[0] = (byte)((ftr010C.Value.Hour & 0xFF00) >> 8); + temp[1] = (byte)(ftr010C.Value.Hour & 0xFF); + shour = System.Text.Encoding.ASCII.GetString(temp); + temp = new byte[2]; + temp[0] = (byte)((ftr010C.Value.Minute & 0xFF00) >> 8); + temp[1] = (byte)(ftr010C.Value.Minute & 0xFF); + sminute = System.Text.Encoding.ASCII.GetString(temp); + temp = new byte[2]; + temp[0] = (byte)((ftr010C.Value.Second & 0xFF00) >> 8); + temp[1] = (byte)(ftr010C.Value.Second & 0xFF); + ssecond = System.Text.Encoding.ASCII.GetString(temp); + + try + { + report.SCSI.MultiMediaDevice.Features.FirmwareDate = new DateTime(int.Parse(syear), int.Parse(smonth), + int.Parse(sday), int.Parse(shour), int.Parse(sminute), + int.Parse(ssecond), DateTimeKind.Utc); + + report.SCSI.MultiMediaDevice.Features.FirmwareDateSpecified = true; + } +#pragma warning disable RECS0022 // A catch clause that catches System.Exception and has an empty body + catch +#pragma warning restore RECS0022 // A catch clause that catches System.Exception and has an empty body + { + } + } + } + break; + case 0x010D: + { + report.SCSI.MultiMediaDevice.Features.SupportsAACS = true; + Decoders.SCSI.MMC.Feature_010D? ftr010D = Decoders.SCSI.MMC.Features.Decode_010D(desc.Data); + if(ftr010D.HasValue) + { + report.SCSI.MultiMediaDevice.Features.CanReadDriveAACSCertificate = ftr010D.Value.RDC; + report.SCSI.MultiMediaDevice.Features.CanReadCPRM_MKB = ftr010D.Value.RMC; + report.SCSI.MultiMediaDevice.Features.CanWriteBusEncryptedBlocks = ftr010D.Value.WBE; + report.SCSI.MultiMediaDevice.Features.SupportsBusEncryption = ftr010D.Value.BEC; + report.SCSI.MultiMediaDevice.Features.CanGenerateBindingNonce = ftr010D.Value.BNG; + + if(ftr010D.Value.BindNonceBlocks > 0) + { + report.SCSI.MultiMediaDevice.Features.BindingNonceBlocksSpecified = true; + report.SCSI.MultiMediaDevice.Features.BindingNonceBlocks = ftr010D.Value.BindNonceBlocks; + } + + if(ftr010D.Value.AGIDs > 0) + { + report.SCSI.MultiMediaDevice.Features.AGIDsSpecified = true; + report.SCSI.MultiMediaDevice.Features.AGIDs = ftr010D.Value.AGIDs; + } + + if(ftr010D.Value.AACSVersion > 0) + { + report.SCSI.MultiMediaDevice.Features.AACSVersionSpecified = true; + report.SCSI.MultiMediaDevice.Features.AACSVersion = ftr010D.Value.AACSVersion; + } + } + } + break; + case 0x010E: + report.SCSI.MultiMediaDevice.Features.CanWriteCSSManagedDVD = true; + break; + case 0x0113: + report.SCSI.MultiMediaDevice.Features.SupportsSecurDisc = true; + break; + case 0x0142: + report.SCSI.MultiMediaDevice.Features.SupportsOSSC = true; + break; + case 0x0110: + report.SCSI.MultiMediaDevice.Features.SupportsVCPS = true; + break; + } + } + } + + if(report.SCSI.MultiMediaDevice.Features.CanReadBD || + report.SCSI.MultiMediaDevice.Features.CanReadBDR || + report.SCSI.MultiMediaDevice.Features.CanReadBDRE1 || + report.SCSI.MultiMediaDevice.Features.CanReadBDRE2 || + report.SCSI.MultiMediaDevice.Features.CanReadBDROM || + report.SCSI.MultiMediaDevice.Features.CanReadOldBDR || + report.SCSI.MultiMediaDevice.Features.CanReadOldBDRE || + report.SCSI.MultiMediaDevice.Features.CanReadOldBDROM) + { + if(!mediaTypes.Contains("BD-ROM")) + mediaTypes.Add("BD-ROM"); + if(!mediaTypes.Contains("BD-R")) + mediaTypes.Add("BD-R"); + if(!mediaTypes.Contains("BD-RE")) + mediaTypes.Add("BD-RE"); + if(!mediaTypes.Contains("BD-R LTH")) + mediaTypes.Add("BD-R LTH"); + if(!mediaTypes.Contains("BD-R XL")) + mediaTypes.Add("BD-R XL"); + } + + if(report.SCSI.MultiMediaDevice.Features.CanReadCD || + report.SCSI.MultiMediaDevice.Features.MultiRead) + { + if(!mediaTypes.Contains("CD-ROM")) + mediaTypes.Add("CD-ROM"); + if(!mediaTypes.Contains("Audio CD")) + mediaTypes.Add("Audio CD"); + if(!mediaTypes.Contains("CD-R")) + mediaTypes.Add("CD-R"); + if(!mediaTypes.Contains("CD-RW")) + mediaTypes.Add("CD-RW"); + } + + if(report.SCSI.MultiMediaDevice.Features.CanReadCDMRW) + { + if(!mediaTypes.Contains("CD-MRW")) + mediaTypes.Add("CD-MRW"); + } + + if(report.SCSI.MultiMediaDevice.Features.CanReadDDCD) + { + if(!mediaTypes.Contains("DDCD-ROM")) + mediaTypes.Add("DDCD-ROM"); + if(!mediaTypes.Contains("DDCD-R")) + mediaTypes.Add("DDCD-R"); + if(!mediaTypes.Contains("DDCD-RW")) + mediaTypes.Add("DDCD-RW"); + } + + if(report.SCSI.MultiMediaDevice.Features.CanReadDVD || + report.SCSI.MultiMediaDevice.Features.DVDMultiRead || + report.SCSI.MultiMediaDevice.Features.CanReadDVDPlusR || + report.SCSI.MultiMediaDevice.Features.CanReadDVDPlusRDL || + report.SCSI.MultiMediaDevice.Features.CanReadDVDPlusRW || + report.SCSI.MultiMediaDevice.Features.CanReadDVDPlusRWDL) + { + if(!mediaTypes.Contains("DVD-ROM")) + mediaTypes.Add("DVD-ROM"); + if(!mediaTypes.Contains("DVD-R")) + mediaTypes.Add("DVD-R"); + if(!mediaTypes.Contains("DVD-RW")) + mediaTypes.Add("DVD-RW"); + if(!mediaTypes.Contains("DVD+R")) + mediaTypes.Add("DVD+R"); + if(!mediaTypes.Contains("DVD+RW")) + mediaTypes.Add("DVD+RW"); + if(!mediaTypes.Contains("DVD-R DL")) + mediaTypes.Add("DVD-R DL"); + if(!mediaTypes.Contains("DVD+R DL")) + mediaTypes.Add("DVD+R DL"); + } + + if(report.SCSI.MultiMediaDevice.Features.CanReadDVDPlusMRW) + { + if(!mediaTypes.Contains("DVD+MRW")) + mediaTypes.Add("DVD+MRW"); + } + + + if(report.SCSI.MultiMediaDevice.Features.CanReadHDDVD || + report.SCSI.MultiMediaDevice.Features.CanReadHDDVDR) + { + if(!mediaTypes.Contains("HD DVD-ROM")) + mediaTypes.Add("HD DVD-ROM"); + if(!mediaTypes.Contains("HD DVD-R")) + mediaTypes.Add("HD DVD-R"); + if(!mediaTypes.Contains("HD DVD-RW")) + mediaTypes.Add("HD DVD-RW"); + } + + if(report.SCSI.MultiMediaDevice.Features.CanReadHDDVDRAM) + { + if(!mediaTypes.Contains("HD DVD-RAM")) + mediaTypes.Add("HD DVD-RAM"); + } + } + + bool tryPlextor = false, tryHLDTST = false, tryPioneer = false, tryNEC = false; + + tryPlextor |= dev.Manufacturer.ToLowerInvariant() == "plextor"; + tryHLDTST |= dev.Manufacturer.ToLowerInvariant() == "hl-dt-st"; + tryPioneer |= dev.Manufacturer.ToLowerInvariant() == "pioneer"; + tryNEC |= dev.Manufacturer.ToLowerInvariant() == "nec"; + + // Very old CD drives do not contain mode page 2Ah neither GET CONFIGURATION, so just try all CDs on them + // Also don't get confident, some drives didn't know CD-RW but are able to read them + if(mediaTypes.Count == 0 || mediaTypes.Contains("CD-ROM")) + { + if(!mediaTypes.Contains("CD-ROM")) + mediaTypes.Add("CD-ROM"); + if(!mediaTypes.Contains("Audio CD")) + mediaTypes.Add("Audio CD"); + if(!mediaTypes.Contains("CD-R")) + mediaTypes.Add("CD-R"); + if(!mediaTypes.Contains("CD-RW")) + mediaTypes.Add("CD-RW"); + } + + mediaTypes.Sort(); + List mediaTests = new List(); + foreach(string mediaType in mediaTypes) + { + pressedKey = new ConsoleKeyInfo(); + while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N) + { + DicConsole.Write("Do you have a {0} disc that you can insert in the drive? (Y/N): ", mediaType); + pressedKey = System.Console.ReadKey(); + DicConsole.WriteLine(); + } + + if(pressedKey.Key == ConsoleKey.Y) + { + dev.AllowMediumRemoval(out senseBuffer, timeout, out duration); + dev.EjectTray(out senseBuffer, timeout, out duration); + DicConsole.WriteLine("Please insert it in the drive and press any key when it is ready."); + System.Console.ReadKey(true); + + testedMediaType mediaTest = new testedMediaType(); + mediaTest.MediumTypeName = mediaType; + mediaTest.MediaIsRecognized = true; + + sense = dev.ScsiTestUnitReady(out senseBuffer, timeout, out duration); + if(sense) + { + Decoders.SCSI.FixedSense? decSense = Decoders.SCSI.Sense.DecodeFixed(senseBuffer); + if(decSense.HasValue) + { + if(decSense.Value.ASC == 0x3A) + { + int leftRetries = 20; + while(leftRetries > 0) + { + DicConsole.Write("\rWaiting for drive to become ready"); + System.Threading.Thread.Sleep(2000); + sense = dev.ScsiTestUnitReady(out senseBuffer, timeout, out duration); + if(!sense) + break; + + leftRetries--; + } + + mediaTest.MediaIsRecognized &= !sense; + } + else if(decSense.Value.ASC == 0x04 && decSense.Value.ASCQ == 0x01) + { + int leftRetries = 20; + while(leftRetries > 0) + { + DicConsole.Write("\rWaiting for drive to become ready"); + System.Threading.Thread.Sleep(2000); + sense = dev.ScsiTestUnitReady(out senseBuffer, timeout, out duration); + if(!sense) + break; + + leftRetries--; + } + + mediaTest.MediaIsRecognized &= !sense; + } + else + mediaTest.MediaIsRecognized = false; + } + else + mediaTest.MediaIsRecognized = false; + } + + if(mediaTest.MediaIsRecognized) + { + mediaTest.SupportsReadCapacitySpecified = true; + mediaTest.SupportsReadCapacity16Specified = true; + + DicConsole.WriteLine("Querying SCSI READ CAPACITY..."); + sense = dev.ReadCapacity(out buffer, out senseBuffer, timeout, out duration); + 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[5] << 24) + (buffer[5] << 16) + (buffer[6] << 8) + (buffer[7])); + mediaTest.BlocksSpecified = true; + mediaTest.BlockSizeSpecified = true; + } + + DicConsole.WriteLine("Querying SCSI READ CAPACITY (16)..."); + sense = dev.ReadCapacity16(out buffer, out buffer, timeout, out duration); + 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[5] << 24) + (buffer[5] << 16) + (buffer[6] << 8) + (buffer[7])); + mediaTest.BlocksSpecified = true; + mediaTest.BlockSizeSpecified = true; + } + + decMode = null; + + DicConsole.WriteLine("Querying SCSI MODE SENSE (10)..."); + sense = dev.ModeSense10(out buffer, out senseBuffer, false, true, ScsiModeSensePageControl.Current, 0x3F, 0x00, timeout, out duration); + if(!sense && !dev.Error) + { + report.SCSI.SupportsModeSense10 = true; + decMode = Decoders.SCSI.Modes.DecodeMode10(buffer, dev.SCSIType); + } + DicConsole.WriteLine("Querying SCSI MODE SENSE..."); + sense = dev.ModeSense(out buffer, out senseBuffer, timeout, out duration); + if(!sense && !dev.Error) + { + report.SCSI.SupportsModeSense6 = true; + if(!decMode.HasValue) + decMode = Decoders.SCSI.Modes.DecodeMode6(buffer, dev.SCSIType); + } + + 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) + { + mediaTest.Density = (byte)decMode.Value.Header.BlockDescriptors[0].Density; + mediaTest.DensitySpecified = true; + } + } + + if(mediaType.StartsWith("CD-", StringComparison.Ordinal) || mediaType == "Audio CD") + { + mediaTest.CanReadTOCSpecified = true; + mediaTest.CanReadFullTOCSpecified = true; + DicConsole.WriteLine("Querying CD TOC..."); + mediaTest.CanReadTOC = !dev.ReadTocPmaAtip(out buffer, out senseBuffer, false, 0, 0, timeout, out duration); + DicConsole.WriteLine("Querying CD Full TOC..."); + mediaTest.CanReadFullTOC = !dev.ReadRawToc(out buffer, out senseBuffer, 1, timeout, out duration); + } + + if(mediaType.StartsWith("CD-R", StringComparison.Ordinal)) + { + mediaTest.CanReadATIPSpecified = true; + mediaTest.CanReadPMASpecified = true; + DicConsole.WriteLine("Querying CD ATIP..."); + mediaTest.CanReadATIP = !dev.ReadAtip(out buffer, out senseBuffer, timeout, out duration); + DicConsole.WriteLine("Querying CD PMA..."); + mediaTest.CanReadPMA = !dev.ReadPma(out buffer, out senseBuffer, timeout, out duration); + } + + if(mediaType.StartsWith("DVD-", StringComparison.Ordinal) || mediaType.StartsWith("HD DVD-", StringComparison.Ordinal)) + { + mediaTest.CanReadPFISpecified = true; + mediaTest.CanReadDMISpecified = true; + DicConsole.WriteLine("Querying DVD PFI..."); + mediaTest.CanReadPFI = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.PhysicalInformation, 0, timeout, out duration); + DicConsole.WriteLine("Querying DVD DMI..."); + mediaTest.CanReadDMI = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.DiscManufacturingInformation, 0, timeout, out duration); + } + + if(mediaType == "DVD-ROM") + { + mediaTest.CanReadCMISpecified = true; + DicConsole.WriteLine("Querying DVD CMI..."); + mediaTest.CanReadCMI = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.CopyrightInformation, 0, timeout, out duration); + } + + if(mediaType == "DVD-ROM" || mediaType == "HD DVD-ROM") + { + mediaTest.CanReadBCASpecified = true; + DicConsole.WriteLine("Querying DVD BCA..."); + mediaTest.CanReadBCA = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.BurstCuttingArea, 0, timeout, out duration); + mediaTest.CanReadAACSSpecified = true; + DicConsole.WriteLine("Querying DVD AACS..."); + mediaTest.CanReadAACS = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.DVD_AACS, 0, timeout, out duration); + } + + if(mediaType == "BD-ROM") + { + mediaTest.CanReadBCASpecified = true; + DicConsole.WriteLine("Querying BD BCA..."); + mediaTest.CanReadBCA = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.BD, 0, 0, MmcDiscStructureFormat.BD_BurstCuttingArea, 0, timeout, out duration); + } + + if(mediaType == "DVD-RAM" || mediaType == "HD DVD-RAM") + { + mediaTest.CanReadDDSSpecified = true; + mediaTest.CanReadSpareAreaInformationSpecified = true; + mediaTest.CanReadDDS = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.DVDRAM_DDS, 0, timeout, out duration); + mediaTest.CanReadSpareAreaInformation = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.DVDRAM_SpareAreaInformation, 0, timeout, out duration); + } + + if(mediaType.StartsWith("BD-R", StringComparison.Ordinal) && mediaType != "BD-ROM") + { + mediaTest.CanReadDDSSpecified = true; + mediaTest.CanReadSpareAreaInformationSpecified = true; + DicConsole.WriteLine("Querying BD DDS..."); + mediaTest.CanReadDDS = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.BD, 0, 0, MmcDiscStructureFormat.BD_DDS, 0, timeout, out duration); + DicConsole.WriteLine("Querying BD SAI..."); + mediaTest.CanReadSpareAreaInformation = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.BD, 0, 0, MmcDiscStructureFormat.BD_SpareAreaInformation, 0, timeout, out duration); + } + + if(mediaType == "DVD-R" || mediaType == "DVD-RW") + { + mediaTest.CanReadPRISpecified = true; + DicConsole.WriteLine("Querying DVD PRI..."); + mediaTest.CanReadPRI = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.PreRecordedInfo, 0, timeout, out duration); + } + + if(mediaType == "DVD-R" || mediaType == "DVD-RW" || mediaType == "HD DVD-R") + { + mediaTest.CanReadMediaIDSpecified = true; + mediaTest.CanReadRecordablePFISpecified = true; + DicConsole.WriteLine("Querying DVD Media ID..."); + mediaTest.CanReadMediaID = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.DVDR_MediaIdentifier, 0, timeout, out duration); + DicConsole.WriteLine("Querying DVD Embossed PFI..."); + mediaTest.CanReadRecordablePFI = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.DVDR_PhysicalInformation, 0, timeout, out duration); + } + + if(mediaType.StartsWith("DVD+R", StringComparison.Ordinal)) + { + mediaTest.CanReadADIPSpecified = true; + mediaTest.CanReadDCBSpecified = true; + DicConsole.WriteLine("Querying DVD ADIP..."); + mediaTest.CanReadADIP = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.ADIP, 0, timeout, out duration); + DicConsole.WriteLine("Querying DVD DCB..."); + mediaTest.CanReadDCB = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.DCB, 0, timeout, out duration); + } + + if(mediaType == "HD DVD-ROM") + { + mediaTest.CanReadHDCMISpecified = true; + DicConsole.WriteLine("Querying HD DVD CMI..."); + mediaTest.CanReadHDCMI = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.HDDVD_CopyrightInformation, 0, timeout, out duration); + } + + if(mediaType.EndsWith(" DL", StringComparison.Ordinal)) + { + mediaTest.CanReadLayerCapacitySpecified = true; + DicConsole.WriteLine("Querying DVD Layer Capacity..."); + mediaTest.CanReadLayerCapacity = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.DVDR_LayerCapacity, 0, timeout, out duration); + } + + if(mediaType.StartsWith("BD-R", StringComparison.Ordinal)) + { + mediaTest.CanReadDiscInformationSpecified = true; + mediaTest.CanReadPACSpecified = true; + DicConsole.WriteLine("Querying BD Disc Information..."); + mediaTest.CanReadDiscInformation = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.BD, 0, 0, MmcDiscStructureFormat.DiscInformation, 0, timeout, out duration); + DicConsole.WriteLine("Querying BD PAC..."); + mediaTest.CanReadPAC = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.BD, 0, 0, MmcDiscStructureFormat.PAC, 0, timeout, out duration); + } + + mediaTest.SupportsReadSpecified = true; + mediaTest.SupportsRead10Specified = true; + mediaTest.SupportsRead12Specified = true; + mediaTest.SupportsRead16Specified = true; + + DicConsole.WriteLine("Trying SCSI READ (6)..."); + mediaTest.SupportsRead = !dev.Read6(out buffer, out senseBuffer, 0, 2048, timeout, out duration); + DicConsole.WriteLine("Trying SCSI READ (10)..."); + mediaTest.SupportsRead10 = !dev.Read10(out buffer, out senseBuffer, 0, false, true, false, false, 0, 2048, 0, 1, timeout, out duration); + DicConsole.WriteLine("Trying SCSI READ (12)..."); + mediaTest.SupportsRead12 = !dev.Read12(out buffer, out senseBuffer, 0, false, true, false, false, 0, 2048, 0, 1, false, timeout, out duration); + DicConsole.WriteLine("Trying SCSI READ (16)..."); + mediaTest.SupportsRead16 = !dev.Read16(out buffer, out senseBuffer, 0, false, true, false, 0, 2048, 0, 1, false, timeout, out duration); + + if(debug) + { + if(!tryPlextor) + { + pressedKey = new ConsoleKeyInfo(); + while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N) + { + DicConsole.Write("Do you have want to try Plextor vendor commands? THIS IS DANGEROUS AND CAN IRREVERSIBLY DESTROY YOUR DRIVE (IF IN DOUBT PRESS 'N') (Y/N): "); + pressedKey = System.Console.ReadKey(); + DicConsole.WriteLine(); + } + + tryPlextor |= pressedKey.Key == ConsoleKey.Y; + } + } + + if(mediaType.StartsWith("CD-", StringComparison.Ordinal) || mediaType == "Audio CD") + { + mediaTest.CanReadC2PointersSpecified = true; + mediaTest.CanReadCorrectedSubchannelSpecified = true; + mediaTest.CanReadCorrectedSubchannelWithC2Specified = true; + mediaTest.CanReadLeadInSpecified = true; + mediaTest.CanReadLeadOutSpecified = true; + mediaTest.CanReadPQSubchannelSpecified = true; + mediaTest.CanReadPQSubchannelWithC2Specified = true; + mediaTest.CanReadRWSubchannelSpecified = true; + mediaTest.CanReadRWSubchannelWithC2Specified = true; + mediaTest.SupportsReadCdMsfSpecified = true; + mediaTest.SupportsReadCdSpecified = true; + mediaTest.SupportsReadCdMsfRawSpecified = true; + mediaTest.SupportsReadCdRawSpecified = true; + + if(mediaType == "Audio CD") + { + DicConsole.WriteLine("Trying SCSI READ CD..."); + mediaTest.SupportsReadCd = !dev.ReadCd(out buffer, out senseBuffer, 0, 2352, 1, MmcSectorTypes.CDDA, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.None, MmcSubchannel.None, timeout, out duration); + DicConsole.WriteLine("Trying SCSI READ CD MSF..."); + mediaTest.SupportsReadCdMsf = !dev.ReadCdMsf(out buffer, out senseBuffer, 0x00000200, 0x00000201, 2352, MmcSectorTypes.CDDA, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.None, MmcSubchannel.None, timeout, out duration); + } + else + { + DicConsole.WriteLine("Trying SCSI READ CD..."); + mediaTest.SupportsReadCd = !dev.ReadCd(out buffer, out senseBuffer, 0, 2048, 1, MmcSectorTypes.AllTypes, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.None, MmcSubchannel.None, timeout, out duration); + DicConsole.WriteLine("Trying SCSI READ CD MSF..."); + mediaTest.SupportsReadCdMsf = !dev.ReadCdMsf(out buffer, out senseBuffer, 0x00000200, 0x00000201, 2048, MmcSectorTypes.AllTypes, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.None, MmcSubchannel.None, timeout, out duration); + DicConsole.WriteLine("Trying SCSI READ CD full sector..."); + mediaTest.SupportsReadCdRaw = !dev.ReadCd(out buffer, out senseBuffer, 0, 2352, 1, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None, MmcSubchannel.None, timeout, out duration); + DicConsole.WriteLine("Trying SCSI READ CD MSF full sector..."); + mediaTest.SupportsReadCdMsfRaw = !dev.ReadCdMsf(out buffer, out senseBuffer, 0x00000200, 0x00000201, 2352, MmcSectorTypes.AllTypes, false, false, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None, MmcSubchannel.None, timeout, out duration); + } + + if(mediaTest.SupportsReadCdRaw || mediaType == "Audio CD") + { + DicConsole.WriteLine("Trying to read CD Lead-In..."); + for(int i = -150; i < 0; i++) + { + if(mediaType == "Audio CD") + sense = dev.ReadCd(out buffer, out senseBuffer, (uint)i, 2352, 1, MmcSectorTypes.CDDA, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.None, MmcSubchannel.None, timeout, out duration); + else + sense = dev.ReadCd(out buffer, out senseBuffer, (uint)i, 2352, 1, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None, MmcSubchannel.None, timeout, out duration); + if(!sense) + { + mediaTest.CanReadLeadIn = true; + break; + } + } + + DicConsole.WriteLine("Trying to read CD Lead-Out..."); + if(mediaType == "Audio CD") + mediaTest.CanReadLeadOut = dev.ReadCd(out buffer, out senseBuffer, (uint)(mediaTest.Blocks + 1), 2352, 1, MmcSectorTypes.CDDA, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.None, MmcSubchannel.None, timeout, out duration); + else + mediaTest.CanReadLeadOut = !dev.ReadCd(out buffer, out senseBuffer, (uint)(mediaTest.Blocks + 1), 2352, 1, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None, MmcSubchannel.None, timeout, out duration); + } + + if(mediaType == "Audio CD" && mediaTest.SupportsReadCd) + { + DicConsole.WriteLine("Trying to read C2 Pointers..."); + mediaTest.CanReadC2Pointers = !dev.ReadCd(out buffer, out senseBuffer, 0, 2646, 1, MmcSectorTypes.CDDA, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2Pointers, MmcSubchannel.None, timeout, out duration); + if(!mediaTest.CanReadC2Pointers) + mediaTest.CanReadC2Pointers = !dev.ReadCd(out buffer, out senseBuffer, 0, 2648, 1, MmcSectorTypes.CDDA, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2PointersAndBlock, MmcSubchannel.None, timeout, out duration); + + DicConsole.WriteLine("Trying to read subchannels..."); + mediaTest.CanReadPQSubchannel = !dev.ReadCd(out buffer, out senseBuffer, 0, 2368, 1, MmcSectorTypes.CDDA, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.None, MmcSubchannel.Q16, timeout, out duration); + mediaTest.CanReadRWSubchannel = !dev.ReadCd(out buffer, out senseBuffer, 0, 2448, 1, MmcSectorTypes.CDDA, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.None, MmcSubchannel.Raw, timeout, out duration); + mediaTest.CanReadCorrectedSubchannel = !dev.ReadCd(out buffer, out senseBuffer, 0, 2448, 1, MmcSectorTypes.CDDA, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.None, MmcSubchannel.RW, timeout, out duration); + + DicConsole.WriteLine("Trying to read subchannels with C2 Pointers..."); + mediaTest.CanReadPQSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2662, 1, MmcSectorTypes.CDDA, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2Pointers, MmcSubchannel.Q16, timeout, out duration); + if(!mediaTest.CanReadPQSubchannelWithC2) + mediaTest.CanReadPQSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2664, 1, MmcSectorTypes.CDDA, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2PointersAndBlock, MmcSubchannel.Q16, timeout, out duration); + + mediaTest.CanReadRWSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2712, 1, MmcSectorTypes.CDDA, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2Pointers, MmcSubchannel.Raw, timeout, out duration); + if(!mediaTest.CanReadRWSubchannelWithC2) + mediaTest.CanReadRWSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2714, 1, MmcSectorTypes.CDDA, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2PointersAndBlock, MmcSubchannel.Raw, timeout, out duration); + + mediaTest.CanReadCorrectedSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2712, 1, MmcSectorTypes.CDDA, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2Pointers, MmcSubchannel.RW, timeout, out duration); + if(!mediaTest.CanReadCorrectedSubchannelWithC2) + mediaTest.CanReadCorrectedSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2714, 1, MmcSectorTypes.CDDA, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2PointersAndBlock, MmcSubchannel.RW, timeout, out duration); + } + else if(mediaTest.SupportsReadCdRaw) + { + DicConsole.WriteLine("Trying to read C2 Pointers..."); + mediaTest.CanReadC2Pointers = !dev.ReadCd(out buffer, out senseBuffer, 0, 2646, 1, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.C2Pointers, MmcSubchannel.None, timeout, out duration); + if(!mediaTest.CanReadC2Pointers) + mediaTest.CanReadC2Pointers = !dev.ReadCd(out buffer, out senseBuffer, 0, 2646, 1, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.C2PointersAndBlock, MmcSubchannel.None, timeout, out duration); + + DicConsole.WriteLine("Trying to read subchannels..."); + mediaTest.CanReadPQSubchannel = !dev.ReadCd(out buffer, out senseBuffer, 0, 2368, 1, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None, MmcSubchannel.Q16, timeout, out duration); + mediaTest.CanReadRWSubchannel = !dev.ReadCd(out buffer, out senseBuffer, 0, 2448, 1, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None, MmcSubchannel.Raw, timeout, out duration); + mediaTest.CanReadCorrectedSubchannel = !dev.ReadCd(out buffer, out senseBuffer, 0, 2448, 1, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None, MmcSubchannel.RW, timeout, out duration); + + DicConsole.WriteLine("Trying to read subchannels with C2 Pointers..."); + mediaTest.CanReadPQSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2662, 1, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.C2Pointers, MmcSubchannel.Q16, timeout, out duration); + if(!mediaTest.CanReadPQSubchannelWithC2) + mediaTest.CanReadPQSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2664, 1, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.C2PointersAndBlock, MmcSubchannel.Q16, timeout, out duration); + + mediaTest.CanReadRWSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2712, 1, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.C2Pointers, MmcSubchannel.Raw, timeout, out duration); + if(!mediaTest.CanReadRWSubchannelWithC2) + mediaTest.CanReadRWSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2714, 1, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.C2PointersAndBlock, MmcSubchannel.Raw, timeout, out duration); + + mediaTest.CanReadCorrectedSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2712, 1, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.C2Pointers, MmcSubchannel.RW, timeout, out duration); + if(!mediaTest.CanReadCorrectedSubchannelWithC2) + mediaTest.CanReadCorrectedSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2714, 1, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.C2PointersAndBlock, MmcSubchannel.RW, timeout, out duration); + } + else + { + DicConsole.WriteLine("Trying to read C2 Pointers..."); + mediaTest.CanReadC2Pointers = !dev.ReadCd(out buffer, out senseBuffer, 0, 2342, 1, MmcSectorTypes.AllTypes, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2Pointers, MmcSubchannel.None, timeout, out duration); + if(!mediaTest.CanReadC2Pointers) + mediaTest.CanReadC2Pointers = !dev.ReadCd(out buffer, out senseBuffer, 0, 2344, 1, MmcSectorTypes.AllTypes, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2PointersAndBlock, MmcSubchannel.None, timeout, out duration); + + DicConsole.WriteLine("Trying to read subchannels..."); + mediaTest.CanReadPQSubchannel = !dev.ReadCd(out buffer, out senseBuffer, 0, 2064, 1, MmcSectorTypes.AllTypes, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.None, MmcSubchannel.Q16, timeout, out duration); + mediaTest.CanReadRWSubchannel = !dev.ReadCd(out buffer, out senseBuffer, 0, 2144, 1, MmcSectorTypes.AllTypes, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.None, MmcSubchannel.Raw, timeout, out duration); + mediaTest.CanReadCorrectedSubchannel = !dev.ReadCd(out buffer, out senseBuffer, 0, 2144, 1, MmcSectorTypes.AllTypes, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.None, MmcSubchannel.RW, timeout, out duration); + + DicConsole.WriteLine("Trying to read subchannels with C2 Pointers..."); + mediaTest.CanReadPQSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2358, 1, MmcSectorTypes.AllTypes, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2Pointers, MmcSubchannel.Q16, timeout, out duration); + if(!mediaTest.CanReadPQSubchannelWithC2) + mediaTest.CanReadPQSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2360, 1, MmcSectorTypes.AllTypes, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2PointersAndBlock, MmcSubchannel.Q16, timeout, out duration); + + mediaTest.CanReadRWSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2438, 1, MmcSectorTypes.AllTypes, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2Pointers, MmcSubchannel.Raw, timeout, out duration); + if(!mediaTest.CanReadRWSubchannelWithC2) + mediaTest.CanReadRWSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2440, 1, MmcSectorTypes.AllTypes, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2PointersAndBlock, MmcSubchannel.Raw, timeout, out duration); + + mediaTest.CanReadCorrectedSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2438, 1, MmcSectorTypes.AllTypes, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2Pointers, MmcSubchannel.RW, timeout, out duration); + if(!mediaTest.CanReadCorrectedSubchannelWithC2) + mediaTest.CanReadCorrectedSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2440, 1, MmcSectorTypes.AllTypes, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2PointersAndBlock, MmcSubchannel.RW, timeout, out duration); + } + + if(debug) + { + if(!tryNEC) + { + pressedKey = new ConsoleKeyInfo(); + while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N) + { + DicConsole.Write("Do you have want to try NEC vendor commands? THIS IS DANGEROUS AND CAN IRREVERSIBLY DESTROY YOUR DRIVE (IF IN DOUBT PRESS 'N') (Y/N): "); + pressedKey = System.Console.ReadKey(); + DicConsole.WriteLine(); + } + + tryNEC |= pressedKey.Key == ConsoleKey.Y; + } + + if(!tryPioneer) + { + pressedKey = new ConsoleKeyInfo(); + while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N) + { + DicConsole.Write("Do you have want to try Pioneer vendor commands? THIS IS DANGEROUS AND CAN IRREVERSIBLY DESTROY YOUR DRIVE (IF IN DOUBT PRESS 'N') (Y/N): "); + pressedKey = System.Console.ReadKey(); + DicConsole.WriteLine(); + } + + tryPioneer |= pressedKey.Key == ConsoleKey.Y; + } + } + + if(tryPlextor) + { + mediaTest.SupportsPlextorReadCDDASpecified = true; + DicConsole.WriteLine("Trying Plextor READ CD-DA..."); + mediaTest.SupportsPlextorReadCDDA = !dev.PlextorReadCdDa(out buffer, out senseBuffer, 0, 2352, 1, PlextorSubchannel.None, timeout, out duration); + } + + if(tryPioneer) + { + mediaTest.SupportsPioneerReadCDDASpecified = true; + mediaTest.SupportsPioneerReadCDDAMSFSpecified = true; + DicConsole.WriteLine("Trying Pioneer READ CD-DA..."); + mediaTest.SupportsPioneerReadCDDA = !dev.PioneerReadCdDa(out buffer, out senseBuffer, 0, 2352, 1, PioneerSubchannel.None, timeout, out duration); + DicConsole.WriteLine("Trying Pioneer READ CD-DA MSF..."); + mediaTest.SupportsPioneerReadCDDAMSF = !dev.PioneerReadCdDaMsf(out buffer, out senseBuffer, 0x00000200, 0x00000201, 2352, PioneerSubchannel.None, timeout, out duration); + } + + if(tryNEC) + { + mediaTest.SupportsNECReadCDDASpecified = true; + DicConsole.WriteLine("Trying NEC READ CD-DA..."); + mediaTest.SupportsNECReadCDDA = !dev.NecReadCdDa(out buffer, out senseBuffer, 0, 1, timeout, out duration); + } + } + + mediaTest.LongBlockSize = mediaTest.BlockSize; + DicConsole.WriteLine("Trying SCSI READ LONG (10)..."); + sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 0xFFFF, timeout, out duration); + if(sense && !dev.Error) + { + Decoders.SCSI.FixedSense? decSense = Decoders.SCSI.Sense.DecodeFixed(senseBuffer); + if(decSense.HasValue) + { + if(decSense.Value.SenseKey == Decoders.SCSI.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); + mediaTest.LongBlockSizeSpecified = true; + } + } + } + } + + if(debug) + { + if(!tryHLDTST) + { + pressedKey = new ConsoleKeyInfo(); + while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N) + { + DicConsole.Write("Do you have want to try HL-DT-ST (aka LG) vendor commands? THIS IS DANGEROUS AND CAN IRREVERSIBLY DESTROY YOUR DRIVE (IF IN DOUBT PRESS 'N') (Y/N): "); + pressedKey = System.Console.ReadKey(); + DicConsole.WriteLine(); + } + + tryHLDTST |= pressedKey.Key == ConsoleKey.Y; + } + } + + if(mediaTest.SupportsReadLong && mediaTest.LongBlockSize == mediaTest.BlockSize) + { + if(mediaTest.BlockSize == 512) + { + // Long sector sizes for 512-byte magneto-opticals + foreach(ushort testSize in new[] { 600, 610, 630 }) + { + sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, testSize, timeout, out duration); + if(!sense && !dev.Error) + { + mediaTest.SupportsReadLong = true; + mediaTest.LongBlockSize = testSize; + mediaTest.LongBlockSizeSpecified = true; + break; + } + } + } + else if(mediaTest.BlockSize == 1024) + { + sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 1200, timeout, out duration); + if(!sense && !dev.Error) + { + mediaTest.SupportsReadLong = true; + mediaTest.LongBlockSize = 1200; + mediaTest.LongBlockSizeSpecified = true; + } + } + else if(mediaTest.BlockSize == 2048) + { + if(mediaType.StartsWith("DVD", StringComparison.Ordinal)) + { + sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 37856, timeout, out duration); + if(!sense && !dev.Error) + { + mediaTest.SupportsReadLong = true; + mediaTest.LongBlockSize = 37856; + mediaTest.LongBlockSizeSpecified = true; + } + } + else + { + sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 2380, timeout, out duration); + if(!sense && !dev.Error) + { + mediaTest.SupportsReadLong = true; + mediaTest.LongBlockSize = 2380; + mediaTest.LongBlockSizeSpecified = true; + } + } + } + else if(mediaTest.BlockSize == 4096) + { + sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 4760, timeout, out duration); + if(!sense && !dev.Error) + { + mediaTest.SupportsReadLong = true; + mediaTest.LongBlockSize = 4760; + mediaTest.LongBlockSizeSpecified = true; + } + } + else if(mediaTest.BlockSize == 8192) + { + sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 9424, timeout, out duration); + if(!sense && !dev.Error) + { + mediaTest.SupportsReadLong = true; + mediaTest.LongBlockSize = 9424; + mediaTest.LongBlockSizeSpecified = true; + } + } + } + + if(tryPlextor) + { + mediaTest.SupportsPlextorReadRawDVDSpecified = true; + DicConsole.WriteLine("Trying Plextor trick to raw read DVDs..."); + mediaTest.SupportsPlextorReadRawDVD = !dev.PlextorReadRawDvd(out buffer, out senseBuffer, 0, 1, timeout, out duration); + if(mediaTest.SupportsPlextorReadRawDVD) + mediaTest.SupportsPlextorReadRawDVD = !ArrayHelpers.ArrayIsNullOrEmpty(buffer); + } + + if(tryHLDTST) + { + mediaTest.SupportsHLDTSTReadRawDVDSpecified = true; + DicConsole.WriteLine("Trying HL-DT-ST (aka LG) trick to raw read DVDs..."); + mediaTest.SupportsHLDTSTReadRawDVD = !dev.HlDtStReadRawDvd(out buffer, out senseBuffer, 0, 1, timeout, out duration); + } + + 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) + { + for(ushort i = (ushort)mediaTest.BlockSize; i < (ushort)mediaTest.BlockSize * 36; i++) + { + DicConsole.Write("\rTrying to READ LONG with a size of {0} bytes...", i); + sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, i, timeout, out duration); + if(!sense) + { + if(debug) + { + FileStream bingo = new FileStream(string.Format("{0}_readlong.bin", mediaType), FileMode.Create); + bingo.Write(buffer, 0, buffer.Length); + bingo.Close(); + } + mediaTest.LongBlockSize = i; + mediaTest.LongBlockSizeSpecified = true; + break; + } + } + DicConsole.WriteLine(); + } + } + } + mediaTests.Add(mediaTest); + } + report.SCSI.MultiMediaDevice.TestedMedia = mediaTests.ToArray(); + } + } + } +} diff --git a/DiscImageChef.Core/Devices/Report/SCSI/SSC.cs b/DiscImageChef.Core/Devices/Report/SCSI/SSC.cs new file mode 100644 index 000000000..0e978a9df --- /dev/null +++ b/DiscImageChef.Core/Devices/Report/SCSI/SSC.cs @@ -0,0 +1,307 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : SSC.cs +// Version : 1.0 +// Author(s) : Natalia Portillo +// +// Component : Component +// +// Revision : $Revision$ +// Last change by : $Author$ +// Date : $Date$ +// +// --[ Description ] ---------------------------------------------------------- +// +// Description +// +// --[ 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 . +// +// ---------------------------------------------------------------------------- +// Copyright (C) 2011-2015 Claunia.com +// ****************************************************************************/ +// //$Id$ +using System; +using System.Collections.Generic; +using DiscImageChef.Console; +using DiscImageChef.Devices; +using DiscImageChef.Metadata; + +namespace DiscImageChef.Core.Devices.Report.SCSI +{ + internal static class SSC + { + internal static void Report(Device dev, ref DeviceReport report) + { + if(report == null) + return; + + byte[] senseBuffer; + byte[] buffer; + double duration; + bool sense; + uint timeout = 5; + ConsoleKeyInfo pressedKey; + Decoders.SCSI.Modes.DecodedMode? decMode = null; + + report.SCSI.SequentialDevice = new sscType(); + DicConsole.WriteLine("Querying SCSI READ BLOCK LIMITS..."); + sense = dev.ReadBlockLimits(out buffer, out senseBuffer, timeout, out duration); + if(!sense) + { + Decoders.SCSI.SSC.BlockLimits.BlockLimitsData? decBL = Decoders.SCSI.SSC.BlockLimits.Decode(buffer); + if(decBL.HasValue) + { + if(decBL.Value.granularity > 0) + { + report.SCSI.SequentialDevice.BlockSizeGranularitySpecified = true; + report.SCSI.SequentialDevice.BlockSizeGranularity = decBL.Value.granularity; + } + if(decBL.Value.maxBlockLen > 0) + { + report.SCSI.SequentialDevice.MaxBlockLengthSpecified = true; + report.SCSI.SequentialDevice.MaxBlockLength = decBL.Value.maxBlockLen; + } + if(decBL.Value.minBlockLen > 0) + { + report.SCSI.SequentialDevice.MinBlockLengthSpecified = true; + report.SCSI.SequentialDevice.MinBlockLength = decBL.Value.minBlockLen; + } + } + } + + DicConsole.WriteLine("Querying SCSI REPORT DENSITY SUPPORT..."); + sense = dev.ReportDensitySupport(out buffer, out senseBuffer, false, false, timeout, out duration); + if(!sense) + { + Decoders.SCSI.SSC.DensitySupport.DensitySupportHeader? dsh = Decoders.SCSI.SSC.DensitySupport.DecodeDensity(buffer); + if(dsh.HasValue) + { + report.SCSI.SequentialDevice.SupportedDensities = new SupportedDensity[dsh.Value.descriptors.Length]; + for(int i = 0; i < dsh.Value.descriptors.Length; i++) + { + report.SCSI.SequentialDevice.SupportedDensities[i].BitsPerMm = dsh.Value.descriptors[i].bpmm; + report.SCSI.SequentialDevice.SupportedDensities[i].Capacity = dsh.Value.descriptors[i].capacity; + report.SCSI.SequentialDevice.SupportedDensities[i].DefaultDensity = dsh.Value.descriptors[i].defaultDensity; + report.SCSI.SequentialDevice.SupportedDensities[i].Description = dsh.Value.descriptors[i].description; + report.SCSI.SequentialDevice.SupportedDensities[i].Duplicate = dsh.Value.descriptors[i].duplicate; + report.SCSI.SequentialDevice.SupportedDensities[i].Name = dsh.Value.descriptors[i].name; + report.SCSI.SequentialDevice.SupportedDensities[i].Organization = dsh.Value.descriptors[i].organization; + report.SCSI.SequentialDevice.SupportedDensities[i].PrimaryCode = dsh.Value.descriptors[i].primaryCode; + report.SCSI.SequentialDevice.SupportedDensities[i].SecondaryCode = dsh.Value.descriptors[i].secondaryCode; + report.SCSI.SequentialDevice.SupportedDensities[i].Tracks = dsh.Value.descriptors[i].tracks; + report.SCSI.SequentialDevice.SupportedDensities[i].Width = dsh.Value.descriptors[i].width; + report.SCSI.SequentialDevice.SupportedDensities[i].Writable = dsh.Value.descriptors[i].writable; + } + } + } + + DicConsole.WriteLine("Querying SCSI REPORT DENSITY SUPPORT for medium types..."); + sense = dev.ReportDensitySupport(out buffer, out senseBuffer, true, false, timeout, out duration); + if(!sense) + { + Decoders.SCSI.SSC.DensitySupport.MediaTypeSupportHeader? mtsh = Decoders.SCSI.SSC.DensitySupport.DecodeMediumType(buffer); + if(mtsh.HasValue) + { + report.SCSI.SequentialDevice.SupportedMediaTypes = new SupportedMedia[mtsh.Value.descriptors.Length]; + for(int i = 0; i < mtsh.Value.descriptors.Length; i++) + { + report.SCSI.SequentialDevice.SupportedMediaTypes[i].Description = mtsh.Value.descriptors[i].description; + report.SCSI.SequentialDevice.SupportedMediaTypes[i].Length = mtsh.Value.descriptors[i].length; + report.SCSI.SequentialDevice.SupportedMediaTypes[i].MediumType = mtsh.Value.descriptors[i].mediumType; + report.SCSI.SequentialDevice.SupportedMediaTypes[i].Name = mtsh.Value.descriptors[i].name; + report.SCSI.SequentialDevice.SupportedMediaTypes[i].Organization = mtsh.Value.descriptors[i].organization; + report.SCSI.SequentialDevice.SupportedMediaTypes[i].Width = mtsh.Value.descriptors[i].width; + if(mtsh.Value.descriptors[i].densityCodes != null) + { + report.SCSI.SequentialDevice.SupportedMediaTypes[i].DensityCodes = new int[mtsh.Value.descriptors[i].densityCodes.Length]; + for(int j = 0; j < mtsh.Value.descriptors.Length; j++) + report.SCSI.SequentialDevice.SupportedMediaTypes[i].DensityCodes[j] = mtsh.Value.descriptors[i].densityCodes[j]; + } + } + } + } + + List seqTests = new List(); + + pressedKey = new ConsoleKeyInfo(); + while(pressedKey.Key != ConsoleKey.N) + { + pressedKey = new ConsoleKeyInfo(); + while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N) + { + DicConsole.Write("Do you have media that you can insert in the drive? (Y/N): "); + pressedKey = System.Console.ReadKey(); + DicConsole.WriteLine(); + } + + if(pressedKey.Key == ConsoleKey.Y) + { + DicConsole.WriteLine("Please insert it in the drive and press any key when it is ready."); + System.Console.ReadKey(true); + + SequentialMedia seqTest = new SequentialMedia(); + DicConsole.Write("Please write a description of the media type and press enter: "); + seqTest.MediumTypeName = System.Console.ReadLine(); + DicConsole.Write("Please write the media manufacturer and press enter: "); + seqTest.Manufacturer = System.Console.ReadLine(); + DicConsole.Write("Please write the media model and press enter: "); + seqTest.Model = System.Console.ReadLine(); + + seqTest.MediaIsRecognized = true; + + sense = dev.Load(out senseBuffer, timeout, out duration); + sense = dev.ScsiTestUnitReady(out senseBuffer, timeout, out duration); + if(sense) + { + Decoders.SCSI.FixedSense? decSense = Decoders.SCSI.Sense.DecodeFixed(senseBuffer); + if(decSense.HasValue) + { + if(decSense.Value.ASC == 0x3A) + { + int leftRetries = 20; + while(leftRetries > 0) + { + DicConsole.Write("\rWaiting for drive to become ready"); + System.Threading.Thread.Sleep(2000); + sense = dev.ScsiTestUnitReady(out senseBuffer, timeout, out duration); + if(!sense) + break; + + leftRetries--; + } + + seqTest.MediaIsRecognized &= !sense; + } + else if(decSense.Value.ASC == 0x04 && decSense.Value.ASCQ == 0x01) + { + int leftRetries = 20; + while(leftRetries > 0) + { + DicConsole.Write("\rWaiting for drive to become ready"); + System.Threading.Thread.Sleep(2000); + sense = dev.ScsiTestUnitReady(out senseBuffer, timeout, out duration); + if(!sense) + break; + + leftRetries--; + } + + seqTest.MediaIsRecognized &= !sense; + } + else + seqTest.MediaIsRecognized = false; + } + else + seqTest.MediaIsRecognized = false; + } + + if(seqTest.MediaIsRecognized) + { + decMode = null; + + DicConsole.WriteLine("Querying SCSI MODE SENSE (10)..."); + sense = dev.ModeSense10(out buffer, out senseBuffer, false, true, ScsiModeSensePageControl.Current, 0x3F, 0x00, timeout, out duration); + if(!sense && !dev.Error) + { + report.SCSI.SupportsModeSense10 = true; + decMode = Decoders.SCSI.Modes.DecodeMode10(buffer, dev.SCSIType); + } + + DicConsole.WriteLine("Querying SCSI MODE SENSE..."); + sense = dev.ModeSense(out buffer, out senseBuffer, timeout, out duration); + if(!sense && !dev.Error) + { + report.SCSI.SupportsModeSense6 = true; + if(!decMode.HasValue) + decMode = Decoders.SCSI.Modes.DecodeMode6(buffer, dev.SCSIType); + } + + if(decMode.HasValue) + { + seqTest.MediumType = (byte)decMode.Value.Header.MediumType; + seqTest.MediumTypeSpecified = true; + if(decMode.Value.Header.BlockDescriptors != null && decMode.Value.Header.BlockDescriptors.Length > 0) + { + seqTest.Density = (byte)decMode.Value.Header.BlockDescriptors[0].Density; + seqTest.DensitySpecified = true; + } + } + } + + DicConsole.WriteLine("Querying SCSI REPORT DENSITY SUPPORT for current media..."); + sense = dev.ReportDensitySupport(out buffer, out senseBuffer, false, true, timeout, out duration); + if(!sense) + { + Decoders.SCSI.SSC.DensitySupport.DensitySupportHeader? dsh = Decoders.SCSI.SSC.DensitySupport.DecodeDensity(buffer); + if(dsh.HasValue) + { + seqTest.SupportedDensities = new SupportedDensity[dsh.Value.descriptors.Length]; + for(int i = 0; i < dsh.Value.descriptors.Length; i++) + { + seqTest.SupportedDensities[i].BitsPerMm = dsh.Value.descriptors[i].bpmm; + seqTest.SupportedDensities[i].Capacity = dsh.Value.descriptors[i].capacity; + seqTest.SupportedDensities[i].DefaultDensity = dsh.Value.descriptors[i].defaultDensity; + seqTest.SupportedDensities[i].Description = dsh.Value.descriptors[i].description; + seqTest.SupportedDensities[i].Duplicate = dsh.Value.descriptors[i].duplicate; + seqTest.SupportedDensities[i].Name = dsh.Value.descriptors[i].name; + seqTest.SupportedDensities[i].Organization = dsh.Value.descriptors[i].organization; + seqTest.SupportedDensities[i].PrimaryCode = dsh.Value.descriptors[i].primaryCode; + seqTest.SupportedDensities[i].SecondaryCode = dsh.Value.descriptors[i].secondaryCode; + seqTest.SupportedDensities[i].Tracks = dsh.Value.descriptors[i].tracks; + seqTest.SupportedDensities[i].Width = dsh.Value.descriptors[i].width; + seqTest.SupportedDensities[i].Writable = dsh.Value.descriptors[i].writable; + } + } + } + + DicConsole.WriteLine("Querying SCSI REPORT DENSITY SUPPORT for medium types for current media..."); + sense = dev.ReportDensitySupport(out buffer, out senseBuffer, true, true, timeout, out duration); + if(!sense) + { + Decoders.SCSI.SSC.DensitySupport.MediaTypeSupportHeader? mtsh = Decoders.SCSI.SSC.DensitySupport.DecodeMediumType(buffer); + if(mtsh.HasValue) + { + seqTest.SupportedMediaTypes = new SupportedMedia[mtsh.Value.descriptors.Length]; + for(int i = 0; i < mtsh.Value.descriptors.Length; i++) + { + seqTest.SupportedMediaTypes[i].Description = mtsh.Value.descriptors[i].description; + seqTest.SupportedMediaTypes[i].Length = mtsh.Value.descriptors[i].length; + seqTest.SupportedMediaTypes[i].MediumType = mtsh.Value.descriptors[i].mediumType; + seqTest.SupportedMediaTypes[i].Name = mtsh.Value.descriptors[i].name; + seqTest.SupportedMediaTypes[i].Organization = mtsh.Value.descriptors[i].organization; + seqTest.SupportedMediaTypes[i].Width = mtsh.Value.descriptors[i].width; + if(mtsh.Value.descriptors[i].densityCodes != null) + { + seqTest.SupportedMediaTypes[i].DensityCodes = new int[mtsh.Value.descriptors[i].densityCodes.Length]; + for(int j = 0; j < mtsh.Value.descriptors.Length; j++) + seqTest.SupportedMediaTypes[i].DensityCodes[j] = mtsh.Value.descriptors[i].densityCodes[j]; + } + } + } + } + + seqTest.CanReadMediaSerialSpecified = true; + DicConsole.WriteLine("Trying SCSI READ MEDIA SERIAL NUMBER..."); + seqTest.CanReadMediaSerial = !dev.ReadMediaSerialNumber(out buffer, out senseBuffer, timeout, out duration); + seqTests.Add(seqTest); + } + } + report.SCSI.SequentialDevice.TestedMedia = seqTests.ToArray(); + } + } +} diff --git a/DiscImageChef.Core/Devices/Report/SecureDigital.cs b/DiscImageChef.Core/Devices/Report/SecureDigital.cs new file mode 100644 index 000000000..b3b112075 --- /dev/null +++ b/DiscImageChef.Core/Devices/Report/SecureDigital.cs @@ -0,0 +1,54 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : SecureDigital.cs +// Version : 1.0 +// Author(s) : Natalia Portillo +// +// Component : Component +// +// Revision : $Revision$ +// Last change by : $Author$ +// Date : $Date$ +// +// --[ Description ] ---------------------------------------------------------- +// +// Description +// +// --[ 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 . +// +// ---------------------------------------------------------------------------- +// Copyright (C) 2011-2015 Claunia.com +// ****************************************************************************/ +// //$Id$ +using System; +using DiscImageChef.Devices; +using DiscImageChef.Metadata; + +namespace DiscImageChef.Core.Devices.Report +{ + public static class SecureDigital + { + public static void Report(Device dev, ref DeviceReport report, bool debug, ref bool removable) + { + if(report == null) + return; + + throw new NotImplementedException("MMC/SD devices not yet supported."); + } + } +} diff --git a/DiscImageChef.Core/Devices/Report/USB.cs b/DiscImageChef.Core/Devices/Report/USB.cs new file mode 100644 index 000000000..ffeac369c --- /dev/null +++ b/DiscImageChef.Core/Devices/Report/USB.cs @@ -0,0 +1,81 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : USB.cs +// Version : 1.0 +// Author(s) : Natalia Portillo +// +// Component : Component +// +// Revision : $Revision$ +// Last change by : $Author$ +// Date : $Date$ +// +// --[ Description ] ---------------------------------------------------------- +// +// Description +// +// --[ 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 . +// +// ---------------------------------------------------------------------------- +// Copyright (C) 2011-2015 Claunia.com +// ****************************************************************************/ +// //$Id$ +using System; +using DiscImageChef.Console; +using DiscImageChef.Devices; +using DiscImageChef.Metadata; + +namespace DiscImageChef.Core.Devices.Report +{ + public static class USB + { + public static void Report(Device dev, ref DeviceReport report, bool debug, ref bool removable) + { + if(report == null) + return; + + ConsoleKeyInfo pressedKey = new ConsoleKeyInfo(); + while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N) + { + DicConsole.Write("Is the device natively USB (in case of doubt, press Y)? (Y/N): "); + pressedKey = System.Console.ReadKey(); + DicConsole.WriteLine(); + } + + if(pressedKey.Key == ConsoleKey.Y) + { + report.USB = new usbType(); + report.USB.Manufacturer = dev.USBManufacturerString; + report.USB.Product = dev.USBProductString; + report.USB.ProductID = dev.USBProductID; + report.USB.VendorID = dev.USBVendorID; + + pressedKey = new ConsoleKeyInfo(); + while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N) + { + DicConsole.Write("Is the media removable from the reading/writing elements? (Y/N): "); + pressedKey = System.Console.ReadKey(); + DicConsole.WriteLine(); + } + + report.USB.RemovableMedia = pressedKey.Key == ConsoleKey.Y; + removable = report.USB.RemovableMedia; + } + } + } +} diff --git a/DiscImageChef.Core/DiscImageChef.Core.csproj b/DiscImageChef.Core/DiscImageChef.Core.csproj index e171c6463..0e0d83526 100644 --- a/DiscImageChef.Core/DiscImageChef.Core.csproj +++ b/DiscImageChef.Core/DiscImageChef.Core.csproj @@ -55,6 +55,17 @@ + + + + + + + + + + + @@ -105,21 +116,36 @@ {9183F2E0-A879-4F23-9EE3-C6908F1332B2} DiscImageChef.Interop + + {F8BDF57B-1571-4CD0-84B3-B422088D359A} + DiscImageChef.Helpers + + + - - - + + + + + + + + + + + + diff --git a/DiscImageChef.Core/Remote.cs b/DiscImageChef.Core/Remote.cs new file mode 100644 index 000000000..c87115f26 --- /dev/null +++ b/DiscImageChef.Core/Remote.cs @@ -0,0 +1,47 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : Remote.cs +// Version : 1.0 +// Author(s) : Natalia Portillo +// +// Component : Component +// +// Revision : $Revision$ +// Last change by : $Author$ +// Date : $Date$ +// +// --[ Description ] ---------------------------------------------------------- +// +// Description +// +// --[ 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 . +// +// ---------------------------------------------------------------------------- +// Copyright (C) 2011-2015 Claunia.com +// ****************************************************************************/ +// //$Id$ +namespace DiscImageChef.Core +{ + public static class Remote + { + public static void SubmitReport(System.Xml.Serialization.XmlSerializer xmlSer) + { + // TODO: Implement this + } + } +} diff --git a/DiscImageChef/ChangeLog b/DiscImageChef/ChangeLog index f0dd4141b..c7102515b 100644 --- a/DiscImageChef/ChangeLog +++ b/DiscImageChef/ChangeLog @@ -1,3 +1,9 @@ +2017-05-28 Natalia Portillo + + * Commands/DeviceReport.cs: + Refactor: Move device-report logic to Core and separate by + category. + 2017-05-28 Natalia Portillo * Commands/MediaScan.cs: diff --git a/DiscImageChef/Commands/DeviceReport.cs b/DiscImageChef/Commands/DeviceReport.cs index a30e29add..3a02ea741 100644 --- a/DiscImageChef/Commands/DeviceReport.cs +++ b/DiscImageChef/Commands/DeviceReport.cs @@ -31,12 +31,10 @@ // ****************************************************************************/ using System; -using DiscImageChef.Console; -using DiscImageChef.Devices; -using DiscImageChef.Metadata; using System.IO; -using System.Collections.Generic; -using DiscImageChef.Decoders.PCMCIA; +using DiscImageChef.Console; +using DiscImageChef.Core; +using DiscImageChef.Devices; namespace DiscImageChef.Commands { @@ -70,3855 +68,50 @@ namespace DiscImageChef.Commands Core.Statistics.AddDevice(dev); + Metadata.DeviceReport report = new Metadata.DeviceReport(); + bool removable = false; + string xmlFile; + if(!string.IsNullOrWhiteSpace(dev.Manufacturer) && !string.IsNullOrWhiteSpace(dev.Revision)) + xmlFile = dev.Manufacturer + "_" + dev.Model + "_" + dev.Revision + ".xml"; + else if(!string.IsNullOrWhiteSpace(dev.Manufacturer)) + xmlFile = dev.Manufacturer + "_" + dev.Model + ".xml"; + else if(!string.IsNullOrWhiteSpace(dev.Revision)) + xmlFile = dev.Model + "_" + dev.Revision + ".xml"; + else + xmlFile = dev.Model + ".xml"; + switch(dev.Type) { case DeviceType.ATA: - doATADeviceReport(options, dev); + Core.Devices.Report.ATA.Report(dev, ref report, options.Debug, ref removable); break; case DeviceType.MMC: case DeviceType.SecureDigital: - doSDDeviceReport(options, dev); + Core.Devices.Report.ATA.Report(dev, ref report, options.Debug, ref removable); break; case DeviceType.NVMe: - doNVMeDeviceReport(options, dev); + Core.Devices.Report.ATA.Report(dev, ref report, options.Debug, ref removable); break; case DeviceType.ATAPI: case DeviceType.SCSI: - doSCSIDeviceReport(options, dev); + Core.Devices.Report.SCSI.General.Report(dev, ref report, options.Debug, ref removable); break; default: throw new NotSupportedException("Unknown device type."); } + FileStream xmlFs = new FileStream(xmlFile, FileMode.Create); + + System.Xml.Serialization.XmlSerializer xmlSer = new System.Xml.Serialization.XmlSerializer(typeof(Metadata.DeviceReport)); + xmlSer.Serialize(xmlFs, report); + xmlFs.Close(); Core.Statistics.AddCommand("device-report"); - } - - static void doATADeviceReport(DeviceReportOptions options, Device dev) - { - Decoders.ATA.AtaErrorRegistersCHS errorRegs; - byte[] buffer; - double duration; - uint timeout = 5; - Metadata.DeviceReport report = new Metadata.DeviceReport(); - string xmlFile; - if(!string.IsNullOrWhiteSpace(dev.Manufacturer) && !string.IsNullOrWhiteSpace(dev.Revision)) - xmlFile = dev.Manufacturer + "_" + dev.Model + "_" + dev.Revision + ".xml"; - else if(!string.IsNullOrWhiteSpace(dev.Manufacturer)) - xmlFile = dev.Manufacturer + "_" + dev.Model + ".xml"; - else if(!string.IsNullOrWhiteSpace(dev.Revision)) - xmlFile = dev.Model + "_" + dev.Revision + ".xml"; - else - xmlFile = dev.Model + ".xml"; - - ConsoleKeyInfo pressedKey; - bool removable = false; - - if(dev.IsUSB) - { - pressedKey = new ConsoleKeyInfo(); - while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N) - { - DicConsole.Write("Is the device natively USB (in case of doubt, press Y)? (Y/N): "); - pressedKey = System.Console.ReadKey(); - DicConsole.WriteLine(); - } - - if(pressedKey.Key == ConsoleKey.Y) - { - report.USB = new usbType(); - report.USB.Manufacturer = dev.USBManufacturerString; - report.USB.Product = dev.USBProductString; - report.USB.ProductID = dev.USBProductID; - report.USB.VendorID = dev.USBVendorID; - - pressedKey = new ConsoleKeyInfo(); - while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N) - { - DicConsole.Write("Is the media removable from the reading/writing elements? (Y/N): "); - pressedKey = System.Console.ReadKey(); - DicConsole.WriteLine(); - } - - report.USB.RemovableMedia = pressedKey.Key == ConsoleKey.Y; - removable = true; - } - } - - if(dev.IsFireWire) - { - pressedKey = new ConsoleKeyInfo(); - while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N) - { - DicConsole.Write("Is the device natively FireWire (in case of doubt, press Y)? (Y/N): "); - pressedKey = System.Console.ReadKey(); - DicConsole.WriteLine(); - } - - if(pressedKey.Key == ConsoleKey.Y) - { - report.FireWire = new firewireType(); - report.FireWire.Manufacturer = dev.FireWireVendorName; - report.FireWire.Product = dev.FireWireModelName; - report.FireWire.ProductID = dev.FireWireModel; - report.FireWire.VendorID = dev.FireWireVendor; - - pressedKey = new ConsoleKeyInfo(); - while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N) - { - DicConsole.Write("Is the media removable from the reading/writing elements? (Y/N): "); - pressedKey = System.Console.ReadKey(); - DicConsole.WriteLine(); - } - - report.FireWire.RemovableMedia = pressedKey.Key == ConsoleKey.Y; - removable = true; - } - } - - if(dev.IsPCMCIA) - { - report.PCMCIA = new pcmciaType(); - report.PCMCIA.CIS = dev.CIS; - Decoders.PCMCIA.Tuple[] tuples = CIS.GetTuples(dev.CIS); - if(tuples != null) - { - foreach(Decoders.PCMCIA.Tuple tuple in tuples) - { - if(tuple.Code == TupleCodes.CISTPL_MANFID) - { - ManufacturerIdentificationTuple manfid = CIS.DecodeManufacturerIdentificationTuple(tuple); - - if(manfid != null) - { - report.PCMCIA.ManufacturerCode = manfid.ManufacturerID; - report.PCMCIA.CardCode = manfid.CardID; - report.PCMCIA.ManufacturerCodeSpecified = true; - report.PCMCIA.CardCodeSpecified = true; - } - } - else if(tuple.Code == TupleCodes.CISTPL_VERS_1) - { - Level1VersionTuple vers = CIS.DecodeLevel1VersionTuple(tuple); - - if(vers != null) - { - report.PCMCIA.Manufacturer = vers.Manufacturer; - report.PCMCIA.ProductName = vers.Product; - report.PCMCIA.Compliance = string.Format("{0}.{1}", vers.MajorVersion, vers.MinorVersion); - report.PCMCIA.AdditionalInformation = vers.AdditionalInformation; - } - } - } - } - - } - - DicConsole.WriteLine("Querying ATA IDENTIFY..."); - - dev.AtaIdentify(out buffer, out errorRegs, timeout, out duration); - - if(Decoders.ATA.Identify.Decode(buffer).HasValue) - { - Decoders.ATA.Identify.IdentifyDevice ataId = Decoders.ATA.Identify.Decode(buffer).Value; - - if((ushort)ataId.GeneralConfiguration == 0x848A) - { - report.CompactFlash = true; - report.CompactFlashSpecified = true; - removable = false; - } - else if(!removable && ataId.GeneralConfiguration.HasFlag(Decoders.ATA.Identify.GeneralConfigurationBit.Removable)) - { - pressedKey = new ConsoleKeyInfo(); - while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N) - { - DicConsole.Write("Is the media removable from the reading/writing elements? (Y/N): "); - pressedKey = System.Console.ReadKey(); - DicConsole.WriteLine(); - } - - removable = pressedKey.Key == ConsoleKey.Y; - } - - if(removable) - { - DicConsole.WriteLine("Please remove any media from the device and press any key when it is out."); - System.Console.ReadKey(true); - DicConsole.WriteLine("Querying ATA IDENTIFY..."); - dev.AtaIdentify(out buffer, out errorRegs, timeout, out duration); - ataId = Decoders.ATA.Identify.Decode(buffer).Value; - } - - report.ATA = new ataType(); - - if(!string.IsNullOrWhiteSpace(ataId.AdditionalPID)) - { - report.ATA.AdditionalPID = ataId.AdditionalPID; - report.ATA.AdditionalPIDSpecified = true; - } - if(ataId.APIOSupported != 0) - { - report.ATA.APIOSupported = ataId.APIOSupported; - report.ATA.APIOSupportedSpecified = true; - } - if(ataId.BufferType != 0) - { - report.ATA.BufferType = ataId.BufferType; - report.ATA.BufferTypeSpecified = true; - } - if(ataId.BufferSize != 0) - { - report.ATA.BufferSize = ataId.BufferSize; - report.ATA.BufferSizeSpecified = true; - } - if(ataId.Capabilities != 0) - { - report.ATA.Capabilities = ataId.Capabilities; - report.ATA.CapabilitiesSpecified = true; - } - if(ataId.Capabilities2 != 0) - { - report.ATA.Capabilities2 = ataId.Capabilities2; - report.ATA.Capabilities2Specified = true; - } - if(ataId.Capabilities3 != 0) - { - report.ATA.Capabilities3 = ataId.Capabilities3; - report.ATA.Capabilities3Specified = true; - } - if(ataId.CFAPowerMode != 0) - { - report.ATA.CFAPowerMode = ataId.CFAPowerMode; - report.ATA.CFAPowerModeSpecified = true; - } - if(ataId.CommandSet != 0) - { - report.ATA.CommandSet = ataId.CommandSet; - report.ATA.CommandSetSpecified = true; - } - if(ataId.CommandSet2 != 0) - { - report.ATA.CommandSet2 = ataId.CommandSet2; - report.ATA.CommandSet2Specified = true; - } - if(ataId.CommandSet3 != 0) - { - report.ATA.CommandSet3 = ataId.CommandSet3; - report.ATA.CommandSet3Specified = true; - } - if(ataId.CommandSet4 != 0) - { - report.ATA.CommandSet4 = ataId.CommandSet4; - report.ATA.CommandSet4Specified = true; - } - if(ataId.CommandSet5 != 0) - { - report.ATA.CommandSet5 = ataId.CommandSet5; - report.ATA.CommandSet5Specified = true; - } - if(ataId.CurrentAAM != 0) - { - report.ATA.CurrentAAM = ataId.CurrentAAM; - report.ATA.CurrentAAMSpecified = true; - } - if(ataId.CurrentAPM != 0) - { - report.ATA.CurrentAPM = ataId.CurrentAPM; - report.ATA.CurrentAPMSpecified = true; - } - if(ataId.DataSetMgmt != 0) - { - report.ATA.DataSetMgmt = ataId.DataSetMgmt; - report.ATA.DataSetMgmtSpecified = true; - } - if(ataId.DataSetMgmtSize != 0) - { - report.ATA.DataSetMgmtSize = ataId.DataSetMgmtSize; - report.ATA.DataSetMgmtSizeSpecified = true; - } - if(ataId.DeviceFormFactor != 0) - { - report.ATA.DeviceFormFactor = ataId.DeviceFormFactor; - report.ATA.DeviceFormFactorSpecified = true; - } - if(ataId.DMAActive != 0) - { - report.ATA.DMAActive = ataId.DMAActive; - report.ATA.DMAActiveSpecified = true; - } - if(ataId.DMASupported != 0) - { - report.ATA.DMASupported = ataId.DMASupported; - report.ATA.DMASupportedSpecified = true; - } - if(ataId.DMATransferTimingMode != 0) - { - report.ATA.DMATransferTimingMode = ataId.DMATransferTimingMode; - report.ATA.DMATransferTimingModeSpecified = true; - } - if(ataId.EnhancedSecurityEraseTime != 0) - { - report.ATA.EnhancedSecurityEraseTime = ataId.EnhancedSecurityEraseTime; - report.ATA.EnhancedSecurityEraseTimeSpecified = true; - } - if(ataId.EnabledCommandSet != 0) - { - report.ATA.EnabledCommandSet = ataId.EnabledCommandSet; - report.ATA.EnabledCommandSetSpecified = true; - } - if(ataId.EnabledCommandSet2 != 0) - { - report.ATA.EnabledCommandSet2 = ataId.EnabledCommandSet2; - report.ATA.EnabledCommandSet2Specified = true; - } - if(ataId.EnabledCommandSet3 != 0) - { - report.ATA.EnabledCommandSet3 = ataId.EnabledCommandSet3; - report.ATA.EnabledCommandSet3Specified = true; - } - if(ataId.EnabledCommandSet4 != 0) - { - report.ATA.EnabledCommandSet4 = ataId.EnabledCommandSet4; - report.ATA.EnabledCommandSet4Specified = true; - } - if(ataId.EnabledSATAFeatures != 0) - { - report.ATA.EnabledSATAFeatures = ataId.EnabledSATAFeatures; - report.ATA.EnabledSATAFeaturesSpecified = true; - } - if(ataId.ExtendedUserSectors != 0) - { - report.ATA.ExtendedUserSectors = ataId.ExtendedUserSectors; - report.ATA.ExtendedUserSectorsSpecified = true; - } - if(ataId.FreeFallSensitivity != 0) - { - report.ATA.FreeFallSensitivity = ataId.FreeFallSensitivity; - report.ATA.FreeFallSensitivitySpecified = true; - } - if(!string.IsNullOrWhiteSpace(ataId.FirmwareRevision)) - { - report.ATA.FirmwareRevision = ataId.FirmwareRevision; - report.ATA.FirmwareRevisionSpecified = true; - } - if(ataId.GeneralConfiguration != 0) - { - report.ATA.GeneralConfiguration = ataId.GeneralConfiguration; - report.ATA.GeneralConfigurationSpecified = true; - } - if(ataId.HardwareResetResult != 0) - { - report.ATA.HardwareResetResult = ataId.HardwareResetResult; - report.ATA.HardwareResetResultSpecified = true; - } - if(ataId.InterseekDelay != 0) - { - report.ATA.InterseekDelay = ataId.InterseekDelay; - report.ATA.InterseekDelaySpecified = true; - } - if(ataId.MajorVersion != 0) - { - report.ATA.MajorVersion = ataId.MajorVersion; - report.ATA.MajorVersionSpecified = true; - } - if(ataId.MasterPasswordRevisionCode != 0) - { - report.ATA.MasterPasswordRevisionCode = ataId.MasterPasswordRevisionCode; - report.ATA.MasterPasswordRevisionCodeSpecified = true; - } - if(ataId.MaxDownloadMicroMode3 != 0) - { - report.ATA.MaxDownloadMicroMode3 = ataId.MaxDownloadMicroMode3; - report.ATA.MaxDownloadMicroMode3Specified = true; - } - if(ataId.MaxQueueDepth != 0) - { - report.ATA.MaxQueueDepth = ataId.MaxQueueDepth; - report.ATA.MaxQueueDepthSpecified = true; - } - if(ataId.MDMAActive != 0) - { - report.ATA.MDMAActive = ataId.MDMAActive; - report.ATA.MDMAActiveSpecified = true; - } - if(ataId.MDMASupported != 0) - { - report.ATA.MDMASupported = ataId.MDMASupported; - report.ATA.MDMASupportedSpecified = true; - } - if(ataId.MinDownloadMicroMode3 != 0) - { - report.ATA.MinDownloadMicroMode3 = ataId.MinDownloadMicroMode3; - report.ATA.MinDownloadMicroMode3Specified = true; - } - if(ataId.MinMDMACycleTime != 0) - { - report.ATA.MinMDMACycleTime = ataId.MinMDMACycleTime; - report.ATA.MinMDMACycleTimeSpecified = true; - } - if(ataId.MinorVersion != 0) - { - report.ATA.MinorVersion = ataId.MinorVersion; - report.ATA.MinorVersionSpecified = true; - } - if(ataId.MinPIOCycleTimeNoFlow != 0) - { - report.ATA.MinPIOCycleTimeNoFlow = ataId.MinPIOCycleTimeNoFlow; - report.ATA.MinPIOCycleTimeNoFlowSpecified = true; - } - if(ataId.MinPIOCycleTimeFlow != 0) - { - report.ATA.MinPIOCycleTimeFlow = ataId.MinPIOCycleTimeFlow; - report.ATA.MinPIOCycleTimeFlowSpecified = true; - } - if(!string.IsNullOrWhiteSpace(ataId.Model)) - { - report.ATA.Model = ataId.Model; - report.ATA.ModelSpecified = true; - } - if(ataId.MultipleMaxSectors != 0) - { - report.ATA.MultipleMaxSectors = ataId.MultipleMaxSectors; - report.ATA.MultipleMaxSectorsSpecified = true; - } - if(ataId.MultipleSectorNumber != 0) - { - report.ATA.MultipleSectorNumber = ataId.MultipleSectorNumber; - report.ATA.MultipleSectorNumberSpecified = true; - } - if(ataId.NVCacheCaps != 0) - { - report.ATA.NVCacheCaps = ataId.NVCacheCaps; - report.ATA.NVCacheCapsSpecified = true; - } - if(ataId.NVCacheSize != 0) - { - report.ATA.NVCacheSize = ataId.NVCacheSize; - report.ATA.NVCacheSizeSpecified = true; - } - if(ataId.NVCacheWriteSpeed != 0) - { - report.ATA.NVCacheWriteSpeed = ataId.NVCacheWriteSpeed; - report.ATA.NVCacheWriteSpeedSpecified = true; - } - if(ataId.NVEstimatedSpinUp != 0) - { - report.ATA.NVEstimatedSpinUp = ataId.NVEstimatedSpinUp; - report.ATA.NVEstimatedSpinUpSpecified = true; - } - if(ataId.PacketBusRelease != 0) - { - report.ATA.PacketBusRelease = ataId.PacketBusRelease; - report.ATA.PacketBusReleaseSpecified = true; - } - if(ataId.PIOTransferTimingMode != 0) - { - report.ATA.PIOTransferTimingMode = ataId.PIOTransferTimingMode; - report.ATA.PIOTransferTimingModeSpecified = true; - } - if(ataId.RecommendedAAM != 0) - { - report.ATA.RecommendedAAM = ataId.RecommendedAAM; - report.ATA.RecommendedAAMSpecified = true; - } - if(ataId.RecMDMACycleTime != 0) - { - report.ATA.RecommendedMDMACycleTime = ataId.RecMDMACycleTime; - report.ATA.RecommendedMDMACycleTimeSpecified = true; - } - if(ataId.RemovableStatusSet != 0) - { - report.ATA.RemovableStatusSet = ataId.RemovableStatusSet; - report.ATA.RemovableStatusSetSpecified = true; - } - if(ataId.SATACapabilities != 0) - { - report.ATA.SATACapabilities = ataId.SATACapabilities; - report.ATA.SATACapabilitiesSpecified = true; - } - if(ataId.SATACapabilities2 != 0) - { - report.ATA.SATACapabilities2 = ataId.SATACapabilities2; - report.ATA.SATACapabilities2Specified = true; - } - if(ataId.SATAFeatures != 0) - { - report.ATA.SATAFeatures = ataId.SATAFeatures; - report.ATA.SATAFeaturesSpecified = true; - } - if(ataId.SCTCommandTransport != 0) - { - report.ATA.SCTCommandTransport = ataId.SCTCommandTransport; - report.ATA.SCTCommandTransportSpecified = true; - } - if(ataId.SectorsPerCard != 0) - { - report.ATA.SectorsPerCard = ataId.SectorsPerCard; - report.ATA.SectorsPerCardSpecified = true; - } - if(ataId.SecurityEraseTime != 0) - { - report.ATA.SecurityEraseTime = ataId.SecurityEraseTime; - report.ATA.SecurityEraseTimeSpecified = true; - } - if(ataId.SecurityStatus != 0) - { - report.ATA.SecurityStatus = ataId.SecurityStatus; - report.ATA.SecurityStatusSpecified = true; - } - if(ataId.ServiceBusyClear != 0) - { - report.ATA.ServiceBusyClear = ataId.ServiceBusyClear; - report.ATA.ServiceBusyClearSpecified = true; - } - if(ataId.SpecificConfiguration != 0) - { - report.ATA.SpecificConfiguration = ataId.SpecificConfiguration; - report.ATA.SpecificConfigurationSpecified = true; - } - if(ataId.StreamAccessLatency != 0) - { - report.ATA.StreamAccessLatency = ataId.StreamAccessLatency; - report.ATA.StreamAccessLatencySpecified = true; - } - if(ataId.StreamMinReqSize != 0) - { - report.ATA.StreamMinReqSize = ataId.StreamMinReqSize; - report.ATA.StreamMinReqSizeSpecified = true; - } - if(ataId.StreamPerformanceGranularity != 0) - { - report.ATA.StreamPerformanceGranularity = ataId.StreamPerformanceGranularity; - report.ATA.StreamPerformanceGranularitySpecified = true; - } - if(ataId.StreamTransferTimeDMA != 0) - { - report.ATA.StreamTransferTimeDMA = ataId.StreamTransferTimeDMA; - report.ATA.StreamTransferTimeDMASpecified = true; - } - if(ataId.StreamTransferTimePIO != 0) - { - report.ATA.StreamTransferTimePIO = ataId.StreamTransferTimePIO; - report.ATA.StreamTransferTimePIOSpecified = true; - } - if(ataId.TransportMajorVersion != 0) - { - report.ATA.TransportMajorVersion = ataId.TransportMajorVersion; - report.ATA.TransportMajorVersionSpecified = true; - } - if(ataId.TransportMinorVersion != 0) - { - report.ATA.TransportMinorVersion = ataId.TransportMinorVersion; - report.ATA.TransportMinorVersionSpecified = true; - } - if(ataId.TrustedComputing != 0) - { - report.ATA.TrustedComputing = ataId.TrustedComputing; - report.ATA.TrustedComputingSpecified = true; - } - if(ataId.UDMAActive != 0) - { - report.ATA.UDMAActive = ataId.UDMAActive; - report.ATA.UDMAActiveSpecified = true; - } - if(ataId.UDMASupported != 0) - { - report.ATA.UDMASupported = ataId.UDMASupported; - report.ATA.UDMASupportedSpecified = true; - } - if(ataId.WRVMode != 0) - { - report.ATA.WRVMode = ataId.WRVMode; - report.ATA.WRVModeSpecified = true; - } - if(ataId.WRVSectorCountMode3 != 0) - { - report.ATA.WRVSectorCountMode3 = ataId.WRVSectorCountMode3; - report.ATA.WRVSectorCountMode3Specified = true; - } - if(ataId.WRVSectorCountMode2 != 0) - { - report.ATA.WRVSectorCountMode2 = ataId.WRVSectorCountMode2; - report.ATA.WRVSectorCountMode2Specified = true; - } - - if(removable) - { - List mediaTests = new List(); - - pressedKey = new ConsoleKeyInfo(); - while(pressedKey.Key != ConsoleKey.N) - { - pressedKey = new ConsoleKeyInfo(); - while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N) - { - DicConsole.Write("Do you have media that you can insert in the drive? (Y/N): "); - pressedKey = System.Console.ReadKey(); - DicConsole.WriteLine(); - } - - if(pressedKey.Key == ConsoleKey.Y) - { - DicConsole.WriteLine("Please insert it in the drive and press any key when it is ready."); - System.Console.ReadKey(true); - - 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 model and press enter: "); - mediaTest.Model = System.Console.ReadLine(); - - mediaTest.ManufacturerSpecified = true; - mediaTest.ModelSpecified = true; - mediaTest.MediaIsRecognized = true; - - DicConsole.WriteLine("Querying ATA IDENTIFY..."); - dev.AtaIdentify(out buffer, out errorRegs, timeout, out duration); - - if(Decoders.ATA.Identify.Decode(buffer).HasValue) - { - ataId = Decoders.ATA.Identify.Decode(buffer).Value; - - if(ataId.UnformattedBPT != 0) - { - mediaTest.UnformattedBPT = ataId.UnformattedBPT; - mediaTest.UnformattedBPTSpecified = true; - } - if(ataId.UnformattedBPS != 0) - { - mediaTest.UnformattedBPS = ataId.UnformattedBPS; - mediaTest.UnformattedBPSSpecified = true; - } - - if(ataId.Cylinders > 0 && ataId.Heads > 0 && ataId.SectorsPerTrack > 0) - { - mediaTest.CHS = new chsType(); - mediaTest.CHS.Cylinders = ataId.Cylinders; - mediaTest.CHS.Heads = ataId.Heads; - mediaTest.CHS.Sectors = ataId.SectorsPerTrack; - mediaTest.Blocks = (ulong)(ataId.Cylinders * ataId.Heads * ataId.SectorsPerTrack); - mediaTest.BlocksSpecified = true; - } - - if(ataId.CurrentCylinders > 0 && ataId.CurrentHeads > 0 && ataId.CurrentSectorsPerTrack > 0) - { - mediaTest.CurrentCHS = new chsType(); - mediaTest.CurrentCHS.Cylinders = ataId.CurrentCylinders; - mediaTest.CurrentCHS.Heads = ataId.CurrentHeads; - mediaTest.CurrentCHS.Sectors = ataId.CurrentSectorsPerTrack; - mediaTest.Blocks = (ulong)(ataId.CurrentCylinders * ataId.CurrentHeads * ataId.CurrentSectorsPerTrack); - mediaTest.BlocksSpecified = true; - } - - if(ataId.Capabilities.HasFlag(Decoders.ATA.Identify.CapabilitiesBit.LBASupport)) - { - mediaTest.LBASectors = ataId.LBASectors; - mediaTest.LBASectorsSpecified = true; - mediaTest.Blocks = ataId.LBASectors; - mediaTest.BlocksSpecified = true; - } - - if(ataId.CommandSet2.HasFlag(Decoders.ATA.Identify.CommandSetBit2.LBA48)) - { - mediaTest.LBA48Sectors = ataId.LBA48Sectors; - mediaTest.LBA48SectorsSpecified = true; - mediaTest.Blocks = ataId.LBA48Sectors; - mediaTest.BlocksSpecified = true; - } - - if(ataId.NominalRotationRate != 0x0000 && - ataId.NominalRotationRate != 0xFFFF) - { - if(ataId.NominalRotationRate == 0x0001) - { - mediaTest.SolidStateDevice = true; - mediaTest.SolidStateDeviceSpecified = true; - } - else - { - mediaTest.SolidStateDevice = false; - mediaTest.SolidStateDeviceSpecified = true; - mediaTest.NominalRotationRate = ataId.NominalRotationRate; - mediaTest.NominalRotationRateSpecified = true; - } - } - - uint logicalsectorsize = 0; - 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) - { -#pragma warning disable IDE0004 // Cast is necessary, otherwise incorrect value is created - physicalsectorsize = logicalsectorsize * (uint)Math.Pow(2, (double)(ataId.PhysLogSectorSize & 0xF)); -#pragma warning restore IDE0004 // Cast is necessary, otherwise incorrect value is created - } - else - physicalsectorsize = logicalsectorsize; - } - else - { - logicalsectorsize = 512; - physicalsectorsize = 512; - } - - mediaTest.BlockSize = logicalsectorsize; - mediaTest.BlockSizeSpecified = true; - if(physicalsectorsize != logicalsectorsize) - { - mediaTest.PhysicalBlockSize = physicalsectorsize; - mediaTest.PhysicalBlockSizeSpecified = true; - - if((ataId.LogicalAlignment & 0x8000) == 0x0000 && - (ataId.LogicalAlignment & 0x4000) == 0x4000) - { - mediaTest.LogicalAlignment = (ushort)(ataId.LogicalAlignment & 0x3FFF); - mediaTest.LogicalAlignmentSpecified = true; - } - } - - if(ataId.EccBytes != 0x0000 && ataId.EccBytes != 0xFFFF) - { - mediaTest.LongBlockSize = logicalsectorsize + ataId.EccBytes; - mediaTest.LongBlockSizeSpecified = true; - } - - if(ataId.CommandSet3.HasFlag(Decoders.ATA.Identify.CommandSetBit3.MustBeSet) && - !ataId.CommandSet3.HasFlag(Decoders.ATA.Identify.CommandSetBit3.MustBeClear) && - ataId.EnabledCommandSet3.HasFlag(Decoders.ATA.Identify.CommandSetBit3.MediaSerial)) - { - mediaTest.CanReadMediaSerial = true; - mediaTest.CanReadMediaSerialSpecified = true; - if(!string.IsNullOrWhiteSpace(ataId.MediaManufacturer)) - { - mediaTest.Manufacturer = ataId.MediaManufacturer; - mediaTest.ManufacturerSpecified = true; - } - } - - mediaTest.SupportsReadLbaSpecified = true; - mediaTest.SupportsReadRetryLbaSpecified = true; - mediaTest.SupportsReadDmaLbaSpecified = true; - mediaTest.SupportsReadDmaRetryLbaSpecified = true; - mediaTest.SupportsReadLongLbaSpecified = true; - mediaTest.SupportsReadLongRetryLbaSpecified = true; - mediaTest.SupportsSeekLbaSpecified = true; - - mediaTest.SupportsReadLba48Specified = true; - mediaTest.SupportsReadDmaLba48Specified = true; - - mediaTest.SupportsReadSpecified = true; - mediaTest.SupportsReadRetrySpecified = true; - mediaTest.SupportsReadDmaSpecified = true; - mediaTest.SupportsReadDmaRetrySpecified = true; - mediaTest.SupportsReadLongSpecified = true; - mediaTest.SupportsReadLongRetrySpecified = true; - mediaTest.SupportsSeekSpecified = true; - - Decoders.ATA.AtaErrorRegistersCHS errorChs; - Decoders.ATA.AtaErrorRegistersLBA28 errorLba; - Decoders.ATA.AtaErrorRegistersLBA48 errorLba48; - - byte[] readBuf; - ulong checkCorrectRead = BitConverter.ToUInt64(buffer, 0); - bool sense = true; - - DicConsole.WriteLine("Trying READ SECTOR(S) in CHS mode..."); - sense = dev.Read(out readBuf, out errorChs, false, 0, 0, 1, 1, timeout, out duration); - mediaTest.SupportsRead = (!sense && (errorChs.status & 0x01) != 0x01 && errorChs.error == 0 && readBuf.Length > 0); - DicConsole.WriteLine("Trying READ SECTOR(S) RETRY in CHS mode..."); - sense = dev.Read(out readBuf, out errorChs, true, 0, 0, 1, 1, timeout, out duration); - mediaTest.SupportsReadRetry = (!sense && (errorChs.status & 0x01) != 0x01 && errorChs.error == 0 && readBuf.Length > 0); - DicConsole.WriteLine("Trying READ DMA in CHS mode..."); - sense = dev.ReadDma(out readBuf, out errorChs, false, 0, 0, 1, 1, timeout, out duration); - mediaTest.SupportsReadDma = (!sense && (errorChs.status & 0x01) != 0x01 && errorChs.error == 0 && readBuf.Length > 0); - DicConsole.WriteLine("Trying READ DMA RETRY in CHS mode..."); - sense = dev.ReadDma(out readBuf, out errorChs, true, 0, 0, 1, 1, timeout, out duration); - mediaTest.SupportsReadDmaRetry = (!sense && (errorChs.status & 0x01) != 0x01 && errorChs.error == 0 && readBuf.Length > 0); - DicConsole.WriteLine("Trying READ LONG in CHS mode..."); - sense = dev.ReadLong(out readBuf, out errorChs, false, 0, 0, 1, mediaTest.LongBlockSize, timeout, out duration); - mediaTest.SupportsReadLong = (!sense && (errorChs.status & 0x01) != 0x01 && errorChs.error == 0 && readBuf.Length > 0 && BitConverter.ToUInt64(readBuf, 0) != checkCorrectRead); - DicConsole.WriteLine("Trying READ LONG RETRY in CHS mode..."); - sense = dev.ReadLong(out readBuf, out errorChs, true, 0, 0, 1, mediaTest.LongBlockSize, timeout, out duration); - mediaTest.SupportsReadLongRetry = (!sense && (errorChs.status & 0x01) != 0x01 && errorChs.error == 0 && readBuf.Length > 0 && BitConverter.ToUInt64(readBuf, 0) != checkCorrectRead); - DicConsole.WriteLine("Trying SEEK in CHS mode..."); - sense = dev.Seek(out errorChs, 0, 0, 1, timeout, out duration); - mediaTest.SupportsSeek = (!sense && (errorChs.status & 0x01) != 0x01 && errorChs.error == 0); - - DicConsole.WriteLine("Trying READ SECTOR(S) in LBA mode..."); - sense = dev.Read(out readBuf, out errorLba, false, 0, 1, timeout, out duration); - mediaTest.SupportsReadLba = (!sense && (errorLba.status & 0x01) != 0x01 && errorLba.error == 0 && readBuf.Length > 0); - DicConsole.WriteLine("Trying READ SECTOR(S) RETRY in LBA mode..."); - sense = dev.Read(out readBuf, out errorLba, true, 0, 1, timeout, out duration); - mediaTest.SupportsReadRetryLba = (!sense && (errorLba.status & 0x01) != 0x01 && errorLba.error == 0 && readBuf.Length > 0); - DicConsole.WriteLine("Trying READ DMA in LBA mode..."); - sense = dev.ReadDma(out readBuf, out errorLba, false, 0, 1, timeout, out duration); - mediaTest.SupportsReadDmaLba = (!sense && (errorLba.status & 0x01) != 0x01 && errorLba.error == 0 && readBuf.Length > 0); - DicConsole.WriteLine("Trying READ DMA RETRY in LBA mode..."); - sense = dev.ReadDma(out readBuf, out errorLba, true, 0, 1, timeout, out duration); - mediaTest.SupportsReadDmaRetryLba = (!sense && (errorLba.status & 0x01) != 0x01 && errorLba.error == 0 && readBuf.Length > 0); - DicConsole.WriteLine("Trying READ LONG in LBA mode..."); - sense = dev.ReadLong(out readBuf, out errorLba, false, 0, mediaTest.LongBlockSize, timeout, out duration); - mediaTest.SupportsReadLongLba = (!sense && (errorLba.status & 0x01) != 0x01 && errorLba.error == 0 && readBuf.Length > 0 && BitConverter.ToUInt64(readBuf, 0) != checkCorrectRead); - DicConsole.WriteLine("Trying READ LONG RETRY in LBA mode..."); - sense = dev.ReadLong(out readBuf, out errorLba, true, 0, mediaTest.LongBlockSize, timeout, out duration); - mediaTest.SupportsReadLongRetryLba = (!sense && (errorLba.status & 0x01) != 0x01 && errorLba.error == 0 && readBuf.Length > 0 && BitConverter.ToUInt64(readBuf, 0) != checkCorrectRead); - DicConsole.WriteLine("Trying SEEK in LBA mode..."); - sense = dev.Seek(out errorLba, 0, timeout, out duration); - mediaTest.SupportsSeekLba = (!sense && (errorLba.status & 0x01) != 0x01 && errorLba.error == 0); - - DicConsole.WriteLine("Trying READ SECTOR(S) in LBA48 mode..."); - sense = dev.Read(out readBuf, out errorLba48, 0, 1, timeout, out duration); - mediaTest.SupportsReadLba48 = (!sense && (errorLba48.status & 0x01) != 0x01 && errorLba48.error == 0 && readBuf.Length > 0); - DicConsole.WriteLine("Trying READ DMA in LBA48 mode..."); - sense = dev.ReadDma(out readBuf, out errorLba48, 0, 1, timeout, out duration); - mediaTest.SupportsReadDmaLba48 = (!sense && (errorLba48.status & 0x01) != 0x01 && errorLba48.error == 0 && readBuf.Length > 0); - } - else - mediaTest.MediaIsRecognized = false; - - mediaTests.Add(mediaTest); - } - } - report.ATA.RemovableMedias = mediaTests.ToArray(); - } - else - { - report.ATA.ReadCapabilities = new testedMediaType(); - - if(ataId.UnformattedBPT != 0) - { - report.ATA.ReadCapabilities.UnformattedBPT = ataId.UnformattedBPT; - report.ATA.ReadCapabilities.UnformattedBPTSpecified = true; - } - if(ataId.UnformattedBPS != 0) - { - report.ATA.ReadCapabilities.UnformattedBPS = ataId.UnformattedBPS; - report.ATA.ReadCapabilities.UnformattedBPSSpecified = true; - } - - if(ataId.Cylinders > 0 && ataId.Heads > 0 && ataId.SectorsPerTrack > 0) - { - report.ATA.ReadCapabilities.CHS = new chsType(); - report.ATA.ReadCapabilities.CHS.Cylinders = ataId.Cylinders; - report.ATA.ReadCapabilities.CHS.Heads = ataId.Heads; - report.ATA.ReadCapabilities.CHS.Sectors = ataId.SectorsPerTrack; - report.ATA.ReadCapabilities.Blocks = (ulong)(ataId.Cylinders * ataId.Heads * ataId.SectorsPerTrack); - report.ATA.ReadCapabilities.BlocksSpecified = true; - } - - if(ataId.CurrentCylinders > 0 && ataId.CurrentHeads > 0 && ataId.CurrentSectorsPerTrack > 0) - { - report.ATA.ReadCapabilities.CurrentCHS = new chsType(); - report.ATA.ReadCapabilities.CurrentCHS.Cylinders = ataId.CurrentCylinders; - report.ATA.ReadCapabilities.CurrentCHS.Heads = ataId.CurrentHeads; - report.ATA.ReadCapabilities.CurrentCHS.Sectors = ataId.CurrentSectorsPerTrack; - report.ATA.ReadCapabilities.Blocks = (ulong)(ataId.CurrentCylinders * ataId.CurrentHeads * ataId.CurrentSectorsPerTrack); - report.ATA.ReadCapabilities.BlocksSpecified = true; - } - - if(ataId.Capabilities.HasFlag(Decoders.ATA.Identify.CapabilitiesBit.LBASupport)) - { - report.ATA.ReadCapabilities.LBASectors = ataId.LBASectors; - report.ATA.ReadCapabilities.LBASectorsSpecified = true; - report.ATA.ReadCapabilities.Blocks = ataId.LBASectors; - report.ATA.ReadCapabilities.BlocksSpecified = true; - } - - if(ataId.CommandSet2.HasFlag(Decoders.ATA.Identify.CommandSetBit2.LBA48)) - { - report.ATA.ReadCapabilities.LBA48Sectors = ataId.LBA48Sectors; - report.ATA.ReadCapabilities.LBA48SectorsSpecified = true; - report.ATA.ReadCapabilities.Blocks = ataId.LBA48Sectors; - report.ATA.ReadCapabilities.BlocksSpecified = true; - } - - if(ataId.NominalRotationRate != 0x0000 && - ataId.NominalRotationRate != 0xFFFF) - { - if(ataId.NominalRotationRate == 0x0001) - { - report.ATA.ReadCapabilities.SolidStateDevice = true; - report.ATA.ReadCapabilities.SolidStateDeviceSpecified = true; - } - else - { - report.ATA.ReadCapabilities.SolidStateDevice = false; - report.ATA.ReadCapabilities.SolidStateDeviceSpecified = true; - report.ATA.ReadCapabilities.NominalRotationRate = ataId.NominalRotationRate; - report.ATA.ReadCapabilities.NominalRotationRateSpecified = true; - } - } - - uint logicalsectorsize = 0; - 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) - { -#pragma warning disable IDE0004 // Cast is necessary, otherwise incorrect value is created - physicalsectorsize = logicalsectorsize * (uint)Math.Pow(2, (double)(ataId.PhysLogSectorSize & 0xF)); -#pragma warning restore IDE0004 // Cast is necessary, otherwise incorrect value is created - } - else - physicalsectorsize = logicalsectorsize; - } - else - { - logicalsectorsize = 512; - physicalsectorsize = 512; - } - - report.ATA.ReadCapabilities.BlockSize = logicalsectorsize; - report.ATA.ReadCapabilities.BlockSizeSpecified = true; - if(physicalsectorsize != logicalsectorsize) - { - report.ATA.ReadCapabilities.PhysicalBlockSize = physicalsectorsize; - report.ATA.ReadCapabilities.PhysicalBlockSizeSpecified = true; - - if((ataId.LogicalAlignment & 0x8000) == 0x0000 && - (ataId.LogicalAlignment & 0x4000) == 0x4000) - { - report.ATA.ReadCapabilities.LogicalAlignment = (ushort)(ataId.LogicalAlignment & 0x3FFF); - report.ATA.ReadCapabilities.LogicalAlignmentSpecified = true; - } - } - - if(ataId.EccBytes != 0x0000 && ataId.EccBytes != 0xFFFF) - { - report.ATA.ReadCapabilities.LongBlockSize = logicalsectorsize + ataId.EccBytes; - report.ATA.ReadCapabilities.LongBlockSizeSpecified = true; - } - - if(ataId.CommandSet3.HasFlag(Decoders.ATA.Identify.CommandSetBit3.MustBeSet) && - !ataId.CommandSet3.HasFlag(Decoders.ATA.Identify.CommandSetBit3.MustBeClear) && - ataId.EnabledCommandSet3.HasFlag(Decoders.ATA.Identify.CommandSetBit3.MediaSerial)) - { - report.ATA.ReadCapabilities.CanReadMediaSerial = true; - report.ATA.ReadCapabilities.CanReadMediaSerialSpecified = true; - if(!string.IsNullOrWhiteSpace(ataId.MediaManufacturer)) - { - report.ATA.ReadCapabilities.Manufacturer = ataId.MediaManufacturer; - report.ATA.ReadCapabilities.ManufacturerSpecified = true; - } - } - - report.ATA.ReadCapabilities.SupportsReadLbaSpecified = true; - report.ATA.ReadCapabilities.SupportsReadRetryLbaSpecified = true; - report.ATA.ReadCapabilities.SupportsReadDmaLbaSpecified = true; - report.ATA.ReadCapabilities.SupportsReadDmaRetryLbaSpecified = true; - report.ATA.ReadCapabilities.SupportsReadLongLbaSpecified = true; - report.ATA.ReadCapabilities.SupportsReadLongRetryLbaSpecified = true; - report.ATA.ReadCapabilities.SupportsSeekLbaSpecified = true; - - report.ATA.ReadCapabilities.SupportsReadLba48Specified = true; - report.ATA.ReadCapabilities.SupportsReadDmaLba48Specified = true; - - report.ATA.ReadCapabilities.SupportsReadSpecified = true; - report.ATA.ReadCapabilities.SupportsReadRetrySpecified = true; - report.ATA.ReadCapabilities.SupportsReadDmaSpecified = true; - report.ATA.ReadCapabilities.SupportsReadDmaRetrySpecified = true; - report.ATA.ReadCapabilities.SupportsReadLongSpecified = true; - report.ATA.ReadCapabilities.SupportsReadLongRetrySpecified = true; - report.ATA.ReadCapabilities.SupportsSeekSpecified = true; - - Decoders.ATA.AtaErrorRegistersCHS errorChs; - Decoders.ATA.AtaErrorRegistersLBA28 errorLba; - Decoders.ATA.AtaErrorRegistersLBA48 errorLba48; - - byte[] readBuf; - ulong checkCorrectRead = BitConverter.ToUInt64(buffer, 0); - bool sense = true; - - DicConsole.WriteLine("Trying READ SECTOR(S) in CHS mode..."); - sense = dev.Read(out readBuf, out errorChs, false, 0, 0, 1, 1, timeout, out duration); - report.ATA.ReadCapabilities.SupportsRead = (!sense && (errorChs.status & 0x01) != 0x01 && errorChs.error == 0 && readBuf.Length > 0); - DicConsole.WriteLine("Trying READ SECTOR(S) RETRY in CHS mode..."); - sense = dev.Read(out readBuf, out errorChs, true, 0, 0, 1, 1, timeout, out duration); - report.ATA.ReadCapabilities.SupportsReadRetry = (!sense && (errorChs.status & 0x01) != 0x01 && errorChs.error == 0 && readBuf.Length > 0); - DicConsole.WriteLine("Trying READ DMA in CHS mode..."); - sense = dev.ReadDma(out readBuf, out errorChs, false, 0, 0, 1, 1, timeout, out duration); - report.ATA.ReadCapabilities.SupportsReadDma = (!sense && (errorChs.status & 0x01) != 0x01 && errorChs.error == 0 && readBuf.Length > 0); - DicConsole.WriteLine("Trying READ DMA RETRY in CHS mode..."); - sense = dev.ReadDma(out readBuf, out errorChs, true, 0, 0, 1, 1, timeout, out duration); - report.ATA.ReadCapabilities.SupportsReadDmaRetry = (!sense && (errorChs.status & 0x01) != 0x01 && errorChs.error == 0 && readBuf.Length > 0); - DicConsole.WriteLine("Trying READ LONG in CHS mode..."); - sense = dev.ReadLong(out readBuf, out errorChs, false, 0, 0, 1, report.ATA.ReadCapabilities.LongBlockSize, timeout, out duration); - report.ATA.ReadCapabilities.SupportsReadLong = (!sense && (errorChs.status & 0x01) != 0x01 && errorChs.error == 0 && readBuf.Length > 0 && BitConverter.ToUInt64(readBuf, 0) != checkCorrectRead); - DicConsole.WriteLine("Trying READ LONG RETRY in CHS mode..."); - sense = dev.ReadLong(out readBuf, out errorChs, true, 0, 0, 1, report.ATA.ReadCapabilities.LongBlockSize, timeout, out duration); - report.ATA.ReadCapabilities.SupportsReadLongRetry = (!sense && (errorChs.status & 0x01) != 0x01 && errorChs.error == 0 && readBuf.Length > 0 && BitConverter.ToUInt64(readBuf, 0) != checkCorrectRead); - DicConsole.WriteLine("Trying SEEK in CHS mode..."); - sense = dev.Seek(out errorChs, 0, 0, 1, timeout, out duration); - report.ATA.ReadCapabilities.SupportsSeek = (!sense && (errorChs.status & 0x01) != 0x01 && errorChs.error == 0); - - DicConsole.WriteLine("Trying READ SECTOR(S) in LBA mode..."); - sense = dev.Read(out readBuf, out errorLba, false, 0, 1, timeout, out duration); - report.ATA.ReadCapabilities.SupportsReadLba = (!sense && (errorLba.status & 0x01) != 0x01 && errorLba.error == 0 && readBuf.Length > 0); - DicConsole.WriteLine("Trying READ SECTOR(S) RETRY in LBA mode..."); - sense = dev.Read(out readBuf, out errorLba, true, 0, 1, timeout, out duration); - report.ATA.ReadCapabilities.SupportsReadRetryLba = (!sense && (errorLba.status & 0x01) != 0x01 && errorLba.error == 0 && readBuf.Length > 0); - DicConsole.WriteLine("Trying READ DMA in LBA mode..."); - sense = dev.ReadDma(out readBuf, out errorLba, false, 0, 1, timeout, out duration); - report.ATA.ReadCapabilities.SupportsReadDmaLba = (!sense && (errorLba.status & 0x01) != 0x01 && errorLba.error == 0 && readBuf.Length > 0); - DicConsole.WriteLine("Trying READ DMA RETRY in LBA mode..."); - sense = dev.ReadDma(out readBuf, out errorLba, true, 0, 1, timeout, out duration); - report.ATA.ReadCapabilities.SupportsReadDmaRetryLba = (!sense && (errorLba.status & 0x01) != 0x01 && errorLba.error == 0 && readBuf.Length > 0); - DicConsole.WriteLine("Trying READ LONG in LBA mode..."); - sense = dev.ReadLong(out readBuf, out errorLba, false, 0, report.ATA.ReadCapabilities.LongBlockSize, timeout, out duration); - report.ATA.ReadCapabilities.SupportsReadLongLba = (!sense && (errorLba.status & 0x01) != 0x01 && errorLba.error == 0 && readBuf.Length > 0 && BitConverter.ToUInt64(readBuf, 0) != checkCorrectRead); - DicConsole.WriteLine("Trying READ LONG RETRY in LBA mode..."); - sense = dev.ReadLong(out readBuf, out errorLba, true, 0, report.ATA.ReadCapabilities.LongBlockSize, timeout, out duration); - report.ATA.ReadCapabilities.SupportsReadLongRetryLba = (!sense && (errorLba.status & 0x01) != 0x01 && errorLba.error == 0 && readBuf.Length > 0 && BitConverter.ToUInt64(readBuf, 0) != checkCorrectRead); - DicConsole.WriteLine("Trying SEEK in LBA mode..."); - sense = dev.Seek(out errorLba, 0, timeout, out duration); - report.ATA.ReadCapabilities.SupportsSeekLba = (!sense && (errorLba.status & 0x01) != 0x01 && errorLba.error == 0); - - DicConsole.WriteLine("Trying READ SECTOR(S) in LBA48 mode..."); - sense = dev.Read(out readBuf, out errorLba48, 0, 1, timeout, out duration); - report.ATA.ReadCapabilities.SupportsReadLba48 = (!sense && (errorLba48.status & 0x01) != 0x01 && errorLba48.error == 0 && readBuf.Length > 0); - DicConsole.WriteLine("Trying READ DMA in LBA48 mode..."); - sense = dev.ReadDma(out readBuf, out errorLba48, 0, 1, timeout, out duration); - report.ATA.ReadCapabilities.SupportsReadDmaLba48 = (!sense && (errorLba48.status & 0x01) != 0x01 && errorLba48.error == 0 && readBuf.Length > 0); - } - } - - FileStream xmlFs = new FileStream(xmlFile, FileMode.Create); - - System.Xml.Serialization.XmlSerializer xmlSer = new System.Xml.Serialization.XmlSerializer(typeof(Metadata.DeviceReport)); - xmlSer.Serialize(xmlFs, report); - xmlFs.Close(); - } - - static void doNVMeDeviceReport(DeviceReportOptions options, Device dev) - { - throw new NotImplementedException("NVMe devices not yet supported."); - } - - static void doSDDeviceReport(DeviceReportOptions options, Device dev) - { - throw new NotImplementedException("MMC/SD devices not yet supported."); - } - - static void doSCSIDeviceReport(DeviceReportOptions options, Device dev) - { - byte[] senseBuffer; - byte[] buffer; - double duration; - bool sense; - uint timeout = 5; - Metadata.DeviceReport report = new Metadata.DeviceReport(); - string xmlFile; - if(!string.IsNullOrWhiteSpace(dev.Manufacturer) && !string.IsNullOrWhiteSpace(dev.Revision)) - xmlFile = dev.Manufacturer + "_" + dev.Model + "_" + dev.Revision + ".xml"; - else if(!string.IsNullOrWhiteSpace(dev.Manufacturer)) - xmlFile = dev.Manufacturer + "_" + dev.Model + ".xml"; - else if(!string.IsNullOrWhiteSpace(dev.Revision)) - xmlFile = dev.Model + "_" + dev.Revision + ".xml"; - else - xmlFile = dev.Model + ".xml"; - ConsoleKeyInfo pressedKey; - bool removable = false; - - if(dev.IsUSB) - { - pressedKey = new ConsoleKeyInfo(); - while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N) - { - DicConsole.Write("Is the device natively USB (in case of doubt, press Y)? (Y/N): "); - pressedKey = System.Console.ReadKey(); - DicConsole.WriteLine(); - } - - if(pressedKey.Key == ConsoleKey.Y) - { - report.USB = new usbType(); - report.USB.Manufacturer = dev.USBManufacturerString; - report.USB.Product = dev.USBProductString; - report.USB.ProductID = dev.USBProductID; - report.USB.VendorID = dev.USBVendorID; - - pressedKey = new ConsoleKeyInfo(); - while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N) - { - DicConsole.Write("Is the media removable from the reading/writing elements? (Y/N): "); - pressedKey = System.Console.ReadKey(); - DicConsole.WriteLine(); - } - - report.USB.RemovableMedia = pressedKey.Key == ConsoleKey.Y; - removable = report.USB.RemovableMedia; - } - } - - if(dev.IsFireWire) - { - pressedKey = new ConsoleKeyInfo(); - while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N) - { - DicConsole.Write("Is the device natively FireWire (in case of doubt, press Y)? (Y/N): "); - pressedKey = System.Console.ReadKey(); - DicConsole.WriteLine(); - } - - if(pressedKey.Key == ConsoleKey.Y) - { - report.FireWire = new firewireType(); - report.FireWire.Manufacturer = dev.FireWireVendorName; - report.FireWire.Product = dev.FireWireModelName; - report.FireWire.ProductID = dev.FireWireModel; - report.FireWire.VendorID = dev.FireWireVendor; - - pressedKey = new ConsoleKeyInfo(); - while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N) - { - DicConsole.Write("Is the media removable from the reading/writing elements? (Y/N): "); - pressedKey = System.Console.ReadKey(); - DicConsole.WriteLine(); - } - - report.FireWire.RemovableMedia = pressedKey.Key == ConsoleKey.Y; - removable = report.FireWire.RemovableMedia; - } - } - - if(!dev.IsUSB && !dev.IsFireWire && dev.IsRemovable) - { - pressedKey = new ConsoleKeyInfo(); - while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N) - { - DicConsole.Write("Is the media removable from the reading/writing elements (flash memories ARE NOT removable)? (Y/N): "); - pressedKey = System.Console.ReadKey(); - DicConsole.WriteLine(); - } - - removable = pressedKey.Key == ConsoleKey.Y; - } - - if(dev.Type == DeviceType.ATAPI) - { - DicConsole.WriteLine("Querying ATAPI IDENTIFY..."); - - Decoders.ATA.AtaErrorRegistersCHS errorRegs; - dev.AtapiIdentify(out buffer, out errorRegs, timeout, out duration); - - if(Decoders.ATA.Identify.Decode(buffer).HasValue) - { - Decoders.ATA.Identify.IdentifyDevice atapiId = Decoders.ATA.Identify.Decode(buffer).Value; - - report.ATAPI = new ataType(); - - if(!string.IsNullOrWhiteSpace(atapiId.AdditionalPID)) - { - report.ATAPI.AdditionalPID = atapiId.AdditionalPID; - report.ATAPI.AdditionalPIDSpecified = true; - } - if(atapiId.APIOSupported != 0) - { - report.ATAPI.APIOSupported = atapiId.APIOSupported; - report.ATAPI.APIOSupportedSpecified = true; - } - if(atapiId.ATAPIByteCount != 0) - { - report.ATAPI.ATAPIByteCount = atapiId.ATAPIByteCount; - report.ATAPI.ATAPIByteCountSpecified = true; - } - if(atapiId.BufferType != 0) - { - report.ATAPI.BufferType = atapiId.BufferType; - report.ATAPI.BufferTypeSpecified = true; - } - if(atapiId.BufferSize != 0) - { - report.ATAPI.BufferSize = atapiId.BufferSize; - report.ATAPI.BufferSizeSpecified = true; - } - if(atapiId.Capabilities != 0) - { - report.ATAPI.Capabilities = atapiId.Capabilities; - report.ATAPI.CapabilitiesSpecified = true; - } - if(atapiId.Capabilities2 != 0) - { - report.ATAPI.Capabilities2 = atapiId.Capabilities2; - report.ATAPI.Capabilities2Specified = true; - } - if(atapiId.Capabilities3 != 0) - { - report.ATAPI.Capabilities3 = atapiId.Capabilities3; - report.ATAPI.Capabilities3Specified = true; - } - if(atapiId.CFAPowerMode != 0) - { - report.ATAPI.CFAPowerMode = atapiId.CFAPowerMode; - report.ATAPI.CFAPowerModeSpecified = true; - } - if(atapiId.CommandSet != 0) - { - report.ATAPI.CommandSet = atapiId.CommandSet; - report.ATAPI.CommandSetSpecified = true; - } - if(atapiId.CommandSet2 != 0) - { - report.ATAPI.CommandSet2 = atapiId.CommandSet2; - report.ATAPI.CommandSet2Specified = true; - } - if(atapiId.CommandSet3 != 0) - { - report.ATAPI.CommandSet3 = atapiId.CommandSet3; - report.ATAPI.CommandSet3Specified = true; - } - if(atapiId.CommandSet4 != 0) - { - report.ATAPI.CommandSet4 = atapiId.CommandSet4; - report.ATAPI.CommandSet4Specified = true; - } - if(atapiId.CommandSet5 != 0) - { - report.ATAPI.CommandSet5 = atapiId.CommandSet5; - report.ATAPI.CommandSet5Specified = true; - } - if(atapiId.CurrentAAM != 0) - { - report.ATAPI.CurrentAAM = atapiId.CurrentAAM; - report.ATAPI.CurrentAAMSpecified = true; - } - if(atapiId.CurrentAPM != 0) - { - report.ATAPI.CurrentAPM = atapiId.CurrentAPM; - report.ATAPI.CurrentAPMSpecified = true; - } - if(atapiId.DataSetMgmt != 0) - { - report.ATAPI.DataSetMgmt = atapiId.DataSetMgmt; - report.ATAPI.DataSetMgmtSpecified = true; - } - if(atapiId.DataSetMgmtSize != 0) - { - report.ATAPI.DataSetMgmtSize = atapiId.DataSetMgmtSize; - report.ATAPI.DataSetMgmtSizeSpecified = true; - } - if(atapiId.DeviceFormFactor != 0) - { - report.ATAPI.DeviceFormFactor = atapiId.DeviceFormFactor; - report.ATAPI.DeviceFormFactorSpecified = true; - } - if(atapiId.DMAActive != 0) - { - report.ATAPI.DMAActive = atapiId.DMAActive; - report.ATAPI.DMAActiveSpecified = true; - } - if(atapiId.DMASupported != 0) - { - report.ATAPI.DMASupported = atapiId.DMASupported; - report.ATAPI.DMASupportedSpecified = true; - } - if(atapiId.DMATransferTimingMode != 0) - { - report.ATAPI.DMATransferTimingMode = atapiId.DMATransferTimingMode; - report.ATAPI.DMATransferTimingModeSpecified = true; - } - if(atapiId.EnhancedSecurityEraseTime != 0) - { - report.ATAPI.EnhancedSecurityEraseTime = atapiId.EnhancedSecurityEraseTime; - report.ATAPI.EnhancedSecurityEraseTimeSpecified = true; - } - if(atapiId.EnabledCommandSet != 0) - { - report.ATAPI.EnabledCommandSet = atapiId.EnabledCommandSet; - report.ATAPI.EnabledCommandSetSpecified = true; - } - if(atapiId.EnabledCommandSet2 != 0) - { - report.ATAPI.EnabledCommandSet2 = atapiId.EnabledCommandSet2; - report.ATAPI.EnabledCommandSet2Specified = true; - } - if(atapiId.EnabledCommandSet3 != 0) - { - report.ATAPI.EnabledCommandSet3 = atapiId.EnabledCommandSet3; - report.ATAPI.EnabledCommandSet3Specified = true; - } - if(atapiId.EnabledCommandSet4 != 0) - { - report.ATAPI.EnabledCommandSet4 = atapiId.EnabledCommandSet4; - report.ATAPI.EnabledCommandSet4Specified = true; - } - if(atapiId.EnabledSATAFeatures != 0) - { - report.ATAPI.EnabledSATAFeatures = atapiId.EnabledSATAFeatures; - report.ATAPI.EnabledSATAFeaturesSpecified = true; - } - if(atapiId.ExtendedUserSectors != 0) - { - report.ATAPI.ExtendedUserSectors = atapiId.ExtendedUserSectors; - report.ATAPI.ExtendedUserSectorsSpecified = true; - } - if(atapiId.FreeFallSensitivity != 0) - { - report.ATAPI.FreeFallSensitivity = atapiId.FreeFallSensitivity; - report.ATAPI.FreeFallSensitivitySpecified = true; - } - if(!string.IsNullOrWhiteSpace(atapiId.FirmwareRevision)) - { - report.ATAPI.FirmwareRevision = atapiId.FirmwareRevision; - report.ATAPI.FirmwareRevisionSpecified = true; - } - if(atapiId.GeneralConfiguration != 0) - { - report.ATAPI.GeneralConfiguration = atapiId.GeneralConfiguration; - report.ATAPI.GeneralConfigurationSpecified = true; - } - if(atapiId.HardwareResetResult != 0) - { - report.ATAPI.HardwareResetResult = atapiId.HardwareResetResult; - report.ATAPI.HardwareResetResultSpecified = true; - } - if(atapiId.InterseekDelay != 0) - { - report.ATAPI.InterseekDelay = atapiId.InterseekDelay; - report.ATAPI.InterseekDelaySpecified = true; - } - if(atapiId.MajorVersion != 0) - { - report.ATAPI.MajorVersion = atapiId.MajorVersion; - report.ATAPI.MajorVersionSpecified = true; - } - if(atapiId.MasterPasswordRevisionCode != 0) - { - report.ATAPI.MasterPasswordRevisionCode = atapiId.MasterPasswordRevisionCode; - report.ATAPI.MasterPasswordRevisionCodeSpecified = true; - } - if(atapiId.MaxDownloadMicroMode3 != 0) - { - report.ATAPI.MaxDownloadMicroMode3 = atapiId.MaxDownloadMicroMode3; - report.ATAPI.MaxDownloadMicroMode3Specified = true; - } - if(atapiId.MaxQueueDepth != 0) - { - report.ATAPI.MaxQueueDepth = atapiId.MaxQueueDepth; - report.ATAPI.MaxQueueDepthSpecified = true; - } - if(atapiId.MDMAActive != 0) - { - report.ATAPI.MDMAActive = atapiId.MDMAActive; - report.ATAPI.MDMAActiveSpecified = true; - } - if(atapiId.MDMASupported != 0) - { - report.ATAPI.MDMASupported = atapiId.MDMASupported; - report.ATAPI.MDMASupportedSpecified = true; - } - if(atapiId.MinDownloadMicroMode3 != 0) - { - report.ATAPI.MinDownloadMicroMode3 = atapiId.MinDownloadMicroMode3; - report.ATAPI.MinDownloadMicroMode3Specified = true; - } - if(atapiId.MinMDMACycleTime != 0) - { - report.ATAPI.MinMDMACycleTime = atapiId.MinMDMACycleTime; - report.ATAPI.MinMDMACycleTimeSpecified = true; - } - if(atapiId.MinorVersion != 0) - { - report.ATAPI.MinorVersion = atapiId.MinorVersion; - report.ATAPI.MinorVersionSpecified = true; - } - if(atapiId.MinPIOCycleTimeNoFlow != 0) - { - report.ATAPI.MinPIOCycleTimeNoFlow = atapiId.MinPIOCycleTimeNoFlow; - report.ATAPI.MinPIOCycleTimeNoFlowSpecified = true; - } - if(atapiId.MinPIOCycleTimeFlow != 0) - { - report.ATAPI.MinPIOCycleTimeFlow = atapiId.MinPIOCycleTimeFlow; - report.ATAPI.MinPIOCycleTimeFlowSpecified = true; - } - if(!string.IsNullOrWhiteSpace(atapiId.Model)) - { - report.ATAPI.Model = atapiId.Model; - report.ATAPI.ModelSpecified = true; - } - if(atapiId.MultipleMaxSectors != 0) - { - report.ATAPI.MultipleMaxSectors = atapiId.MultipleMaxSectors; - report.ATAPI.MultipleMaxSectorsSpecified = true; - } - if(atapiId.MultipleSectorNumber != 0) - { - report.ATAPI.MultipleSectorNumber = atapiId.MultipleSectorNumber; - report.ATAPI.MultipleSectorNumberSpecified = true; - } - if(atapiId.NVCacheCaps != 0) - { - report.ATAPI.NVCacheCaps = atapiId.NVCacheCaps; - report.ATAPI.NVCacheCapsSpecified = true; - } - if(atapiId.NVCacheSize != 0) - { - report.ATAPI.NVCacheSize = atapiId.NVCacheSize; - report.ATAPI.NVCacheSizeSpecified = true; - } - if(atapiId.NVCacheWriteSpeed != 0) - { - report.ATAPI.NVCacheWriteSpeed = atapiId.NVCacheWriteSpeed; - report.ATAPI.NVCacheWriteSpeedSpecified = true; - } - if(atapiId.NVEstimatedSpinUp != 0) - { - report.ATAPI.NVEstimatedSpinUp = atapiId.NVEstimatedSpinUp; - report.ATAPI.NVEstimatedSpinUpSpecified = true; - } - if(atapiId.PacketBusRelease != 0) - { - report.ATAPI.PacketBusRelease = atapiId.PacketBusRelease; - report.ATAPI.PacketBusReleaseSpecified = true; - } - if(atapiId.PIOTransferTimingMode != 0) - { - report.ATAPI.PIOTransferTimingMode = atapiId.PIOTransferTimingMode; - report.ATAPI.PIOTransferTimingModeSpecified = true; - } - if(atapiId.RecommendedAAM != 0) - { - report.ATAPI.RecommendedAAM = atapiId.RecommendedAAM; - report.ATAPI.RecommendedAAMSpecified = true; - } - if(atapiId.RecMDMACycleTime != 0) - { - report.ATAPI.RecommendedMDMACycleTime = atapiId.RecMDMACycleTime; - report.ATAPI.RecommendedMDMACycleTimeSpecified = true; - } - if(atapiId.RemovableStatusSet != 0) - { - report.ATAPI.RemovableStatusSet = atapiId.RemovableStatusSet; - report.ATAPI.RemovableStatusSetSpecified = true; - } - if(atapiId.SATACapabilities != 0) - { - report.ATAPI.SATACapabilities = atapiId.SATACapabilities; - report.ATAPI.SATACapabilitiesSpecified = true; - } - if(atapiId.SATACapabilities2 != 0) - { - report.ATAPI.SATACapabilities2 = atapiId.SATACapabilities2; - report.ATAPI.SATACapabilities2Specified = true; - } - if(atapiId.SATAFeatures != 0) - { - report.ATAPI.SATAFeatures = atapiId.SATAFeatures; - report.ATAPI.SATAFeaturesSpecified = true; - } - if(atapiId.SCTCommandTransport != 0) - { - report.ATAPI.SCTCommandTransport = atapiId.SCTCommandTransport; - report.ATAPI.SCTCommandTransportSpecified = true; - } - if(atapiId.SectorsPerCard != 0) - { - report.ATAPI.SectorsPerCard = atapiId.SectorsPerCard; - report.ATAPI.SectorsPerCardSpecified = true; - } - if(atapiId.SecurityEraseTime != 0) - { - report.ATAPI.SecurityEraseTime = atapiId.SecurityEraseTime; - report.ATAPI.SecurityEraseTimeSpecified = true; - } - if(atapiId.SecurityStatus != 0) - { - report.ATAPI.SecurityStatus = atapiId.SecurityStatus; - report.ATAPI.SecurityStatusSpecified = true; - } - if(atapiId.ServiceBusyClear != 0) - { - report.ATAPI.ServiceBusyClear = atapiId.ServiceBusyClear; - report.ATAPI.ServiceBusyClearSpecified = true; - } - if(atapiId.SpecificConfiguration != 0) - { - report.ATAPI.SpecificConfiguration = atapiId.SpecificConfiguration; - report.ATAPI.SpecificConfigurationSpecified = true; - } - if(atapiId.StreamAccessLatency != 0) - { - report.ATAPI.StreamAccessLatency = atapiId.StreamAccessLatency; - report.ATAPI.StreamAccessLatencySpecified = true; - } - if(atapiId.StreamMinReqSize != 0) - { - report.ATAPI.StreamMinReqSize = atapiId.StreamMinReqSize; - report.ATAPI.StreamMinReqSizeSpecified = true; - } - if(atapiId.StreamPerformanceGranularity != 0) - { - report.ATAPI.StreamPerformanceGranularity = atapiId.StreamPerformanceGranularity; - report.ATAPI.StreamPerformanceGranularitySpecified = true; - } - if(atapiId.StreamTransferTimeDMA != 0) - { - report.ATAPI.StreamTransferTimeDMA = atapiId.StreamTransferTimeDMA; - report.ATAPI.StreamTransferTimeDMASpecified = true; - } - if(atapiId.StreamTransferTimePIO != 0) - { - report.ATAPI.StreamTransferTimePIO = atapiId.StreamTransferTimePIO; - report.ATAPI.StreamTransferTimePIOSpecified = true; - } - if(atapiId.TransportMajorVersion != 0) - { - report.ATAPI.TransportMajorVersion = atapiId.TransportMajorVersion; - report.ATAPI.TransportMajorVersionSpecified = true; - } - if(atapiId.TransportMinorVersion != 0) - { - report.ATAPI.TransportMinorVersion = atapiId.TransportMinorVersion; - report.ATAPI.TransportMinorVersionSpecified = true; - } - if(atapiId.TrustedComputing != 0) - { - report.ATAPI.TrustedComputing = atapiId.TrustedComputing; - report.ATAPI.TrustedComputingSpecified = true; - } - if(atapiId.UDMAActive != 0) - { - report.ATAPI.UDMAActive = atapiId.UDMAActive; - report.ATAPI.UDMAActiveSpecified = true; - } - if(atapiId.UDMASupported != 0) - { - report.ATAPI.UDMASupported = atapiId.UDMASupported; - report.ATAPI.UDMASupportedSpecified = true; - } - if(atapiId.WRVMode != 0) - { - report.ATAPI.WRVMode = atapiId.WRVMode; - report.ATAPI.WRVModeSpecified = true; - } - if(atapiId.WRVSectorCountMode3 != 0) - { - report.ATAPI.WRVSectorCountMode3 = atapiId.WRVSectorCountMode3; - report.ATAPI.WRVSectorCountMode3Specified = true; - } - if(atapiId.WRVSectorCountMode2 != 0) - { - report.ATAPI.WRVSectorCountMode2 = atapiId.WRVSectorCountMode2; - report.ATAPI.WRVSectorCountMode2Specified = true; - } - } - } - - DicConsole.WriteLine("Querying SCSI INQUIRY..."); - sense = dev.ScsiInquiry(out buffer, out senseBuffer); - - report.SCSI = new scsiType(); - - if(!sense && Decoders.SCSI.Inquiry.Decode(buffer).HasValue) - { - Decoders.SCSI.Inquiry.SCSIInquiry inq = Decoders.SCSI.Inquiry.Decode(buffer).Value; - - List versionDescriptors = new List(); - 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))) - { - report.SCSI.Inquiry.VendorIdentification = StringHandlers.CToString(inq.VendorIdentification).Trim(); - if(!string.IsNullOrWhiteSpace(report.SCSI.Inquiry.VendorIdentification)) - report.SCSI.Inquiry.VendorIdentificationSpecified = true; - } - if(!string.IsNullOrWhiteSpace(StringHandlers.CToString(inq.ProductIdentification))) - { - report.SCSI.Inquiry.ProductIdentification = StringHandlers.CToString(inq.ProductIdentification).Trim(); - if(!string.IsNullOrWhiteSpace(report.SCSI.Inquiry.ProductIdentification)) - report.SCSI.Inquiry.ProductIdentificationSpecified = true; - } - if(!string.IsNullOrWhiteSpace(StringHandlers.CToString(inq.ProductRevisionLevel))) - { - report.SCSI.Inquiry.ProductRevisionLevel = StringHandlers.CToString(inq.ProductRevisionLevel).Trim(); - if(!string.IsNullOrWhiteSpace(report.SCSI.Inquiry.ProductRevisionLevel)) - report.SCSI.Inquiry.ProductRevisionLevelSpecified = true; - } - if(inq.VersionDescriptors != null) - { - foreach(ushort descriptor in inq.VersionDescriptors) - { - if(descriptor != 0) - versionDescriptors.Add(descriptor); - } - - if(versionDescriptors.Count > 0) - report.SCSI.Inquiry.VersionDescriptors = versionDescriptors.ToArray(); - } - - report.SCSI.Inquiry.PeripheralQualifier = (Decoders.SCSI.PeripheralQualifiers)inq.PeripheralQualifier; - report.SCSI.Inquiry.PeripheralDeviceType = (Decoders.SCSI.PeripheralDeviceTypes)inq.PeripheralDeviceType; - report.SCSI.Inquiry.AsymmetricalLUNAccess = (Decoders.SCSI.TGPSValues)inq.TPGS; - report.SCSI.Inquiry.SPIClocking = (Decoders.SCSI.SPIClocking)inq.Clocking; - - 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; - } - - DicConsole.WriteLine("Querying list of SCSI EVPDs..."); - sense = dev.ScsiInquiry(out buffer, out senseBuffer, 0x00); - - if(!sense) - { - byte[] evpdPages = Decoders.SCSI.EVPD.DecodePage00(buffer); - if(evpdPages != null && evpdPages.Length > 0) - { - List evpds = new List(); - foreach(byte page in evpdPages) - { - if(page != 0x80) - { - DicConsole.WriteLine("Querying SCSI EVPD {0:X2}h...", page); - sense = dev.ScsiInquiry(out buffer, out senseBuffer, page); - if(!sense) - { - pageType evpd = new pageType(); - evpd.page = page; - evpd.value = buffer; - evpds.Add(evpd); - } - } - } - if(evpds.Count > 0) - report.SCSI.EVPDPages = evpds.ToArray(); - } - } - - if(removable) - { - if(dev.SCSIType == Decoders.SCSI.PeripheralDeviceTypes.MultiMediaDevice) - { - dev.AllowMediumRemoval(out senseBuffer, timeout, out duration); - dev.EjectTray(out senseBuffer, timeout, out duration); - } - else if(dev.SCSIType == Decoders.SCSI.PeripheralDeviceTypes.SequentialAccess) - { - dev.SpcAllowMediumRemoval(out senseBuffer, timeout, out duration); - DicConsole.WriteLine("Asking drive to unload tape (can take a few minutes)..."); - dev.Unload(out senseBuffer, timeout, out duration); - } - DicConsole.WriteLine("Please remove any media from the device and press any key when it is out."); - System.Console.ReadKey(true); - } - - Decoders.SCSI.Modes.DecodedMode? decMode = null; - Decoders.SCSI.PeripheralDeviceTypes devType = dev.SCSIType; - - DicConsole.WriteLine("Querying all mode pages and subpages using SCSI MODE SENSE (10)..."); - sense = dev.ModeSense10(out buffer, out senseBuffer, false, true, ScsiModeSensePageControl.Default, 0x3F, 0xFF, timeout, out duration); - if(sense || dev.Error) - { - DicConsole.WriteLine("Querying all mode pages using SCSI MODE SENSE (10)..."); - sense = dev.ModeSense10(out buffer, out senseBuffer, false, true, ScsiModeSensePageControl.Default, 0x3F, 0x00, timeout, out duration); - if(!sense && dev.Error) - { - report.SCSI.SupportsModeSense10 = true; - report.SCSI.SupportsModeSubpages = false; - decMode = Decoders.SCSI.Modes.DecodeMode10(buffer, devType); - } - } - else - { - report.SCSI.SupportsModeSense10 = true; - report.SCSI.SupportsModeSubpages = true; - decMode = Decoders.SCSI.Modes.DecodeMode10(buffer, devType); - } - - DicConsole.WriteLine("Querying all mode pages and subpages using SCSI MODE SENSE (6)..."); - sense = dev.ModeSense6(out buffer, out senseBuffer, false, ScsiModeSensePageControl.Default, 0x3F, 0xFF, timeout, out duration); - if(sense || dev.Error) - { - DicConsole.WriteLine("Querying all mode pages using SCSI MODE SENSE (6)..."); - sense = dev.ModeSense6(out buffer, out senseBuffer, false, ScsiModeSensePageControl.Default, 0x3F, 0x00, timeout, out duration); - if(sense || dev.Error) - { - DicConsole.WriteLine("Querying SCSI MODE SENSE (6)..."); - sense = dev.ModeSense(out buffer, out senseBuffer, timeout, out duration); - } - } - else - report.SCSI.SupportsModeSubpages = true; - - if(!sense && !dev.Error && !decMode.HasValue) - decMode = Decoders.SCSI.Modes.DecodeMode6(buffer, devType); - - report.SCSI.SupportsModeSense6 |= (!sense && !dev.Error); - - Decoders.SCSI.Modes.ModePage_2A? cdromMode = null; - - if(decMode.HasValue) - { - report.SCSI.ModeSense = new modeType(); - report.SCSI.ModeSense.BlankCheckEnabled = decMode.Value.Header.EBC; - report.SCSI.ModeSense.DPOandFUA = decMode.Value.Header.DPOFUA; - report.SCSI.ModeSense.WriteProtected = decMode.Value.Header.WriteProtected; - - 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 modePages = new List(); - foreach(Decoders.SCSI.Modes.ModePage page in decMode.Value.Pages) - { - modePageType modePage = new modePageType(); - modePage.page = page.Page; - modePage.subpage = page.Subpage; - modePage.value = page.PageResponse; - modePages.Add(modePage); - - if(modePage.page == 0x2A && modePage.subpage == 0x00) - { - cdromMode = Decoders.SCSI.Modes.DecodeModePage_2A(page.PageResponse); - } - } - - if(modePages.Count > 0) - report.SCSI.ModeSense.ModePages = modePages.ToArray(); - } - } - - List mediaTypes = new List(); - - #region MultiMediaDevice - if(dev.SCSIType == Decoders.SCSI.PeripheralDeviceTypes.MultiMediaDevice) - { - report.SCSI.MultiMediaDevice = new mmcType(); - - if(cdromMode.HasValue) - { - report.SCSI.MultiMediaDevice.ModeSense2A = new mmcModeType(); - if(cdromMode.Value.BufferSize != 0) - { - report.SCSI.MultiMediaDevice.ModeSense2A.BufferSize = cdromMode.Value.BufferSize; - report.SCSI.MultiMediaDevice.ModeSense2A.BufferSizeSpecified = true; - } - if(cdromMode.Value.CurrentSpeed != 0) - { - report.SCSI.MultiMediaDevice.ModeSense2A.CurrentSpeed = cdromMode.Value.CurrentSpeed; - report.SCSI.MultiMediaDevice.ModeSense2A.CurrentSpeedSpecified = true; - } - if(cdromMode.Value.CurrentWriteSpeed != 0) - { - report.SCSI.MultiMediaDevice.ModeSense2A.CurrentWriteSpeed = cdromMode.Value.CurrentWriteSpeed; - report.SCSI.MultiMediaDevice.ModeSense2A.CurrentWriteSpeedSpecified = true; - } - if(cdromMode.Value.CurrentWriteSpeedSelected != 0) - { - report.SCSI.MultiMediaDevice.ModeSense2A.CurrentWriteSpeedSelected = cdromMode.Value.CurrentWriteSpeedSelected; - report.SCSI.MultiMediaDevice.ModeSense2A.CurrentWriteSpeedSelectedSpecified = true; - } - if(cdromMode.Value.MaximumSpeed != 0) - { - report.SCSI.MultiMediaDevice.ModeSense2A.MaximumSpeed = cdromMode.Value.MaximumSpeed; - report.SCSI.MultiMediaDevice.ModeSense2A.MaximumSpeedSpecified = true; - } - if(cdromMode.Value.MaxWriteSpeed != 0) - { - report.SCSI.MultiMediaDevice.ModeSense2A.MaximumWriteSpeed = cdromMode.Value.MaxWriteSpeed; - report.SCSI.MultiMediaDevice.ModeSense2A.MaximumWriteSpeedSpecified = true; - } - if(cdromMode.Value.RotationControlSelected != 0) - { - report.SCSI.MultiMediaDevice.ModeSense2A.RotationControlSelected = cdromMode.Value.RotationControlSelected; - report.SCSI.MultiMediaDevice.ModeSense2A.RotationControlSelectedSpecified = true; - } - if(cdromMode.Value.SupportedVolumeLevels != 0) - { - report.SCSI.MultiMediaDevice.ModeSense2A.SupportedVolumeLevels = cdromMode.Value.SupportedVolumeLevels; - report.SCSI.MultiMediaDevice.ModeSense2A.SupportedVolumeLevelsSpecified = true; - } - - report.SCSI.MultiMediaDevice.ModeSense2A.AccurateCDDA = cdromMode.Value.AccurateCDDA; - report.SCSI.MultiMediaDevice.ModeSense2A.BCK = cdromMode.Value.BCK; - report.SCSI.MultiMediaDevice.ModeSense2A.BufferUnderRunProtection = cdromMode.Value.BUF; - report.SCSI.MultiMediaDevice.ModeSense2A.CanEject = cdromMode.Value.Eject; - report.SCSI.MultiMediaDevice.ModeSense2A.CanLockMedia = cdromMode.Value.Lock; - report.SCSI.MultiMediaDevice.ModeSense2A.CDDACommand = cdromMode.Value.CDDACommand; - report.SCSI.MultiMediaDevice.ModeSense2A.CompositeAudioVideo = cdromMode.Value.Composite; - report.SCSI.MultiMediaDevice.ModeSense2A.CSSandCPPMSupported = cdromMode.Value.CMRSupported == 1; - report.SCSI.MultiMediaDevice.ModeSense2A.DeterministicSlotChanger = cdromMode.Value.SDP; - report.SCSI.MultiMediaDevice.ModeSense2A.DigitalPort1 = cdromMode.Value.DigitalPort1; - report.SCSI.MultiMediaDevice.ModeSense2A.DigitalPort2 = cdromMode.Value.DigitalPort2; - report.SCSI.MultiMediaDevice.ModeSense2A.LeadInPW = cdromMode.Value.LeadInPW; - report.SCSI.MultiMediaDevice.ModeSense2A.LoadingMechanismType = cdromMode.Value.LoadingMechanism; - report.SCSI.MultiMediaDevice.ModeSense2A.LockStatus = cdromMode.Value.LockState; - report.SCSI.MultiMediaDevice.ModeSense2A.LSBF = cdromMode.Value.LSBF; - report.SCSI.MultiMediaDevice.ModeSense2A.PlaysAudio = cdromMode.Value.AudioPlay; - report.SCSI.MultiMediaDevice.ModeSense2A.PreventJumperStatus = cdromMode.Value.PreventJumper; - report.SCSI.MultiMediaDevice.ModeSense2A.RCK = cdromMode.Value.RCK; - report.SCSI.MultiMediaDevice.ModeSense2A.ReadsBarcode = cdromMode.Value.ReadBarcode; - report.SCSI.MultiMediaDevice.ModeSense2A.ReadsBothSides = cdromMode.Value.SCC; - report.SCSI.MultiMediaDevice.ModeSense2A.ReadsCDR = cdromMode.Value.ReadCDR; - report.SCSI.MultiMediaDevice.ModeSense2A.ReadsCDRW = cdromMode.Value.ReadCDRW; - report.SCSI.MultiMediaDevice.ModeSense2A.ReadsDeinterlavedSubchannel = cdromMode.Value.DeinterlaveSubchannel; - report.SCSI.MultiMediaDevice.ModeSense2A.ReadsDVDR = cdromMode.Value.ReadDVDR; - report.SCSI.MultiMediaDevice.ModeSense2A.ReadsDVDRAM = cdromMode.Value.ReadDVDRAM; - report.SCSI.MultiMediaDevice.ModeSense2A.ReadsDVDROM = cdromMode.Value.ReadDVDROM; - report.SCSI.MultiMediaDevice.ModeSense2A.ReadsISRC = cdromMode.Value.ISRC; - report.SCSI.MultiMediaDevice.ModeSense2A.ReadsMode2Form2 = cdromMode.Value.Mode2Form2; - report.SCSI.MultiMediaDevice.ModeSense2A.ReadsMode2Form1 = cdromMode.Value.Mode2Form1; - report.SCSI.MultiMediaDevice.ModeSense2A.ReadsPacketCDR = cdromMode.Value.Method2; - report.SCSI.MultiMediaDevice.ModeSense2A.ReadsSubchannel = cdromMode.Value.Subchannel; - report.SCSI.MultiMediaDevice.ModeSense2A.ReadsUPC = cdromMode.Value.UPC; - report.SCSI.MultiMediaDevice.ModeSense2A.ReturnsC2Pointers = cdromMode.Value.C2Pointer; - report.SCSI.MultiMediaDevice.ModeSense2A.SeparateChannelMute = cdromMode.Value.SeparateChannelMute; - report.SCSI.MultiMediaDevice.ModeSense2A.SeparateChannelVolume = cdromMode.Value.SeparateChannelVolume; - report.SCSI.MultiMediaDevice.ModeSense2A.SSS = cdromMode.Value.SSS; - report.SCSI.MultiMediaDevice.ModeSense2A.SupportsMultiSession = cdromMode.Value.MultiSession; - report.SCSI.MultiMediaDevice.ModeSense2A.TestWrite = cdromMode.Value.TestWrite; - report.SCSI.MultiMediaDevice.ModeSense2A.WritesCDR = cdromMode.Value.WriteCDR; - report.SCSI.MultiMediaDevice.ModeSense2A.WritesCDRW = cdromMode.Value.WriteCDRW; - report.SCSI.MultiMediaDevice.ModeSense2A.WritesDVDR = cdromMode.Value.WriteDVDR; - report.SCSI.MultiMediaDevice.ModeSense2A.WritesDVDRAM = cdromMode.Value.WriteDVDRAM; - report.SCSI.MultiMediaDevice.ModeSense2A.WriteSpeedPerformanceDescriptors = cdromMode.Value.WriteSpeedPerformanceDescriptors; - - mediaTypes.Add("CD-ROM"); - mediaTypes.Add("Audio CD"); - if(cdromMode.Value.ReadCDR) - mediaTypes.Add("CD-R"); - if(cdromMode.Value.ReadCDRW) - mediaTypes.Add("CD-RW"); - if(cdromMode.Value.ReadDVDROM) - mediaTypes.Add("DVD-ROM"); - if(cdromMode.Value.ReadDVDRAM) - mediaTypes.Add("DVD-RAM"); - if(cdromMode.Value.ReadDVDR) - mediaTypes.Add("DVD-R"); - } - - DicConsole.WriteLine("Querying MMC GET CONFIGURATION..."); - sense = dev.GetConfiguration(out buffer, out senseBuffer, timeout, out duration); - - if(!sense) - { - Decoders.SCSI.MMC.Features.SeparatedFeatures ftr = Decoders.SCSI.MMC.Features.Separate(buffer); - if(ftr.Descriptors != null && ftr.Descriptors.Length > 0) - { - report.SCSI.MultiMediaDevice.Features = new mmcFeaturesType(); - foreach(Decoders.SCSI.MMC.Features.FeatureDescriptor desc in ftr.Descriptors) - { - switch(desc.Code) - { - case 0x0001: - { - Decoders.SCSI.MMC.Feature_0001? ftr0001 = Decoders.SCSI.MMC.Features.Decode_0001(desc.Data); - if(ftr0001.HasValue) - { - report.SCSI.MultiMediaDevice.Features.PhysicalInterfaceStandard = ftr0001.Value.PhysicalInterfaceStandard; - report.SCSI.MultiMediaDevice.Features.PhysicalInterfaceStandardSpecified = true; - report.SCSI.MultiMediaDevice.Features.SupportsDeviceBusyEvent = ftr0001.Value.DBE; - } - } - break; - case 0x0003: - { - Decoders.SCSI.MMC.Feature_0003? ftr0003 = Decoders.SCSI.MMC.Features.Decode_0003(desc.Data); - if(ftr0003.HasValue) - { - report.SCSI.MultiMediaDevice.Features.LoadingMechanismType = ftr0003.Value.LoadingMechanismType; - report.SCSI.MultiMediaDevice.Features.LoadingMechanismTypeSpecified = true; - report.SCSI.MultiMediaDevice.Features.CanLoad = ftr0003.Value.Load; - report.SCSI.MultiMediaDevice.Features.CanEject = ftr0003.Value.Eject; - report.SCSI.MultiMediaDevice.Features.PreventJumper = ftr0003.Value.PreventJumper; - report.SCSI.MultiMediaDevice.Features.DBML = ftr0003.Value.DBML; - report.SCSI.MultiMediaDevice.Features.Locked = ftr0003.Value.Lock; - } - } - break; - case 0x0004: - { - Decoders.SCSI.MMC.Feature_0004? ftr0004 = Decoders.SCSI.MMC.Features.Decode_0004(desc.Data); - if(ftr0004.HasValue) - { - report.SCSI.MultiMediaDevice.Features.SupportsWriteProtectPAC = ftr0004.Value.DWP; - report.SCSI.MultiMediaDevice.Features.SupportsWriteInhibitDCB = ftr0004.Value.WDCB; - report.SCSI.MultiMediaDevice.Features.SupportsPWP = ftr0004.Value.SPWP; - report.SCSI.MultiMediaDevice.Features.SupportsSWPP = ftr0004.Value.SSWPP; - } - } - break; - case 0x0010: - { - Decoders.SCSI.MMC.Feature_0010? ftr0010 = Decoders.SCSI.MMC.Features.Decode_0010(desc.Data); - if(ftr0010.HasValue) - { - if(ftr0010.Value.LogicalBlockSize > 0) - { - report.SCSI.MultiMediaDevice.Features.LogicalBlockSize = ftr0010.Value.LogicalBlockSize; - report.SCSI.MultiMediaDevice.Features.LogicalBlockSizeSpecified = true; - } - if(ftr0010.Value.Blocking > 0) - { - report.SCSI.MultiMediaDevice.Features.BlocksPerReadableUnit = ftr0010.Value.Blocking; - report.SCSI.MultiMediaDevice.Features.BlocksPerReadableUnitSpecified = true; - } - report.SCSI.MultiMediaDevice.Features.ErrorRecoveryPage = ftr0010.Value.PP; - } - } - break; - case 0x001D: - report.SCSI.MultiMediaDevice.Features.MultiRead = true; - break; - case 0x001E: - { - report.SCSI.MultiMediaDevice.Features.CanReadCD = true; - Decoders.SCSI.MMC.Feature_001E? ftr001E = Decoders.SCSI.MMC.Features.Decode_001E(desc.Data); - if(ftr001E.HasValue) - { - report.SCSI.MultiMediaDevice.Features.SupportsDAP = ftr001E.Value.DAP; - report.SCSI.MultiMediaDevice.Features.SupportsC2 = ftr001E.Value.C2; - report.SCSI.MultiMediaDevice.Features.CanReadLeadInCDText = ftr001E.Value.CDText; - } - } - break; - case 0x001F: - { - report.SCSI.MultiMediaDevice.Features.CanReadDVD = true; - Decoders.SCSI.MMC.Feature_001F? ftr001F = Decoders.SCSI.MMC.Features.Decode_001F(desc.Data); - if(ftr001F.HasValue) - { - report.SCSI.MultiMediaDevice.Features.DVDMultiRead = ftr001F.Value.MULTI110; - report.SCSI.MultiMediaDevice.Features.CanReadAllDualRW = ftr001F.Value.DualRW; - report.SCSI.MultiMediaDevice.Features.CanReadAllDualR = ftr001F.Value.DualRW; - } - } - break; - case 0x0022: - report.SCSI.MultiMediaDevice.Features.CanEraseSector = true; - break; - case 0x0023: - { - report.SCSI.MultiMediaDevice.Features.CanFormat = true; - Decoders.SCSI.MMC.Feature_0023? ftr0023 = Decoders.SCSI.MMC.Features.Decode_0023(desc.Data); - if(ftr0023.HasValue) - { - report.SCSI.MultiMediaDevice.Features.CanFormatBDREWithoutSpare = ftr0023.Value.RENoSA; - report.SCSI.MultiMediaDevice.Features.CanExpandBDRESpareArea = ftr0023.Value.Expand; - report.SCSI.MultiMediaDevice.Features.CanFormatQCert = ftr0023.Value.QCert; - report.SCSI.MultiMediaDevice.Features.CanFormatCert = ftr0023.Value.Cert; - report.SCSI.MultiMediaDevice.Features.CanFormatFRF = ftr0023.Value.FRF; - report.SCSI.MultiMediaDevice.Features.CanFormatRRM = ftr0023.Value.RRM; - } - } - break; - case 0x0024: - report.SCSI.MultiMediaDevice.Features.CanReadSpareAreaInformation = true; - break; - case 0x0027: - report.SCSI.MultiMediaDevice.Features.CanWriteCDRWCAV = true; - break; - case 0x0028: - { - report.SCSI.MultiMediaDevice.Features.CanReadCDMRW = true; - Decoders.SCSI.MMC.Feature_0028? ftr0028 = Decoders.SCSI.MMC.Features.Decode_0028(desc.Data); - if(ftr0028.HasValue) - { - report.SCSI.MultiMediaDevice.Features.CanReadDVDPlusMRW = ftr0028.Value.DVDPRead; - report.SCSI.MultiMediaDevice.Features.CanWriteDVDPlusMRW = ftr0028.Value.DVDPWrite; - report.SCSI.MultiMediaDevice.Features.CanWriteCDMRW = ftr0028.Value.Write; - } - } - break; - case 0x002A: - { - report.SCSI.MultiMediaDevice.Features.CanReadDVDPlusRW = true; - Decoders.SCSI.MMC.Feature_002A? ftr002A = Decoders.SCSI.MMC.Features.Decode_002A(desc.Data); - if(ftr002A.HasValue) - { - report.SCSI.MultiMediaDevice.Features.CanWriteDVDPlusRW = ftr002A.Value.Write; - } - } - break; - case 0x002B: - { - report.SCSI.MultiMediaDevice.Features.CanReadDVDPlusR = true; - Decoders.SCSI.MMC.Feature_002B? ftr002B = Decoders.SCSI.MMC.Features.Decode_002B(desc.Data); - if(ftr002B.HasValue) - { - report.SCSI.MultiMediaDevice.Features.CanWriteDVDPlusR = ftr002B.Value.Write; - } - } - break; - case 0x002D: - { - report.SCSI.MultiMediaDevice.Features.CanWriteCDTAO = true; - Decoders.SCSI.MMC.Feature_002D? ftr002D = Decoders.SCSI.MMC.Features.Decode_002D(desc.Data); - if(ftr002D.HasValue) - { - report.SCSI.MultiMediaDevice.Features.BufferUnderrunFreeInTAO = ftr002D.Value.BUF; - report.SCSI.MultiMediaDevice.Features.CanWriteRawSubchannelInTAO = ftr002D.Value.RWRaw; - report.SCSI.MultiMediaDevice.Features.CanWritePackedSubchannelInTAO = ftr002D.Value.RWPack; - report.SCSI.MultiMediaDevice.Features.CanTestWriteInTAO = ftr002D.Value.TestWrite; - report.SCSI.MultiMediaDevice.Features.CanOverwriteTAOTrack = ftr002D.Value.CDRW; - report.SCSI.MultiMediaDevice.Features.CanWriteRWSubchannelInTAO = ftr002D.Value.RWSubchannel; - } - } - break; - case 0x002E: - { - report.SCSI.MultiMediaDevice.Features.CanWriteCDSAO = true; - Decoders.SCSI.MMC.Feature_002E? ftr002E = Decoders.SCSI.MMC.Features.Decode_002E(desc.Data); - if(ftr002E.HasValue) - { - report.SCSI.MultiMediaDevice.Features.BufferUnderrunFreeInSAO = ftr002E.Value.BUF; - report.SCSI.MultiMediaDevice.Features.CanWriteRawMultiSession = ftr002E.Value.RAWMS; - report.SCSI.MultiMediaDevice.Features.CanWriteRaw = ftr002E.Value.RAW; - report.SCSI.MultiMediaDevice.Features.CanTestWriteInSAO = ftr002E.Value.TestWrite; - report.SCSI.MultiMediaDevice.Features.CanOverwriteSAOTrack = ftr002E.Value.CDRW; - report.SCSI.MultiMediaDevice.Features.CanWriteRWSubchannelInSAO = ftr002E.Value.RW; - } - } - break; - case 0x002F: - { - report.SCSI.MultiMediaDevice.Features.CanWriteDVDR = true; - Decoders.SCSI.MMC.Feature_002F? ftr002F = Decoders.SCSI.MMC.Features.Decode_002F(desc.Data); - if(ftr002F.HasValue) - { - report.SCSI.MultiMediaDevice.Features.BufferUnderrunFreeInDVD = ftr002F.Value.BUF; - report.SCSI.MultiMediaDevice.Features.CanWriteDVDRDL = ftr002F.Value.RDL; - report.SCSI.MultiMediaDevice.Features.CanTestWriteDVD = ftr002F.Value.TestWrite; - report.SCSI.MultiMediaDevice.Features.CanWriteDVDRW = ftr002F.Value.DVDRW; - } - } - break; - case 0x0030: - report.SCSI.MultiMediaDevice.Features.CanReadDDCD = true; - break; - case 0x0031: - { - report.SCSI.MultiMediaDevice.Features.CanWriteDDCDR = true; - Decoders.SCSI.MMC.Feature_0031? ftr0031 = Decoders.SCSI.MMC.Features.Decode_0031(desc.Data); - if(ftr0031.HasValue) - report.SCSI.MultiMediaDevice.Features.CanTestWriteDDCDR = ftr0031.Value.TestWrite; - } - break; - case 0x0032: - report.SCSI.MultiMediaDevice.Features.CanWriteDDCDRW = true; - break; - case 0x0037: - report.SCSI.MultiMediaDevice.Features.CanWriteCDRW = true; - break; - case 0x0038: - report.SCSI.MultiMediaDevice.Features.CanPseudoOverwriteBDR = true; - break; - case 0x003A: - { - report.SCSI.MultiMediaDevice.Features.CanReadDVDPlusRWDL = true; - Decoders.SCSI.MMC.Feature_003A? ftr003A = Decoders.SCSI.MMC.Features.Decode_003A(desc.Data); - if(ftr003A.HasValue) - report.SCSI.MultiMediaDevice.Features.CanWriteDVDPlusRWDL = ftr003A.Value.Write; - } - break; - case 0x003B: - { - report.SCSI.MultiMediaDevice.Features.CanReadDVDPlusRDL = true; - Decoders.SCSI.MMC.Feature_003B? ftr003B = Decoders.SCSI.MMC.Features.Decode_003B(desc.Data); - if(ftr003B.HasValue) - report.SCSI.MultiMediaDevice.Features.CanWriteDVDPlusRDL = ftr003B.Value.Write; - } - break; - case 0x0040: - { - report.SCSI.MultiMediaDevice.Features.CanReadBD = true; - Decoders.SCSI.MMC.Feature_0040? ftr0040 = Decoders.SCSI.MMC.Features.Decode_0040(desc.Data); - if(ftr0040.HasValue) - { - report.SCSI.MultiMediaDevice.Features.CanReadBluBCA = ftr0040.Value.BCA; - report.SCSI.MultiMediaDevice.Features.CanReadBDRE2 = ftr0040.Value.RE2; - report.SCSI.MultiMediaDevice.Features.CanReadBDRE1 = ftr0040.Value.RE1; - report.SCSI.MultiMediaDevice.Features.CanReadOldBDRE = ftr0040.Value.OldRE; - report.SCSI.MultiMediaDevice.Features.CanReadBDR = ftr0040.Value.R; - report.SCSI.MultiMediaDevice.Features.CanReadOldBDR = ftr0040.Value.OldR; - report.SCSI.MultiMediaDevice.Features.CanReadBDROM = ftr0040.Value.ROM; - report.SCSI.MultiMediaDevice.Features.CanReadOldBDROM = ftr0040.Value.OldROM; - } - } - break; - case 0x0041: - { - report.SCSI.MultiMediaDevice.Features.CanWriteBD = true; - Decoders.SCSI.MMC.Feature_0041? ftr0041 = Decoders.SCSI.MMC.Features.Decode_0041(desc.Data); - if(ftr0041.HasValue) - { - report.SCSI.MultiMediaDevice.Features.CanWriteBDRE2 = ftr0041.Value.RE2; - report.SCSI.MultiMediaDevice.Features.CanWriteBDRE1 = ftr0041.Value.RE1; - report.SCSI.MultiMediaDevice.Features.CanReadOldBDRE = ftr0041.Value.OldRE; - report.SCSI.MultiMediaDevice.Features.CanReadBDR = ftr0041.Value.R; - report.SCSI.MultiMediaDevice.Features.CanReadOldBDR = ftr0041.Value.OldR; - } - } - break; - case 0x0050: - { - report.SCSI.MultiMediaDevice.Features.CanReadHDDVD = true; - Decoders.SCSI.MMC.Feature_0050? ftr0050 = Decoders.SCSI.MMC.Features.Decode_0050(desc.Data); - if(ftr0050.HasValue) - { - report.SCSI.MultiMediaDevice.Features.CanReadHDDVDR = ftr0050.Value.HDDVDR; - report.SCSI.MultiMediaDevice.Features.CanReadHDDVDRAM = ftr0050.Value.HDDVDRAM; - } - } - break; - case 0x0051: - { - Decoders.SCSI.MMC.Feature_0051? ftr0051 = Decoders.SCSI.MMC.Features.Decode_0051(desc.Data); - if(ftr0051.HasValue) - { - report.SCSI.MultiMediaDevice.Features.CanWriteHDDVDR = ftr0051.Value.HDDVDR; - report.SCSI.MultiMediaDevice.Features.CanWriteHDDVDRAM = ftr0051.Value.HDDVDRAM; - } - } - break; - case 0x0080: - report.SCSI.MultiMediaDevice.Features.SupportsHybridDiscs = true; - break; - case 0x0101: - report.SCSI.MultiMediaDevice.Features.SupportsModePage1Ch = true; - break; - case 0x0102: - { - report.SCSI.MultiMediaDevice.Features.EmbeddedChanger = true; - Decoders.SCSI.MMC.Feature_0102? ftr0102 = Decoders.SCSI.MMC.Features.Decode_0102(desc.Data); - if(ftr0102.HasValue) - { - report.SCSI.MultiMediaDevice.Features.ChangerIsSideChangeCapable = ftr0102.Value.SCC; - report.SCSI.MultiMediaDevice.Features.ChangerSupportsDiscPresent = ftr0102.Value.SDP; - report.SCSI.MultiMediaDevice.Features.ChangerSlots = (byte)(ftr0102.Value.HighestSlotNumber + 1); - } - } - break; - case 0x0103: - { - report.SCSI.MultiMediaDevice.Features.CanPlayCDAudio = true; - Decoders.SCSI.MMC.Feature_0103? ftr0103 = Decoders.SCSI.MMC.Features.Decode_0103(desc.Data); - if(ftr0103.HasValue) - { - report.SCSI.MultiMediaDevice.Features.CanAudioScan = ftr0103.Value.Scan; - report.SCSI.MultiMediaDevice.Features.CanMuteSeparateChannels = ftr0103.Value.SCM; - report.SCSI.MultiMediaDevice.Features.SupportsSeparateVolume = ftr0103.Value.SV; - if(ftr0103.Value.VolumeLevels > 0) - { - report.SCSI.MultiMediaDevice.Features.VolumeLevelsSpecified = true; - report.SCSI.MultiMediaDevice.Features.VolumeLevels = ftr0103.Value.VolumeLevels; - } - } - } - break; - case 0x0104: - report.SCSI.MultiMediaDevice.Features.CanUpgradeFirmware = true; - break; - case 0x0106: - { - report.SCSI.MultiMediaDevice.Features.SupportsCSS = true; - Decoders.SCSI.MMC.Feature_0106? ftr0106 = Decoders.SCSI.MMC.Features.Decode_0106(desc.Data); - if(ftr0106.HasValue) - { - if(ftr0106.Value.CSSVersion > 0) - { - report.SCSI.MultiMediaDevice.Features.CSSVersionSpecified = true; - report.SCSI.MultiMediaDevice.Features.CSSVersion = ftr0106.Value.CSSVersion; - } - } - } - break; - case 0x0108: - report.SCSI.MultiMediaDevice.Features.CanReportDriveSerial = true; - break; - case 0x0109: - report.SCSI.MultiMediaDevice.Features.CanReportMediaSerial = true; - break; - case 0x010B: - { - report.SCSI.MultiMediaDevice.Features.SupportsCPRM = true; - Decoders.SCSI.MMC.Feature_010B? ftr010B = Decoders.SCSI.MMC.Features.Decode_010B(desc.Data); - if(ftr010B.HasValue) - { - if(ftr010B.Value.CPRMVersion > 0) - { - report.SCSI.MultiMediaDevice.Features.CPRMVersionSpecified = true; - report.SCSI.MultiMediaDevice.Features.CPRMVersion = ftr010B.Value.CPRMVersion; - } - } - } - break; - case 0x010C: - { - Decoders.SCSI.MMC.Feature_010C? ftr010C = Decoders.SCSI.MMC.Features.Decode_010C(desc.Data); - if(ftr010C.HasValue) - { - string syear, smonth, sday, shour, sminute, ssecond; - byte[] temp; - - temp = new byte[4]; - temp[0] = (byte)((ftr010C.Value.Century & 0xFF00) >> 8); - temp[1] = (byte)(ftr010C.Value.Century & 0xFF); - temp[2] = (byte)((ftr010C.Value.Year & 0xFF00) >> 8); - temp[3] = (byte)(ftr010C.Value.Year & 0xFF); - syear = System.Text.Encoding.ASCII.GetString(temp); - temp = new byte[2]; - temp[0] = (byte)((ftr010C.Value.Month & 0xFF00) >> 8); - temp[1] = (byte)(ftr010C.Value.Month & 0xFF); - smonth = System.Text.Encoding.ASCII.GetString(temp); - temp = new byte[2]; - temp[0] = (byte)((ftr010C.Value.Day & 0xFF00) >> 8); - temp[1] = (byte)(ftr010C.Value.Day & 0xFF); - sday = System.Text.Encoding.ASCII.GetString(temp); - temp = new byte[2]; - temp[0] = (byte)((ftr010C.Value.Hour & 0xFF00) >> 8); - temp[1] = (byte)(ftr010C.Value.Hour & 0xFF); - shour = System.Text.Encoding.ASCII.GetString(temp); - temp = new byte[2]; - temp[0] = (byte)((ftr010C.Value.Minute & 0xFF00) >> 8); - temp[1] = (byte)(ftr010C.Value.Minute & 0xFF); - sminute = System.Text.Encoding.ASCII.GetString(temp); - temp = new byte[2]; - temp[0] = (byte)((ftr010C.Value.Second & 0xFF00) >> 8); - temp[1] = (byte)(ftr010C.Value.Second & 0xFF); - ssecond = System.Text.Encoding.ASCII.GetString(temp); - - try - { - report.SCSI.MultiMediaDevice.Features.FirmwareDate = new DateTime(int.Parse(syear), int.Parse(smonth), - int.Parse(sday), int.Parse(shour), int.Parse(sminute), - int.Parse(ssecond), DateTimeKind.Utc); - - report.SCSI.MultiMediaDevice.Features.FirmwareDateSpecified = true; - } -#pragma warning disable RECS0022 // A catch clause that catches System.Exception and has an empty body - catch -#pragma warning restore RECS0022 // A catch clause that catches System.Exception and has an empty body - { - } - } - } - break; - case 0x010D: - { - report.SCSI.MultiMediaDevice.Features.SupportsAACS = true; - Decoders.SCSI.MMC.Feature_010D? ftr010D = Decoders.SCSI.MMC.Features.Decode_010D(desc.Data); - if(ftr010D.HasValue) - { - report.SCSI.MultiMediaDevice.Features.CanReadDriveAACSCertificate = ftr010D.Value.RDC; - report.SCSI.MultiMediaDevice.Features.CanReadCPRM_MKB = ftr010D.Value.RMC; - report.SCSI.MultiMediaDevice.Features.CanWriteBusEncryptedBlocks = ftr010D.Value.WBE; - report.SCSI.MultiMediaDevice.Features.SupportsBusEncryption = ftr010D.Value.BEC; - report.SCSI.MultiMediaDevice.Features.CanGenerateBindingNonce = ftr010D.Value.BNG; - - if(ftr010D.Value.BindNonceBlocks > 0) - { - report.SCSI.MultiMediaDevice.Features.BindingNonceBlocksSpecified = true; - report.SCSI.MultiMediaDevice.Features.BindingNonceBlocks = ftr010D.Value.BindNonceBlocks; - } - - if(ftr010D.Value.AGIDs > 0) - { - report.SCSI.MultiMediaDevice.Features.AGIDsSpecified = true; - report.SCSI.MultiMediaDevice.Features.AGIDs = ftr010D.Value.AGIDs; - } - - if(ftr010D.Value.AACSVersion > 0) - { - report.SCSI.MultiMediaDevice.Features.AACSVersionSpecified = true; - report.SCSI.MultiMediaDevice.Features.AACSVersion = ftr010D.Value.AACSVersion; - } - } - } - break; - case 0x010E: - report.SCSI.MultiMediaDevice.Features.CanWriteCSSManagedDVD = true; - break; - case 0x0113: - report.SCSI.MultiMediaDevice.Features.SupportsSecurDisc = true; - break; - case 0x0142: - report.SCSI.MultiMediaDevice.Features.SupportsOSSC = true; - break; - case 0x0110: - report.SCSI.MultiMediaDevice.Features.SupportsVCPS = true; - break; - } - } - } - - if(report.SCSI.MultiMediaDevice.Features.CanReadBD || - report.SCSI.MultiMediaDevice.Features.CanReadBDR || - report.SCSI.MultiMediaDevice.Features.CanReadBDRE1 || - report.SCSI.MultiMediaDevice.Features.CanReadBDRE2 || - report.SCSI.MultiMediaDevice.Features.CanReadBDROM || - report.SCSI.MultiMediaDevice.Features.CanReadOldBDR || - report.SCSI.MultiMediaDevice.Features.CanReadOldBDRE || - report.SCSI.MultiMediaDevice.Features.CanReadOldBDROM) - { - if(!mediaTypes.Contains("BD-ROM")) - mediaTypes.Add("BD-ROM"); - if(!mediaTypes.Contains("BD-R")) - mediaTypes.Add("BD-R"); - if(!mediaTypes.Contains("BD-RE")) - mediaTypes.Add("BD-RE"); - if(!mediaTypes.Contains("BD-R LTH")) - mediaTypes.Add("BD-R LTH"); - if(!mediaTypes.Contains("BD-R XL")) - mediaTypes.Add("BD-R XL"); - } - - if(report.SCSI.MultiMediaDevice.Features.CanReadCD || - report.SCSI.MultiMediaDevice.Features.MultiRead) - { - if(!mediaTypes.Contains("CD-ROM")) - mediaTypes.Add("CD-ROM"); - if(!mediaTypes.Contains("Audio CD")) - mediaTypes.Add("Audio CD"); - if(!mediaTypes.Contains("CD-R")) - mediaTypes.Add("CD-R"); - if(!mediaTypes.Contains("CD-RW")) - mediaTypes.Add("CD-RW"); - } - - if(report.SCSI.MultiMediaDevice.Features.CanReadCDMRW) - { - if(!mediaTypes.Contains("CD-MRW")) - mediaTypes.Add("CD-MRW"); - } - - if(report.SCSI.MultiMediaDevice.Features.CanReadDDCD) - { - if(!mediaTypes.Contains("DDCD-ROM")) - mediaTypes.Add("DDCD-ROM"); - if(!mediaTypes.Contains("DDCD-R")) - mediaTypes.Add("DDCD-R"); - if(!mediaTypes.Contains("DDCD-RW")) - mediaTypes.Add("DDCD-RW"); - } - - if(report.SCSI.MultiMediaDevice.Features.CanReadDVD || - report.SCSI.MultiMediaDevice.Features.DVDMultiRead || - report.SCSI.MultiMediaDevice.Features.CanReadDVDPlusR || - report.SCSI.MultiMediaDevice.Features.CanReadDVDPlusRDL || - report.SCSI.MultiMediaDevice.Features.CanReadDVDPlusRW || - report.SCSI.MultiMediaDevice.Features.CanReadDVDPlusRWDL) - { - if(!mediaTypes.Contains("DVD-ROM")) - mediaTypes.Add("DVD-ROM"); - if(!mediaTypes.Contains("DVD-R")) - mediaTypes.Add("DVD-R"); - if(!mediaTypes.Contains("DVD-RW")) - mediaTypes.Add("DVD-RW"); - if(!mediaTypes.Contains("DVD+R")) - mediaTypes.Add("DVD+R"); - if(!mediaTypes.Contains("DVD+RW")) - mediaTypes.Add("DVD+RW"); - if(!mediaTypes.Contains("DVD-R DL")) - mediaTypes.Add("DVD-R DL"); - if(!mediaTypes.Contains("DVD+R DL")) - mediaTypes.Add("DVD+R DL"); - } - - if(report.SCSI.MultiMediaDevice.Features.CanReadDVDPlusMRW) - { - if(!mediaTypes.Contains("DVD+MRW")) - mediaTypes.Add("DVD+MRW"); - } - - - if(report.SCSI.MultiMediaDevice.Features.CanReadHDDVD || - report.SCSI.MultiMediaDevice.Features.CanReadHDDVDR) - { - if(!mediaTypes.Contains("HD DVD-ROM")) - mediaTypes.Add("HD DVD-ROM"); - if(!mediaTypes.Contains("HD DVD-R")) - mediaTypes.Add("HD DVD-R"); - if(!mediaTypes.Contains("HD DVD-RW")) - mediaTypes.Add("HD DVD-RW"); - } - - if(report.SCSI.MultiMediaDevice.Features.CanReadHDDVDRAM) - { - if(!mediaTypes.Contains("HD DVD-RAM")) - mediaTypes.Add("HD DVD-RAM"); - } - } - - bool tryPlextor = false, tryHLDTST = false, tryPioneer = false, tryNEC = false; - - tryPlextor |= dev.Manufacturer.ToLowerInvariant() == "plextor"; - tryHLDTST |= dev.Manufacturer.ToLowerInvariant() == "hl-dt-st"; - tryPioneer |= dev.Manufacturer.ToLowerInvariant() == "pioneer"; - tryNEC |= dev.Manufacturer.ToLowerInvariant() == "nec"; - - // Very old CD drives do not contain mode page 2Ah neither GET CONFIGURATION, so just try all CDs on them - // Also don't get confident, some drives didn't know CD-RW but are able to read them - if(mediaTypes.Count == 0 || mediaTypes.Contains("CD-ROM")) - { - if(!mediaTypes.Contains("CD-ROM")) - mediaTypes.Add("CD-ROM"); - if(!mediaTypes.Contains("Audio CD")) - mediaTypes.Add("Audio CD"); - if(!mediaTypes.Contains("CD-R")) - mediaTypes.Add("CD-R"); - if(!mediaTypes.Contains("CD-RW")) - mediaTypes.Add("CD-RW"); - } - - mediaTypes.Sort(); - List mediaTests = new List(); - foreach(string mediaType in mediaTypes) - { - pressedKey = new ConsoleKeyInfo(); - while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N) - { - DicConsole.Write("Do you have a {0} disc that you can insert in the drive? (Y/N): ", mediaType); - pressedKey = System.Console.ReadKey(); - DicConsole.WriteLine(); - } - - if(pressedKey.Key == ConsoleKey.Y) - { - dev.AllowMediumRemoval(out senseBuffer, timeout, out duration); - dev.EjectTray(out senseBuffer, timeout, out duration); - DicConsole.WriteLine("Please insert it in the drive and press any key when it is ready."); - System.Console.ReadKey(true); - - testedMediaType mediaTest = new testedMediaType(); - mediaTest.MediumTypeName = mediaType; - mediaTest.MediaIsRecognized = true; - - sense = dev.ScsiTestUnitReady(out senseBuffer, timeout, out duration); - if(sense) - { - Decoders.SCSI.FixedSense? decSense = Decoders.SCSI.Sense.DecodeFixed(senseBuffer); - if(decSense.HasValue) - { - if(decSense.Value.ASC == 0x3A) - { - int leftRetries = 20; - while(leftRetries > 0) - { - DicConsole.Write("\rWaiting for drive to become ready"); - System.Threading.Thread.Sleep(2000); - sense = dev.ScsiTestUnitReady(out senseBuffer, timeout, out duration); - if(!sense) - break; - - leftRetries--; - } - - mediaTest.MediaIsRecognized &= !sense; - } - else if(decSense.Value.ASC == 0x04 && decSense.Value.ASCQ == 0x01) - { - int leftRetries = 20; - while(leftRetries > 0) - { - DicConsole.Write("\rWaiting for drive to become ready"); - System.Threading.Thread.Sleep(2000); - sense = dev.ScsiTestUnitReady(out senseBuffer, timeout, out duration); - if(!sense) - break; - - leftRetries--; - } - - mediaTest.MediaIsRecognized &= !sense; - } - else - mediaTest.MediaIsRecognized = false; - } - else - mediaTest.MediaIsRecognized = false; - } - - if(mediaTest.MediaIsRecognized) - { - mediaTest.SupportsReadCapacitySpecified = true; - mediaTest.SupportsReadCapacity16Specified = true; - - DicConsole.WriteLine("Querying SCSI READ CAPACITY..."); - sense = dev.ReadCapacity(out buffer, out senseBuffer, timeout, out duration); - 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[5] << 24) + (buffer[5] << 16) + (buffer[6] << 8) + (buffer[7])); - mediaTest.BlocksSpecified = true; - mediaTest.BlockSizeSpecified = true; - } - - DicConsole.WriteLine("Querying SCSI READ CAPACITY (16)..."); - sense = dev.ReadCapacity16(out buffer, out buffer, timeout, out duration); - 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[5] << 24) + (buffer[5] << 16) + (buffer[6] << 8) + (buffer[7])); - mediaTest.BlocksSpecified = true; - mediaTest.BlockSizeSpecified = true; - } - - decMode = null; - - DicConsole.WriteLine("Querying SCSI MODE SENSE (10)..."); - sense = dev.ModeSense10(out buffer, out senseBuffer, false, true, ScsiModeSensePageControl.Current, 0x3F, 0x00, timeout, out duration); - if(!sense && !dev.Error) - { - report.SCSI.SupportsModeSense10 = true; - decMode = Decoders.SCSI.Modes.DecodeMode10(buffer, dev.SCSIType); - } - DicConsole.WriteLine("Querying SCSI MODE SENSE..."); - sense = dev.ModeSense(out buffer, out senseBuffer, timeout, out duration); - if(!sense && !dev.Error) - { - report.SCSI.SupportsModeSense6 = true; - if(!decMode.HasValue) - decMode = Decoders.SCSI.Modes.DecodeMode6(buffer, dev.SCSIType); - } - - 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) - { - mediaTest.Density = (byte)decMode.Value.Header.BlockDescriptors[0].Density; - mediaTest.DensitySpecified = true; - } - } - - if(mediaType.StartsWith("CD-", StringComparison.Ordinal) || mediaType == "Audio CD") - { - mediaTest.CanReadTOCSpecified = true; - mediaTest.CanReadFullTOCSpecified = true; - DicConsole.WriteLine("Querying CD TOC..."); - mediaTest.CanReadTOC = !dev.ReadTocPmaAtip(out buffer, out senseBuffer, false, 0, 0, timeout, out duration); - DicConsole.WriteLine("Querying CD Full TOC..."); - mediaTest.CanReadFullTOC = !dev.ReadRawToc(out buffer, out senseBuffer, 1, timeout, out duration); - } - - if(mediaType.StartsWith("CD-R", StringComparison.Ordinal)) - { - mediaTest.CanReadATIPSpecified = true; - mediaTest.CanReadPMASpecified = true; - DicConsole.WriteLine("Querying CD ATIP..."); - mediaTest.CanReadATIP = !dev.ReadAtip(out buffer, out senseBuffer, timeout, out duration); - DicConsole.WriteLine("Querying CD PMA..."); - mediaTest.CanReadPMA = !dev.ReadPma(out buffer, out senseBuffer, timeout, out duration); - } - - if(mediaType.StartsWith("DVD-", StringComparison.Ordinal) || mediaType.StartsWith("HD DVD-", StringComparison.Ordinal)) - { - mediaTest.CanReadPFISpecified = true; - mediaTest.CanReadDMISpecified = true; - DicConsole.WriteLine("Querying DVD PFI..."); - mediaTest.CanReadPFI = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.PhysicalInformation, 0, timeout, out duration); - DicConsole.WriteLine("Querying DVD DMI..."); - mediaTest.CanReadDMI = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.DiscManufacturingInformation, 0, timeout, out duration); - } - - if(mediaType == "DVD-ROM") - { - mediaTest.CanReadCMISpecified = true; - DicConsole.WriteLine("Querying DVD CMI..."); - mediaTest.CanReadCMI = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.CopyrightInformation, 0, timeout, out duration); - } - - if(mediaType == "DVD-ROM" || mediaType == "HD DVD-ROM") - { - mediaTest.CanReadBCASpecified = true; - DicConsole.WriteLine("Querying DVD BCA..."); - mediaTest.CanReadBCA = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.BurstCuttingArea, 0, timeout, out duration); - mediaTest.CanReadAACSSpecified = true; - DicConsole.WriteLine("Querying DVD AACS..."); - mediaTest.CanReadAACS = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.DVD_AACS, 0, timeout, out duration); - } - - if(mediaType == "BD-ROM") - { - mediaTest.CanReadBCASpecified = true; - DicConsole.WriteLine("Querying BD BCA..."); - mediaTest.CanReadBCA = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.BD, 0, 0, MmcDiscStructureFormat.BD_BurstCuttingArea, 0, timeout, out duration); - } - - if(mediaType == "DVD-RAM" || mediaType == "HD DVD-RAM") - { - mediaTest.CanReadDDSSpecified = true; - mediaTest.CanReadSpareAreaInformationSpecified = true; - mediaTest.CanReadDDS = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.DVDRAM_DDS, 0, timeout, out duration); - mediaTest.CanReadSpareAreaInformation = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.DVDRAM_SpareAreaInformation, 0, timeout, out duration); - } - - if(mediaType.StartsWith("BD-R", StringComparison.Ordinal) && mediaType != "BD-ROM") - { - mediaTest.CanReadDDSSpecified = true; - mediaTest.CanReadSpareAreaInformationSpecified = true; - DicConsole.WriteLine("Querying BD DDS..."); - mediaTest.CanReadDDS = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.BD, 0, 0, MmcDiscStructureFormat.BD_DDS, 0, timeout, out duration); - DicConsole.WriteLine("Querying BD SAI..."); - mediaTest.CanReadSpareAreaInformation = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.BD, 0, 0, MmcDiscStructureFormat.BD_SpareAreaInformation, 0, timeout, out duration); - } - - if(mediaType == "DVD-R" || mediaType == "DVD-RW") - { - mediaTest.CanReadPRISpecified = true; - DicConsole.WriteLine("Querying DVD PRI..."); - mediaTest.CanReadPRI = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.PreRecordedInfo, 0, timeout, out duration); - } - - if(mediaType == "DVD-R" || mediaType == "DVD-RW" || mediaType == "HD DVD-R") - { - mediaTest.CanReadMediaIDSpecified = true; - mediaTest.CanReadRecordablePFISpecified = true; - DicConsole.WriteLine("Querying DVD Media ID..."); - mediaTest.CanReadMediaID = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.DVDR_MediaIdentifier, 0, timeout, out duration); - DicConsole.WriteLine("Querying DVD Embossed PFI..."); - mediaTest.CanReadRecordablePFI = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.DVDR_PhysicalInformation, 0, timeout, out duration); - } - - if(mediaType.StartsWith("DVD+R", StringComparison.Ordinal)) - { - mediaTest.CanReadADIPSpecified = true; - mediaTest.CanReadDCBSpecified = true; - DicConsole.WriteLine("Querying DVD ADIP..."); - mediaTest.CanReadADIP = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.ADIP, 0, timeout, out duration); - DicConsole.WriteLine("Querying DVD DCB..."); - mediaTest.CanReadDCB = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.DCB, 0, timeout, out duration); - } - - if(mediaType == "HD DVD-ROM") - { - mediaTest.CanReadHDCMISpecified = true; - DicConsole.WriteLine("Querying HD DVD CMI..."); - mediaTest.CanReadHDCMI = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.HDDVD_CopyrightInformation, 0, timeout, out duration); - } - - if(mediaType.EndsWith(" DL", StringComparison.Ordinal)) - { - mediaTest.CanReadLayerCapacitySpecified = true; - DicConsole.WriteLine("Querying DVD Layer Capacity..."); - mediaTest.CanReadLayerCapacity = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.DVDR_LayerCapacity, 0, timeout, out duration); - } - - if(mediaType.StartsWith("BD-R", StringComparison.Ordinal)) - { - mediaTest.CanReadDiscInformationSpecified = true; - mediaTest.CanReadPACSpecified = true; - DicConsole.WriteLine("Querying BD Disc Information..."); - mediaTest.CanReadDiscInformation = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.BD, 0, 0, MmcDiscStructureFormat.DiscInformation, 0, timeout, out duration); - DicConsole.WriteLine("Querying BD PAC..."); - mediaTest.CanReadPAC = !dev.ReadDiscStructure(out buffer, out senseBuffer, MmcDiscStructureMediaType.BD, 0, 0, MmcDiscStructureFormat.PAC, 0, timeout, out duration); - } - - mediaTest.SupportsReadSpecified = true; - mediaTest.SupportsRead10Specified = true; - mediaTest.SupportsRead12Specified = true; - mediaTest.SupportsRead16Specified = true; - - DicConsole.WriteLine("Trying SCSI READ (6)..."); - mediaTest.SupportsRead = !dev.Read6(out buffer, out senseBuffer, 0, 2048, timeout, out duration); - DicConsole.WriteLine("Trying SCSI READ (10)..."); - mediaTest.SupportsRead10 = !dev.Read10(out buffer, out senseBuffer, 0, false, true, false, false, 0, 2048, 0, 1, timeout, out duration); - DicConsole.WriteLine("Trying SCSI READ (12)..."); - mediaTest.SupportsRead12 = !dev.Read12(out buffer, out senseBuffer, 0, false, true, false, false, 0, 2048, 0, 1, false, timeout, out duration); - DicConsole.WriteLine("Trying SCSI READ (16)..."); - mediaTest.SupportsRead16 = !dev.Read16(out buffer, out senseBuffer, 0, false, true, false, 0, 2048, 0, 1, false, timeout, out duration); - - if(options.Debug) - { - if(!tryPlextor) - { - pressedKey = new ConsoleKeyInfo(); - while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N) - { - DicConsole.Write("Do you have want to try Plextor vendor commands? THIS IS DANGEROUS AND CAN IRREVERSIBLY DESTROY YOUR DRIVE (IF IN DOUBT PRESS 'N') (Y/N): "); - pressedKey = System.Console.ReadKey(); - DicConsole.WriteLine(); - } - - tryPlextor |= pressedKey.Key == ConsoleKey.Y; - } - } - - if(mediaType.StartsWith("CD-", StringComparison.Ordinal) || mediaType == "Audio CD") - { - mediaTest.CanReadC2PointersSpecified = true; - mediaTest.CanReadCorrectedSubchannelSpecified = true; - mediaTest.CanReadCorrectedSubchannelWithC2Specified = true; - mediaTest.CanReadLeadInSpecified = true; - mediaTest.CanReadLeadOutSpecified = true; - mediaTest.CanReadPQSubchannelSpecified = true; - mediaTest.CanReadPQSubchannelWithC2Specified = true; - mediaTest.CanReadRWSubchannelSpecified = true; - mediaTest.CanReadRWSubchannelWithC2Specified = true; - mediaTest.SupportsReadCdMsfSpecified = true; - mediaTest.SupportsReadCdSpecified = true; - mediaTest.SupportsReadCdMsfRawSpecified = true; - mediaTest.SupportsReadCdRawSpecified = true; - - if(mediaType == "Audio CD") - { - DicConsole.WriteLine("Trying SCSI READ CD..."); - mediaTest.SupportsReadCd = !dev.ReadCd(out buffer, out senseBuffer, 0, 2352, 1, MmcSectorTypes.CDDA, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.None, MmcSubchannel.None, timeout, out duration); - DicConsole.WriteLine("Trying SCSI READ CD MSF..."); - mediaTest.SupportsReadCdMsf = !dev.ReadCdMsf(out buffer, out senseBuffer, 0x00000200, 0x00000201, 2352, MmcSectorTypes.CDDA, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.None, MmcSubchannel.None, timeout, out duration); - } - else - { - DicConsole.WriteLine("Trying SCSI READ CD..."); - mediaTest.SupportsReadCd = !dev.ReadCd(out buffer, out senseBuffer, 0, 2048, 1, MmcSectorTypes.AllTypes, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.None, MmcSubchannel.None, timeout, out duration); - DicConsole.WriteLine("Trying SCSI READ CD MSF..."); - mediaTest.SupportsReadCdMsf = !dev.ReadCdMsf(out buffer, out senseBuffer, 0x00000200, 0x00000201, 2048, MmcSectorTypes.AllTypes, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.None, MmcSubchannel.None, timeout, out duration); - DicConsole.WriteLine("Trying SCSI READ CD full sector..."); - mediaTest.SupportsReadCdRaw = !dev.ReadCd(out buffer, out senseBuffer, 0, 2352, 1, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None, MmcSubchannel.None, timeout, out duration); - DicConsole.WriteLine("Trying SCSI READ CD MSF full sector..."); - mediaTest.SupportsReadCdMsfRaw = !dev.ReadCdMsf(out buffer, out senseBuffer, 0x00000200, 0x00000201, 2352, MmcSectorTypes.AllTypes, false, false, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None, MmcSubchannel.None, timeout, out duration); - } - - if(mediaTest.SupportsReadCdRaw || mediaType == "Audio CD") - { - DicConsole.WriteLine("Trying to read CD Lead-In..."); - for(int i = -150; i < 0; i++) - { - if(mediaType == "Audio CD") - sense = dev.ReadCd(out buffer, out senseBuffer, (uint)i, 2352, 1, MmcSectorTypes.CDDA, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.None, MmcSubchannel.None, timeout, out duration); - else - sense = dev.ReadCd(out buffer, out senseBuffer, (uint)i, 2352, 1, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None, MmcSubchannel.None, timeout, out duration); - if(!sense) - { - mediaTest.CanReadLeadIn = true; - break; - } - } - - DicConsole.WriteLine("Trying to read CD Lead-Out..."); - if(mediaType == "Audio CD") - mediaTest.CanReadLeadOut = dev.ReadCd(out buffer, out senseBuffer, (uint)(mediaTest.Blocks + 1), 2352, 1, MmcSectorTypes.CDDA, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.None, MmcSubchannel.None, timeout, out duration); - else - mediaTest.CanReadLeadOut = !dev.ReadCd(out buffer, out senseBuffer, (uint)(mediaTest.Blocks + 1), 2352, 1, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None, MmcSubchannel.None, timeout, out duration); - } - - if(mediaType == "Audio CD" && mediaTest.SupportsReadCd) - { - DicConsole.WriteLine("Trying to read C2 Pointers..."); - mediaTest.CanReadC2Pointers = !dev.ReadCd(out buffer, out senseBuffer, 0, 2646, 1, MmcSectorTypes.CDDA, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2Pointers, MmcSubchannel.None, timeout, out duration); - if(!mediaTest.CanReadC2Pointers) - mediaTest.CanReadC2Pointers = !dev.ReadCd(out buffer, out senseBuffer, 0, 2648, 1, MmcSectorTypes.CDDA, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2PointersAndBlock, MmcSubchannel.None, timeout, out duration); - - DicConsole.WriteLine("Trying to read subchannels..."); - mediaTest.CanReadPQSubchannel = !dev.ReadCd(out buffer, out senseBuffer, 0, 2368, 1, MmcSectorTypes.CDDA, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.None, MmcSubchannel.Q16, timeout, out duration); - mediaTest.CanReadRWSubchannel = !dev.ReadCd(out buffer, out senseBuffer, 0, 2448, 1, MmcSectorTypes.CDDA, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.None, MmcSubchannel.Raw, timeout, out duration); - mediaTest.CanReadCorrectedSubchannel = !dev.ReadCd(out buffer, out senseBuffer, 0, 2448, 1, MmcSectorTypes.CDDA, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.None, MmcSubchannel.RW, timeout, out duration); - - DicConsole.WriteLine("Trying to read subchannels with C2 Pointers..."); - mediaTest.CanReadPQSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2662, 1, MmcSectorTypes.CDDA, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2Pointers, MmcSubchannel.Q16, timeout, out duration); - if(!mediaTest.CanReadPQSubchannelWithC2) - mediaTest.CanReadPQSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2664, 1, MmcSectorTypes.CDDA, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2PointersAndBlock, MmcSubchannel.Q16, timeout, out duration); - - mediaTest.CanReadRWSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2712, 1, MmcSectorTypes.CDDA, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2Pointers, MmcSubchannel.Raw, timeout, out duration); - if(!mediaTest.CanReadRWSubchannelWithC2) - mediaTest.CanReadRWSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2714, 1, MmcSectorTypes.CDDA, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2PointersAndBlock, MmcSubchannel.Raw, timeout, out duration); - - mediaTest.CanReadCorrectedSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2712, 1, MmcSectorTypes.CDDA, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2Pointers, MmcSubchannel.RW, timeout, out duration); - if(!mediaTest.CanReadCorrectedSubchannelWithC2) - mediaTest.CanReadCorrectedSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2714, 1, MmcSectorTypes.CDDA, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2PointersAndBlock, MmcSubchannel.RW, timeout, out duration); - } - else if(mediaTest.SupportsReadCdRaw) - { - DicConsole.WriteLine("Trying to read C2 Pointers..."); - mediaTest.CanReadC2Pointers = !dev.ReadCd(out buffer, out senseBuffer, 0, 2646, 1, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.C2Pointers, MmcSubchannel.None, timeout, out duration); - if(!mediaTest.CanReadC2Pointers) - mediaTest.CanReadC2Pointers = !dev.ReadCd(out buffer, out senseBuffer, 0, 2646, 1, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.C2PointersAndBlock, MmcSubchannel.None, timeout, out duration); - - DicConsole.WriteLine("Trying to read subchannels..."); - mediaTest.CanReadPQSubchannel = !dev.ReadCd(out buffer, out senseBuffer, 0, 2368, 1, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None, MmcSubchannel.Q16, timeout, out duration); - mediaTest.CanReadRWSubchannel = !dev.ReadCd(out buffer, out senseBuffer, 0, 2448, 1, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None, MmcSubchannel.Raw, timeout, out duration); - mediaTest.CanReadCorrectedSubchannel = !dev.ReadCd(out buffer, out senseBuffer, 0, 2448, 1, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None, MmcSubchannel.RW, timeout, out duration); - - DicConsole.WriteLine("Trying to read subchannels with C2 Pointers..."); - mediaTest.CanReadPQSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2662, 1, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.C2Pointers, MmcSubchannel.Q16, timeout, out duration); - if(!mediaTest.CanReadPQSubchannelWithC2) - mediaTest.CanReadPQSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2664, 1, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.C2PointersAndBlock, MmcSubchannel.Q16, timeout, out duration); - - mediaTest.CanReadRWSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2712, 1, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.C2Pointers, MmcSubchannel.Raw, timeout, out duration); - if(!mediaTest.CanReadRWSubchannelWithC2) - mediaTest.CanReadRWSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2714, 1, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.C2PointersAndBlock, MmcSubchannel.Raw, timeout, out duration); - - mediaTest.CanReadCorrectedSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2712, 1, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.C2Pointers, MmcSubchannel.RW, timeout, out duration); - if(!mediaTest.CanReadCorrectedSubchannelWithC2) - mediaTest.CanReadCorrectedSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2714, 1, MmcSectorTypes.AllTypes, false, false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.C2PointersAndBlock, MmcSubchannel.RW, timeout, out duration); - } - else - { - DicConsole.WriteLine("Trying to read C2 Pointers..."); - mediaTest.CanReadC2Pointers = !dev.ReadCd(out buffer, out senseBuffer, 0, 2342, 1, MmcSectorTypes.AllTypes, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2Pointers, MmcSubchannel.None, timeout, out duration); - if(!mediaTest.CanReadC2Pointers) - mediaTest.CanReadC2Pointers = !dev.ReadCd(out buffer, out senseBuffer, 0, 2344, 1, MmcSectorTypes.AllTypes, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2PointersAndBlock, MmcSubchannel.None, timeout, out duration); - - DicConsole.WriteLine("Trying to read subchannels..."); - mediaTest.CanReadPQSubchannel = !dev.ReadCd(out buffer, out senseBuffer, 0, 2064, 1, MmcSectorTypes.AllTypes, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.None, MmcSubchannel.Q16, timeout, out duration); - mediaTest.CanReadRWSubchannel = !dev.ReadCd(out buffer, out senseBuffer, 0, 2144, 1, MmcSectorTypes.AllTypes, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.None, MmcSubchannel.Raw, timeout, out duration); - mediaTest.CanReadCorrectedSubchannel = !dev.ReadCd(out buffer, out senseBuffer, 0, 2144, 1, MmcSectorTypes.AllTypes, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.None, MmcSubchannel.RW, timeout, out duration); - - DicConsole.WriteLine("Trying to read subchannels with C2 Pointers..."); - mediaTest.CanReadPQSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2358, 1, MmcSectorTypes.AllTypes, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2Pointers, MmcSubchannel.Q16, timeout, out duration); - if(!mediaTest.CanReadPQSubchannelWithC2) - mediaTest.CanReadPQSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2360, 1, MmcSectorTypes.AllTypes, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2PointersAndBlock, MmcSubchannel.Q16, timeout, out duration); - - mediaTest.CanReadRWSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2438, 1, MmcSectorTypes.AllTypes, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2Pointers, MmcSubchannel.Raw, timeout, out duration); - if(!mediaTest.CanReadRWSubchannelWithC2) - mediaTest.CanReadRWSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2440, 1, MmcSectorTypes.AllTypes, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2PointersAndBlock, MmcSubchannel.Raw, timeout, out duration); - - mediaTest.CanReadCorrectedSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2438, 1, MmcSectorTypes.AllTypes, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2Pointers, MmcSubchannel.RW, timeout, out duration); - if(!mediaTest.CanReadCorrectedSubchannelWithC2) - mediaTest.CanReadCorrectedSubchannelWithC2 = !dev.ReadCd(out buffer, out senseBuffer, 0, 2440, 1, MmcSectorTypes.AllTypes, false, false, false, MmcHeaderCodes.None, true, false, MmcErrorField.C2PointersAndBlock, MmcSubchannel.RW, timeout, out duration); - } - - if(options.Debug) - { - if(!tryNEC) - { - pressedKey = new ConsoleKeyInfo(); - while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N) - { - DicConsole.Write("Do you have want to try NEC vendor commands? THIS IS DANGEROUS AND CAN IRREVERSIBLY DESTROY YOUR DRIVE (IF IN DOUBT PRESS 'N') (Y/N): "); - pressedKey = System.Console.ReadKey(); - DicConsole.WriteLine(); - } - - tryNEC |= pressedKey.Key == ConsoleKey.Y; - } - - if(!tryPioneer) - { - pressedKey = new ConsoleKeyInfo(); - while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N) - { - DicConsole.Write("Do you have want to try Pioneer vendor commands? THIS IS DANGEROUS AND CAN IRREVERSIBLY DESTROY YOUR DRIVE (IF IN DOUBT PRESS 'N') (Y/N): "); - pressedKey = System.Console.ReadKey(); - DicConsole.WriteLine(); - } - - tryPioneer |= pressedKey.Key == ConsoleKey.Y; - } - } - - if(tryPlextor) - { - mediaTest.SupportsPlextorReadCDDASpecified = true; - DicConsole.WriteLine("Trying Plextor READ CD-DA..."); - mediaTest.SupportsPlextorReadCDDA = !dev.PlextorReadCdDa(out buffer, out senseBuffer, 0, 2352, 1, PlextorSubchannel.None, timeout, out duration); - } - - if(tryPioneer) - { - mediaTest.SupportsPioneerReadCDDASpecified = true; - mediaTest.SupportsPioneerReadCDDAMSFSpecified = true; - DicConsole.WriteLine("Trying Pioneer READ CD-DA..."); - mediaTest.SupportsPioneerReadCDDA = !dev.PioneerReadCdDa(out buffer, out senseBuffer, 0, 2352, 1, PioneerSubchannel.None, timeout, out duration); - DicConsole.WriteLine("Trying Pioneer READ CD-DA MSF..."); - mediaTest.SupportsPioneerReadCDDAMSF = !dev.PioneerReadCdDaMsf(out buffer, out senseBuffer, 0x00000200, 0x00000201, 2352, PioneerSubchannel.None, timeout, out duration); - } - - if(tryNEC) - { - mediaTest.SupportsNECReadCDDASpecified = true; - DicConsole.WriteLine("Trying NEC READ CD-DA..."); - mediaTest.SupportsNECReadCDDA = !dev.NecReadCdDa(out buffer, out senseBuffer, 0, 1, timeout, out duration); - } - } - - mediaTest.LongBlockSize = mediaTest.BlockSize; - DicConsole.WriteLine("Trying SCSI READ LONG (10)..."); - sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 0xFFFF, timeout, out duration); - if(sense && !dev.Error) - { - Decoders.SCSI.FixedSense? decSense = Decoders.SCSI.Sense.DecodeFixed(senseBuffer); - if(decSense.HasValue) - { - if(decSense.Value.SenseKey == Decoders.SCSI.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); - mediaTest.LongBlockSizeSpecified = true; - } - } - } - } - - if(options.Debug) - { - if(!tryHLDTST) - { - pressedKey = new ConsoleKeyInfo(); - while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N) - { - DicConsole.Write("Do you have want to try HL-DT-ST (aka LG) vendor commands? THIS IS DANGEROUS AND CAN IRREVERSIBLY DESTROY YOUR DRIVE (IF IN DOUBT PRESS 'N') (Y/N): "); - pressedKey = System.Console.ReadKey(); - DicConsole.WriteLine(); - } - - tryHLDTST |= pressedKey.Key == ConsoleKey.Y; - } - } - - if(mediaTest.SupportsReadLong && mediaTest.LongBlockSize == mediaTest.BlockSize) - { - if(mediaTest.BlockSize == 512) - { - // Long sector sizes for 512-byte magneto-opticals - foreach(ushort testSize in new[] { 600, 610, 630 }) - { - sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, testSize, timeout, out duration); - if(!sense && !dev.Error) - { - mediaTest.SupportsReadLong = true; - mediaTest.LongBlockSize = testSize; - mediaTest.LongBlockSizeSpecified = true; - break; - } - } - } - else if(mediaTest.BlockSize == 1024) - { - sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 1200, timeout, out duration); - if(!sense && !dev.Error) - { - mediaTest.SupportsReadLong = true; - mediaTest.LongBlockSize = 1200; - mediaTest.LongBlockSizeSpecified = true; - } - } - else if(mediaTest.BlockSize == 2048) - { - if(mediaType.StartsWith("DVD", StringComparison.Ordinal)) - { - sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 37856, timeout, out duration); - if(!sense && !dev.Error) - { - mediaTest.SupportsReadLong = true; - mediaTest.LongBlockSize = 37856; - mediaTest.LongBlockSizeSpecified = true; - } - } - else - { - sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 2380, timeout, out duration); - if(!sense && !dev.Error) - { - mediaTest.SupportsReadLong = true; - mediaTest.LongBlockSize = 2380; - mediaTest.LongBlockSizeSpecified = true; - } - } - } - else if(mediaTest.BlockSize == 4096) - { - sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 4760, timeout, out duration); - if(!sense && !dev.Error) - { - mediaTest.SupportsReadLong = true; - mediaTest.LongBlockSize = 4760; - mediaTest.LongBlockSizeSpecified = true; - } - } - else if(mediaTest.BlockSize == 8192) - { - sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 9424, timeout, out duration); - if(!sense && !dev.Error) - { - mediaTest.SupportsReadLong = true; - mediaTest.LongBlockSize = 9424; - mediaTest.LongBlockSizeSpecified = true; - } - } - } - - if(tryPlextor) - { - mediaTest.SupportsPlextorReadRawDVDSpecified = true; - DicConsole.WriteLine("Trying Plextor trick to raw read DVDs..."); - mediaTest.SupportsPlextorReadRawDVD = !dev.PlextorReadRawDvd(out buffer, out senseBuffer, 0, 1, timeout, out duration); - if(mediaTest.SupportsPlextorReadRawDVD) - mediaTest.SupportsPlextorReadRawDVD = !ArrayHelpers.ArrayIsNullOrEmpty(buffer); - } - - if(tryHLDTST) - { - mediaTest.SupportsHLDTSTReadRawDVDSpecified = true; - DicConsole.WriteLine("Trying HL-DT-ST (aka LG) trick to raw read DVDs..."); - mediaTest.SupportsHLDTSTReadRawDVD = !dev.HlDtStReadRawDvd(out buffer, out senseBuffer, 0, 1, timeout, out duration); - } - - 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) - { - for(ushort i = (ushort)mediaTest.BlockSize; i < (ushort)mediaTest.BlockSize * 36; i++) - { - DicConsole.Write("\rTrying to READ LONG with a size of {0} bytes...", i); - sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, i, timeout, out duration); - if(!sense) - { - if(options.Debug) - { - FileStream bingo = new FileStream(string.Format("{0}_readlong.bin", mediaType), FileMode.Create); - bingo.Write(buffer, 0, buffer.Length); - bingo.Close(); - } - mediaTest.LongBlockSize = i; - mediaTest.LongBlockSizeSpecified = true; - break; - } - } - DicConsole.WriteLine(); - } - } - } - mediaTests.Add(mediaTest); - } - report.SCSI.MultiMediaDevice.TestedMedia = mediaTests.ToArray(); - } - } - #endregion MultiMediaDevice - #region SequentialAccessDevice - else if(dev.SCSIType == Decoders.SCSI.PeripheralDeviceTypes.SequentialAccess) - { - report.SCSI.SequentialDevice = new sscType(); - DicConsole.WriteLine("Querying SCSI READ BLOCK LIMITS..."); - sense = dev.ReadBlockLimits(out buffer, out senseBuffer, timeout, out duration); - if(!sense) - { - Decoders.SCSI.SSC.BlockLimits.BlockLimitsData? decBL = Decoders.SCSI.SSC.BlockLimits.Decode(buffer); - if(decBL.HasValue) - { - if(decBL.Value.granularity > 0) - { - report.SCSI.SequentialDevice.BlockSizeGranularitySpecified = true; - report.SCSI.SequentialDevice.BlockSizeGranularity = decBL.Value.granularity; - } - if(decBL.Value.maxBlockLen > 0) - { - report.SCSI.SequentialDevice.MaxBlockLengthSpecified = true; - report.SCSI.SequentialDevice.MaxBlockLength = decBL.Value.maxBlockLen; - } - if(decBL.Value.minBlockLen > 0) - { - report.SCSI.SequentialDevice.MinBlockLengthSpecified = true; - report.SCSI.SequentialDevice.MinBlockLength = decBL.Value.minBlockLen; - } - } - } - - DicConsole.WriteLine("Querying SCSI REPORT DENSITY SUPPORT..."); - sense = dev.ReportDensitySupport(out buffer, out senseBuffer, false, false, timeout, out duration); - if(!sense) - { - Decoders.SCSI.SSC.DensitySupport.DensitySupportHeader? dsh = Decoders.SCSI.SSC.DensitySupport.DecodeDensity(buffer); - if(dsh.HasValue) - { - report.SCSI.SequentialDevice.SupportedDensities = new SupportedDensity[dsh.Value.descriptors.Length]; - for(int i = 0; i < dsh.Value.descriptors.Length; i++) - { - report.SCSI.SequentialDevice.SupportedDensities[i].BitsPerMm = dsh.Value.descriptors[i].bpmm; - report.SCSI.SequentialDevice.SupportedDensities[i].Capacity = dsh.Value.descriptors[i].capacity; - report.SCSI.SequentialDevice.SupportedDensities[i].DefaultDensity = dsh.Value.descriptors[i].defaultDensity; - report.SCSI.SequentialDevice.SupportedDensities[i].Description = dsh.Value.descriptors[i].description; - report.SCSI.SequentialDevice.SupportedDensities[i].Duplicate = dsh.Value.descriptors[i].duplicate; - report.SCSI.SequentialDevice.SupportedDensities[i].Name = dsh.Value.descriptors[i].name; - report.SCSI.SequentialDevice.SupportedDensities[i].Organization = dsh.Value.descriptors[i].organization; - report.SCSI.SequentialDevice.SupportedDensities[i].PrimaryCode = dsh.Value.descriptors[i].primaryCode; - report.SCSI.SequentialDevice.SupportedDensities[i].SecondaryCode = dsh.Value.descriptors[i].secondaryCode; - report.SCSI.SequentialDevice.SupportedDensities[i].Tracks = dsh.Value.descriptors[i].tracks; - report.SCSI.SequentialDevice.SupportedDensities[i].Width = dsh.Value.descriptors[i].width; - report.SCSI.SequentialDevice.SupportedDensities[i].Writable = dsh.Value.descriptors[i].writable; - } - } - } - - DicConsole.WriteLine("Querying SCSI REPORT DENSITY SUPPORT for medium types..."); - sense = dev.ReportDensitySupport(out buffer, out senseBuffer, true, false, timeout, out duration); - if(!sense) - { - Decoders.SCSI.SSC.DensitySupport.MediaTypeSupportHeader? mtsh = Decoders.SCSI.SSC.DensitySupport.DecodeMediumType(buffer); - if(mtsh.HasValue) - { - report.SCSI.SequentialDevice.SupportedMediaTypes = new SupportedMedia[mtsh.Value.descriptors.Length]; - for(int i = 0; i < mtsh.Value.descriptors.Length; i++) - { - report.SCSI.SequentialDevice.SupportedMediaTypes[i].Description = mtsh.Value.descriptors[i].description; - report.SCSI.SequentialDevice.SupportedMediaTypes[i].Length = mtsh.Value.descriptors[i].length; - report.SCSI.SequentialDevice.SupportedMediaTypes[i].MediumType = mtsh.Value.descriptors[i].mediumType; - report.SCSI.SequentialDevice.SupportedMediaTypes[i].Name = mtsh.Value.descriptors[i].name; - report.SCSI.SequentialDevice.SupportedMediaTypes[i].Organization = mtsh.Value.descriptors[i].organization; - report.SCSI.SequentialDevice.SupportedMediaTypes[i].Width = mtsh.Value.descriptors[i].width; - if(mtsh.Value.descriptors[i].densityCodes != null) - { - report.SCSI.SequentialDevice.SupportedMediaTypes[i].DensityCodes = new int[mtsh.Value.descriptors[i].densityCodes.Length]; - for(int j = 0; j < mtsh.Value.descriptors.Length; j++) - report.SCSI.SequentialDevice.SupportedMediaTypes[i].DensityCodes[j] = mtsh.Value.descriptors[i].densityCodes[j]; - } - } - } - } - - List seqTests = new List(); - - pressedKey = new ConsoleKeyInfo(); - while(pressedKey.Key != ConsoleKey.N) - { - pressedKey = new ConsoleKeyInfo(); - while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N) - { - DicConsole.Write("Do you have media that you can insert in the drive? (Y/N): "); - pressedKey = System.Console.ReadKey(); - DicConsole.WriteLine(); - } - - if(pressedKey.Key == ConsoleKey.Y) - { - DicConsole.WriteLine("Please insert it in the drive and press any key when it is ready."); - System.Console.ReadKey(true); - - SequentialMedia seqTest = new SequentialMedia(); - DicConsole.Write("Please write a description of the media type and press enter: "); - seqTest.MediumTypeName = System.Console.ReadLine(); - DicConsole.Write("Please write the media manufacturer and press enter: "); - seqTest.Manufacturer = System.Console.ReadLine(); - DicConsole.Write("Please write the media model and press enter: "); - seqTest.Model = System.Console.ReadLine(); - - seqTest.MediaIsRecognized = true; - - sense = dev.Load(out senseBuffer, timeout, out duration); - sense = dev.ScsiTestUnitReady(out senseBuffer, timeout, out duration); - if(sense) - { - Decoders.SCSI.FixedSense? decSense = Decoders.SCSI.Sense.DecodeFixed(senseBuffer); - if(decSense.HasValue) - { - if(decSense.Value.ASC == 0x3A) - { - int leftRetries = 20; - while(leftRetries > 0) - { - DicConsole.Write("\rWaiting for drive to become ready"); - System.Threading.Thread.Sleep(2000); - sense = dev.ScsiTestUnitReady(out senseBuffer, timeout, out duration); - if(!sense) - break; - - leftRetries--; - } - - seqTest.MediaIsRecognized &= !sense; - } - else if(decSense.Value.ASC == 0x04 && decSense.Value.ASCQ == 0x01) - { - int leftRetries = 20; - while(leftRetries > 0) - { - DicConsole.Write("\rWaiting for drive to become ready"); - System.Threading.Thread.Sleep(2000); - sense = dev.ScsiTestUnitReady(out senseBuffer, timeout, out duration); - if(!sense) - break; - - leftRetries--; - } - - seqTest.MediaIsRecognized &= !sense; - } - else - seqTest.MediaIsRecognized = false; - } - else - seqTest.MediaIsRecognized = false; - } - - if(seqTest.MediaIsRecognized) - { - decMode = null; - - DicConsole.WriteLine("Querying SCSI MODE SENSE (10)..."); - sense = dev.ModeSense10(out buffer, out senseBuffer, false, true, ScsiModeSensePageControl.Current, 0x3F, 0x00, timeout, out duration); - if(!sense && !dev.Error) - { - report.SCSI.SupportsModeSense10 = true; - decMode = Decoders.SCSI.Modes.DecodeMode10(buffer, dev.SCSIType); - } - - DicConsole.WriteLine("Querying SCSI MODE SENSE..."); - sense = dev.ModeSense(out buffer, out senseBuffer, timeout, out duration); - if(!sense && !dev.Error) - { - report.SCSI.SupportsModeSense6 = true; - if(!decMode.HasValue) - decMode = Decoders.SCSI.Modes.DecodeMode6(buffer, dev.SCSIType); - } - - if(decMode.HasValue) - { - seqTest.MediumType = (byte)decMode.Value.Header.MediumType; - seqTest.MediumTypeSpecified = true; - if(decMode.Value.Header.BlockDescriptors != null && decMode.Value.Header.BlockDescriptors.Length > 0) - { - seqTest.Density = (byte)decMode.Value.Header.BlockDescriptors[0].Density; - seqTest.DensitySpecified = true; - } - } - } - - DicConsole.WriteLine("Querying SCSI REPORT DENSITY SUPPORT for current media..."); - sense = dev.ReportDensitySupport(out buffer, out senseBuffer, false, true, timeout, out duration); - if(!sense) - { - Decoders.SCSI.SSC.DensitySupport.DensitySupportHeader? dsh = Decoders.SCSI.SSC.DensitySupport.DecodeDensity(buffer); - if(dsh.HasValue) - { - seqTest.SupportedDensities = new SupportedDensity[dsh.Value.descriptors.Length]; - for(int i = 0; i < dsh.Value.descriptors.Length; i++) - { - seqTest.SupportedDensities[i].BitsPerMm = dsh.Value.descriptors[i].bpmm; - seqTest.SupportedDensities[i].Capacity = dsh.Value.descriptors[i].capacity; - seqTest.SupportedDensities[i].DefaultDensity = dsh.Value.descriptors[i].defaultDensity; - seqTest.SupportedDensities[i].Description = dsh.Value.descriptors[i].description; - seqTest.SupportedDensities[i].Duplicate = dsh.Value.descriptors[i].duplicate; - seqTest.SupportedDensities[i].Name = dsh.Value.descriptors[i].name; - seqTest.SupportedDensities[i].Organization = dsh.Value.descriptors[i].organization; - seqTest.SupportedDensities[i].PrimaryCode = dsh.Value.descriptors[i].primaryCode; - seqTest.SupportedDensities[i].SecondaryCode = dsh.Value.descriptors[i].secondaryCode; - seqTest.SupportedDensities[i].Tracks = dsh.Value.descriptors[i].tracks; - seqTest.SupportedDensities[i].Width = dsh.Value.descriptors[i].width; - seqTest.SupportedDensities[i].Writable = dsh.Value.descriptors[i].writable; - } - } - } - - DicConsole.WriteLine("Querying SCSI REPORT DENSITY SUPPORT for medium types for current media..."); - sense = dev.ReportDensitySupport(out buffer, out senseBuffer, true, true, timeout, out duration); - if(!sense) - { - Decoders.SCSI.SSC.DensitySupport.MediaTypeSupportHeader? mtsh = Decoders.SCSI.SSC.DensitySupport.DecodeMediumType(buffer); - if(mtsh.HasValue) - { - seqTest.SupportedMediaTypes = new SupportedMedia[mtsh.Value.descriptors.Length]; - for(int i = 0; i < mtsh.Value.descriptors.Length; i++) - { - seqTest.SupportedMediaTypes[i].Description = mtsh.Value.descriptors[i].description; - seqTest.SupportedMediaTypes[i].Length = mtsh.Value.descriptors[i].length; - seqTest.SupportedMediaTypes[i].MediumType = mtsh.Value.descriptors[i].mediumType; - seqTest.SupportedMediaTypes[i].Name = mtsh.Value.descriptors[i].name; - seqTest.SupportedMediaTypes[i].Organization = mtsh.Value.descriptors[i].organization; - seqTest.SupportedMediaTypes[i].Width = mtsh.Value.descriptors[i].width; - if(mtsh.Value.descriptors[i].densityCodes != null) - { - seqTest.SupportedMediaTypes[i].DensityCodes = new int[mtsh.Value.descriptors[i].densityCodes.Length]; - for(int j = 0; j < mtsh.Value.descriptors.Length; j++) - seqTest.SupportedMediaTypes[i].DensityCodes[j] = mtsh.Value.descriptors[i].densityCodes[j]; - } - } - } - } - - seqTest.CanReadMediaSerialSpecified = true; - DicConsole.WriteLine("Trying SCSI READ MEDIA SERIAL NUMBER..."); - seqTest.CanReadMediaSerial = !dev.ReadMediaSerialNumber(out buffer, out senseBuffer, timeout, out duration); - seqTests.Add(seqTest); - } - } - report.SCSI.SequentialDevice.TestedMedia = seqTests.ToArray(); - } - #endregion SequentialAccessDevice - #region OtherDevices - else - { - if(removable) - { - List mediaTests = new List(); - - pressedKey = new ConsoleKeyInfo(); - while(pressedKey.Key != ConsoleKey.N) - { - pressedKey = new ConsoleKeyInfo(); - while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N) - { - DicConsole.Write("Do you have media that you can insert in the drive? (Y/N): "); - pressedKey = System.Console.ReadKey(); - DicConsole.WriteLine(); - } - - if(pressedKey.Key == ConsoleKey.Y) - { - DicConsole.WriteLine("Please insert it in the drive and press any key when it is ready."); - System.Console.ReadKey(true); - - 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(); - - mediaTest.ManufacturerSpecified = true; - mediaTest.ModelSpecified = true; - mediaTest.MediaIsRecognized = true; - - sense = dev.ScsiTestUnitReady(out senseBuffer, timeout, out duration); - if(sense) - { - Decoders.SCSI.FixedSense? decSense = Decoders.SCSI.Sense.DecodeFixed(senseBuffer); - if(decSense.HasValue) - { - if(decSense.Value.ASC == 0x3A) - { - int leftRetries = 20; - while(leftRetries > 0) - { - DicConsole.Write("\rWaiting for drive to become ready"); - System.Threading.Thread.Sleep(2000); - sense = dev.ScsiTestUnitReady(out senseBuffer, timeout, out duration); - if(!sense) - break; - - leftRetries--; - } - - mediaTest.MediaIsRecognized &= !sense; - } - else if(decSense.Value.ASC == 0x04 && decSense.Value.ASCQ == 0x01) - { - int leftRetries = 20; - while(leftRetries > 0) - { - DicConsole.Write("\rWaiting for drive to become ready"); - System.Threading.Thread.Sleep(2000); - sense = dev.ScsiTestUnitReady(out senseBuffer, timeout, out duration); - if(!sense) - break; - - leftRetries--; - } - - mediaTest.MediaIsRecognized &= !sense; - } - else - mediaTest.MediaIsRecognized = false; - } - else - mediaTest.MediaIsRecognized = false; - } - - if(mediaTest.MediaIsRecognized) - { - mediaTest.SupportsReadCapacitySpecified = true; - mediaTest.SupportsReadCapacity16Specified = true; - - DicConsole.WriteLine("Querying SCSI READ CAPACITY..."); - sense = dev.ReadCapacity(out buffer, out senseBuffer, timeout, out duration); - 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[5] << 24) + (buffer[5] << 16) + (buffer[6] << 8) + (buffer[7])); - mediaTest.BlocksSpecified = true; - mediaTest.BlockSizeSpecified = true; - } - - DicConsole.WriteLine("Querying SCSI READ CAPACITY (16)..."); - sense = dev.ReadCapacity16(out buffer, out buffer, timeout, out duration); - 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[5] << 24) + (buffer[5] << 16) + (buffer[6] << 8) + (buffer[7])); - mediaTest.BlocksSpecified = true; - mediaTest.BlockSizeSpecified = true; - } - - decMode = null; - - DicConsole.WriteLine("Querying SCSI MODE SENSE (10)..."); - sense = dev.ModeSense10(out buffer, out senseBuffer, false, true, ScsiModeSensePageControl.Current, 0x3F, 0x00, timeout, out duration); - if(!sense && !dev.Error) - { - report.SCSI.SupportsModeSense10 = true; - decMode = Decoders.SCSI.Modes.DecodeMode10(buffer, dev.SCSIType); - } - - DicConsole.WriteLine("Querying SCSI MODE SENSE..."); - sense = dev.ModeSense(out buffer, out senseBuffer, timeout, out duration); - if(!sense && !dev.Error) - { - report.SCSI.SupportsModeSense6 = true; - if(!decMode.HasValue) - decMode = Decoders.SCSI.Modes.DecodeMode6(buffer, dev.SCSIType); - } - - 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) - { - mediaTest.Density = (byte)decMode.Value.Header.BlockDescriptors[0].Density; - mediaTest.DensitySpecified = true; - } - } - - mediaTest.SupportsReadSpecified = true; - mediaTest.SupportsRead10Specified = true; - mediaTest.SupportsRead12Specified = true; - mediaTest.SupportsRead16Specified = true; - mediaTest.SupportsReadLongSpecified = true; - - DicConsole.WriteLine("Trying SCSI READ (6)..."); - mediaTest.SupportsRead = !dev.Read6(out buffer, out senseBuffer, 0, mediaTest.BlockSize, timeout, out duration); - DicConsole.WriteLine("Trying SCSI READ (10)..."); - mediaTest.SupportsRead10 = !dev.Read10(out buffer, out senseBuffer, 0, false, true, false, false, 0, mediaTest.BlockSize, 0, 1, timeout, out duration); - DicConsole.WriteLine("Trying SCSI READ (12)..."); - mediaTest.SupportsRead12 = !dev.Read12(out buffer, out senseBuffer, 0, false, true, false, false, 0, mediaTest.BlockSize, 0, 1, false, timeout, out duration); - DicConsole.WriteLine("Trying SCSI READ (16)..."); - mediaTest.SupportsRead16 = !dev.Read16(out buffer, out senseBuffer, 0, false, true, false, 0, mediaTest.BlockSize, 0, 1, false, timeout, out duration); - - mediaTest.LongBlockSize = mediaTest.BlockSize; - DicConsole.WriteLine("Trying SCSI READ LONG (10)..."); - sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 0xFFFF, timeout, out duration); - if(sense && !dev.Error) - { - Decoders.SCSI.FixedSense? decSense = Decoders.SCSI.Sense.DecodeFixed(senseBuffer); - if(decSense.HasValue) - { - if(decSense.Value.SenseKey == Decoders.SCSI.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); - mediaTest.LongBlockSizeSpecified = true; - } - } - } - } - - if(mediaTest.SupportsReadLong && mediaTest.LongBlockSize == mediaTest.BlockSize) - { - if(mediaTest.BlockSize == 512) - { - // Long sector sizes for 512-byte magneto-opticals - foreach(ushort testSize in new[] { 600, 610, 630 }) - { - sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, testSize, timeout, out duration); - if(!sense && !dev.Error) - { - mediaTest.SupportsReadLong = true; - mediaTest.LongBlockSize = testSize; - mediaTest.LongBlockSizeSpecified = true; - break; - } - } - } - else if(mediaTest.BlockSize == 1024) - { - sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 1200, timeout, out duration); - if(!sense && !dev.Error) - { - mediaTest.SupportsReadLong = true; - mediaTest.LongBlockSize = 1200; - mediaTest.LongBlockSizeSpecified = true; - } - } - else if(mediaTest.BlockSize == 2048) - { - sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 2380, timeout, out duration); - if(!sense && !dev.Error) - { - mediaTest.SupportsReadLong = true; - mediaTest.LongBlockSize = 2380; - mediaTest.LongBlockSizeSpecified = true; - } - } - else if(mediaTest.BlockSize == 4096) - { - sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 4760, timeout, out duration); - if(!sense && !dev.Error) - { - mediaTest.SupportsReadLong = true; - mediaTest.LongBlockSize = 4760; - mediaTest.LongBlockSizeSpecified = true; - } - } - else if(mediaTest.BlockSize == 8192) - { - sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 9424, timeout, out duration); - if(!sense && !dev.Error) - { - mediaTest.SupportsReadLong = true; - mediaTest.LongBlockSize = 9424; - mediaTest.LongBlockSizeSpecified = true; - } - } - } - - 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) - { - for(ushort i = (ushort)mediaTest.BlockSize; i < (ushort)mediaTest.BlockSize * 36; i++) - { - DicConsole.Write("\rTrying to READ LONG with a size of {0} bytes...", i); - sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, i, timeout, out duration); - if(!sense) - { - if(options.Debug) - { - FileStream bingo = new FileStream(string.Format("{0}_readlong.bin", mediaTest.MediumTypeName), FileMode.Create); - bingo.Write(buffer, 0, buffer.Length); - bingo.Close(); - } - mediaTest.LongBlockSize = i; - mediaTest.LongBlockSizeSpecified = true; - break; - } - } - DicConsole.WriteLine(); - } - } - - mediaTest.CanReadMediaSerialSpecified = true; - DicConsole.WriteLine("Trying SCSI READ MEDIA SERIAL NUMBER..."); - mediaTest.CanReadMediaSerial = !dev.ReadMediaSerialNumber(out buffer, out senseBuffer, timeout, out duration); - } - mediaTests.Add(mediaTest); - } - } - report.SCSI.RemovableMedias = mediaTests.ToArray(); - } - else - { - report.SCSI.ReadCapabilities = new testedMediaType(); - report.SCSI.ReadCapabilitiesSpecified = true; - report.SCSI.ReadCapabilities.MediaIsRecognized = true; - - report.SCSI.ReadCapabilities.SupportsReadCapacitySpecified = true; - report.SCSI.ReadCapabilities.SupportsReadCapacity16Specified = true; - - DicConsole.WriteLine("Querying SCSI READ CAPACITY..."); - sense = dev.ReadCapacity(out buffer, out senseBuffer, timeout, out duration); - 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[5] << 24) + (buffer[5] << 16) + (buffer[6] << 8) + (buffer[7])); - report.SCSI.ReadCapabilities.BlocksSpecified = true; - report.SCSI.ReadCapabilities.BlockSizeSpecified = true; - } - - DicConsole.WriteLine("Querying SCSI READ CAPACITY (16)..."); - sense = dev.ReadCapacity16(out buffer, out buffer, timeout, out duration); - 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[5] << 24) + (buffer[5] << 16) + (buffer[6] << 8) + (buffer[7])); - report.SCSI.ReadCapabilities.BlocksSpecified = true; - report.SCSI.ReadCapabilities.BlockSizeSpecified = true; - } - - decMode = null; - - DicConsole.WriteLine("Querying SCSI MODE SENSE (10)..."); - sense = dev.ModeSense10(out buffer, out senseBuffer, false, true, ScsiModeSensePageControl.Current, 0x3F, 0x00, timeout, out duration); - if(!sense && !dev.Error) - { - report.SCSI.SupportsModeSense10 = true; - decMode = Decoders.SCSI.Modes.DecodeMode10(buffer, dev.SCSIType); - } - - DicConsole.WriteLine("Querying SCSI MODE SENSE..."); - sense = dev.ModeSense(out buffer, out senseBuffer, timeout, out duration); - if(!sense && !dev.Error) - { - report.SCSI.SupportsModeSense6 = true; - if(!decMode.HasValue) - decMode = Decoders.SCSI.Modes.DecodeMode6(buffer, dev.SCSIType); - } - - 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; - } - } - - 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)..."); - report.SCSI.ReadCapabilities.SupportsRead = !dev.Read6(out buffer, out senseBuffer, 0, report.SCSI.ReadCapabilities.BlockSize, timeout, out duration); - DicConsole.WriteLine("Trying SCSI READ (10)..."); - report.SCSI.ReadCapabilities.SupportsRead10 = !dev.Read10(out buffer, out senseBuffer, 0, false, true, false, false, 0, report.SCSI.ReadCapabilities.BlockSize, 0, 1, timeout, out duration); - DicConsole.WriteLine("Trying SCSI READ (12)..."); - report.SCSI.ReadCapabilities.SupportsRead12 = !dev.Read12(out buffer, out senseBuffer, 0, false, true, false, false, 0, report.SCSI.ReadCapabilities.BlockSize, 0, 1, false, timeout, out duration); - DicConsole.WriteLine("Trying SCSI READ (16)..."); - report.SCSI.ReadCapabilities.SupportsRead16 = !dev.Read16(out buffer, out senseBuffer, 0, false, true, false, 0, report.SCSI.ReadCapabilities.BlockSize, 0, 1, false, timeout, out duration); - - report.SCSI.ReadCapabilities.LongBlockSize = report.SCSI.ReadCapabilities.BlockSize; - DicConsole.WriteLine("Trying SCSI READ LONG (10)..."); - sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 0xFFFF, timeout, out duration); - if(sense && !dev.Error) - { - Decoders.SCSI.FixedSense? decSense = Decoders.SCSI.Sense.DecodeFixed(senseBuffer); - if(decSense.HasValue) - { - if(decSense.Value.SenseKey == Decoders.SCSI.SenseKeys.IllegalRequest && - decSense.Value.ASC == 0x24 && decSense.Value.ASCQ == 0x00) - { - report.SCSI.ReadCapabilities.SupportsReadLong = true; - if(decSense.Value.InformationValid && decSense.Value.ILI) - { - report.SCSI.ReadCapabilities.LongBlockSize = 0xFFFF - (decSense.Value.Information & 0xFFFF); - report.SCSI.ReadCapabilities.LongBlockSizeSpecified = true; - } - } - } - } - - if(report.SCSI.ReadCapabilities.SupportsReadLong && report.SCSI.ReadCapabilities.LongBlockSize == report.SCSI.ReadCapabilities.BlockSize) - { - if(report.SCSI.ReadCapabilities.BlockSize == 512) - { - // Long sector sizes for 512-byte magneto-opticals - foreach(ushort testSize in new[] { 600, 610, 630 }) - { - sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, testSize, timeout, out duration); - if(!sense && !dev.Error) - { - report.SCSI.ReadCapabilities.SupportsReadLong = true; - report.SCSI.ReadCapabilities.LongBlockSize = testSize; - report.SCSI.ReadCapabilities.LongBlockSizeSpecified = true; - break; - } - } - } - else if(report.SCSI.ReadCapabilities.BlockSize == 1024) - { - sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 1200, timeout, out duration); - if(!sense && !dev.Error) - { - report.SCSI.ReadCapabilities.SupportsReadLong = true; - report.SCSI.ReadCapabilities.LongBlockSize = 1200; - report.SCSI.ReadCapabilities.LongBlockSizeSpecified = true; - } - } - else if(report.SCSI.ReadCapabilities.BlockSize == 2048) - { - sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 2380, timeout, out duration); - if(!sense && !dev.Error) - { - report.SCSI.ReadCapabilities.SupportsReadLong = true; - report.SCSI.ReadCapabilities.LongBlockSize = 2380; - report.SCSI.ReadCapabilities.LongBlockSizeSpecified = true; - } - } - else if(report.SCSI.ReadCapabilities.BlockSize == 4096) - { - sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 4760, timeout, out duration); - if(!sense && !dev.Error) - { - report.SCSI.ReadCapabilities.SupportsReadLong = true; - report.SCSI.ReadCapabilities.LongBlockSize = 4760; - report.SCSI.ReadCapabilities.LongBlockSizeSpecified = true; - } - } - else if(report.SCSI.ReadCapabilities.BlockSize == 8192) - { - sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, 9424, timeout, out duration); - if(!sense && !dev.Error) - { - report.SCSI.ReadCapabilities.SupportsReadLong = true; - report.SCSI.ReadCapabilities.LongBlockSize = 9424; - report.SCSI.ReadCapabilities.LongBlockSizeSpecified = true; - } - } - } - - if(report.SCSI.ReadCapabilities.SupportsReadLong && report.SCSI.ReadCapabilities.LongBlockSize == report.SCSI.ReadCapabilities.BlockSize) - { - pressedKey = new ConsoleKeyInfo(); - while(pressedKey.Key != ConsoleKey.Y && pressedKey.Key != ConsoleKey.N) - { - DicConsole.Write("Drive supports SCSI READ LONG but I cannot find the correct size. Do you want me to try? (This can take hours) (Y/N): "); - pressedKey = System.Console.ReadKey(); - DicConsole.WriteLine(); - } - - if(pressedKey.Key == ConsoleKey.Y) - { - for(ushort i = (ushort)report.SCSI.ReadCapabilities.BlockSize; i < (ushort)report.SCSI.ReadCapabilities.BlockSize * 36; i++) - { - DicConsole.Write("\rTrying to READ LONG with a size of {0} bytes...", i); - sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, i, timeout, out duration); - if(!sense) - { - if(options.Debug) - { - FileStream bingo = new FileStream(string.Format("{0}_readlong.bin", dev.Model), FileMode.Create); - bingo.Write(buffer, 0, buffer.Length); - bingo.Close(); - } - report.SCSI.ReadCapabilities.LongBlockSize = i; - report.SCSI.ReadCapabilities.LongBlockSizeSpecified = true; - break; - } - } - DicConsole.WriteLine(); - } - } - } - } - #endregion OtherDevices - - FileStream xmlFs = new FileStream(xmlFile, FileMode.Create); - - System.Xml.Serialization.XmlSerializer xmlSer = new System.Xml.Serialization.XmlSerializer(typeof(Metadata.DeviceReport)); - xmlSer.Serialize(xmlFs, report); - xmlFs.Close(); - - if(Settings.Settings.Current.SaveReportsGlobally && !string.IsNullOrEmpty(Settings.Settings.ReportsPath)) - { - xmlFs = new FileStream(Path.Combine(Settings.Settings.ReportsPath, xmlFile), FileMode.Create); - xmlSer.Serialize(xmlFs, report); - xmlFs.Close(); - } if(Settings.Settings.Current.ShareReports) { - SubmitReport(xmlSer); + Remote.SubmitReport(xmlSer); } } - - static void SubmitReport(System.Xml.Serialization.XmlSerializer xmlSer) - { - // TODO: Implement this - } } }