Add stubs for remote device commands.

This commit is contained in:
2019-10-13 23:31:56 +01:00
parent 63544feaec
commit 53a8a11408
3 changed files with 257 additions and 179 deletions

View File

@@ -40,7 +40,7 @@ using PlatformID = DiscImageChef.CommonTypes.Interop.PlatformID;
namespace DiscImageChef.Devices namespace DiscImageChef.Devices
{ {
static class Command internal static class Command
{ {
/// <summary> /// <summary>
/// Sends a SCSI command /// Sends a SCSI command
@@ -58,15 +58,15 @@ namespace DiscImageChef.Devices
/// sense /// sense
/// </param> /// </param>
/// <exception cref="InvalidOperationException">If the specified platform is not supported</exception> /// <exception cref="InvalidOperationException">If the specified platform is not supported</exception>
internal static int SendScsiCommand(object fd, byte[] cdb, ref byte[] buffer, internal static int SendScsiCommand(object fd, byte[] cdb, ref byte[] buffer,
out byte[] senseBuffer, out byte[] senseBuffer,
uint timeout, ScsiDirection direction, out double duration, uint timeout, ScsiDirection direction, out double duration,
out bool sense) out bool sense)
{ {
PlatformID ptId = DetectOS.GetRealPlatformID(); var ptId = DetectOS.GetRealPlatformID();
return SendScsiCommand(ptId, fd, cdb, ref buffer, out senseBuffer, timeout, direction, out duration, return SendScsiCommand(ptId, fd, cdb, ref buffer, out senseBuffer, timeout, direction, out duration,
out sense); out sense);
} }
/// <summary> /// <summary>
@@ -87,17 +87,17 @@ namespace DiscImageChef.Devices
/// </param> /// </param>
/// <exception cref="InvalidOperationException">If the specified platform is not supported</exception> /// <exception cref="InvalidOperationException">If the specified platform is not supported</exception>
internal static int SendScsiCommand(PlatformID ptId, object fd, byte[] cdb, internal static int SendScsiCommand(PlatformID ptId, object fd, byte[] cdb,
ref byte[] buffer, ref byte[] buffer,
out byte[] senseBuffer, uint timeout, ScsiDirection direction, out byte[] senseBuffer, uint timeout, ScsiDirection direction,
out double duration, out bool sense) out double duration, out bool sense)
{ {
switch(ptId) switch (ptId)
{ {
case PlatformID.Win32NT: case PlatformID.Win32NT:
{ {
ScsiIoctlDirection dir; ScsiIoctlDirection dir;
switch(direction) switch (direction)
{ {
case ScsiDirection.In: case ScsiDirection.In:
dir = ScsiIoctlDirection.In; dir = ScsiIoctlDirection.In;
@@ -110,14 +110,14 @@ namespace DiscImageChef.Devices
break; break;
} }
return Windows.Command.SendScsiCommand((SafeFileHandle)fd, cdb, ref buffer, out senseBuffer, return Windows.Command.SendScsiCommand((SafeFileHandle) fd, cdb, ref buffer, out senseBuffer,
timeout, dir, out duration, out sense); timeout, dir, out duration, out sense);
} }
case PlatformID.Linux: case PlatformID.Linux:
{ {
Linux.ScsiIoctlDirection dir; Linux.ScsiIoctlDirection dir;
switch(direction) switch (direction)
{ {
case ScsiDirection.In: case ScsiDirection.In:
dir = Linux.ScsiIoctlDirection.In; dir = Linux.ScsiIoctlDirection.In;
@@ -136,14 +136,14 @@ namespace DiscImageChef.Devices
break; break;
} }
return Linux.Command.SendScsiCommand((int)fd, cdb, ref buffer, out senseBuffer, timeout, dir, return Linux.Command.SendScsiCommand((int) fd, cdb, ref buffer, out senseBuffer, timeout, dir,
out duration, out sense); out duration, out sense);
} }
case PlatformID.FreeBSD: case PlatformID.FreeBSD:
{ {
CcbFlags flags = 0; CcbFlags flags = 0;
switch(direction) switch (direction)
{ {
case ScsiDirection.In: case ScsiDirection.In:
flags = CcbFlags.CamDirIn; flags = CcbFlags.CamDirIn;
@@ -160,10 +160,10 @@ namespace DiscImageChef.Devices
} }
return IntPtr.Size == 8 return IntPtr.Size == 8
? FreeBSD.Command.SendScsiCommand64((IntPtr)fd, cdb, ref buffer, out senseBuffer, ? FreeBSD.Command.SendScsiCommand64((IntPtr) fd, cdb, ref buffer, out senseBuffer,
timeout, flags, out duration, out sense) timeout, flags, out duration, out sense)
: FreeBSD.Command.SendScsiCommand((IntPtr)fd, cdb, ref buffer, out senseBuffer, timeout, : FreeBSD.Command.SendScsiCommand((IntPtr) fd, cdb, ref buffer, out senseBuffer, timeout,
flags, out duration, out sense); flags, out duration, out sense);
} }
default: throw new InvalidOperationException($"Platform {ptId} not yet supported."); default: throw new InvalidOperationException($"Platform {ptId} not yet supported.");
} }
@@ -184,18 +184,18 @@ namespace DiscImageChef.Devices
/// <param name="transferRegister">What register contains the transfer length</param> /// <param name="transferRegister">What register contains the transfer length</param>
/// <param name="transferBlocks">Set to <c>true</c> if the transfer length is in block, otherwise it is in bytes</param> /// <param name="transferBlocks">Set to <c>true</c> if the transfer length is in block, otherwise it is in bytes</param>
/// <exception cref="InvalidOperationException">If the specified platform is not supported</exception> /// <exception cref="InvalidOperationException">If the specified platform is not supported</exception>
internal static int SendAtaCommand(object fd, AtaRegistersChs registers, internal static int SendAtaCommand(object fd, AtaRegistersChs registers,
out AtaErrorRegistersChs errorRegisters, AtaProtocol protocol, out AtaErrorRegistersChs errorRegisters, AtaProtocol protocol,
AtaTransferRegister transferRegister, ref byte[] buffer, AtaTransferRegister transferRegister, ref byte[] buffer,
uint timeout, uint timeout,
bool transferBlocks, out double duration, bool transferBlocks, out double duration,
out bool sense) out bool sense)
{ {
PlatformID ptId = DetectOS.GetRealPlatformID(); var ptId = DetectOS.GetRealPlatformID();
return SendAtaCommand(ptId, fd, registers, out errorRegisters, protocol, transferRegister, return SendAtaCommand(ptId, fd, registers, out errorRegisters, protocol, transferRegister,
ref buffer, ref buffer,
timeout, transferBlocks, out duration, out sense); timeout, transferBlocks, out duration, out sense);
} }
/// <summary> /// <summary>
@@ -214,41 +214,41 @@ namespace DiscImageChef.Devices
/// <param name="transferRegister">What register contains the transfer length</param> /// <param name="transferRegister">What register contains the transfer length</param>
/// <param name="transferBlocks">Set to <c>true</c> if the transfer length is in block, otherwise it is in bytes</param> /// <param name="transferBlocks">Set to <c>true</c> if the transfer length is in block, otherwise it is in bytes</param>
/// <exception cref="InvalidOperationException">If the specified platform is not supported</exception> /// <exception cref="InvalidOperationException">If the specified platform is not supported</exception>
internal static int SendAtaCommand(PlatformID ptId, object fd, internal static int SendAtaCommand(PlatformID ptId, object fd,
AtaRegistersChs registers, AtaRegistersChs registers,
out AtaErrorRegistersChs errorRegisters, AtaProtocol protocol, out AtaErrorRegistersChs errorRegisters, AtaProtocol protocol,
AtaTransferRegister transferRegister, ref byte[] buffer, AtaTransferRegister transferRegister, ref byte[] buffer,
uint timeout, uint timeout,
bool transferBlocks, out double duration, bool transferBlocks, out double duration,
out bool sense) out bool sense)
{ {
switch(ptId) switch (ptId)
{ {
case PlatformID.Win32NT: case PlatformID.Win32NT:
{ {
if(Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor == 1 && if (Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor == 1 &&
(Environment.OSVersion.ServicePack == "Service Pack 1" || (Environment.OSVersion.ServicePack == "Service Pack 1" ||
Environment.OSVersion.ServicePack == "") || Environment.OSVersion.ServicePack == "") ||
Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor == 0) Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor == 0)
throw new InvalidOperationException("Windows XP or earlier is not supported."); throw new InvalidOperationException("Windows XP or earlier is not supported.");
// Windows NT 4 or earlier, requires special ATA pass thru SCSI. But DiscImageChef cannot run there (or can it?) // Windows NT 4 or earlier, requires special ATA pass thru SCSI. But DiscImageChef cannot run there (or can it?)
if(Environment.OSVersion.Version.Major <= 4) if (Environment.OSVersion.Version.Major <= 4)
throw new InvalidOperationException("Windows NT 4.0 or earlier is not supported."); throw new InvalidOperationException("Windows NT 4.0 or earlier is not supported.");
return Windows.Command.SendAtaCommand((SafeFileHandle)fd, registers, out errorRegisters, protocol, return Windows.Command.SendAtaCommand((SafeFileHandle) fd, registers, out errorRegisters, protocol,
ref buffer, timeout, out duration, out sense); ref buffer, timeout, out duration, out sense);
} }
case PlatformID.Linux: case PlatformID.Linux:
{ {
return Linux.Command.SendAtaCommand((int)fd, registers, out errorRegisters, protocol, return Linux.Command.SendAtaCommand((int) fd, registers, out errorRegisters, protocol,
transferRegister, ref buffer, timeout, transferBlocks, transferRegister, ref buffer, timeout, transferBlocks,
out duration, out sense); out duration, out sense);
} }
case PlatformID.FreeBSD: case PlatformID.FreeBSD:
{ {
return FreeBSD.Command.SendAtaCommand((IntPtr)fd, registers, out errorRegisters, protocol, return FreeBSD.Command.SendAtaCommand((IntPtr) fd, registers, out errorRegisters, protocol,
ref buffer, timeout, out duration, out sense); ref buffer, timeout, out duration, out sense);
} }
default: throw new InvalidOperationException($"Platform {ptId} not yet supported."); default: throw new InvalidOperationException($"Platform {ptId} not yet supported.");
} }
@@ -269,18 +269,18 @@ namespace DiscImageChef.Devices
/// <param name="transferRegister">What register contains the transfer length</param> /// <param name="transferRegister">What register contains the transfer length</param>
/// <param name="transferBlocks">Set to <c>true</c> if the transfer length is in block, otherwise it is in bytes</param> /// <param name="transferBlocks">Set to <c>true</c> if the transfer length is in block, otherwise it is in bytes</param>
/// <exception cref="InvalidOperationException">If the specified platform is not supported</exception> /// <exception cref="InvalidOperationException">If the specified platform is not supported</exception>
internal static int SendAtaCommand(object fd, AtaRegistersLba28 registers, internal static int SendAtaCommand(object fd, AtaRegistersLba28 registers,
out AtaErrorRegistersLba28 errorRegisters, AtaProtocol protocol, out AtaErrorRegistersLba28 errorRegisters, AtaProtocol protocol,
AtaTransferRegister transferRegister, ref byte[] buffer, AtaTransferRegister transferRegister, ref byte[] buffer,
uint timeout, uint timeout,
bool transferBlocks, out double duration, bool transferBlocks, out double duration,
out bool sense) out bool sense)
{ {
PlatformID ptId = DetectOS.GetRealPlatformID(); var ptId = DetectOS.GetRealPlatformID();
return SendAtaCommand(ptId, fd, registers, out errorRegisters, protocol, transferRegister, return SendAtaCommand(ptId, fd, registers, out errorRegisters, protocol, transferRegister,
ref buffer, ref buffer,
timeout, transferBlocks, out duration, out sense); timeout, transferBlocks, out duration, out sense);
} }
/// <summary> /// <summary>
@@ -299,41 +299,41 @@ namespace DiscImageChef.Devices
/// <param name="transferRegister">What register contains the transfer length</param> /// <param name="transferRegister">What register contains the transfer length</param>
/// <param name="transferBlocks">Set to <c>true</c> if the transfer length is in block, otherwise it is in bytes</param> /// <param name="transferBlocks">Set to <c>true</c> if the transfer length is in block, otherwise it is in bytes</param>
/// <exception cref="InvalidOperationException">If the specified platform is not supported</exception> /// <exception cref="InvalidOperationException">If the specified platform is not supported</exception>
internal static int SendAtaCommand(PlatformID ptId, object fd, internal static int SendAtaCommand(PlatformID ptId, object fd,
AtaRegistersLba28 registers, AtaRegistersLba28 registers,
out AtaErrorRegistersLba28 errorRegisters, AtaProtocol protocol, out AtaErrorRegistersLba28 errorRegisters, AtaProtocol protocol,
AtaTransferRegister transferRegister, ref byte[] buffer, AtaTransferRegister transferRegister, ref byte[] buffer,
uint timeout, uint timeout,
bool transferBlocks, out double duration, bool transferBlocks, out double duration,
out bool sense) out bool sense)
{ {
switch(ptId) switch (ptId)
{ {
case PlatformID.Win32NT: case PlatformID.Win32NT:
{ {
if(Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor == 1 && if (Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor == 1 &&
(Environment.OSVersion.ServicePack == "Service Pack 1" || (Environment.OSVersion.ServicePack == "Service Pack 1" ||
Environment.OSVersion.ServicePack == "") || Environment.OSVersion.ServicePack == "") ||
Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor == 0) Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor == 0)
throw new InvalidOperationException("Windows XP or earlier is not supported."); throw new InvalidOperationException("Windows XP or earlier is not supported.");
// Windows NT 4 or earlier, requires special ATA pass thru SCSI. But DiscImageChef cannot run there (or can it?) // Windows NT 4 or earlier, requires special ATA pass thru SCSI. But DiscImageChef cannot run there (or can it?)
if(Environment.OSVersion.Version.Major <= 4) if (Environment.OSVersion.Version.Major <= 4)
throw new InvalidOperationException("Windows NT 4.0 or earlier is not supported."); throw new InvalidOperationException("Windows NT 4.0 or earlier is not supported.");
return Windows.Command.SendAtaCommand((SafeFileHandle)fd, registers, out errorRegisters, protocol, return Windows.Command.SendAtaCommand((SafeFileHandle) fd, registers, out errorRegisters, protocol,
ref buffer, timeout, out duration, out sense); ref buffer, timeout, out duration, out sense);
} }
case PlatformID.Linux: case PlatformID.Linux:
{ {
return Linux.Command.SendAtaCommand((int)fd, registers, out errorRegisters, protocol, return Linux.Command.SendAtaCommand((int) fd, registers, out errorRegisters, protocol,
transferRegister, ref buffer, timeout, transferBlocks, transferRegister, ref buffer, timeout, transferBlocks,
out duration, out sense); out duration, out sense);
} }
case PlatformID.FreeBSD: case PlatformID.FreeBSD:
{ {
return FreeBSD.Command.SendAtaCommand((IntPtr)fd, registers, out errorRegisters, protocol, return FreeBSD.Command.SendAtaCommand((IntPtr) fd, registers, out errorRegisters, protocol,
ref buffer, timeout, out duration, out sense); ref buffer, timeout, out duration, out sense);
} }
default: throw new InvalidOperationException($"Platform {ptId} not yet supported."); default: throw new InvalidOperationException($"Platform {ptId} not yet supported.");
} }
@@ -354,18 +354,18 @@ namespace DiscImageChef.Devices
/// <param name="transferRegister">What register contains the transfer length</param> /// <param name="transferRegister">What register contains the transfer length</param>
/// <param name="transferBlocks">Set to <c>true</c> if the transfer length is in block, otherwise it is in bytes</param> /// <param name="transferBlocks">Set to <c>true</c> if the transfer length is in block, otherwise it is in bytes</param>
/// <exception cref="InvalidOperationException">If the specified platform is not supported</exception> /// <exception cref="InvalidOperationException">If the specified platform is not supported</exception>
internal static int SendAtaCommand(object fd, AtaRegistersLba48 registers, internal static int SendAtaCommand(object fd, AtaRegistersLba48 registers,
out AtaErrorRegistersLba48 errorRegisters, AtaProtocol protocol, out AtaErrorRegistersLba48 errorRegisters, AtaProtocol protocol,
AtaTransferRegister transferRegister, ref byte[] buffer, AtaTransferRegister transferRegister, ref byte[] buffer,
uint timeout, uint timeout,
bool transferBlocks, out double duration, bool transferBlocks, out double duration,
out bool sense) out bool sense)
{ {
PlatformID ptId = DetectOS.GetRealPlatformID(); var ptId = DetectOS.GetRealPlatformID();
return SendAtaCommand(ptId, fd, registers, out errorRegisters, protocol, transferRegister, return SendAtaCommand(ptId, fd, registers, out errorRegisters, protocol, transferRegister,
ref buffer, ref buffer,
timeout, transferBlocks, out duration, out sense); timeout, transferBlocks, out duration, out sense);
} }
/// <summary> /// <summary>
@@ -384,32 +384,32 @@ namespace DiscImageChef.Devices
/// <param name="transferRegister">What register contains the transfer length</param> /// <param name="transferRegister">What register contains the transfer length</param>
/// <param name="transferBlocks">Set to <c>true</c> if the transfer length is in block, otherwise it is in bytes</param> /// <param name="transferBlocks">Set to <c>true</c> if the transfer length is in block, otherwise it is in bytes</param>
/// <exception cref="InvalidOperationException">If the specified platform is not supported</exception> /// <exception cref="InvalidOperationException">If the specified platform is not supported</exception>
internal static int SendAtaCommand(PlatformID ptId, object fd, internal static int SendAtaCommand(PlatformID ptId, object fd,
AtaRegistersLba48 registers, AtaRegistersLba48 registers,
out AtaErrorRegistersLba48 errorRegisters, AtaProtocol protocol, out AtaErrorRegistersLba48 errorRegisters, AtaProtocol protocol,
AtaTransferRegister transferRegister, ref byte[] buffer, AtaTransferRegister transferRegister, ref byte[] buffer,
uint timeout, uint timeout,
bool transferBlocks, out double duration, bool transferBlocks, out double duration,
out bool sense) out bool sense)
{ {
switch(ptId) switch (ptId)
{ {
case PlatformID.Win32NT: case PlatformID.Win32NT:
{ {
// No check for Windows version. A 48-bit ATA disk simply does not work on earlier systems // No check for Windows version. A 48-bit ATA disk simply does not work on earlier systems
return Windows.Command.SendAtaCommand((SafeFileHandle)fd, registers, out errorRegisters, protocol, return Windows.Command.SendAtaCommand((SafeFileHandle) fd, registers, out errorRegisters, protocol,
ref buffer, timeout, out duration, out sense); ref buffer, timeout, out duration, out sense);
} }
case PlatformID.Linux: case PlatformID.Linux:
{ {
return Linux.Command.SendAtaCommand((int)fd, registers, out errorRegisters, protocol, return Linux.Command.SendAtaCommand((int) fd, registers, out errorRegisters, protocol,
transferRegister, ref buffer, timeout, transferBlocks, transferRegister, ref buffer, timeout, transferBlocks,
out duration, out sense); out duration, out sense);
} }
case PlatformID.FreeBSD: case PlatformID.FreeBSD:
{ {
return FreeBSD.Command.SendAtaCommand((IntPtr)fd, registers, out errorRegisters, protocol, return FreeBSD.Command.SendAtaCommand((IntPtr) fd, registers, out errorRegisters, protocol,
ref buffer, timeout, out duration, out sense); ref buffer, timeout, out duration, out sense);
} }
default: throw new InvalidOperationException($"Platform {ptId} not yet supported."); default: throw new InvalidOperationException($"Platform {ptId} not yet supported.");
} }
@@ -433,19 +433,19 @@ namespace DiscImageChef.Devices
/// <param name="response">Response registers</param> /// <param name="response">Response registers</param>
/// <param name="blockSize">Size of block in bytes</param> /// <param name="blockSize">Size of block in bytes</param>
/// <exception cref="InvalidOperationException">If the specified platform is not supported</exception> /// <exception cref="InvalidOperationException">If the specified platform is not supported</exception>
internal static int SendMmcCommand(object fd, MmcCommands command, bool write, internal static int SendMmcCommand(object fd, MmcCommands command, bool write,
bool isApplication, bool isApplication,
MmcFlags flags, uint argument, uint blockSize, MmcFlags flags, uint argument, uint blockSize,
uint blocks, uint blocks,
ref byte[] buffer, out uint[] response, out double duration, ref byte[] buffer, out uint[] response, out double duration,
out bool sense, out bool sense,
uint timeout = 0) uint timeout = 0)
{ {
PlatformID ptId = DetectOS.GetRealPlatformID(); var ptId = DetectOS.GetRealPlatformID();
return SendMmcCommand(ptId, (int)fd, command, write, isApplication, flags, argument, return SendMmcCommand(ptId, (int) fd, command, write, isApplication, flags, argument,
blockSize, blocks, blockSize, blocks,
ref buffer, out response, out duration, out sense, timeout); ref buffer, out response, out duration, out sense, timeout);
} }
/// <summary> /// <summary>
@@ -468,26 +468,26 @@ namespace DiscImageChef.Devices
/// <param name="blockSize">Size of block in bytes</param> /// <param name="blockSize">Size of block in bytes</param>
/// <exception cref="InvalidOperationException">If the specified platform is not supported</exception> /// <exception cref="InvalidOperationException">If the specified platform is not supported</exception>
internal static int SendMmcCommand(PlatformID ptId, object fd, MmcCommands command, internal static int SendMmcCommand(PlatformID ptId, object fd, MmcCommands command,
bool write, bool write,
bool isApplication, MmcFlags flags, uint argument, bool isApplication, MmcFlags flags, uint argument,
uint blockSize, uint blockSize,
uint blocks, ref byte[] buffer, out uint[] response, uint blocks, ref byte[] buffer, out uint[] response,
out double duration, out double duration,
out bool sense, uint timeout = 0) out bool sense, uint timeout = 0)
{ {
switch(ptId) switch (ptId)
{ {
case PlatformID.Win32NT: case PlatformID.Win32NT:
{ {
return Windows.Command.SendMmcCommand((SafeFileHandle)fd, command, write, isApplication, flags, return Windows.Command.SendMmcCommand((SafeFileHandle) fd, command, write, isApplication, flags,
argument, blockSize, blocks, ref buffer, out response, argument, blockSize, blocks, ref buffer, out response,
out duration, out sense, timeout); out duration, out sense, timeout);
} }
case PlatformID.Linux: case PlatformID.Linux:
{ {
return Linux.Command.SendMmcCommand((int)fd, command, write, isApplication, flags, argument, return Linux.Command.SendMmcCommand((int) fd, command, write, isApplication, flags, argument,
blockSize, blocks, ref buffer, out response, out duration, blockSize, blocks, ref buffer, out response, out duration,
out sense, timeout); out sense, timeout);
} }
default: throw new InvalidOperationException($"Platform {ptId} not yet supported."); default: throw new InvalidOperationException($"Platform {ptId} not yet supported.");
} }

View File

@@ -53,10 +53,16 @@ namespace DiscImageChef.Devices
/// <c>True</c> if SCSI command returned non-OK status and <paramref name="senseBuffer" /> contains /// <c>True</c> if SCSI command returned non-OK status and <paramref name="senseBuffer" /> contains
/// SCSI sense /// SCSI sense
/// </param> /// </param>
public int SendScsiCommand(byte[] cdb, ref byte[] buffer, out byte[] senseBuffer, uint timeout, public int SendScsiCommand(byte[] cdb, ref byte[] buffer, out byte[] senseBuffer, uint timeout,
ScsiDirection direction, out double duration, out bool sense) => ScsiDirection direction, out double duration, out bool sense)
Command.SendScsiCommand(PlatformId, FileHandle, cdb, ref buffer, out senseBuffer, timeout, direction, {
out duration, out sense); if (!(remote is null))
return remote.SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout,
direction, out duration, out sense);
return Command.SendScsiCommand(PlatformId, FileHandle, cdb, ref buffer, out senseBuffer, timeout, direction,
out duration, out sense);
}
/// <summary> /// <summary>
/// Sends an ATA/ATAPI command to this device using CHS addressing /// Sends an ATA/ATAPI command to this device using CHS addressing
@@ -75,12 +81,17 @@ namespace DiscImageChef.Devices
/// <param name="duration">Time it took to execute the command in milliseconds</param> /// <param name="duration">Time it took to execute the command in milliseconds</param>
/// <param name="sense"><c>True</c> if ATA/ATAPI command returned non-OK status</param> /// <param name="sense"><c>True</c> if ATA/ATAPI command returned non-OK status</param>
public int SendAtaCommand(AtaRegistersChs registers, out AtaErrorRegistersChs errorRegisters, public int SendAtaCommand(AtaRegistersChs registers, out AtaErrorRegistersChs errorRegisters,
AtaProtocol protocol, AtaTransferRegister transferRegister, AtaProtocol protocol, AtaTransferRegister transferRegister,
ref byte[] buffer, ref byte[] buffer,
uint timeout, bool transferBlocks, uint timeout, bool transferBlocks,
out double duration, out bool sense) => out double duration, out bool sense)
Command.SendAtaCommand(PlatformId, FileHandle, registers, out errorRegisters, protocol, transferRegister, {
ref buffer, timeout, transferBlocks, out duration, out sense); if (!(remote is null)) throw new NotImplementedException("Remote CHS ATA commands not yet implemented...");
return Command.SendAtaCommand(PlatformId, FileHandle, registers, out errorRegisters, protocol,
transferRegister,
ref buffer, timeout, transferBlocks, out duration, out sense);
}
/// <summary> /// <summary>
/// Sends an ATA/ATAPI command to this device using 28-bit LBA addressing /// Sends an ATA/ATAPI command to this device using 28-bit LBA addressing
@@ -99,12 +110,22 @@ namespace DiscImageChef.Devices
/// <param name="duration">Time it took to execute the command in milliseconds</param> /// <param name="duration">Time it took to execute the command in milliseconds</param>
/// <param name="sense"><c>True</c> if ATA/ATAPI command returned non-OK status</param> /// <param name="sense"><c>True</c> if ATA/ATAPI command returned non-OK status</param>
public int SendAtaCommand(AtaRegistersLba28 registers, out AtaErrorRegistersLba28 errorRegisters, public int SendAtaCommand(AtaRegistersLba28 registers, out AtaErrorRegistersLba28 errorRegisters,
AtaProtocol protocol, AtaTransferRegister transferRegister, AtaProtocol protocol, AtaTransferRegister transferRegister,
ref byte[] buffer, ref byte[] buffer,
uint timeout, bool transferBlocks, uint timeout, bool transferBlocks,
out double duration, out bool sense) => out double duration, out bool sense)
Command.SendAtaCommand(PlatformId, FileHandle, registers, out errorRegisters, protocol, transferRegister, {
ref buffer, timeout, transferBlocks, out duration, out sense); if (!(remote is null))
remote.SendAtaCommand(registers, out errorRegisters,
protocol, transferRegister,
ref buffer,
timeout, transferBlocks,
out duration, out sense);
return Command.SendAtaCommand(PlatformId, FileHandle, registers, out errorRegisters, protocol,
transferRegister,
ref buffer, timeout, transferBlocks, out duration, out sense);
}
/// <summary> /// <summary>
/// Sends an ATA/ATAPI command to this device using 48-bit LBA addressing /// Sends an ATA/ATAPI command to this device using 48-bit LBA addressing
@@ -123,12 +144,22 @@ namespace DiscImageChef.Devices
/// <param name="duration">Time it took to execute the command in milliseconds</param> /// <param name="duration">Time it took to execute the command in milliseconds</param>
/// <param name="sense"><c>True</c> if ATA/ATAPI command returned non-OK status</param> /// <param name="sense"><c>True</c> if ATA/ATAPI command returned non-OK status</param>
public int SendAtaCommand(AtaRegistersLba48 registers, out AtaErrorRegistersLba48 errorRegisters, public int SendAtaCommand(AtaRegistersLba48 registers, out AtaErrorRegistersLba48 errorRegisters,
AtaProtocol protocol, AtaTransferRegister transferRegister, AtaProtocol protocol, AtaTransferRegister transferRegister,
ref byte[] buffer, ref byte[] buffer,
uint timeout, bool transferBlocks, uint timeout, bool transferBlocks,
out double duration, out bool sense) => out double duration, out bool sense)
Command.SendAtaCommand(PlatformId, FileHandle, registers, out errorRegisters, protocol, transferRegister, {
ref buffer, timeout, transferBlocks, out duration, out sense); if (!(remote is null))
remote.SendAtaCommand(registers, out errorRegisters,
protocol, transferRegister,
ref buffer,
timeout, transferBlocks,
out duration, out sense);
return Command.SendAtaCommand(PlatformId, FileHandle, registers, out errorRegisters, protocol,
transferRegister,
ref buffer, timeout, transferBlocks, out duration, out sense);
}
/// <summary> /// <summary>
/// Sends a MMC/SD command to this device /// Sends a MMC/SD command to this device
@@ -147,63 +178,68 @@ namespace DiscImageChef.Devices
/// <param name="response">Response registers</param> /// <param name="response">Response registers</param>
/// <param name="blockSize">Size of block in bytes</param> /// <param name="blockSize">Size of block in bytes</param>
public int SendMmcCommand(MmcCommands command, bool write, bool isApplication, MmcFlags flags, public int SendMmcCommand(MmcCommands command, bool write, bool isApplication, MmcFlags flags,
uint argument, uint argument,
uint blockSize, uint blocks, ref byte[] buffer, out uint[] response, uint blockSize, uint blocks, ref byte[] buffer, out uint[] response,
out double duration, out bool sense, uint timeout = 0) out double duration, out bool sense, uint timeout = 0)
{ {
switch(command) switch (command)
{ {
case MmcCommands.SendCid when cachedCid != null: case MmcCommands.SendCid when cachedCid != null:
{ {
DateTime start = DateTime.Now; var start = DateTime.Now;
buffer = new byte[cachedCid.Length]; buffer = new byte[cachedCid.Length];
Array.Copy(cachedCid, buffer, buffer.Length); Array.Copy(cachedCid, buffer, buffer.Length);
response = new uint[4]; response = new uint[4];
sense = false; sense = false;
DateTime end = DateTime.Now; var end = DateTime.Now;
duration = (end - start).TotalMilliseconds; duration = (end - start).TotalMilliseconds;
return 0; return 0;
} }
case MmcCommands.SendCsd when cachedCid != null: case MmcCommands.SendCsd when cachedCid != null:
{ {
DateTime start = DateTime.Now; var start = DateTime.Now;
buffer = new byte[cachedCsd.Length]; buffer = new byte[cachedCsd.Length];
Array.Copy(cachedCsd, buffer, buffer.Length); Array.Copy(cachedCsd, buffer, buffer.Length);
response = new uint[4]; response = new uint[4];
sense = false; sense = false;
DateTime end = DateTime.Now; var end = DateTime.Now;
duration = (end - start).TotalMilliseconds; duration = (end - start).TotalMilliseconds;
return 0; return 0;
} }
case (MmcCommands)SecureDigitalCommands.SendScr when cachedScr != null: case (MmcCommands) SecureDigitalCommands.SendScr when cachedScr != null:
{ {
DateTime start = DateTime.Now; var start = DateTime.Now;
buffer = new byte[cachedScr.Length]; buffer = new byte[cachedScr.Length];
Array.Copy(cachedScr, buffer, buffer.Length); Array.Copy(cachedScr, buffer, buffer.Length);
response = new uint[4]; response = new uint[4];
sense = false; sense = false;
DateTime end = DateTime.Now; var end = DateTime.Now;
duration = (end - start).TotalMilliseconds;
return 0;
}
case (MmcCommands) SecureDigitalCommands.SendOperatingCondition when cachedOcr != null:
case MmcCommands.SendOpCond when cachedOcr != null:
{
var start = DateTime.Now;
buffer = new byte[cachedOcr.Length];
Array.Copy(cachedOcr, buffer, buffer.Length);
response = new uint[4];
sense = false;
var end = DateTime.Now;
duration = (end - start).TotalMilliseconds; duration = (end - start).TotalMilliseconds;
return 0; return 0;
} }
} }
if(command != (MmcCommands)SecureDigitalCommands.SendOperatingCondition && if (!(remote is null))
command != MmcCommands.SendOpCond || cachedOcr == null) remote.SendMmcCommand(command, write, isApplication, flags,
return Command.SendMmcCommand(PlatformId, FileHandle, command, write, isApplication, flags, argument, argument,
blockSize, blocks, ref buffer, out response, out duration, out sense, blockSize, blocks, ref buffer, out response,
timeout); out duration, out sense, timeout);
{ return Command.SendMmcCommand(PlatformId, FileHandle, command, write, isApplication, flags, argument,
DateTime start = DateTime.Now; blockSize, blocks, ref buffer, out response, out duration, out sense,
buffer = new byte[cachedOcr.Length]; timeout);
Array.Copy(cachedOcr, buffer, buffer.Length);
response = new uint[4];
sense = false;
DateTime end = DateTime.Now;
duration = (end - start).TotalMilliseconds;
return 0;
}
} }
} }
} }

View File

@@ -7,6 +7,7 @@ using System.Net.Sockets;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using DiscImageChef.CommonTypes.Interop; using DiscImageChef.CommonTypes.Interop;
using DiscImageChef.Console; using DiscImageChef.Console;
using DiscImageChef.Decoders.ATA;
using Marshal = DiscImageChef.Helpers.Marshal; using Marshal = DiscImageChef.Helpers.Marshal;
using Version = DiscImageChef.CommonTypes.Interop.Version; using Version = DiscImageChef.CommonTypes.Interop.Version;
@@ -325,5 +326,46 @@ namespace DiscImageChef.Devices.Remote
LastError = nop.errno; LastError = nop.errno;
return false; return false;
} }
public int SendScsiCommand(byte[] cdb, ref byte[] buffer, out byte[] senseBuffer, uint timeout,
ScsiDirection direction, out double duration, out bool sense)
{
throw new NotImplementedException("Remote SCSI commands not yet implemented...");
}
public int SendAtaCommand(AtaRegistersChs registers, out AtaErrorRegistersChs errorRegisters,
AtaProtocol protocol, AtaTransferRegister transferRegister,
ref byte[] buffer,
uint timeout, bool transferBlocks,
out double duration, out bool sense)
{
throw new NotImplementedException("Remote CHS ATA commands not yet implemented...");
}
public int SendAtaCommand(AtaRegistersLba28 registers, out AtaErrorRegistersLba28 errorRegisters,
AtaProtocol protocol, AtaTransferRegister transferRegister,
ref byte[] buffer,
uint timeout, bool transferBlocks,
out double duration, out bool sense)
{
throw new NotImplementedException("Remote 28-bit ATA commands not yet implemented...");
}
public int SendAtaCommand(AtaRegistersLba48 registers, out AtaErrorRegistersLba48 errorRegisters,
AtaProtocol protocol, AtaTransferRegister transferRegister,
ref byte[] buffer,
uint timeout, bool transferBlocks,
out double duration, out bool sense)
{
throw new NotImplementedException("Remote 48-bit ATA commands not yet implemented...");
}
public int SendMmcCommand(MmcCommands command, bool write, bool isApplication, MmcFlags flags,
uint argument,
uint blockSize, uint blocks, ref byte[] buffer, out uint[] response,
out double duration, out bool sense, uint timeout = 0)
{
throw new NotImplementedException("Remote SDHCI commands not yet implemented...");
}
} }
} }