diff --git a/.idea/.idea.DiscImageChef/.idea/contentModel.xml b/.idea/.idea.DiscImageChef/.idea/contentModel.xml
index 53b6ed816..131537e79 100644
--- a/.idea/.idea.DiscImageChef/.idea/contentModel.xml
+++ b/.idea/.idea.DiscImageChef/.idea/contentModel.xml
@@ -213,6 +213,11 @@
+
+
+
+
+
diff --git a/DiscImageChef.Core/Devices/Info/DeviceInfo.cs b/DiscImageChef.Core/Devices/Info/DeviceInfo.cs
new file mode 100644
index 000000000..0dc294772
--- /dev/null
+++ b/DiscImageChef.Core/Devices/Info/DeviceInfo.cs
@@ -0,0 +1,460 @@
+// /***************************************************************************
+// The Disc Image Chef
+// ----------------------------------------------------------------------------
+//
+// Filename : DeviceInfo.cs
+// Author(s) : Natalia Portillo
+//
+// Component : Core.
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Retrieves the device info.
+//
+// --[ License ] --------------------------------------------------------------
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2018 Natalia Portillo
+// ****************************************************************************/
+
+using System;
+using System.Collections.Generic;
+using DiscImageChef.Console;
+using DiscImageChef.Decoders.ATA;
+using DiscImageChef.Decoders.SCSI;
+using DiscImageChef.Devices;
+
+namespace DiscImageChef.Core.Devices.Info
+{
+ public partial class DeviceInfo
+ {
+ public DeviceInfo(Device dev)
+ {
+ switch(dev.Type)
+ {
+ case DeviceType.ATA:
+ {
+ bool sense = dev.AtaIdentify(out byte[] ataBuf, out AtaErrorRegistersChs errorRegisters);
+
+ if(sense)
+ {
+ DicConsole.DebugWriteLine("Device-Info command", "STATUS = 0x{0:X2}", errorRegisters.Status);
+ DicConsole.DebugWriteLine("Device-Info command", "ERROR = 0x{0:X2}", errorRegisters.Error);
+ DicConsole.DebugWriteLine("Device-Info command", "NSECTOR = 0x{0:X2}",
+ errorRegisters.SectorCount);
+ DicConsole.DebugWriteLine("Device-Info command", "SECTOR = 0x{0:X2}", errorRegisters.Sector);
+ DicConsole.DebugWriteLine("Device-Info command", "CYLHIGH = 0x{0:X2}",
+ errorRegisters.CylinderHigh);
+ DicConsole.DebugWriteLine("Device-Info command", "CYLLOW = 0x{0:X2}",
+ errorRegisters.CylinderLow);
+ DicConsole.DebugWriteLine("Device-Info command", "DEVICE = 0x{0:X2}",
+ errorRegisters.DeviceHead);
+ DicConsole.DebugWriteLine("Device-Info command", "Error code = {0}", dev.LastError);
+ break;
+ }
+
+ AtaIdentify = ataBuf;
+
+ dev.EnableMediaCardPassThrough(out errorRegisters, dev.Timeout, out _);
+
+ if(errorRegisters.Sector == 0xAA && errorRegisters.SectorCount == 0x55)
+ AtaMcptError = errorRegisters;
+
+ break;
+ }
+ case DeviceType.ATAPI:
+ {
+ bool sense = dev.AtapiIdentify(out byte[] ataBuf, out AtaErrorRegistersChs errorRegisters);
+
+ if(sense)
+ {
+ DicConsole.DebugWriteLine("Device-Info command", "STATUS = 0x{0:X2}", errorRegisters.Status);
+ DicConsole.DebugWriteLine("Device-Info command", "ERROR = 0x{0:X2}", errorRegisters.Error);
+ DicConsole.DebugWriteLine("Device-Info command", "NSECTOR = 0x{0:X2}",
+ errorRegisters.SectorCount);
+ DicConsole.DebugWriteLine("Device-Info command", "SECTOR = 0x{0:X2}", errorRegisters.Sector);
+ DicConsole.DebugWriteLine("Device-Info command", "CYLHIGH = 0x{0:X2}",
+ errorRegisters.CylinderHigh);
+ DicConsole.DebugWriteLine("Device-Info command", "CYLLOW = 0x{0:X2}",
+ errorRegisters.CylinderLow);
+ DicConsole.DebugWriteLine("Device-Info command", "DEVICE = 0x{0:X2}",
+ errorRegisters.DeviceHead);
+ DicConsole.DebugWriteLine("Device-Info command", "Error code = {0}", dev.LastError);
+ break;
+ }
+
+ AtapiIdentify = ataBuf;
+
+ // ATAPI devices are also SCSI devices
+ goto case DeviceType.SCSI;
+ }
+ case DeviceType.SCSI:
+ {
+ bool sense = dev.ScsiInquiry(out byte[] inqBuf, out byte[] senseBuf);
+
+ if(sense)
+ {
+ DicConsole.ErrorWriteLine("SCSI error:\n{0}", Sense.PrettifySense(senseBuf));
+ break;
+ }
+
+ ScsiInquiryData = inqBuf;
+ ScsiInquiry = Inquiry.Decode(inqBuf);
+
+ sense = dev.ScsiInquiry(out inqBuf, out senseBuf, 0x00);
+
+ if(!sense)
+ {
+ ScsiEvpdPages = new Dictionary();
+
+ byte[] pages = EVPD.DecodePage00(inqBuf);
+
+ if(pages != null)
+ foreach(byte page in pages)
+ {
+ sense = dev.ScsiInquiry(out inqBuf, out senseBuf, page);
+ if(sense) continue;
+
+ ScsiEvpdPages.Add(page, inqBuf);
+ }
+ }
+
+ PeripheralDeviceTypes devType = (PeripheralDeviceTypes)ScsiInquiry.Value.PeripheralDeviceType;
+
+ sense = dev.ModeSense10(out byte[] modeBuf, out senseBuf, false, true,
+ ScsiModeSensePageControl.Current, 0x3F, 0xFF, 5, out _);
+
+ if(!sense && !dev.Error) ScsiModeSense10 = modeBuf;
+
+ if(sense || dev.Error)
+ {
+ sense = dev.ModeSense10(out modeBuf, out senseBuf, false, true,
+ ScsiModeSensePageControl.Current, 0x3F, 0x00, 5, out _);
+ if(!sense && !dev.Error) ScsiModeSense10 = modeBuf;
+ }
+
+ if(!sense && !dev.Error) ScsiMode = Modes.DecodeMode10(modeBuf, devType);
+
+ bool useMode10 = !(sense || dev.Error || !ScsiMode.HasValue);
+
+ sense = dev.ModeSense6(out modeBuf, out senseBuf, false, ScsiModeSensePageControl.Current, 0x3F,
+ 0xFF, 5, out _);
+
+ if(!sense && !dev.Error) ScsiModeSense6 = modeBuf;
+
+ if(sense || dev.Error)
+ {
+ sense = dev.ModeSense6(out modeBuf, out senseBuf, false, ScsiModeSensePageControl.Current, 0x3F,
+ 0x00, 5, out _);
+
+ if(!sense && !dev.Error) ScsiModeSense6 = modeBuf;
+ }
+
+ if(sense || dev.Error)
+ {
+ sense = dev.ModeSense(out modeBuf, out senseBuf, 5, out _);
+ if(!sense && !dev.Error) ScsiModeSense6 = modeBuf;
+ }
+
+ if(!sense && !dev.Error && !useMode10) ScsiMode = Modes.DecodeMode6(modeBuf, devType);
+
+ switch(devType)
+ {
+ case PeripheralDeviceTypes.MultiMediaDevice:
+ {
+ sense = dev.GetConfiguration(out byte[] confBuf, out senseBuf, dev.Timeout, out _);
+
+ if(!sense) MmcConfiguration = confBuf;
+
+ // TODO: DVD drives respond correctly to BD status.
+ // While specification says if no medium is present
+ // it should inform all possible capabilities,
+ // testing drives show only supported media capabilities.
+ /*
+ byte[] strBuf;
+ sense = dev.ReadDiscStructure(out strBuf, out senseBuf, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.CapabilityList, 0, dev.Timeout, out _);
+
+ if (!sense)
+ {
+ Decoders.SCSI.DiscStructureCapabilities.Capability[] caps = Decoders.SCSI.DiscStructureCapabilities.Decode(strBuf);
+ if (caps != null)
+ {
+ foreach (Decoders.SCSI.DiscStructureCapabilities.Capability cap in caps)
+ {
+ if (cap.SDS && cap.RDS)
+ DicConsole.WriteLine("Drive can READ/SEND DISC STRUCTURE format {0:X2}h", cap.FormatCode);
+ else if (cap.SDS)
+ DicConsole.WriteLine("Drive can SEND DISC STRUCTURE format {0:X2}h", cap.FormatCode);
+ else if (cap.RDS)
+ DicConsole.WriteLine("Drive can READ DISC STRUCTURE format {0:X2}h", cap.FormatCode);
+ }
+ }
+ }
+
+ sense = dev.ReadDiscStructure(out strBuf, out senseBuf, MmcDiscStructureMediaType.BD, 0, 0, MmcDiscStructureFormat.CapabilityList, 0, dev.Timeout, out _);
+
+ if (!sense)
+ {
+ Decoders.SCSI.DiscStructureCapabilities.Capability[] caps = Decoders.SCSI.DiscStructureCapabilities.Decode(strBuf);
+ if (caps != null)
+ {
+ foreach (Decoders.SCSI.DiscStructureCapabilities.Capability cap in caps)
+ {
+ if (cap.SDS && cap.RDS)
+ DicConsole.WriteLine("Drive can READ/SEND DISC STRUCTURE format {0:X2}h", cap.FormatCode);
+ else if (cap.SDS)
+ DicConsole.WriteLine("Drive can SEND DISC STRUCTURE format {0:X2}h", cap.FormatCode);
+ else if (cap.RDS)
+ DicConsole.WriteLine("Drive can READ DISC STRUCTURE format {0:X2}h", cap.FormatCode);
+ }
+ }
+ }
+ */
+
+ #region Plextor
+ if(dev.Manufacturer == "PLEXTOR")
+ {
+ bool plxtSense = true;
+ bool plxtDvd = false;
+ byte[] plxtBuf = null;
+
+ switch(dev.Model)
+ {
+ case "DVDR PX-708A":
+ case "DVDR PX-708A2":
+ case "DVDR PX-712A":
+ plxtDvd = true;
+ plxtSense = dev.PlextorReadEeprom(out plxtBuf, out senseBuf, dev.Timeout,
+ out _);
+ break;
+ case "DVDR PX-714A":
+ case "DVDR PX-716A":
+ case "DVDR PX-716AL":
+ case "DVDR PX-755A":
+ case "DVDR PX-760A":
+ {
+ plxtBuf = new byte[256 * 4];
+ for(byte i = 0; i < 4; i++)
+ {
+ plxtSense = dev.PlextorReadEepromBlock(out byte[] plxtBufSmall,
+ out senseBuf, i, 256, dev.Timeout,
+ out _);
+ if(plxtSense) break;
+
+ Array.Copy(plxtBufSmall, 0, plxtBuf, i * 256, 256);
+ }
+
+ plxtDvd = true;
+ break;
+ }
+ default:
+ {
+ if(dev.Model.StartsWith("CD-R ", StringComparison.Ordinal))
+ plxtSense = dev.PlextorReadEepromCdr(out plxtBuf, out senseBuf, dev.Timeout,
+ out _);
+ break;
+ }
+ }
+
+ PlextorFeatures = new Plextor {IsDvd = plxtDvd};
+
+ if(!plxtSense)
+ {
+ PlextorFeatures.Eeprom = plxtBuf;
+
+ BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian;
+ if(plxtDvd)
+ {
+ PlextorFeatures.Discs = BigEndianBitConverter.ToUInt16(plxtBuf, 0x0120);
+ PlextorFeatures.CdReadTime = BigEndianBitConverter.ToUInt32(plxtBuf, 0x0122);
+ PlextorFeatures.CdWriteTime = BigEndianBitConverter.ToUInt32(plxtBuf, 0x0126);
+ PlextorFeatures.DvdReadTime = BigEndianBitConverter.ToUInt32(plxtBuf, 0x012A);
+ PlextorFeatures.DvdWriteTime = BigEndianBitConverter.ToUInt32(plxtBuf, 0x012E);
+ }
+ else
+ {
+ PlextorFeatures.Discs = BigEndianBitConverter.ToUInt16(plxtBuf, 0x0078);
+ PlextorFeatures.CdReadTime = BigEndianBitConverter.ToUInt32(plxtBuf, 0x006C);
+ PlextorFeatures.CdWriteTime = BigEndianBitConverter.ToUInt32(plxtBuf, 0x007A);
+ }
+ }
+
+ plxtSense = dev.PlextorGetPoweRec(out senseBuf, out bool plxtPwrRecEnabled,
+ out ushort plxtPwrRecSpeed, dev.Timeout, out _);
+ if(!plxtSense)
+ {
+ PlextorFeatures.PoweRec = true;
+
+ if(plxtPwrRecEnabled)
+ {
+ PlextorFeatures.PoweRecEnabled = true;
+ PlextorFeatures.PoweRecRecommendedSpeed = plxtPwrRecSpeed;
+
+ plxtSense = dev.PlextorGetSpeeds(out senseBuf, out ushort plxtPwrRecSelected,
+ out ushort plxtPwrRecMax,
+ out ushort plxtPwrRecLast, dev.Timeout, out _);
+
+ if(!plxtSense)
+ {
+ PlextorFeatures.PoweRecSelected = plxtPwrRecSelected;
+ PlextorFeatures.PoweRecMax = plxtPwrRecMax;
+ PlextorFeatures.PoweRecLast = plxtPwrRecLast;
+ }
+ }
+ }
+
+ // TODO: Check it with a drive
+ plxtSense = dev.PlextorGetSilentMode(out plxtBuf, out senseBuf, dev.Timeout, out _);
+ if(!plxtSense)
+ if(plxtBuf[0] == 1)
+ {
+ PlextorFeatures.SilentModeEnabled = true;
+ PlextorFeatures.AccessTimeLimit = plxtBuf[1];
+
+ PlextorFeatures.CdReadSpeedLimit = plxtBuf[2];
+ PlextorFeatures.DvdReadSpeedLimit = plxtBuf[3];
+ PlextorFeatures.CdWriteSpeedLimit = plxtBuf[4];
+
+ // TODO: Check which one is each one
+ /*
+ if(plxtBuf[6] > 0)
+ DicConsole.WriteLine("\tTray eject speed limited to {0}",
+ -(plxtBuf[6] + 48));
+ if(plxtBuf[7] > 0)
+ DicConsole.WriteLine("\tTray eject speed limited to {0}",
+ plxtBuf[7] - 47);
+ */
+ }
+
+ plxtSense = dev.PlextorGetGigaRec(out plxtBuf, out senseBuf, dev.Timeout, out _);
+ if(!plxtSense) PlextorFeatures.GigaRec = true;
+
+ plxtSense = dev.PlextorGetSecuRec(out plxtBuf, out senseBuf, dev.Timeout, out _);
+ if(!plxtSense) PlextorFeatures.SecuRec = true;
+
+ plxtSense = dev.PlextorGetSpeedRead(out plxtBuf, out senseBuf, dev.Timeout, out _);
+ if(!plxtSense)
+ {
+ PlextorFeatures.SpeedRead = true;
+ if((plxtBuf[2] & 0x01) == 0x01) PlextorFeatures.SpeedReadEnabled = true;
+ }
+
+ plxtSense = dev.PlextorGetHiding(out plxtBuf, out senseBuf, dev.Timeout, out _);
+ if(!plxtSense)
+ {
+ PlextorFeatures.Hiding = true;
+ if((plxtBuf[2] & 0x02) == 0x02) PlextorFeatures.HidesRecordables = true;
+ if((plxtBuf[2] & 0x01) == 0x01) PlextorFeatures.HidesSessions = true;
+ }
+
+ plxtSense = dev.PlextorGetVariRec(out plxtBuf, out senseBuf, false, dev.Timeout, out _);
+ if(!plxtSense) PlextorFeatures.VariRec = true;
+
+ if(plxtDvd)
+ {
+ plxtSense = dev.PlextorGetVariRec(out plxtBuf, out senseBuf, true, dev.Timeout,
+ out _);
+ if(!plxtSense) PlextorFeatures.VariRecDvd = true;
+
+ plxtSense = dev.PlextorGetBitsetting(out plxtBuf, out senseBuf, false, dev.Timeout,
+ out _);
+ if(!plxtSense) PlextorFeatures.BitSetting = true;
+ plxtSense = dev.PlextorGetBitsetting(out plxtBuf, out senseBuf, true, dev.Timeout,
+ out _);
+ if(!plxtSense) PlextorFeatures.BitSettingDl = true;
+ plxtSense = dev.PlextorGetTestWriteDvdPlus(out plxtBuf, out senseBuf, dev.Timeout,
+ out _);
+ if(!plxtSense) PlextorFeatures.DvdPlusWriteTest = true;
+ }
+ }
+ #endregion Plextor
+
+ if(ScsiInquiry.Value.KreonPresent)
+ if(!dev.KreonGetFeatureList(out senseBuf, out KreonFeatures krFeatures, dev.Timeout,
+ out _))
+ KreonFeatures = krFeatures;
+ break;
+ }
+ case PeripheralDeviceTypes.SequentialAccess:
+ {
+ sense = dev.ReadBlockLimits(out byte[] seqBuf, out senseBuf, dev.Timeout, out _);
+ if(sense)
+ DicConsole.ErrorWriteLine("READ BLOCK LIMITS:\n{0}", Sense.PrettifySense(senseBuf));
+ else BlockLimits = seqBuf;
+
+ sense = dev.ReportDensitySupport(out seqBuf, out senseBuf, dev.Timeout, out _);
+ if(sense)
+ DicConsole.ErrorWriteLine("REPORT DENSITY SUPPORT:\n{0}",
+ Sense.PrettifySense(senseBuf));
+ else
+ {
+ DensitySupport = seqBuf;
+ DensitySupportHeader = Decoders.SCSI.SSC.DensitySupport.DecodeDensity(seqBuf);
+ }
+
+ sense = dev.ReportDensitySupport(out seqBuf, out senseBuf, true, false, dev.Timeout, out _);
+ if(sense)
+ DicConsole.ErrorWriteLine("REPORT DENSITY SUPPORT (MEDIUM):\n{0}",
+ Sense.PrettifySense(senseBuf));
+ else
+ {
+ MediumDensitySupport = seqBuf;
+ MediaTypeSupportHeader = Decoders.SCSI.SSC.DensitySupport.DecodeMediumType(seqBuf);
+ }
+
+ break;
+ }
+ }
+
+ break;
+ }
+ case DeviceType.MMC:
+ {
+ bool sense = dev.ReadCid(out byte[] mmcBuf, out _, dev.Timeout, out _);
+ if(!sense) CID = mmcBuf;
+
+ sense = dev.ReadCsd(out mmcBuf, out _, dev.Timeout, out _);
+ if(!sense) CSD = mmcBuf;
+
+ sense = dev.ReadOcr(out mmcBuf, out _, dev.Timeout, out _);
+ if(!sense) OCR = mmcBuf;
+
+ sense = dev.ReadExtendedCsd(out mmcBuf, out _, dev.Timeout, out _);
+ if(!sense) ExtendedCSD = mmcBuf;
+ }
+ break;
+ case DeviceType.SecureDigital:
+ {
+ bool sense = dev.ReadCid(out byte[] sdBuf, out _, dev.Timeout, out _);
+ if(!sense) CID = sdBuf;
+
+ sense = dev.ReadCsd(out sdBuf, out _, dev.Timeout, out _);
+ if(!sense) CSD = sdBuf;
+
+ sense = dev.ReadSdocr(out sdBuf, out _, dev.Timeout, out _);
+ if(!sense) OCR = sdBuf;
+
+ sense = dev.ReadScr(out sdBuf, out _, dev.Timeout, out _);
+ if(!sense) SCR = sdBuf;
+ }
+ break;
+ default:
+ DicConsole.ErrorWriteLine("Unknown device type {0}, cannot get information.", dev.Type);
+ break;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/DiscImageChef.Core/Devices/Info/Plextor.cs b/DiscImageChef.Core/Devices/Info/Plextor.cs
new file mode 100644
index 000000000..6ed3a7a73
--- /dev/null
+++ b/DiscImageChef.Core/Devices/Info/Plextor.cs
@@ -0,0 +1,69 @@
+// /***************************************************************************
+// The Disc Image Chef
+// ----------------------------------------------------------------------------
+//
+// Filename : Plextor.cs
+// Author(s) : Natalia Portillo
+//
+// Component : Core.
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Structures for Plextor features.
+//
+// --[ License ] --------------------------------------------------------------
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2018 Natalia Portillo
+// ****************************************************************************/
+
+namespace DiscImageChef.Core.Devices.Info
+{
+ public class Plextor
+ {
+ public byte AccessTimeLimit;
+ public bool BitSetting;
+ public bool BitSettingDl;
+ public byte CdReadSpeedLimit;
+ public uint CdReadTime;
+ public byte CdWriteSpeedLimit;
+ public uint CdWriteTime;
+ public ushort Discs;
+ public bool DvdPlusWriteTest;
+ public byte DvdReadSpeedLimit;
+ public uint DvdReadTime;
+ public uint DvdWriteTime;
+ public byte[] Eeprom;
+ public bool GigaRec;
+ public bool HidesRecordables;
+ public bool HidesSessions;
+ public bool Hiding;
+ public bool IsDvd;
+ public ushort PoweRecLast;
+ public ushort PoweRecMax;
+ public ushort PoweRecSelected;
+ public bool PoweRec;
+ public bool PoweRecEnabled;
+ public ushort PoweRecRecommendedSpeed;
+ public bool SecuRec;
+ public bool SilentMode;
+ public bool SilentModeEnabled;
+ public bool SpeedRead;
+ public bool SpeedReadEnabled;
+ public bool VariRec;
+ public bool VariRecDvd;
+ }
+}
\ No newline at end of file
diff --git a/DiscImageChef.Core/Devices/Info/Properties.cs b/DiscImageChef.Core/Devices/Info/Properties.cs
new file mode 100644
index 000000000..1c9728783
--- /dev/null
+++ b/DiscImageChef.Core/Devices/Info/Properties.cs
@@ -0,0 +1,66 @@
+// /***************************************************************************
+// The Disc Image Chef
+// ----------------------------------------------------------------------------
+//
+// Filename : Properties.cs
+// Author(s) : Natalia Portillo
+//
+// Component : Core.
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Contains the device info properties.
+//
+// --[ License ] --------------------------------------------------------------
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2018 Natalia Portillo
+// ****************************************************************************/
+
+using System.Collections.Generic;
+using DiscImageChef.Decoders.ATA;
+using DiscImageChef.Decoders.SCSI;
+using DiscImageChef.Decoders.SCSI.SSC;
+using DiscImageChef.Devices;
+
+namespace DiscImageChef.Core.Devices.Info
+{
+ public partial class DeviceInfo
+ {
+ public byte[] AtaIdentify { get; }
+ public byte[] AtapiIdentify { get; }
+ public byte[] ScsiInquiryData { get; }
+ public Inquiry.SCSIInquiry? ScsiInquiry { get; }
+ public AtaErrorRegistersChs? AtaMcptError { get; }
+ public Dictionary ScsiEvpdPages { get; }
+ public Modes.DecodedMode? ScsiMode { get; }
+ public byte[] ScsiModeSense6 { get; }
+ public byte[] ScsiModeSense10 { get; }
+ public byte[] MmcConfiguration { get; }
+ public Plextor PlextorFeatures { get; }
+ public KreonFeatures KreonFeatures { get; }
+ public byte[] BlockLimits { get; }
+ public byte[] DensitySupport { get; }
+ public DensitySupport.DensitySupportHeader? DensitySupportHeader { get; }
+ public byte[] MediumDensitySupport { get; }
+ public DensitySupport.MediaTypeSupportHeader? MediaTypeSupportHeader { get; }
+ public byte[] CID { get; }
+ public byte[] CSD { get; }
+ public byte[] ExtendedCSD { get; }
+ public byte[] SCR { get; }
+ public byte[] OCR { get; }
+ }
+}
\ No newline at end of file
diff --git a/DiscImageChef.Core/DiscImageChef.Core.csproj b/DiscImageChef.Core/DiscImageChef.Core.csproj
index 19f4bb458..9c61bda4a 100644
--- a/DiscImageChef.Core/DiscImageChef.Core.csproj
+++ b/DiscImageChef.Core/DiscImageChef.Core.csproj
@@ -46,6 +46,9 @@
+
+
+
diff --git a/DiscImageChef/Commands/DeviceInfo.cs b/DiscImageChef/Commands/DeviceInfo.cs
index 31ec565a0..30b1517dc 100644
--- a/DiscImageChef/Commands/DeviceInfo.cs
+++ b/DiscImageChef/Commands/DeviceInfo.cs
@@ -30,7 +30,7 @@
// Copyright © 2011-2018 Natalia Portillo
// ****************************************************************************/
-using System;
+using System.Collections.Generic;
using DiscImageChef.Console;
using DiscImageChef.Core;
using DiscImageChef.Decoders.ATA;
@@ -39,7 +39,6 @@ using DiscImageChef.Decoders.SCSI;
using DiscImageChef.Decoders.SCSI.MMC;
using DiscImageChef.Decoders.SCSI.SSC;
using DiscImageChef.Devices;
-using Tuple = DiscImageChef.Decoders.PCMCIA.Tuple;
namespace DiscImageChef.Commands
{
@@ -156,993 +155,690 @@ namespace DiscImageChef.Commands
else DicConsole.DebugWriteLine("Device-Info command", "Could not get tuples");
}
+ Core.Devices.Info.DeviceInfo devInfo = new Core.Devices.Info.DeviceInfo(dev);
+
+ if(devInfo.AtaIdentify != null)
+ {
+ DataFile.WriteTo("Device-Info command", options.OutputPrefix, "_ata_identify.bin", "ATA IDENTIFY",
+ devInfo.AtaIdentify);
+
+ DicConsole.WriteLine(Identify.Prettify(devInfo.AtaIdentify));
+
+ if(devInfo.AtaMcptError.HasValue)
+ {
+ DicConsole.WriteLine("Device supports the Media Card Pass Through Command Set");
+ switch(devInfo.AtaMcptError.Value.DeviceHead & 0x7)
+ {
+ case 0:
+ DicConsole.WriteLine("Device reports incorrect media card type");
+ break;
+ case 1:
+ DicConsole.WriteLine("Device contains a Secure Digital card");
+ break;
+ case 2:
+ DicConsole.WriteLine("Device contains a MultiMediaCard ");
+ break;
+ case 3:
+ DicConsole.WriteLine("Device contains a Secure Digital I/O card");
+ break;
+ case 4:
+ DicConsole.WriteLine("Device contains a Smart Media card");
+ break;
+ default:
+ DicConsole.WriteLine("Device contains unknown media card type {0}",
+ devInfo.AtaMcptError.Value.DeviceHead & 0x07);
+ break;
+ }
+
+ if((devInfo.AtaMcptError.Value.DeviceHead & 0x08) == 0x08)
+ DicConsole.WriteLine("Media card is write protected");
+
+ ushort specificData = (ushort)(devInfo.AtaMcptError.Value.CylinderHigh * 0x100 +
+ devInfo.AtaMcptError.Value.CylinderLow);
+ if(specificData != 0) DicConsole.WriteLine("Card specific data: 0x{0:X4}", specificData);
+ }
+ }
+
+ if(devInfo.AtapiIdentify != null)
+ {
+ DataFile.WriteTo("Device-Info command", options.OutputPrefix, "_atapi_identify.bin", "ATAPI IDENTIFY",
+ devInfo.AtapiIdentify);
+
+ DicConsole.WriteLine(Identify.Prettify(devInfo.AtapiIdentify));
+ }
+
+ if(devInfo.ScsiInquiry != null)
+ {
+ if(dev.Type != DeviceType.ATAPI) DicConsole.WriteLine("SCSI device");
+
+ DataFile.WriteTo("Device-Info command", options.OutputPrefix, "_scsi_inquiry.bin", "SCSI INQUIRY",
+ devInfo.ScsiInquiryData);
+
+ DicConsole.WriteLine(Inquiry.Prettify(devInfo.ScsiInquiry));
+
+ if(devInfo.ScsiEvpdPages != null)
+ foreach(KeyValuePair page in devInfo.ScsiEvpdPages)
+ if(page.Key >= 0x01 && page.Key <= 0x7F)
+ {
+ DicConsole.WriteLine("ASCII Page {0:X2}h: {1}", page, EVPD.DecodeASCIIPage(page.Value));
+
+ DataFile.WriteTo("Device-Info command", options.OutputPrefix, page.Value);
+ }
+ else if(page.Key == 0x80)
+ {
+ DicConsole.WriteLine("Unit Serial Number: {0}", EVPD.DecodePage80(page.Value));
+ DataFile.WriteTo("Device-Info command", options.OutputPrefix,
+ $"_scsi_evpd_{page.Key:X2}h.bin", $"SCSI INQUIRY EVPD {page.Key:X2}h",
+ page.Value);
+ }
+ else if(page.Key == 0x81)
+ {
+ DicConsole.WriteLine("{0}", EVPD.PrettifyPage_81(page.Value));
+ DataFile.WriteTo("Device-Info command", options.OutputPrefix,
+ $"_scsi_evpd_{page.Key:X2}h.bin", $"SCSI INQUIRY EVPD {page.Key:X2}h",
+ page.Value);
+ }
+ else if(page.Key == 0x82)
+ {
+ DicConsole.WriteLine("ASCII implemented operating definitions: {0}",
+ EVPD.DecodePage82(page.Value));
+ DataFile.WriteTo("Device-Info command", options.OutputPrefix,
+ $"_scsi_evpd_{page.Key:X2}h.bin", $"SCSI INQUIRY EVPD {page.Key:X2}h",
+ page.Value);
+ }
+ else if(page.Key == 0x83)
+ {
+ DicConsole.WriteLine("{0}", EVPD.PrettifyPage_83(page.Value));
+ DataFile.WriteTo("Device-Info command", options.OutputPrefix,
+ $"_scsi_evpd_{page.Key:X2}h.bin", $"SCSI INQUIRY EVPD {page.Key:X2}h",
+ page.Value);
+ }
+ else if(page.Key == 0x84)
+ {
+ DicConsole.WriteLine("{0}", EVPD.PrettifyPage_84(page.Value));
+ DataFile.WriteTo("Device-Info command", options.OutputPrefix,
+ $"_scsi_evpd_{page.Key:X2}h.bin", $"SCSI INQUIRY EVPD {page.Key:X2}h",
+ page.Value);
+ }
+ else if(page.Key == 0x85)
+ {
+ DicConsole.WriteLine("{0}", EVPD.PrettifyPage_85(page.Value));
+ DataFile.WriteTo("Device-Info command", options.OutputPrefix,
+ $"_scsi_evpd_{page.Key:X2}h.bin", $"SCSI INQUIRY EVPD {page.Key:X2}h",
+ page.Value);
+ }
+ else if(page.Key == 0x86)
+ {
+ DicConsole.WriteLine("{0}", EVPD.PrettifyPage_86(page.Value));
+ DataFile.WriteTo("Device-Info command", options.OutputPrefix,
+ $"_scsi_evpd_{page.Key:X2}h.bin", $"SCSI INQUIRY EVPD {page.Key:X2}h",
+ page.Value);
+ }
+ else if(page.Key == 0x89)
+ {
+ DicConsole.WriteLine("{0}", EVPD.PrettifyPage_89(page.Value));
+ DataFile.WriteTo("Device-Info command", options.OutputPrefix,
+ $"_scsi_evpd_{page.Key:X2}h.bin", $"SCSI INQUIRY EVPD {page.Key:X2}h",
+ page.Value);
+ }
+ else if(page.Key == 0xB0)
+ {
+ DicConsole.WriteLine("{0}", EVPD.PrettifyPage_B0(page.Value));
+ DataFile.WriteTo("Device-Info command", options.OutputPrefix,
+ $"_scsi_evpd_{page.Key:X2}h.bin", $"SCSI INQUIRY EVPD {page.Key:X2}h",
+ page.Value);
+ }
+ else if(page.Key == 0xB1)
+ {
+ DicConsole.WriteLine("Manufacturer-assigned Serial Number: {0}",
+ EVPD.DecodePageB1(page.Value));
+ DataFile.WriteTo("Device-Info command", options.OutputPrefix,
+ $"_scsi_evpd_{page.Key:X2}h.bin", $"SCSI INQUIRY EVPD {page.Key:X2}h",
+ page.Value);
+ }
+ else if(page.Key == 0xB2)
+ {
+ DicConsole.WriteLine("TapeAlert Supported Flags Bitmap: 0x{0:X16}",
+ EVPD.DecodePageB2(page.Value));
+ DataFile.WriteTo("Device-Info command", options.OutputPrefix,
+ $"_scsi_evpd_{page.Key:X2}h.bin", $"SCSI INQUIRY EVPD {page.Key:X2}h",
+ page.Value);
+ }
+ else if(page.Key == 0xB3)
+ {
+ DicConsole.WriteLine("Automation Device Serial Number: {0}", EVPD.DecodePageB3(page.Value));
+ DataFile.WriteTo("Device-Info command", options.OutputPrefix,
+ $"_scsi_evpd_{page.Key:X2}h.bin", $"SCSI INQUIRY EVPD {page.Key:X2}h",
+ page.Value);
+ }
+ else if(page.Key == 0xB4)
+ {
+ DicConsole.WriteLine("Data Transfer Device Element Address: 0x{0}",
+ EVPD.DecodePageB4(page.Value));
+ DataFile.WriteTo("Device-Info command", options.OutputPrefix,
+ $"_scsi_evpd_{page.Key:X2}h.bin", $"SCSI INQUIRY EVPD {page.Key:X2}h",
+ page.Value);
+ }
+ else if(page.Key == 0xC0 &&
+ StringHandlers.CToString(devInfo.ScsiInquiry.Value.VendorIdentification)
+ .ToLowerInvariant().Trim() == "quantum")
+ {
+ DicConsole.WriteLine("{0}", EVPD.PrettifyPage_C0_Quantum(page.Value));
+ DataFile.WriteTo("Device-Info command", options.OutputPrefix,
+ $"_scsi_evpd_{page.Key:X2}h.bin", $"SCSI INQUIRY EVPD {page.Key:X2}h",
+ page.Value);
+ }
+ else if(page.Key == 0xC0 &&
+ StringHandlers.CToString(devInfo.ScsiInquiry.Value.VendorIdentification)
+ .ToLowerInvariant().Trim() == "seagate")
+ {
+ DicConsole.WriteLine("{0}", EVPD.PrettifyPage_C0_Seagate(page.Value));
+ DataFile.WriteTo("Device-Info command", options.OutputPrefix,
+ $"_scsi_evpd_{page.Key:X2}h.bin", $"SCSI INQUIRY EVPD {page.Key:X2}h",
+ page.Value);
+ }
+ else if(page.Key == 0xC0 &&
+ StringHandlers.CToString(devInfo.ScsiInquiry.Value.VendorIdentification)
+ .ToLowerInvariant().Trim() == "ibm")
+ {
+ DicConsole.WriteLine("{0}", EVPD.PrettifyPage_C0_IBM(page.Value));
+ DataFile.WriteTo("Device-Info command", options.OutputPrefix,
+ $"_scsi_evpd_{page.Key:X2}h.bin", $"SCSI INQUIRY EVPD {page.Key:X2}h",
+ page.Value);
+ }
+ else if(page.Key == 0xC1 &&
+ StringHandlers.CToString(devInfo.ScsiInquiry.Value.VendorIdentification)
+ .ToLowerInvariant().Trim() == "ibm")
+ {
+ DicConsole.WriteLine("{0}", EVPD.PrettifyPage_C1_IBM(page.Value));
+ DataFile.WriteTo("Device-Info command", options.OutputPrefix,
+ $"_scsi_evpd_{page.Key:X2}h.bin", $"SCSI INQUIRY EVPD {page.Key:X2}h",
+ page.Value);
+ }
+ else if((page.Key == 0xC0 || page.Key == 0xC1) &&
+ StringHandlers.CToString(devInfo.ScsiInquiry.Value.VendorIdentification)
+ .ToLowerInvariant().Trim() == "certance")
+ {
+ DicConsole.WriteLine("{0}", EVPD.PrettifyPage_C0_C1_Certance(page.Value));
+ DataFile.WriteTo("Device-Info command", options.OutputPrefix,
+ $"_scsi_evpd_{page.Key:X2}h.bin", $"SCSI INQUIRY EVPD {page.Key:X2}h",
+ page.Value);
+ }
+ else if((page.Key == 0xC2 || page.Key == 0xC3 || page.Key == 0xC4 || page.Key == 0xC5 ||
+ page.Key == 0xC6) &&
+ StringHandlers.CToString(devInfo.ScsiInquiry.Value.VendorIdentification)
+ .ToLowerInvariant().Trim() == "certance")
+ {
+ DicConsole.WriteLine("{0}", EVPD.PrettifyPage_C2_C3_C4_C5_C6_Certance(page.Value));
+ DataFile.WriteTo("Device-Info command", options.OutputPrefix,
+ $"_scsi_evpd_{page.Key:X2}h.bin", $"SCSI INQUIRY EVPD {page.Key:X2}h",
+ page.Value);
+ }
+ else if((page.Key == 0xC0 || page.Key == 0xC1 || page.Key == 0xC2 || page.Key == 0xC3 ||
+ page.Key == 0xC4 || page.Key == 0xC5) && StringHandlers
+ .CToString(devInfo.ScsiInquiry.Value
+ .VendorIdentification)
+ .ToLowerInvariant().Trim() == "hp")
+ {
+ DicConsole.WriteLine("{0}", EVPD.PrettifyPage_C0_to_C5_HP(page.Value));
+ DataFile.WriteTo("Device-Info command", options.OutputPrefix,
+ $"_scsi_evpd_{page.Key:X2}h.bin", $"SCSI INQUIRY EVPD {page.Key:X2}h",
+ page.Value);
+ }
+ else if(page.Key == 0xDF &&
+ StringHandlers.CToString(devInfo.ScsiInquiry.Value.VendorIdentification)
+ .ToLowerInvariant().Trim() == "certance")
+ {
+ DicConsole.WriteLine("{0}", EVPD.PrettifyPage_DF_Certance(page.Value));
+ DataFile.WriteTo("Device-Info command", options.OutputPrefix,
+ $"_scsi_evpd_{page.Key:X2}h.bin", $"SCSI INQUIRY EVPD {page.Key:X2}h",
+ page.Value);
+ }
+ else
+ {
+ if(page.Key == 0x00) continue;
+
+ DicConsole.DebugWriteLine("Device-Info command", "Found undecoded SCSI VPD page 0x{0:X2}",
+ page);
+
+ DataFile.WriteTo("Device-Info command", options.OutputPrefix,
+ $"_scsi_evpd_{page.Key:X2}h.bin", $"SCSI INQUIRY EVPD {page.Key:X2}h",
+ page.Value);
+ }
+
+ if(devInfo.ScsiModeSense6 != null)
+ DataFile.WriteTo("Device-Info command", options.OutputPrefix, "_scsi_modesense6.bin",
+ "SCSI MODE SENSE", devInfo.ScsiModeSense6);
+
+ if(devInfo.ScsiModeSense10 != null)
+ DataFile.WriteTo("Device-Info command", options.OutputPrefix, "_scsi_modesense10.bin",
+ "SCSI MODE SENSE", devInfo.ScsiModeSense10);
+
+ if(devInfo.ScsiMode.HasValue)
+ PrintScsiModePages.Print(devInfo.ScsiMode.Value,
+ (PeripheralDeviceTypes)devInfo.ScsiInquiry.Value.PeripheralDeviceType,
+ devInfo.ScsiInquiry.Value.VendorIdentification);
+
+ if(devInfo.MmcConfiguration != null)
+ {
+ DataFile.WriteTo("Device-Info command", options.OutputPrefix, "_mmc_getconfiguration.bin",
+ "MMC GET CONFIGURATION", devInfo.MmcConfiguration);
+
+ Features.SeparatedFeatures ftr = Features.Separate(devInfo.MmcConfiguration);
+
+ DicConsole.DebugWriteLine("Device-Info command", "GET CONFIGURATION length is {0} bytes",
+ ftr.DataLength);
+ DicConsole.DebugWriteLine("Device-Info command", "GET CONFIGURATION current profile is {0:X4}h",
+ ftr.CurrentProfile);
+ if(ftr.Descriptors != null)
+ {
+ DicConsole.WriteLine("SCSI MMC GET CONFIGURATION Features:");
+ foreach(Features.FeatureDescriptor desc in ftr.Descriptors)
+ {
+ DicConsole.DebugWriteLine("Device-Info command", "Feature {0:X4}h", desc.Code);
+
+ switch(desc.Code)
+ {
+ case 0x0000:
+ DicConsole.WriteLine(Features.Prettify_0000(desc.Data));
+ break;
+ case 0x0001:
+ DicConsole.WriteLine(Features.Prettify_0001(desc.Data));
+ break;
+ case 0x0002:
+ DicConsole.WriteLine(Features.Prettify_0002(desc.Data));
+ break;
+ case 0x0003:
+ DicConsole.WriteLine(Features.Prettify_0003(desc.Data));
+ break;
+ case 0x0004:
+ DicConsole.WriteLine(Features.Prettify_0004(desc.Data));
+ break;
+ case 0x0010:
+ DicConsole.WriteLine(Features.Prettify_0010(desc.Data));
+ break;
+ case 0x001D:
+ DicConsole.WriteLine(Features.Prettify_001D(desc.Data));
+ break;
+ case 0x001E:
+ DicConsole.WriteLine(Features.Prettify_001E(desc.Data));
+ break;
+ case 0x001F:
+ DicConsole.WriteLine(Features.Prettify_001F(desc.Data));
+ break;
+ case 0x0020:
+ DicConsole.WriteLine(Features.Prettify_0020(desc.Data));
+ break;
+ case 0x0021:
+ DicConsole.WriteLine(Features.Prettify_0021(desc.Data));
+ break;
+ case 0x0022:
+ DicConsole.WriteLine(Features.Prettify_0022(desc.Data));
+ break;
+ case 0x0023:
+ DicConsole.WriteLine(Features.Prettify_0023(desc.Data));
+ break;
+ case 0x0024:
+ DicConsole.WriteLine(Features.Prettify_0024(desc.Data));
+ break;
+ case 0x0025:
+ DicConsole.WriteLine(Features.Prettify_0025(desc.Data));
+ break;
+ case 0x0026:
+ DicConsole.WriteLine(Features.Prettify_0026(desc.Data));
+ break;
+ case 0x0027:
+ DicConsole.WriteLine(Features.Prettify_0027(desc.Data));
+ break;
+ case 0x0028:
+ DicConsole.WriteLine(Features.Prettify_0028(desc.Data));
+ break;
+ case 0x0029:
+ DicConsole.WriteLine(Features.Prettify_0029(desc.Data));
+ break;
+ case 0x002A:
+ DicConsole.WriteLine(Features.Prettify_002A(desc.Data));
+ break;
+ case 0x002B:
+ DicConsole.WriteLine(Features.Prettify_002B(desc.Data));
+ break;
+ case 0x002C:
+ DicConsole.WriteLine(Features.Prettify_002C(desc.Data));
+ break;
+ case 0x002D:
+ DicConsole.WriteLine(Features.Prettify_002D(desc.Data));
+ break;
+ case 0x002E:
+ DicConsole.WriteLine(Features.Prettify_002E(desc.Data));
+ break;
+ case 0x002F:
+ DicConsole.WriteLine(Features.Prettify_002F(desc.Data));
+ break;
+ case 0x0030:
+ DicConsole.WriteLine(Features.Prettify_0030(desc.Data));
+ break;
+ case 0x0031:
+ DicConsole.WriteLine(Features.Prettify_0031(desc.Data));
+ break;
+ case 0x0032:
+ DicConsole.WriteLine(Features.Prettify_0032(desc.Data));
+ break;
+ case 0x0033:
+ DicConsole.WriteLine(Features.Prettify_0033(desc.Data));
+ break;
+ case 0x0035:
+ DicConsole.WriteLine(Features.Prettify_0035(desc.Data));
+ break;
+ case 0x0037:
+ DicConsole.WriteLine(Features.Prettify_0037(desc.Data));
+ break;
+ case 0x0038:
+ DicConsole.WriteLine(Features.Prettify_0038(desc.Data));
+ break;
+ case 0x003A:
+ DicConsole.WriteLine(Features.Prettify_003A(desc.Data));
+ break;
+ case 0x003B:
+ DicConsole.WriteLine(Features.Prettify_003B(desc.Data));
+ break;
+ case 0x0040:
+ DicConsole.WriteLine(Features.Prettify_0040(desc.Data));
+ break;
+ case 0x0041:
+ DicConsole.WriteLine(Features.Prettify_0041(desc.Data));
+ break;
+ case 0x0042:
+ DicConsole.WriteLine(Features.Prettify_0042(desc.Data));
+ break;
+ case 0x0050:
+ DicConsole.WriteLine(Features.Prettify_0050(desc.Data));
+ break;
+ case 0x0051:
+ DicConsole.WriteLine(Features.Prettify_0051(desc.Data));
+ break;
+ case 0x0080:
+ DicConsole.WriteLine(Features.Prettify_0080(desc.Data));
+ break;
+ case 0x0100:
+ DicConsole.WriteLine(Features.Prettify_0100(desc.Data));
+ break;
+ case 0x0101:
+ DicConsole.WriteLine(Features.Prettify_0101(desc.Data));
+ break;
+ case 0x0102:
+ DicConsole.WriteLine(Features.Prettify_0102(desc.Data));
+ break;
+ case 0x0103:
+ DicConsole.WriteLine(Features.Prettify_0103(desc.Data));
+ break;
+ case 0x0104:
+ DicConsole.WriteLine(Features.Prettify_0104(desc.Data));
+ break;
+ case 0x0105:
+ DicConsole.WriteLine(Features.Prettify_0105(desc.Data));
+ break;
+ case 0x0106:
+ DicConsole.WriteLine(Features.Prettify_0106(desc.Data));
+ break;
+ case 0x0107:
+ DicConsole.WriteLine(Features.Prettify_0107(desc.Data));
+ break;
+ case 0x0108:
+ DicConsole.WriteLine(Features.Prettify_0108(desc.Data));
+ break;
+ case 0x0109:
+ DicConsole.WriteLine(Features.Prettify_0109(desc.Data));
+ break;
+ case 0x010A:
+ DicConsole.WriteLine(Features.Prettify_010A(desc.Data));
+ break;
+ case 0x010B:
+ DicConsole.WriteLine(Features.Prettify_010B(desc.Data));
+ break;
+ case 0x010C:
+ DicConsole.WriteLine(Features.Prettify_010C(desc.Data));
+ break;
+ case 0x010D:
+ DicConsole.WriteLine(Features.Prettify_010D(desc.Data));
+ break;
+ case 0x010E:
+ DicConsole.WriteLine(Features.Prettify_010E(desc.Data));
+ break;
+ case 0x0110:
+ DicConsole.WriteLine(Features.Prettify_0110(desc.Data));
+ break;
+ case 0x0113:
+ DicConsole.WriteLine(Features.Prettify_0113(desc.Data));
+ break;
+ case 0x0142:
+ DicConsole.WriteLine(Features.Prettify_0142(desc.Data));
+ break;
+ default:
+ DicConsole.WriteLine("Found unknown feature code {0:X4}h", desc.Code);
+ break;
+ }
+ }
+ }
+ else
+ DicConsole.DebugWriteLine("Device-Info command",
+ "GET CONFIGURATION returned no feature descriptors");
+ }
+
+ if(devInfo.PlextorFeatures != null)
+ {
+ if(devInfo.PlextorFeatures.Eeprom != null)
+ {
+ DataFile.WriteTo("Device-Info command", options.OutputPrefix, "_plextor_eeprom.bin",
+ "PLEXTOR READ EEPROM", devInfo.PlextorFeatures.Eeprom);
+
+ DicConsole.WriteLine("Drive has loaded a total of {0} discs", devInfo.PlextorFeatures.Discs);
+ DicConsole.WriteLine("Drive has spent {0} hours, {1} minutes and {2} seconds reading CDs",
+ devInfo.PlextorFeatures.CdReadTime / 3600,
+ devInfo.PlextorFeatures.CdReadTime / 60 % 60,
+ devInfo.PlextorFeatures.CdReadTime % 60);
+ DicConsole.WriteLine("Drive has spent {0} hours, {1} minutes and {2} seconds writing CDs",
+ devInfo.PlextorFeatures.CdWriteTime / 3600,
+ devInfo.PlextorFeatures.CdWriteTime / 60 % 60,
+ devInfo.PlextorFeatures.CdWriteTime % 60);
+ if(devInfo.PlextorFeatures.IsDvd)
+ {
+ DicConsole.WriteLine("Drive has spent {0} hours, {1} minutes and {2} seconds reading DVDs",
+ devInfo.PlextorFeatures.DvdReadTime / 3600,
+ devInfo.PlextorFeatures.DvdReadTime / 60 % 60,
+ devInfo.PlextorFeatures.DvdReadTime % 60);
+ DicConsole.WriteLine("Drive has spent {0} hours, {1} minutes and {2} seconds writing DVDs",
+ devInfo.PlextorFeatures.DvdWriteTime / 3600,
+ devInfo.PlextorFeatures.DvdWriteTime / 60 % 60,
+ devInfo.PlextorFeatures.DvdWriteTime % 60);
+ }
+ }
+
+ if(devInfo.PlextorFeatures.PoweRec)
+ {
+ DicConsole.Write("Drive supports PoweRec");
+
+ if(devInfo.PlextorFeatures.PoweRecEnabled)
+ {
+ DicConsole.Write(", has it enabled");
+
+ if(devInfo.PlextorFeatures.PoweRecRecommendedSpeed > 0)
+ DicConsole.WriteLine(" and recommends {0} Kb/sec.",
+ devInfo.PlextorFeatures.PoweRecRecommendedSpeed);
+ else DicConsole.WriteLine(".");
+
+ if(devInfo.PlextorFeatures.PoweRecSelected > 0)
+ DicConsole
+ .WriteLine("Selected PoweRec speed for currently inserted media is {0} Kb/sec ({1}x)",
+ devInfo.PlextorFeatures.PoweRecSelected,
+ devInfo.PlextorFeatures.PoweRecSelected / 177);
+ if(devInfo.PlextorFeatures.PoweRecMax > 0)
+ DicConsole
+ .WriteLine("Maximum PoweRec speed for currently inserted media is {0} Kb/sec ({1}x)",
+ devInfo.PlextorFeatures.PoweRecMax,
+ devInfo.PlextorFeatures.PoweRecMax / 177);
+ if(devInfo.PlextorFeatures.PoweRecLast > 0)
+ DicConsole.WriteLine("Last used PoweRec was {0} Kb/sec ({1}x)",
+ devInfo.PlextorFeatures.PoweRecLast,
+ devInfo.PlextorFeatures.PoweRecLast / 177);
+ }
+ else
+ {
+ DicConsole.WriteLine(".");
+ DicConsole.WriteLine("PoweRec is disabled");
+ }
+ }
+
+ if(devInfo.PlextorFeatures.SilentMode)
+ {
+ DicConsole.WriteLine("Drive supports Plextor SilentMode");
+ if(devInfo.PlextorFeatures.SilentModeEnabled)
+ {
+ DicConsole.WriteLine("Plextor SilentMode is enabled:");
+ DicConsole.WriteLine(devInfo.PlextorFeatures.AccessTimeLimit == 2
+ ? "\tAccess time is slow"
+ : "\tAccess time is fast");
+
+ if(devInfo.PlextorFeatures.CdReadSpeedLimit > 0)
+ DicConsole.WriteLine("\tCD read speed limited to {0}x",
+ devInfo.PlextorFeatures.CdReadSpeedLimit);
+ if(devInfo.PlextorFeatures.DvdReadSpeedLimit > 0 && devInfo.PlextorFeatures.IsDvd)
+ DicConsole.WriteLine("\tDVD read speed limited to {0}x",
+ devInfo.PlextorFeatures.DvdReadSpeedLimit);
+ if(devInfo.PlextorFeatures.CdWriteSpeedLimit > 0)
+ DicConsole.WriteLine("\tCD write speed limited to {0}x",
+ devInfo.PlextorFeatures.CdWriteSpeedLimit);
+ }
+ }
+
+ if(!devInfo.PlextorFeatures.GigaRec) DicConsole.WriteLine("Drive supports Plextor GigaRec");
+ if(!devInfo.PlextorFeatures.SecuRec) DicConsole.WriteLine("Drive supports Plextor SecuRec");
+ if(!devInfo.PlextorFeatures.SpeedRead)
+ {
+ DicConsole.Write("Drive supports Plextor SpeedRead");
+ if(devInfo.PlextorFeatures.SpeedReadEnabled) DicConsole.WriteLine("and has it enabled");
+ else DicConsole.WriteLine();
+ }
+
+ if(!devInfo.PlextorFeatures.Hiding)
+ {
+ DicConsole.WriteLine("Drive supports hiding CD-Rs and forcing single session");
+
+ if(devInfo.PlextorFeatures.HidesRecordables)
+ DicConsole.WriteLine("Drive currently hides CD-Rs");
+ if(devInfo.PlextorFeatures.HidesSessions)
+ DicConsole.WriteLine("Drive currently forces single session");
+ }
+
+ if(!devInfo.PlextorFeatures.VariRec) DicConsole.WriteLine("Drive supports Plextor VariRec");
+
+ if(devInfo.PlextorFeatures.IsDvd)
+ {
+ if(!devInfo.PlextorFeatures.VariRecDvd)
+ DicConsole.WriteLine("Drive supports Plextor VariRec for DVDs");
+ if(!devInfo.PlextorFeatures.BitSetting)
+ DicConsole.WriteLine("Drive supports bitsetting DVD+R book type");
+ if(!devInfo.PlextorFeatures.BitSettingDl)
+ DicConsole.WriteLine("Drive supports bitsetting DVD+R DL book type");
+ if(!devInfo.PlextorFeatures.DvdPlusWriteTest)
+ DicConsole.WriteLine("Drive supports test writing DVD+");
+ }
+ }
+
+ if(devInfo.ScsiInquiry.Value.KreonPresent)
+ {
+ DicConsole.WriteLine("Drive has kreon firmware:");
+ if(devInfo.KreonFeatures.HasFlag(KreonFeatures.ChallengeResponse))
+ DicConsole.WriteLine("\tCan do challenge/response with Xbox discs");
+ if(devInfo.KreonFeatures.HasFlag(KreonFeatures.DecryptSs))
+ DicConsole.WriteLine("\tCan read and descrypt SS from Xbox discs");
+ if(devInfo.KreonFeatures.HasFlag(KreonFeatures.XtremeUnlock))
+ DicConsole.WriteLine("\tCan set xtreme unlock state with Xbox discs");
+ if(devInfo.KreonFeatures.HasFlag(KreonFeatures.WxripperUnlock))
+ DicConsole.WriteLine("\tCan set wxripper unlock state with Xbox discs");
+ if(devInfo.KreonFeatures.HasFlag(KreonFeatures.ChallengeResponse360))
+ DicConsole.WriteLine("\tCan do challenge/response with Xbox 360 discs");
+ if(devInfo.KreonFeatures.HasFlag(KreonFeatures.DecryptSs360))
+ DicConsole.WriteLine("\tCan read and descrypt SS from Xbox 360 discs");
+ if(devInfo.KreonFeatures.HasFlag(KreonFeatures.XtremeUnlock360))
+ DicConsole.WriteLine("\tCan set xtreme unlock state with Xbox 360 discs");
+ if(devInfo.KreonFeatures.HasFlag(KreonFeatures.WxripperUnlock360))
+ DicConsole.WriteLine("\tCan set wxripper unlock state with Xbox 360 discs");
+ if(devInfo.KreonFeatures.HasFlag(KreonFeatures.Lock))
+ DicConsole.WriteLine("\tCan set locked state");
+ if(devInfo.KreonFeatures.HasFlag(KreonFeatures.ErrorSkipping))
+ DicConsole.WriteLine("\tCan skip read errors");
+ }
+
+ if(devInfo.BlockLimits != null)
+ {
+ DataFile.WriteTo("Device-Info command", options.OutputPrefix, "_ssc_readblocklimits.bin",
+ "SSC READ BLOCK LIMITS", devInfo.BlockLimits);
+ DicConsole.WriteLine("Block limits for device:");
+ DicConsole.WriteLine(BlockLimits.Prettify(devInfo.BlockLimits));
+ }
+
+ if(devInfo.DensitySupport != null)
+ {
+ DataFile.WriteTo("Device-Info command", options.OutputPrefix, "_ssc_reportdensitysupport.bin",
+ "SSC REPORT DENSITY SUPPORT", devInfo.DensitySupport);
+ if(devInfo.DensitySupportHeader.HasValue)
+ {
+ DicConsole.WriteLine("Densities supported by device:");
+ DicConsole.WriteLine(DensitySupport.PrettifyDensity(devInfo.DensitySupportHeader));
+ }
+ }
+
+ if(devInfo.MediumDensitySupport != null)
+ {
+ DataFile.WriteTo("Device-Info command", options.OutputPrefix,
+ "_ssc_reportdensitysupport_medium.bin", "SSC REPORT DENSITY SUPPORT (MEDIUM)",
+ devInfo.MediumDensitySupport);
+ if(devInfo.MediaTypeSupportHeader.HasValue)
+ {
+ DicConsole.WriteLine("Medium types supported by device:");
+ DicConsole.WriteLine(DensitySupport.PrettifyMediumType(devInfo.MediaTypeSupportHeader));
+ }
+
+ DicConsole.WriteLine(DensitySupport.PrettifyMediumType(devInfo.MediumDensitySupport));
+ }
+ }
+
switch(dev.Type)
{
- case DeviceType.ATA:
- {
- bool sense = dev.AtaIdentify(out byte[] ataBuf, out AtaErrorRegistersChs errorRegisters);
-
- if(sense)
- {
- DicConsole.DebugWriteLine("Device-Info command", "STATUS = 0x{0:X2}", errorRegisters.Status);
- DicConsole.DebugWriteLine("Device-Info command", "ERROR = 0x{0:X2}", errorRegisters.Error);
- DicConsole.DebugWriteLine("Device-Info command", "NSECTOR = 0x{0:X2}",
- errorRegisters.SectorCount);
- DicConsole.DebugWriteLine("Device-Info command", "SECTOR = 0x{0:X2}", errorRegisters.Sector);
- DicConsole.DebugWriteLine("Device-Info command", "CYLHIGH = 0x{0:X2}",
- errorRegisters.CylinderHigh);
- DicConsole.DebugWriteLine("Device-Info command", "CYLLOW = 0x{0:X2}",
- errorRegisters.CylinderLow);
- DicConsole.DebugWriteLine("Device-Info command", "DEVICE = 0x{0:X2}",
- errorRegisters.DeviceHead);
- DicConsole.DebugWriteLine("Device-Info command", "Error code = {0}", dev.LastError);
- break;
- }
-
- DataFile.WriteTo("Device-Info command", options.OutputPrefix, "_ata_identify.bin", "ATA IDENTIFY",
- ataBuf);
-
- DicConsole.WriteLine(Identify.Prettify(ataBuf));
-
- dev.EnableMediaCardPassThrough(out errorRegisters, dev.Timeout, out _);
-
- if(errorRegisters.Sector == 0xAA && errorRegisters.SectorCount == 0x55)
- {
- DicConsole.WriteLine("Device supports the Media Card Pass Through Command Set");
- switch(errorRegisters.DeviceHead & 0x7)
- {
- case 0:
- DicConsole.WriteLine("Device reports incorrect media card type");
- break;
- case 1:
- DicConsole.WriteLine("Device contains a Secure Digital card");
- break;
- case 2:
- DicConsole.WriteLine("Device contains a MultiMediaCard ");
- break;
- case 3:
- DicConsole.WriteLine("Device contains a Secure Digital I/O card");
- break;
- case 4:
- DicConsole.WriteLine("Device contains a Smart Media card");
- break;
- default:
- DicConsole.WriteLine("Device contains unknown media card type {0}",
- errorRegisters.DeviceHead & 0x07);
- break;
- }
-
- if((errorRegisters.DeviceHead & 0x08) == 0x08)
- DicConsole.WriteLine("Media card is write protected");
-
- ushort specificData =
- (ushort)(errorRegisters.CylinderHigh * 0x100 + errorRegisters.CylinderLow);
- if(specificData != 0) DicConsole.WriteLine("Card specific data: 0x{0:X4}", specificData);
- }
-
- break;
- }
- case DeviceType.ATAPI:
- {
- bool sense = dev.AtapiIdentify(out byte[] ataBuf, out AtaErrorRegistersChs errorRegisters);
-
- if(sense)
- {
- DicConsole.DebugWriteLine("Device-Info command", "STATUS = 0x{0:X2}", errorRegisters.Status);
- DicConsole.DebugWriteLine("Device-Info command", "ERROR = 0x{0:X2}", errorRegisters.Error);
- DicConsole.DebugWriteLine("Device-Info command", "NSECTOR = 0x{0:X2}",
- errorRegisters.SectorCount);
- DicConsole.DebugWriteLine("Device-Info command", "SECTOR = 0x{0:X2}", errorRegisters.Sector);
- DicConsole.DebugWriteLine("Device-Info command", "CYLHIGH = 0x{0:X2}",
- errorRegisters.CylinderHigh);
- DicConsole.DebugWriteLine("Device-Info command", "CYLLOW = 0x{0:X2}",
- errorRegisters.CylinderLow);
- DicConsole.DebugWriteLine("Device-Info command", "DEVICE = 0x{0:X2}",
- errorRegisters.DeviceHead);
- DicConsole.DebugWriteLine("Device-Info command", "Error code = {0}", dev.LastError);
- break;
- }
-
- DataFile.WriteTo("Device-Info command", options.OutputPrefix, "_atapi_identify.bin",
- "ATAPI IDENTIFY", ataBuf);
-
- DicConsole.WriteLine(Identify.Prettify(ataBuf));
-
- // ATAPI devices are also SCSI devices
- goto case DeviceType.SCSI;
- }
- case DeviceType.SCSI:
- {
- bool sense = dev.ScsiInquiry(out byte[] inqBuf, out byte[] senseBuf);
-
- if(sense)
- {
- DicConsole.ErrorWriteLine("SCSI error:\n{0}", Sense.PrettifySense(senseBuf));
-
- break;
- }
-
- if(dev.Type != DeviceType.ATAPI) DicConsole.WriteLine("SCSI device");
-
- DataFile.WriteTo("Device-Info command", options.OutputPrefix, "_scsi_inquiry.bin", "SCSI INQUIRY",
- inqBuf);
-
- Inquiry.SCSIInquiry? inq = Inquiry.Decode(inqBuf);
- DicConsole.WriteLine(Inquiry.Prettify(inq));
-
- sense = dev.ScsiInquiry(out inqBuf, out senseBuf, 0x00);
-
- if(!sense)
- {
- byte[] pages = EVPD.DecodePage00(inqBuf);
-
- if(pages != null)
- foreach(byte page in pages)
- if(page >= 0x01 && page <= 0x7F)
- {
- sense = dev.ScsiInquiry(out inqBuf, out senseBuf, page);
- if(sense) continue;
-
- DicConsole.WriteLine("ASCII Page {0:X2}h: {1}", page, EVPD.DecodeASCIIPage(inqBuf));
-
- DataFile.WriteTo("Device-Info command", options.OutputPrefix,
- $"_scsi_evpd_{page:X2}h.bin", $"SCSI INQUIRY EVPD {page:X2}h",
- inqBuf);
- }
- else if(page == 0x80)
- {
- sense = dev.ScsiInquiry(out inqBuf, out senseBuf, page);
- if(sense) continue;
-
- DicConsole.WriteLine("Unit Serial Number: {0}", EVPD.DecodePage80(inqBuf));
- DataFile.WriteTo("Device-Info command", options.OutputPrefix,
- $"_scsi_evpd_{page:X2}h.bin", $"SCSI INQUIRY EVPD {page:X2}h",
- inqBuf);
- }
- else if(page == 0x81)
- {
- sense = dev.ScsiInquiry(out inqBuf, out senseBuf, page);
- if(sense) continue;
-
- DicConsole.WriteLine("{0}", EVPD.PrettifyPage_81(inqBuf));
- DataFile.WriteTo("Device-Info command", options.OutputPrefix,
- $"_scsi_evpd_{page:X2}h.bin", $"SCSI INQUIRY EVPD {page:X2}h",
- inqBuf);
- }
- else if(page == 0x82)
- {
- sense = dev.ScsiInquiry(out inqBuf, out senseBuf, page);
- if(sense) continue;
-
- DicConsole.WriteLine("ASCII implemented operating definitions: {0}",
- EVPD.DecodePage82(inqBuf));
- DataFile.WriteTo("Device-Info command", options.OutputPrefix,
- $"_scsi_evpd_{page:X2}h.bin", $"SCSI INQUIRY EVPD {page:X2}h",
- inqBuf);
- }
- else if(page == 0x83)
- {
- sense = dev.ScsiInquiry(out inqBuf, out senseBuf, page);
- if(sense) continue;
-
- DicConsole.WriteLine("{0}", EVPD.PrettifyPage_83(inqBuf));
- DataFile.WriteTo("Device-Info command", options.OutputPrefix,
- $"_scsi_evpd_{page:X2}h.bin", $"SCSI INQUIRY EVPD {page:X2}h",
- inqBuf);
- }
- else if(page == 0x84)
- {
- sense = dev.ScsiInquiry(out inqBuf, out senseBuf, page);
- if(sense) continue;
-
- DicConsole.WriteLine("{0}", EVPD.PrettifyPage_84(inqBuf));
- DataFile.WriteTo("Device-Info command", options.OutputPrefix,
- $"_scsi_evpd_{page:X2}h.bin", $"SCSI INQUIRY EVPD {page:X2}h",
- inqBuf);
- }
- else if(page == 0x85)
- {
- sense = dev.ScsiInquiry(out inqBuf, out senseBuf, page);
- if(sense) continue;
-
- DicConsole.WriteLine("{0}", EVPD.PrettifyPage_85(inqBuf));
- DataFile.WriteTo("Device-Info command", options.OutputPrefix,
- $"_scsi_evpd_{page:X2}h.bin", $"SCSI INQUIRY EVPD {page:X2}h",
- inqBuf);
- }
- else if(page == 0x86)
- {
- sense = dev.ScsiInquiry(out inqBuf, out senseBuf, page);
- if(sense) continue;
-
- DicConsole.WriteLine("{0}", EVPD.PrettifyPage_86(inqBuf));
- DataFile.WriteTo("Device-Info command", options.OutputPrefix,
- $"_scsi_evpd_{page:X2}h.bin", $"SCSI INQUIRY EVPD {page:X2}h",
- inqBuf);
- }
- else if(page == 0x89)
- {
- sense = dev.ScsiInquiry(out inqBuf, out senseBuf, page);
- if(sense) continue;
-
- DicConsole.WriteLine("{0}", EVPD.PrettifyPage_89(inqBuf));
- DataFile.WriteTo("Device-Info command", options.OutputPrefix,
- $"_scsi_evpd_{page:X2}h.bin", $"SCSI INQUIRY EVPD {page:X2}h",
- inqBuf);
- }
- else if(page == 0xB0)
- {
- sense = dev.ScsiInquiry(out inqBuf, out senseBuf, page);
- if(sense) continue;
-
- DicConsole.WriteLine("{0}", EVPD.PrettifyPage_B0(inqBuf));
- DataFile.WriteTo("Device-Info command", options.OutputPrefix,
- $"_scsi_evpd_{page:X2}h.bin", $"SCSI INQUIRY EVPD {page:X2}h",
- inqBuf);
- }
- else if(page == 0xB1)
- {
- sense = dev.ScsiInquiry(out inqBuf, out senseBuf, page);
- if(sense) continue;
-
- DicConsole.WriteLine("Manufacturer-assigned Serial Number: {0}",
- EVPD.DecodePageB1(inqBuf));
- DataFile.WriteTo("Device-Info command", options.OutputPrefix,
- $"_scsi_evpd_{page:X2}h.bin", $"SCSI INQUIRY EVPD {page:X2}h",
- inqBuf);
- }
- else if(page == 0xB2)
- {
- sense = dev.ScsiInquiry(out inqBuf, out senseBuf, page);
- if(sense) continue;
-
- DicConsole.WriteLine("TapeAlert Supported Flags Bitmap: 0x{0:X16}",
- EVPD.DecodePageB2(inqBuf));
- DataFile.WriteTo("Device-Info command", options.OutputPrefix,
- $"_scsi_evpd_{page:X2}h.bin", $"SCSI INQUIRY EVPD {page:X2}h",
- inqBuf);
- }
- else if(page == 0xB3)
- {
- sense = dev.ScsiInquiry(out inqBuf, out senseBuf, page);
- if(sense) continue;
-
- DicConsole.WriteLine("Automation Device Serial Number: {0}",
- EVPD.DecodePageB3(inqBuf));
- DataFile.WriteTo("Device-Info command", options.OutputPrefix,
- $"_scsi_evpd_{page:X2}h.bin", $"SCSI INQUIRY EVPD {page:X2}h",
- inqBuf);
- }
- else if(page == 0xB4)
- {
- sense = dev.ScsiInquiry(out inqBuf, out senseBuf, page);
- if(sense) continue;
-
- DicConsole.WriteLine("Data Transfer Device Element Address: 0x{0}",
- EVPD.DecodePageB4(inqBuf));
- DataFile.WriteTo("Device-Info command", options.OutputPrefix,
- $"_scsi_evpd_{page:X2}h.bin", $"SCSI INQUIRY EVPD {page:X2}h",
- inqBuf);
- }
- else if(page == 0xC0 &&
- StringHandlers
- .CToString(inq.Value.VendorIdentification).ToLowerInvariant().Trim() ==
- "quantum")
- {
- sense = dev.ScsiInquiry(out inqBuf, out senseBuf, page);
- if(sense) continue;
-
- DicConsole.WriteLine("{0}", EVPD.PrettifyPage_C0_Quantum(inqBuf));
- DataFile.WriteTo("Device-Info command", options.OutputPrefix,
- $"_scsi_evpd_{page:X2}h.bin", $"SCSI INQUIRY EVPD {page:X2}h",
- inqBuf);
- }
- else if(page == 0xC0 &&
- StringHandlers
- .CToString(inq.Value.VendorIdentification).ToLowerInvariant().Trim() ==
- "seagate")
- {
- sense = dev.ScsiInquiry(out inqBuf, out senseBuf, page);
- if(sense) continue;
-
- DicConsole.WriteLine("{0}", EVPD.PrettifyPage_C0_Seagate(inqBuf));
- DataFile.WriteTo("Device-Info command", options.OutputPrefix,
- $"_scsi_evpd_{page:X2}h.bin", $"SCSI INQUIRY EVPD {page:X2}h",
- inqBuf);
- }
- else if(page == 0xC0 &&
- StringHandlers
- .CToString(inq.Value.VendorIdentification).ToLowerInvariant().Trim() ==
- "ibm")
- {
- sense = dev.ScsiInquiry(out inqBuf, out senseBuf, page);
- if(sense) continue;
-
- DicConsole.WriteLine("{0}", EVPD.PrettifyPage_C0_IBM(inqBuf));
- DataFile.WriteTo("Device-Info command", options.OutputPrefix,
- $"_scsi_evpd_{page:X2}h.bin", $"SCSI INQUIRY EVPD {page:X2}h",
- inqBuf);
- }
- else if(page == 0xC1 &&
- StringHandlers
- .CToString(inq.Value.VendorIdentification).ToLowerInvariant().Trim() ==
- "ibm")
- {
- sense = dev.ScsiInquiry(out inqBuf, out senseBuf, page);
- if(sense) continue;
-
- DicConsole.WriteLine("{0}", EVPD.PrettifyPage_C1_IBM(inqBuf));
- DataFile.WriteTo("Device-Info command", options.OutputPrefix,
- $"_scsi_evpd_{page:X2}h.bin", $"SCSI INQUIRY EVPD {page:X2}h",
- inqBuf);
- }
- else if((page == 0xC0 || page == 0xC1) &&
- StringHandlers
- .CToString(inq.Value.VendorIdentification).ToLowerInvariant().Trim() ==
- "certance")
- {
- sense = dev.ScsiInquiry(out inqBuf, out senseBuf, page);
- if(sense) continue;
-
- DicConsole.WriteLine("{0}", EVPD.PrettifyPage_C0_C1_Certance(inqBuf));
- DataFile.WriteTo("Device-Info command", options.OutputPrefix,
- $"_scsi_evpd_{page:X2}h.bin", $"SCSI INQUIRY EVPD {page:X2}h",
- inqBuf);
- }
- else if((page == 0xC2 || page == 0xC3 || page == 0xC4 || page == 0xC5 ||
- page == 0xC6) &&
- StringHandlers
- .CToString(inq.Value.VendorIdentification).ToLowerInvariant().Trim() ==
- "certance")
- {
- sense = dev.ScsiInquiry(out inqBuf, out senseBuf, page);
- if(sense) continue;
-
- DicConsole.WriteLine("{0}", EVPD.PrettifyPage_C2_C3_C4_C5_C6_Certance(inqBuf));
- DataFile.WriteTo("Device-Info command", options.OutputPrefix,
- $"_scsi_evpd_{page:X2}h.bin", $"SCSI INQUIRY EVPD {page:X2}h",
- inqBuf);
- }
- else if((page == 0xC0 || page == 0xC1 || page == 0xC2 || page == 0xC3 || page == 0xC4 ||
- page == 0xC5) &&
- StringHandlers
- .CToString(inq.Value.VendorIdentification).ToLowerInvariant().Trim() == "hp")
- {
- sense = dev.ScsiInquiry(out inqBuf, out senseBuf, page);
- if(sense) continue;
-
- DicConsole.WriteLine("{0}", EVPD.PrettifyPage_C0_to_C5_HP(inqBuf));
- DataFile.WriteTo("Device-Info command", options.OutputPrefix,
- $"_scsi_evpd_{page:X2}h.bin", $"SCSI INQUIRY EVPD {page:X2}h",
- inqBuf);
- }
- else if(page == 0xDF &&
- StringHandlers
- .CToString(inq.Value.VendorIdentification).ToLowerInvariant().Trim() ==
- "certance")
- {
- sense = dev.ScsiInquiry(out inqBuf, out senseBuf, page);
- if(sense) continue;
-
- DicConsole.WriteLine("{0}", EVPD.PrettifyPage_DF_Certance(inqBuf));
- DataFile.WriteTo("Device-Info command", options.OutputPrefix,
- $"_scsi_evpd_{page:X2}h.bin", $"SCSI INQUIRY EVPD {page:X2}h",
- inqBuf);
- }
- else
- {
- if(page == 0x00) continue;
-
- DicConsole.DebugWriteLine("Device-Info command",
- "Found undecoded SCSI VPD page 0x{0:X2}", page);
-
- sense = dev.ScsiInquiry(out inqBuf, out senseBuf, page);
- if(!sense)
- DataFile.WriteTo("Device-Info command", options.OutputPrefix,
- $"_scsi_evpd_{page:X2}h.bin", $"SCSI INQUIRY EVPD {page:X2}h",
- inqBuf);
- }
- }
-
- Modes.DecodedMode? decMode = null;
- PeripheralDeviceTypes devType = (PeripheralDeviceTypes)inq.Value.PeripheralDeviceType;
-
- sense = dev.ModeSense10(out byte[] modeBuf, out senseBuf, false, true,
- ScsiModeSensePageControl.Current, 0x3F, 0xFF, 5, out _);
- if(sense || dev.Error)
- sense = dev.ModeSense10(out modeBuf, out senseBuf, false, true,
- ScsiModeSensePageControl.Current, 0x3F, 0x00, 5, out _);
-
- if(!sense && !dev.Error) decMode = Modes.DecodeMode10(modeBuf, devType);
-
- if(sense || dev.Error || !decMode.HasValue)
- {
- sense = dev.ModeSense6(out modeBuf, out senseBuf, false, ScsiModeSensePageControl.Current, 0x3F,
- 0xFF, 5, out _);
- if(sense || dev.Error)
- sense = dev.ModeSense6(out modeBuf, out senseBuf, false, ScsiModeSensePageControl.Current,
- 0x3F, 0x00, 5, out _);
- if(sense || dev.Error) sense = dev.ModeSense(out modeBuf, out senseBuf, 5, out _);
-
- if(!sense && !dev.Error) decMode = Modes.DecodeMode6(modeBuf, devType);
- }
-
- if(!sense)
- DataFile.WriteTo("Device-Info command", options.OutputPrefix, "_scsi_modesense.bin",
- "SCSI MODE SENSE", modeBuf);
-
- if(decMode.HasValue)
- PrintScsiModePages.Print(decMode.Value, devType, inq.Value.VendorIdentification);
-
- switch(devType)
- {
- case PeripheralDeviceTypes.MultiMediaDevice:
- sense = dev.GetConfiguration(out byte[] confBuf, out senseBuf, dev.Timeout, out _);
-
- if(!sense)
- {
- DataFile.WriteTo("Device-Info command", options.OutputPrefix,
- "_mmc_getconfiguration.bin", "MMC GET CONFIGURATION", confBuf);
-
- Features.SeparatedFeatures ftr = Features.Separate(confBuf);
-
- DicConsole.DebugWriteLine("Device-Info command",
- "GET CONFIGURATION length is {0} bytes", ftr.DataLength);
- DicConsole.DebugWriteLine("Device-Info command",
- "GET CONFIGURATION current profile is {0:X4}h",
- ftr.CurrentProfile);
- if(ftr.Descriptors != null)
- {
- DicConsole.WriteLine("SCSI MMC GET CONFIGURATION Features:");
- foreach(Features.FeatureDescriptor desc in ftr.Descriptors)
- {
- DicConsole.DebugWriteLine("Device-Info command", "Feature {0:X4}h", desc.Code);
-
- switch(desc.Code)
- {
- case 0x0000:
- DicConsole.WriteLine(Features.Prettify_0000(desc.Data));
- break;
- case 0x0001:
- DicConsole.WriteLine(Features.Prettify_0001(desc.Data));
- break;
- case 0x0002:
- DicConsole.WriteLine(Features.Prettify_0002(desc.Data));
- break;
- case 0x0003:
- DicConsole.WriteLine(Features.Prettify_0003(desc.Data));
- break;
- case 0x0004:
- DicConsole.WriteLine(Features.Prettify_0004(desc.Data));
- break;
- case 0x0010:
- DicConsole.WriteLine(Features.Prettify_0010(desc.Data));
- break;
- case 0x001D:
- DicConsole.WriteLine(Features.Prettify_001D(desc.Data));
- break;
- case 0x001E:
- DicConsole.WriteLine(Features.Prettify_001E(desc.Data));
- break;
- case 0x001F:
- DicConsole.WriteLine(Features.Prettify_001F(desc.Data));
- break;
- case 0x0020:
- DicConsole.WriteLine(Features.Prettify_0020(desc.Data));
- break;
- case 0x0021:
- DicConsole.WriteLine(Features.Prettify_0021(desc.Data));
- break;
- case 0x0022:
- DicConsole.WriteLine(Features.Prettify_0022(desc.Data));
- break;
- case 0x0023:
- DicConsole.WriteLine(Features.Prettify_0023(desc.Data));
- break;
- case 0x0024:
- DicConsole.WriteLine(Features.Prettify_0024(desc.Data));
- break;
- case 0x0025:
- DicConsole.WriteLine(Features.Prettify_0025(desc.Data));
- break;
- case 0x0026:
- DicConsole.WriteLine(Features.Prettify_0026(desc.Data));
- break;
- case 0x0027:
- DicConsole.WriteLine(Features.Prettify_0027(desc.Data));
- break;
- case 0x0028:
- DicConsole.WriteLine(Features.Prettify_0028(desc.Data));
- break;
- case 0x0029:
- DicConsole.WriteLine(Features.Prettify_0029(desc.Data));
- break;
- case 0x002A:
- DicConsole.WriteLine(Features.Prettify_002A(desc.Data));
- break;
- case 0x002B:
- DicConsole.WriteLine(Features.Prettify_002B(desc.Data));
- break;
- case 0x002C:
- DicConsole.WriteLine(Features.Prettify_002C(desc.Data));
- break;
- case 0x002D:
- DicConsole.WriteLine(Features.Prettify_002D(desc.Data));
- break;
- case 0x002E:
- DicConsole.WriteLine(Features.Prettify_002E(desc.Data));
- break;
- case 0x002F:
- DicConsole.WriteLine(Features.Prettify_002F(desc.Data));
- break;
- case 0x0030:
- DicConsole.WriteLine(Features.Prettify_0030(desc.Data));
- break;
- case 0x0031:
- DicConsole.WriteLine(Features.Prettify_0031(desc.Data));
- break;
- case 0x0032:
- DicConsole.WriteLine(Features.Prettify_0032(desc.Data));
- break;
- case 0x0033:
- DicConsole.WriteLine(Features.Prettify_0033(desc.Data));
- break;
- case 0x0035:
- DicConsole.WriteLine(Features.Prettify_0035(desc.Data));
- break;
- case 0x0037:
- DicConsole.WriteLine(Features.Prettify_0037(desc.Data));
- break;
- case 0x0038:
- DicConsole.WriteLine(Features.Prettify_0038(desc.Data));
- break;
- case 0x003A:
- DicConsole.WriteLine(Features.Prettify_003A(desc.Data));
- break;
- case 0x003B:
- DicConsole.WriteLine(Features.Prettify_003B(desc.Data));
- break;
- case 0x0040:
- DicConsole.WriteLine(Features.Prettify_0040(desc.Data));
- break;
- case 0x0041:
- DicConsole.WriteLine(Features.Prettify_0041(desc.Data));
- break;
- case 0x0042:
- DicConsole.WriteLine(Features.Prettify_0042(desc.Data));
- break;
- case 0x0050:
- DicConsole.WriteLine(Features.Prettify_0050(desc.Data));
- break;
- case 0x0051:
- DicConsole.WriteLine(Features.Prettify_0051(desc.Data));
- break;
- case 0x0080:
- DicConsole.WriteLine(Features.Prettify_0080(desc.Data));
- break;
- case 0x0100:
- DicConsole.WriteLine(Features.Prettify_0100(desc.Data));
- break;
- case 0x0101:
- DicConsole.WriteLine(Features.Prettify_0101(desc.Data));
- break;
- case 0x0102:
- DicConsole.WriteLine(Features.Prettify_0102(desc.Data));
- break;
- case 0x0103:
- DicConsole.WriteLine(Features.Prettify_0103(desc.Data));
- break;
- case 0x0104:
- DicConsole.WriteLine(Features.Prettify_0104(desc.Data));
- break;
- case 0x0105:
- DicConsole.WriteLine(Features.Prettify_0105(desc.Data));
- break;
- case 0x0106:
- DicConsole.WriteLine(Features.Prettify_0106(desc.Data));
- break;
- case 0x0107:
- DicConsole.WriteLine(Features.Prettify_0107(desc.Data));
- break;
- case 0x0108:
- DicConsole.WriteLine(Features.Prettify_0108(desc.Data));
- break;
- case 0x0109:
- DicConsole.WriteLine(Features.Prettify_0109(desc.Data));
- break;
- case 0x010A:
- DicConsole.WriteLine(Features.Prettify_010A(desc.Data));
- break;
- case 0x010B:
- DicConsole.WriteLine(Features.Prettify_010B(desc.Data));
- break;
- case 0x010C:
- DicConsole.WriteLine(Features.Prettify_010C(desc.Data));
- break;
- case 0x010D:
- DicConsole.WriteLine(Features.Prettify_010D(desc.Data));
- break;
- case 0x010E:
- DicConsole.WriteLine(Features.Prettify_010E(desc.Data));
- break;
- case 0x0110:
- DicConsole.WriteLine(Features.Prettify_0110(desc.Data));
- break;
- case 0x0113:
- DicConsole.WriteLine(Features.Prettify_0113(desc.Data));
- break;
- case 0x0142:
- DicConsole.WriteLine(Features.Prettify_0142(desc.Data));
- break;
- default:
- DicConsole.WriteLine("Found unknown feature code {0:X4}h", desc.Code);
- break;
- }
- }
- }
- else
- DicConsole.DebugWriteLine("Device-Info command",
- "GET CONFIGURATION returned no feature descriptors");
- }
-
- // TODO: DVD drives respond correctly to BD status.
- // While specification says if no medium is present
- // it should inform all possible capabilities,
- // testing drives show only supported media capabilities.
- /*
- byte[] strBuf;
- sense = dev.ReadDiscStructure(out strBuf, out senseBuf, MmcDiscStructureMediaType.DVD, 0, 0, MmcDiscStructureFormat.CapabilityList, 0, dev.Timeout, out _);
-
- if (!sense)
- {
- Decoders.SCSI.DiscStructureCapabilities.Capability[] caps = Decoders.SCSI.DiscStructureCapabilities.Decode(strBuf);
- if (caps != null)
- {
- foreach (Decoders.SCSI.DiscStructureCapabilities.Capability cap in caps)
- {
- if (cap.SDS && cap.RDS)
- DicConsole.WriteLine("Drive can READ/SEND DISC STRUCTURE format {0:X2}h", cap.FormatCode);
- else if (cap.SDS)
- DicConsole.WriteLine("Drive can SEND DISC STRUCTURE format {0:X2}h", cap.FormatCode);
- else if (cap.RDS)
- DicConsole.WriteLine("Drive can READ DISC STRUCTURE format {0:X2}h", cap.FormatCode);
- }
- }
- }
-
- sense = dev.ReadDiscStructure(out strBuf, out senseBuf, MmcDiscStructureMediaType.BD, 0, 0, MmcDiscStructureFormat.CapabilityList, 0, dev.Timeout, out _);
-
- if (!sense)
- {
- Decoders.SCSI.DiscStructureCapabilities.Capability[] caps = Decoders.SCSI.DiscStructureCapabilities.Decode(strBuf);
- if (caps != null)
- {
- foreach (Decoders.SCSI.DiscStructureCapabilities.Capability cap in caps)
- {
- if (cap.SDS && cap.RDS)
- DicConsole.WriteLine("Drive can READ/SEND DISC STRUCTURE format {0:X2}h", cap.FormatCode);
- else if (cap.SDS)
- DicConsole.WriteLine("Drive can SEND DISC STRUCTURE format {0:X2}h", cap.FormatCode);
- else if (cap.RDS)
- DicConsole.WriteLine("Drive can READ DISC STRUCTURE format {0:X2}h", cap.FormatCode);
- }
- }
- }
- */
-
- #region Plextor
- if(dev.Manufacturer == "PLEXTOR")
- {
- bool plxtSense = true;
- bool plxtDvd = false;
- byte[] plxtBuf = null;
-
- switch(dev.Model)
- {
- case "DVDR PX-708A":
- case "DVDR PX-708A2":
- case "DVDR PX-712A":
- plxtDvd = true;
- plxtSense = dev.PlextorReadEeprom(out plxtBuf, out senseBuf, dev.Timeout,
- out _);
- break;
- case "DVDR PX-714A":
- case "DVDR PX-716A":
- case "DVDR PX-716AL":
- case "DVDR PX-755A":
- case "DVDR PX-760A":
- {
- plxtBuf = new byte[256 * 4];
- for(byte i = 0; i < 4; i++)
- {
- plxtSense = dev.PlextorReadEepromBlock(out byte[] plxtBufSmall,
- out senseBuf, i, 256, dev.Timeout,
- out _);
- if(plxtSense) break;
-
- Array.Copy(plxtBufSmall, 0, plxtBuf, i * 256, 256);
- }
-
- plxtDvd = true;
- break;
- }
- default:
- {
- if(dev.Model.StartsWith("CD-R ", StringComparison.Ordinal))
- plxtSense = dev.PlextorReadEepromCdr(out plxtBuf, out senseBuf, dev.Timeout,
- out _);
- break;
- }
- }
-
- if(!plxtSense)
- {
- DataFile.WriteTo("Device-Info command", options.OutputPrefix, "_plextor_eeprom.bin",
- "PLEXTOR READ EEPROM", plxtBuf);
-
- ushort discs;
- uint cdReadTime, cdWriteTime, dvdReadTime = 0, dvdWriteTime = 0;
-
- BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian;
- if(plxtDvd)
- {
- discs = BigEndianBitConverter.ToUInt16(plxtBuf, 0x0120);
- cdReadTime = BigEndianBitConverter.ToUInt32(plxtBuf, 0x0122);
- cdWriteTime = BigEndianBitConverter.ToUInt32(plxtBuf, 0x0126);
- dvdReadTime = BigEndianBitConverter.ToUInt32(plxtBuf, 0x012A);
- dvdWriteTime = BigEndianBitConverter.ToUInt32(plxtBuf, 0x012E);
- }
- else
- {
- discs = BigEndianBitConverter.ToUInt16(plxtBuf, 0x0078);
- cdReadTime = BigEndianBitConverter.ToUInt32(plxtBuf, 0x006C);
- cdWriteTime = BigEndianBitConverter.ToUInt32(plxtBuf, 0x007A);
- }
-
- DicConsole.WriteLine("Drive has loaded a total of {0} discs", discs);
- DicConsole
- .WriteLine("Drive has spent {0} hours, {1} minutes and {2} seconds reading CDs",
- cdReadTime / 3600, cdReadTime / 60 % 60, cdReadTime % 60);
- DicConsole
- .WriteLine("Drive has spent {0} hours, {1} minutes and {2} seconds writing CDs",
- cdWriteTime / 3600, cdWriteTime / 60 % 60, cdWriteTime % 60);
- if(plxtDvd)
- {
- DicConsole
- .WriteLine("Drive has spent {0} hours, {1} minutes and {2} seconds reading DVDs",
- dvdReadTime / 3600, dvdReadTime / 60 % 60, dvdReadTime % 60);
- DicConsole
- .WriteLine("Drive has spent {0} hours, {1} minutes and {2} seconds writing DVDs",
- dvdWriteTime / 3600, dvdWriteTime / 60 % 60, dvdWriteTime % 60);
- }
- }
-
- plxtSense = dev.PlextorGetPoweRec(out senseBuf, out bool plxtPwrRecEnabled,
- out ushort plxtPwrRecSpeed, dev.Timeout, out _);
- if(!plxtSense)
- {
- DicConsole.Write("Drive supports PoweRec");
- if(plxtPwrRecEnabled)
- {
- DicConsole.Write(", has it enabled");
-
- if(plxtPwrRecSpeed > 0)
- DicConsole.WriteLine(" and recommends {0} Kb/sec.", plxtPwrRecSpeed);
- else DicConsole.WriteLine(".");
-
- plxtSense = dev.PlextorGetSpeeds(out senseBuf, out ushort plxtPwrRecSelected,
- out ushort plxtPwrRecMax,
- out ushort plxtPwrRecLast, dev.Timeout, out _);
-
- if(!plxtSense)
- {
- if(plxtPwrRecSelected > 0)
- DicConsole
- .WriteLine("Selected PoweRec speed for currently inserted media is {0} Kb/sec ({1}x)",
- plxtPwrRecSelected, plxtPwrRecSelected / 177);
- if(plxtPwrRecMax > 0)
- DicConsole
- .WriteLine("Maximum PoweRec speed for currently inserted media is {0} Kb/sec ({1}x)",
- plxtPwrRecMax, plxtPwrRecMax / 177);
- if(plxtPwrRecLast > 0)
- DicConsole.WriteLine("Last used PoweRec was {0} Kb/sec ({1}x)",
- plxtPwrRecLast, plxtPwrRecLast / 177);
- }
- }
- else DicConsole.WriteLine("PoweRec is disabled");
- }
-
- // TODO: Check it with a drive
- plxtSense = dev.PlextorGetSilentMode(out plxtBuf, out senseBuf, dev.Timeout, out _);
- if(!plxtSense)
- {
- DicConsole.WriteLine("Drive supports Plextor SilentMode");
- if(plxtBuf[0] == 1)
- {
- DicConsole.WriteLine("Plextor SilentMode is enabled:");
- DicConsole.WriteLine(plxtBuf[1] == 2
- ? "\tAccess time is slow"
- : "\tAccess time is fast");
-
- if(plxtBuf[2] > 0)
- DicConsole.WriteLine("\tCD read speed limited to {0}x", plxtBuf[2]);
- if(plxtBuf[3] > 0 && plxtDvd)
- DicConsole.WriteLine("\tDVD read speed limited to {0}x", plxtBuf[3]);
- if(plxtBuf[4] > 0)
- DicConsole.WriteLine("\tCD write speed limited to {0}x", plxtBuf[4]);
- if(plxtBuf[6] > 0)
- DicConsole.WriteLine("\tTray eject speed limited to {0}",
- -(plxtBuf[6] + 48));
- if(plxtBuf[7] > 0)
- DicConsole.WriteLine("\tTray eject speed limited to {0}", plxtBuf[7] - 47);
- }
- }
-
- plxtSense = dev.PlextorGetGigaRec(out plxtBuf, out senseBuf, dev.Timeout, out _);
- if(!plxtSense) DicConsole.WriteLine("Drive supports Plextor GigaRec");
-
- plxtSense = dev.PlextorGetSecuRec(out plxtBuf, out senseBuf, dev.Timeout, out _);
- if(!plxtSense) DicConsole.WriteLine("Drive supports Plextor SecuRec");
-
- plxtSense = dev.PlextorGetSpeedRead(out plxtBuf, out senseBuf, dev.Timeout, out _);
- if(!plxtSense)
- {
- DicConsole.Write("Drive supports Plextor SpeedRead");
- if((plxtBuf[2] & 0x01) == 0x01) DicConsole.WriteLine("and has it enabled");
- else DicConsole.WriteLine();
- }
-
- plxtSense = dev.PlextorGetHiding(out plxtBuf, out senseBuf, dev.Timeout, out _);
- if(!plxtSense)
- {
- DicConsole.WriteLine("Drive supports hiding CD-Rs and forcing single session");
-
- if((plxtBuf[2] & 0x02) == 0x02) DicConsole.WriteLine("Drive currently hides CD-Rs");
- if((plxtBuf[2] & 0x01) == 0x01)
- DicConsole.WriteLine("Drive currently forces single session");
- }
-
- plxtSense = dev.PlextorGetVariRec(out plxtBuf, out senseBuf, false, dev.Timeout, out _);
- if(!plxtSense) DicConsole.WriteLine("Drive supports Plextor VariRec");
-
- if(plxtDvd)
- {
- plxtSense = dev.PlextorGetVariRec(out plxtBuf, out senseBuf, true, dev.Timeout,
- out _);
- if(!plxtSense) DicConsole.WriteLine("Drive supports Plextor VariRec for DVDs");
-
- plxtSense = dev.PlextorGetBitsetting(out plxtBuf, out senseBuf, false, dev.Timeout,
- out _);
- if(!plxtSense) DicConsole.WriteLine("Drive supports bitsetting DVD+R book type");
- plxtSense = dev.PlextorGetBitsetting(out plxtBuf, out senseBuf, true, dev.Timeout,
- out _);
- if(!plxtSense) DicConsole.WriteLine("Drive supports bitsetting DVD+R DL book type");
- plxtSense = dev.PlextorGetTestWriteDvdPlus(out plxtBuf, out senseBuf, dev.Timeout,
- out _);
- if(!plxtSense) DicConsole.WriteLine("Drive supports test writing DVD+");
- }
- }
- #endregion Plextor
-
- if(inq.Value.KreonPresent)
- if(!dev.KreonGetFeatureList(out senseBuf, out KreonFeatures krFeatures, dev.Timeout,
- out _))
- {
- DicConsole.WriteLine("Drive has kreon firmware:");
- if(krFeatures.HasFlag(KreonFeatures.ChallengeResponse))
- DicConsole.WriteLine("\tCan do challenge/response with Xbox discs");
- if(krFeatures.HasFlag(KreonFeatures.DecryptSs))
- DicConsole.WriteLine("\tCan read and descrypt SS from Xbox discs");
- if(krFeatures.HasFlag(KreonFeatures.XtremeUnlock))
- DicConsole.WriteLine("\tCan set xtreme unlock state with Xbox discs");
- if(krFeatures.HasFlag(KreonFeatures.WxripperUnlock))
- DicConsole.WriteLine("\tCan set wxripper unlock state with Xbox discs");
- if(krFeatures.HasFlag(KreonFeatures.ChallengeResponse360))
- DicConsole.WriteLine("\tCan do challenge/response with Xbox 360 discs");
- if(krFeatures.HasFlag(KreonFeatures.DecryptSs360))
- DicConsole.WriteLine("\tCan read and descrypt SS from Xbox 360 discs");
- if(krFeatures.HasFlag(KreonFeatures.XtremeUnlock360))
- DicConsole.WriteLine("\tCan set xtreme unlock state with Xbox 360 discs");
- if(krFeatures.HasFlag(KreonFeatures.WxripperUnlock360))
- DicConsole.WriteLine("\tCan set wxripper unlock state with Xbox 360 discs");
- if(krFeatures.HasFlag(KreonFeatures.Lock))
- DicConsole.WriteLine("\tCan set locked state");
- if(krFeatures.HasFlag(KreonFeatures.ErrorSkipping))
- DicConsole.WriteLine("\tCan skip read errors");
- }
-
- break;
- case PeripheralDeviceTypes.SequentialAccess:
-
- sense = dev.ReadBlockLimits(out byte[] seqBuf, out senseBuf, dev.Timeout, out _);
- if(sense)
- DicConsole.ErrorWriteLine("READ BLOCK LIMITS:\n{0}", Sense.PrettifySense(senseBuf));
- else
- {
- DataFile.WriteTo("Device-Info command", options.OutputPrefix,
- "_ssc_readblocklimits.bin", "SSC READ BLOCK LIMITS", seqBuf);
- DicConsole.WriteLine("Block limits for device:");
- DicConsole.WriteLine(BlockLimits.Prettify(seqBuf));
- }
-
- sense = dev.ReportDensitySupport(out seqBuf, out senseBuf, dev.Timeout, out _);
- if(sense)
- DicConsole.ErrorWriteLine("REPORT DENSITY SUPPORT:\n{0}",
- Sense.PrettifySense(senseBuf));
- else
- {
- DataFile.WriteTo("Device-Info command", options.OutputPrefix,
- "_ssc_reportdensitysupport.bin", "SSC REPORT DENSITY SUPPORT", seqBuf);
- DensitySupport.DensitySupportHeader? dens = DensitySupport.DecodeDensity(seqBuf);
- if(dens.HasValue)
- {
- DicConsole.WriteLine("Densities supported by device:");
- DicConsole.WriteLine(DensitySupport.PrettifyDensity(dens));
- }
- }
-
- sense = dev.ReportDensitySupport(out seqBuf, out senseBuf, true, false, dev.Timeout, out _);
- if(sense)
- DicConsole.ErrorWriteLine("REPORT DENSITY SUPPORT (MEDIUM):\n{0}",
- Sense.PrettifySense(senseBuf));
- else
- {
- DataFile.WriteTo("Device-Info command", options.OutputPrefix,
- "_ssc_reportdensitysupport_medium.bin",
- "SSC REPORT DENSITY SUPPORT (MEDIUM)", seqBuf);
- DensitySupport.MediaTypeSupportHeader? meds = DensitySupport.DecodeMediumType(seqBuf);
- if(meds.HasValue)
- {
- DicConsole.WriteLine("Medium types supported by device:");
- DicConsole.WriteLine(DensitySupport.PrettifyMediumType(meds));
- }
-
- DicConsole.WriteLine(DensitySupport.PrettifyMediumType(seqBuf));
- }
-
- break;
- }
-
- break;
- }
case DeviceType.MMC:
{
bool noInfo = true;
- bool sense = dev.ReadCid(out byte[] mmcBuf, out _, dev.Timeout, out _);
- if(!sense)
+ if(devInfo.CID != null)
{
noInfo = false;
DataFile.WriteTo("Device-Info command", options.OutputPrefix, "_mmc_cid.bin", "MMC CID",
- mmcBuf);
- DicConsole.WriteLine("{0}", Decoders.MMC.Decoders.PrettifyCID(mmcBuf));
+ devInfo.CID);
+ DicConsole.WriteLine("{0}", Decoders.MMC.Decoders.PrettifyCID(devInfo.CID));
}
- sense = dev.ReadCsd(out mmcBuf, out _, dev.Timeout, out _);
- if(!sense)
+ if(devInfo.CSD != null)
{
noInfo = false;
DataFile.WriteTo("Device-Info command", options.OutputPrefix, "_mmc_csd.bin", "MMC CSD",
- mmcBuf);
- DicConsole.WriteLine("{0}", Decoders.MMC.Decoders.PrettifyCSD(mmcBuf));
+ devInfo.CSD);
+ DicConsole.WriteLine("{0}", Decoders.MMC.Decoders.PrettifyCSD(devInfo.CSD));
}
- sense = dev.ReadOcr(out mmcBuf, out _, dev.Timeout, out _);
- if(!sense)
+ if(devInfo.OCR != null)
{
noInfo = false;
DataFile.WriteTo("Device-Info command", options.OutputPrefix, "_mmc_ocr.bin", "MMC OCR",
- mmcBuf);
- DicConsole.WriteLine("{0}", Decoders.MMC.Decoders.PrettifyOCR(mmcBuf));
+ devInfo.OCR);
+ DicConsole.WriteLine("{0}", Decoders.MMC.Decoders.PrettifyOCR(devInfo.OCR));
}
- sense = dev.ReadExtendedCsd(out mmcBuf, out _, dev.Timeout, out _);
- if(!sense)
+ if(devInfo.ExtendedCSD != null)
{
noInfo = false;
DataFile.WriteTo("Device-Info command", options.OutputPrefix, "_mmc_ecsd.bin",
- "MMC Extended CSD", mmcBuf);
- DicConsole.WriteLine("{0}", Decoders.MMC.Decoders.PrettifyExtendedCSD(mmcBuf));
+ "MMC Extended CSD", devInfo.ExtendedCSD);
+ DicConsole.WriteLine("{0}", Decoders.MMC.Decoders.PrettifyExtendedCSD(devInfo.ExtendedCSD));
}
if(noInfo) DicConsole.WriteLine("Could not get any kind of information from the device !!!");
@@ -1152,48 +848,41 @@ namespace DiscImageChef.Commands
{
bool noInfo = true;
- bool sense = dev.ReadCid(out byte[] sdBuf, out _, dev.Timeout, out _);
- if(!sense)
+ if(devInfo.CID != null)
{
noInfo = false;
DataFile.WriteTo("Device-Info command", options.OutputPrefix, "_sd_cid.bin",
- "SecureDigital CID", sdBuf);
- DicConsole.WriteLine("{0}", Decoders.SecureDigital.Decoders.PrettifyCID(sdBuf));
+ "SecureDigital CID", devInfo.CID);
+ DicConsole.WriteLine("{0}", Decoders.SecureDigital.Decoders.PrettifyCID(devInfo.CID));
}
- sense = dev.ReadCsd(out sdBuf, out _, dev.Timeout, out _);
- if(!sense)
+ if(devInfo.CSD != null)
{
noInfo = false;
DataFile.WriteTo("Device-Info command", options.OutputPrefix, "_sd_csd.bin",
- "SecureDigital CSD", sdBuf);
- DicConsole.WriteLine("{0}", Decoders.SecureDigital.Decoders.PrettifyCSD(sdBuf));
+ "SecureDigital CSD", devInfo.CSD);
+ DicConsole.WriteLine("{0}", Decoders.SecureDigital.Decoders.PrettifyCSD(devInfo.CSD));
}
- sense = dev.ReadSdocr(out sdBuf, out _, dev.Timeout, out _);
- if(!sense)
+ if(devInfo.OCR != null)
{
noInfo = false;
DataFile.WriteTo("Device-Info command", options.OutputPrefix, "_sd_ocr.bin",
- "SecureDigital OCR", sdBuf);
- DicConsole.WriteLine("{0}", Decoders.SecureDigital.Decoders.PrettifyOCR(sdBuf));
+ "SecureDigital OCR", devInfo.OCR);
+ DicConsole.WriteLine("{0}", Decoders.SecureDigital.Decoders.PrettifyOCR(devInfo.OCR));
}
- sense = dev.ReadScr(out sdBuf, out _, dev.Timeout, out _);
- if(!sense)
+ if(devInfo.SCR != null)
{
noInfo = false;
DataFile.WriteTo("Device-Info command", options.OutputPrefix, "_sd_scr.bin",
- "SecureDigital SCR", sdBuf);
- DicConsole.WriteLine("{0}", Decoders.SecureDigital.Decoders.PrettifySCR(sdBuf));
+ "SecureDigital SCR", devInfo.SCR);
+ DicConsole.WriteLine("{0}", Decoders.SecureDigital.Decoders.PrettifySCR(devInfo.SCR));
}
if(noInfo) DicConsole.WriteLine("Could not get any kind of information from the device !!!");
}
break;
- default:
- DicConsole.ErrorWriteLine("Unknown device type {0}, cannot get information.", dev.Type);
- break;
}
Core.Statistics.AddCommand("device-info");