mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
Add stubs for remote device commands.
This commit is contained in:
@@ -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.");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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...");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user