mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
Refactor: Move device-report logic to Core and separate by
category.
This commit is contained in:
961
DiscImageChef.Core/Devices/Report/ATA.cs
Normal file
961
DiscImageChef.Core/Devices/Report/ATA.cs
Normal file
@@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// 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<testedMediaType> mediaTests = new List<testedMediaType>();
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
464
DiscImageChef.Core/Devices/Report/ATAPI.cs
Normal file
464
DiscImageChef.Core/Devices/Report/ATAPI.cs
Normal file
@@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
81
DiscImageChef.Core/Devices/Report/FireWire.cs
Normal file
81
DiscImageChef.Core/Devices/Report/FireWire.cs
Normal file
@@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
54
DiscImageChef.Core/Devices/Report/NVMe.cs
Normal file
54
DiscImageChef.Core/Devices/Report/NVMe.cs
Normal file
@@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// 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.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
83
DiscImageChef.Core/Devices/Report/PCMCIA.cs
Normal file
83
DiscImageChef.Core/Devices/Report/PCMCIA.cs
Normal file
@@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
792
DiscImageChef.Core/Devices/Report/SCSI/General.cs
Normal file
792
DiscImageChef.Core/Devices/Report/SCSI/General.cs
Normal file
@@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// 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<ushort> versionDescriptors = new List<ushort>();
|
||||||
|
report.SCSI.Inquiry = new scsiInquiryType();
|
||||||
|
|
||||||
|
if(inq.DeviceTypeModifier != 0)
|
||||||
|
{
|
||||||
|
report.SCSI.Inquiry.DeviceTypeModifier = inq.DeviceTypeModifier;
|
||||||
|
report.SCSI.Inquiry.DeviceTypeModifierSpecified = true;
|
||||||
|
}
|
||||||
|
if(inq.ISOVersion != 0)
|
||||||
|
{
|
||||||
|
report.SCSI.Inquiry.ISOVersion = inq.ISOVersion;
|
||||||
|
report.SCSI.Inquiry.ISOVersionSpecified = true;
|
||||||
|
}
|
||||||
|
if(inq.ECMAVersion != 0)
|
||||||
|
{
|
||||||
|
report.SCSI.Inquiry.ECMAVersion = inq.ECMAVersion;
|
||||||
|
report.SCSI.Inquiry.ECMAVersionSpecified = true;
|
||||||
|
}
|
||||||
|
if(inq.ANSIVersion != 0)
|
||||||
|
{
|
||||||
|
report.SCSI.Inquiry.ANSIVersion = inq.ANSIVersion;
|
||||||
|
report.SCSI.Inquiry.ANSIVersionSpecified = true;
|
||||||
|
}
|
||||||
|
if(inq.ResponseDataFormat != 0)
|
||||||
|
{
|
||||||
|
report.SCSI.Inquiry.ResponseDataFormat = inq.ResponseDataFormat;
|
||||||
|
report.SCSI.Inquiry.ResponseDataFormatSpecified = true;
|
||||||
|
}
|
||||||
|
if(!string.IsNullOrWhiteSpace(StringHandlers.CToString(inq.VendorIdentification)))
|
||||||
|
{
|
||||||
|
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<pageType> evpds = new List<pageType>();
|
||||||
|
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<modePageType> modePages = new List<modePageType>();
|
||||||
|
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<string> mediaTypes = new List<string>();
|
||||||
|
|
||||||
|
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<testedMediaType> mediaTests = new List<testedMediaType>();
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
1372
DiscImageChef.Core/Devices/Report/SCSI/MMC.cs
Normal file
1372
DiscImageChef.Core/Devices/Report/SCSI/MMC.cs
Normal file
File diff suppressed because it is too large
Load Diff
307
DiscImageChef.Core/Devices/Report/SCSI/SSC.cs
Normal file
307
DiscImageChef.Core/Devices/Report/SCSI/SSC.cs
Normal file
@@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// 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<SequentialMedia> seqTests = new List<SequentialMedia>();
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
54
DiscImageChef.Core/Devices/Report/SecureDigital.cs
Normal file
54
DiscImageChef.Core/Devices/Report/SecureDigital.cs
Normal file
@@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// 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.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
81
DiscImageChef.Core/Devices/Report/USB.cs
Normal file
81
DiscImageChef.Core/Devices/Report/USB.cs
Normal file
@@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -55,6 +55,17 @@
|
|||||||
<Compile Include="Benchmark.cs" />
|
<Compile Include="Benchmark.cs" />
|
||||||
<Compile Include="Delegates.cs" />
|
<Compile Include="Delegates.cs" />
|
||||||
<Compile Include="Devices\Scanning\ScanResults.cs" />
|
<Compile Include="Devices\Scanning\ScanResults.cs" />
|
||||||
|
<Compile Include="Devices\Report\ATA.cs" />
|
||||||
|
<Compile Include="Devices\Report\ATAPI.cs" />
|
||||||
|
<Compile Include="Devices\Report\FireWire.cs" />
|
||||||
|
<Compile Include="Devices\Report\USB.cs" />
|
||||||
|
<Compile Include="Devices\Report\NVMe.cs" />
|
||||||
|
<Compile Include="Devices\Report\SecureDigital.cs" />
|
||||||
|
<Compile Include="Devices\Report\SCSI\MMC.cs" />
|
||||||
|
<Compile Include="Devices\Report\SCSI\SSC.cs" />
|
||||||
|
<Compile Include="Devices\Report\SCSI\General.cs" />
|
||||||
|
<Compile Include="Remote.cs" />
|
||||||
|
<Compile Include="Devices\Report\PCMCIA.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\DiscImageChef.Console\DiscImageChef.Console.csproj">
|
<ProjectReference Include="..\DiscImageChef.Console\DiscImageChef.Console.csproj">
|
||||||
@@ -105,21 +116,36 @@
|
|||||||
<Project>{9183F2E0-A879-4F23-9EE3-C6908F1332B2}</Project>
|
<Project>{9183F2E0-A879-4F23-9EE3-C6908F1332B2}</Project>
|
||||||
<Name>DiscImageChef.Interop</Name>
|
<Name>DiscImageChef.Interop</Name>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\DiscImageChef.Helpers\DiscImageChef.Helpers.csproj">
|
||||||
|
<Project>{F8BDF57B-1571-4CD0-84B3-B422088D359A}</Project>
|
||||||
|
<Name>DiscImageChef.Helpers</Name>
|
||||||
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Folder Include="Logging\" />
|
<Folder Include="Logging\" />
|
||||||
<Folder Include="Devices\" />
|
<Folder Include="Devices\" />
|
||||||
<Folder Include="Devices\Scanning\" />
|
<Folder Include="Devices\Scanning\" />
|
||||||
<Folder Include="Devices\Dumping\" />
|
<Folder Include="Devices\Dumping\" />
|
||||||
|
<Folder Include="Devices\Report\" />
|
||||||
|
<Folder Include="Devices\Report\SCSI\" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||||
<ProjectExtensions>
|
<ProjectExtensions>
|
||||||
<MonoDevelop>
|
<MonoDevelop>
|
||||||
<Properties>
|
<Properties>
|
||||||
<Policies>
|
<Policies>
|
||||||
<TextStylePolicy TabWidth="4" TabsToSpaces="True" IndentWidth="4" RemoveTrailingWhitespace="True" NoTabsAfterNonTabs="False" EolMarker="Native" FileWidth="120" inheritsSet="VisualStudio" inheritsScope="text/plain" scope="text/x-csharp" />
|
<TextStylePolicy FileWidth="120" TabWidth="4" IndentWidth="4" RemoveTrailingWhitespace="True" NoTabsAfterNonTabs="False" EolMarker="Native" TabsToSpaces="True" scope="text/x-csharp">
|
||||||
<CSharpFormattingPolicy IndentBlock="True" IndentBraces="False" IndentSwitchCaseSection="True" LabelPositioning="OneLess" NewLinesForBracesInTypes="True" NewLinesForBracesInMethods="True" NewLineForMembersInObjectInit="False" NewLineForMembersInAnonymousTypes="False" NewLineForClausesInQuery="False" SpaceWithinMethodDeclarationParenthesis="False" SpaceBetweenEmptyMethodDeclarationParentheses="False" SpaceWithinMethodCallParentheses="False" SpaceBetweenEmptyMethodCallParentheses="False" SpaceWithinExpressionParentheses="False" SpaceWithinCastParentheses="False" SpaceWithinOtherParentheses="False" SpaceAfterCast="False" SpacesIgnoreAroundVariableDeclaration="False" SpaceBetweenEmptySquareBrackets="False" SpaceWithinSquareBrackets="False" SpaceAfterColonInBaseTypeDeclaration="True" SpaceAfterComma="True" SpaceAfterDot="False" SpaceAfterSemicolonsInForStatement="True" SpaceBeforeColonInBaseTypeDeclaration="True" SpaceBeforeComma="False" SpaceBeforeDot="False" SpaceBeforeSemicolonsInForStatement="False" SpacingAroundBinaryOperator="Single" WrappingPreserveSingleLine="True" WrappingKeepStatementsOnSingleLine="True" PlaceSystemDirectiveFirst="True" IndentSwitchSection="True" NewLinesForBracesInProperties="True" NewLinesForBracesInAccessors="True" NewLinesForBracesInAnonymousMethods="True" NewLinesForBracesInControlBlocks="True" NewLinesForBracesInAnonymousTypes="True" NewLinesForBracesInObjectCollectionArrayInitializers="True" NewLinesForBracesInLambdaExpressionBody="True" NewLineForElse="True" NewLineForCatch="True" NewLineForFinally="True" SpacingAfterMethodDeclarationName="False" SpaceAfterMethodCallName="False" SpaceAfterControlFlowStatementKeyword="False" SpaceBeforeOpenSquareBracket="False" inheritsSet="Mono" inheritsScope="text/x-csharp" scope="text/x-csharp" />
|
<inheritsSet />
|
||||||
<DotNetNamingPolicy DirectoryNamespaceAssociation="PrefixedHierarchical" ResourceNamePolicy="MSBuild" />
|
<inheritsScope />
|
||||||
|
</TextStylePolicy>
|
||||||
|
<CSharpFormattingPolicy IndentBlock="True" IndentBraces="False" IndentSwitchSection="True" IndentSwitchCaseSection="True" LabelPositioning="OneLess" NewLinesForBracesInTypes="True" NewLinesForBracesInMethods="True" NewLinesForBracesInProperties="True" NewLinesForBracesInAccessors="True" NewLinesForBracesInAnonymousMethods="True" NewLinesForBracesInControlBlocks="True" NewLinesForBracesInAnonymousTypes="True" NewLinesForBracesInObjectCollectionArrayInitializers="True" NewLinesForBracesInLambdaExpressionBody="True" NewLineForElse="True" NewLineForCatch="True" NewLineForFinally="True" NewLineForMembersInObjectInit="False" NewLineForMembersInAnonymousTypes="False" NewLineForClausesInQuery="False" SpacingAfterMethodDeclarationName="False" SpaceWithinMethodDeclarationParenthesis="False" SpaceBetweenEmptyMethodDeclarationParentheses="False" SpaceAfterMethodCallName="False" SpaceWithinMethodCallParentheses="False" SpaceBetweenEmptyMethodCallParentheses="False" SpaceAfterControlFlowStatementKeyword="False" SpaceWithinExpressionParentheses="False" SpaceWithinCastParentheses="False" SpaceWithinOtherParentheses="False" SpaceAfterCast="False" SpacesIgnoreAroundVariableDeclaration="False" SpaceBeforeOpenSquareBracket="False" SpaceBetweenEmptySquareBrackets="False" SpaceWithinSquareBrackets="False" SpaceAfterColonInBaseTypeDeclaration="True" SpaceAfterComma="True" SpaceAfterDot="False" SpaceAfterSemicolonsInForStatement="True" SpaceBeforeColonInBaseTypeDeclaration="True" SpaceBeforeComma="False" SpaceBeforeDot="False" SpaceBeforeSemicolonsInForStatement="False" SpacingAroundBinaryOperator="Single" WrappingPreserveSingleLine="True" WrappingKeepStatementsOnSingleLine="True" PlaceSystemDirectiveFirst="True" scope="text/x-csharp">
|
||||||
|
<inheritsSet />
|
||||||
|
<inheritsScope />
|
||||||
|
</CSharpFormattingPolicy>
|
||||||
|
<DotNetNamingPolicy DirectoryNamespaceAssociation="PrefixedHierarchical" ResourceNamePolicy="MSBuild">
|
||||||
|
<inheritsSet />
|
||||||
|
<inheritsScope />
|
||||||
|
</DotNetNamingPolicy>
|
||||||
</Policies>
|
</Policies>
|
||||||
</Properties>
|
</Properties>
|
||||||
</MonoDevelop>
|
</MonoDevelop>
|
||||||
|
|||||||
47
DiscImageChef.Core/Remote.cs
Normal file
47
DiscImageChef.Core/Remote.cs
Normal file
@@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,3 +1,9 @@
|
|||||||
|
2017-05-28 Natalia Portillo <claunia@claunia.com>
|
||||||
|
|
||||||
|
* Commands/DeviceReport.cs:
|
||||||
|
Refactor: Move device-report logic to Core and separate by
|
||||||
|
category.
|
||||||
|
|
||||||
2017-05-28 Natalia Portillo <claunia@claunia.com>
|
2017-05-28 Natalia Portillo <claunia@claunia.com>
|
||||||
|
|
||||||
* Commands/MediaScan.cs:
|
* Commands/MediaScan.cs:
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user