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
{
static class Command
internal static class Command
{
/// <summary>
/// Sends a SCSI command
@@ -58,15 +58,15 @@ namespace DiscImageChef.Devices
/// sense
/// </param>
/// <exception cref="InvalidOperationException">If the specified platform is not supported</exception>
internal static int SendScsiCommand(object fd, byte[] cdb, ref byte[] buffer,
out byte[] senseBuffer,
uint timeout, ScsiDirection direction, out double duration,
out bool sense)
internal static int SendScsiCommand(object fd, byte[] cdb, ref byte[] buffer,
out byte[] senseBuffer,
uint timeout, ScsiDirection direction, out double duration,
out bool sense)
{
PlatformID ptId = DetectOS.GetRealPlatformID();
var ptId = DetectOS.GetRealPlatformID();
return SendScsiCommand(ptId, fd, cdb, ref buffer, out senseBuffer, timeout, direction, out duration,
out sense);
out sense);
}
/// <summary>
@@ -87,17 +87,17 @@ namespace DiscImageChef.Devices
/// </param>
/// <exception cref="InvalidOperationException">If the specified platform is not supported</exception>
internal static int SendScsiCommand(PlatformID ptId, object fd, byte[] cdb,
ref byte[] buffer,
out byte[] senseBuffer, uint timeout, ScsiDirection direction,
out double duration, out bool sense)
ref byte[] buffer,
out byte[] senseBuffer, uint timeout, ScsiDirection direction,
out double duration, out bool sense)
{
switch(ptId)
switch (ptId)
{
case PlatformID.Win32NT:
{
ScsiIoctlDirection dir;
switch(direction)
switch (direction)
{
case ScsiDirection.In:
dir = ScsiIoctlDirection.In;
@@ -110,14 +110,14 @@ namespace DiscImageChef.Devices
break;
}
return Windows.Command.SendScsiCommand((SafeFileHandle)fd, cdb, ref buffer, out senseBuffer,
timeout, dir, out duration, out sense);
return Windows.Command.SendScsiCommand((SafeFileHandle) fd, cdb, ref buffer, out senseBuffer,
timeout, dir, out duration, out sense);
}
case PlatformID.Linux:
{
Linux.ScsiIoctlDirection dir;
switch(direction)
switch (direction)
{
case ScsiDirection.In:
dir = Linux.ScsiIoctlDirection.In;
@@ -136,14 +136,14 @@ namespace DiscImageChef.Devices
break;
}
return Linux.Command.SendScsiCommand((int)fd, cdb, ref buffer, out senseBuffer, timeout, dir,
out duration, out sense);
return Linux.Command.SendScsiCommand((int) fd, cdb, ref buffer, out senseBuffer, timeout, dir,
out duration, out sense);
}
case PlatformID.FreeBSD:
{
CcbFlags flags = 0;
switch(direction)
switch (direction)
{
case ScsiDirection.In:
flags = CcbFlags.CamDirIn;
@@ -160,10 +160,10 @@ namespace DiscImageChef.Devices
}
return IntPtr.Size == 8
? FreeBSD.Command.SendScsiCommand64((IntPtr)fd, cdb, ref buffer, out senseBuffer,
timeout, flags, out duration, out sense)
: FreeBSD.Command.SendScsiCommand((IntPtr)fd, cdb, ref buffer, out senseBuffer, timeout,
flags, out duration, out sense);
? FreeBSD.Command.SendScsiCommand64((IntPtr) fd, cdb, ref buffer, out senseBuffer,
timeout, flags, out duration, out sense)
: FreeBSD.Command.SendScsiCommand((IntPtr) fd, cdb, ref buffer, out senseBuffer, timeout,
flags, out duration, out sense);
}
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="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>
internal static int SendAtaCommand(object fd, AtaRegistersChs registers,
out AtaErrorRegistersChs errorRegisters, AtaProtocol protocol,
AtaTransferRegister transferRegister, ref byte[] buffer,
uint timeout,
bool transferBlocks, out double duration,
out bool sense)
internal static int SendAtaCommand(object fd, AtaRegistersChs registers,
out AtaErrorRegistersChs errorRegisters, AtaProtocol protocol,
AtaTransferRegister transferRegister, ref byte[] buffer,
uint timeout,
bool transferBlocks, out double duration,
out bool sense)
{
PlatformID ptId = DetectOS.GetRealPlatformID();
var ptId = DetectOS.GetRealPlatformID();
return SendAtaCommand(ptId, fd, registers, out errorRegisters, protocol, transferRegister,
ref buffer,
timeout, transferBlocks, out duration, out sense);
ref buffer,
timeout, transferBlocks, out duration, out sense);
}
/// <summary>
@@ -214,41 +214,41 @@ namespace DiscImageChef.Devices
/// <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>
/// <exception cref="InvalidOperationException">If the specified platform is not supported</exception>
internal static int SendAtaCommand(PlatformID ptId, object fd,
AtaRegistersChs registers,
out AtaErrorRegistersChs errorRegisters, AtaProtocol protocol,
AtaTransferRegister transferRegister, ref byte[] buffer,
uint timeout,
bool transferBlocks, out double duration,
out bool sense)
internal static int SendAtaCommand(PlatformID ptId, object fd,
AtaRegistersChs registers,
out AtaErrorRegistersChs errorRegisters, AtaProtocol protocol,
AtaTransferRegister transferRegister, ref byte[] buffer,
uint timeout,
bool transferBlocks, out double duration,
out bool sense)
{
switch(ptId)
switch (ptId)
{
case PlatformID.Win32NT:
{
if(Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor == 1 &&
(Environment.OSVersion.ServicePack == "Service Pack 1" ||
Environment.OSVersion.ServicePack == "") ||
Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor == 0)
if (Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor == 1 &&
(Environment.OSVersion.ServicePack == "Service Pack 1" ||
Environment.OSVersion.ServicePack == "") ||
Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor == 0)
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?)
if(Environment.OSVersion.Version.Major <= 4)
if (Environment.OSVersion.Version.Major <= 4)
throw new InvalidOperationException("Windows NT 4.0 or earlier is not supported.");
return Windows.Command.SendAtaCommand((SafeFileHandle)fd, registers, out errorRegisters, protocol,
ref buffer, timeout, out duration, out sense);
return Windows.Command.SendAtaCommand((SafeFileHandle) fd, registers, out errorRegisters, protocol,
ref buffer, timeout, out duration, out sense);
}
case PlatformID.Linux:
{
return Linux.Command.SendAtaCommand((int)fd, registers, out errorRegisters, protocol,
transferRegister, ref buffer, timeout, transferBlocks,
out duration, out sense);
return Linux.Command.SendAtaCommand((int) fd, registers, out errorRegisters, protocol,
transferRegister, ref buffer, timeout, transferBlocks,
out duration, out sense);
}
case PlatformID.FreeBSD:
{
return FreeBSD.Command.SendAtaCommand((IntPtr)fd, registers, out errorRegisters, protocol,
ref buffer, timeout, out duration, out sense);
return FreeBSD.Command.SendAtaCommand((IntPtr) fd, registers, out errorRegisters, protocol,
ref buffer, timeout, out duration, out sense);
}
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="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>
internal static int SendAtaCommand(object fd, AtaRegistersLba28 registers,
out AtaErrorRegistersLba28 errorRegisters, AtaProtocol protocol,
AtaTransferRegister transferRegister, ref byte[] buffer,
uint timeout,
bool transferBlocks, out double duration,
out bool sense)
internal static int SendAtaCommand(object fd, AtaRegistersLba28 registers,
out AtaErrorRegistersLba28 errorRegisters, AtaProtocol protocol,
AtaTransferRegister transferRegister, ref byte[] buffer,
uint timeout,
bool transferBlocks, out double duration,
out bool sense)
{
PlatformID ptId = DetectOS.GetRealPlatformID();
var ptId = DetectOS.GetRealPlatformID();
return SendAtaCommand(ptId, fd, registers, out errorRegisters, protocol, transferRegister,
ref buffer,
timeout, transferBlocks, out duration, out sense);
ref buffer,
timeout, transferBlocks, out duration, out sense);
}
/// <summary>
@@ -299,41 +299,41 @@ namespace DiscImageChef.Devices
/// <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>
/// <exception cref="InvalidOperationException">If the specified platform is not supported</exception>
internal static int SendAtaCommand(PlatformID ptId, object fd,
AtaRegistersLba28 registers,
out AtaErrorRegistersLba28 errorRegisters, AtaProtocol protocol,
AtaTransferRegister transferRegister, ref byte[] buffer,
uint timeout,
bool transferBlocks, out double duration,
out bool sense)
internal static int SendAtaCommand(PlatformID ptId, object fd,
AtaRegistersLba28 registers,
out AtaErrorRegistersLba28 errorRegisters, AtaProtocol protocol,
AtaTransferRegister transferRegister, ref byte[] buffer,
uint timeout,
bool transferBlocks, out double duration,
out bool sense)
{
switch(ptId)
switch (ptId)
{
case PlatformID.Win32NT:
{
if(Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor == 1 &&
(Environment.OSVersion.ServicePack == "Service Pack 1" ||
Environment.OSVersion.ServicePack == "") ||
Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor == 0)
if (Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor == 1 &&
(Environment.OSVersion.ServicePack == "Service Pack 1" ||
Environment.OSVersion.ServicePack == "") ||
Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor == 0)
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?)
if(Environment.OSVersion.Version.Major <= 4)
if (Environment.OSVersion.Version.Major <= 4)
throw new InvalidOperationException("Windows NT 4.0 or earlier is not supported.");
return Windows.Command.SendAtaCommand((SafeFileHandle)fd, registers, out errorRegisters, protocol,
ref buffer, timeout, out duration, out sense);
return Windows.Command.SendAtaCommand((SafeFileHandle) fd, registers, out errorRegisters, protocol,
ref buffer, timeout, out duration, out sense);
}
case PlatformID.Linux:
{
return Linux.Command.SendAtaCommand((int)fd, registers, out errorRegisters, protocol,
transferRegister, ref buffer, timeout, transferBlocks,
out duration, out sense);
return Linux.Command.SendAtaCommand((int) fd, registers, out errorRegisters, protocol,
transferRegister, ref buffer, timeout, transferBlocks,
out duration, out sense);
}
case PlatformID.FreeBSD:
{
return FreeBSD.Command.SendAtaCommand((IntPtr)fd, registers, out errorRegisters, protocol,
ref buffer, timeout, out duration, out sense);
return FreeBSD.Command.SendAtaCommand((IntPtr) fd, registers, out errorRegisters, protocol,
ref buffer, timeout, out duration, out sense);
}
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="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>
internal static int SendAtaCommand(object fd, AtaRegistersLba48 registers,
out AtaErrorRegistersLba48 errorRegisters, AtaProtocol protocol,
AtaTransferRegister transferRegister, ref byte[] buffer,
uint timeout,
bool transferBlocks, out double duration,
out bool sense)
internal static int SendAtaCommand(object fd, AtaRegistersLba48 registers,
out AtaErrorRegistersLba48 errorRegisters, AtaProtocol protocol,
AtaTransferRegister transferRegister, ref byte[] buffer,
uint timeout,
bool transferBlocks, out double duration,
out bool sense)
{
PlatformID ptId = DetectOS.GetRealPlatformID();
var ptId = DetectOS.GetRealPlatformID();
return SendAtaCommand(ptId, fd, registers, out errorRegisters, protocol, transferRegister,
ref buffer,
timeout, transferBlocks, out duration, out sense);
ref buffer,
timeout, transferBlocks, out duration, out sense);
}
/// <summary>
@@ -384,32 +384,32 @@ namespace DiscImageChef.Devices
/// <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>
/// <exception cref="InvalidOperationException">If the specified platform is not supported</exception>
internal static int SendAtaCommand(PlatformID ptId, object fd,
AtaRegistersLba48 registers,
out AtaErrorRegistersLba48 errorRegisters, AtaProtocol protocol,
AtaTransferRegister transferRegister, ref byte[] buffer,
uint timeout,
bool transferBlocks, out double duration,
out bool sense)
internal static int SendAtaCommand(PlatformID ptId, object fd,
AtaRegistersLba48 registers,
out AtaErrorRegistersLba48 errorRegisters, AtaProtocol protocol,
AtaTransferRegister transferRegister, ref byte[] buffer,
uint timeout,
bool transferBlocks, out double duration,
out bool sense)
{
switch(ptId)
switch (ptId)
{
case PlatformID.Win32NT:
{
// 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,
ref buffer, timeout, out duration, out sense);
return Windows.Command.SendAtaCommand((SafeFileHandle) fd, registers, out errorRegisters, protocol,
ref buffer, timeout, out duration, out sense);
}
case PlatformID.Linux:
{
return Linux.Command.SendAtaCommand((int)fd, registers, out errorRegisters, protocol,
transferRegister, ref buffer, timeout, transferBlocks,
out duration, out sense);
return Linux.Command.SendAtaCommand((int) fd, registers, out errorRegisters, protocol,
transferRegister, ref buffer, timeout, transferBlocks,
out duration, out sense);
}
case PlatformID.FreeBSD:
{
return FreeBSD.Command.SendAtaCommand((IntPtr)fd, registers, out errorRegisters, protocol,
ref buffer, timeout, out duration, out sense);
return FreeBSD.Command.SendAtaCommand((IntPtr) fd, registers, out errorRegisters, protocol,
ref buffer, timeout, out duration, out sense);
}
default: throw new InvalidOperationException($"Platform {ptId} not yet supported.");
}
@@ -433,19 +433,19 @@ namespace DiscImageChef.Devices
/// <param name="response">Response registers</param>
/// <param name="blockSize">Size of block in bytes</param>
/// <exception cref="InvalidOperationException">If the specified platform is not supported</exception>
internal static int SendMmcCommand(object fd, 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)
internal static int SendMmcCommand(object fd, 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)
{
PlatformID ptId = DetectOS.GetRealPlatformID();
var ptId = DetectOS.GetRealPlatformID();
return SendMmcCommand(ptId, (int)fd, command, write, isApplication, flags, argument,
blockSize, blocks,
ref buffer, out response, out duration, out sense, timeout);
return SendMmcCommand(ptId, (int) fd, command, write, isApplication, flags, argument,
blockSize, blocks,
ref buffer, out response, out duration, out sense, timeout);
}
/// <summary>
@@ -468,26 +468,26 @@ namespace DiscImageChef.Devices
/// <param name="blockSize">Size of block in bytes</param>
/// <exception cref="InvalidOperationException">If the specified platform is not supported</exception>
internal static int SendMmcCommand(PlatformID ptId, object fd, 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)
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)
{
switch(ptId)
switch (ptId)
{
case PlatformID.Win32NT:
{
return Windows.Command.SendMmcCommand((SafeFileHandle)fd, command, write, isApplication, flags,
argument, blockSize, blocks, ref buffer, out response,
out duration, out sense, timeout);
return Windows.Command.SendMmcCommand((SafeFileHandle) fd, command, write, isApplication, flags,
argument, blockSize, blocks, ref buffer, out response,
out duration, out sense, timeout);
}
case PlatformID.Linux:
{
return Linux.Command.SendMmcCommand((int)fd, command, write, isApplication, flags, argument,
blockSize, blocks, ref buffer, out response, out duration,
out sense, timeout);
return Linux.Command.SendMmcCommand((int) fd, command, write, isApplication, flags, argument,
blockSize, blocks, ref buffer, out response, out duration,
out sense, timeout);
}
default: throw new InvalidOperationException($"Platform {ptId} not yet supported.");
}