* DiscImageChef.Decoders/SCSI/MMC/Features.cs:

Added code to separate features and the feature header.

	* DiscImageChef.Devices/Enums.cs:
	* DiscImageChef.Devices/Device/ScsiCommands.cs:
	  Added SCSI GET CONFIGURATION
This commit is contained in:
2015-11-01 20:06:24 +00:00
parent cfdbb92d44
commit dfb15d0e4f
5 changed files with 136 additions and 4 deletions

View File

@@ -1,3 +1,8 @@
2015-11-01 Natalia Portillo <claunia@claunia.com>
* SCSI/MMC/Features.cs:
Added code to separate features and the feature header.
2015-11-01 Natalia Portillo <claunia@claunia.com> 2015-11-01 Natalia Portillo <claunia@claunia.com>
* SCSI/MMC/Features.cs: * SCSI/MMC/Features.cs:

View File

@@ -5739,6 +5739,43 @@ namespace DiscImageChef.Decoders.SCSI.MMC
{ {
return Prettify_0142(Decode_0142(feature)); return Prettify_0142(Decode_0142(feature));
} }
public struct FeatureDescriptor
{
public ushort Code;
public byte[] Data;
}
public struct SeparatedFeatures
{
public uint DataLength;
public ushort CurrentProfile;
public FeatureDescriptor[] Descriptors;
}
public static SeparatedFeatures Separate(byte[] response)
{
SeparatedFeatures dec = new SeparatedFeatures();
dec.DataLength = (uint)(response[0] << 24 + response[1] << 16 + response[2] << 8 + response[4]);
dec.CurrentProfile = (ushort)(response[6] << 8 + response[7]);
uint offset = 8;
List<FeatureDescriptor> descLst = new List<FeatureDescriptor>();
while (offset < response.Length)
{
FeatureDescriptor desc = new FeatureDescriptor();
desc.Code = (ushort)(response[offset + 0] << 8 + response[offset + 1]);
desc.Data = new byte[response[offset + 3] + 4];
Array.Copy(response, offset + 4, desc.Data, 0, desc.Data.Length + 4);
offset += (uint)(4 + desc.Data.Length);
descLst.Add(desc);
}
dec.Descriptors = descLst.ToArray();
return dec;
}
} }
} }

View File

@@ -1,3 +1,9 @@
2015-11-01 Natalia Portillo <claunia@claunia.com>
* Enums.cs:
* Device/ScsiCommands.cs:
Added SCSI GET CONFIGURATION
2015-11-01 Natalia Portillo <claunia@claunia.com> 2015-11-01 Natalia Portillo <claunia@claunia.com>
* Enums.cs: * Enums.cs:

View File

@@ -374,7 +374,6 @@ namespace DiscImageChef.Devices
/// <summary> /// <summary>
/// Sends the SCSI PREVENT ALLOW MEDIUM REMOVAL command to prevent medium removal /// Sends the SCSI PREVENT ALLOW MEDIUM REMOVAL command to prevent medium removal
/// </summary> /// </summary>
/// <returns><c>true</c>, if allow medium removal was prevented, <c>false</c> otherwise.</returns>
/// <returns><c>true</c> if the command failed and <paramref name="senseBuffer"/> contains the sense buffer.</returns> /// <returns><c>true</c> if the command failed and <paramref name="senseBuffer"/> contains the sense buffer.</returns>
/// <param name="senseBuffer">Sense buffer.</param> /// <param name="senseBuffer">Sense buffer.</param>
/// <param name="timeout">Timeout in seconds.</param> /// <param name="timeout">Timeout in seconds.</param>
@@ -387,7 +386,6 @@ namespace DiscImageChef.Devices
/// <summary> /// <summary>
/// Sends the SCSI PREVENT ALLOW MEDIUM REMOVAL command to allow medium removal /// Sends the SCSI PREVENT ALLOW MEDIUM REMOVAL command to allow medium removal
/// </summary> /// </summary>
/// <returns><c>true</c>, if allow medium removal was prevented, <c>false</c> otherwise.</returns>
/// <returns><c>true</c> if the command failed and <paramref name="senseBuffer"/> contains the sense buffer.</returns> /// <returns><c>true</c> if the command failed and <paramref name="senseBuffer"/> contains the sense buffer.</returns>
/// <param name="senseBuffer">Sense buffer.</param> /// <param name="senseBuffer">Sense buffer.</param>
/// <param name="timeout">Timeout in seconds.</param> /// <param name="timeout">Timeout in seconds.</param>
@@ -400,7 +398,6 @@ namespace DiscImageChef.Devices
/// <summary> /// <summary>
/// Sends the SCSI PREVENT ALLOW MEDIUM REMOVAL command /// Sends the SCSI PREVENT ALLOW MEDIUM REMOVAL command
/// </summary> /// </summary>
/// <returns><c>true</c>, if allow medium removal was prevented, <c>false</c> otherwise.</returns>
/// <returns><c>true</c> if the command failed and <paramref name="senseBuffer"/> contains the sense buffer.</returns> /// <returns><c>true</c> if the command failed and <paramref name="senseBuffer"/> contains the sense buffer.</returns>
/// <param name="senseBuffer">Sense buffer.</param> /// <param name="senseBuffer">Sense buffer.</param>
/// <param name="timeout">Timeout in seconds.</param> /// <param name="timeout">Timeout in seconds.</param>
@@ -417,7 +414,6 @@ namespace DiscImageChef.Devices
/// <summary> /// <summary>
/// Sends the SCSI PREVENT ALLOW MEDIUM REMOVAL command /// Sends the SCSI PREVENT ALLOW MEDIUM REMOVAL command
/// </summary> /// </summary>
/// <returns><c>true</c>, if allow medium removal was prevented, <c>false</c> otherwise.</returns>
/// <returns><c>true</c> if the command failed and <paramref name="senseBuffer"/> contains the sense buffer.</returns> /// <returns><c>true</c> if the command failed and <paramref name="senseBuffer"/> contains the sense buffer.</returns>
/// <param name="senseBuffer">Sense buffer.</param> /// <param name="senseBuffer">Sense buffer.</param>
/// <param name="timeout">Timeout in seconds.</param> /// <param name="timeout">Timeout in seconds.</param>
@@ -440,6 +436,77 @@ namespace DiscImageChef.Devices
return sense; return sense;
} }
/// <summary>
/// Sends the SCSI GET CONFIGURATION command for all Features
/// </summary>
/// <returns><c>true</c> if the command failed and <paramref name="senseBuffer"/> contains the sense buffer.</returns>
/// <param name="buffer">Buffer where the SCSI GET CONFIGURATION response will be stored</param>
/// <param name="senseBuffer">Sense buffer.</param>
/// <param name="timeout">Timeout in seconds.</param>
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
public bool GetConfiguration(out byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration)
{
return GetConfiguration(out buffer, out senseBuffer, 0x0000, MmcGetConfigurationRt.All, timeout, out duration);
}
/// <summary>
/// Sends the SCSI GET CONFIGURATION command for all Features starting with specified one
/// </summary>
/// <returns><c>true</c> if the command failed and <paramref name="senseBuffer"/> contains the sense buffer.</returns>
/// <param name="buffer">Buffer where the SCSI GET CONFIGURATION response will be stored</param>
/// <param name="senseBuffer">Sense buffer.</param>
/// <param name="timeout">Timeout in seconds.</param>
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
public bool GetConfiguration(out byte[] buffer, out byte[] senseBuffer, ushort startingFeatureNumber, uint timeout, out double duration)
{
return GetConfiguration(out buffer, out senseBuffer, startingFeatureNumber, MmcGetConfigurationRt.All, timeout, out duration);
}
/// <summary>
/// Sends the SCSI GET CONFIGURATION command
/// </summary>
/// <returns><c>true</c> if the command failed and <paramref name="senseBuffer"/> contains the sense buffer.</returns>
/// <param name="buffer">Buffer where the SCSI GET CONFIGURATION response will be stored</param>
/// <param name="senseBuffer">Sense buffer.</param>
/// <param name="timeout">Timeout in seconds.</param>
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
/// <param name="startingFeatureNumber">Starting Feature number.</param>
/// <param name="RT">Return type, <see cref="MmcGetConfigurationRt"/>.</param>
public bool GetConfiguration(out byte[] buffer, out byte[] senseBuffer, ushort startingFeatureNumber, MmcGetConfigurationRt RT, uint timeout, out double duration)
{
senseBuffer = new byte[32];
byte[] cdb = new byte[10];
buffer = new byte[8];
bool sense;
cdb[0] = (byte)ScsiCommands.GetConfiguration;
cdb[1] = (byte)((byte)RT & 0x03);
cdb[2] = (byte)((startingFeatureNumber & 0xFF00) >> 8);
cdb[3] = (byte)(startingFeatureNumber & 0xFF);
cdb[7] = (byte)((buffer.Length & 0xFF00) >> 8);
cdb[8] = (byte)(buffer.Length & 0xFF);
cdb[9] = 0;
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
error = lastError != 0;
if (sense)
return true;
ushort confLength = (ushort)(((int)buffer[2] << 8) + buffer[3] + 2);
buffer = new byte[confLength];
cdb[7] = (byte)((buffer.Length & 0xFF00) >> 8);
cdb[8] = (byte)(buffer.Length & 0xFF);
senseBuffer = new byte[32];
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
error = lastError != 0;
DicConsole.DebugWriteLine("SCSI Device", "GET CONFIGURATION took {0} ms.", duration);
return sense;
}
} }
} }

View File

@@ -2743,5 +2743,22 @@ namespace DiscImageChef.Devices
[Obsolete] [Obsolete]
PreventAll = 0x03 PreventAll = 0x03
} }
public enum MmcGetConfigurationRt : byte
{
/// <summary>
/// Drive shall return the Feature Header and all Feature Descriptors
/// </summary>
All = 0x00,
/// <summary>
/// Drive shall return the Feature Header and current Feature Descriptors
/// </summary>
Current = 0x01,
/// <summary>
/// Drive shall return only the Feature Header with the chosen Feature Descriptor
/// </summary>
Single = 0x02,
Reserved = 0x03
}
} }