mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
REFACTOR: Reformat code.
This commit is contained in:
@@ -51,11 +51,13 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="direction">SCSI command transfer direction</param>
|
||||
/// <param name="duration">Time it took to execute the command in milliseconds</param>
|
||||
/// <param name="sense"><c>True</c> if SCSI error returned non-OK status and <paramref name="senseBuffer"/> contains SCSI sense</param>
|
||||
public static int SendScsiCommand(object fd, byte[] cdb, ref byte[] buffer, out byte[] senseBuffer, uint timeout, ScsiDirection direction, out double duration, out bool sense)
|
||||
public static int SendScsiCommand(object fd, byte[] cdb, ref byte[] buffer, out byte[] senseBuffer,
|
||||
uint timeout, ScsiDirection direction, out double duration, out bool sense)
|
||||
{
|
||||
Interop.PlatformID ptID = DetectOS.GetRealPlatformID();
|
||||
|
||||
return SendScsiCommand(ptID, fd, cdb, ref buffer, out senseBuffer, timeout, direction, out duration, out sense);
|
||||
return SendScsiCommand(ptID, fd, cdb, ref buffer, out senseBuffer, timeout, direction, out duration,
|
||||
out sense);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -71,54 +73,58 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="direction">SCSI command transfer direction</param>
|
||||
/// <param name="duration">Time it took to execute the command in milliseconds</param>
|
||||
/// <param name="sense"><c>True</c> if SCSI error returned non-OK status and <paramref name="senseBuffer"/> contains SCSI sense</param>
|
||||
public static int SendScsiCommand(Interop.PlatformID ptID, object fd, byte[] cdb, ref byte[] buffer, out byte[] senseBuffer, uint timeout, ScsiDirection direction, out double duration, out bool sense)
|
||||
public static int SendScsiCommand(Interop.PlatformID ptID, object fd, byte[] cdb, ref byte[] buffer,
|
||||
out byte[] senseBuffer, uint timeout, ScsiDirection direction,
|
||||
out double duration, out bool sense)
|
||||
{
|
||||
switch(ptID)
|
||||
{
|
||||
case Interop.PlatformID.Win32NT:
|
||||
{
|
||||
Windows.ScsiIoctlDirection dir;
|
||||
|
||||
switch(direction)
|
||||
{
|
||||
Windows.ScsiIoctlDirection dir;
|
||||
|
||||
switch(direction)
|
||||
{
|
||||
case ScsiDirection.In:
|
||||
dir = Windows.ScsiIoctlDirection.In;
|
||||
break;
|
||||
case ScsiDirection.Out:
|
||||
dir = Windows.ScsiIoctlDirection.Out;
|
||||
break;
|
||||
default:
|
||||
dir = Windows.ScsiIoctlDirection.Unspecified;
|
||||
break;
|
||||
}
|
||||
|
||||
return Windows.Command.SendScsiCommand((SafeFileHandle)fd, cdb, ref buffer, out senseBuffer, timeout, dir, out duration, out sense);
|
||||
case ScsiDirection.In:
|
||||
dir = Windows.ScsiIoctlDirection.In;
|
||||
break;
|
||||
case ScsiDirection.Out:
|
||||
dir = Windows.ScsiIoctlDirection.Out;
|
||||
break;
|
||||
default:
|
||||
dir = Windows.ScsiIoctlDirection.Unspecified;
|
||||
break;
|
||||
}
|
||||
|
||||
return Windows.Command.SendScsiCommand((SafeFileHandle)fd, cdb, ref buffer, out senseBuffer,
|
||||
timeout, dir, out duration, out sense);
|
||||
}
|
||||
case Interop.PlatformID.Linux:
|
||||
{
|
||||
Linux.ScsiIoctlDirection dir;
|
||||
|
||||
switch(direction)
|
||||
{
|
||||
Linux.ScsiIoctlDirection dir;
|
||||
|
||||
switch(direction)
|
||||
{
|
||||
case ScsiDirection.In:
|
||||
dir = Linux.ScsiIoctlDirection.In;
|
||||
break;
|
||||
case ScsiDirection.Out:
|
||||
dir = Linux.ScsiIoctlDirection.Out;
|
||||
break;
|
||||
case ScsiDirection.Bidirectional:
|
||||
dir = Linux.ScsiIoctlDirection.Unspecified;
|
||||
break;
|
||||
case ScsiDirection.None:
|
||||
dir = Linux.ScsiIoctlDirection.None;
|
||||
break;
|
||||
default:
|
||||
dir = Linux.ScsiIoctlDirection.Unknown;
|
||||
break;
|
||||
}
|
||||
|
||||
return Linux.Command.SendScsiCommand((int)fd, cdb, ref buffer, out senseBuffer, timeout, dir, out duration, out sense);
|
||||
case ScsiDirection.In:
|
||||
dir = Linux.ScsiIoctlDirection.In;
|
||||
break;
|
||||
case ScsiDirection.Out:
|
||||
dir = Linux.ScsiIoctlDirection.Out;
|
||||
break;
|
||||
case ScsiDirection.Bidirectional:
|
||||
dir = Linux.ScsiIoctlDirection.Unspecified;
|
||||
break;
|
||||
case ScsiDirection.None:
|
||||
dir = Linux.ScsiIoctlDirection.None;
|
||||
break;
|
||||
default:
|
||||
dir = Linux.ScsiIoctlDirection.Unknown;
|
||||
break;
|
||||
}
|
||||
|
||||
return Linux.Command.SendScsiCommand((int)fd, cdb, ref buffer, out senseBuffer, timeout, dir,
|
||||
out duration, out sense);
|
||||
}
|
||||
case Interop.PlatformID.FreeBSD:
|
||||
{
|
||||
FreeBSD.ccb_flags flags = 0;
|
||||
@@ -140,192 +146,184 @@ 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.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(string.Format("Platform {0} not yet supported.", ptID));
|
||||
default: throw new InvalidOperationException(string.Format("Platform {0} not yet supported.", ptID));
|
||||
}
|
||||
}
|
||||
|
||||
public 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)
|
||||
public 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)
|
||||
{
|
||||
Interop.PlatformID ptID = DetectOS.GetRealPlatformID();
|
||||
|
||||
return SendAtaCommand(ptID, fd, registers, out errorRegisters, protocol,
|
||||
transferRegister, ref buffer, timeout, transferBlocks, out duration, out sense);
|
||||
return SendAtaCommand(ptID, fd, registers, out errorRegisters, protocol, transferRegister, ref buffer,
|
||||
timeout, transferBlocks, out duration, out sense);
|
||||
}
|
||||
|
||||
public static int SendAtaCommand(Interop.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)
|
||||
out AtaErrorRegistersCHS errorRegisters, AtaProtocol protocol,
|
||||
AtaTransferRegister transferRegister, ref byte[] buffer, uint timeout,
|
||||
bool transferBlocks, out double duration, out bool sense)
|
||||
{
|
||||
switch(ptID)
|
||||
{
|
||||
case Interop.PlatformID.Win32NT:
|
||||
{
|
||||
if(
|
||||
( // Windows XP <= SP1
|
||||
Environment.OSVersion.Version.Major == 5 &&
|
||||
Environment.OSVersion.Version.Minor == 1 &&
|
||||
(Environment.OSVersion.ServicePack == "Service Pack 1" || Environment.OSVersion.ServicePack == "")) ||
|
||||
( // Windows 2000
|
||||
Environment.OSVersion.Version.Major == 5 &&
|
||||
Environment.OSVersion.Version.Minor == 0)
|
||||
)
|
||||
return Windows.Command.SendIdeCommand((SafeFileHandle)fd, registers, out errorRegisters,
|
||||
protocol, ref buffer, timeout, out duration, out sense);
|
||||
// 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
|
||||
)
|
||||
throw new InvalidOperationException("Windows NT 4.0 or earlier is not supported.");
|
||||
|
||||
return Windows.Command.SendAtaCommand((SafeFileHandle)fd, registers, out errorRegisters,
|
||||
{
|
||||
if(( // Windows XP <= SP1
|
||||
Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor == 1 &&
|
||||
(Environment.OSVersion.ServicePack == "Service Pack 1" ||
|
||||
Environment.OSVersion.ServicePack == "")) || ( // Windows 2000
|
||||
Environment.OSVersion.Version.Major == 5 &&
|
||||
Environment.OSVersion.Version.Minor == 0))
|
||||
return Windows.Command.SendIdeCommand((SafeFileHandle)fd, registers, out errorRegisters,
|
||||
protocol, ref buffer, timeout, out duration, out sense);
|
||||
}
|
||||
// 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)
|
||||
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);
|
||||
}
|
||||
case Interop.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 Interop.PlatformID.FreeBSD:
|
||||
{
|
||||
return FreeBSD.Command.SendAtaCommand((IntPtr)fd, registers, out errorRegisters, protocol,
|
||||
ref buffer, timeout, out duration, out sense);
|
||||
}
|
||||
default:
|
||||
throw new InvalidOperationException(string.Format("Platform {0} not yet supported.", ptID));
|
||||
default: throw new InvalidOperationException(string.Format("Platform {0} not yet supported.", ptID));
|
||||
}
|
||||
}
|
||||
|
||||
public 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)
|
||||
out AtaErrorRegistersLBA28 errorRegisters, AtaProtocol protocol,
|
||||
AtaTransferRegister transferRegister, ref byte[] buffer, uint timeout,
|
||||
bool transferBlocks, out double duration, out bool sense)
|
||||
{
|
||||
Interop.PlatformID ptID = DetectOS.GetRealPlatformID();
|
||||
|
||||
return SendAtaCommand(ptID, fd, registers, out errorRegisters, protocol,
|
||||
transferRegister, ref buffer, timeout, transferBlocks, out duration, out sense);
|
||||
return SendAtaCommand(ptID, fd, registers, out errorRegisters, protocol, transferRegister, ref buffer,
|
||||
timeout, transferBlocks, out duration, out sense);
|
||||
}
|
||||
|
||||
public static int SendAtaCommand(Interop.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)
|
||||
out AtaErrorRegistersLBA28 errorRegisters, AtaProtocol protocol,
|
||||
AtaTransferRegister transferRegister, ref byte[] buffer, uint timeout,
|
||||
bool transferBlocks, out double duration, out bool sense)
|
||||
{
|
||||
switch(ptID)
|
||||
{
|
||||
case Interop.PlatformID.Win32NT:
|
||||
{
|
||||
if(
|
||||
( // Windows XP <= SP1
|
||||
Environment.OSVersion.Version.Major == 5 &&
|
||||
Environment.OSVersion.Version.Minor == 1 &&
|
||||
(Environment.OSVersion.ServicePack == "Service Pack 1" || Environment.OSVersion.ServicePack == "")) ||
|
||||
( // Windows 2000
|
||||
Environment.OSVersion.Version.Major == 5 &&
|
||||
Environment.OSVersion.Version.Minor == 0)
|
||||
)
|
||||
return Windows.Command.SendIdeCommand((SafeFileHandle)fd, registers, out errorRegisters,
|
||||
protocol, ref buffer, timeout, out duration, out sense);
|
||||
// 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
|
||||
)
|
||||
throw new InvalidOperationException("Windows NT 4.0 or earlier is not supported.");
|
||||
|
||||
return Windows.Command.SendAtaCommand((SafeFileHandle)fd, registers, out errorRegisters,
|
||||
{
|
||||
if(( // Windows XP <= SP1
|
||||
Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor == 1 &&
|
||||
(Environment.OSVersion.ServicePack == "Service Pack 1" ||
|
||||
Environment.OSVersion.ServicePack == "")) || ( // Windows 2000
|
||||
Environment.OSVersion.Version.Major == 5 &&
|
||||
Environment.OSVersion.Version.Minor == 0))
|
||||
return Windows.Command.SendIdeCommand((SafeFileHandle)fd, registers, out errorRegisters,
|
||||
protocol, ref buffer, timeout, out duration, out sense);
|
||||
}
|
||||
// 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)
|
||||
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);
|
||||
}
|
||||
case Interop.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 Interop.PlatformID.FreeBSD:
|
||||
{
|
||||
return FreeBSD.Command.SendAtaCommand((IntPtr)fd, registers, out errorRegisters, protocol,
|
||||
ref buffer, timeout, out duration, out sense);
|
||||
}
|
||||
default:
|
||||
throw new InvalidOperationException(string.Format("Platform {0} not yet supported.", ptID));
|
||||
default: throw new InvalidOperationException(string.Format("Platform {0} not yet supported.", ptID));
|
||||
}
|
||||
}
|
||||
|
||||
public 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)
|
||||
out AtaErrorRegistersLBA48 errorRegisters, AtaProtocol protocol,
|
||||
AtaTransferRegister transferRegister, ref byte[] buffer, uint timeout,
|
||||
bool transferBlocks, out double duration, out bool sense)
|
||||
{
|
||||
Interop.PlatformID ptID = DetectOS.GetRealPlatformID();
|
||||
|
||||
return SendAtaCommand(ptID, fd, registers, out errorRegisters, protocol,
|
||||
transferRegister, ref buffer, timeout, transferBlocks, out duration, out sense);
|
||||
return SendAtaCommand(ptID, fd, registers, out errorRegisters, protocol, transferRegister, ref buffer,
|
||||
timeout, transferBlocks, out duration, out sense);
|
||||
}
|
||||
|
||||
public static int SendAtaCommand(Interop.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)
|
||||
out AtaErrorRegistersLBA48 errorRegisters, AtaProtocol protocol,
|
||||
AtaTransferRegister transferRegister, ref byte[] buffer, uint timeout,
|
||||
bool transferBlocks, out double duration, out bool sense)
|
||||
{
|
||||
switch(ptID)
|
||||
{
|
||||
case Interop.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);
|
||||
}
|
||||
{
|
||||
// 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);
|
||||
}
|
||||
case Interop.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 Interop.PlatformID.FreeBSD:
|
||||
{
|
||||
return FreeBSD.Command.SendAtaCommand((IntPtr)fd, registers, out errorRegisters, protocol,
|
||||
ref buffer, timeout, out duration, out sense);
|
||||
}
|
||||
default:
|
||||
throw new InvalidOperationException(string.Format("Platform {0} not yet supported.", ptID));
|
||||
default: throw new InvalidOperationException(string.Format("Platform {0} not yet supported.", ptID));
|
||||
}
|
||||
}
|
||||
|
||||
public 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)
|
||||
public 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)
|
||||
{
|
||||
Interop.PlatformID 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);
|
||||
}
|
||||
|
||||
public static int SendMmcCommand(Interop.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)
|
||||
public static int SendMmcCommand(Interop.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)
|
||||
{
|
||||
switch(ptID)
|
||||
{
|
||||
case Interop.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 Interop.PlatformID.Linux:
|
||||
{
|
||||
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(string.Format("Platform {0} not yet supported.", ptID));
|
||||
{
|
||||
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(string.Format("Platform {0} not yet supported.", ptID));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -37,7 +37,8 @@ namespace DiscImageChef.Devices
|
||||
{
|
||||
public partial class Device
|
||||
{
|
||||
public bool ReadBuffer(out byte[] buffer, out AtaErrorRegistersLBA28 statusRegisters, uint timeout, out double duration)
|
||||
public bool ReadBuffer(out byte[] buffer, out AtaErrorRegistersLBA28 statusRegisters, uint timeout,
|
||||
out double duration)
|
||||
{
|
||||
buffer = new byte[512];
|
||||
AtaRegistersLBA28 registers = new AtaRegistersLBA28();
|
||||
@@ -45,8 +46,9 @@ namespace DiscImageChef.Devices
|
||||
|
||||
registers.command = (byte)AtaCommands.ReadBuffer;
|
||||
|
||||
lastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.PioIn, AtaTransferRegister.NoTransfer,
|
||||
ref buffer, timeout, false, out duration, out sense);
|
||||
lastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.PioIn,
|
||||
AtaTransferRegister.NoTransfer, ref buffer, timeout, false, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("ATA Device", "READ BUFFER took {0} ms.", duration);
|
||||
@@ -54,7 +56,8 @@ namespace DiscImageChef.Devices
|
||||
return sense;
|
||||
}
|
||||
|
||||
public bool ReadBufferDma(out byte[] buffer, out AtaErrorRegistersLBA28 statusRegisters, uint timeout, out double duration)
|
||||
public bool ReadBufferDma(out byte[] buffer, out AtaErrorRegistersLBA28 statusRegisters, uint timeout,
|
||||
out double duration)
|
||||
{
|
||||
buffer = new byte[512];
|
||||
AtaRegistersLBA28 registers = new AtaRegistersLBA28();
|
||||
@@ -71,24 +74,22 @@ namespace DiscImageChef.Devices
|
||||
return sense;
|
||||
}
|
||||
|
||||
public bool ReadDma(out byte[] buffer, out AtaErrorRegistersLBA28 statusRegisters, uint lba, byte count, uint timeout, out double duration)
|
||||
public bool ReadDma(out byte[] buffer, out AtaErrorRegistersLBA28 statusRegisters, uint lba, byte count,
|
||||
uint timeout, out double duration)
|
||||
{
|
||||
return ReadDma(out buffer, out statusRegisters, true, lba, count, timeout, out duration);
|
||||
}
|
||||
|
||||
public bool ReadDma(out byte[] buffer, out AtaErrorRegistersLBA28 statusRegisters, bool retry, uint lba, byte count, uint timeout, out double duration)
|
||||
public bool ReadDma(out byte[] buffer, out AtaErrorRegistersLBA28 statusRegisters, bool retry, uint lba,
|
||||
byte count, uint timeout, out double duration)
|
||||
{
|
||||
if(count == 0)
|
||||
buffer = new byte[512 * 256];
|
||||
else
|
||||
buffer = new byte[512 * count];
|
||||
if(count == 0) buffer = new byte[512 * 256];
|
||||
else buffer = new byte[512 * count];
|
||||
AtaRegistersLBA28 registers = new AtaRegistersLBA28();
|
||||
bool sense;
|
||||
|
||||
if(retry)
|
||||
registers.command = (byte)AtaCommands.ReadDmaRetry;
|
||||
else
|
||||
registers.command = (byte)AtaCommands.ReadDma;
|
||||
if(retry) registers.command = (byte)AtaCommands.ReadDmaRetry;
|
||||
else registers.command = (byte)AtaCommands.ReadDma;
|
||||
registers.sectorCount = count;
|
||||
registers.deviceHead = (byte)((lba & 0xF000000) / 0x1000000);
|
||||
registers.lbaHigh = (byte)((lba & 0xFF0000) / 0x10000);
|
||||
@@ -105,12 +106,11 @@ namespace DiscImageChef.Devices
|
||||
return sense;
|
||||
}
|
||||
|
||||
public bool ReadMultiple(out byte[] buffer, out AtaErrorRegistersLBA28 statusRegisters, uint lba, byte count, uint timeout, out double duration)
|
||||
public bool ReadMultiple(out byte[] buffer, out AtaErrorRegistersLBA28 statusRegisters, uint lba, byte count,
|
||||
uint timeout, out double duration)
|
||||
{
|
||||
if(count == 0)
|
||||
buffer = new byte[512 * 256];
|
||||
else
|
||||
buffer = new byte[512 * count];
|
||||
if(count == 0) buffer = new byte[512 * 256];
|
||||
else buffer = new byte[512 * count];
|
||||
AtaRegistersLBA28 registers = new AtaRegistersLBA28();
|
||||
bool sense;
|
||||
|
||||
@@ -122,8 +122,9 @@ namespace DiscImageChef.Devices
|
||||
registers.lbaLow = (byte)((lba & 0xFF) / 0x1);
|
||||
registers.deviceHead += 0x40;
|
||||
|
||||
lastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.PioIn, AtaTransferRegister.SectorCount,
|
||||
ref buffer, timeout, true, out duration, out sense);
|
||||
lastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.PioIn,
|
||||
AtaTransferRegister.SectorCount, ref buffer, timeout, true, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("ATA Device", "READ MULTIPLE took {0} ms.", duration);
|
||||
@@ -131,7 +132,8 @@ namespace DiscImageChef.Devices
|
||||
return sense;
|
||||
}
|
||||
|
||||
public bool ReadNativeMaxAddress(out uint lba, out AtaErrorRegistersLBA28 statusRegisters, uint timeout, out double duration)
|
||||
public bool ReadNativeMaxAddress(out uint lba, out AtaErrorRegistersLBA28 statusRegisters, uint timeout,
|
||||
out double duration)
|
||||
{
|
||||
lba = 0;
|
||||
byte[] buffer = new byte[0];
|
||||
@@ -141,8 +143,9 @@ namespace DiscImageChef.Devices
|
||||
registers.command = (byte)AtaCommands.ReadNativeMaxAddress;
|
||||
registers.deviceHead += 0x40;
|
||||
|
||||
lastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.NonData, AtaTransferRegister.NoTransfer,
|
||||
ref buffer, timeout, false, out duration, out sense);
|
||||
lastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.NonData,
|
||||
AtaTransferRegister.NoTransfer, ref buffer, timeout, false, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
if((statusRegisters.status & 0x23) == 0)
|
||||
@@ -159,24 +162,22 @@ namespace DiscImageChef.Devices
|
||||
return sense;
|
||||
}
|
||||
|
||||
public bool Read(out byte[] buffer, out AtaErrorRegistersLBA28 statusRegisters, uint lba, byte count, uint timeout, out double duration)
|
||||
public bool Read(out byte[] buffer, out AtaErrorRegistersLBA28 statusRegisters, uint lba, byte count,
|
||||
uint timeout, out double duration)
|
||||
{
|
||||
return Read(out buffer, out statusRegisters, true, lba, count, timeout, out duration);
|
||||
}
|
||||
|
||||
public bool Read(out byte[] buffer, out AtaErrorRegistersLBA28 statusRegisters, bool retry, uint lba, byte count, uint timeout, out double duration)
|
||||
public bool Read(out byte[] buffer, out AtaErrorRegistersLBA28 statusRegisters, bool retry, uint lba,
|
||||
byte count, uint timeout, out double duration)
|
||||
{
|
||||
if(count == 0)
|
||||
buffer = new byte[512 * 256];
|
||||
else
|
||||
buffer = new byte[512 * count];
|
||||
if(count == 0) buffer = new byte[512 * 256];
|
||||
else buffer = new byte[512 * count];
|
||||
AtaRegistersLBA28 registers = new AtaRegistersLBA28();
|
||||
bool sense;
|
||||
|
||||
if(retry)
|
||||
registers.command = (byte)AtaCommands.ReadRetry;
|
||||
else
|
||||
registers.command = (byte)AtaCommands.Read;
|
||||
if(retry) registers.command = (byte)AtaCommands.ReadRetry;
|
||||
else registers.command = (byte)AtaCommands.Read;
|
||||
registers.sectorCount = count;
|
||||
registers.deviceHead = (byte)((lba & 0xF000000) / 0x1000000);
|
||||
registers.lbaHigh = (byte)((lba & 0xFF0000) / 0x10000);
|
||||
@@ -184,8 +185,9 @@ namespace DiscImageChef.Devices
|
||||
registers.lbaLow = (byte)((lba & 0xFF) / 0x1);
|
||||
registers.deviceHead += 0x40;
|
||||
|
||||
lastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.PioIn, AtaTransferRegister.SectorCount,
|
||||
ref buffer, timeout, true, out duration, out sense);
|
||||
lastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.PioIn,
|
||||
AtaTransferRegister.SectorCount, ref buffer, timeout, true, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("ATA Device", "READ SECTORS took {0} ms.", duration);
|
||||
@@ -193,22 +195,21 @@ namespace DiscImageChef.Devices
|
||||
return sense;
|
||||
}
|
||||
|
||||
|
||||
public bool ReadLong(out byte[] buffer, out AtaErrorRegistersLBA28 statusRegisters, uint lba, uint blockSize, uint timeout, out double duration)
|
||||
public bool ReadLong(out byte[] buffer, out AtaErrorRegistersLBA28 statusRegisters, uint lba, uint blockSize,
|
||||
uint timeout, out double duration)
|
||||
{
|
||||
return ReadLong(out buffer, out statusRegisters, true, lba, blockSize, timeout, out duration);
|
||||
}
|
||||
|
||||
public bool ReadLong(out byte[] buffer, out AtaErrorRegistersLBA28 statusRegisters, bool retry, uint lba, uint blockSize, uint timeout, out double duration)
|
||||
public bool ReadLong(out byte[] buffer, out AtaErrorRegistersLBA28 statusRegisters, bool retry, uint lba,
|
||||
uint blockSize, uint timeout, out double duration)
|
||||
{
|
||||
buffer = new byte[blockSize];
|
||||
AtaRegistersLBA28 registers = new AtaRegistersLBA28();
|
||||
bool sense;
|
||||
|
||||
if(retry)
|
||||
registers.command = (byte)AtaCommands.ReadLongRetry;
|
||||
else
|
||||
registers.command = (byte)AtaCommands.ReadLong;
|
||||
if(retry) registers.command = (byte)AtaCommands.ReadLongRetry;
|
||||
else registers.command = (byte)AtaCommands.ReadLong;
|
||||
registers.sectorCount = 1;
|
||||
registers.deviceHead = (byte)((lba & 0xF000000) / 0x1000000);
|
||||
registers.lbaHigh = (byte)((lba & 0xFF0000) / 0x10000);
|
||||
@@ -216,8 +217,9 @@ namespace DiscImageChef.Devices
|
||||
registers.lbaLow = (byte)((lba & 0xFF) / 0x1);
|
||||
registers.deviceHead += 0x40;
|
||||
|
||||
lastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.PioIn, AtaTransferRegister.SectorCount,
|
||||
ref buffer, timeout, true, out duration, out sense);
|
||||
lastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.PioIn,
|
||||
AtaTransferRegister.SectorCount, ref buffer, timeout, true, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("ATA Device", "READ LONG took {0} ms.", duration);
|
||||
@@ -238,8 +240,9 @@ namespace DiscImageChef.Devices
|
||||
registers.lbaLow = (byte)((lba & 0xFF) / 0x1);
|
||||
registers.deviceHead += 0x40;
|
||||
|
||||
lastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.NonData, AtaTransferRegister.NoTransfer,
|
||||
ref buffer, timeout, false, out duration, out sense);
|
||||
lastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.NonData,
|
||||
AtaTransferRegister.NoTransfer, ref buffer, timeout, false, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("ATA Device", "SEEK took {0} ms.", duration);
|
||||
@@ -247,5 +250,4 @@ namespace DiscImageChef.Devices
|
||||
return sense;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -37,7 +37,8 @@ namespace DiscImageChef.Devices
|
||||
{
|
||||
public partial class Device
|
||||
{
|
||||
public bool GetNativeMaxAddressExt(out ulong lba, out AtaErrorRegistersLBA48 statusRegisters, uint timeout, out double duration)
|
||||
public bool GetNativeMaxAddressExt(out ulong lba, out AtaErrorRegistersLBA48 statusRegisters, uint timeout,
|
||||
out double duration)
|
||||
{
|
||||
lba = 0;
|
||||
AtaRegistersLBA48 registers = new AtaRegistersLBA48();
|
||||
@@ -47,8 +48,9 @@ namespace DiscImageChef.Devices
|
||||
registers.command = (byte)AtaCommands.NativeMaxAddress;
|
||||
registers.feature = 0x0000;
|
||||
|
||||
lastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.NonData, AtaTransferRegister.NoTransfer,
|
||||
ref buffer, timeout, false, out duration, out sense);
|
||||
lastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.NonData,
|
||||
AtaTransferRegister.NoTransfer, ref buffer, timeout, false, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
if((statusRegisters.status & 0x23) == 0)
|
||||
@@ -64,12 +66,11 @@ namespace DiscImageChef.Devices
|
||||
return sense;
|
||||
}
|
||||
|
||||
public bool ReadDma(out byte[] buffer, out AtaErrorRegistersLBA48 statusRegisters, ulong lba, ushort count, uint timeout, out double duration)
|
||||
public bool ReadDma(out byte[] buffer, out AtaErrorRegistersLBA48 statusRegisters, ulong lba, ushort count,
|
||||
uint timeout, out double duration)
|
||||
{
|
||||
if(count == 0)
|
||||
buffer = new byte[512 * 65536];
|
||||
else
|
||||
buffer = new byte[512 * count];
|
||||
if(count == 0) buffer = new byte[512 * 65536];
|
||||
else buffer = new byte[512 * count];
|
||||
AtaRegistersLBA48 registers = new AtaRegistersLBA48();
|
||||
bool sense;
|
||||
|
||||
@@ -89,7 +90,8 @@ namespace DiscImageChef.Devices
|
||||
return sense;
|
||||
}
|
||||
|
||||
public bool ReadLog(out byte[] buffer, out AtaErrorRegistersLBA48 statusRegisters, byte logAddress, ushort pageNumber, ushort count, uint timeout, out double duration)
|
||||
public bool ReadLog(out byte[] buffer, out AtaErrorRegistersLBA48 statusRegisters, byte logAddress,
|
||||
ushort pageNumber, ushort count, uint timeout, out double duration)
|
||||
{
|
||||
buffer = new byte[512 * count];
|
||||
AtaRegistersLBA48 registers = new AtaRegistersLBA48();
|
||||
@@ -101,8 +103,9 @@ namespace DiscImageChef.Devices
|
||||
registers.lbaLow += logAddress;
|
||||
registers.lbaHigh = (ushort)((pageNumber & 0xFF00) / 0x100);
|
||||
|
||||
lastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.PioIn, AtaTransferRegister.SectorCount,
|
||||
ref buffer, timeout, true, out duration, out sense);
|
||||
lastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.PioIn,
|
||||
AtaTransferRegister.SectorCount, ref buffer, timeout, true, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("ATA Device", "READ LOG EXT took {0} ms.", duration);
|
||||
@@ -110,7 +113,8 @@ namespace DiscImageChef.Devices
|
||||
return sense;
|
||||
}
|
||||
|
||||
public bool ReadLogDma(out byte[] buffer, out AtaErrorRegistersLBA48 statusRegisters, byte logAddress, ushort pageNumber, ushort count, uint timeout, out double duration)
|
||||
public bool ReadLogDma(out byte[] buffer, out AtaErrorRegistersLBA48 statusRegisters, byte logAddress,
|
||||
ushort pageNumber, ushort count, uint timeout, out double duration)
|
||||
{
|
||||
buffer = new byte[512 * count];
|
||||
AtaRegistersLBA48 registers = new AtaRegistersLBA48();
|
||||
@@ -131,12 +135,11 @@ namespace DiscImageChef.Devices
|
||||
return sense;
|
||||
}
|
||||
|
||||
public bool ReadMultiple(out byte[] buffer, out AtaErrorRegistersLBA48 statusRegisters, ulong lba, ushort count, uint timeout, out double duration)
|
||||
public bool ReadMultiple(out byte[] buffer, out AtaErrorRegistersLBA48 statusRegisters, ulong lba, ushort count,
|
||||
uint timeout, out double duration)
|
||||
{
|
||||
if(count == 0)
|
||||
buffer = new byte[512 * 65536];
|
||||
else
|
||||
buffer = new byte[512 * count];
|
||||
if(count == 0) buffer = new byte[512 * 65536];
|
||||
else buffer = new byte[512 * count];
|
||||
AtaRegistersLBA48 registers = new AtaRegistersLBA48();
|
||||
bool sense;
|
||||
|
||||
@@ -147,8 +150,9 @@ namespace DiscImageChef.Devices
|
||||
registers.lbaLow = (ushort)((lba & 0xFFFF) / 0x1);
|
||||
registers.deviceHead += 0x40;
|
||||
|
||||
lastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.PioIn, AtaTransferRegister.SectorCount,
|
||||
ref buffer, timeout, true, out duration, out sense);
|
||||
lastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.PioIn,
|
||||
AtaTransferRegister.SectorCount, ref buffer, timeout, true, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("ATA Device", "READ MULTIPLE EXT took {0} ms.", duration);
|
||||
@@ -156,7 +160,8 @@ namespace DiscImageChef.Devices
|
||||
return sense;
|
||||
}
|
||||
|
||||
public bool ReadNativeMaxAddress(out ulong lba, out AtaErrorRegistersLBA48 statusRegisters, uint timeout, out double duration)
|
||||
public bool ReadNativeMaxAddress(out ulong lba, out AtaErrorRegistersLBA48 statusRegisters, uint timeout,
|
||||
out double duration)
|
||||
{
|
||||
lba = 0;
|
||||
byte[] buffer = new byte[0];
|
||||
@@ -166,8 +171,9 @@ namespace DiscImageChef.Devices
|
||||
registers.command = (byte)AtaCommands.ReadNativeMaxAddressExt;
|
||||
registers.deviceHead += 0x40;
|
||||
|
||||
lastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.NonData, AtaTransferRegister.NoTransfer,
|
||||
ref buffer, timeout, false, out duration, out sense);
|
||||
lastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.NonData,
|
||||
AtaTransferRegister.NoTransfer, ref buffer, timeout, false, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
if((statusRegisters.status & 0x23) == 0)
|
||||
@@ -183,12 +189,11 @@ namespace DiscImageChef.Devices
|
||||
return sense;
|
||||
}
|
||||
|
||||
public bool Read(out byte[] buffer, out AtaErrorRegistersLBA48 statusRegisters, ulong lba, ushort count, uint timeout, out double duration)
|
||||
public bool Read(out byte[] buffer, out AtaErrorRegistersLBA48 statusRegisters, ulong lba, ushort count,
|
||||
uint timeout, out double duration)
|
||||
{
|
||||
if(count == 0)
|
||||
buffer = new byte[512 * 65536];
|
||||
else
|
||||
buffer = new byte[512 * count];
|
||||
if(count == 0) buffer = new byte[512 * 65536];
|
||||
else buffer = new byte[512 * count];
|
||||
AtaRegistersLBA48 registers = new AtaRegistersLBA48();
|
||||
bool sense;
|
||||
|
||||
@@ -199,8 +204,9 @@ namespace DiscImageChef.Devices
|
||||
registers.lbaLow = (ushort)((lba & 0xFFFF) / 0x1);
|
||||
registers.deviceHead += 0x40;
|
||||
|
||||
lastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.PioIn, AtaTransferRegister.SectorCount,
|
||||
ref buffer, timeout, true, out duration, out sense);
|
||||
lastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.PioIn,
|
||||
AtaTransferRegister.SectorCount, ref buffer, timeout, true, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("ATA Device", "READ SECTORS EXT took {0} ms.", duration);
|
||||
|
||||
@@ -81,7 +81,8 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="statusRegisters">Status registers.</param>
|
||||
/// <param name="timeout">Timeout.</param>
|
||||
/// <param name="duration">Duration.</param>
|
||||
public bool AtaIdentify(out byte[] buffer, out AtaErrorRegistersCHS statusRegisters, uint timeout, out double duration)
|
||||
public bool AtaIdentify(out byte[] buffer, out AtaErrorRegistersCHS statusRegisters, uint timeout,
|
||||
out double duration)
|
||||
{
|
||||
buffer = new byte[512];
|
||||
AtaRegistersCHS registers = new AtaRegistersCHS();
|
||||
@@ -89,8 +90,9 @@ namespace DiscImageChef.Devices
|
||||
|
||||
registers.command = (byte)AtaCommands.IdentifyDevice;
|
||||
|
||||
lastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.PioIn, AtaTransferRegister.NoTransfer,
|
||||
ref buffer, timeout, false, out duration, out sense);
|
||||
lastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.PioIn,
|
||||
AtaTransferRegister.NoTransfer, ref buffer, timeout, false, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("ATA Device", "IDENTIFY DEVICE took {0} ms.", duration);
|
||||
@@ -98,24 +100,22 @@ namespace DiscImageChef.Devices
|
||||
return sense;
|
||||
}
|
||||
|
||||
public bool ReadDma(out byte[] buffer, out AtaErrorRegistersCHS statusRegisters, ushort cylinder, byte head, byte sector, byte count, uint timeout, out double duration)
|
||||
public bool ReadDma(out byte[] buffer, out AtaErrorRegistersCHS statusRegisters, ushort cylinder, byte head,
|
||||
byte sector, byte count, uint timeout, out double duration)
|
||||
{
|
||||
return ReadDma(out buffer, out statusRegisters, true, cylinder, head, sector, count, timeout, out duration);
|
||||
}
|
||||
|
||||
public bool ReadDma(out byte[] buffer, out AtaErrorRegistersCHS statusRegisters, bool retry, ushort cylinder, byte head, byte sector, byte count, uint timeout, out double duration)
|
||||
public bool ReadDma(out byte[] buffer, out AtaErrorRegistersCHS statusRegisters, bool retry, ushort cylinder,
|
||||
byte head, byte sector, byte count, uint timeout, out double duration)
|
||||
{
|
||||
if(count == 0)
|
||||
buffer = new byte[512 * 256];
|
||||
else
|
||||
buffer = new byte[512 * count];
|
||||
if(count == 0) buffer = new byte[512 * 256];
|
||||
else buffer = new byte[512 * count];
|
||||
AtaRegistersCHS registers = new AtaRegistersCHS();
|
||||
bool sense;
|
||||
|
||||
if(retry)
|
||||
registers.command = (byte)AtaCommands.ReadDmaRetry;
|
||||
else
|
||||
registers.command = (byte)AtaCommands.ReadDma;
|
||||
if(retry) registers.command = (byte)AtaCommands.ReadDmaRetry;
|
||||
else registers.command = (byte)AtaCommands.ReadDma;
|
||||
registers.sectorCount = count;
|
||||
registers.cylinderHigh = (byte)((cylinder & 0xFF00) / 0x100);
|
||||
registers.cylinderLow = (byte)((cylinder & 0xFF) / 0x1);
|
||||
@@ -131,12 +131,11 @@ namespace DiscImageChef.Devices
|
||||
return sense;
|
||||
}
|
||||
|
||||
public bool ReadMultiple(out byte[] buffer, out AtaErrorRegistersCHS statusRegisters, ushort cylinder, byte head, byte sector, byte count, uint timeout, out double duration)
|
||||
public bool ReadMultiple(out byte[] buffer, out AtaErrorRegistersCHS statusRegisters, ushort cylinder,
|
||||
byte head, byte sector, byte count, uint timeout, out double duration)
|
||||
{
|
||||
if(count == 0)
|
||||
buffer = new byte[512 * 256];
|
||||
else
|
||||
buffer = new byte[512 * count];
|
||||
if(count == 0) buffer = new byte[512 * 256];
|
||||
else buffer = new byte[512 * count];
|
||||
AtaRegistersCHS registers = new AtaRegistersCHS();
|
||||
bool sense;
|
||||
|
||||
@@ -147,8 +146,9 @@ namespace DiscImageChef.Devices
|
||||
registers.deviceHead = (byte)(head & 0x0F);
|
||||
registers.sector = sector;
|
||||
|
||||
lastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.PioIn, AtaTransferRegister.SectorCount,
|
||||
ref buffer, timeout, true, out duration, out sense);
|
||||
lastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.PioIn,
|
||||
AtaTransferRegister.SectorCount, ref buffer, timeout, true, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("ATA Device", "READ MULTIPLE took {0} ms.", duration);
|
||||
@@ -156,33 +156,31 @@ namespace DiscImageChef.Devices
|
||||
return sense;
|
||||
}
|
||||
|
||||
|
||||
public bool Read(out byte[] buffer, out AtaErrorRegistersCHS statusRegisters, ushort cylinder, byte head, byte sector, byte count, uint timeout, out double duration)
|
||||
public bool Read(out byte[] buffer, out AtaErrorRegistersCHS statusRegisters, ushort cylinder, byte head,
|
||||
byte sector, byte count, uint timeout, out double duration)
|
||||
{
|
||||
return Read(out buffer, out statusRegisters, true, cylinder, head, sector, count, timeout, out duration);
|
||||
}
|
||||
|
||||
public bool Read(out byte[] buffer, out AtaErrorRegistersCHS statusRegisters, bool retry, ushort cylinder, byte head, byte sector, byte count, uint timeout, out double duration)
|
||||
public bool Read(out byte[] buffer, out AtaErrorRegistersCHS statusRegisters, bool retry, ushort cylinder,
|
||||
byte head, byte sector, byte count, uint timeout, out double duration)
|
||||
{
|
||||
if(count == 0)
|
||||
buffer = new byte[512 * 256];
|
||||
else
|
||||
buffer = new byte[512 * count];
|
||||
if(count == 0) buffer = new byte[512 * 256];
|
||||
else buffer = new byte[512 * count];
|
||||
AtaRegistersCHS registers = new AtaRegistersCHS();
|
||||
bool sense;
|
||||
|
||||
if(retry)
|
||||
registers.command = (byte)AtaCommands.ReadRetry;
|
||||
else
|
||||
registers.command = (byte)AtaCommands.Read;
|
||||
if(retry) registers.command = (byte)AtaCommands.ReadRetry;
|
||||
else registers.command = (byte)AtaCommands.Read;
|
||||
registers.sectorCount = count;
|
||||
registers.cylinderHigh = (byte)((cylinder & 0xFF00) / 0x100);
|
||||
registers.cylinderLow = (byte)((cylinder & 0xFF) / 0x1);
|
||||
registers.deviceHead = (byte)(head & 0x0F);
|
||||
registers.sector = sector;
|
||||
|
||||
lastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.PioIn, AtaTransferRegister.SectorCount,
|
||||
ref buffer, timeout, true, out duration, out sense);
|
||||
lastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.PioIn,
|
||||
AtaTransferRegister.SectorCount, ref buffer, timeout, true, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("ATA Device", "READ SECTORS took {0} ms.", duration);
|
||||
@@ -190,29 +188,31 @@ namespace DiscImageChef.Devices
|
||||
return sense;
|
||||
}
|
||||
|
||||
public bool ReadLong(out byte[] buffer, out AtaErrorRegistersCHS statusRegisters, ushort cylinder, byte head, byte sector, uint blockSize, uint timeout, out double duration)
|
||||
public bool ReadLong(out byte[] buffer, out AtaErrorRegistersCHS statusRegisters, ushort cylinder, byte head,
|
||||
byte sector, uint blockSize, uint timeout, out double duration)
|
||||
{
|
||||
return ReadLong(out buffer, out statusRegisters, true, cylinder, head, sector, blockSize, timeout, out duration);
|
||||
return ReadLong(out buffer, out statusRegisters, true, cylinder, head, sector, blockSize, timeout,
|
||||
out duration);
|
||||
}
|
||||
|
||||
public bool ReadLong(out byte[] buffer, out AtaErrorRegistersCHS statusRegisters, bool retry, ushort cylinder, byte head, byte sector, uint blockSize, uint timeout, out double duration)
|
||||
public bool ReadLong(out byte[] buffer, out AtaErrorRegistersCHS statusRegisters, bool retry, ushort cylinder,
|
||||
byte head, byte sector, uint blockSize, uint timeout, out double duration)
|
||||
{
|
||||
buffer = new byte[blockSize];
|
||||
AtaRegistersCHS registers = new AtaRegistersCHS();
|
||||
bool sense;
|
||||
|
||||
if(retry)
|
||||
registers.command = (byte)AtaCommands.ReadLongRetry;
|
||||
else
|
||||
registers.command = (byte)AtaCommands.ReadLong;
|
||||
if(retry) registers.command = (byte)AtaCommands.ReadLongRetry;
|
||||
else registers.command = (byte)AtaCommands.ReadLong;
|
||||
registers.sectorCount = 1;
|
||||
registers.cylinderHigh = (byte)((cylinder & 0xFF00) / 0x100);
|
||||
registers.cylinderLow = (byte)((cylinder & 0xFF) / 0x1);
|
||||
registers.deviceHead = (byte)(head & 0x0F);
|
||||
registers.sector = sector;
|
||||
|
||||
lastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.PioIn, AtaTransferRegister.SectorCount,
|
||||
ref buffer, timeout, true, out duration, out sense);
|
||||
lastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.PioIn,
|
||||
AtaTransferRegister.SectorCount, ref buffer, timeout, true, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("ATA Device", "READ LONG took {0} ms.", duration);
|
||||
@@ -220,7 +220,8 @@ namespace DiscImageChef.Devices
|
||||
return sense;
|
||||
}
|
||||
|
||||
public bool Seek(out AtaErrorRegistersCHS statusRegisters, ushort cylinder, byte head, byte sector, uint timeout, out double duration)
|
||||
public bool Seek(out AtaErrorRegistersCHS statusRegisters, ushort cylinder, byte head, byte sector,
|
||||
uint timeout, out double duration)
|
||||
{
|
||||
byte[] buffer = new byte[0];
|
||||
AtaRegistersCHS registers = new AtaRegistersCHS();
|
||||
@@ -232,8 +233,9 @@ namespace DiscImageChef.Devices
|
||||
registers.deviceHead = (byte)(head & 0x0F);
|
||||
registers.sector = sector;
|
||||
|
||||
lastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.NonData, AtaTransferRegister.NoTransfer,
|
||||
ref buffer, timeout, true, out duration, out sense);
|
||||
lastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.NonData,
|
||||
AtaTransferRegister.NoTransfer, ref buffer, timeout, true, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("ATA Device", "SEEK took {0} ms.", duration);
|
||||
@@ -241,5 +243,4 @@ namespace DiscImageChef.Devices
|
||||
return sense;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -81,7 +81,8 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="statusRegisters">Status registers.</param>
|
||||
/// <param name="timeout">Timeout.</param>
|
||||
/// <param name="duration">Duration.</param>
|
||||
public bool AtapiIdentify(out byte[] buffer, out AtaErrorRegistersCHS statusRegisters, uint timeout, out double duration)
|
||||
public bool AtapiIdentify(out byte[] buffer, out AtaErrorRegistersCHS statusRegisters, uint timeout,
|
||||
out double duration)
|
||||
{
|
||||
buffer = new byte[512];
|
||||
AtaRegistersCHS registers = new AtaRegistersCHS();
|
||||
@@ -89,8 +90,9 @@ namespace DiscImageChef.Devices
|
||||
|
||||
registers.command = (byte)AtaCommands.IdentifyPacketDevice;
|
||||
|
||||
lastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.PioIn, AtaTransferRegister.NoTransfer,
|
||||
ref buffer, timeout, false, out duration, out sense);
|
||||
lastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.PioIn,
|
||||
AtaTransferRegister.NoTransfer, ref buffer, timeout, false, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("ATA Device", "IDENTIFY PACKET DEVICE took {0} ms.", duration);
|
||||
@@ -98,5 +100,4 @@ namespace DiscImageChef.Devices
|
||||
return sense;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -37,7 +37,8 @@ namespace DiscImageChef.Devices
|
||||
{
|
||||
public partial class Device
|
||||
{
|
||||
public bool TranslateSector(out byte[] buffer, out AtaErrorRegistersLBA28 statusRegisters, uint lba, uint timeout, out double duration)
|
||||
public bool TranslateSector(out byte[] buffer, out AtaErrorRegistersLBA28 statusRegisters, uint lba,
|
||||
uint timeout, out double duration)
|
||||
{
|
||||
buffer = new byte[512];
|
||||
AtaRegistersLBA28 registers = new AtaRegistersLBA28();
|
||||
@@ -50,8 +51,9 @@ namespace DiscImageChef.Devices
|
||||
registers.lbaLow = (byte)((lba & 0xFF) / 0x1);
|
||||
registers.deviceHead += 0x40;
|
||||
|
||||
lastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.PioIn, AtaTransferRegister.NoTransfer,
|
||||
ref buffer, timeout, false, out duration, out sense);
|
||||
lastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.PioIn,
|
||||
AtaTransferRegister.NoTransfer, ref buffer, timeout, false, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("ATA Device", "CFA TRANSLATE SECTOR took {0} ms.", duration);
|
||||
@@ -59,7 +61,8 @@ namespace DiscImageChef.Devices
|
||||
return sense;
|
||||
}
|
||||
|
||||
public bool TranslateSector(out byte[] buffer, out AtaErrorRegistersCHS statusRegisters, ushort cylinder, byte head, byte sector, uint timeout, out double duration)
|
||||
public bool TranslateSector(out byte[] buffer, out AtaErrorRegistersCHS statusRegisters, ushort cylinder,
|
||||
byte head, byte sector, uint timeout, out double duration)
|
||||
{
|
||||
buffer = new byte[512];
|
||||
AtaRegistersCHS registers = new AtaRegistersCHS();
|
||||
@@ -71,8 +74,9 @@ namespace DiscImageChef.Devices
|
||||
registers.sector = sector;
|
||||
registers.deviceHead = (byte)(head & 0x0F);
|
||||
|
||||
lastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.PioIn, AtaTransferRegister.NoTransfer,
|
||||
ref buffer, timeout, false, out duration, out sense);
|
||||
lastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.PioIn,
|
||||
AtaTransferRegister.NoTransfer, ref buffer, timeout, false, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("ATA Device", "CFA TRANSLATE SECTOR took {0} ms.", duration);
|
||||
@@ -80,7 +84,8 @@ namespace DiscImageChef.Devices
|
||||
return sense;
|
||||
}
|
||||
|
||||
public bool RequestExtendedErrorCode(out byte errorCode, out AtaErrorRegistersLBA28 statusRegisters, uint timeout, out double duration)
|
||||
public bool RequestExtendedErrorCode(out byte errorCode, out AtaErrorRegistersLBA28 statusRegisters,
|
||||
uint timeout, out double duration)
|
||||
{
|
||||
byte[] buffer = new byte[0];
|
||||
AtaRegistersLBA28 registers = new AtaRegistersLBA28();
|
||||
@@ -88,8 +93,9 @@ namespace DiscImageChef.Devices
|
||||
|
||||
registers.command = (byte)AtaCommands.RequestSense;
|
||||
|
||||
lastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.PioIn, AtaTransferRegister.NoTransfer,
|
||||
ref buffer, timeout, false, out duration, out sense);
|
||||
lastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.PioIn,
|
||||
AtaTransferRegister.NoTransfer, ref buffer, timeout, false, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
errorCode = statusRegisters.error;
|
||||
@@ -99,5 +105,4 @@ namespace DiscImageChef.Devices
|
||||
return sense;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -37,17 +37,20 @@ namespace DiscImageChef.Devices
|
||||
{
|
||||
public partial class Device
|
||||
{
|
||||
public bool EnableMediaCardPassThrough(out AtaErrorRegistersCHS statusRegisters, uint timeout, out double duration)
|
||||
public bool EnableMediaCardPassThrough(out AtaErrorRegistersCHS statusRegisters, uint timeout,
|
||||
out double duration)
|
||||
{
|
||||
return CheckMediaCardType(1, out statusRegisters, timeout, out duration);
|
||||
}
|
||||
|
||||
public bool DisableMediaCardPassThrough(out AtaErrorRegistersCHS statusRegisters, uint timeout, out double duration)
|
||||
public bool DisableMediaCardPassThrough(out AtaErrorRegistersCHS statusRegisters, uint timeout,
|
||||
out double duration)
|
||||
{
|
||||
return CheckMediaCardType(0, out statusRegisters, timeout, out duration);
|
||||
}
|
||||
|
||||
public bool CheckMediaCardType(byte feature, out AtaErrorRegistersCHS statusRegisters, uint timeout, out double duration)
|
||||
public bool CheckMediaCardType(byte feature, out AtaErrorRegistersCHS statusRegisters, uint timeout,
|
||||
out double duration)
|
||||
{
|
||||
byte[] buffer = new byte[0];
|
||||
AtaRegistersCHS registers = new AtaRegistersCHS();
|
||||
@@ -56,8 +59,9 @@ namespace DiscImageChef.Devices
|
||||
registers.command = (byte)AtaCommands.CheckMediaCardType;
|
||||
registers.feature = feature;
|
||||
|
||||
lastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.NonData, AtaTransferRegister.NoTransfer,
|
||||
ref buffer, timeout, false, out duration, out sense);
|
||||
lastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.NonData,
|
||||
AtaTransferRegister.NoTransfer, ref buffer, timeout, false, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("ATA Device", "CHECK MEDIA CARD TYPE took {0} ms.", duration);
|
||||
@@ -65,5 +69,4 @@ namespace DiscImageChef.Devices
|
||||
return sense;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -48,8 +48,9 @@ namespace DiscImageChef.Devices
|
||||
registers.lbaHigh = 0xC2;
|
||||
registers.lbaMid = 0x4F;
|
||||
|
||||
lastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.NonData, AtaTransferRegister.NoTransfer,
|
||||
ref buffer, timeout, false, out duration, out sense);
|
||||
lastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.NonData,
|
||||
AtaTransferRegister.NoTransfer, ref buffer, timeout, false, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("ATA Device", "SMART DISABLE OPERATIONS took {0} ms.", duration);
|
||||
@@ -57,7 +58,8 @@ namespace DiscImageChef.Devices
|
||||
return sense;
|
||||
}
|
||||
|
||||
public bool SmartEnableAttributeAutosave(out AtaErrorRegistersLBA28 statusRegisters, uint timeout, out double duration)
|
||||
public bool SmartEnableAttributeAutosave(out AtaErrorRegistersLBA28 statusRegisters, uint timeout,
|
||||
out double duration)
|
||||
{
|
||||
byte[] buffer = new byte[0];
|
||||
AtaRegistersLBA28 registers = new AtaRegistersLBA28();
|
||||
@@ -69,8 +71,9 @@ namespace DiscImageChef.Devices
|
||||
registers.lbaMid = 0x4F;
|
||||
registers.sectorCount = 0xF1;
|
||||
|
||||
lastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.NonData, AtaTransferRegister.NoTransfer,
|
||||
ref buffer, timeout, false, out duration, out sense);
|
||||
lastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.NonData,
|
||||
AtaTransferRegister.NoTransfer, ref buffer, timeout, false, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("ATA Device", "SMART ENABLE ATTRIBUTE AUTOSAVE took {0} ms.", duration);
|
||||
@@ -78,7 +81,8 @@ namespace DiscImageChef.Devices
|
||||
return sense;
|
||||
}
|
||||
|
||||
public bool SmartDisableAttributeAutosave(out AtaErrorRegistersLBA28 statusRegisters, uint timeout, out double duration)
|
||||
public bool SmartDisableAttributeAutosave(out AtaErrorRegistersLBA28 statusRegisters, uint timeout,
|
||||
out double duration)
|
||||
{
|
||||
byte[] buffer = new byte[0];
|
||||
AtaRegistersLBA28 registers = new AtaRegistersLBA28();
|
||||
@@ -89,8 +93,9 @@ namespace DiscImageChef.Devices
|
||||
registers.lbaHigh = 0xC2;
|
||||
registers.lbaMid = 0x4F;
|
||||
|
||||
lastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.NonData, AtaTransferRegister.NoTransfer,
|
||||
ref buffer, timeout, false, out duration, out sense);
|
||||
lastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.NonData,
|
||||
AtaTransferRegister.NoTransfer, ref buffer, timeout, false, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("ATA Device", "SMART DISABLE ATTRIBUTE AUTOSAVE took {0} ms.", duration);
|
||||
@@ -109,8 +114,9 @@ namespace DiscImageChef.Devices
|
||||
registers.lbaHigh = 0xC2;
|
||||
registers.lbaMid = 0x4F;
|
||||
|
||||
lastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.NonData, AtaTransferRegister.NoTransfer,
|
||||
ref buffer, timeout, false, out duration, out sense);
|
||||
lastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.NonData,
|
||||
AtaTransferRegister.NoTransfer, ref buffer, timeout, false, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("ATA Device", "SMART ENABLE OPERATIONS took {0} ms.", duration);
|
||||
@@ -118,7 +124,8 @@ namespace DiscImageChef.Devices
|
||||
return sense;
|
||||
}
|
||||
|
||||
public bool SmartExecuteOffLineImmediate(out AtaErrorRegistersLBA28 statusRegisters, byte subcommand, uint timeout, out double duration)
|
||||
public bool SmartExecuteOffLineImmediate(out AtaErrorRegistersLBA28 statusRegisters, byte subcommand,
|
||||
uint timeout, out double duration)
|
||||
{
|
||||
byte[] buffer = new byte[0];
|
||||
AtaRegistersLBA28 registers = new AtaRegistersLBA28();
|
||||
@@ -130,8 +137,9 @@ namespace DiscImageChef.Devices
|
||||
registers.lbaMid = 0x4F;
|
||||
registers.lbaLow = subcommand;
|
||||
|
||||
lastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.NonData, AtaTransferRegister.NoTransfer,
|
||||
ref buffer, timeout, false, out duration, out sense);
|
||||
lastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.NonData,
|
||||
AtaTransferRegister.NoTransfer, ref buffer, timeout, false, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("ATA Device", "SMART EXECUTE OFF-LINE IMMEDIATE took {0} ms.", duration);
|
||||
@@ -139,7 +147,8 @@ namespace DiscImageChef.Devices
|
||||
return sense;
|
||||
}
|
||||
|
||||
public bool SmartReadData(out byte[] buffer, out AtaErrorRegistersLBA28 statusRegisters, uint timeout, out double duration)
|
||||
public bool SmartReadData(out byte[] buffer, out AtaErrorRegistersLBA28 statusRegisters, uint timeout,
|
||||
out double duration)
|
||||
{
|
||||
buffer = new byte[512];
|
||||
AtaRegistersLBA28 registers = new AtaRegistersLBA28();
|
||||
@@ -150,8 +159,9 @@ namespace DiscImageChef.Devices
|
||||
registers.lbaHigh = 0xC2;
|
||||
registers.lbaMid = 0x4F;
|
||||
|
||||
lastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.PioIn, AtaTransferRegister.NoTransfer,
|
||||
ref buffer, timeout, false, out duration, out sense);
|
||||
lastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.PioIn,
|
||||
AtaTransferRegister.NoTransfer, ref buffer, timeout, false, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("ATA Device", "SMART READ DATA took {0} ms.", duration);
|
||||
@@ -159,7 +169,8 @@ namespace DiscImageChef.Devices
|
||||
return sense;
|
||||
}
|
||||
|
||||
public bool SmartReadLog(out byte[] buffer, out AtaErrorRegistersLBA28 statusRegisters, byte logAddress, uint timeout, out double duration)
|
||||
public bool SmartReadLog(out byte[] buffer, out AtaErrorRegistersLBA28 statusRegisters, byte logAddress,
|
||||
uint timeout, out double duration)
|
||||
{
|
||||
buffer = new byte[512];
|
||||
AtaRegistersLBA28 registers = new AtaRegistersLBA28();
|
||||
@@ -171,8 +182,9 @@ namespace DiscImageChef.Devices
|
||||
registers.lbaMid = 0x4F;
|
||||
registers.lbaLow = logAddress;
|
||||
|
||||
lastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.PioIn, AtaTransferRegister.NoTransfer,
|
||||
ref buffer, timeout, false, out duration, out sense);
|
||||
lastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.PioIn,
|
||||
AtaTransferRegister.NoTransfer, ref buffer, timeout, false, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("ATA Device", "SMART READ LOG took {0} ms.", duration);
|
||||
@@ -191,8 +203,9 @@ namespace DiscImageChef.Devices
|
||||
registers.lbaHigh = 0xC2;
|
||||
registers.lbaMid = 0x4F;
|
||||
|
||||
lastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.NonData, AtaTransferRegister.NoTransfer,
|
||||
ref buffer, timeout, false, out duration, out sense);
|
||||
lastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.NonData,
|
||||
AtaTransferRegister.NoTransfer, ref buffer, timeout, false, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("ATA Device", "SMART RETURN STATUS took {0} ms.", duration);
|
||||
|
||||
@@ -47,9 +47,11 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="direction">SCSI command transfer direction</param>
|
||||
/// <param name="duration">Time it took to execute the command in milliseconds</param>
|
||||
/// <param name="sense"><c>True</c> if SCSI command returned non-OK status and <paramref name="senseBuffer"/> contains SCSI sense</param>
|
||||
public int SendScsiCommand(byte[] cdb, ref byte[] buffer, out byte[] senseBuffer, uint timeout, ScsiDirection direction, out double duration, out bool sense)
|
||||
public int SendScsiCommand(byte[] cdb, ref byte[] buffer, out byte[] senseBuffer, uint timeout,
|
||||
ScsiDirection direction, out double duration, out bool sense)
|
||||
{
|
||||
return Command.SendScsiCommand(platformID, fd, cdb, ref buffer, out senseBuffer, timeout, direction, out duration, out sense);
|
||||
return Command.SendScsiCommand(platformID, fd, cdb, ref buffer, out senseBuffer, timeout, direction,
|
||||
out duration, out sense);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -66,11 +68,11 @@ namespace DiscImageChef.Devices
|
||||
/// <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>
|
||||
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)
|
||||
AtaProtocol protocol, AtaTransferRegister transferRegister, ref byte[] buffer,
|
||||
uint timeout, bool transferBlocks, out double duration, out bool sense)
|
||||
{
|
||||
return Command.SendAtaCommand(platformID, fd, registers, out errorRegisters, protocol, transferRegister,
|
||||
ref buffer, timeout, transferBlocks, out duration, out sense);
|
||||
ref buffer, timeout, transferBlocks, out duration, out sense);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -87,11 +89,11 @@ namespace DiscImageChef.Devices
|
||||
/// <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>
|
||||
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)
|
||||
AtaProtocol protocol, AtaTransferRegister transferRegister, ref byte[] buffer,
|
||||
uint timeout, bool transferBlocks, out double duration, out bool sense)
|
||||
{
|
||||
return Command.SendAtaCommand(platformID, fd, registers, out errorRegisters, protocol, transferRegister,
|
||||
ref buffer, timeout, transferBlocks, out duration, out sense);
|
||||
ref buffer, timeout, transferBlocks, out duration, out sense);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -108,11 +110,11 @@ namespace DiscImageChef.Devices
|
||||
/// <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>
|
||||
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)
|
||||
AtaProtocol protocol, AtaTransferRegister transferRegister, ref byte[] buffer,
|
||||
uint timeout, bool transferBlocks, out double duration, out bool sense)
|
||||
{
|
||||
return Command.SendAtaCommand(platformID, fd, registers, out errorRegisters, protocol, transferRegister,
|
||||
ref buffer, timeout, transferBlocks, out duration, out sense);
|
||||
ref buffer, timeout, transferBlocks, out duration, out sense);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -131,8 +133,8 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="argument">Command argument</param>
|
||||
/// <param name="response">Response registers</param>
|
||||
/// <param name="blockSize">Size of block in bytes</param>
|
||||
public int SendMmcCommand(MmcCommands command, bool write, bool isApplication, MmcFlags flags,
|
||||
uint argument, uint blockSize, uint blocks, ref byte[] buffer, out uint[] response,
|
||||
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)
|
||||
{
|
||||
if(command == MmcCommands.SendCID && cachedCid != null)
|
||||
@@ -184,9 +186,8 @@ namespace DiscImageChef.Devices
|
||||
return 0;
|
||||
}
|
||||
|
||||
return Command.SendMmcCommand(platformID, fd, command, write, isApplication, flags, argument, blockSize, blocks,
|
||||
ref buffer, out response, out duration, out sense, timeout);
|
||||
return Command.SendMmcCommand(platformID, fd, command, write, isApplication, flags, argument, blockSize,
|
||||
blocks, ref buffer, out response, out duration, out sense, timeout);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -54,33 +54,33 @@ namespace DiscImageChef.Devices
|
||||
switch(platformID)
|
||||
{
|
||||
case Interop.PlatformID.Win32NT:
|
||||
{
|
||||
fd = Windows.Extern.CreateFile(devicePath,
|
||||
Windows.FileAccess.GenericRead | Windows.FileAccess.GenericWrite,
|
||||
Windows.FileShare.Read | Windows.FileShare.Write, IntPtr.Zero,
|
||||
Windows.FileMode.OpenExisting, Windows.FileAttributes.Normal,
|
||||
IntPtr.Zero);
|
||||
|
||||
if(((SafeFileHandle)fd).IsInvalid)
|
||||
{
|
||||
fd = Windows.Extern.CreateFile(devicePath,
|
||||
Windows.FileAccess.GenericRead | Windows.FileAccess.GenericWrite,
|
||||
Windows.FileShare.Read | Windows.FileShare.Write,
|
||||
IntPtr.Zero, Windows.FileMode.OpenExisting,
|
||||
Windows.FileAttributes.Normal, IntPtr.Zero);
|
||||
|
||||
if(((SafeFileHandle)fd).IsInvalid)
|
||||
{
|
||||
error = true;
|
||||
lastError = Marshal.GetLastWin32Error();
|
||||
}
|
||||
|
||||
break;
|
||||
error = true;
|
||||
lastError = Marshal.GetLastWin32Error();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case Interop.PlatformID.Linux:
|
||||
{
|
||||
fd = Linux.Extern.open(devicePath, Linux.FileFlags.Readonly | Linux.FileFlags.NonBlocking);
|
||||
|
||||
if((int)fd < 0)
|
||||
{
|
||||
fd = Linux.Extern.open(devicePath, Linux.FileFlags.Readonly | Linux.FileFlags.NonBlocking);
|
||||
|
||||
if((int)fd < 0)
|
||||
{
|
||||
error = true;
|
||||
lastError = Marshal.GetLastWin32Error();
|
||||
}
|
||||
|
||||
break;
|
||||
error = true;
|
||||
lastError = Marshal.GetLastWin32Error();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case Interop.PlatformID.FreeBSD:
|
||||
{
|
||||
fd = FreeBSD.Extern.cam_open_device(devicePath, FreeBSD.FileFlags.ReadWrite);
|
||||
@@ -93,9 +93,10 @@ namespace DiscImageChef.Devices
|
||||
|
||||
FreeBSD.cam_device camDevice =
|
||||
(FreeBSD.cam_device)Marshal.PtrToStructure((IntPtr)fd, typeof(FreeBSD.cam_device));
|
||||
|
||||
|
||||
if(StringHandlers.CToString(camDevice.sim_name) == "ata")
|
||||
throw new InvalidOperationException("Parallel ATA devices are not supported on FreeBSD due to upstream bug #224250.");
|
||||
throw new
|
||||
InvalidOperationException("Parallel ATA devices are not supported on FreeBSD due to upstream bug #224250.");
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -103,8 +104,7 @@ namespace DiscImageChef.Devices
|
||||
throw new InvalidOperationException(string.Format("Platform {0} not yet supported.", platformID));
|
||||
}
|
||||
|
||||
if(error)
|
||||
throw new SystemException(string.Format("Error {0} opening device.", lastError));
|
||||
if(error) throw new SystemException(string.Format("Error {0} opening device.", lastError));
|
||||
|
||||
type = DeviceType.Unknown;
|
||||
scsiType = Decoders.SCSI.PeripheralDeviceTypes.UnknownDevice;
|
||||
@@ -115,8 +115,7 @@ namespace DiscImageChef.Devices
|
||||
byte[] senseBuf;
|
||||
byte[] inqBuf = null;
|
||||
|
||||
if(error)
|
||||
throw new SystemException(string.Format("Error {0} trying device.", lastError));
|
||||
if(error) throw new SystemException(string.Format("Error {0} trying device.", lastError));
|
||||
|
||||
bool scsiSense = true;
|
||||
string ntDevicePath = null;
|
||||
@@ -135,21 +134,24 @@ namespace DiscImageChef.Devices
|
||||
uint returned = 0;
|
||||
int error = 0;
|
||||
|
||||
bool hasError = !Windows.Extern.DeviceIoControlStorageQuery((SafeFileHandle)fd, Windows.WindowsIoctl.IOCTL_STORAGE_QUERY_PROPERTY, ref query, (uint)Marshal.SizeOf(query), descriptorPtr, 1000, ref returned, IntPtr.Zero);
|
||||
bool hasError = !Windows.Extern.DeviceIoControlStorageQuery((SafeFileHandle)fd,
|
||||
Windows.WindowsIoctl
|
||||
.IOCTL_STORAGE_QUERY_PROPERTY,
|
||||
ref query, (uint)Marshal.SizeOf(query),
|
||||
descriptorPtr, 1000, ref returned,
|
||||
IntPtr.Zero);
|
||||
|
||||
if(hasError)
|
||||
error = Marshal.GetLastWin32Error();
|
||||
if(hasError) error = Marshal.GetLastWin32Error();
|
||||
|
||||
Marshal.Copy(descriptorPtr, descriptor_b, 0, 1000);
|
||||
|
||||
if(!hasError && error == 0)
|
||||
{
|
||||
|
||||
Windows.StorageDeviceDescriptor descriptor = new Windows.StorageDeviceDescriptor();
|
||||
descriptor.Version = BitConverter.ToUInt32(descriptor_b, 0);
|
||||
descriptor.Size = BitConverter.ToUInt32(descriptor_b, 4);
|
||||
descriptor.DeviceType = descriptor_b[8];
|
||||
descriptor.DeviceTypeModifier= descriptor_b[9];
|
||||
descriptor.DeviceTypeModifier = descriptor_b[9];
|
||||
descriptor.RemovableMedia = descriptor_b[10] > 0;
|
||||
descriptor.CommandQueueing = descriptor_b[11] > 0;
|
||||
descriptor.VendorIdOffset = BitConverter.ToUInt32(descriptor_b, 12);
|
||||
@@ -207,14 +209,12 @@ namespace DiscImageChef.Devices
|
||||
type = DeviceType.ATAPI;
|
||||
Identify.IdentifyDevice? ATAID = Identify.Decode(ataBuf);
|
||||
|
||||
if(ATAID.HasValue)
|
||||
scsiSense = ScsiInquiry(out inqBuf, out senseBuf);
|
||||
if(ATAID.HasValue) scsiSense = ScsiInquiry(out inqBuf, out senseBuf);
|
||||
}
|
||||
else
|
||||
manufacturer = "ATA";
|
||||
else manufacturer = "ATA";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ntDevicePath = Windows.Command.GetDevicePath((SafeFileHandle)fd);
|
||||
DicConsole.DebugWriteLine("Windows devices", "NT device path: {0}", ntDevicePath);
|
||||
Marshal.FreeHGlobal(descriptorPtr);
|
||||
@@ -224,9 +224,11 @@ namespace DiscImageChef.Devices
|
||||
byte[] sdBuffer = new byte[16];
|
||||
bool sense = false;
|
||||
|
||||
lastError = Windows.Command.SendMmcCommand((SafeFileHandle)fd, MmcCommands.SendCSD, false, false, MmcFlags.ResponseSPI_R2 | MmcFlags.Response_R2 | MmcFlags.CommandAC,
|
||||
0, 16, 1, ref sdBuffer, out uint[] response, out double duration, out sense, 0);
|
||||
|
||||
lastError = Windows.Command.SendMmcCommand((SafeFileHandle)fd, MmcCommands.SendCSD, false, false,
|
||||
MmcFlags.ResponseSPI_R2 | MmcFlags.Response_R2 |
|
||||
MmcFlags.CommandAC, 0, 16, 1, ref sdBuffer,
|
||||
out uint[] response, out double duration, out sense, 0);
|
||||
|
||||
if(!sense)
|
||||
{
|
||||
cachedCsd = new byte[16];
|
||||
@@ -236,8 +238,10 @@ namespace DiscImageChef.Devices
|
||||
sdBuffer = new byte[16];
|
||||
sense = false;
|
||||
|
||||
lastError = Windows.Command.SendMmcCommand((SafeFileHandle)fd, MmcCommands.SendCID, false, false, MmcFlags.ResponseSPI_R2 | MmcFlags.Response_R2 | MmcFlags.CommandAC,
|
||||
0, 16, 1, ref sdBuffer, out response, out duration, out sense, 0);
|
||||
lastError = Windows.Command.SendMmcCommand((SafeFileHandle)fd, MmcCommands.SendCID, false, false,
|
||||
MmcFlags.ResponseSPI_R2 | MmcFlags.Response_R2 |
|
||||
MmcFlags.CommandAC, 0, 16, 1, ref sdBuffer, out response,
|
||||
out duration, out sense, 0);
|
||||
|
||||
if(!sense)
|
||||
{
|
||||
@@ -248,8 +252,11 @@ namespace DiscImageChef.Devices
|
||||
sdBuffer = new byte[8];
|
||||
sense = false;
|
||||
|
||||
lastError = Windows.Command.SendMmcCommand((SafeFileHandle)fd, (MmcCommands)SecureDigitalCommands.SendSCR, false, true, MmcFlags.ResponseSPI_R1 | MmcFlags.Response_R1 | MmcFlags.CommandADTC,
|
||||
0, 8, 1, ref sdBuffer, out response, out duration, out sense, 0);
|
||||
lastError = Windows.Command.SendMmcCommand((SafeFileHandle)fd,
|
||||
(MmcCommands)SecureDigitalCommands.SendSCR, false, true,
|
||||
MmcFlags.ResponseSPI_R1 | MmcFlags.Response_R1 |
|
||||
MmcFlags.CommandADTC, 0, 8, 1, ref sdBuffer,
|
||||
out response, out duration, out sense, 0);
|
||||
|
||||
if(!sense)
|
||||
{
|
||||
@@ -262,8 +269,12 @@ namespace DiscImageChef.Devices
|
||||
sdBuffer = new byte[4];
|
||||
sense = false;
|
||||
|
||||
lastError = Windows.Command.SendMmcCommand((SafeFileHandle)fd, (MmcCommands)SecureDigitalCommands.SendOperatingCondition, false, true, MmcFlags.ResponseSPI_R3 | MmcFlags.Response_R3 | MmcFlags.CommandBCR,
|
||||
0, 4, 1, ref sdBuffer, out response, out duration, out sense, 0);
|
||||
lastError = Windows.Command.SendMmcCommand((SafeFileHandle)fd,
|
||||
(MmcCommands)SecureDigitalCommands
|
||||
.SendOperatingCondition, false, true,
|
||||
MmcFlags.ResponseSPI_R3 | MmcFlags.Response_R3 |
|
||||
MmcFlags.CommandBCR, 0, 4, 1, ref sdBuffer,
|
||||
out response, out duration, out sense, 0);
|
||||
|
||||
if(!sense)
|
||||
{
|
||||
@@ -276,8 +287,11 @@ namespace DiscImageChef.Devices
|
||||
sdBuffer = new byte[4];
|
||||
sense = false;
|
||||
|
||||
lastError = Windows.Command.SendMmcCommand((SafeFileHandle)fd, MmcCommands.SendOpCond, false, true, MmcFlags.ResponseSPI_R3 | MmcFlags.Response_R3 | MmcFlags.CommandBCR,
|
||||
0, 4, 1, ref sdBuffer, out response, out duration, out sense, 0);
|
||||
lastError = Windows.Command.SendMmcCommand((SafeFileHandle)fd, MmcCommands.SendOpCond, false,
|
||||
true,
|
||||
MmcFlags.ResponseSPI_R3 | MmcFlags.Response_R3 |
|
||||
MmcFlags.CommandBCR, 0, 4, 1, ref sdBuffer,
|
||||
out response, out duration, out sense, 0);
|
||||
|
||||
if(!sense)
|
||||
{
|
||||
@@ -289,7 +303,9 @@ namespace DiscImageChef.Devices
|
||||
}
|
||||
else if(platformID == Interop.PlatformID.Linux)
|
||||
{
|
||||
if(devicePath.StartsWith("/dev/sd", StringComparison.Ordinal) || devicePath.StartsWith("/dev/sr", StringComparison.Ordinal) || devicePath.StartsWith("/dev/st", StringComparison.Ordinal))
|
||||
if(devicePath.StartsWith("/dev/sd", StringComparison.Ordinal) ||
|
||||
devicePath.StartsWith("/dev/sr", StringComparison.Ordinal) ||
|
||||
devicePath.StartsWith("/dev/st", StringComparison.Ordinal))
|
||||
scsiSense = ScsiInquiry(out inqBuf, out senseBuf);
|
||||
// MultiMediaCard and SecureDigital go here
|
||||
else if(devicePath.StartsWith("/dev/mmcblk", StringComparison.Ordinal))
|
||||
@@ -298,31 +314,26 @@ namespace DiscImageChef.Devices
|
||||
if(System.IO.File.Exists("/sys/block/" + devPath + "/device/csd"))
|
||||
{
|
||||
int len = ConvertFromHexASCII("/sys/block/" + devPath + "/device/csd", out cachedCsd);
|
||||
if(len == 0)
|
||||
cachedCsd = null;
|
||||
if(len == 0) cachedCsd = null;
|
||||
}
|
||||
if(System.IO.File.Exists("/sys/block/" + devPath + "/device/cid"))
|
||||
{
|
||||
int len = ConvertFromHexASCII("/sys/block/" + devPath + "/device/cid", out cachedCid);
|
||||
if(len == 0)
|
||||
cachedCid = null;
|
||||
if(len == 0) cachedCid = null;
|
||||
}
|
||||
if(System.IO.File.Exists("/sys/block/" + devPath + "/device/scr"))
|
||||
{
|
||||
int len = ConvertFromHexASCII("/sys/block/" + devPath + "/device/scr", out cachedScr);
|
||||
if(len == 0)
|
||||
cachedScr = null;
|
||||
if(len == 0) cachedScr = null;
|
||||
}
|
||||
if(System.IO.File.Exists("/sys/block/" + devPath + "/device/ocr"))
|
||||
{
|
||||
int len = ConvertFromHexASCII("/sys/block/" + devPath + "/device/ocr", out cachedOcr);
|
||||
if(len == 0)
|
||||
cachedOcr = null;
|
||||
if(len == 0) cachedOcr = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
scsiSense = ScsiInquiry(out inqBuf, out senseBuf);
|
||||
else scsiSense = ScsiInquiry(out inqBuf, out senseBuf);
|
||||
|
||||
#region SecureDigital / MultiMediaCard
|
||||
if(cachedCid != null)
|
||||
@@ -336,7 +347,8 @@ namespace DiscImageChef.Devices
|
||||
Decoders.SecureDigital.CID decoded = Decoders.SecureDigital.Decoders.DecodeCID(cachedCid);
|
||||
manufacturer = Decoders.SecureDigital.VendorString.Prettify(decoded.Manufacturer);
|
||||
model = decoded.ProductName;
|
||||
revision = string.Format("{0:X2}.{1:X2}", (decoded.ProductRevision & 0xF0) >> 4, decoded.ProductRevision & 0x0F);
|
||||
revision = string.Format("{0:X2}.{1:X2}", (decoded.ProductRevision & 0xF0) >> 4,
|
||||
decoded.ProductRevision & 0x0F);
|
||||
serial = string.Format("{0}", decoded.ProductSerialNumber);
|
||||
}
|
||||
else
|
||||
@@ -345,14 +357,14 @@ namespace DiscImageChef.Devices
|
||||
Decoders.MMC.CID decoded = Decoders.MMC.Decoders.DecodeCID(cachedCid);
|
||||
manufacturer = Decoders.MMC.VendorString.Prettify(decoded.Manufacturer);
|
||||
model = decoded.ProductName;
|
||||
revision = string.Format("{0:X2}.{1:X2}", (decoded.ProductRevision & 0xF0) >> 4, decoded.ProductRevision & 0x0F);
|
||||
revision = string.Format("{0:X2}.{1:X2}", (decoded.ProductRevision & 0xF0) >> 4,
|
||||
decoded.ProductRevision & 0x0F);
|
||||
serial = string.Format("{0}", decoded.ProductSerialNumber);
|
||||
}
|
||||
}
|
||||
#endregion SecureDigital / MultiMediaCard
|
||||
|
||||
#region USB
|
||||
|
||||
#region USB
|
||||
if(platformID == Interop.PlatformID.Linux)
|
||||
{
|
||||
if(devicePath.StartsWith("/dev/sd", StringComparison.Ordinal) ||
|
||||
@@ -378,7 +390,8 @@ namespace DiscImageChef.Devices
|
||||
string usbTemp;
|
||||
|
||||
usbFs = new System.IO.FileStream(resolvedLink + "/descriptors",
|
||||
System.IO.FileMode.Open, System.IO.FileAccess.Read);
|
||||
System.IO.FileMode.Open,
|
||||
System.IO.FileAccess.Read);
|
||||
byte[] usbBuf = new byte[65536];
|
||||
int usbCount = usbFs.Read(usbBuf, 0, 65536);
|
||||
usbDescriptors = new byte[usbCount];
|
||||
@@ -388,13 +401,13 @@ namespace DiscImageChef.Devices
|
||||
usbSr = new System.IO.StreamReader(resolvedLink + "/idProduct");
|
||||
usbTemp = usbSr.ReadToEnd();
|
||||
ushort.TryParse(usbTemp, System.Globalization.NumberStyles.HexNumber,
|
||||
System.Globalization.CultureInfo.InvariantCulture, out usbProduct);
|
||||
System.Globalization.CultureInfo.InvariantCulture, out usbProduct);
|
||||
usbSr.Close();
|
||||
|
||||
usbSr = new System.IO.StreamReader(resolvedLink + "/idVendor");
|
||||
usbTemp = usbSr.ReadToEnd();
|
||||
ushort.TryParse(usbTemp, System.Globalization.NumberStyles.HexNumber,
|
||||
System.Globalization.CultureInfo.InvariantCulture, out usbVendor);
|
||||
System.Globalization.CultureInfo.InvariantCulture, out usbVendor);
|
||||
usbSr.Close();
|
||||
|
||||
if(System.IO.File.Exists(resolvedLink + "/manufacturer"))
|
||||
@@ -429,13 +442,16 @@ namespace DiscImageChef.Devices
|
||||
else if(platformID == Interop.PlatformID.Win32NT)
|
||||
{
|
||||
Windows.Usb.USBDevice usbDevice = null;
|
||||
|
||||
|
||||
// I have to search for USB disks, floppies and CD-ROMs as separate device types
|
||||
foreach(string devGuid in new [] { Windows.Usb.GUID_DEVINTERFACE_FLOPPY, Windows.Usb.GUID_DEVINTERFACE_CDROM , Windows.Usb.GUID_DEVINTERFACE_DISK })
|
||||
foreach(string devGuid in new[]
|
||||
{
|
||||
Windows.Usb.GUID_DEVINTERFACE_FLOPPY, Windows.Usb.GUID_DEVINTERFACE_CDROM,
|
||||
Windows.Usb.GUID_DEVINTERFACE_DISK
|
||||
})
|
||||
{
|
||||
usbDevice = Windows.Usb.FindDrivePath(devicePath, devGuid);
|
||||
if (usbDevice != null)
|
||||
break;
|
||||
if(usbDevice != null) break;
|
||||
}
|
||||
|
||||
if(usbDevice != null)
|
||||
@@ -445,19 +461,20 @@ namespace DiscImageChef.Devices
|
||||
usbProduct = (ushort)usbDevice.DeviceDescriptor.idProduct;
|
||||
usbManufacturerString = usbDevice.Manufacturer;
|
||||
usbProductString = usbDevice.Product;
|
||||
usbSerialString = usbDevice.SerialNumber; // This is incorrect filled by Windows with SCSI/ATA serial number
|
||||
usbSerialString =
|
||||
usbDevice.SerialNumber; // This is incorrect filled by Windows with SCSI/ATA serial number
|
||||
}
|
||||
|
||||
}
|
||||
// TODO: Implement for other operating systems
|
||||
else
|
||||
usb = false;
|
||||
else usb = false;
|
||||
#endregion USB
|
||||
|
||||
#region FireWire
|
||||
if(platformID == Interop.PlatformID.Linux)
|
||||
{
|
||||
if(devicePath.StartsWith("/dev/sd", StringComparison.Ordinal) || devicePath.StartsWith("/dev/sr", StringComparison.Ordinal) || devicePath.StartsWith("/dev/st", StringComparison.Ordinal))
|
||||
if(devicePath.StartsWith("/dev/sd", StringComparison.Ordinal) ||
|
||||
devicePath.StartsWith("/dev/sr", StringComparison.Ordinal) ||
|
||||
devicePath.StartsWith("/dev/st", StringComparison.Ordinal))
|
||||
{
|
||||
string devPath = devicePath.Substring(5);
|
||||
if(System.IO.Directory.Exists("/sys/block/" + devPath))
|
||||
@@ -470,25 +487,29 @@ namespace DiscImageChef.Devices
|
||||
{
|
||||
resolvedLink = System.IO.Path.GetDirectoryName(resolvedLink);
|
||||
if(System.IO.File.Exists(resolvedLink + "/model") &&
|
||||
System.IO.File.Exists(resolvedLink + "/vendor") &&
|
||||
System.IO.File.Exists(resolvedLink + "/guid"))
|
||||
System.IO.File.Exists(resolvedLink + "/vendor") &&
|
||||
System.IO.File.Exists(resolvedLink + "/guid"))
|
||||
{
|
||||
System.IO.StreamReader fwSr;
|
||||
string fwTemp;
|
||||
|
||||
fwSr = new System.IO.StreamReader(resolvedLink + "/model");
|
||||
fwTemp = fwSr.ReadToEnd();
|
||||
uint.TryParse(fwTemp, System.Globalization.NumberStyles.HexNumber, System.Globalization.CultureInfo.InvariantCulture, out firewireModel);
|
||||
uint.TryParse(fwTemp, System.Globalization.NumberStyles.HexNumber,
|
||||
System.Globalization.CultureInfo.InvariantCulture, out firewireModel);
|
||||
fwSr.Close();
|
||||
|
||||
fwSr = new System.IO.StreamReader(resolvedLink + "/vendor");
|
||||
fwTemp = fwSr.ReadToEnd();
|
||||
uint.TryParse(fwTemp, System.Globalization.NumberStyles.HexNumber, System.Globalization.CultureInfo.InvariantCulture, out firewireVendor);
|
||||
uint.TryParse(fwTemp, System.Globalization.NumberStyles.HexNumber,
|
||||
System.Globalization.CultureInfo.InvariantCulture,
|
||||
out firewireVendor);
|
||||
fwSr.Close();
|
||||
|
||||
fwSr = new System.IO.StreamReader(resolvedLink + "/guid");
|
||||
fwTemp = fwSr.ReadToEnd();
|
||||
ulong.TryParse(fwTemp, System.Globalization.NumberStyles.HexNumber, System.Globalization.CultureInfo.InvariantCulture, out firewireGuid);
|
||||
ulong.TryParse(fwTemp, System.Globalization.NumberStyles.HexNumber,
|
||||
System.Globalization.CultureInfo.InvariantCulture, out firewireGuid);
|
||||
fwSr.Close();
|
||||
|
||||
if(System.IO.File.Exists(resolvedLink + "/model_name"))
|
||||
@@ -514,14 +535,15 @@ namespace DiscImageChef.Devices
|
||||
}
|
||||
}
|
||||
// TODO: Implement for other operating systems
|
||||
else
|
||||
firewire = false;
|
||||
else firewire = false;
|
||||
#endregion FireWire
|
||||
|
||||
#region PCMCIA
|
||||
if(platformID == Interop.PlatformID.Linux)
|
||||
{
|
||||
if(devicePath.StartsWith("/dev/sd", StringComparison.Ordinal) || devicePath.StartsWith("/dev/sr", StringComparison.Ordinal) || devicePath.StartsWith("/dev/st", StringComparison.Ordinal))
|
||||
if(devicePath.StartsWith("/dev/sd", StringComparison.Ordinal) ||
|
||||
devicePath.StartsWith("/dev/sr", StringComparison.Ordinal) ||
|
||||
devicePath.StartsWith("/dev/st", StringComparison.Ordinal))
|
||||
{
|
||||
string devPath = devicePath.Substring(5);
|
||||
if(System.IO.Directory.Exists("/sys/block/" + devPath))
|
||||
@@ -535,17 +557,23 @@ namespace DiscImageChef.Devices
|
||||
resolvedLink = System.IO.Path.GetDirectoryName(resolvedLink);
|
||||
if(System.IO.Directory.Exists(resolvedLink + "/pcmcia_socket"))
|
||||
{
|
||||
string[] subdirs = System.IO.Directory.GetDirectories(resolvedLink + "/pcmcia_socket", "pcmcia_socket*", System.IO.SearchOption.TopDirectoryOnly);
|
||||
string[] subdirs =
|
||||
System.IO.Directory.GetDirectories(resolvedLink + "/pcmcia_socket",
|
||||
"pcmcia_socket*",
|
||||
System.IO.SearchOption.TopDirectoryOnly);
|
||||
|
||||
if(subdirs.Length > 0)
|
||||
{
|
||||
string possibleDir = System.IO.Path.Combine(resolvedLink, "pcmcia_socket", subdirs[0]);
|
||||
string possibleDir =
|
||||
System.IO.Path.Combine(resolvedLink, "pcmcia_socket", subdirs[0]);
|
||||
if(System.IO.File.Exists(possibleDir + "/card_type") &&
|
||||
System.IO.File.Exists(possibleDir + "/cis"))
|
||||
{
|
||||
System.IO.FileStream cisFs;
|
||||
|
||||
cisFs = new System.IO.FileStream(possibleDir + "/cis", System.IO.FileMode.Open, System.IO.FileAccess.Read);
|
||||
cisFs = new System.IO.FileStream(possibleDir + "/cis",
|
||||
System.IO.FileMode.Open,
|
||||
System.IO.FileAccess.Read);
|
||||
byte[] cisBuf = new byte[65536];
|
||||
int cisCount = cisFs.Read(cisBuf, 0, 65536);
|
||||
cis = new byte[cisCount];
|
||||
@@ -563,8 +591,7 @@ namespace DiscImageChef.Devices
|
||||
}
|
||||
}
|
||||
// TODO: Implement for other operating systems
|
||||
else
|
||||
pcmcia = false;
|
||||
else pcmcia = false;
|
||||
#endregion PCMCIA
|
||||
|
||||
if(!scsiSense)
|
||||
@@ -573,20 +600,16 @@ namespace DiscImageChef.Devices
|
||||
|
||||
type = DeviceType.SCSI;
|
||||
bool serialSense = ScsiInquiry(out inqBuf, out senseBuf, 0x80);
|
||||
if(!serialSense)
|
||||
serial = Decoders.SCSI.EVPD.DecodePage80(inqBuf);
|
||||
if(!serialSense) serial = Decoders.SCSI.EVPD.DecodePage80(inqBuf);
|
||||
|
||||
if(Inquiry.HasValue)
|
||||
{
|
||||
string tmp = StringHandlers.CToString(Inquiry.Value.ProductRevisionLevel);
|
||||
if(tmp != null)
|
||||
revision = tmp.Trim();
|
||||
if(tmp != null) revision = tmp.Trim();
|
||||
tmp = StringHandlers.CToString(Inquiry.Value.ProductIdentification);
|
||||
if(tmp != null)
|
||||
model = tmp.Trim();
|
||||
if(tmp != null) model = tmp.Trim();
|
||||
tmp = StringHandlers.CToString(Inquiry.Value.VendorIdentification);
|
||||
if(tmp != null)
|
||||
manufacturer = tmp.Trim();
|
||||
if(tmp != null) manufacturer = tmp.Trim();
|
||||
removable = Inquiry.Value.RMB;
|
||||
|
||||
scsiType = (Decoders.SCSI.PeripheralDeviceTypes)Inquiry.Value.PeripheralDeviceType;
|
||||
@@ -599,8 +622,7 @@ namespace DiscImageChef.Devices
|
||||
type = DeviceType.ATAPI;
|
||||
Identify.IdentifyDevice? ATAID = Identify.Decode(ataBuf);
|
||||
|
||||
if(ATAID.HasValue)
|
||||
serial = ATAID.Value.SerialNumber;
|
||||
if(ATAID.HasValue) serial = ATAID.Value.SerialNumber;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -609,7 +631,7 @@ namespace DiscImageChef.Devices
|
||||
}
|
||||
}
|
||||
|
||||
if ((scsiSense && (usb || firewire)) || manufacturer == "ATA")
|
||||
if((scsiSense && (usb || firewire)) || manufacturer == "ATA")
|
||||
{
|
||||
bool ataSense = AtaIdentify(out ataBuf, out errorRegisters);
|
||||
if(!ataSense)
|
||||
@@ -621,8 +643,7 @@ namespace DiscImageChef.Devices
|
||||
{
|
||||
string[] separated = ATAID.Value.Model.Split(' ');
|
||||
|
||||
if(separated.Length == 1)
|
||||
model = separated[0];
|
||||
if(separated.Length == 1) model = separated[0];
|
||||
else
|
||||
{
|
||||
manufacturer = separated[0];
|
||||
@@ -636,10 +657,11 @@ namespace DiscImageChef.Devices
|
||||
|
||||
if((ushort)ATAID.Value.GeneralConfiguration != 0x848A)
|
||||
{
|
||||
removable |= (ATAID.Value.GeneralConfiguration & Identify.GeneralConfigurationBit.Removable) == Identify.GeneralConfigurationBit.Removable;
|
||||
removable |=
|
||||
(ATAID.Value.GeneralConfiguration & Identify.GeneralConfigurationBit.Removable) ==
|
||||
Identify.GeneralConfigurationBit.Removable;
|
||||
}
|
||||
else
|
||||
compactFlash = true;
|
||||
else compactFlash = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -654,37 +676,20 @@ namespace DiscImageChef.Devices
|
||||
|
||||
if(usb)
|
||||
{
|
||||
if(string.IsNullOrEmpty(manufacturer))
|
||||
manufacturer = usbManufacturerString;
|
||||
if(string.IsNullOrEmpty(model))
|
||||
model = usbProductString;
|
||||
if(string.IsNullOrEmpty(serial))
|
||||
serial = usbSerialString;
|
||||
else
|
||||
{
|
||||
foreach(char c in serial)
|
||||
{
|
||||
if(char.IsControl(c))
|
||||
serial = usbSerialString;
|
||||
}
|
||||
}
|
||||
if(string.IsNullOrEmpty(manufacturer)) manufacturer = usbManufacturerString;
|
||||
if(string.IsNullOrEmpty(model)) model = usbProductString;
|
||||
if(string.IsNullOrEmpty(serial)) serial = usbSerialString;
|
||||
else { foreach(char c in serial) { if(char.IsControl(c)) serial = usbSerialString; } }
|
||||
}
|
||||
|
||||
if(firewire)
|
||||
{
|
||||
if(string.IsNullOrEmpty(manufacturer))
|
||||
manufacturer = firewireVendorName;
|
||||
if(string.IsNullOrEmpty(model))
|
||||
model = firewireModelName;
|
||||
if(string.IsNullOrEmpty(serial))
|
||||
serial = string.Format("{0:X16}", firewireGuid);
|
||||
if(string.IsNullOrEmpty(manufacturer)) manufacturer = firewireVendorName;
|
||||
if(string.IsNullOrEmpty(model)) model = firewireModelName;
|
||||
if(string.IsNullOrEmpty(serial)) serial = string.Format("{0:X16}", firewireGuid);
|
||||
else
|
||||
{
|
||||
foreach(char c in serial)
|
||||
{
|
||||
if(char.IsControl(c))
|
||||
serial = string.Format("{0:X16}", firewireGuid);
|
||||
}
|
||||
foreach(char c in serial) { if(char.IsControl(c)) serial = string.Format("{0:X16}", firewireGuid); }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -698,20 +703,16 @@ namespace DiscImageChef.Devices
|
||||
|
||||
try
|
||||
{
|
||||
for(int i = 0; i < ins.Length; i+=2)
|
||||
for(int i = 0; i < ins.Length; i += 2)
|
||||
{
|
||||
outBuf[i/2] = Convert.ToByte(ins.Substring(i, 2), 16);
|
||||
outBuf[i / 2] = Convert.ToByte(ins.Substring(i, 2), 16);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
count = 0;
|
||||
}
|
||||
catch { count = 0; }
|
||||
|
||||
sr.Close();
|
||||
return count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -60,5 +60,4 @@ namespace DiscImageChef.Devices
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -50,16 +50,13 @@ namespace DiscImageChef.Devices
|
||||
{
|
||||
switch(Interop.DetectOS.GetRealPlatformID())
|
||||
{
|
||||
case Interop.PlatformID.Win32NT:
|
||||
return Windows.ListDevices.GetList();
|
||||
case Interop.PlatformID.Linux:
|
||||
return Linux.ListDevices.GetList();
|
||||
case Interop.PlatformID.FreeBSD:
|
||||
return FreeBSD.ListDevices.GetList();
|
||||
case Interop.PlatformID.Win32NT: return Windows.ListDevices.GetList();
|
||||
case Interop.PlatformID.Linux: return Linux.ListDevices.GetList();
|
||||
case Interop.PlatformID.FreeBSD: return FreeBSD.ListDevices.GetList();
|
||||
default:
|
||||
throw new InvalidOperationException(string.Format("Platform {0} not yet supported.", Interop.DetectOS.GetRealPlatformID()));
|
||||
throw new InvalidOperationException(string.Format("Platform {0} not yet supported.",
|
||||
Interop.DetectOS.GetRealPlatformID()));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -41,8 +41,9 @@ namespace DiscImageChef.Devices
|
||||
buffer = new byte[16];
|
||||
bool sense = false;
|
||||
|
||||
lastError = SendMmcCommand(MmcCommands.SendCSD, false, false, MmcFlags.ResponseSPI_R2 | MmcFlags.Response_R2 | MmcFlags.CommandAC,
|
||||
0, 16, 1, ref buffer, out response, out duration, out sense, timeout);
|
||||
lastError = SendMmcCommand(MmcCommands.SendCSD, false, false,
|
||||
MmcFlags.ResponseSPI_R2 | MmcFlags.Response_R2 | MmcFlags.CommandAC, 0, 16, 1,
|
||||
ref buffer, out response, out duration, out sense, timeout);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("MMC Device", "SEND_CSD took {0} ms.", duration);
|
||||
@@ -55,8 +56,9 @@ namespace DiscImageChef.Devices
|
||||
buffer = new byte[16];
|
||||
bool sense = false;
|
||||
|
||||
lastError = SendMmcCommand(MmcCommands.SendCID, false, false, MmcFlags.ResponseSPI_R2 | MmcFlags.Response_R2 | MmcFlags.CommandAC,
|
||||
0, 16, 1, ref buffer, out response, out duration, out sense, timeout);
|
||||
lastError = SendMmcCommand(MmcCommands.SendCID, false, false,
|
||||
MmcFlags.ResponseSPI_R2 | MmcFlags.Response_R2 | MmcFlags.CommandAC, 0, 16, 1,
|
||||
ref buffer, out response, out duration, out sense, timeout);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("MMC Device", "SEND_CID took {0} ms.", duration);
|
||||
@@ -69,8 +71,9 @@ namespace DiscImageChef.Devices
|
||||
buffer = new byte[4];
|
||||
bool sense = false;
|
||||
|
||||
lastError = SendMmcCommand(MmcCommands.SendOpCond, false, true, MmcFlags.ResponseSPI_R3 | MmcFlags.Response_R3 | MmcFlags.CommandBCR,
|
||||
0, 4, 1, ref buffer, out response, out duration, out sense, timeout);
|
||||
lastError = SendMmcCommand(MmcCommands.SendOpCond, false, true,
|
||||
MmcFlags.ResponseSPI_R3 | MmcFlags.Response_R3 | MmcFlags.CommandBCR, 0, 4, 1,
|
||||
ref buffer, out response, out duration, out sense, timeout);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SecureDigital Device", "SEND_OP_COND took {0} ms.", duration);
|
||||
@@ -83,8 +86,9 @@ namespace DiscImageChef.Devices
|
||||
buffer = new byte[512];
|
||||
bool sense = false;
|
||||
|
||||
lastError = SendMmcCommand(MmcCommands.SendExtCSD, false, false, MmcFlags.ResponseSPI_R1 | MmcFlags.Response_R1 | MmcFlags.CommandADTC,
|
||||
0, 512, 1, ref buffer, out response, out duration, out sense, timeout);
|
||||
lastError = SendMmcCommand(MmcCommands.SendExtCSD, false, false,
|
||||
MmcFlags.ResponseSPI_R1 | MmcFlags.Response_R1 | MmcFlags.CommandADTC, 0, 512, 1,
|
||||
ref buffer, out response, out duration, out sense, timeout);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("MMC Device", "SEND_EXT_CSD took {0} ms.", duration);
|
||||
@@ -97,8 +101,9 @@ namespace DiscImageChef.Devices
|
||||
byte[] buffer = new byte[0];
|
||||
bool sense = false;
|
||||
|
||||
lastError = SendMmcCommand(MmcCommands.SetBlocklen, false, false, MmcFlags.ResponseSPI_R1 | MmcFlags.Response_R1 | MmcFlags.CommandAC,
|
||||
length, 0, 0, ref buffer, out response, out duration, out sense, timeout);
|
||||
lastError = SendMmcCommand(MmcCommands.SetBlocklen, false, false,
|
||||
MmcFlags.ResponseSPI_R1 | MmcFlags.Response_R1 | MmcFlags.CommandAC, length, 0,
|
||||
0, ref buffer, out response, out duration, out sense, timeout);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("MMC Device", "SET_BLOCKLEN took {0} ms.", duration);
|
||||
@@ -106,36 +111,35 @@ namespace DiscImageChef.Devices
|
||||
return sense;
|
||||
}
|
||||
|
||||
public bool Read(out byte[] buffer, out uint[] response, uint lba, uint blockSize, uint transferLength, bool byteAddressed, uint timeout, out double duration)
|
||||
public bool Read(out byte[] buffer, out uint[] response, uint lba, uint blockSize, uint transferLength,
|
||||
bool byteAddressed, uint timeout, out double duration)
|
||||
{
|
||||
buffer = new byte[transferLength * blockSize];
|
||||
bool sense = false;
|
||||
uint address;
|
||||
if(byteAddressed)
|
||||
address = lba * blockSize;
|
||||
else
|
||||
address = lba;
|
||||
if(byteAddressed) address = lba * blockSize;
|
||||
else address = lba;
|
||||
|
||||
MmcCommands command;
|
||||
if(transferLength > 1)
|
||||
command = MmcCommands.ReadMultipleBlock;
|
||||
else
|
||||
command = MmcCommands.ReadSingleBlock;
|
||||
if(transferLength > 1) command = MmcCommands.ReadMultipleBlock;
|
||||
else command = MmcCommands.ReadSingleBlock;
|
||||
|
||||
lastError = SendMmcCommand(command, false, false, MmcFlags.ResponseSPI_R1 | MmcFlags.Response_R1 | MmcFlags.CommandADTC,
|
||||
address, blockSize, transferLength, ref buffer, out response, out duration, out sense, timeout);
|
||||
lastError = SendMmcCommand(command, false, false,
|
||||
MmcFlags.ResponseSPI_R1 | MmcFlags.Response_R1 | MmcFlags.CommandADTC, address,
|
||||
blockSize, transferLength, ref buffer, out response, out duration, out sense,
|
||||
timeout);
|
||||
error = lastError != 0;
|
||||
|
||||
if(transferLength > 1)
|
||||
{
|
||||
byte[] foo = new byte[0];
|
||||
SendMmcCommand(MmcCommands.StopTransmission, false, false, MmcFlags.Response_R1b | MmcFlags.ResponseSPI_R1b | MmcFlags.CommandAC,
|
||||
0, 0, 0, ref foo, out uint[] responseStop, out double stopDuration, out bool stopSense, timeout);
|
||||
SendMmcCommand(MmcCommands.StopTransmission, false, false,
|
||||
MmcFlags.Response_R1b | MmcFlags.ResponseSPI_R1b | MmcFlags.CommandAC, 0, 0, 0, ref foo,
|
||||
out uint[] responseStop, out double stopDuration, out bool stopSense, timeout);
|
||||
duration += stopDuration;
|
||||
DicConsole.DebugWriteLine("MMC Device", "READ_MULTIPLE_BLOCK took {0} ms.", duration);
|
||||
}
|
||||
else
|
||||
DicConsole.DebugWriteLine("MMC Device", "READ_SINGLE_BLOCK took {0} ms.", duration);
|
||||
else DicConsole.DebugWriteLine("MMC Device", "READ_SINGLE_BLOCK took {0} ms.", duration);
|
||||
|
||||
return sense;
|
||||
}
|
||||
@@ -145,8 +149,9 @@ namespace DiscImageChef.Devices
|
||||
buffer = new byte[4];
|
||||
bool sense = false;
|
||||
|
||||
lastError = SendMmcCommand(MmcCommands.SendStatus, false, true, MmcFlags.ResponseSPI_R1 | MmcFlags.Response_R1 | MmcFlags.CommandAC,
|
||||
0, 4, 1, ref buffer, out response, out duration, out sense, timeout);
|
||||
lastError = SendMmcCommand(MmcCommands.SendStatus, false, true,
|
||||
MmcFlags.ResponseSPI_R1 | MmcFlags.Response_R1 | MmcFlags.CommandAC, 0, 4, 1,
|
||||
ref buffer, out response, out duration, out sense, timeout);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SecureDigital Device", "SEND_STATUS took {0} ms.", duration);
|
||||
@@ -154,4 +159,4 @@ namespace DiscImageChef.Devices
|
||||
return sense;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -41,8 +41,9 @@ namespace DiscImageChef.Devices
|
||||
buffer = new byte[64];
|
||||
bool sense = false;
|
||||
|
||||
lastError = SendMmcCommand((MmcCommands)SecureDigitalCommands.SendStatus, false, true, MmcFlags.ResponseSPI_R1 | MmcFlags.Response_R1 | MmcFlags.CommandADTC,
|
||||
0, 64, 1, ref buffer, out response, out duration, out sense, timeout);
|
||||
lastError = SendMmcCommand((MmcCommands)SecureDigitalCommands.SendStatus, false, true,
|
||||
MmcFlags.ResponseSPI_R1 | MmcFlags.Response_R1 | MmcFlags.CommandADTC, 0, 64, 1,
|
||||
ref buffer, out response, out duration, out sense, timeout);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SecureDigital Device", "SD_STATUS took {0} ms.", duration);
|
||||
@@ -55,22 +56,24 @@ namespace DiscImageChef.Devices
|
||||
buffer = new byte[4];
|
||||
bool sense = false;
|
||||
|
||||
lastError = SendMmcCommand((MmcCommands)SecureDigitalCommands.SendOperatingCondition, false, true, MmcFlags.ResponseSPI_R3 | MmcFlags.Response_R3 | MmcFlags.CommandBCR,
|
||||
0, 4, 1, ref buffer, out response, out duration, out sense, timeout);
|
||||
lastError = SendMmcCommand((MmcCommands)SecureDigitalCommands.SendOperatingCondition, false, true,
|
||||
MmcFlags.ResponseSPI_R3 | MmcFlags.Response_R3 | MmcFlags.CommandBCR, 0, 4, 1,
|
||||
ref buffer, out response, out duration, out sense, timeout);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SecureDigital Device", "SD_SEND_OP_COND took {0} ms.", duration);
|
||||
|
||||
return sense;
|
||||
}
|
||||
|
||||
|
||||
public bool ReadSCR(out byte[] buffer, out uint[] response, uint timeout, out double duration)
|
||||
{
|
||||
buffer = new byte[8];
|
||||
bool sense = false;
|
||||
|
||||
lastError = SendMmcCommand((MmcCommands)SecureDigitalCommands.SendSCR, false, true, MmcFlags.ResponseSPI_R1 | MmcFlags.Response_R1 | MmcFlags.CommandADTC,
|
||||
0, 8, 1, ref buffer, out response, out duration, out sense, timeout);
|
||||
lastError = SendMmcCommand((MmcCommands)SecureDigitalCommands.SendSCR, false, true,
|
||||
MmcFlags.ResponseSPI_R1 | MmcFlags.Response_R1 | MmcFlags.CommandADTC, 0, 8, 1,
|
||||
ref buffer, out response, out duration, out sense, timeout);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SecureDigital Device", "SEND_SCR took {0} ms.", duration);
|
||||
@@ -78,4 +81,4 @@ namespace DiscImageChef.Devices
|
||||
return sense;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -46,7 +46,8 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="lba">SCSI Logical Block Address.</param>
|
||||
/// <param name="timeout">Timeout.</param>
|
||||
/// <param name="duration">Duration.</param>
|
||||
public bool AdaptecTranslate(out byte[] buffer, out byte[] senseBuffer, uint lba, uint timeout, out double duration)
|
||||
public bool AdaptecTranslate(out byte[] buffer, out byte[] senseBuffer, uint lba, uint timeout,
|
||||
out double duration)
|
||||
{
|
||||
return AdaptecTranslate(out buffer, out senseBuffer, false, lba, timeout, out duration);
|
||||
}
|
||||
@@ -60,7 +61,8 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="lba">SCSI Logical Block Address.</param>
|
||||
/// <param name="timeout">Timeout.</param>
|
||||
/// <param name="duration">Duration.</param>
|
||||
public bool AdaptecTranslate(out byte[] buffer, out byte[] senseBuffer, bool drive1, uint lba, uint timeout, out double duration)
|
||||
public bool AdaptecTranslate(out byte[] buffer, out byte[] senseBuffer, bool drive1, uint lba, uint timeout,
|
||||
out double duration)
|
||||
{
|
||||
buffer = new byte[8];
|
||||
byte[] cdb = new byte[6];
|
||||
@@ -71,10 +73,10 @@ namespace DiscImageChef.Devices
|
||||
cdb[1] = (byte)((lba & 0x1F0000) >> 16);
|
||||
cdb[2] = (byte)((lba & 0xFF00) >> 8);
|
||||
cdb[3] = (byte)(lba & 0xFF);
|
||||
if(drive1)
|
||||
cdb[1] += 0x20;
|
||||
if(drive1) cdb[1] += 0x20;
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "ADAPTEC TRANSLATE took {0} ms.", duration);
|
||||
@@ -104,7 +106,8 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="drive1">If set to <c>true</c> set the threshold from drive 1.</param>
|
||||
/// <param name="timeout">Timeout.</param>
|
||||
/// <param name="duration">Duration.</param>
|
||||
public bool AdaptecSetErrorThreshold(byte threshold, out byte[] senseBuffer, bool drive1, uint timeout, out double duration)
|
||||
public bool AdaptecSetErrorThreshold(byte threshold, out byte[] senseBuffer, bool drive1, uint timeout,
|
||||
out double duration)
|
||||
{
|
||||
byte[] buffer = new byte[1];
|
||||
buffer[0] = threshold;
|
||||
@@ -113,11 +116,11 @@ namespace DiscImageChef.Devices
|
||||
bool sense;
|
||||
|
||||
cdb[0] = (byte)ScsiCommands.Adaptec_SetErrorThreshold;
|
||||
if(drive1)
|
||||
cdb[1] += 0x20;
|
||||
if(drive1) cdb[1] += 0x20;
|
||||
cdb[4] = 1;
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.Out, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.Out, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "ADAPTEC SET ERROR THRESHOLD took {0} ms.", duration);
|
||||
@@ -132,7 +135,8 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="senseBuffer">Sense buffer.</param>
|
||||
/// <param name="timeout">Timeout.</param>
|
||||
/// <param name="duration">Duration.</param>
|
||||
public bool AdaptecReadUsageCounter(out byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration)
|
||||
public bool AdaptecReadUsageCounter(out byte[] buffer, out byte[] senseBuffer, uint timeout,
|
||||
out double duration)
|
||||
{
|
||||
return AdaptecReadUsageCounter(out buffer, out senseBuffer, false, timeout, out duration);
|
||||
}
|
||||
@@ -145,7 +149,8 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="drive1">If set to <c>true</c> get the counters from drive 1.</param>
|
||||
/// <param name="timeout">Timeout.</param>
|
||||
/// <param name="duration">Duration.</param>
|
||||
public bool AdaptecReadUsageCounter(out byte[] buffer, out byte[] senseBuffer, bool drive1, uint timeout, out double duration)
|
||||
public bool AdaptecReadUsageCounter(out byte[] buffer, out byte[] senseBuffer, bool drive1, uint timeout,
|
||||
out double duration)
|
||||
{
|
||||
buffer = new byte[9];
|
||||
byte[] cdb = new byte[6];
|
||||
@@ -153,11 +158,11 @@ namespace DiscImageChef.Devices
|
||||
bool sense;
|
||||
|
||||
cdb[0] = (byte)ScsiCommands.Adaptec_Translate;
|
||||
if(drive1)
|
||||
cdb[1] += 0x20;
|
||||
if(drive1) cdb[1] += 0x20;
|
||||
cdb[4] = (byte)buffer.Length;
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "ADAPTEC READ/RESET USAGE COUNTER took {0} ms.", duration);
|
||||
@@ -175,10 +180,8 @@ namespace DiscImageChef.Devices
|
||||
public bool AdaptecWriteBuffer(byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration)
|
||||
{
|
||||
byte[] oneKBuffer = new byte[1024];
|
||||
if(buffer.Length < 1024)
|
||||
Array.Copy(buffer, 0, oneKBuffer, 0, buffer.Length);
|
||||
else
|
||||
Array.Copy(buffer, 0, oneKBuffer, 0, 1024);
|
||||
if(buffer.Length < 1024) Array.Copy(buffer, 0, oneKBuffer, 0, buffer.Length);
|
||||
else Array.Copy(buffer, 0, oneKBuffer, 0, 1024);
|
||||
|
||||
byte[] cdb = new byte[6];
|
||||
senseBuffer = new byte[32];
|
||||
@@ -186,7 +189,8 @@ namespace DiscImageChef.Devices
|
||||
|
||||
cdb[0] = (byte)ScsiCommands.Adaptec_WriteBuffer;
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref oneKBuffer, out senseBuffer, timeout, ScsiDirection.Out, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref oneKBuffer, out senseBuffer, timeout, ScsiDirection.Out, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "ADAPTEC WRITE DATA BUFFER took {0} ms.", duration);
|
||||
@@ -210,7 +214,8 @@ namespace DiscImageChef.Devices
|
||||
|
||||
cdb[0] = (byte)ScsiCommands.Adaptec_ReadBuffer;
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "ADAPTEC READ DATA BUFFER took {0} ms.", duration);
|
||||
@@ -218,5 +223,4 @@ namespace DiscImageChef.Devices
|
||||
return sense;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -43,7 +43,8 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="senseBuffer">Sense buffer.</param>
|
||||
/// <param name="timeout">Timeout.</param>
|
||||
/// <param name="duration">Duration.</param>
|
||||
public bool ArchiveCorpRequestBlockAddress(out byte[] buffer, out byte[] senseBuffer, uint lba, uint timeout, out double duration)
|
||||
public bool ArchiveCorpRequestBlockAddress(out byte[] buffer, out byte[] senseBuffer, uint lba, uint timeout,
|
||||
out double duration)
|
||||
{
|
||||
buffer = new byte[3];
|
||||
byte[] cdb = new byte[6];
|
||||
@@ -56,7 +57,8 @@ namespace DiscImageChef.Devices
|
||||
cdb[3] = (byte)(lba & 0xFF);
|
||||
cdb[4] = 3;
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "ARCHIVE CORP. REQUEST BLOCK ADDRESS took {0} ms.", duration);
|
||||
@@ -84,7 +86,8 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="lba">Logical Block Address, starting from 1.</param>
|
||||
/// <param name="timeout">Timeout.</param>
|
||||
/// <param name="duration">Duration.</param>
|
||||
public bool ArchiveCorpSeekBlock(out byte[] senseBuffer, bool immediate, uint lba, uint timeout, out double duration)
|
||||
public bool ArchiveCorpSeekBlock(out byte[] senseBuffer, bool immediate, uint lba, uint timeout,
|
||||
out double duration)
|
||||
{
|
||||
byte[] buffer = new byte[0];
|
||||
byte[] cdb = new byte[6];
|
||||
@@ -95,10 +98,10 @@ namespace DiscImageChef.Devices
|
||||
cdb[1] = (byte)((lba & 0x1F0000) >> 16);
|
||||
cdb[2] = (byte)((lba & 0xFF00) >> 8);
|
||||
cdb[3] = (byte)(lba & 0xFF);
|
||||
if(immediate)
|
||||
cdb[1] += 0x01;
|
||||
if(immediate) cdb[1] += 0x01;
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.None, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.None, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "ARCHIVE CORP. SEEK BLOCK took {0} ms.", duration);
|
||||
@@ -106,5 +109,4 @@ namespace DiscImageChef.Devices
|
||||
return sense;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -73,10 +73,10 @@ namespace DiscImageChef.Devices
|
||||
bool sense;
|
||||
|
||||
cdb[0] = (byte)ScsiCommands.Certance_ParkUnpark;
|
||||
if(park)
|
||||
cdb[4] = 1;
|
||||
if(park) cdb[4] = 1;
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.None, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.None, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "CERTANCE PARK UNPARK took {0} ms.", duration);
|
||||
@@ -84,5 +84,4 @@ namespace DiscImageChef.Devices
|
||||
return sense;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -37,7 +37,8 @@ namespace DiscImageChef.Devices
|
||||
{
|
||||
public partial class Device
|
||||
{
|
||||
public bool FujitsuDisplay(out byte[] senseBuffer, bool flash, FujitsuDisplayModes mode, string firstHalf, string secondHalf, uint timeout, out double duration)
|
||||
public bool FujitsuDisplay(out byte[] senseBuffer, bool flash, FujitsuDisplayModes mode, string firstHalf,
|
||||
string secondHalf, uint timeout, out double duration)
|
||||
{
|
||||
byte[] tmp;
|
||||
byte[] firstHalfBytes = new byte[8];
|
||||
@@ -62,19 +63,19 @@ namespace DiscImageChef.Devices
|
||||
if(mode != FujitsuDisplayModes.Half)
|
||||
{
|
||||
if(!ArrayHelpers.ArrayIsNullOrWhiteSpace(firstHalfBytes) &&
|
||||
!ArrayHelpers.ArrayIsNullOrWhiteSpace(secondHalfBytes))
|
||||
!ArrayHelpers.ArrayIsNullOrWhiteSpace(secondHalfBytes))
|
||||
{
|
||||
displayLen = true;
|
||||
halfMsg = false;
|
||||
}
|
||||
else if(ArrayHelpers.ArrayIsNullOrWhiteSpace(firstHalfBytes) &&
|
||||
!ArrayHelpers.ArrayIsNullOrWhiteSpace(secondHalfBytes))
|
||||
!ArrayHelpers.ArrayIsNullOrWhiteSpace(secondHalfBytes))
|
||||
{
|
||||
displayLen = false;
|
||||
halfMsg = false;
|
||||
}
|
||||
else if(!ArrayHelpers.ArrayIsNullOrWhiteSpace(firstHalfBytes) &&
|
||||
ArrayHelpers.ArrayIsNullOrWhiteSpace(secondHalfBytes))
|
||||
ArrayHelpers.ArrayIsNullOrWhiteSpace(secondHalfBytes))
|
||||
{
|
||||
displayLen = false;
|
||||
halfMsg = true;
|
||||
@@ -87,12 +88,9 @@ namespace DiscImageChef.Devices
|
||||
}
|
||||
|
||||
buffer[0] = (byte)((byte)mode << 5);
|
||||
if(displayLen)
|
||||
buffer[0] += 0x10;
|
||||
if(flash)
|
||||
buffer[0] += 0x08;
|
||||
if(halfMsg)
|
||||
buffer[0] += 0x04;
|
||||
if(displayLen) buffer[0] += 0x10;
|
||||
if(flash) buffer[0] += 0x08;
|
||||
if(halfMsg) buffer[0] += 0x04;
|
||||
buffer[0] += 0x01; // Always ASCII
|
||||
|
||||
Array.Copy(firstHalfBytes, 0, buffer, 1, 8);
|
||||
@@ -101,7 +99,8 @@ namespace DiscImageChef.Devices
|
||||
cdb[0] = (byte)ScsiCommands.Fujitsu_Display;
|
||||
cdb[6] = (byte)buffer.Length;
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.Out, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.Out, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "FUJITSU DISPLAY took {0} ms.", duration);
|
||||
@@ -109,5 +108,4 @@ namespace DiscImageChef.Devices
|
||||
return sense;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -46,7 +46,8 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
|
||||
/// <param name="lba">Start block address.</param>
|
||||
/// <param name="transferLength">How many blocks to read.</param>
|
||||
public bool HlDtStReadRawDvd(out byte[] buffer, out byte[] senseBuffer, uint lba, uint transferLength, uint timeout, out double duration)
|
||||
public bool HlDtStReadRawDvd(out byte[] buffer, out byte[] senseBuffer, uint lba, uint transferLength,
|
||||
uint timeout, out double duration)
|
||||
{
|
||||
senseBuffer = new byte[32];
|
||||
byte[] cdb = new byte[12];
|
||||
@@ -65,7 +66,8 @@ namespace DiscImageChef.Devices
|
||||
cdb[10] = (byte)((buffer.Length & 0xFF00) >> 8);
|
||||
cdb[11] = (byte)(buffer.Length & 0xFF);
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "HL-DT-ST READ DVD (RAW) took {0} ms.", duration);
|
||||
@@ -73,5 +75,4 @@ namespace DiscImageChef.Devices
|
||||
return sense;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -48,9 +48,11 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="pba">If set to <c>true</c> address contain physical block address.</param>
|
||||
/// <param name="timeout">Timeout in seconds.</param>
|
||||
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
|
||||
public bool HPReadLong(out byte[] buffer, out byte[] senseBuffer, bool relAddr, uint address, ushort blockBytes, bool pba, uint timeout, out double duration)
|
||||
public bool HPReadLong(out byte[] buffer, out byte[] senseBuffer, bool relAddr, uint address, ushort blockBytes,
|
||||
bool pba, uint timeout, out double duration)
|
||||
{
|
||||
return HPReadLong(out buffer, out senseBuffer, relAddr, address, 0, blockBytes, pba, false, timeout, out duration);
|
||||
return HPReadLong(out buffer, out senseBuffer, relAddr, address, 0, blockBytes, pba, false, timeout,
|
||||
out duration);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -67,32 +69,30 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="sectorCount">If set to <c>true</c> <paramref name="transferLen"/> is a count of secors to read. Otherwise it will be ignored</param>
|
||||
/// <param name="timeout">Timeout in seconds.</param>
|
||||
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
|
||||
public bool HPReadLong(out byte[] buffer, out byte[] senseBuffer, bool relAddr, uint address, ushort transferLen, ushort blockBytes, bool pba, bool sectorCount, uint timeout, out double duration)
|
||||
public bool HPReadLong(out byte[] buffer, out byte[] senseBuffer, bool relAddr, uint address,
|
||||
ushort transferLen, ushort blockBytes, bool pba, bool sectorCount, uint timeout,
|
||||
out double duration)
|
||||
{
|
||||
senseBuffer = new byte[32];
|
||||
byte[] cdb = new byte[10];
|
||||
bool sense;
|
||||
|
||||
cdb[0] = (byte)ScsiCommands.ReadLong;
|
||||
if(relAddr)
|
||||
cdb[1] += 0x01;
|
||||
if(relAddr) cdb[1] += 0x01;
|
||||
cdb[2] = (byte)((address & 0xFF000000) >> 24);
|
||||
cdb[3] = (byte)((address & 0xFF0000) >> 16);
|
||||
cdb[4] = (byte)((address & 0xFF00) >> 8);
|
||||
cdb[5] = (byte)(address & 0xFF);
|
||||
cdb[7] = (byte)((transferLen & 0xFF00) >> 8);
|
||||
cdb[8] = (byte)(transferLen & 0xFF);
|
||||
if(pba)
|
||||
cdb[9] += 0x80;
|
||||
if(sectorCount)
|
||||
cdb[9] += 0x40;
|
||||
if(pba) cdb[9] += 0x80;
|
||||
if(sectorCount) cdb[9] += 0x40;
|
||||
|
||||
if(sectorCount)
|
||||
buffer = new byte[blockBytes * transferLen];
|
||||
else
|
||||
buffer = new byte[transferLen];
|
||||
if(sectorCount) buffer = new byte[blockBytes * transferLen];
|
||||
else buffer = new byte[transferLen];
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "HP READ LONG took {0} ms.", duration);
|
||||
@@ -100,5 +100,4 @@ namespace DiscImageChef.Devices
|
||||
return sense;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -56,7 +56,8 @@ namespace DiscImageChef.Devices
|
||||
cdb[2] = 0x01;
|
||||
cdb[3] = 0x01;
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.None, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.None, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "KREON DEPRECATED UNLOCK took {0} ms.", duration);
|
||||
@@ -121,7 +122,8 @@ namespace DiscImageChef.Devices
|
||||
cdb[3] = 0x11;
|
||||
cdb[4] = (byte)state;
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.None, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.None, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "KREON SET LOCK STATE took {0} ms.", duration);
|
||||
@@ -137,7 +139,8 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="timeout">Timeout.</param>
|
||||
/// <param name="duration">Duration.</param>
|
||||
/// <param name="features">Features supported by drive.</param>
|
||||
public bool KreonGetFeatureList(out byte[] senseBuffer, out KreonFeatures features, uint timeout, out double duration)
|
||||
public bool KreonGetFeatureList(out byte[] senseBuffer, out KreonFeatures features, uint timeout,
|
||||
out double duration)
|
||||
{
|
||||
senseBuffer = new byte[32];
|
||||
byte[] cdb = new byte[6];
|
||||
@@ -150,23 +153,21 @@ namespace DiscImageChef.Devices
|
||||
cdb[2] = 0x01;
|
||||
cdb[3] = 0x10;
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "KREON GET FEATURE LIST took {0} ms.", duration);
|
||||
|
||||
if(sense)
|
||||
return sense;
|
||||
if(sense) return sense;
|
||||
|
||||
if(buffer[0] != 0xA5 || buffer[1] != 0x5A || buffer[2] != 0x5A || buffer[3] != 0xA5)
|
||||
return true;
|
||||
if(buffer[0] != 0xA5 || buffer[1] != 0x5A || buffer[2] != 0x5A || buffer[3] != 0xA5) return true;
|
||||
|
||||
for(int i = 4; i < 26; i += 2)
|
||||
{
|
||||
ushort feature = BitConverter.ToUInt16(buffer, i);
|
||||
|
||||
if(feature == 0x0000)
|
||||
break;
|
||||
if(feature == 0x0000) break;
|
||||
|
||||
switch(feature)
|
||||
{
|
||||
@@ -214,7 +215,8 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="timeout">Timeout.</param>
|
||||
/// <param name="duration">Duration.</param>
|
||||
/// <param name="buffer">The SS sector.</param>
|
||||
public bool KreonExtractSS(out byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration, byte requestNumber = 0x00)
|
||||
public bool KreonExtractSS(out byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration,
|
||||
byte requestNumber = 0x00)
|
||||
{
|
||||
buffer = new byte[2048];
|
||||
byte[] cdb = new byte[12];
|
||||
@@ -234,7 +236,8 @@ namespace DiscImageChef.Devices
|
||||
cdb[10] = requestNumber;
|
||||
cdb[11] = 0xC0;
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "KREON EXTRACT SS took {0} ms.", duration);
|
||||
@@ -242,5 +245,4 @@ namespace DiscImageChef.Devices
|
||||
return sense;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -47,7 +47,8 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
|
||||
public bool GetConfiguration(out byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration)
|
||||
{
|
||||
return GetConfiguration(out buffer, out senseBuffer, 0x0000, MmcGetConfigurationRt.All, timeout, out duration);
|
||||
return GetConfiguration(out buffer, out senseBuffer, 0x0000, MmcGetConfigurationRt.All, timeout,
|
||||
out duration);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -59,9 +60,11 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="startingFeatureNumber">Feature number where the feature list should start from</param>
|
||||
/// <param name="timeout">Timeout in seconds.</param>
|
||||
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
|
||||
public bool GetConfiguration(out byte[] buffer, out byte[] senseBuffer, ushort startingFeatureNumber, uint timeout, out double duration)
|
||||
public bool GetConfiguration(out byte[] buffer, out byte[] senseBuffer, ushort startingFeatureNumber,
|
||||
uint timeout, out double duration)
|
||||
{
|
||||
return GetConfiguration(out buffer, out senseBuffer, startingFeatureNumber, MmcGetConfigurationRt.All, timeout, out duration);
|
||||
return GetConfiguration(out buffer, out senseBuffer, startingFeatureNumber, MmcGetConfigurationRt.All,
|
||||
timeout, out duration);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -74,7 +77,8 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
|
||||
/// <param name="startingFeatureNumber">Starting Feature number.</param>
|
||||
/// <param name="RT">Return type, <see cref="MmcGetConfigurationRt"/>.</param>
|
||||
public bool GetConfiguration(out byte[] buffer, out byte[] senseBuffer, ushort startingFeatureNumber, MmcGetConfigurationRt RT, uint timeout, out double duration)
|
||||
public bool GetConfiguration(out byte[] buffer, out byte[] senseBuffer, ushort startingFeatureNumber,
|
||||
MmcGetConfigurationRt RT, uint timeout, out double duration)
|
||||
{
|
||||
senseBuffer = new byte[32];
|
||||
byte[] cdb = new byte[10];
|
||||
@@ -89,11 +93,11 @@ namespace DiscImageChef.Devices
|
||||
cdb[8] = (byte)(buffer.Length & 0xFF);
|
||||
cdb[9] = 0;
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
if(sense)
|
||||
return true;
|
||||
if(sense) return true;
|
||||
|
||||
#pragma warning disable IDE0004 // Cast is necessary or an invalid bitshift happens
|
||||
ushort confLength = (ushort)(((int)buffer[2] << 8) + buffer[3] + 4);
|
||||
@@ -103,7 +107,8 @@ namespace DiscImageChef.Devices
|
||||
cdb[8] = (byte)(buffer.Length & 0xFF);
|
||||
senseBuffer = new byte[32];
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "GET CONFIGURATION took {0} ms.", duration);
|
||||
@@ -124,7 +129,9 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="format">Which disc structure are we requesting</param>
|
||||
/// <param name="AGID">AGID used in medium copy protection</param>
|
||||
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
|
||||
public bool ReadDiscStructure(out byte[] buffer, out byte[] senseBuffer, MmcDiscStructureMediaType mediaType, uint address, byte layerNumber, MmcDiscStructureFormat format, byte AGID, uint timeout, out double duration)
|
||||
public bool ReadDiscStructure(out byte[] buffer, out byte[] senseBuffer, MmcDiscStructureMediaType mediaType,
|
||||
uint address, byte layerNumber, MmcDiscStructureFormat format, byte AGID,
|
||||
uint timeout, out double duration)
|
||||
{
|
||||
senseBuffer = new byte[32];
|
||||
byte[] cdb = new byte[12];
|
||||
@@ -143,11 +150,11 @@ namespace DiscImageChef.Devices
|
||||
cdb[9] = (byte)(buffer.Length & 0xFF);
|
||||
cdb[10] = (byte)((AGID & 0x03) << 6);
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
if(sense)
|
||||
return true;
|
||||
if(sense) return true;
|
||||
|
||||
#pragma warning disable IDE0004 // Cast is necessary or an invalid bitshift happens
|
||||
ushort strctLength = (ushort)(((int)buffer[0] << 8) + buffer[1] + 2);
|
||||
@@ -157,7 +164,8 @@ namespace DiscImageChef.Devices
|
||||
cdb[9] = (byte)(buffer.Length & 0xFF);
|
||||
senseBuffer = new byte[32];
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "READ DISC STRUCTURE took {0} ms.", duration);
|
||||
@@ -189,7 +197,8 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="track">Start TOC from this track</param>
|
||||
/// <param name="timeout">Timeout in seconds.</param>
|
||||
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
|
||||
public bool ReadToc(out byte[] buffer, out byte[] senseBuffer, bool MSF, byte track, uint timeout, out double duration)
|
||||
public bool ReadToc(out byte[] buffer, out byte[] senseBuffer, bool MSF, byte track, uint timeout,
|
||||
out double duration)
|
||||
{
|
||||
return ReadTocPmaAtip(out buffer, out senseBuffer, MSF, 0, track, timeout, out duration);
|
||||
}
|
||||
@@ -216,7 +225,8 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="MSF">If <c>true</c>, request data in MM:SS:FF units, otherwise, in blocks</param>
|
||||
/// <param name="timeout">Timeout in seconds.</param>
|
||||
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
|
||||
public bool ReadSessionInfo(out byte[] buffer, out byte[] senseBuffer, bool MSF, uint timeout, out double duration)
|
||||
public bool ReadSessionInfo(out byte[] buffer, out byte[] senseBuffer, bool MSF, uint timeout,
|
||||
out double duration)
|
||||
{
|
||||
return ReadTocPmaAtip(out buffer, out senseBuffer, MSF, 1, 0, timeout, out duration);
|
||||
}
|
||||
@@ -230,7 +240,8 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="sessionNumber">Session which TOC to get</param>
|
||||
/// <param name="timeout">Timeout in seconds.</param>
|
||||
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
|
||||
public bool ReadRawToc(out byte[] buffer, out byte[] senseBuffer, byte sessionNumber, uint timeout, out double duration)
|
||||
public bool ReadRawToc(out byte[] buffer, out byte[] senseBuffer, byte sessionNumber, uint timeout,
|
||||
out double duration)
|
||||
{
|
||||
return ReadTocPmaAtip(out buffer, out senseBuffer, true, 2, sessionNumber, timeout, out duration);
|
||||
}
|
||||
@@ -285,27 +296,26 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="trackSessionNumber">Track/Session number</param>
|
||||
/// <param name="timeout">Timeout in seconds.</param>
|
||||
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
|
||||
public bool ReadTocPmaAtip(out byte[] buffer, out byte[] senseBuffer, bool MSF, byte format, byte trackSessionNumber, uint timeout, out double duration)
|
||||
public bool ReadTocPmaAtip(out byte[] buffer, out byte[] senseBuffer, bool MSF, byte format,
|
||||
byte trackSessionNumber, uint timeout, out double duration)
|
||||
{
|
||||
senseBuffer = new byte[32];
|
||||
byte[] cdb = new byte[10];
|
||||
byte[] tmpBuffer;
|
||||
bool sense;
|
||||
|
||||
if((format & 0x0F)== 5)
|
||||
tmpBuffer = new byte[32768];
|
||||
else
|
||||
tmpBuffer = new byte[1024];
|
||||
if((format & 0x0F) == 5) tmpBuffer = new byte[32768];
|
||||
else tmpBuffer = new byte[1024];
|
||||
|
||||
cdb[0] = (byte)ScsiCommands.ReadTocPmaAtip;
|
||||
if(MSF)
|
||||
cdb[1] = 0x02;
|
||||
if(MSF) cdb[1] = 0x02;
|
||||
cdb[2] = (byte)(format & 0x0F);
|
||||
cdb[6] = trackSessionNumber;
|
||||
cdb[7] = (byte)((tmpBuffer.Length & 0xFF00) >> 8);
|
||||
cdb[8] = (byte)(tmpBuffer.Length & 0xFF);
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref tmpBuffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref tmpBuffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
#pragma warning disable IDE0004 // Cast is necessary or an invalid bitshift happens
|
||||
@@ -322,7 +332,8 @@ namespace DiscImageChef.Devices
|
||||
|
||||
double tmpDuration = duration;
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
duration += tmpDuration;
|
||||
@@ -340,7 +351,8 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
|
||||
public bool ReadDiscInformation(out byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration)
|
||||
{
|
||||
return ReadDiscInformation(out buffer, out senseBuffer, MmcDiscInformationDataTypes.DiscInformation, timeout, out duration);
|
||||
return ReadDiscInformation(out buffer, out senseBuffer, MmcDiscInformationDataTypes.DiscInformation,
|
||||
timeout, out duration);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -352,7 +364,8 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="dataType">Which disc information to read</param>
|
||||
/// <param name="timeout">Timeout in seconds.</param>
|
||||
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
|
||||
public bool ReadDiscInformation(out byte[] buffer, out byte[] senseBuffer, MmcDiscInformationDataTypes dataType, uint timeout, out double duration)
|
||||
public bool ReadDiscInformation(out byte[] buffer, out byte[] senseBuffer, MmcDiscInformationDataTypes dataType,
|
||||
uint timeout, out double duration)
|
||||
{
|
||||
senseBuffer = new byte[32];
|
||||
byte[] cdb = new byte[10];
|
||||
@@ -364,7 +377,8 @@ namespace DiscImageChef.Devices
|
||||
cdb[7] = (byte)((tmpBuffer.Length & 0xFF00) >> 8);
|
||||
cdb[8] = (byte)(tmpBuffer.Length & 0xFF);
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref tmpBuffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref tmpBuffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
#pragma warning disable IDE0004 // Cast is necessary or an invalid bitshift happens
|
||||
@@ -398,8 +412,10 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="edcEcc">If set to <c>true</c> we request the EDC/ECC fields for data sectors.</param>
|
||||
/// <param name="C2Error">C2 error options.</param>
|
||||
/// <param name="subchannel">Subchannel selection.</param>
|
||||
public bool ReadCd(out byte[] buffer, out byte[] senseBuffer, uint lba, uint blockSize, uint transferLength, MmcSectorTypes expectedSectorType,
|
||||
bool DAP, bool relAddr, bool sync, MmcHeaderCodes headerCodes, bool userData, bool edcEcc, MmcErrorField C2Error, MmcSubchannel subchannel, uint timeout, out double duration)
|
||||
public bool ReadCd(out byte[] buffer, out byte[] senseBuffer, uint lba, uint blockSize, uint transferLength,
|
||||
MmcSectorTypes expectedSectorType, bool DAP, bool relAddr, bool sync,
|
||||
MmcHeaderCodes headerCodes, bool userData, bool edcEcc, MmcErrorField C2Error,
|
||||
MmcSubchannel subchannel, uint timeout, out double duration)
|
||||
{
|
||||
senseBuffer = new byte[32];
|
||||
byte[] cdb = new byte[12];
|
||||
@@ -407,10 +423,8 @@ namespace DiscImageChef.Devices
|
||||
|
||||
cdb[0] = (byte)ScsiCommands.ReadCd;
|
||||
cdb[1] = (byte)((byte)expectedSectorType << 2);
|
||||
if(DAP)
|
||||
cdb[1] += 0x02;
|
||||
if(relAddr)
|
||||
cdb[1] += 0x01;
|
||||
if(DAP) cdb[1] += 0x02;
|
||||
if(relAddr) cdb[1] += 0x01;
|
||||
cdb[2] = (byte)((lba & 0xFF000000) >> 24);
|
||||
cdb[3] = (byte)((lba & 0xFF0000) >> 16);
|
||||
cdb[4] = (byte)((lba & 0xFF00) >> 8);
|
||||
@@ -420,17 +434,15 @@ namespace DiscImageChef.Devices
|
||||
cdb[8] = (byte)(transferLength & 0xFF);
|
||||
cdb[9] = (byte)((byte)C2Error << 1);
|
||||
cdb[9] += (byte)((byte)headerCodes << 5);
|
||||
if(sync)
|
||||
cdb[9] += 0x80;
|
||||
if(userData)
|
||||
cdb[9] += 0x10;
|
||||
if(edcEcc)
|
||||
cdb[9] += 0x08;
|
||||
if(sync) cdb[9] += 0x80;
|
||||
if(userData) cdb[9] += 0x10;
|
||||
if(edcEcc) cdb[9] += 0x08;
|
||||
cdb[10] = (byte)subchannel;
|
||||
|
||||
buffer = new byte[blockSize * transferLength];
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "READ CD took {0} ms.", duration);
|
||||
@@ -457,8 +469,10 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="edcEcc">If set to <c>true</c> we request the EDC/ECC fields for data sectors.</param>
|
||||
/// <param name="C2Error">C2 error options.</param>
|
||||
/// <param name="subchannel">Subchannel selection.</param>
|
||||
public bool ReadCdMsf(out byte[] buffer, out byte[] senseBuffer, uint startMsf, uint endMsf, uint blockSize, MmcSectorTypes expectedSectorType,
|
||||
bool DAP, bool sync, MmcHeaderCodes headerCodes, bool userData, bool edcEcc, MmcErrorField C2Error, MmcSubchannel subchannel, uint timeout, out double duration)
|
||||
public bool ReadCdMsf(out byte[] buffer, out byte[] senseBuffer, uint startMsf, uint endMsf, uint blockSize,
|
||||
MmcSectorTypes expectedSectorType, bool DAP, bool sync, MmcHeaderCodes headerCodes,
|
||||
bool userData, bool edcEcc, MmcErrorField C2Error, MmcSubchannel subchannel, uint timeout,
|
||||
out double duration)
|
||||
{
|
||||
senseBuffer = new byte[32];
|
||||
byte[] cdb = new byte[12];
|
||||
@@ -466,8 +480,7 @@ namespace DiscImageChef.Devices
|
||||
|
||||
cdb[0] = (byte)ScsiCommands.ReadCdMsf;
|
||||
cdb[1] = (byte)((byte)expectedSectorType << 2);
|
||||
if(DAP)
|
||||
cdb[1] += 0x02;
|
||||
if(DAP) cdb[1] += 0x02;
|
||||
cdb[3] = (byte)((startMsf & 0xFF0000) >> 16);
|
||||
cdb[4] = (byte)((startMsf & 0xFF00) >> 8);
|
||||
cdb[5] = (byte)(startMsf & 0xFF);
|
||||
@@ -476,19 +489,17 @@ namespace DiscImageChef.Devices
|
||||
cdb[8] = (byte)(endMsf & 0xFF);
|
||||
cdb[9] = (byte)((byte)C2Error << 1);
|
||||
cdb[9] += (byte)((byte)headerCodes << 5);
|
||||
if(sync)
|
||||
cdb[9] += 0x80;
|
||||
if(userData)
|
||||
cdb[9] += 0x10;
|
||||
if(edcEcc)
|
||||
cdb[9] += 0x08;
|
||||
if(sync) cdb[9] += 0x80;
|
||||
if(userData) cdb[9] += 0x10;
|
||||
if(edcEcc) cdb[9] += 0x08;
|
||||
cdb[10] = (byte)subchannel;
|
||||
|
||||
uint transferLength = (uint)((cdb[6] - cdb[3]) * 60 * 75 + (cdb[7] - cdb[4]) * 75 + (cdb[8] - cdb[5]));
|
||||
|
||||
buffer = new byte[blockSize * transferLength];
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "READ CD MSF took {0} ms.", duration);
|
||||
@@ -506,7 +517,8 @@ namespace DiscImageChef.Devices
|
||||
return PreventAllowMediumRemoval(out senseBuffer, false, false, timeout, out duration);
|
||||
}
|
||||
|
||||
public bool PreventAllowMediumRemoval(out byte[] senseBuffer, bool persistent, bool prevent, uint timeout, out double duration)
|
||||
public bool PreventAllowMediumRemoval(out byte[] senseBuffer, bool persistent, bool prevent, uint timeout,
|
||||
out double duration)
|
||||
{
|
||||
senseBuffer = new byte[32];
|
||||
byte[] cdb = new byte[6];
|
||||
@@ -514,12 +526,11 @@ namespace DiscImageChef.Devices
|
||||
bool sense;
|
||||
|
||||
cdb[0] = (byte)ScsiCommands.PreventAllowMediumRemoval;
|
||||
if(prevent)
|
||||
cdb[4] += 0x01;
|
||||
if(persistent)
|
||||
cdb[4] += 0x02;
|
||||
if(prevent) cdb[4] += 0x01;
|
||||
if(persistent) cdb[4] += 0x02;
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.None, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.None, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "PREVENT ALLOW MEDIUM REMOVAL took {0} ms.", duration);
|
||||
@@ -547,7 +558,8 @@ namespace DiscImageChef.Devices
|
||||
return StartStopUnit(out senseBuffer, false, 0, 0, false, false, false, timeout, out duration);
|
||||
}
|
||||
|
||||
public bool StartStopUnit(out byte[] senseBuffer, bool immediate, byte formatLayer, byte powerConditions, bool changeFormatLayer, bool loadEject, bool start, uint timeout, out double duration)
|
||||
public bool StartStopUnit(out byte[] senseBuffer, bool immediate, byte formatLayer, byte powerConditions,
|
||||
bool changeFormatLayer, bool loadEject, bool start, uint timeout, out double duration)
|
||||
{
|
||||
senseBuffer = new byte[32];
|
||||
byte[] cdb = new byte[6];
|
||||
@@ -555,8 +567,7 @@ namespace DiscImageChef.Devices
|
||||
bool sense;
|
||||
|
||||
cdb[0] = (byte)ScsiCommands.StartStopUnit;
|
||||
if(immediate)
|
||||
cdb[1] += 0x01;
|
||||
if(immediate) cdb[1] += 0x01;
|
||||
if(changeFormatLayer)
|
||||
{
|
||||
cdb[3] = (byte)(formatLayer & 0x03);
|
||||
@@ -564,21 +575,18 @@ namespace DiscImageChef.Devices
|
||||
}
|
||||
else
|
||||
{
|
||||
if(loadEject)
|
||||
cdb[4] += 0x02;
|
||||
if(start)
|
||||
cdb[4] += 0x01;
|
||||
if(loadEject) cdb[4] += 0x02;
|
||||
if(start) cdb[4] += 0x01;
|
||||
}
|
||||
cdb[4] += (byte)((powerConditions & 0x0F) << 4);
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.None, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.None, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "START STOP UNIT took {0} ms.", duration);
|
||||
|
||||
return sense;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -46,7 +46,8 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
|
||||
/// <param name="lba">Start block address.</param>
|
||||
/// <param name="transferLength">How many blocks to read.</param>
|
||||
public bool NecReadCdDa(out byte[] buffer, out byte[] senseBuffer, uint lba, uint transferLength, uint timeout, out double duration)
|
||||
public bool NecReadCdDa(out byte[] buffer, out byte[] senseBuffer, uint lba, uint transferLength, uint timeout,
|
||||
out double duration)
|
||||
{
|
||||
senseBuffer = new byte[32];
|
||||
byte[] cdb = new byte[10];
|
||||
@@ -62,7 +63,8 @@ namespace DiscImageChef.Devices
|
||||
|
||||
buffer = new byte[2352 * transferLength];
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "READ CD-DA took {0} ms.", duration);
|
||||
@@ -70,5 +72,4 @@ namespace DiscImageChef.Devices
|
||||
return sense;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -48,7 +48,9 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="transferLength">How many blocks to read.</param>
|
||||
/// <param name="blockSize">Block size.</param>
|
||||
/// <param name="subchannel">Subchannel selection.</param>
|
||||
public bool PioneerReadCdDa(out byte[] buffer, out byte[] senseBuffer, uint lba, uint blockSize, uint transferLength, PioneerSubchannel subchannel, uint timeout, out double duration)
|
||||
public bool PioneerReadCdDa(out byte[] buffer, out byte[] senseBuffer, uint lba, uint blockSize,
|
||||
uint transferLength, PioneerSubchannel subchannel, uint timeout,
|
||||
out double duration)
|
||||
{
|
||||
senseBuffer = new byte[32];
|
||||
byte[] cdb = new byte[12];
|
||||
@@ -66,7 +68,8 @@ namespace DiscImageChef.Devices
|
||||
|
||||
buffer = new byte[blockSize * transferLength];
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "PIONEER READ CD-DA took {0} ms.", duration);
|
||||
@@ -86,7 +89,8 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="endMsf">End MM:SS:FF of read encoded as 0x00MMSSFF.</param>
|
||||
/// <param name="blockSize">Block size.</param>
|
||||
/// <param name="subchannel">Subchannel selection.</param>
|
||||
public bool PioneerReadCdDaMsf(out byte[] buffer, out byte[] senseBuffer, uint startMsf, uint endMsf, uint blockSize, PioneerSubchannel subchannel, uint timeout, out double duration)
|
||||
public bool PioneerReadCdDaMsf(out byte[] buffer, out byte[] senseBuffer, uint startMsf, uint endMsf,
|
||||
uint blockSize, PioneerSubchannel subchannel, uint timeout, out double duration)
|
||||
{
|
||||
senseBuffer = new byte[32];
|
||||
byte[] cdb = new byte[12];
|
||||
@@ -104,7 +108,8 @@ namespace DiscImageChef.Devices
|
||||
uint transferLength = (uint)((cdb[7] - cdb[3]) * 60 * 75 + (cdb[8] - cdb[4]) * 75 + (cdb[9] - cdb[5]));
|
||||
buffer = new byte[blockSize * transferLength];
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "PIONEER READ CD-DA MSF took {0} ms.", duration);
|
||||
@@ -124,7 +129,8 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="wholeSector">If set to <c>true</c>, returns all 2352 bytes of sector data.</param>
|
||||
/// <param name="lba">Start block address.</param>
|
||||
/// <param name="transferLength">How many blocks to read.</param>
|
||||
public bool PioneerReadCdXa(out byte[] buffer, out byte[] senseBuffer, uint lba, uint transferLength, bool errorFlags, bool wholeSector, uint timeout, out double duration)
|
||||
public bool PioneerReadCdXa(out byte[] buffer, out byte[] senseBuffer, uint lba, uint transferLength,
|
||||
bool errorFlags, bool wholeSector, uint timeout, out double duration)
|
||||
{
|
||||
senseBuffer = new byte[32];
|
||||
byte[] cdb = new byte[12];
|
||||
@@ -155,7 +161,8 @@ namespace DiscImageChef.Devices
|
||||
cdb[6] = 0x00;
|
||||
}
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "PIONEER READ CD-XA took {0} ms.", duration);
|
||||
@@ -163,5 +170,4 @@ namespace DiscImageChef.Devices
|
||||
return sense;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -48,9 +48,11 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="pba">If set to <c>true</c> address contain physical block address.</param>
|
||||
/// <param name="timeout">Timeout in seconds.</param>
|
||||
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
|
||||
public bool PlasmonReadLong(out byte[] buffer, out byte[] senseBuffer, bool relAddr, uint address, ushort blockBytes, bool pba, uint timeout, out double duration)
|
||||
public bool PlasmonReadLong(out byte[] buffer, out byte[] senseBuffer, bool relAddr, uint address,
|
||||
ushort blockBytes, bool pba, uint timeout, out double duration)
|
||||
{
|
||||
return HPReadLong(out buffer, out senseBuffer, relAddr, address, 0, blockBytes, pba, false, timeout, out duration);
|
||||
return HPReadLong(out buffer, out senseBuffer, relAddr, address, 0, blockBytes, pba, false, timeout,
|
||||
out duration);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -67,9 +69,12 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="sectorCount">If set to <c>true</c> <paramref name="transferLen"/> is a count of secors to read. Otherwise it will be ignored</param>
|
||||
/// <param name="timeout">Timeout in seconds.</param>
|
||||
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
|
||||
public bool PlasmonReadLong(out byte[] buffer, out byte[] senseBuffer, bool relAddr, uint address, ushort transferLen, ushort blockBytes, bool pba, bool sectorCount, uint timeout, out double duration)
|
||||
public bool PlasmonReadLong(out byte[] buffer, out byte[] senseBuffer, bool relAddr, uint address,
|
||||
ushort transferLen, ushort blockBytes, bool pba, bool sectorCount, uint timeout,
|
||||
out double duration)
|
||||
{
|
||||
return HPReadLong(out buffer, out senseBuffer, relAddr, address, transferLen, blockBytes, pba, sectorCount, timeout, out duration);
|
||||
return HPReadLong(out buffer, out senseBuffer, relAddr, address, transferLen, blockBytes, pba, sectorCount,
|
||||
timeout, out duration);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -82,7 +87,8 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="pba">If set to <c>true</c> address contain a physical block address.</param>
|
||||
/// <param name="timeout">Timeout in seconds.</param>
|
||||
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
|
||||
public bool PlasmonReadSectorLocation(out byte[] buffer, out byte[] senseBuffer, uint address, bool pba, uint timeout, out double duration)
|
||||
public bool PlasmonReadSectorLocation(out byte[] buffer, out byte[] senseBuffer, uint address, bool pba,
|
||||
uint timeout, out double duration)
|
||||
{
|
||||
senseBuffer = new byte[32];
|
||||
byte[] cdb = new byte[10];
|
||||
@@ -93,12 +99,12 @@ namespace DiscImageChef.Devices
|
||||
cdb[3] = (byte)((address & 0xFF0000) >> 16);
|
||||
cdb[4] = (byte)((address & 0xFF00) >> 8);
|
||||
cdb[5] = (byte)(address & 0xFF);
|
||||
if(pba)
|
||||
cdb[9] += 0x80;
|
||||
if(pba) cdb[9] += 0x80;
|
||||
|
||||
buffer = new byte[8];
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "PLASMON READ SECTOR LOCATION took {0} ms.", duration);
|
||||
@@ -106,5 +112,4 @@ namespace DiscImageChef.Devices
|
||||
return sense;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -49,7 +49,9 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="transferLength">How many blocks to read.</param>
|
||||
/// <param name="blockSize">Block size.</param>
|
||||
/// <param name="subchannel">Subchannel selection.</param>
|
||||
public bool PlextorReadCdDa(out byte[] buffer, out byte[] senseBuffer, uint lba, uint blockSize, uint transferLength, PlextorSubchannel subchannel, uint timeout, out double duration)
|
||||
public bool PlextorReadCdDa(out byte[] buffer, out byte[] senseBuffer, uint lba, uint blockSize,
|
||||
uint transferLength, PlextorSubchannel subchannel, uint timeout,
|
||||
out double duration)
|
||||
{
|
||||
senseBuffer = new byte[32];
|
||||
byte[] cdb = new byte[12];
|
||||
@@ -68,7 +70,8 @@ namespace DiscImageChef.Devices
|
||||
|
||||
buffer = new byte[blockSize * transferLength];
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "READ CD-DA took {0} ms.", duration);
|
||||
@@ -86,7 +89,8 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
|
||||
/// <param name="lba">Start block address.</param>
|
||||
/// <param name="transferLength">How many blocks to read.</param>
|
||||
public bool PlextorReadRawDvd(out byte[] buffer, out byte[] senseBuffer, uint lba, uint transferLength, uint timeout, out double duration)
|
||||
public bool PlextorReadRawDvd(out byte[] buffer, out byte[] senseBuffer, uint lba, uint transferLength,
|
||||
uint timeout, out double duration)
|
||||
{
|
||||
senseBuffer = new byte[32];
|
||||
byte[] cdb = new byte[10];
|
||||
@@ -102,7 +106,8 @@ namespace DiscImageChef.Devices
|
||||
cdb[4] = (byte)((buffer.Length & 0xFF00) >> 8);
|
||||
cdb[5] = (byte)(buffer.Length & 0xFF);
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "Plextor READ DVD (RAW) took {0} ms.", duration);
|
||||
@@ -128,7 +133,8 @@ namespace DiscImageChef.Devices
|
||||
cdb[0] = (byte)ScsiCommands.Plextor_ReadEeprom;
|
||||
cdb[8] = 1;
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "PLEXTOR READ EEPROM took {0} ms.", duration);
|
||||
@@ -154,7 +160,8 @@ namespace DiscImageChef.Devices
|
||||
cdb[0] = (byte)ScsiCommands.Plextor_ReadEeprom;
|
||||
cdb[8] = 2;
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "PLEXTOR READ EEPROM took {0} ms.", duration);
|
||||
@@ -172,7 +179,8 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="blockSize">How many bytes are in the EEPROM block</param>
|
||||
/// <param name="timeout">Timeout.</param>
|
||||
/// <param name="duration">Duration.</param>
|
||||
public bool PlextorReadEepromBlock(out byte[] buffer, out byte[] senseBuffer, byte block, ushort blockSize, uint timeout, out double duration)
|
||||
public bool PlextorReadEepromBlock(out byte[] buffer, out byte[] senseBuffer, byte block, ushort blockSize,
|
||||
uint timeout, out double duration)
|
||||
{
|
||||
buffer = new byte[blockSize];
|
||||
senseBuffer = new byte[32];
|
||||
@@ -185,7 +193,8 @@ namespace DiscImageChef.Devices
|
||||
cdb[8] = (byte)((blockSize & 0xFF00) >> 8);
|
||||
cdb[9] = (byte)(blockSize & 0xFF);
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "PLEXTOR READ EEPROM took {0} ms.", duration);
|
||||
@@ -203,7 +212,8 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="last">Last actual speed.</param>
|
||||
/// <param name="timeout">Timeout.</param>
|
||||
/// <param name="duration">Duration.</param>
|
||||
public bool PlextorGetSpeeds(out byte[] senseBuffer, out ushort selected, out ushort max, out ushort last, uint timeout, out double duration)
|
||||
public bool PlextorGetSpeeds(out byte[] senseBuffer, out ushort selected, out ushort max, out ushort last,
|
||||
uint timeout, out double duration)
|
||||
{
|
||||
byte[] buf = new byte[10];
|
||||
senseBuffer = new byte[32];
|
||||
@@ -217,7 +227,8 @@ namespace DiscImageChef.Devices
|
||||
cdb[0] = (byte)ScsiCommands.Plextor_PoweRec;
|
||||
cdb[9] = (byte)buf.Length;
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buf, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buf, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "PLEXTOR POWEREC GET SPEEDS took {0} ms.", duration);
|
||||
@@ -242,7 +253,8 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="speed">PoweRec recommended speed.</param>
|
||||
/// <param name="timeout">Timeout.</param>
|
||||
/// <param name="duration">Duration.</param>
|
||||
public bool PlextorGetPoweRec(out byte[] senseBuffer, out bool enabled, out ushort speed, uint timeout, out double duration)
|
||||
public bool PlextorGetPoweRec(out byte[] senseBuffer, out bool enabled, out ushort speed, uint timeout,
|
||||
out double duration)
|
||||
{
|
||||
byte[] buf = new byte[8];
|
||||
senseBuffer = new byte[32];
|
||||
@@ -256,7 +268,8 @@ namespace DiscImageChef.Devices
|
||||
cdb[1] = (byte)PlextorSubCommands.GetMode;
|
||||
cdb[9] = (byte)buf.Length;
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buf, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buf, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "PLEXTOR POWEREC GET SPEEDS took {0} ms.", duration);
|
||||
@@ -292,7 +305,8 @@ namespace DiscImageChef.Devices
|
||||
cdb[3] = 4;
|
||||
cdb[10] = (byte)buffer.Length;
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "PLEXTOR GET SILENT MODE took {0} ms.", duration);
|
||||
@@ -320,7 +334,8 @@ namespace DiscImageChef.Devices
|
||||
cdb[2] = (byte)PlextorSubCommands.GigaRec;
|
||||
cdb[10] = (byte)buffer.Length;
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "PLEXTOR GET GIGAREC took {0} ms.", duration);
|
||||
@@ -336,7 +351,8 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="senseBuffer">Sense buffer.</param>
|
||||
/// <param name="timeout">Timeout.</param>
|
||||
/// <param name="duration">Duration.</param>
|
||||
public bool PlextorGetVariRec(out byte[] buffer, out byte[] senseBuffer, bool dvd, uint timeout, out double duration)
|
||||
public bool PlextorGetVariRec(out byte[] buffer, out byte[] senseBuffer, bool dvd, uint timeout,
|
||||
out double duration)
|
||||
{
|
||||
buffer = new byte[8];
|
||||
senseBuffer = new byte[32];
|
||||
@@ -348,12 +364,11 @@ namespace DiscImageChef.Devices
|
||||
cdb[2] = (byte)PlextorSubCommands.VariRec;
|
||||
cdb[10] = (byte)buffer.Length;
|
||||
|
||||
if(dvd)
|
||||
cdb[3] = 0x12;
|
||||
else
|
||||
cdb[3] = 0x02;
|
||||
if(dvd) cdb[3] = 0x12;
|
||||
else cdb[3] = 0x02;
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "PLEXTOR GET VARIREC took {0} ms.", duration);
|
||||
@@ -380,7 +395,8 @@ namespace DiscImageChef.Devices
|
||||
cdb[2] = (byte)PlextorSubCommands.SecuRec;
|
||||
cdb[10] = (byte)buffer.Length;
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "PLEXTOR GET SECUREC took {0} ms.", duration);
|
||||
@@ -408,7 +424,8 @@ namespace DiscImageChef.Devices
|
||||
cdb[2] = (byte)PlextorSubCommands.SpeedRead;
|
||||
cdb[10] = (byte)buffer.Length;
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "PLEXTOR GET SPEEDREAD took {0} ms.", duration);
|
||||
@@ -436,7 +453,8 @@ namespace DiscImageChef.Devices
|
||||
cdb[2] = (byte)PlextorSubCommands.SessionHide;
|
||||
cdb[9] = (byte)buffer.Length;
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "PLEXTOR GET SINGLE-SESSION / HIDE CD-R took {0} ms.", duration);
|
||||
@@ -452,7 +470,8 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="senseBuffer">Sense buffer.</param>
|
||||
/// <param name="timeout">Timeout.</param>
|
||||
/// <param name="duration">Duration.</param>
|
||||
public bool PlextorGetBitsetting(out byte[] buffer, out byte[] senseBuffer, bool dualLayer, uint timeout, out double duration)
|
||||
public bool PlextorGetBitsetting(out byte[] buffer, out byte[] senseBuffer, bool dualLayer, uint timeout,
|
||||
out double duration)
|
||||
{
|
||||
buffer = new byte[8];
|
||||
senseBuffer = new byte[32];
|
||||
@@ -464,12 +483,11 @@ namespace DiscImageChef.Devices
|
||||
cdb[2] = (byte)PlextorSubCommands.BitSet;
|
||||
cdb[9] = (byte)buffer.Length;
|
||||
|
||||
if(dualLayer)
|
||||
cdb[3] = (byte)PlextorSubCommands.BitSetRDL;
|
||||
else
|
||||
cdb[3] = (byte)PlextorSubCommands.BitSetR;
|
||||
if(dualLayer) cdb[3] = (byte)PlextorSubCommands.BitSetRDL;
|
||||
else cdb[3] = (byte)PlextorSubCommands.BitSetR;
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "PLEXTOR GET BOOK BITSETTING took {0} ms.", duration);
|
||||
@@ -485,7 +503,8 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="senseBuffer">Sense buffer.</param>
|
||||
/// <param name="timeout">Timeout.</param>
|
||||
/// <param name="duration">Duration.</param>
|
||||
public bool PlextorGetTestWriteDvdPlus(out byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration)
|
||||
public bool PlextorGetTestWriteDvdPlus(out byte[] buffer, out byte[] senseBuffer, uint timeout,
|
||||
out double duration)
|
||||
{
|
||||
buffer = new byte[8];
|
||||
senseBuffer = new byte[32];
|
||||
@@ -497,7 +516,8 @@ namespace DiscImageChef.Devices
|
||||
cdb[2] = (byte)PlextorSubCommands.TestWriteDvdPlus;
|
||||
cdb[10] = (byte)buffer.Length;
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "PLEXTOR GET TEST WRITE DVD+ took {0} ms.", duration);
|
||||
@@ -505,5 +525,4 @@ namespace DiscImageChef.Devices
|
||||
return sense;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -47,7 +47,8 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
|
||||
/// <param name="lba">Starting block.</param>
|
||||
/// <param name="blockSize">Block size in bytes.</param>
|
||||
public bool Read6(out byte[] buffer, out byte[] senseBuffer, uint lba, uint blockSize, uint timeout, out double duration)
|
||||
public bool Read6(out byte[] buffer, out byte[] senseBuffer, uint lba, uint blockSize, uint timeout,
|
||||
out double duration)
|
||||
{
|
||||
return Read6(out buffer, out senseBuffer, lba, blockSize, 1, timeout, out duration);
|
||||
}
|
||||
@@ -63,7 +64,8 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="lba">Starting block.</param>
|
||||
/// <param name="blockSize">Block size in bytes.</param>
|
||||
/// <param name="transferLength">How many blocks to read.</param>
|
||||
public bool Read6(out byte[] buffer, out byte[] senseBuffer, uint lba, uint blockSize, byte transferLength, uint timeout, out double duration)
|
||||
public bool Read6(out byte[] buffer, out byte[] senseBuffer, uint lba, uint blockSize, byte transferLength,
|
||||
uint timeout, out double duration)
|
||||
{
|
||||
senseBuffer = new byte[32];
|
||||
byte[] cdb = new byte[6];
|
||||
@@ -75,12 +77,11 @@ namespace DiscImageChef.Devices
|
||||
cdb[3] = (byte)(lba & 0xFF);
|
||||
cdb[4] = transferLength;
|
||||
|
||||
if(transferLength == 0)
|
||||
buffer = new byte[256 * blockSize];
|
||||
else
|
||||
buffer = new byte[transferLength * blockSize];
|
||||
if(transferLength == 0) buffer = new byte[256 * blockSize];
|
||||
else buffer = new byte[transferLength * blockSize];
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "READ (6) took {0} ms.", duration);
|
||||
@@ -105,7 +106,9 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="groupNumber">Group number where attributes associated with this command should be collected.</param>
|
||||
/// <param name="transferLength">How many blocks to read.</param>
|
||||
/// <param name="relAddr">If set to <c>true</c> address is relative to current position.</param>
|
||||
public bool Read10(out byte[] buffer, out byte[] senseBuffer, byte rdprotect, bool dpo, bool fua, bool fuaNv, bool relAddr, uint lba, uint blockSize, byte groupNumber, ushort transferLength, uint timeout, out double duration)
|
||||
public bool Read10(out byte[] buffer, out byte[] senseBuffer, byte rdprotect, bool dpo, bool fua, bool fuaNv,
|
||||
bool relAddr, uint lba, uint blockSize, byte groupNumber, ushort transferLength,
|
||||
uint timeout, out double duration)
|
||||
{
|
||||
senseBuffer = new byte[32];
|
||||
byte[] cdb = new byte[10];
|
||||
@@ -113,14 +116,10 @@ namespace DiscImageChef.Devices
|
||||
|
||||
cdb[0] = (byte)ScsiCommands.Read10;
|
||||
cdb[1] = (byte)((rdprotect & 0x07) << 5);
|
||||
if(dpo)
|
||||
cdb[1] += 0x10;
|
||||
if(fua)
|
||||
cdb[1] += 0x08;
|
||||
if(fuaNv)
|
||||
cdb[1] += 0x02;
|
||||
if(relAddr)
|
||||
cdb[1] += 0x01;
|
||||
if(dpo) cdb[1] += 0x10;
|
||||
if(fua) cdb[1] += 0x08;
|
||||
if(fuaNv) cdb[1] += 0x02;
|
||||
if(relAddr) cdb[1] += 0x01;
|
||||
cdb[2] = (byte)((lba & 0xFF000000) >> 24);
|
||||
cdb[3] = (byte)((lba & 0xFF0000) >> 16);
|
||||
cdb[4] = (byte)((lba & 0xFF00) >> 8);
|
||||
@@ -131,7 +130,8 @@ namespace DiscImageChef.Devices
|
||||
|
||||
buffer = new byte[transferLength * blockSize];
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "READ (10) took {0} ms.", duration);
|
||||
@@ -157,7 +157,9 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="transferLength">How many blocks to read.</param>
|
||||
/// <param name="streaming">If set to <c>true</c> the stream playback operation should be used (MMC only).</param>
|
||||
/// <param name="relAddr">If set to <c>true</c> address is relative to current position.</param>
|
||||
public bool Read12(out byte[] buffer, out byte[] senseBuffer, byte rdprotect, bool dpo, bool fua, bool fuaNv, bool relAddr, uint lba, uint blockSize, byte groupNumber, uint transferLength, bool streaming, uint timeout, out double duration)
|
||||
public bool Read12(out byte[] buffer, out byte[] senseBuffer, byte rdprotect, bool dpo, bool fua, bool fuaNv,
|
||||
bool relAddr, uint lba, uint blockSize, byte groupNumber, uint transferLength,
|
||||
bool streaming, uint timeout, out double duration)
|
||||
{
|
||||
senseBuffer = new byte[32];
|
||||
byte[] cdb = new byte[12];
|
||||
@@ -165,14 +167,10 @@ namespace DiscImageChef.Devices
|
||||
|
||||
cdb[0] = (byte)ScsiCommands.Read12;
|
||||
cdb[1] = (byte)((rdprotect & 0x07) << 5);
|
||||
if(dpo)
|
||||
cdb[1] += 0x10;
|
||||
if(fua)
|
||||
cdb[1] += 0x08;
|
||||
if(fuaNv)
|
||||
cdb[1] += 0x02;
|
||||
if(relAddr)
|
||||
cdb[1] += 0x01;
|
||||
if(dpo) cdb[1] += 0x10;
|
||||
if(fua) cdb[1] += 0x08;
|
||||
if(fuaNv) cdb[1] += 0x02;
|
||||
if(relAddr) cdb[1] += 0x01;
|
||||
cdb[2] = (byte)((lba & 0xFF000000) >> 24);
|
||||
cdb[3] = (byte)((lba & 0xFF0000) >> 16);
|
||||
cdb[4] = (byte)((lba & 0xFF00) >> 8);
|
||||
@@ -182,12 +180,12 @@ namespace DiscImageChef.Devices
|
||||
cdb[8] = (byte)((transferLength & 0xFF00) >> 8);
|
||||
cdb[9] = (byte)(transferLength & 0xFF);
|
||||
cdb[10] = (byte)(groupNumber & 0x1F);
|
||||
if(streaming)
|
||||
cdb[10] += 0x80;
|
||||
if(streaming) cdb[10] += 0x80;
|
||||
|
||||
buffer = new byte[transferLength * blockSize];
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "READ (12) took {0} ms.", duration);
|
||||
@@ -212,7 +210,9 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="groupNumber">Group number where attributes associated with this command should be collected.</param>
|
||||
/// <param name="transferLength">How many blocks to read.</param>
|
||||
/// <param name="streaming">If set to <c>true</c> the stream playback operation should be used (MMC only).</param>
|
||||
public bool Read16(out byte[] buffer, out byte[] senseBuffer, byte rdprotect, bool dpo, bool fua, bool fuaNv, ulong lba, uint blockSize, byte groupNumber, uint transferLength, bool streaming, uint timeout, out double duration)
|
||||
public bool Read16(out byte[] buffer, out byte[] senseBuffer, byte rdprotect, bool dpo, bool fua, bool fuaNv,
|
||||
ulong lba, uint blockSize, byte groupNumber, uint transferLength, bool streaming,
|
||||
uint timeout, out double duration)
|
||||
{
|
||||
senseBuffer = new byte[32];
|
||||
byte[] cdb = new byte[16];
|
||||
@@ -221,12 +221,9 @@ namespace DiscImageChef.Devices
|
||||
|
||||
cdb[0] = (byte)ScsiCommands.Read16;
|
||||
cdb[1] = (byte)((rdprotect & 0x07) << 5);
|
||||
if(dpo)
|
||||
cdb[1] += 0x10;
|
||||
if(fua)
|
||||
cdb[1] += 0x08;
|
||||
if(fuaNv)
|
||||
cdb[1] += 0x02;
|
||||
if(dpo) cdb[1] += 0x10;
|
||||
if(fua) cdb[1] += 0x08;
|
||||
if(fuaNv) cdb[1] += 0x02;
|
||||
cdb[2] = lbaBytes[7];
|
||||
cdb[3] = lbaBytes[6];
|
||||
cdb[4] = lbaBytes[5];
|
||||
@@ -240,12 +237,12 @@ namespace DiscImageChef.Devices
|
||||
cdb[12] = (byte)((transferLength & 0xFF00) >> 8);
|
||||
cdb[13] = (byte)(transferLength & 0xFF);
|
||||
cdb[14] = (byte)(groupNumber & 0x1F);
|
||||
if(streaming)
|
||||
cdb[14] += 0x80;
|
||||
if(streaming) cdb[14] += 0x80;
|
||||
|
||||
buffer = new byte[transferLength * blockSize];
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "READ (16) took {0} ms.", duration);
|
||||
@@ -265,17 +262,16 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="correct">If set to <c>true</c> ask the drive to try to correct errors in the sector.</param>
|
||||
/// <param name="lba">LBA to read.</param>
|
||||
/// <param name="transferBytes">How many bytes to read. If the number is not exactly the drive's size, the command will fail and incidate a delta of the size in SENSE.</param>
|
||||
public bool ReadLong10(out byte[] buffer, out byte[] senseBuffer, bool correct, bool relAddr, uint lba, ushort transferBytes, uint timeout, out double duration)
|
||||
public bool ReadLong10(out byte[] buffer, out byte[] senseBuffer, bool correct, bool relAddr, uint lba,
|
||||
ushort transferBytes, uint timeout, out double duration)
|
||||
{
|
||||
senseBuffer = new byte[32];
|
||||
byte[] cdb = new byte[10];
|
||||
bool sense;
|
||||
|
||||
cdb[0] = (byte)ScsiCommands.ReadLong;
|
||||
if(correct)
|
||||
cdb[1] += 0x02;
|
||||
if(relAddr)
|
||||
cdb[1] += 0x01;
|
||||
if(correct) cdb[1] += 0x02;
|
||||
if(relAddr) cdb[1] += 0x01;
|
||||
cdb[2] = (byte)((lba & 0xFF000000) >> 24);
|
||||
cdb[3] = (byte)((lba & 0xFF0000) >> 16);
|
||||
cdb[4] = (byte)((lba & 0xFF00) >> 8);
|
||||
@@ -285,7 +281,8 @@ namespace DiscImageChef.Devices
|
||||
|
||||
buffer = new byte[transferBytes];
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "READ LONG (10) took {0} ms.", duration);
|
||||
@@ -304,7 +301,8 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="correct">If set to <c>true</c> ask the drive to try to correct errors in the sector.</param>
|
||||
/// <param name="lba">LBA to read.</param>
|
||||
/// <param name="transferBytes">How many bytes to read. If the number is not exactly the drive's size, the command will fail and incidate a delta of the size in SENSE.</param>
|
||||
public bool ReadLong16(out byte[] buffer, out byte[] senseBuffer, bool correct, ulong lba, uint transferBytes, uint timeout, out double duration)
|
||||
public bool ReadLong16(out byte[] buffer, out byte[] senseBuffer, bool correct, ulong lba, uint transferBytes,
|
||||
uint timeout, out double duration)
|
||||
{
|
||||
senseBuffer = new byte[32];
|
||||
byte[] cdb = new byte[16];
|
||||
@@ -323,12 +321,12 @@ namespace DiscImageChef.Devices
|
||||
cdb[9] = lbaBytes[0];
|
||||
cdb[12] = (byte)((transferBytes & 0xFF00) >> 8);
|
||||
cdb[13] = (byte)(transferBytes & 0xFF);
|
||||
if(correct)
|
||||
cdb[14] += 0x01;
|
||||
if(correct) cdb[14] += 0x01;
|
||||
|
||||
buffer = new byte[transferBytes];
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "READ LONG (16) took {0} ms.", duration);
|
||||
@@ -355,7 +353,8 @@ namespace DiscImageChef.Devices
|
||||
cdb[2] = (byte)((lba & 0xFF00) >> 8);
|
||||
cdb[3] = (byte)(lba & 0xFF);
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.None, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.None, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "SEEK (6) took {0} ms.", duration);
|
||||
@@ -383,7 +382,8 @@ namespace DiscImageChef.Devices
|
||||
cdb[4] = (byte)((lba & 0xFF00) >> 8);
|
||||
cdb[5] = (byte)(lba & 0xFF);
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.None, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.None, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "SEEK (10) took {0} ms.", duration);
|
||||
@@ -391,5 +391,4 @@ namespace DiscImageChef.Devices
|
||||
return sense;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -50,7 +50,9 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="cache">If set to <c>true</c> device can return cached data.</param>
|
||||
/// <param name="timeout">Timeout.</param>
|
||||
/// <param name="duration">Duration.</param>
|
||||
public bool ReadAttribute(out byte[] buffer, out byte[] senseBuffer, ScsiAttributeAction action, ushort element, byte elementType, byte volume, byte partition, ushort firstAttribute, bool cache, uint timeout, out double duration)
|
||||
public bool ReadAttribute(out byte[] buffer, out byte[] senseBuffer, ScsiAttributeAction action, ushort element,
|
||||
byte elementType, byte volume, byte partition, ushort firstAttribute, bool cache,
|
||||
uint timeout, out double duration)
|
||||
{
|
||||
buffer = new byte[256];
|
||||
byte[] cdb = new byte[16];
|
||||
@@ -70,17 +72,17 @@ namespace DiscImageChef.Devices
|
||||
cdb[11] = (byte)((buffer.Length & 0xFF0000) >> 16);
|
||||
cdb[12] = (byte)((buffer.Length & 0xFF00) >> 8);
|
||||
cdb[13] = (byte)(buffer.Length & 0xFF);
|
||||
if(cache)
|
||||
cdb[14] += 0x01;
|
||||
if(cache) cdb[14] += 0x01;
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
if(sense)
|
||||
return true;
|
||||
if(sense) return true;
|
||||
|
||||
#pragma warning disable IDE0004 // Cast is necessary or an invalid bitshift happens
|
||||
uint attrLen = (uint)(((int)buffer[0] << 24) + ((int)buffer[1] << 16) + ((int)buffer[2] << 8) + buffer[3] + 4);
|
||||
uint attrLen = (uint)(((int)buffer[0] << 24) + ((int)buffer[1] << 16) + ((int)buffer[2] << 8) + buffer[3] +
|
||||
4);
|
||||
#pragma warning restore IDE0004 // Cast is necessary or an invalid bitshift happens
|
||||
buffer = new byte[attrLen];
|
||||
cdb[10] = (byte)((buffer.Length & 0xFF000000) >> 24);
|
||||
@@ -89,7 +91,8 @@ namespace DiscImageChef.Devices
|
||||
cdb[13] = (byte)(buffer.Length & 0xFF);
|
||||
senseBuffer = new byte[32];
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "READ ATTRIBUTE took {0} ms.", duration);
|
||||
@@ -97,5 +100,4 @@ namespace DiscImageChef.Devices
|
||||
return sense;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -85,22 +85,23 @@ namespace DiscImageChef.Devices
|
||||
{
|
||||
buffer = new byte[36];
|
||||
senseBuffer = new byte[32];
|
||||
byte[] cdb = { (byte)ScsiCommands.Inquiry, 0, 0, 0, 36, 0 };
|
||||
byte[] cdb = {(byte)ScsiCommands.Inquiry, 0, 0, 0, 36, 0};
|
||||
bool sense;
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
if(sense)
|
||||
return true;
|
||||
if(sense) return true;
|
||||
|
||||
byte pagesLength = (byte)(buffer[4] + 5);
|
||||
|
||||
cdb = new byte[] { (byte)ScsiCommands.Inquiry, 0, 0, 0, pagesLength, 0 };
|
||||
cdb = new byte[] {(byte)ScsiCommands.Inquiry, 0, 0, 0, pagesLength, 0};
|
||||
buffer = new byte[pagesLength];
|
||||
senseBuffer = new byte[32];
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "INQUIRY took {0} ms.", duration);
|
||||
@@ -160,26 +161,26 @@ namespace DiscImageChef.Devices
|
||||
{
|
||||
buffer = new byte[36];
|
||||
senseBuffer = new byte[32];
|
||||
byte[] cdb = { (byte)ScsiCommands.Inquiry, 1, page, 0, 36, 0 };
|
||||
byte[] cdb = {(byte)ScsiCommands.Inquiry, 1, page, 0, 36, 0};
|
||||
bool sense;
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
if(sense)
|
||||
return true;
|
||||
if(sense) return true;
|
||||
|
||||
// This is because INQ was returned instead of EVPD
|
||||
if(buffer[1] != page)
|
||||
return true;
|
||||
if(buffer[1] != page) return true;
|
||||
|
||||
byte pagesLength = (byte)(buffer[3] + 4);
|
||||
|
||||
cdb = new byte[] { (byte)ScsiCommands.Inquiry, 1, page, 0, pagesLength, 0 };
|
||||
cdb = new byte[] {(byte)ScsiCommands.Inquiry, 1, page, 0, pagesLength, 0};
|
||||
buffer = new byte[pagesLength];
|
||||
senseBuffer = new byte[32];
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "INQUIRY took {0} ms.", duration);
|
||||
@@ -197,11 +198,12 @@ namespace DiscImageChef.Devices
|
||||
public bool ScsiTestUnitReady(out byte[] senseBuffer, uint timeout, out double duration)
|
||||
{
|
||||
senseBuffer = new byte[32];
|
||||
byte[] cdb = { (byte)ScsiCommands.TestUnitReady, 0, 0, 0, 0, 0 };
|
||||
byte[] cdb = {(byte)ScsiCommands.TestUnitReady, 0, 0, 0, 0, 0};
|
||||
bool sense;
|
||||
byte[] buffer = new byte[0];
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.None, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.None, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "TEST UNIT READY took {0} ms.", duration);
|
||||
@@ -219,7 +221,8 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
|
||||
public bool ModeSense(out byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration)
|
||||
{
|
||||
return ModeSense6(out buffer, out senseBuffer, false, ScsiModeSensePageControl.Current, 0, 0, timeout, out duration);
|
||||
return ModeSense6(out buffer, out senseBuffer, false, ScsiModeSensePageControl.Current, 0, 0, timeout,
|
||||
out duration);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -233,7 +236,8 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="DBD">If set to <c>true</c> device MUST not return any block descriptor.</param>
|
||||
/// <param name="pageControl">Page control.</param>
|
||||
/// <param name="pageCode">Page code.</param>
|
||||
public bool ModeSense6(out byte[] buffer, out byte[] senseBuffer, bool DBD, ScsiModeSensePageControl pageControl, byte pageCode, uint timeout, out double duration)
|
||||
public bool ModeSense6(out byte[] buffer, out byte[] senseBuffer, bool DBD,
|
||||
ScsiModeSensePageControl pageControl, byte pageCode, uint timeout, out double duration)
|
||||
{
|
||||
return ModeSense6(out buffer, out senseBuffer, DBD, pageControl, pageCode, 0, timeout, out duration);
|
||||
}
|
||||
@@ -250,7 +254,9 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="pageControl">Page control.</param>
|
||||
/// <param name="pageCode">Page code.</param>
|
||||
/// <param name="subPageCode">Sub-page code.</param>
|
||||
public bool ModeSense6(out byte[] buffer, out byte[] senseBuffer, bool DBD, ScsiModeSensePageControl pageControl, byte pageCode, byte subPageCode, uint timeout, out double duration)
|
||||
public bool ModeSense6(out byte[] buffer, out byte[] senseBuffer, bool DBD,
|
||||
ScsiModeSensePageControl pageControl, byte pageCode, byte subPageCode, uint timeout,
|
||||
out double duration)
|
||||
{
|
||||
senseBuffer = new byte[32];
|
||||
byte[] cdb = new byte[6];
|
||||
@@ -258,26 +264,26 @@ namespace DiscImageChef.Devices
|
||||
bool sense;
|
||||
|
||||
cdb[0] = (byte)ScsiCommands.ModeSense;
|
||||
if(DBD)
|
||||
cdb[1] = 0x08;
|
||||
if(DBD) cdb[1] = 0x08;
|
||||
cdb[2] |= (byte)pageControl;
|
||||
cdb[2] |= (byte)(pageCode & 0x3F);
|
||||
cdb[3] = subPageCode;
|
||||
cdb[4] = (byte)buffer.Length;
|
||||
cdb[5] = 0;
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
if(sense)
|
||||
return true;
|
||||
if(sense) return true;
|
||||
|
||||
byte modeLength = (byte)(buffer[0] + 1);
|
||||
buffer = new byte[modeLength];
|
||||
cdb[4] = (byte)buffer.Length;
|
||||
senseBuffer = new byte[32];
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "MODE SENSE(6) took {0} ms.", duration);
|
||||
@@ -296,9 +302,11 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="DBD">If set to <c>true</c> device MUST not return any block descriptor.</param>
|
||||
/// <param name="pageControl">Page control.</param>
|
||||
/// <param name="pageCode">Page code.</param>
|
||||
public bool ModeSense10(out byte[] buffer, out byte[] senseBuffer, bool DBD, ScsiModeSensePageControl pageControl, byte pageCode, uint timeout, out double duration)
|
||||
public bool ModeSense10(out byte[] buffer, out byte[] senseBuffer, bool DBD,
|
||||
ScsiModeSensePageControl pageControl, byte pageCode, uint timeout, out double duration)
|
||||
{
|
||||
return ModeSense10(out buffer, out senseBuffer, false, DBD, pageControl, pageCode, 0, timeout, out duration);
|
||||
return ModeSense10(out buffer, out senseBuffer, false, DBD, pageControl, pageCode, 0, timeout,
|
||||
out duration);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -313,9 +321,11 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="pageControl">Page control.</param>
|
||||
/// <param name="pageCode">Page code.</param>
|
||||
/// <param name="LLBAA">If set means 64-bit LBAs are accepted by the caller.</param>
|
||||
public bool ModeSense10(out byte[] buffer, out byte[] senseBuffer, bool LLBAA, bool DBD, ScsiModeSensePageControl pageControl, byte pageCode, uint timeout, out double duration)
|
||||
public bool ModeSense10(out byte[] buffer, out byte[] senseBuffer, bool LLBAA, bool DBD,
|
||||
ScsiModeSensePageControl pageControl, byte pageCode, uint timeout, out double duration)
|
||||
{
|
||||
return ModeSense10(out buffer, out senseBuffer, LLBAA, DBD, pageControl, pageCode, 0, timeout, out duration);
|
||||
return ModeSense10(out buffer, out senseBuffer, LLBAA, DBD, pageControl, pageCode, 0, timeout,
|
||||
out duration);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -331,7 +341,9 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="pageCode">Page code.</param>
|
||||
/// <param name="subPageCode">Sub-page code.</param>
|
||||
/// <param name="LLBAA">If set means 64-bit LBAs are accepted by the caller.</param>
|
||||
public bool ModeSense10(out byte[] buffer, out byte[] senseBuffer, bool LLBAA, bool DBD, ScsiModeSensePageControl pageControl, byte pageCode, byte subPageCode, uint timeout, out double duration)
|
||||
public bool ModeSense10(out byte[] buffer, out byte[] senseBuffer, bool LLBAA, bool DBD,
|
||||
ScsiModeSensePageControl pageControl, byte pageCode, byte subPageCode, uint timeout,
|
||||
out double duration)
|
||||
{
|
||||
senseBuffer = new byte[32];
|
||||
byte[] cdb = new byte[10];
|
||||
@@ -339,10 +351,8 @@ namespace DiscImageChef.Devices
|
||||
bool sense;
|
||||
|
||||
cdb[0] = (byte)ScsiCommands.ModeSense10;
|
||||
if(LLBAA)
|
||||
cdb[1] |= 0x10;
|
||||
if(DBD)
|
||||
cdb[1] |= 0x08;
|
||||
if(LLBAA) cdb[1] |= 0x10;
|
||||
if(DBD) cdb[1] |= 0x08;
|
||||
cdb[2] |= (byte)pageControl;
|
||||
cdb[2] |= (byte)(pageCode & 0x3F);
|
||||
cdb[3] = subPageCode;
|
||||
@@ -350,11 +360,11 @@ namespace DiscImageChef.Devices
|
||||
cdb[8] = (byte)(buffer.Length & 0xFF);
|
||||
cdb[9] = 0;
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
if(sense)
|
||||
return true;
|
||||
if(sense) return true;
|
||||
|
||||
#pragma warning disable IDE0004 // Cast is necessary or an invalid bitshift happens
|
||||
ushort modeLength = (ushort)(((int)buffer[0] << 8) + buffer[1] + 2);
|
||||
@@ -364,7 +374,8 @@ namespace DiscImageChef.Devices
|
||||
cdb[8] = (byte)(buffer.Length & 0xFF);
|
||||
senseBuffer = new byte[32];
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "MODE SENSE(10) took {0} ms.", duration);
|
||||
@@ -404,10 +415,12 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="timeout">Timeout in seconds.</param>
|
||||
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
|
||||
/// <param name="prevent"><c>true</c> to prevent medium removal, <c>false</c> to allow it.</param>
|
||||
public bool SpcPreventAllowMediumRemoval(out byte[] senseBuffer, bool prevent, uint timeout, out double duration)
|
||||
public bool SpcPreventAllowMediumRemoval(out byte[] senseBuffer, bool prevent, uint timeout,
|
||||
out double duration)
|
||||
{
|
||||
if(prevent)
|
||||
return SpcPreventAllowMediumRemoval(out senseBuffer, ScsiPreventAllowMode.Prevent, timeout, out duration);
|
||||
return SpcPreventAllowMediumRemoval(out senseBuffer, ScsiPreventAllowMode.Prevent, timeout,
|
||||
out duration);
|
||||
else
|
||||
return SpcPreventAllowMediumRemoval(out senseBuffer, ScsiPreventAllowMode.Allow, timeout, out duration);
|
||||
}
|
||||
@@ -420,7 +433,8 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="timeout">Timeout in seconds.</param>
|
||||
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
|
||||
/// <param name="preventMode">Prevention mode.</param>
|
||||
public bool SpcPreventAllowMediumRemoval(out byte[] senseBuffer, ScsiPreventAllowMode preventMode, uint timeout, out double duration)
|
||||
public bool SpcPreventAllowMediumRemoval(out byte[] senseBuffer, ScsiPreventAllowMode preventMode, uint timeout,
|
||||
out double duration)
|
||||
{
|
||||
senseBuffer = new byte[32];
|
||||
byte[] cdb = new byte[6];
|
||||
@@ -430,7 +444,8 @@ namespace DiscImageChef.Devices
|
||||
cdb[0] = (byte)ScsiCommands.PreventAllowMediumRemoval;
|
||||
cdb[4] = (byte)((byte)preventMode & 0x03);
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.None, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.None, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "PREVENT ALLOW MEDIUM REMOVAL took {0} ms.", duration);
|
||||
@@ -462,7 +477,8 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="PMI">If set, it is requesting partial media capacity</param>
|
||||
/// <param name="timeout">Timeout in seconds.</param>
|
||||
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
|
||||
public bool ReadCapacity(out byte[] buffer, out byte[] senseBuffer, bool RelAddr, uint address, bool PMI, uint timeout, out double duration)
|
||||
public bool ReadCapacity(out byte[] buffer, out byte[] senseBuffer, bool RelAddr, uint address, bool PMI,
|
||||
uint timeout, out double duration)
|
||||
{
|
||||
senseBuffer = new byte[32];
|
||||
byte[] cdb = new byte[10];
|
||||
@@ -474,8 +490,7 @@ namespace DiscImageChef.Devices
|
||||
if(PMI)
|
||||
{
|
||||
cdb[8] = 0x01;
|
||||
if(RelAddr)
|
||||
cdb[1] = 0x01;
|
||||
if(RelAddr) cdb[1] = 0x01;
|
||||
|
||||
cdb[2] = (byte)((address & 0xFF000000) >> 24);
|
||||
cdb[3] = (byte)((address & 0xFF0000) >> 16);
|
||||
@@ -483,7 +498,8 @@ namespace DiscImageChef.Devices
|
||||
cdb[5] = (byte)(address & 0xFF);
|
||||
}
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "READ CAPACITY took {0} ms.", duration);
|
||||
@@ -514,7 +530,8 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="PMI">If set, it is requesting partial media capacity</param>
|
||||
/// <param name="timeout">Timeout in seconds.</param>
|
||||
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
|
||||
public bool ReadCapacity16(out byte[] buffer, out byte[] senseBuffer, ulong address, bool PMI, uint timeout, out double duration)
|
||||
public bool ReadCapacity16(out byte[] buffer, out byte[] senseBuffer, ulong address, bool PMI, uint timeout,
|
||||
out double duration)
|
||||
{
|
||||
senseBuffer = new byte[32];
|
||||
byte[] cdb = new byte[16];
|
||||
@@ -543,7 +560,8 @@ namespace DiscImageChef.Devices
|
||||
cdb[12] = (byte)((buffer.Length & 0xFF00) >> 8);
|
||||
cdb[13] = (byte)(buffer.Length & 0xFF);
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "READ CAPACITY(16) took {0} ms.", duration);
|
||||
@@ -573,14 +591,15 @@ namespace DiscImageChef.Devices
|
||||
cdb[8] = (byte)((buffer.Length & 0xFF00) >> 8);
|
||||
cdb[9] = (byte)(buffer.Length & 0xFF);
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
if(sense)
|
||||
return true;
|
||||
if(sense) return true;
|
||||
|
||||
#pragma warning disable IDE0004 // Cast is necessary or an invalid bitshift happens
|
||||
uint strctLength = (uint)(((int)buffer[0] << 24) + ((int)buffer[1] << 16) + ((int)buffer[2] << 8) + buffer[3] + 4);
|
||||
uint strctLength = (uint)(((int)buffer[0] << 24) + ((int)buffer[1] << 16) + ((int)buffer[2] << 8) +
|
||||
buffer[3] + 4);
|
||||
#pragma warning restore IDE0004 // Cast is necessary or an invalid bitshift happens
|
||||
buffer = new byte[strctLength];
|
||||
cdb[6] = (byte)((buffer.Length & 0xFF000000) >> 24);
|
||||
@@ -589,7 +608,8 @@ namespace DiscImageChef.Devices
|
||||
cdb[9] = (byte)(buffer.Length & 0xFF);
|
||||
senseBuffer = new byte[32];
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "READ MEDIA SERIAL NUMBER took {0} ms.", duration);
|
||||
@@ -608,9 +628,11 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="cache">If set to <c>true</c> device can return cached data.</param>
|
||||
/// <param name="timeout">Timeout.</param>
|
||||
/// <param name="duration">Duration.</param>
|
||||
public bool ReadAttribute(out byte[] buffer, out byte[] senseBuffer, ScsiAttributeAction action, byte partition, ushort firstAttribute, bool cache, uint timeout, out double duration)
|
||||
public bool ReadAttribute(out byte[] buffer, out byte[] senseBuffer, ScsiAttributeAction action, byte partition,
|
||||
ushort firstAttribute, bool cache, uint timeout, out double duration)
|
||||
{
|
||||
return ReadAttribute(out buffer, out senseBuffer, action, 0, 0, 0, partition, firstAttribute, cache, timeout, out duration);
|
||||
return ReadAttribute(out buffer, out senseBuffer, action, 0, 0, 0, partition, firstAttribute, cache,
|
||||
timeout, out duration);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -623,9 +645,11 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="cache">If set to <c>true</c> device can return cached data.</param>
|
||||
/// <param name="timeout">Timeout.</param>
|
||||
/// <param name="duration">Duration.</param>
|
||||
public bool ReadAttribute(out byte[] buffer, out byte[] senseBuffer, ScsiAttributeAction action, ushort firstAttribute, bool cache, uint timeout, out double duration)
|
||||
public bool ReadAttribute(out byte[] buffer, out byte[] senseBuffer, ScsiAttributeAction action,
|
||||
ushort firstAttribute, bool cache, uint timeout, out double duration)
|
||||
{
|
||||
return ReadAttribute(out buffer, out senseBuffer, action, 0, 0, 0, 0, firstAttribute, cache, timeout, out duration);
|
||||
return ReadAttribute(out buffer, out senseBuffer, action, 0, 0, 0, 0, firstAttribute, cache, timeout,
|
||||
out duration);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -638,9 +662,11 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="firstAttribute">First attribute identifier.</param>
|
||||
/// <param name="timeout">Timeout.</param>
|
||||
/// <param name="duration">Duration.</param>
|
||||
public bool ReadAttribute(out byte[] buffer, out byte[] senseBuffer, ScsiAttributeAction action, byte partition, ushort firstAttribute, uint timeout, out double duration)
|
||||
public bool ReadAttribute(out byte[] buffer, out byte[] senseBuffer, ScsiAttributeAction action, byte partition,
|
||||
ushort firstAttribute, uint timeout, out double duration)
|
||||
{
|
||||
return ReadAttribute(out buffer, out senseBuffer, action, 0, 0, 0, partition, firstAttribute, false, timeout, out duration);
|
||||
return ReadAttribute(out buffer, out senseBuffer, action, 0, 0, 0, partition, firstAttribute, false,
|
||||
timeout, out duration);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -652,9 +678,11 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="firstAttribute">First attribute identifier.</param>
|
||||
/// <param name="timeout">Timeout.</param>
|
||||
/// <param name="duration">Duration.</param>
|
||||
public bool ReadAttribute(out byte[] buffer, out byte[] senseBuffer, ScsiAttributeAction action, ushort firstAttribute, uint timeout, out double duration)
|
||||
public bool ReadAttribute(out byte[] buffer, out byte[] senseBuffer, ScsiAttributeAction action,
|
||||
ushort firstAttribute, uint timeout, out double duration)
|
||||
{
|
||||
return ReadAttribute(out buffer, out senseBuffer, action, 0, 0, 0, 0, firstAttribute, false, timeout, out duration);
|
||||
return ReadAttribute(out buffer, out senseBuffer, action, 0, 0, 0, 0, firstAttribute, false, timeout,
|
||||
out duration);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -668,9 +696,11 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="firstAttribute">First attribute identifier.</param>
|
||||
/// <param name="timeout">Timeout.</param>
|
||||
/// <param name="duration">Duration.</param>
|
||||
public bool ReadAttribute(out byte[] buffer, out byte[] senseBuffer, ScsiAttributeAction action, byte volume, byte partition, ushort firstAttribute, uint timeout, out double duration)
|
||||
public bool ReadAttribute(out byte[] buffer, out byte[] senseBuffer, ScsiAttributeAction action, byte volume,
|
||||
byte partition, ushort firstAttribute, uint timeout, out double duration)
|
||||
{
|
||||
return ReadAttribute(out buffer, out senseBuffer, action, 0, 0, volume, partition, firstAttribute, false, timeout, out duration);
|
||||
return ReadAttribute(out buffer, out senseBuffer, action, 0, 0, volume, partition, firstAttribute, false,
|
||||
timeout, out duration);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -685,9 +715,11 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="cache">If set to <c>true</c> device can return cached data.</param>
|
||||
/// <param name="timeout">Timeout.</param>
|
||||
/// <param name="duration">Duration.</param>
|
||||
public bool ReadAttribute(out byte[] buffer, out byte[] senseBuffer, ScsiAttributeAction action, byte volume, byte partition, ushort firstAttribute, bool cache, uint timeout, out double duration)
|
||||
public bool ReadAttribute(out byte[] buffer, out byte[] senseBuffer, ScsiAttributeAction action, byte volume,
|
||||
byte partition, ushort firstAttribute, bool cache, uint timeout, out double duration)
|
||||
{
|
||||
return ReadAttribute(out buffer, out senseBuffer, action, 0, 0, volume, partition, firstAttribute, cache, timeout, out duration);
|
||||
return ReadAttribute(out buffer, out senseBuffer, action, 0, 0, volume, partition, firstAttribute, cache,
|
||||
timeout, out duration);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -698,17 +730,19 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="senseBuffer">Sense buffer.</param>
|
||||
/// <param name="timeout">Timeout in seconds.</param>
|
||||
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
|
||||
public bool ModeSelect(byte[] buffer, out byte[] senseBuffer, bool pageFormat, bool savePages, uint timeout, out double duration)
|
||||
public bool ModeSelect(byte[] buffer, out byte[] senseBuffer, bool pageFormat, bool savePages, uint timeout,
|
||||
out double duration)
|
||||
{
|
||||
senseBuffer = new byte[32];
|
||||
|
||||
// Prevent overflows
|
||||
if(buffer.Length > 255)
|
||||
{
|
||||
if(platformID != Interop.PlatformID.Win32NT && platformID != Interop.PlatformID.Win32S && platformID != Interop.PlatformID.Win32Windows && platformID != Interop.PlatformID.WinCE && platformID != Interop.PlatformID.WindowsPhone && platformID != Interop.PlatformID.Xbox)
|
||||
lastError = 75;
|
||||
else
|
||||
lastError = 111;
|
||||
if(platformID != Interop.PlatformID.Win32NT && platformID != Interop.PlatformID.Win32S &&
|
||||
platformID != Interop.PlatformID.Win32Windows && platformID != Interop.PlatformID.WinCE &&
|
||||
platformID != Interop.PlatformID.WindowsPhone &&
|
||||
platformID != Interop.PlatformID.Xbox) lastError = 75;
|
||||
else lastError = 111;
|
||||
error = true;
|
||||
duration = 0;
|
||||
return true;
|
||||
@@ -718,13 +752,12 @@ namespace DiscImageChef.Devices
|
||||
bool sense;
|
||||
|
||||
cdb[0] = (byte)ScsiCommands.ModeSelect;
|
||||
if(pageFormat)
|
||||
cdb[1] += 0x10;
|
||||
if(savePages)
|
||||
cdb[1] += 0x01;
|
||||
if(pageFormat) cdb[1] += 0x10;
|
||||
if(savePages) cdb[1] += 0x01;
|
||||
cdb[4] = (byte)buffer.Length;
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.Out, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.Out, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "MODE SELECT(6) took {0} ms.", duration);
|
||||
@@ -740,17 +773,19 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="senseBuffer">Sense buffer.</param>
|
||||
/// <param name="timeout">Timeout in seconds.</param>
|
||||
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
|
||||
public bool ModeSelect10(byte[] buffer, out byte[] senseBuffer, bool pageFormat, bool savePages, uint timeout, out double duration)
|
||||
public bool ModeSelect10(byte[] buffer, out byte[] senseBuffer, bool pageFormat, bool savePages, uint timeout,
|
||||
out double duration)
|
||||
{
|
||||
senseBuffer = new byte[32];
|
||||
|
||||
// Prevent overflows
|
||||
if(buffer.Length > 65535)
|
||||
{
|
||||
if(platformID != Interop.PlatformID.Win32NT && platformID != Interop.PlatformID.Win32S && platformID != Interop.PlatformID.Win32Windows && platformID != Interop.PlatformID.WinCE && platformID != Interop.PlatformID.WindowsPhone && platformID != Interop.PlatformID.Xbox)
|
||||
lastError = 75;
|
||||
else
|
||||
lastError = 111;
|
||||
if(platformID != Interop.PlatformID.Win32NT && platformID != Interop.PlatformID.Win32S &&
|
||||
platformID != Interop.PlatformID.Win32Windows && platformID != Interop.PlatformID.WinCE &&
|
||||
platformID != Interop.PlatformID.WindowsPhone &&
|
||||
platformID != Interop.PlatformID.Xbox) lastError = 75;
|
||||
else lastError = 111;
|
||||
error = true;
|
||||
duration = 0;
|
||||
return true;
|
||||
@@ -760,14 +795,13 @@ namespace DiscImageChef.Devices
|
||||
bool sense;
|
||||
|
||||
cdb[0] = (byte)ScsiCommands.ModeSelect10;
|
||||
if(pageFormat)
|
||||
cdb[1] += 0x10;
|
||||
if(savePages)
|
||||
cdb[1] += 0x01;
|
||||
if(pageFormat) cdb[1] += 0x10;
|
||||
if(savePages) cdb[1] += 0x01;
|
||||
cdb[7] = (byte)((buffer.Length & 0xFF00) << 8);
|
||||
cdb[8] = (byte)(buffer.Length & 0xFF);
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.Out, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.Out, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "MODE SELECT(10) took {0} ms.", duration);
|
||||
@@ -788,14 +822,14 @@ namespace DiscImageChef.Devices
|
||||
bool sense;
|
||||
|
||||
cdb[0] = (byte)ScsiCommands.RequestSense;
|
||||
if(descriptor)
|
||||
cdb[1] = 0x01;
|
||||
if(descriptor) cdb[1] = 0x01;
|
||||
cdb[2] = 0;
|
||||
cdb[3] = 0;
|
||||
cdb[4] = (byte)buffer.Length;
|
||||
cdb[5] = 0;
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "REQUEST SENSE took {0} ms.", duration);
|
||||
@@ -803,5 +837,4 @@ namespace DiscImageChef.Devices
|
||||
return sense;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -73,7 +73,8 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="hold">If set to <c>true</c> and <paramref name="load"/> is also set to <c>true</c>, moves the medium to the drive but does not prepare it for reading.</param>
|
||||
/// <param name="timeout">Timeout.</param>
|
||||
/// <param name="duration">Duration.</param>
|
||||
public bool LoadUnload(out byte[] senseBuffer, bool immediate, bool load, bool retense, bool endOfTape, bool hold, uint timeout, out double duration)
|
||||
public bool LoadUnload(out byte[] senseBuffer, bool immediate, bool load, bool retense, bool endOfTape,
|
||||
bool hold, uint timeout, out double duration)
|
||||
{
|
||||
senseBuffer = new byte[32];
|
||||
byte[] cdb = new byte[6];
|
||||
@@ -81,18 +82,14 @@ namespace DiscImageChef.Devices
|
||||
bool sense;
|
||||
|
||||
cdb[0] = (byte)ScsiCommands.LoadUnload;
|
||||
if(immediate)
|
||||
cdb[1] = 0x01;
|
||||
if(load)
|
||||
cdb[4] += 0x01;
|
||||
if(retense)
|
||||
cdb[4] += 0x02;
|
||||
if(endOfTape)
|
||||
cdb[4] += 0x04;
|
||||
if(hold)
|
||||
cdb[4] += 0x08;
|
||||
if(immediate) cdb[1] = 0x01;
|
||||
if(load) cdb[4] += 0x01;
|
||||
if(retense) cdb[4] += 0x02;
|
||||
if(endOfTape) cdb[4] += 0x04;
|
||||
if(hold) cdb[4] += 0x08;
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.None, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.None, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "LOAD UNLOAD (6) took {0} ms.", duration);
|
||||
@@ -147,7 +144,8 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="lba">Logical block address.</param>
|
||||
/// <param name="timeout">Timeout.</param>
|
||||
/// <param name="duration">Duration.</param>
|
||||
public bool Locate(out byte[] senseBuffer, bool immediate, byte partition, uint lba, uint timeout, out double duration)
|
||||
public bool Locate(out byte[] senseBuffer, bool immediate, byte partition, uint lba, uint timeout,
|
||||
out double duration)
|
||||
{
|
||||
return Locate(out senseBuffer, immediate, false, true, partition, lba, timeout, out duration);
|
||||
}
|
||||
@@ -163,7 +161,8 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="objectId">Object identifier.</param>
|
||||
/// <param name="timeout">Timeout.</param>
|
||||
/// <param name="duration">Duration.</param>
|
||||
public bool Locate(out byte[] senseBuffer, bool immediate, bool blockType, bool changePartition, byte partition, uint objectId, uint timeout, out double duration)
|
||||
public bool Locate(out byte[] senseBuffer, bool immediate, bool blockType, bool changePartition, byte partition,
|
||||
uint objectId, uint timeout, out double duration)
|
||||
{
|
||||
senseBuffer = new byte[32];
|
||||
byte[] cdb = new byte[10];
|
||||
@@ -171,19 +170,17 @@ namespace DiscImageChef.Devices
|
||||
bool sense;
|
||||
|
||||
cdb[0] = (byte)ScsiCommands.Locate;
|
||||
if(immediate)
|
||||
cdb[1] += 0x01;
|
||||
if(changePartition)
|
||||
cdb[1] += 0x02;
|
||||
if(blockType)
|
||||
cdb[1] += 0x04;
|
||||
if(immediate) cdb[1] += 0x01;
|
||||
if(changePartition) cdb[1] += 0x02;
|
||||
if(blockType) cdb[1] += 0x04;
|
||||
cdb[3] = (byte)((objectId & 0xFF000000) >> 24);
|
||||
cdb[4] = (byte)((objectId & 0xFF0000) >> 16);
|
||||
cdb[5] = (byte)((objectId & 0xFF00) >> 8);
|
||||
cdb[6] = (byte)(objectId & 0xFF);
|
||||
cdb[8] = partition;
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.None, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.None, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "LOCATE (10) took {0} ms.", duration);
|
||||
@@ -200,7 +197,8 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="duration">Duration.</param>
|
||||
public bool Locate16(out byte[] senseBuffer, ulong lba, uint timeout, out double duration)
|
||||
{
|
||||
return Locate16(out senseBuffer, false, false, SscLogicalIdTypes.ObjectId, false, 0, lba, timeout, out duration);
|
||||
return Locate16(out senseBuffer, false, false, SscLogicalIdTypes.ObjectId, false, 0, lba, timeout,
|
||||
out duration);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -213,7 +211,8 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="duration">Duration.</param>
|
||||
public bool Locate16(out byte[] senseBuffer, byte partition, ulong lba, uint timeout, out double duration)
|
||||
{
|
||||
return Locate16(out senseBuffer, false, true, SscLogicalIdTypes.ObjectId, false, partition, lba, timeout, out duration);
|
||||
return Locate16(out senseBuffer, false, true, SscLogicalIdTypes.ObjectId, false, partition, lba, timeout,
|
||||
out duration);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -226,7 +225,8 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="duration">Duration.</param>
|
||||
public bool Locate16(out byte[] senseBuffer, bool immediate, ulong lba, uint timeout, out double duration)
|
||||
{
|
||||
return Locate16(out senseBuffer, immediate, false, SscLogicalIdTypes.ObjectId, false, 0, lba, timeout, out duration);
|
||||
return Locate16(out senseBuffer, immediate, false, SscLogicalIdTypes.ObjectId, false, 0, lba, timeout,
|
||||
out duration);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -238,9 +238,11 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="lba">Logical block address.</param>
|
||||
/// <param name="timeout">Timeout.</param>
|
||||
/// <param name="duration">Duration.</param>
|
||||
public bool Locate16(out byte[] senseBuffer, bool immediate, byte partition, ulong lba, uint timeout, out double duration)
|
||||
public bool Locate16(out byte[] senseBuffer, bool immediate, byte partition, ulong lba, uint timeout,
|
||||
out double duration)
|
||||
{
|
||||
return Locate16(out senseBuffer, immediate, true, SscLogicalIdTypes.ObjectId, false, partition, lba, timeout, out duration);
|
||||
return Locate16(out senseBuffer, immediate, true, SscLogicalIdTypes.ObjectId, false, partition, lba,
|
||||
timeout, out duration);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -255,7 +257,8 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="identifier">Destination identifier.</param>
|
||||
/// <param name="timeout">Timeout.</param>
|
||||
/// <param name="duration">Duration.</param>
|
||||
public bool Locate16(out byte[] senseBuffer, bool immediate, bool changePartition, SscLogicalIdTypes destType, bool bam, byte partition, ulong identifier, uint timeout, out double duration)
|
||||
public bool Locate16(out byte[] senseBuffer, bool immediate, bool changePartition, SscLogicalIdTypes destType,
|
||||
bool bam, byte partition, ulong identifier, uint timeout, out double duration)
|
||||
{
|
||||
senseBuffer = new byte[32];
|
||||
byte[] cdb = new byte[16];
|
||||
@@ -265,12 +268,9 @@ namespace DiscImageChef.Devices
|
||||
|
||||
cdb[0] = (byte)ScsiCommands.Locate16;
|
||||
cdb[1] = (byte)((byte)destType << 3);
|
||||
if(immediate)
|
||||
cdb[1] += 0x01;
|
||||
if(changePartition)
|
||||
cdb[1] += 0x02;
|
||||
if(bam)
|
||||
cdb[2] = 0x01;
|
||||
if(immediate) cdb[1] += 0x01;
|
||||
if(changePartition) cdb[1] += 0x02;
|
||||
if(bam) cdb[2] = 0x01;
|
||||
cdb[3] = partition;
|
||||
|
||||
cdb[4] = idBytes[7];
|
||||
@@ -282,7 +282,8 @@ namespace DiscImageChef.Devices
|
||||
cdb[10] = idBytes[1];
|
||||
cdb[11] = idBytes[0];
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.None, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.None, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "LOCATE (16) took {0} ms.", duration);
|
||||
@@ -314,7 +315,8 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="blockSize">Block size in bytes.</param>
|
||||
/// <param name="timeout">Timeout.</param>
|
||||
/// <param name="duration">Duration.</param>
|
||||
public bool Read6(out byte[] buffer, out byte[] senseBuffer, bool sili, uint transferLen, uint blockSize, uint timeout, out double duration)
|
||||
public bool Read6(out byte[] buffer, out byte[] senseBuffer, bool sili, uint transferLen, uint blockSize,
|
||||
uint timeout, out double duration)
|
||||
{
|
||||
return Read6(out buffer, out senseBuffer, sili, false, transferLen, blockSize, timeout, out duration);
|
||||
}
|
||||
@@ -330,26 +332,24 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="blockSize">Block size in bytes.</param>
|
||||
/// <param name="timeout">Timeout.</param>
|
||||
/// <param name="duration">Duration.</param>
|
||||
public bool Read6(out byte[] buffer, out byte[] senseBuffer, bool sili, bool fixedLen, uint transferLen, uint blockSize, uint timeout, out double duration)
|
||||
public bool Read6(out byte[] buffer, out byte[] senseBuffer, bool sili, bool fixedLen, uint transferLen,
|
||||
uint blockSize, uint timeout, out double duration)
|
||||
{
|
||||
if(fixedLen)
|
||||
buffer = new byte[blockSize * transferLen];
|
||||
else
|
||||
buffer = new byte[transferLen];
|
||||
if(fixedLen) buffer = new byte[blockSize * transferLen];
|
||||
else buffer = new byte[transferLen];
|
||||
byte[] cdb = new byte[6];
|
||||
senseBuffer = new byte[32];
|
||||
bool sense;
|
||||
|
||||
cdb[0] = (byte)ScsiCommands.Read6;
|
||||
if(fixedLen)
|
||||
cdb[1] += 0x01;
|
||||
if(sili)
|
||||
cdb[1] += 0x02;
|
||||
if(fixedLen) cdb[1] += 0x01;
|
||||
if(sili) cdb[1] += 0x02;
|
||||
cdb[2] = (byte)((transferLen & 0xFF0000) >> 16);
|
||||
cdb[3] = (byte)((transferLen & 0xFF00) >> 8);
|
||||
cdb[4] = (byte)(transferLen & 0xFF);
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "READ (6) took {0} ms.", duration);
|
||||
@@ -368,9 +368,11 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="blockSize">Object size in bytes.</param>
|
||||
/// <param name="timeout">Timeout.</param>
|
||||
/// <param name="duration">Duration.</param>
|
||||
public bool Read16(out byte[] buffer, out byte[] senseBuffer, bool sili, ulong objectId, uint blocks, uint blockSize, uint timeout, out double duration)
|
||||
public bool Read16(out byte[] buffer, out byte[] senseBuffer, bool sili, ulong objectId, uint blocks,
|
||||
uint blockSize, uint timeout, out double duration)
|
||||
{
|
||||
return Read16(out buffer, out senseBuffer, sili, false, 0, objectId, blocks, blockSize, timeout, out duration);
|
||||
return Read16(out buffer, out senseBuffer, sili, false, 0, objectId, blocks, blockSize, timeout,
|
||||
out duration);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -385,9 +387,11 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="blockSize">Object size in bytes.</param>
|
||||
/// <param name="timeout">Timeout.</param>
|
||||
/// <param name="duration">Duration.</param>
|
||||
public bool Read16(out byte[] buffer, out byte[] senseBuffer, bool sili, byte partition, ulong objectId, uint blocks, uint blockSize, uint timeout, out double duration)
|
||||
public bool Read16(out byte[] buffer, out byte[] senseBuffer, bool sili, byte partition, ulong objectId,
|
||||
uint blocks, uint blockSize, uint timeout, out double duration)
|
||||
{
|
||||
return Read16(out buffer, out senseBuffer, sili, false, partition, objectId, blocks, blockSize, timeout, out duration);
|
||||
return Read16(out buffer, out senseBuffer, sili, false, partition, objectId, blocks, blockSize, timeout,
|
||||
out duration);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -400,9 +404,11 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="blockSize">Object size in bytes.</param>
|
||||
/// <param name="timeout">Timeout.</param>
|
||||
/// <param name="duration">Duration.</param>
|
||||
public bool Read16(out byte[] buffer, out byte[] senseBuffer, ulong objectId, uint blocks, uint blockSize, uint timeout, out double duration)
|
||||
public bool Read16(out byte[] buffer, out byte[] senseBuffer, ulong objectId, uint blocks, uint blockSize,
|
||||
uint timeout, out double duration)
|
||||
{
|
||||
return Read16(out buffer, out senseBuffer, false, true, 0, objectId, blocks, blockSize, timeout, out duration);
|
||||
return Read16(out buffer, out senseBuffer, false, true, 0, objectId, blocks, blockSize, timeout,
|
||||
out duration);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -416,9 +422,11 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="blockSize">Object size in bytes.</param>
|
||||
/// <param name="timeout">Timeout.</param>
|
||||
/// <param name="duration">Duration.</param>
|
||||
public bool Read16(out byte[] buffer, out byte[] senseBuffer, byte partition, ulong objectId, uint blocks, uint blockSize, uint timeout, out double duration)
|
||||
public bool Read16(out byte[] buffer, out byte[] senseBuffer, byte partition, ulong objectId, uint blocks,
|
||||
uint blockSize, uint timeout, out double duration)
|
||||
{
|
||||
return Read16(out buffer, out senseBuffer, false, true, partition, objectId, blocks, blockSize, timeout, out duration);
|
||||
return Read16(out buffer, out senseBuffer, false, true, partition, objectId, blocks, blockSize, timeout,
|
||||
out duration);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -434,22 +442,19 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="objectSize">Object size in bytes.</param>
|
||||
/// <param name="timeout">Timeout.</param>
|
||||
/// <param name="duration">Duration.</param>
|
||||
public bool Read16(out byte[] buffer, out byte[] senseBuffer, bool sili, bool fixedLen, byte partition, ulong objectId, uint transferLen, uint objectSize, uint timeout, out double duration)
|
||||
public bool Read16(out byte[] buffer, out byte[] senseBuffer, bool sili, bool fixedLen, byte partition,
|
||||
ulong objectId, uint transferLen, uint objectSize, uint timeout, out double duration)
|
||||
{
|
||||
if(fixedLen)
|
||||
buffer = new byte[objectSize * transferLen];
|
||||
else
|
||||
buffer = new byte[transferLen];
|
||||
if(fixedLen) buffer = new byte[objectSize * transferLen];
|
||||
else buffer = new byte[transferLen];
|
||||
byte[] cdb = new byte[6];
|
||||
senseBuffer = new byte[32];
|
||||
bool sense;
|
||||
byte[] idBytes = BitConverter.GetBytes(objectId);
|
||||
|
||||
cdb[0] = (byte)ScsiCommands.Read16;
|
||||
if(fixedLen)
|
||||
cdb[1] += 0x01;
|
||||
if(sili)
|
||||
cdb[1] += 0x02;
|
||||
if(fixedLen) cdb[1] += 0x01;
|
||||
if(sili) cdb[1] += 0x02;
|
||||
cdb[3] = partition;
|
||||
cdb[4] = idBytes[7];
|
||||
cdb[5] = idBytes[6];
|
||||
@@ -463,7 +468,8 @@ namespace DiscImageChef.Devices
|
||||
cdb[13] = (byte)((transferLen & 0xFF00) >> 8);
|
||||
cdb[14] = (byte)(transferLen & 0xFF);
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "READ (16) took {0} ms.", duration);
|
||||
@@ -487,7 +493,8 @@ namespace DiscImageChef.Devices
|
||||
|
||||
cdb[0] = (byte)ScsiCommands.ReadBlockLimits;
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "READ BLOCK LIMITS took {0} ms.", duration);
|
||||
@@ -529,15 +536,13 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="totalPosition">Requests current logical position.</param>
|
||||
/// <param name="timeout">Timeout.</param>
|
||||
/// <param name="duration">Duration.</param>
|
||||
public bool ReadPosition(out byte[] buffer, out byte[] senseBuffer, bool vendorType, bool longForm, bool totalPosition, uint timeout, out double duration)
|
||||
public bool ReadPosition(out byte[] buffer, out byte[] senseBuffer, bool vendorType, bool longForm,
|
||||
bool totalPosition, uint timeout, out double duration)
|
||||
{
|
||||
byte responseForm = 0;
|
||||
if(vendorType)
|
||||
responseForm += 0x01;
|
||||
if(longForm)
|
||||
responseForm += 0x02;
|
||||
if(totalPosition)
|
||||
responseForm += 0x04;
|
||||
if(vendorType) responseForm += 0x01;
|
||||
if(longForm) responseForm += 0x02;
|
||||
if(totalPosition) responseForm += 0x04;
|
||||
|
||||
return ReadPosition(out buffer, out senseBuffer, (SscPositionForms)responseForm, timeout, out duration);
|
||||
}
|
||||
@@ -550,7 +555,8 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="responseForm">Response form.</param>
|
||||
/// <param name="timeout">Timeout.</param>
|
||||
/// <param name="duration">Duration.</param>
|
||||
public bool ReadPosition(out byte[] buffer, out byte[] senseBuffer, SscPositionForms responseForm, uint timeout, out double duration)
|
||||
public bool ReadPosition(out byte[] buffer, out byte[] senseBuffer, SscPositionForms responseForm, uint timeout,
|
||||
out double duration)
|
||||
{
|
||||
switch(responseForm)
|
||||
{
|
||||
@@ -571,6 +577,7 @@ namespace DiscImageChef.Devices
|
||||
buffer = new byte[32]; // Invalid
|
||||
break;
|
||||
}
|
||||
|
||||
byte[] cdb = new byte[10];
|
||||
senseBuffer = new byte[32];
|
||||
bool sense;
|
||||
@@ -583,7 +590,8 @@ namespace DiscImageChef.Devices
|
||||
cdb[8] = (byte)(buffer.Length & 0xFF);
|
||||
}
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "READ POSITION took {0} ms.", duration);
|
||||
@@ -600,9 +608,11 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="blockSize">Block size in bytes.</param>
|
||||
/// <param name="timeout">Timeout.</param>
|
||||
/// <param name="duration">Duration.</param>
|
||||
public bool ReadReverse6(out byte[] buffer, out byte[] senseBuffer, uint blocks, uint blockSize, uint timeout, out double duration)
|
||||
public bool ReadReverse6(out byte[] buffer, out byte[] senseBuffer, uint blocks, uint blockSize, uint timeout,
|
||||
out double duration)
|
||||
{
|
||||
return ReadReverse6(out buffer, out senseBuffer, false, false, true, blocks, blockSize, timeout, out duration);
|
||||
return ReadReverse6(out buffer, out senseBuffer, false, false, true, blocks, blockSize, timeout,
|
||||
out duration);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -615,9 +625,11 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="blockSize">Block size in bytes.</param>
|
||||
/// <param name="timeout">Timeout.</param>
|
||||
/// <param name="duration">Duration.</param>
|
||||
public bool ReadReverse6(out byte[] buffer, out byte[] senseBuffer, bool sili, uint transferLen, uint blockSize, uint timeout, out double duration)
|
||||
public bool ReadReverse6(out byte[] buffer, out byte[] senseBuffer, bool sili, uint transferLen, uint blockSize,
|
||||
uint timeout, out double duration)
|
||||
{
|
||||
return ReadReverse6(out buffer, out senseBuffer, false, sili, false, transferLen, blockSize, timeout, out duration);
|
||||
return ReadReverse6(out buffer, out senseBuffer, false, sili, false, transferLen, blockSize, timeout,
|
||||
out duration);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -632,28 +644,25 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="blockSize">Block size in bytes.</param>
|
||||
/// <param name="timeout">Timeout.</param>
|
||||
/// <param name="duration">Duration.</param>
|
||||
public bool ReadReverse6(out byte[] buffer, out byte[] senseBuffer, bool byteOrder, bool sili, bool fixedLen, uint transferLen, uint blockSize, uint timeout, out double duration)
|
||||
public bool ReadReverse6(out byte[] buffer, out byte[] senseBuffer, bool byteOrder, bool sili, bool fixedLen,
|
||||
uint transferLen, uint blockSize, uint timeout, out double duration)
|
||||
{
|
||||
if(fixedLen)
|
||||
buffer = new byte[blockSize * transferLen];
|
||||
else
|
||||
buffer = new byte[transferLen];
|
||||
if(fixedLen) buffer = new byte[blockSize * transferLen];
|
||||
else buffer = new byte[transferLen];
|
||||
byte[] cdb = new byte[6];
|
||||
senseBuffer = new byte[32];
|
||||
bool sense;
|
||||
|
||||
cdb[0] = (byte)ScsiCommands.ReadReverse;
|
||||
if(fixedLen)
|
||||
cdb[1] += 0x01;
|
||||
if(sili)
|
||||
cdb[1] += 0x02;
|
||||
if(byteOrder)
|
||||
cdb[1] += 0x04;
|
||||
if(fixedLen) cdb[1] += 0x01;
|
||||
if(sili) cdb[1] += 0x02;
|
||||
if(byteOrder) cdb[1] += 0x04;
|
||||
cdb[2] = (byte)((transferLen & 0xFF0000) >> 16);
|
||||
cdb[3] = (byte)((transferLen & 0xFF00) >> 8);
|
||||
cdb[4] = (byte)(transferLen & 0xFF);
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "READ REVERSE (6) took {0} ms.", duration);
|
||||
@@ -672,9 +681,11 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="blockSize">Object size in bytes.</param>
|
||||
/// <param name="timeout">Timeout.</param>
|
||||
/// <param name="duration">Duration.</param>
|
||||
public bool ReadReverse16(out byte[] buffer, out byte[] senseBuffer, bool sili, ulong objectId, uint blocks, uint blockSize, uint timeout, out double duration)
|
||||
public bool ReadReverse16(out byte[] buffer, out byte[] senseBuffer, bool sili, ulong objectId, uint blocks,
|
||||
uint blockSize, uint timeout, out double duration)
|
||||
{
|
||||
return ReadReverse16(out buffer, out senseBuffer, false, sili, false, 0, objectId, blocks, blockSize, timeout, out duration);
|
||||
return ReadReverse16(out buffer, out senseBuffer, false, sili, false, 0, objectId, blocks, blockSize,
|
||||
timeout, out duration);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -689,9 +700,11 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="blockSize">Object size in bytes.</param>
|
||||
/// <param name="timeout">Timeout.</param>
|
||||
/// <param name="duration">Duration.</param>
|
||||
public bool ReadReverse16(out byte[] buffer, out byte[] senseBuffer, bool sili, byte partition, ulong objectId, uint blocks, uint blockSize, uint timeout, out double duration)
|
||||
public bool ReadReverse16(out byte[] buffer, out byte[] senseBuffer, bool sili, byte partition, ulong objectId,
|
||||
uint blocks, uint blockSize, uint timeout, out double duration)
|
||||
{
|
||||
return ReadReverse16(out buffer, out senseBuffer, false, sili, false, partition, objectId, blocks, blockSize, timeout, out duration);
|
||||
return ReadReverse16(out buffer, out senseBuffer, false, sili, false, partition, objectId, blocks,
|
||||
blockSize, timeout, out duration);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -704,9 +717,11 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="blockSize">Object size in bytes.</param>
|
||||
/// <param name="timeout">Timeout.</param>
|
||||
/// <param name="duration">Duration.</param>
|
||||
public bool ReadReverse16(out byte[] buffer, out byte[] senseBuffer, ulong objectId, uint blocks, uint blockSize, uint timeout, out double duration)
|
||||
public bool ReadReverse16(out byte[] buffer, out byte[] senseBuffer, ulong objectId, uint blocks,
|
||||
uint blockSize, uint timeout, out double duration)
|
||||
{
|
||||
return ReadReverse16(out buffer, out senseBuffer, false, false, true, 0, objectId, blocks, blockSize, timeout, out duration);
|
||||
return ReadReverse16(out buffer, out senseBuffer, false, false, true, 0, objectId, blocks, blockSize,
|
||||
timeout, out duration);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -720,9 +735,11 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="blockSize">Object size in bytes.</param>
|
||||
/// <param name="timeout">Timeout.</param>
|
||||
/// <param name="duration">Duration.</param>
|
||||
public bool ReadReverse16(out byte[] buffer, out byte[] senseBuffer, byte partition, ulong objectId, uint blocks, uint blockSize, uint timeout, out double duration)
|
||||
public bool ReadReverse16(out byte[] buffer, out byte[] senseBuffer, byte partition, ulong objectId,
|
||||
uint blocks, uint blockSize, uint timeout, out double duration)
|
||||
{
|
||||
return ReadReverse16(out buffer, out senseBuffer, false, false, true, partition, objectId, blocks, blockSize, timeout, out duration);
|
||||
return ReadReverse16(out buffer, out senseBuffer, false, false, true, partition, objectId, blocks,
|
||||
blockSize, timeout, out duration);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -739,24 +756,21 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="objectSize">Object size in bytes.</param>
|
||||
/// <param name="timeout">Timeout.</param>
|
||||
/// <param name="duration">Duration.</param>
|
||||
public bool ReadReverse16(out byte[] buffer, out byte[] senseBuffer, bool byteOrder, bool sili, bool fixedLen, byte partition, ulong objectId, uint transferLen, uint objectSize, uint timeout, out double duration)
|
||||
public bool ReadReverse16(out byte[] buffer, out byte[] senseBuffer, bool byteOrder, bool sili, bool fixedLen,
|
||||
byte partition, ulong objectId, uint transferLen, uint objectSize, uint timeout,
|
||||
out double duration)
|
||||
{
|
||||
if(fixedLen)
|
||||
buffer = new byte[objectSize * transferLen];
|
||||
else
|
||||
buffer = new byte[transferLen];
|
||||
if(fixedLen) buffer = new byte[objectSize * transferLen];
|
||||
else buffer = new byte[transferLen];
|
||||
byte[] cdb = new byte[6];
|
||||
senseBuffer = new byte[32];
|
||||
bool sense;
|
||||
byte[] idBytes = BitConverter.GetBytes(objectId);
|
||||
|
||||
cdb[0] = (byte)ScsiCommands.Read16;
|
||||
if(fixedLen)
|
||||
cdb[1] += 0x01;
|
||||
if(sili)
|
||||
cdb[1] += 0x02;
|
||||
if(byteOrder)
|
||||
cdb[1] += 0x04;
|
||||
if(fixedLen) cdb[1] += 0x01;
|
||||
if(sili) cdb[1] += 0x02;
|
||||
if(byteOrder) cdb[1] += 0x04;
|
||||
cdb[3] = partition;
|
||||
cdb[4] = idBytes[7];
|
||||
cdb[5] = idBytes[6];
|
||||
@@ -770,7 +784,8 @@ namespace DiscImageChef.Devices
|
||||
cdb[13] = (byte)((transferLen & 0xFF00) >> 8);
|
||||
cdb[14] = (byte)(transferLen & 0xFF);
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "READ REVERSE (16) took {0} ms.", duration);
|
||||
@@ -787,9 +802,11 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="blockSize">Block size in bytes.</param>
|
||||
/// <param name="timeout">Timeout.</param>
|
||||
/// <param name="duration">Duration.</param>
|
||||
public bool RecoverBufferedData(out byte[] buffer, out byte[] senseBuffer, uint blocks, uint blockSize, uint timeout, out double duration)
|
||||
public bool RecoverBufferedData(out byte[] buffer, out byte[] senseBuffer, uint blocks, uint blockSize,
|
||||
uint timeout, out double duration)
|
||||
{
|
||||
return RecoverBufferedData(out buffer, out senseBuffer, false, true, blocks, blockSize, timeout, out duration);
|
||||
return RecoverBufferedData(out buffer, out senseBuffer, false, true, blocks, blockSize, timeout,
|
||||
out duration);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -802,9 +819,11 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="blockSize">Block size in bytes.</param>
|
||||
/// <param name="timeout">Timeout.</param>
|
||||
/// <param name="duration">Duration.</param>
|
||||
public bool RecoverBufferedData(out byte[] buffer, out byte[] senseBuffer, bool sili, uint transferLen, uint blockSize, uint timeout, out double duration)
|
||||
public bool RecoverBufferedData(out byte[] buffer, out byte[] senseBuffer, bool sili, uint transferLen,
|
||||
uint blockSize, uint timeout, out double duration)
|
||||
{
|
||||
return RecoverBufferedData(out buffer, out senseBuffer, sili, false, transferLen, blockSize, timeout, out duration);
|
||||
return RecoverBufferedData(out buffer, out senseBuffer, sili, false, transferLen, blockSize, timeout,
|
||||
out duration);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -818,26 +837,24 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="blockSize">Block size in bytes.</param>
|
||||
/// <param name="timeout">Timeout.</param>
|
||||
/// <param name="duration">Duration.</param>
|
||||
public bool RecoverBufferedData(out byte[] buffer, out byte[] senseBuffer, bool sili, bool fixedLen, uint transferLen, uint blockSize, uint timeout, out double duration)
|
||||
public bool RecoverBufferedData(out byte[] buffer, out byte[] senseBuffer, bool sili, bool fixedLen,
|
||||
uint transferLen, uint blockSize, uint timeout, out double duration)
|
||||
{
|
||||
if(fixedLen)
|
||||
buffer = new byte[blockSize * transferLen];
|
||||
else
|
||||
buffer = new byte[transferLen];
|
||||
if(fixedLen) buffer = new byte[blockSize * transferLen];
|
||||
else buffer = new byte[transferLen];
|
||||
byte[] cdb = new byte[6];
|
||||
senseBuffer = new byte[32];
|
||||
bool sense;
|
||||
|
||||
cdb[0] = (byte)ScsiCommands.RecoverBufferedData;
|
||||
if(fixedLen)
|
||||
cdb[1] += 0x01;
|
||||
if(sili)
|
||||
cdb[1] += 0x02;
|
||||
if(fixedLen) cdb[1] += 0x01;
|
||||
if(sili) cdb[1] += 0x02;
|
||||
cdb[2] = (byte)((transferLen & 0xFF0000) >> 16);
|
||||
cdb[3] = (byte)((transferLen & 0xFF00) >> 8);
|
||||
cdb[4] = (byte)(transferLen & 0xFF);
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "RECOVER BUFFERED DATA took {0} ms.", duration);
|
||||
@@ -865,7 +882,8 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="currentMedia">If set to <c>true</c> descriptors should apply to currently inserted media.</param>
|
||||
/// <param name="timeout">Timeout.</param>
|
||||
/// <param name="duration">Duration.</param>
|
||||
public bool ReportDensitySupport(out byte[] buffer, out byte[] senseBuffer, bool currentMedia, uint timeout, out double duration)
|
||||
public bool ReportDensitySupport(out byte[] buffer, out byte[] senseBuffer, bool currentMedia, uint timeout,
|
||||
out double duration)
|
||||
{
|
||||
return ReportDensitySupport(out buffer, out senseBuffer, false, currentMedia, timeout, out duration);
|
||||
}
|
||||
@@ -879,7 +897,8 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="currentMedia">If set to <c>true</c> descriptors should apply to currently inserted media.</param>
|
||||
/// <param name="timeout">Timeout.</param>
|
||||
/// <param name="duration">Duration.</param>
|
||||
public bool ReportDensitySupport(out byte[] buffer, out byte[] senseBuffer, bool mediumType, bool currentMedia, uint timeout, out double duration)
|
||||
public bool ReportDensitySupport(out byte[] buffer, out byte[] senseBuffer, bool mediumType, bool currentMedia,
|
||||
uint timeout, out double duration)
|
||||
{
|
||||
buffer = new byte[256];
|
||||
byte[] cdb = new byte[10];
|
||||
@@ -887,18 +906,16 @@ namespace DiscImageChef.Devices
|
||||
bool sense;
|
||||
|
||||
cdb[0] = (byte)ScsiCommands.ReportDensitySupport;
|
||||
if(currentMedia)
|
||||
cdb[1] += 0x01;
|
||||
if(mediumType)
|
||||
cdb[1] += 0x02;
|
||||
if(currentMedia) cdb[1] += 0x01;
|
||||
if(mediumType) cdb[1] += 0x02;
|
||||
cdb[7] = (byte)((buffer.Length & 0xFF00) >> 8);
|
||||
cdb[8] = (byte)(buffer.Length & 0xFF);
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
if(sense)
|
||||
return true;
|
||||
if(sense) return true;
|
||||
|
||||
#pragma warning disable IDE0004 // Cast is necessary or an invalid bitshift happens
|
||||
ushort availableLength = (ushort)(((int)buffer[0] << 8) + buffer[1] + 2);
|
||||
@@ -908,7 +925,8 @@ namespace DiscImageChef.Devices
|
||||
cdb[8] = (byte)(buffer.Length & 0xFF);
|
||||
senseBuffer = new byte[32];
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "REPORT DENSITY SUPPORT took {0} ms.", duration);
|
||||
@@ -942,10 +960,10 @@ namespace DiscImageChef.Devices
|
||||
bool sense;
|
||||
|
||||
cdb[0] = (byte)ScsiCommands.Rewind;
|
||||
if(immediate)
|
||||
cdb[1] += 0x01;
|
||||
if(immediate) cdb[1] += 0x01;
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.None, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.None, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "REWIND took {0} ms.", duration);
|
||||
@@ -971,7 +989,8 @@ namespace DiscImageChef.Devices
|
||||
cdb[0] = (byte)ScsiCommands.TrackSelect;
|
||||
cdb[5] = track;
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.None, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.None, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "TRACK SELECT took {0} ms.", duration);
|
||||
@@ -993,7 +1012,8 @@ namespace DiscImageChef.Devices
|
||||
cdb[3] = count_b[1];
|
||||
cdb[4] = count_b[0];
|
||||
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.None, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.None, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "SPACE took {0} ms.", duration);
|
||||
@@ -1001,5 +1021,4 @@ namespace DiscImageChef.Devices
|
||||
return sense;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -46,7 +46,8 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
|
||||
/// <param name="lba">Starting block.</param>
|
||||
/// <param name="blockSize">Block size in bytes.</param>
|
||||
public bool SyQuestRead6(out byte[] buffer, out byte[] senseBuffer, uint lba, uint blockSize, uint timeout, out double duration)
|
||||
public bool SyQuestRead6(out byte[] buffer, out byte[] senseBuffer, uint lba, uint blockSize, uint timeout,
|
||||
out double duration)
|
||||
{
|
||||
return SyQuestRead6(out buffer, out senseBuffer, lba, blockSize, 1, false, false, timeout, out duration);
|
||||
}
|
||||
@@ -61,7 +62,8 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
|
||||
/// <param name="lba">Starting block.</param>
|
||||
/// <param name="blockSize">Block size in bytes.</param>
|
||||
public bool SyQuestReadLong6(out byte[] buffer, out byte[] senseBuffer, uint lba, uint blockSize, uint timeout, out double duration)
|
||||
public bool SyQuestReadLong6(out byte[] buffer, out byte[] senseBuffer, uint lba, uint blockSize, uint timeout,
|
||||
out double duration)
|
||||
{
|
||||
return SyQuestRead6(out buffer, out senseBuffer, lba, blockSize, 1, false, true, timeout, out duration);
|
||||
}
|
||||
@@ -79,7 +81,8 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="readLong">If set to <c>true</c> drive will return ECC bytes and disable error detection.</param>
|
||||
/// <param name="blockSize">Block size in bytes.</param>
|
||||
/// <param name="transferLength">How many blocks to read.</param>
|
||||
public bool SyQuestRead6(out byte[] buffer, out byte[] senseBuffer, uint lba, uint blockSize, byte transferLength, bool inhibitDma, bool readLong, uint timeout, out double duration)
|
||||
public bool SyQuestRead6(out byte[] buffer, out byte[] senseBuffer, uint lba, uint blockSize,
|
||||
byte transferLength, bool inhibitDma, bool readLong, uint timeout, out double duration)
|
||||
{
|
||||
senseBuffer = new byte[32];
|
||||
byte[] cdb = new byte[6];
|
||||
@@ -90,30 +93,27 @@ namespace DiscImageChef.Devices
|
||||
cdb[2] = (byte)((lba & 0xFF00) >> 8);
|
||||
cdb[3] = (byte)(lba & 0xFF);
|
||||
cdb[4] = transferLength;
|
||||
if(inhibitDma)
|
||||
cdb[5] += 0x80;
|
||||
if(readLong)
|
||||
cdb[5] += 0x40;
|
||||
if(inhibitDma) cdb[5] += 0x80;
|
||||
if(readLong) cdb[5] += 0x40;
|
||||
|
||||
if(!inhibitDma && !readLong)
|
||||
{
|
||||
if(transferLength == 0)
|
||||
buffer = new byte[256 * blockSize];
|
||||
else
|
||||
buffer = new byte[transferLength * blockSize];
|
||||
if(transferLength == 0) buffer = new byte[256 * blockSize];
|
||||
else buffer = new byte[transferLength * blockSize];
|
||||
}
|
||||
else if(readLong)
|
||||
{
|
||||
buffer = new byte[blockSize];
|
||||
cdb[4] = 1;
|
||||
}
|
||||
else
|
||||
buffer = new byte[0];
|
||||
else buffer = new byte[0];
|
||||
|
||||
if(!inhibitDma)
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
else
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.None, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.None, out duration,
|
||||
out sense);
|
||||
|
||||
error = lastError != 0;
|
||||
|
||||
@@ -129,7 +129,8 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="senseBuffer">Sense buffer.</param>
|
||||
/// <param name="timeout">Timeout.</param>
|
||||
/// <param name="duration">Duration.</param>
|
||||
public bool SyQuestReadUsageCounter(out byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration)
|
||||
public bool SyQuestReadUsageCounter(out byte[] buffer, out byte[] senseBuffer, uint timeout,
|
||||
out double duration)
|
||||
{
|
||||
return AdaptecReadUsageCounter(out buffer, out senseBuffer, false, timeout, out duration);
|
||||
}
|
||||
@@ -144,7 +145,8 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
|
||||
/// <param name="lba">Starting block.</param>
|
||||
/// <param name="blockSize">Block size in bytes.</param>
|
||||
public bool SyQuestReadLong10(out byte[] buffer, out byte[] senseBuffer, uint lba, uint blockSize, uint timeout, out double duration)
|
||||
public bool SyQuestReadLong10(out byte[] buffer, out byte[] senseBuffer, uint lba, uint blockSize, uint timeout,
|
||||
out double duration)
|
||||
{
|
||||
return SyQuestRead10(out buffer, out senseBuffer, lba, blockSize, 1, false, true, timeout, out duration);
|
||||
}
|
||||
@@ -162,7 +164,9 @@ namespace DiscImageChef.Devices
|
||||
/// <param name="readLong">If set to <c>true</c> drive will return ECC bytes and disable error detection.</param>
|
||||
/// <param name="blockSize">Block size in bytes.</param>
|
||||
/// <param name="transferLength">How many blocks to read.</param>
|
||||
public bool SyQuestRead10(out byte[] buffer, out byte[] senseBuffer, uint lba, uint blockSize, ushort transferLength, bool inhibitDma, bool readLong, uint timeout, out double duration)
|
||||
public bool SyQuestRead10(out byte[] buffer, out byte[] senseBuffer, uint lba, uint blockSize,
|
||||
ushort transferLength, bool inhibitDma, bool readLong, uint timeout,
|
||||
out double duration)
|
||||
{
|
||||
senseBuffer = new byte[32];
|
||||
byte[] cdb = new byte[10];
|
||||
@@ -175,27 +179,23 @@ namespace DiscImageChef.Devices
|
||||
cdb[5] = (byte)(lba & 0xFF);
|
||||
cdb[7] = (byte)((transferLength & 0xFF00) >> 8);
|
||||
cdb[8] = (byte)(transferLength & 0xFF);
|
||||
if(inhibitDma)
|
||||
cdb[9] += 0x80;
|
||||
if(readLong)
|
||||
cdb[9] += 0x40;
|
||||
if(inhibitDma) cdb[9] += 0x80;
|
||||
if(readLong) cdb[9] += 0x40;
|
||||
|
||||
if(!inhibitDma && !readLong)
|
||||
{
|
||||
buffer = new byte[transferLength * blockSize];
|
||||
}
|
||||
if(!inhibitDma && !readLong) { buffer = new byte[transferLength * blockSize]; }
|
||||
else if(readLong)
|
||||
{
|
||||
buffer = new byte[blockSize];
|
||||
cdb[4] = 1;
|
||||
}
|
||||
else
|
||||
buffer = new byte[0];
|
||||
else buffer = new byte[0];
|
||||
|
||||
if(!inhibitDma)
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
|
||||
out sense);
|
||||
else
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.None, out duration, out sense);
|
||||
lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.None, out duration,
|
||||
out sense);
|
||||
error = lastError != 0;
|
||||
|
||||
DicConsole.DebugWriteLine("SCSI Device", "SYQUEST READ (10) took {0} ms.", duration);
|
||||
@@ -203,5 +203,4 @@ namespace DiscImageChef.Devices
|
||||
return sense;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -75,10 +75,7 @@ namespace DiscImageChef.Devices
|
||||
/// <value>The Platform ID</value>
|
||||
public Interop.PlatformID PlatformID
|
||||
{
|
||||
get
|
||||
{
|
||||
return platformID;
|
||||
}
|
||||
get { return platformID; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -87,21 +84,14 @@ namespace DiscImageChef.Devices
|
||||
/// <value>The file handle</value>
|
||||
public object FileHandle
|
||||
{
|
||||
get
|
||||
{
|
||||
return fd;
|
||||
}
|
||||
get { return fd; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the standard timeout for commands sent to this device
|
||||
/// </summary>
|
||||
/// <value>The timeout in seconds</value>
|
||||
public uint Timeout
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
public uint Timeout { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this <see cref="Device"/> is in error.
|
||||
@@ -109,10 +99,7 @@ namespace DiscImageChef.Devices
|
||||
/// <value><c>true</c> if error; otherwise, <c>false</c>.</value>
|
||||
public bool Error
|
||||
{
|
||||
get
|
||||
{
|
||||
return error;
|
||||
}
|
||||
get { return error; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -121,10 +108,7 @@ namespace DiscImageChef.Devices
|
||||
/// <value>The last error.</value>
|
||||
public int LastError
|
||||
{
|
||||
get
|
||||
{
|
||||
return lastError;
|
||||
}
|
||||
get { return lastError; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -133,10 +117,7 @@ namespace DiscImageChef.Devices
|
||||
/// <value>The device type.</value>
|
||||
public DeviceType Type
|
||||
{
|
||||
get
|
||||
{
|
||||
return type;
|
||||
}
|
||||
get { return type; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -145,10 +126,7 @@ namespace DiscImageChef.Devices
|
||||
/// <value>The manufacturer.</value>
|
||||
public string Manufacturer
|
||||
{
|
||||
get
|
||||
{
|
||||
return manufacturer;
|
||||
}
|
||||
get { return manufacturer; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -157,10 +135,7 @@ namespace DiscImageChef.Devices
|
||||
/// <value>The model.</value>
|
||||
public string Model
|
||||
{
|
||||
get
|
||||
{
|
||||
return model;
|
||||
}
|
||||
get { return model; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -169,10 +144,7 @@ namespace DiscImageChef.Devices
|
||||
/// <value>The revision.</value>
|
||||
public string Revision
|
||||
{
|
||||
get
|
||||
{
|
||||
return revision;
|
||||
}
|
||||
get { return revision; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -181,10 +153,7 @@ namespace DiscImageChef.Devices
|
||||
/// <value>The serial number.</value>
|
||||
public string Serial
|
||||
{
|
||||
get
|
||||
{
|
||||
return serial;
|
||||
}
|
||||
get { return serial; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -193,10 +162,7 @@ namespace DiscImageChef.Devices
|
||||
/// <value>The SCSI peripheral device type.</value>
|
||||
public Decoders.SCSI.PeripheralDeviceTypes SCSIType
|
||||
{
|
||||
get
|
||||
{
|
||||
return scsiType;
|
||||
}
|
||||
get { return scsiType; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -205,10 +171,7 @@ namespace DiscImageChef.Devices
|
||||
/// <value><c>true</c> if this device's media is removable; otherwise, <c>false</c>.</value>
|
||||
public bool IsRemovable
|
||||
{
|
||||
get
|
||||
{
|
||||
return removable;
|
||||
}
|
||||
get { return removable; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -217,10 +180,7 @@ namespace DiscImageChef.Devices
|
||||
/// <value><c>true</c> if this device is attached via USB; otherwise, <c>false</c>.</value>
|
||||
public bool IsUSB
|
||||
{
|
||||
get
|
||||
{
|
||||
return usb;
|
||||
}
|
||||
get { return usb; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -229,10 +189,7 @@ namespace DiscImageChef.Devices
|
||||
/// <value>The USB vendor ID.</value>
|
||||
public ushort USBVendorID
|
||||
{
|
||||
get
|
||||
{
|
||||
return usbVendor;
|
||||
}
|
||||
get { return usbVendor; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -241,10 +198,7 @@ namespace DiscImageChef.Devices
|
||||
/// <value>The USB product ID.</value>
|
||||
public ushort USBProductID
|
||||
{
|
||||
get
|
||||
{
|
||||
return usbProduct;
|
||||
}
|
||||
get { return usbProduct; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -253,10 +207,7 @@ namespace DiscImageChef.Devices
|
||||
/// <value>The USB descriptors.</value>
|
||||
public byte[] USBDescriptors
|
||||
{
|
||||
get
|
||||
{
|
||||
return usbDescriptors;
|
||||
}
|
||||
get { return usbDescriptors; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -265,10 +216,7 @@ namespace DiscImageChef.Devices
|
||||
/// <value>The USB manufacturer string.</value>
|
||||
public string USBManufacturerString
|
||||
{
|
||||
get
|
||||
{
|
||||
return usbManufacturerString;
|
||||
}
|
||||
get { return usbManufacturerString; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -277,10 +225,7 @@ namespace DiscImageChef.Devices
|
||||
/// <value>The USB product string.</value>
|
||||
public string USBProductString
|
||||
{
|
||||
get
|
||||
{
|
||||
return usbProductString;
|
||||
}
|
||||
get { return usbProductString; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -289,47 +234,62 @@ namespace DiscImageChef.Devices
|
||||
/// <value>The USB serial string.</value>
|
||||
public string USBSerialString
|
||||
{
|
||||
get
|
||||
{
|
||||
return usbSerialString;
|
||||
}
|
||||
get { return usbSerialString; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this device is attached via FireWire.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if this device is attached via FireWire; otherwise, <c>false</c>.</value>
|
||||
public bool IsFireWire { get { return firewire; } }
|
||||
public bool IsFireWire
|
||||
{
|
||||
get { return firewire; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the FireWire GUID
|
||||
/// </summary>
|
||||
/// <value>The FireWire GUID.</value>
|
||||
public ulong FireWireGUID { get { return firewireGuid; } }
|
||||
public ulong FireWireGUID
|
||||
{
|
||||
get { return firewireGuid; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the FireWire model number
|
||||
/// </summary>
|
||||
/// <value>The FireWire model.</value>
|
||||
public uint FireWireModel { get { return firewireModel; } }
|
||||
public uint FireWireModel
|
||||
{
|
||||
get { return firewireModel; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the FireWire model name.
|
||||
/// </summary>
|
||||
/// <value>The FireWire model name.</value>
|
||||
public string FireWireModelName { get { return firewireModelName; } }
|
||||
public string FireWireModelName
|
||||
{
|
||||
get { return firewireModelName; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the FireWire vendor number.
|
||||
/// </summary>
|
||||
/// <value>The FireWire vendor number.</value>
|
||||
public uint FireWireVendor { get { return firewireVendor; } }
|
||||
public uint FireWireVendor
|
||||
{
|
||||
get { return firewireVendor; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the FireWire vendor name.
|
||||
/// </summary>
|
||||
/// <value>The FireWire vendor name.</value>
|
||||
public string FireWireVendorName { get { return firewireVendorName; } }
|
||||
public string FireWireVendorName
|
||||
{
|
||||
get { return firewireVendorName; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this device is a CompactFlash device.
|
||||
@@ -337,10 +297,7 @@ namespace DiscImageChef.Devices
|
||||
/// <value><c>true</c> if this device is a CompactFlash device; otherwise, <c>false</c>.</value>
|
||||
public bool IsCompactFlash
|
||||
{
|
||||
get
|
||||
{
|
||||
return compactFlash;
|
||||
}
|
||||
get { return compactFlash; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -349,10 +306,7 @@ namespace DiscImageChef.Devices
|
||||
/// <value><c>true</c> if this device is a PCMCIA device; otherwise, <c>false</c>.</value>
|
||||
public bool IsPCMCIA
|
||||
{
|
||||
get
|
||||
{
|
||||
return pcmcia;
|
||||
}
|
||||
get { return pcmcia; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -360,11 +314,7 @@ namespace DiscImageChef.Devices
|
||||
/// </summary>
|
||||
public byte[] CIS
|
||||
{
|
||||
get
|
||||
{
|
||||
return cis;
|
||||
}
|
||||
get { return cis; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -52,7 +52,6 @@ namespace DiscImageChef.Devices
|
||||
public enum AtaCommands : byte
|
||||
{
|
||||
#region Commands defined on Western Digital WD1000 Winchester Disk Controller
|
||||
|
||||
/// <summary>
|
||||
/// Formats a track
|
||||
/// </summary>
|
||||
@@ -81,7 +80,6 @@ namespace DiscImageChef.Devices
|
||||
#endregion Commands defined on Western Digital WD1000 Winchester Disk Controller
|
||||
|
||||
#region Commands defined on ATA rev. 4c
|
||||
|
||||
/// <summary>
|
||||
/// Acknowledges media change
|
||||
/// </summary>
|
||||
@@ -349,7 +347,6 @@ namespace DiscImageChef.Devices
|
||||
#endregion Commands defined on ATA rev. 4c
|
||||
|
||||
#region Commands defined on ATA-2 rev. 4c
|
||||
|
||||
/// <summary>
|
||||
/// Alters the device microcode
|
||||
/// </summary>
|
||||
@@ -361,7 +358,6 @@ namespace DiscImageChef.Devices
|
||||
#endregion Commands defined on ATA-2 rev. 4c
|
||||
|
||||
#region Commands defined on ATA-3 rev. 7b
|
||||
|
||||
/// <summary>
|
||||
/// Gets a sector containing drive identification and capabilities
|
||||
/// </summary>
|
||||
@@ -397,7 +393,6 @@ namespace DiscImageChef.Devices
|
||||
#endregion Commands defined on ATA-3 rev. 7b
|
||||
|
||||
#region Commands defined on CompactFlash Specification
|
||||
|
||||
/// <summary>
|
||||
/// Pre-erases and conditions data sectors
|
||||
/// </summary>
|
||||
@@ -426,7 +421,6 @@ namespace DiscImageChef.Devices
|
||||
#endregion Commands defined on CompactFlash Specification
|
||||
|
||||
#region Commands defined on ATA/ATAPI-4 rev. 18
|
||||
|
||||
/// <summary>
|
||||
/// Resets a device
|
||||
/// </summary>
|
||||
@@ -482,7 +476,6 @@ namespace DiscImageChef.Devices
|
||||
#endregion Commands defined on ATA/ATAPI-4 rev. 18
|
||||
|
||||
#region Commands defined on ATA/ATAPI-6 rev. 3b
|
||||
|
||||
/// <summary>
|
||||
/// Determines if the device supports the Media Card Pass Through Command feature set
|
||||
/// </summary>
|
||||
@@ -554,7 +547,6 @@ namespace DiscImageChef.Devices
|
||||
#endregion Commands defined on ATA/ATAPI-6 rev. 3b
|
||||
|
||||
#region Commands defined on ATA/ATAPI-7 rev. 4b
|
||||
|
||||
/// <summary>
|
||||
/// Configurates the operating parameters for a stream
|
||||
/// </summary>
|
||||
@@ -578,7 +570,6 @@ namespace DiscImageChef.Devices
|
||||
#endregion Commands defined on ATA/ATAPI-7 rev. 4b
|
||||
|
||||
#region Commands defined on ATA/ATAPI-8 rev. 3f
|
||||
|
||||
/// <summary>
|
||||
/// Sends a Non Volatile Cache subcommand. <see cref="AtaNonVolatileCacheSubCommands"/>
|
||||
/// </summary>
|
||||
@@ -618,7 +609,6 @@ namespace DiscImageChef.Devices
|
||||
#endregion Commands defined on ATA/ATAPI-8 rev. 3f
|
||||
|
||||
#region Commands defined on ATA/ATAPI Command Set 2 (ACS-2) rev. 2
|
||||
|
||||
/// <summary>
|
||||
/// Provides information for device optimization
|
||||
/// In SSDs, this contains trimming
|
||||
@@ -660,7 +650,6 @@ namespace DiscImageChef.Devices
|
||||
#endregion Commands defined on ATA/ATAPI Command Set 2 (ACS-2) rev. 2
|
||||
|
||||
#region Commands defined on ATA/ATAPI Command Set 3 (ACS-3) rev. 5
|
||||
|
||||
/// <summary>
|
||||
/// Sends <see cref="AtaNCQQueueManagementSubcommands"/>
|
||||
/// </summary>
|
||||
@@ -669,7 +658,6 @@ namespace DiscImageChef.Devices
|
||||
/// Sets the device date and time
|
||||
/// </summary>
|
||||
SetDateAndTimeExt = 0x77,
|
||||
|
||||
#endregion Commands defined on ATA/ATAPI Command Set 3 (ACS-3) rev. 5
|
||||
|
||||
#region Commands defined on ATA/ATAPI Command Set 3 (ACS-3) rev. 6
|
||||
@@ -685,7 +673,6 @@ namespace DiscImageChef.Devices
|
||||
public enum AtaSmartSubCommands : byte
|
||||
{
|
||||
#region Commands defined on ATA-3 rev. 7b
|
||||
|
||||
/// <summary>
|
||||
/// Disables all SMART capabilities
|
||||
/// </summary>
|
||||
@@ -717,7 +704,6 @@ namespace DiscImageChef.Devices
|
||||
#endregion Commands defined on ATA-3 rev. 7b
|
||||
|
||||
#region Commands defined on ATA/ATAPI-4 rev. 18
|
||||
|
||||
/// <summary>
|
||||
/// Causes the device to immediately initiate a SMART data collection and saves it to the device
|
||||
/// </summary>
|
||||
@@ -729,7 +715,6 @@ namespace DiscImageChef.Devices
|
||||
#endregion Commands defined on ATA/ATAPI-4 rev. 18
|
||||
|
||||
#region Commands defined on ATA/ATAPI-5 rev. 3
|
||||
|
||||
/// <summary>
|
||||
/// Returns the indicated log to the host
|
||||
/// </summary>
|
||||
@@ -738,7 +723,6 @@ namespace DiscImageChef.Devices
|
||||
/// Writes data to the indicated log
|
||||
/// </summary>
|
||||
WriteLog = 0xD6
|
||||
|
||||
#endregion Commands defined on ATA/ATAPI-5 rev. 3
|
||||
}
|
||||
#endregion ATA SMART SubCommands
|
||||
@@ -750,7 +734,6 @@ namespace DiscImageChef.Devices
|
||||
public enum AtaDeviceConfigurationSubCommands : byte
|
||||
{
|
||||
#region Commands defined on ATA/ATAPI-6 rev. 3b
|
||||
|
||||
/// <summary>
|
||||
/// Disables any change made by <see cref="Set"/>
|
||||
/// </summary>
|
||||
@@ -767,7 +750,6 @@ namespace DiscImageChef.Devices
|
||||
/// Modifies the commands, modes and features sets the device will obey to
|
||||
/// </summary>
|
||||
Set = 0xC3
|
||||
|
||||
#endregion Commands defined on ATA/ATAPI-6 rev. 3b
|
||||
}
|
||||
#endregion ATA Device Configuration Overlay SubCommands
|
||||
@@ -779,7 +761,6 @@ namespace DiscImageChef.Devices
|
||||
public enum AtaSetMaxSubCommands : byte
|
||||
{
|
||||
#region Commands defined on ATA/ATAPI-6 rev. 3b
|
||||
|
||||
/// <summary>
|
||||
/// Redefines the maximum user-accessible address space
|
||||
/// </summary>
|
||||
@@ -811,7 +792,6 @@ namespace DiscImageChef.Devices
|
||||
public enum AtaNonVolatileCacheSubCommands : byte
|
||||
{
|
||||
#region Commands defined on ATA/ATAPI-8 rev. 3f
|
||||
|
||||
/// <summary>
|
||||
/// Adds the specified LBA to the Non Volatile Cache
|
||||
/// </summary>
|
||||
@@ -841,7 +821,6 @@ namespace DiscImageChef.Devices
|
||||
/// Enables the Non Volatile Cache Power Mode, so the device tries to serve all accesses from the Non Volatile Cache
|
||||
/// </summary>
|
||||
SetNvCachePowerMode = 0x00
|
||||
|
||||
#endregion Commands defined on ATA/ATAPI-8 rev. 3f
|
||||
}
|
||||
#endregion ATA Non Volatile Cache SubCommands
|
||||
@@ -853,7 +832,6 @@ namespace DiscImageChef.Devices
|
||||
public enum AtaSanitizeSubCommands : ushort
|
||||
{
|
||||
#region Commands defined on ATA/ATAPI Command Set 2 (ACS-2) rev. 2
|
||||
|
||||
/// <summary>
|
||||
/// Causes a block erase on all user data
|
||||
/// </summary>
|
||||
@@ -877,12 +855,10 @@ namespace DiscImageChef.Devices
|
||||
#endregion Commands defined on ATA/ATAPI Command Set 2 (ACS-2) rev. 2
|
||||
|
||||
#region Commands defined on ATA/ATAPI Command Set 3 (ACS-3) rev. 5
|
||||
|
||||
/// <summary>
|
||||
/// Disables the <see cref="FreezeLockExt"/> command
|
||||
/// </summary>
|
||||
AntiFreezeLockExt = 0x0040
|
||||
|
||||
#endregion Commands defined on ATA/ATAPI Command Set 3 (ACS-3) rev. 5
|
||||
}
|
||||
#endregion ATA Sanitize SubCommands
|
||||
@@ -894,7 +870,6 @@ namespace DiscImageChef.Devices
|
||||
public enum AtaNCQQueueManagementSubcommands : byte
|
||||
{
|
||||
#region Commands defined on ATA/ATAPI Command Set 3 (ACS-3) rev. 5
|
||||
|
||||
/// <summary>
|
||||
/// Aborts pending NCQ commands
|
||||
/// </summary>
|
||||
@@ -914,11 +889,11 @@ namespace DiscImageChef.Devices
|
||||
/// Commands 0x40 to 0x5F are 8-byte
|
||||
/// Commands 0xA0 to 0xBF are 12-byte
|
||||
/// </summary>
|
||||
|
||||
#region SASI Commands
|
||||
public enum SasiCommands : byte
|
||||
{
|
||||
#region SASI Class 0 commands
|
||||
|
||||
/// <summary>
|
||||
/// Returns zero status if requested unit is on and ready.
|
||||
/// SASI rev. 0a
|
||||
@@ -1101,7 +1076,6 @@ namespace DiscImageChef.Devices
|
||||
#endregion SASI Class 0 commands
|
||||
|
||||
#region SASI Class 1 commands
|
||||
|
||||
/// <summary>
|
||||
/// SASI rev. 0a
|
||||
/// Unknown
|
||||
@@ -1162,11 +1136,9 @@ namespace DiscImageChef.Devices
|
||||
/// ANSI X3T9.3 No. 185 (SASI)
|
||||
/// </summary>
|
||||
SearchDataLow = 0x32,
|
||||
|
||||
#endregion SASI Class 1 commands
|
||||
|
||||
#region SASI Class 2 commands
|
||||
|
||||
/// <summary>
|
||||
/// Unknown
|
||||
/// SASI rev. 0a
|
||||
@@ -1275,7 +1247,6 @@ namespace DiscImageChef.Devices
|
||||
#endregion SASI Class 2 commands
|
||||
|
||||
#region SASI Class 3 commands
|
||||
|
||||
/// <summary>
|
||||
/// SASI rev. 0a
|
||||
/// </summary>
|
||||
@@ -1307,7 +1278,6 @@ namespace DiscImageChef.Devices
|
||||
#endregion SASI Class 3 commands
|
||||
|
||||
#region SASI Class 5 commands
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of blocks in device.
|
||||
/// ANSI X3T9.3 No. 185 (SASI)
|
||||
@@ -1318,11 +1288,9 @@ namespace DiscImageChef.Devices
|
||||
/// ANSI X3T9.3 No. 185 (SASI)
|
||||
/// </summary>
|
||||
SetBlockLimits = 0xA9,
|
||||
|
||||
#endregion SASI Class 5 commands
|
||||
|
||||
#region SASI Class 6 commands
|
||||
|
||||
/// <summary>
|
||||
/// SASI rev. 0a
|
||||
/// </summary>
|
||||
@@ -1346,7 +1314,6 @@ namespace DiscImageChef.Devices
|
||||
#endregion SASI Class 6 commands
|
||||
|
||||
#region SASI Class 7 commands
|
||||
|
||||
/// <summary>
|
||||
/// SASI rev. 0a
|
||||
/// </summary>
|
||||
@@ -1375,7 +1342,6 @@ namespace DiscImageChef.Devices
|
||||
/// Found on a vendor document
|
||||
/// </summary>
|
||||
WriteLong = 0xE6
|
||||
|
||||
#endregion SASI Class 7 commands
|
||||
}
|
||||
#endregion SASI Commands
|
||||
@@ -1387,7 +1353,6 @@ namespace DiscImageChef.Devices
|
||||
public enum ScsiCommands : byte
|
||||
{
|
||||
#region SCSI Primary Commands (SPC)
|
||||
|
||||
/// <summary>
|
||||
/// Commands used to obtain information about the access controls that are active
|
||||
/// SPC-4 rev. 16
|
||||
@@ -1581,7 +1546,6 @@ namespace DiscImageChef.Devices
|
||||
#endregion SCSI Primary Commands (SPC)
|
||||
|
||||
#region SCSI Block Commands (SBC)
|
||||
|
||||
/// <summary>
|
||||
/// Compares blocks with sent data, and if equal, writes those block to device, atomically
|
||||
/// SBC-3 rev. 25
|
||||
@@ -1799,7 +1763,6 @@ namespace DiscImageChef.Devices
|
||||
#endregion SCSI Block Commands (SBC)
|
||||
|
||||
#region SCSI Streaming Commands (SSC)
|
||||
|
||||
/// <summary>
|
||||
/// Prepares the medium for use by the LUN
|
||||
/// SSC-1 rev. 22
|
||||
@@ -1883,7 +1846,6 @@ namespace DiscImageChef.Devices
|
||||
#endregion SCSI Streaming Commands (SSC)
|
||||
|
||||
#region SCSI Streaming Commands for Printers (SSC)
|
||||
|
||||
/// <summary>
|
||||
/// Assures that the data in the buffer has been printed, or, for other devices, written to media
|
||||
/// ECMA-111 (SCSI-1)
|
||||
@@ -1917,7 +1879,6 @@ namespace DiscImageChef.Devices
|
||||
#endregion SCSI Streaming Commands for Printers (SSC)
|
||||
|
||||
#region SCSI Processor Commands
|
||||
|
||||
/// <summary>
|
||||
/// Transfers data from the device
|
||||
/// ECMA-111 (SCSI-1)
|
||||
@@ -1931,7 +1892,6 @@ namespace DiscImageChef.Devices
|
||||
#endregion SCSI Processor Commands
|
||||
|
||||
#region SCSI Multimedia Commands (MMC)
|
||||
|
||||
/// <summary>
|
||||
/// Erases any part of a CD-RW
|
||||
/// MMC-1 rev. 9
|
||||
@@ -2150,7 +2110,6 @@ namespace DiscImageChef.Devices
|
||||
#endregion SCSI Multimedia Commands (MMC)
|
||||
|
||||
#region SCSI Scanner Commands
|
||||
|
||||
/// <summary>
|
||||
/// Gets information about the data buffer
|
||||
/// SCSI-2 X3T9.2/375R rev. 10l
|
||||
@@ -2184,7 +2143,6 @@ namespace DiscImageChef.Devices
|
||||
#endregion SCSI Scanner Commands
|
||||
|
||||
#region SCSI Block Commands for Optical Media (SBC)
|
||||
|
||||
/// <summary>
|
||||
/// Erases the specified number of blocks
|
||||
/// </summary>
|
||||
@@ -2257,7 +2215,6 @@ namespace DiscImageChef.Devices
|
||||
#endregion SCSI Block Commands for Optical Media (SBC)
|
||||
|
||||
#region SCSI Medium Changer Commands (SMC)
|
||||
|
||||
/// <summary>
|
||||
/// Provides a means to exchange the medium in the source element with the medium at destination element
|
||||
/// SCSI-2 X3T9.2/375R rev. 10l
|
||||
@@ -2341,7 +2298,6 @@ namespace DiscImageChef.Devices
|
||||
#endregion SCSI Medium Changer Commands (SMC)
|
||||
|
||||
#region SCSI Communication Commands
|
||||
|
||||
/// <summary>
|
||||
/// Gets data from the device
|
||||
/// SCSI-2 X3T9.2/375R rev. 10l
|
||||
@@ -2375,7 +2331,6 @@ namespace DiscImageChef.Devices
|
||||
#endregion SCSI Communication Commands
|
||||
|
||||
#region SCSI Controller Commands
|
||||
|
||||
/// <summary>
|
||||
/// Commands that get information about redundancy groups
|
||||
/// SCC-2 rev. 4
|
||||
@@ -2399,7 +2354,6 @@ namespace DiscImageChef.Devices
|
||||
#endregion SCSI Controller Commands
|
||||
|
||||
#region Pioneer CD-ROM SCSI-2 Command Set
|
||||
|
||||
/// <summary>
|
||||
/// Scans for a block playing a block on each track cross
|
||||
/// </summary>
|
||||
@@ -2436,7 +2390,6 @@ namespace DiscImageChef.Devices
|
||||
#endregion
|
||||
|
||||
#region ATA Command Pass-Through
|
||||
|
||||
/// <summary>
|
||||
/// Sends a 24-bit ATA command to the device
|
||||
/// Clashes with <see cref="Blank"/>
|
||||
@@ -2451,7 +2404,6 @@ namespace DiscImageChef.Devices
|
||||
#endregion ATA Command Pass-Through
|
||||
|
||||
#region 6-byte CDB aliases
|
||||
|
||||
ModeSelect6 = ModeSelect,
|
||||
ModeSense6 = ModeSense,
|
||||
Read6 = Read,
|
||||
@@ -2460,7 +2412,6 @@ namespace DiscImageChef.Devices
|
||||
#endregion 6-byte CDB aliases
|
||||
|
||||
#region SCSI Zoned Block Commands
|
||||
|
||||
/// <summary>
|
||||
/// ZBC commands with host->device information
|
||||
/// </summary>
|
||||
@@ -2472,7 +2423,6 @@ namespace DiscImageChef.Devices
|
||||
#endregion
|
||||
|
||||
#region SCSI Commands with unknown meaning, mostly vendor specific
|
||||
|
||||
SetCdSpeedUnk = 0xB8,
|
||||
WriteCdMsf = 0xA2,
|
||||
WriteCd = 0xAA,
|
||||
@@ -2489,7 +2439,6 @@ namespace DiscImageChef.Devices
|
||||
#endregion SCSI Commands with unknown meaning, mostly vendor specific
|
||||
|
||||
#region SEGA Packet Interface (all are 12-byte CDB)
|
||||
|
||||
/// <summary>
|
||||
/// Verifies that the device can be accessed
|
||||
/// Sega SPI ver. 1.30
|
||||
@@ -2864,13 +2813,11 @@ namespace DiscImageChef.Devices
|
||||
/// <summary>
|
||||
/// Allows medium removal from data transport but prevents it from medium changer
|
||||
/// </summary>
|
||||
[Obsolete]
|
||||
PreventChanger = 0x02,
|
||||
[Obsolete] PreventChanger = 0x02,
|
||||
/// <summary>
|
||||
/// Prevents medium removal from both data transport and medium changer
|
||||
/// </summary>
|
||||
[Obsolete]
|
||||
PreventAll = 0x03
|
||||
[Obsolete] PreventAll = 0x03
|
||||
}
|
||||
|
||||
public enum MmcGetConfigurationRt : byte
|
||||
@@ -3528,8 +3475,7 @@ namespace DiscImageChef.Devices
|
||||
/// <summary>
|
||||
/// Reads data stream from device, starting at given address, until a <see cref="StopTransmission"/> follows (ADTC, R1)
|
||||
/// </summary>
|
||||
[Obsolete]
|
||||
ReadDatUntilStop = 11,
|
||||
[Obsolete] ReadDatUntilStop = 11,
|
||||
/// <summary>
|
||||
/// Terminates a read/write stream/multiple block operation (AC, R1 / R1b)
|
||||
/// </summary>
|
||||
@@ -3577,8 +3523,7 @@ namespace DiscImageChef.Devices
|
||||
/// <summary>
|
||||
/// Writes data stream from host until a <see cref="StopTransmission"/> follows (ADTC, R1)
|
||||
/// </summary>
|
||||
[Obsolete]
|
||||
WriteDatUntilStop = 20,
|
||||
[Obsolete] WriteDatUntilStop = 20,
|
||||
#endregion Class 3 MMC Commands (Stream write)
|
||||
|
||||
#region Class 4 MMC Commands (Block-oriented write)
|
||||
@@ -3868,5 +3813,4 @@ namespace DiscImageChef.Devices
|
||||
Xtreme = 1,
|
||||
Wxripper = 2
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -55,14 +55,14 @@ namespace DiscImageChef.Devices.FreeBSD
|
||||
/// <param name="direction">SCSI command transfer direction</param>
|
||||
/// <param name="duration">Time it took to execute the command in milliseconds</param>
|
||||
/// <param name="sense"><c>True</c> if SCSI error returned non-OK status and <paramref name="senseBuffer"/> contains SCSI sense</param>
|
||||
internal static int SendScsiCommand64(IntPtr dev, byte[] cdb, ref byte[] buffer, out byte[] senseBuffer, uint timeout, ccb_flags direction, out double duration, out bool sense)
|
||||
internal static int SendScsiCommand64(IntPtr dev, byte[] cdb, ref byte[] buffer, out byte[] senseBuffer,
|
||||
uint timeout, ccb_flags direction, out double duration, out bool sense)
|
||||
{
|
||||
senseBuffer = null;
|
||||
duration = 0;
|
||||
sense = false;
|
||||
|
||||
if(buffer == null)
|
||||
return -1;
|
||||
if(buffer == null) return -1;
|
||||
|
||||
IntPtr ccbPtr = cam_getccb(dev);
|
||||
IntPtr cdbPtr = IntPtr.Zero;
|
||||
@@ -87,8 +87,7 @@ namespace DiscImageChef.Devices.FreeBSD
|
||||
// TODO: Create enum?
|
||||
csio.tag_action = 0x20;
|
||||
csio.cdb_bytes = new byte[CAM_MAX_CDBLEN];
|
||||
if(cdb.Length <= CAM_MAX_CDBLEN)
|
||||
Array.Copy(cdb, 0, csio.cdb_bytes, 0, cdb.Length);
|
||||
if(cdb.Length <= CAM_MAX_CDBLEN) Array.Copy(cdb, 0, csio.cdb_bytes, 0, cdb.Length);
|
||||
else
|
||||
{
|
||||
cdbPtr = Marshal.AllocHGlobal(cdb.Length);
|
||||
@@ -105,8 +104,7 @@ namespace DiscImageChef.Devices.FreeBSD
|
||||
int error = cam_send_ccb(dev, ccbPtr);
|
||||
DateTime end = DateTime.UtcNow;
|
||||
|
||||
if(error < 0)
|
||||
error = Marshal.GetLastWin32Error();
|
||||
if(error < 0) error = Marshal.GetLastWin32Error();
|
||||
|
||||
csio = (ccb_scsiio64)Marshal.PtrToStructure(ccbPtr, typeof(ccb_scsiio64));
|
||||
|
||||
@@ -142,12 +140,10 @@ namespace DiscImageChef.Devices.FreeBSD
|
||||
Marshal.Copy(csio.data_ptr, buffer, 0, buffer.Length);
|
||||
if(csio.ccb_h.flags.HasFlag(ccb_flags.CAM_CDB_POINTER))
|
||||
Marshal.Copy(new IntPtr(BitConverter.ToInt64(csio.cdb_bytes, 0)), cdb, 0, cdb.Length);
|
||||
else
|
||||
Array.Copy(csio.cdb_bytes, 0, cdb, 0, cdb.Length);
|
||||
else Array.Copy(csio.cdb_bytes, 0, cdb, 0, cdb.Length);
|
||||
duration = (end - start).TotalMilliseconds;
|
||||
|
||||
if(csio.ccb_h.flags.HasFlag(ccb_flags.CAM_CDB_POINTER))
|
||||
Marshal.FreeHGlobal(cdbPtr);
|
||||
if(csio.ccb_h.flags.HasFlag(ccb_flags.CAM_CDB_POINTER)) Marshal.FreeHGlobal(cdbPtr);
|
||||
Marshal.FreeHGlobal(csio.data_ptr);
|
||||
cam_freeccb(ccbPtr);
|
||||
|
||||
@@ -166,14 +162,14 @@ namespace DiscImageChef.Devices.FreeBSD
|
||||
/// <param name="direction">SCSI command transfer direction</param>
|
||||
/// <param name="duration">Time it took to execute the command in milliseconds</param>
|
||||
/// <param name="sense"><c>True</c> if SCSI error returned non-OK status and <paramref name="senseBuffer"/> contains SCSI sense</param>
|
||||
internal static int SendScsiCommand(IntPtr dev, byte[] cdb, ref byte[] buffer, out byte[] senseBuffer, uint timeout, ccb_flags direction, out double duration, out bool sense)
|
||||
internal static int SendScsiCommand(IntPtr dev, byte[] cdb, ref byte[] buffer, out byte[] senseBuffer,
|
||||
uint timeout, ccb_flags direction, out double duration, out bool sense)
|
||||
{
|
||||
senseBuffer = null;
|
||||
duration = 0;
|
||||
sense = false;
|
||||
|
||||
if(buffer == null)
|
||||
return -1;
|
||||
if(buffer == null) return -1;
|
||||
|
||||
IntPtr ccbPtr = cam_getccb(dev);
|
||||
IntPtr cdbPtr = IntPtr.Zero;
|
||||
@@ -198,8 +194,7 @@ namespace DiscImageChef.Devices.FreeBSD
|
||||
// TODO: Create enum?
|
||||
csio.tag_action = 0x20;
|
||||
csio.cdb_bytes = new byte[CAM_MAX_CDBLEN];
|
||||
if(cdb.Length <= CAM_MAX_CDBLEN)
|
||||
Array.Copy(cdb, 0, csio.cdb_bytes, 0, cdb.Length);
|
||||
if(cdb.Length <= CAM_MAX_CDBLEN) Array.Copy(cdb, 0, csio.cdb_bytes, 0, cdb.Length);
|
||||
else
|
||||
{
|
||||
cdbPtr = Marshal.AllocHGlobal(cdb.Length);
|
||||
@@ -216,8 +211,7 @@ namespace DiscImageChef.Devices.FreeBSD
|
||||
int error = cam_send_ccb(dev, ccbPtr);
|
||||
DateTime end = DateTime.UtcNow;
|
||||
|
||||
if(error < 0)
|
||||
error = Marshal.GetLastWin32Error();
|
||||
if(error < 0) error = Marshal.GetLastWin32Error();
|
||||
|
||||
csio = (ccb_scsiio)Marshal.PtrToStructure(ccbPtr, typeof(ccb_scsiio));
|
||||
|
||||
@@ -253,12 +247,10 @@ namespace DiscImageChef.Devices.FreeBSD
|
||||
Marshal.Copy(csio.data_ptr, buffer, 0, buffer.Length);
|
||||
if(csio.ccb_h.flags.HasFlag(ccb_flags.CAM_CDB_POINTER))
|
||||
Marshal.Copy(new IntPtr(BitConverter.ToInt32(csio.cdb_bytes, 0)), cdb, 0, cdb.Length);
|
||||
else
|
||||
Array.Copy(csio.cdb_bytes, 0, cdb, 0, cdb.Length);
|
||||
else Array.Copy(csio.cdb_bytes, 0, cdb, 0, cdb.Length);
|
||||
duration = (end - start).TotalMilliseconds;
|
||||
|
||||
if(csio.ccb_h.flags.HasFlag(ccb_flags.CAM_CDB_POINTER))
|
||||
Marshal.FreeHGlobal(cdbPtr);
|
||||
if(csio.ccb_h.flags.HasFlag(ccb_flags.CAM_CDB_POINTER)) Marshal.FreeHGlobal(cdbPtr);
|
||||
Marshal.FreeHGlobal(csio.data_ptr);
|
||||
cam_freeccb(ccbPtr);
|
||||
|
||||
@@ -274,16 +266,12 @@ namespace DiscImageChef.Devices.FreeBSD
|
||||
case AtaProtocol.HardReset:
|
||||
case AtaProtocol.NonData:
|
||||
case AtaProtocol.SoftReset:
|
||||
case AtaProtocol.ReturnResponse:
|
||||
return ccb_flags.CAM_DIR_NONE;
|
||||
case AtaProtocol.ReturnResponse: return ccb_flags.CAM_DIR_NONE;
|
||||
case AtaProtocol.PioIn:
|
||||
case AtaProtocol.UDmaIn:
|
||||
return ccb_flags.CAM_DIR_IN;
|
||||
case AtaProtocol.UDmaIn: return ccb_flags.CAM_DIR_IN;
|
||||
case AtaProtocol.PioOut:
|
||||
case AtaProtocol.UDmaOut:
|
||||
return ccb_flags.CAM_DIR_OUT;
|
||||
default:
|
||||
return ccb_flags.CAM_DIR_NONE;
|
||||
case AtaProtocol.UDmaOut: return ccb_flags.CAM_DIR_OUT;
|
||||
default: return ccb_flags.CAM_DIR_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -470,7 +458,7 @@ namespace DiscImageChef.Devices.FreeBSD
|
||||
// 48-bit ATA CAM commands can crash FreeBSD < 9.2-RELEASE
|
||||
if((System.Environment.Version.Major == 9 && System.Environment.Version.Minor < 2) ||
|
||||
System.Environment.Version.Major < 9) return -1;
|
||||
|
||||
|
||||
if(buffer == null) return -1;
|
||||
|
||||
IntPtr ccbPtr = cam_getccb(dev);
|
||||
@@ -554,5 +542,4 @@ namespace DiscImageChef.Devices.FreeBSD
|
||||
return error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -174,8 +174,7 @@ namespace DiscImageChef.Devices.FreeBSD
|
||||
/// <summary>Set device type information</summary>
|
||||
XPT_SDEV_TYPE = 0x07,
|
||||
/// <summary>(Re)Scan the SCSI Bus</summary>
|
||||
XPT_SCAN_BUS = 0x08 | XPT_FC_QUEUED | XPT_FC_USER_CCB
|
||||
| XPT_FC_XPT_ONLY,
|
||||
XPT_SCAN_BUS = 0x08 | XPT_FC_QUEUED | XPT_FC_USER_CCB | XPT_FC_XPT_ONLY,
|
||||
/// <summary>Get EDT entries matching the given pattern</summary>
|
||||
XPT_DEV_MATCH = 0x09 | XPT_FC_XPT_ONLY,
|
||||
/// <summary>Turn on debugging for a bus, target or lun</summary>
|
||||
@@ -187,11 +186,9 @@ namespace DiscImageChef.Devices.FreeBSD
|
||||
/// <summary>Get/Set Device advanced information</summary>
|
||||
XPT_DEV_ADVINFO = 0x0e,
|
||||
/// <summary>Asynchronous event</summary>
|
||||
XPT_ASYNC = 0x0f | XPT_FC_QUEUED | XPT_FC_USER_CCB
|
||||
| XPT_FC_XPT_ONLY,
|
||||
XPT_ASYNC = 0x0f | XPT_FC_QUEUED | XPT_FC_USER_CCB | XPT_FC_XPT_ONLY,
|
||||
|
||||
/// <summary>SCSI Control Functions: 0x10->0x1F</summary>
|
||||
|
||||
/// <summary>Abort the specified CCB</summary>
|
||||
XPT_ABORT = 0x10,
|
||||
/// <summary>Reset the specified SCSI bus</summary>
|
||||
@@ -201,8 +198,7 @@ namespace DiscImageChef.Devices.FreeBSD
|
||||
/// <summary>Terminate the I/O process</summary>
|
||||
XPT_TERM_IO = 0x13,
|
||||
/// <summary>Scan Logical Unit</summary>
|
||||
XPT_SCAN_LUN = 0x14 | XPT_FC_QUEUED | XPT_FC_USER_CCB
|
||||
| XPT_FC_XPT_ONLY,
|
||||
XPT_SCAN_LUN = 0x14 | XPT_FC_QUEUED | XPT_FC_USER_CCB | XPT_FC_XPT_ONLY,
|
||||
/// <summary>Get default/user transfer settings for the target</summary>
|
||||
XPT_GET_TRAN_SETTINGS = 0x15,
|
||||
/// <summary>Set transfer rate/width negotiation settings</summary>
|
||||
@@ -222,8 +218,7 @@ namespace DiscImageChef.Devices.FreeBSD
|
||||
/// <summary>Serial Management Protocol</summary>
|
||||
XPT_SMP_IO = 0x1b | XPT_FC_DEV_QUEUED,
|
||||
/// <summary>Scan Target</summary>
|
||||
XPT_SCAN_TGT = 0x1E | XPT_FC_QUEUED | XPT_FC_USER_CCB
|
||||
| XPT_FC_XPT_ONLY,
|
||||
XPT_SCAN_TGT = 0x1E | XPT_FC_QUEUED | XPT_FC_USER_CCB | XPT_FC_XPT_ONLY,
|
||||
|
||||
// HBA engine commands 0x20->0x2F
|
||||
|
||||
@@ -280,7 +275,7 @@ namespace DiscImageChef.Devices.FreeBSD
|
||||
PERIPH_MATCH_LUN = 0x004,
|
||||
PERIPH_MATCH_NAME = 0x008,
|
||||
PERIPH_MATCH_UNIT = 0x010,
|
||||
// PERIPH_MATCH_ANY = 0x01f
|
||||
// PERIPH_MATCH_ANY = 0x01f
|
||||
}
|
||||
|
||||
[Flags]
|
||||
@@ -292,7 +287,7 @@ namespace DiscImageChef.Devices.FreeBSD
|
||||
DEV_MATCH_LUN = 0x004,
|
||||
DEV_MATCH_INQUIRY = 0x008,
|
||||
DEV_MATCH_DEVID = 0x010,
|
||||
// DEV_MATCH_ANY = 0x00f
|
||||
// DEV_MATCH_ANY = 0x00f
|
||||
}
|
||||
|
||||
[Flags]
|
||||
@@ -303,7 +298,7 @@ namespace DiscImageChef.Devices.FreeBSD
|
||||
BUS_MATCH_NAME = 0x002,
|
||||
BUS_MATCH_UNIT = 0x004,
|
||||
BUS_MATCH_BUS_ID = 0x008,
|
||||
// BUS_MATCH_ANY = 0x00f
|
||||
// BUS_MATCH_ANY = 0x00f
|
||||
}
|
||||
|
||||
[Flags]
|
||||
@@ -382,11 +377,11 @@ namespace DiscImageChef.Devices.FreeBSD
|
||||
CAM_DEV_POS_DEVICE = 0x004,
|
||||
CAM_DEV_POS_PERIPH = 0x008,
|
||||
CAM_DEV_POS_PDPTR = 0x010,
|
||||
// CAM_DEV_POS_TYPEMASK = 0xf00,
|
||||
// CAM_DEV_POS_TYPEMASK = 0xf00,
|
||||
CAM_DEV_POS_EDT = 0x100,
|
||||
CAM_DEV_POS_PDRV = 0x200
|
||||
}
|
||||
|
||||
|
||||
enum FreebsdIoctl : uint
|
||||
{
|
||||
CAMIOCOMMAND = 0xC4D81802,
|
||||
@@ -564,176 +559,174 @@ namespace DiscImageChef.Devices.FreeBSD
|
||||
CAM_UNLOCKED = 0x80000000
|
||||
}
|
||||
|
||||
enum cam_status : uint
|
||||
{
|
||||
/// <summary>CCB request is in progress</summary>
|
||||
CAM_REQ_INPROG = 0x00,
|
||||
enum cam_status : uint
|
||||
{
|
||||
/// <summary>CCB request is in progress</summary>
|
||||
CAM_REQ_INPROG = 0x00,
|
||||
|
||||
/// <summary>CCB request completed without error</summary>
|
||||
CAM_REQ_CMP = 0x01,
|
||||
/// <summary>CCB request completed without error</summary>
|
||||
CAM_REQ_CMP = 0x01,
|
||||
|
||||
/// <summary>CCB request aborted by the host</summary>
|
||||
CAM_REQ_ABORTED = 0x02,
|
||||
/// <summary>CCB request aborted by the host</summary>
|
||||
CAM_REQ_ABORTED = 0x02,
|
||||
|
||||
/// <summary>Unable to abort CCB request</summary>
|
||||
CAM_UA_ABORT = 0x03,
|
||||
/// <summary>Unable to abort CCB request</summary>
|
||||
CAM_UA_ABORT = 0x03,
|
||||
|
||||
/// <summary>CCB request completed with an error</summary>
|
||||
CAM_REQ_CMP_ERR = 0x04,
|
||||
/// <summary>CCB request completed with an error</summary>
|
||||
CAM_REQ_CMP_ERR = 0x04,
|
||||
|
||||
/// <summary>CAM subsystem is busy</summary>
|
||||
CAM_BUSY = 0x05,
|
||||
/// <summary>CAM subsystem is busy</summary>
|
||||
CAM_BUSY = 0x05,
|
||||
|
||||
/// <summary>CCB request was invalid</summary>
|
||||
CAM_REQ_INVALID = 0x06,
|
||||
/// <summary>CCB request was invalid</summary>
|
||||
CAM_REQ_INVALID = 0x06,
|
||||
|
||||
/// <summary>Supplied Path ID is invalid</summary>
|
||||
CAM_PATH_INVALID = 0x07,
|
||||
/// <summary>Supplied Path ID is invalid</summary>
|
||||
CAM_PATH_INVALID = 0x07,
|
||||
|
||||
/// <summary>SCSI Device Not Installed/there</summary>
|
||||
CAM_DEV_NOT_THERE = 0x08,
|
||||
/// <summary>SCSI Device Not Installed/there</summary>
|
||||
CAM_DEV_NOT_THERE = 0x08,
|
||||
|
||||
/// <summary>Unable to terminate I/O CCB request</summary>
|
||||
CAM_UA_TERMIO = 0x09,
|
||||
/// <summary>Unable to terminate I/O CCB request</summary>
|
||||
CAM_UA_TERMIO = 0x09,
|
||||
|
||||
/// <summary>Target Selection Timeout</summary>
|
||||
CAM_SEL_TIMEOUT = 0x0a,
|
||||
/// <summary>Target Selection Timeout</summary>
|
||||
CAM_SEL_TIMEOUT = 0x0a,
|
||||
|
||||
/// <summary>Command timeout</summary>
|
||||
CAM_CMD_TIMEOUT = 0x0b,
|
||||
/// <summary>Command timeout</summary>
|
||||
CAM_CMD_TIMEOUT = 0x0b,
|
||||
|
||||
/// <summary>SCSI error, look at error code in CCB</summary>
|
||||
CAM_SCSI_STATUS_ERROR = 0x0c,
|
||||
/// <summary>SCSI error, look at error code in CCB</summary>
|
||||
CAM_SCSI_STATUS_ERROR = 0x0c,
|
||||
|
||||
/// <summary>Message Reject Received</summary>
|
||||
CAM_MSG_REJECT_REC = 0x0d,
|
||||
/// <summary>Message Reject Received</summary>
|
||||
CAM_MSG_REJECT_REC = 0x0d,
|
||||
|
||||
/// <summary>SCSI Bus Reset Sent/Received</summary>
|
||||
CAM_SCSI_BUS_RESET = 0x0e,
|
||||
/// <summary>SCSI Bus Reset Sent/Received</summary>
|
||||
CAM_SCSI_BUS_RESET = 0x0e,
|
||||
|
||||
/// <summary>Uncorrectable parity error occurred</summary>
|
||||
CAM_UNCOR_PARITY = 0x0f,
|
||||
/// <summary>Uncorrectable parity error occurred</summary>
|
||||
CAM_UNCOR_PARITY = 0x0f,
|
||||
|
||||
/// <summary>Autosense: request sense cmd fail</summary>
|
||||
CAM_AUTOSENSE_FAIL = 0x10,
|
||||
/// <summary>Autosense: request sense cmd fail</summary>
|
||||
CAM_AUTOSENSE_FAIL = 0x10,
|
||||
|
||||
/// <summary>No HBA Detected error</summary>
|
||||
CAM_NO_HBA = 0x11,
|
||||
/// <summary>No HBA Detected error</summary>
|
||||
CAM_NO_HBA = 0x11,
|
||||
|
||||
/// <summary>Data Overrun error</summary>
|
||||
CAM_DATA_RUN_ERR = 0x12,
|
||||
/// <summary>Data Overrun error</summary>
|
||||
CAM_DATA_RUN_ERR = 0x12,
|
||||
|
||||
/// <summary>Unexpected Bus Free</summary>
|
||||
CAM_UNEXP_BUSFREE = 0x13,
|
||||
/// <summary>Unexpected Bus Free</summary>
|
||||
CAM_UNEXP_BUSFREE = 0x13,
|
||||
|
||||
/// <summary>Target Bus Phase Sequence Failure</summary>
|
||||
CAM_SEQUENCE_FAIL = 0x14,
|
||||
/// <summary>Target Bus Phase Sequence Failure</summary>
|
||||
CAM_SEQUENCE_FAIL = 0x14,
|
||||
|
||||
/// <summary>CCB length supplied is inadequate</summary>
|
||||
CAM_CCB_LEN_ERR = 0x15,
|
||||
/// <summary>CCB length supplied is inadequate</summary>
|
||||
CAM_CCB_LEN_ERR = 0x15,
|
||||
|
||||
/// <summary>Unable to provide requested capability</summary>
|
||||
CAM_PROVIDE_FAIL = 0x16,
|
||||
/// <summary>Unable to provide requested capability</summary>
|
||||
CAM_PROVIDE_FAIL = 0x16,
|
||||
|
||||
/// <summary>A SCSI BDR msg was sent to target</summary>
|
||||
CAM_BDR_SENT = 0x17,
|
||||
/// <summary>A SCSI BDR msg was sent to target</summary>
|
||||
CAM_BDR_SENT = 0x17,
|
||||
|
||||
/// <summary>CCB request terminated by the host</summary>
|
||||
CAM_REQ_TERMIO = 0x18,
|
||||
/// <summary>CCB request terminated by the host</summary>
|
||||
CAM_REQ_TERMIO = 0x18,
|
||||
|
||||
/// <summary>Unrecoverable Host Bus Adapter Error</summary>
|
||||
CAM_UNREC_HBA_ERROR = 0x19,
|
||||
/// <summary>Unrecoverable Host Bus Adapter Error</summary>
|
||||
CAM_UNREC_HBA_ERROR = 0x19,
|
||||
|
||||
/// <summary>Request was too large for this host</summary>
|
||||
CAM_REQ_TOO_BIG = 0x1a,
|
||||
/// <summary>Request was too large for this host</summary>
|
||||
CAM_REQ_TOO_BIG = 0x1a,
|
||||
|
||||
/// <summary>This request should be requeued to preserve transaction ordering. This typically occurs when the SIM recognizes an error that should freeze the queue and must place additional requests for the target at the sim level back into the XPT queue.</summary>
|
||||
CAM_REQUEUE_REQ = 0x1b,
|
||||
/// <summary>This request should be requeued to preserve transaction ordering. This typically occurs when the SIM recognizes an error that should freeze the queue and must place additional requests for the target at the sim level back into the XPT queue.</summary>
|
||||
CAM_REQUEUE_REQ = 0x1b,
|
||||
|
||||
/// <summary>ATA error, look at error code in CCB</summary>
|
||||
CAM_ATA_STATUS_ERROR = 0x1c,
|
||||
/// <summary>ATA error, look at error code in CCB</summary>
|
||||
CAM_ATA_STATUS_ERROR = 0x1c,
|
||||
|
||||
/// <summary>Initiator/Target Nexus lost.</summary>
|
||||
CAM_SCSI_IT_NEXUS_LOST = 0x1d,
|
||||
/// <summary>Initiator/Target Nexus lost.</summary>
|
||||
CAM_SCSI_IT_NEXUS_LOST = 0x1d,
|
||||
|
||||
/// <summary>SMP error, look at error code in CCB</summary>
|
||||
CAM_SMP_STATUS_ERROR = 0x1e,
|
||||
/// <summary>SMP error, look at error code in CCB</summary>
|
||||
CAM_SMP_STATUS_ERROR = 0x1e,
|
||||
|
||||
/// <summary>Command completed without error but exceeded the soft timeout threshold.</summary>
|
||||
CAM_REQ_SOFTTIMEOUT = 0x1f,
|
||||
/// <summary>Command completed without error but exceeded the soft timeout threshold.</summary>
|
||||
CAM_REQ_SOFTTIMEOUT = 0x1f,
|
||||
|
||||
/*
|
||||
* 0x20 - 0x32 are unassigned
|
||||
*/
|
||||
/*
|
||||
* 0x20 - 0x32 are unassigned
|
||||
*/
|
||||
|
||||
/// <summary>Initiator Detected Error</summary>
|
||||
CAM_IDE = 0x33,
|
||||
/// <summary>Initiator Detected Error</summary>
|
||||
CAM_IDE = 0x33,
|
||||
|
||||
/// <summary>Resource Unavailable</summary>
|
||||
CAM_RESRC_UNAVAIL = 0x34,
|
||||
/// <summary>Resource Unavailable</summary>
|
||||
CAM_RESRC_UNAVAIL = 0x34,
|
||||
|
||||
/// <summary>Unacknowledged Event by Host</summary>
|
||||
CAM_UNACKED_EVENT = 0x35,
|
||||
/// <summary>Unacknowledged Event by Host</summary>
|
||||
CAM_UNACKED_EVENT = 0x35,
|
||||
|
||||
/// <summary>Message Received in Host Target Mode</summary>
|
||||
CAM_MESSAGE_RECV = 0x36,
|
||||
/// <summary>Message Received in Host Target Mode</summary>
|
||||
CAM_MESSAGE_RECV = 0x36,
|
||||
|
||||
/// <summary>Invalid CDB received in Host Target Mode</summary>
|
||||
CAM_INVALID_CDB = 0x37,
|
||||
/// <summary>Invalid CDB received in Host Target Mode</summary>
|
||||
CAM_INVALID_CDB = 0x37,
|
||||
|
||||
/// <summary>Lun supplied is invalid</summary>
|
||||
CAM_LUN_INVALID = 0x38,
|
||||
/// <summary>Lun supplied is invalid</summary>
|
||||
CAM_LUN_INVALID = 0x38,
|
||||
|
||||
/// <summary>Target ID supplied is invalid</summary>
|
||||
CAM_TID_INVALID = 0x39,
|
||||
/// <summary>Target ID supplied is invalid</summary>
|
||||
CAM_TID_INVALID = 0x39,
|
||||
|
||||
/// <summary>The requested function is not available</summary>
|
||||
CAM_FUNC_NOTAVAIL = 0x3a,
|
||||
/// <summary>The requested function is not available</summary>
|
||||
CAM_FUNC_NOTAVAIL = 0x3a,
|
||||
|
||||
/// <summary>Nexus is not established</summary>
|
||||
CAM_NO_NEXUS = 0x3b,
|
||||
/// <summary>Nexus is not established</summary>
|
||||
CAM_NO_NEXUS = 0x3b,
|
||||
|
||||
/// <summary>The initiator ID is invalid</summary>
|
||||
CAM_IID_INVALID = 0x3c,
|
||||
/// <summary>The initiator ID is invalid</summary>
|
||||
CAM_IID_INVALID = 0x3c,
|
||||
|
||||
/// <summary>The SCSI CDB has been received</summary>
|
||||
CAM_CDB_RECVD = 0x3d,
|
||||
/// <summary>The SCSI CDB has been received</summary>
|
||||
CAM_CDB_RECVD = 0x3d,
|
||||
|
||||
/// <summary>The LUN is already enabled for target mode</summary>
|
||||
CAM_LUN_ALRDY_ENA = 0x3e,
|
||||
/// <summary>The LUN is already enabled for target mode</summary>
|
||||
CAM_LUN_ALRDY_ENA = 0x3e,
|
||||
|
||||
/// <summary>SCSI Bus Busy</summary>
|
||||
CAM_SCSI_BUSY = 0x3f,
|
||||
/// <summary>SCSI Bus Busy</summary>
|
||||
CAM_SCSI_BUSY = 0x3f,
|
||||
|
||||
/*
|
||||
* Flags
|
||||
*/
|
||||
|
||||
/*
|
||||
* Flags
|
||||
*/
|
||||
/// <summary>The DEV queue is frozen w/this err</summary>
|
||||
CAM_DEV_QFRZN = 0x40,
|
||||
|
||||
/// <summary>The DEV queue is frozen w/this err</summary>
|
||||
CAM_DEV_QFRZN = 0x40,
|
||||
/// <summary>Autosense data valid for target</summary>
|
||||
CAM_AUTOSNS_VALID = 0x80,
|
||||
|
||||
/// <summary>Autosense data valid for target</summary>
|
||||
CAM_AUTOSNS_VALID = 0x80,
|
||||
/// <summary>SIM ready to take more commands</summary>
|
||||
CAM_RELEASE_SIMQ = 0x100,
|
||||
|
||||
/// <summary>SIM ready to take more commands</summary>
|
||||
CAM_RELEASE_SIMQ = 0x100,
|
||||
/// <summary>SIM has this command in its queue</summary>
|
||||
CAM_SIM_QUEUED = 0x200,
|
||||
|
||||
/// <summary>SIM has this command in its queue</summary>
|
||||
CAM_SIM_QUEUED = 0x200,
|
||||
/// <summary>Quality of service data is valid</summary>
|
||||
CAM_QOS_VALID = 0x400,
|
||||
|
||||
/// <summary>Quality of service data is valid</summary>
|
||||
CAM_QOS_VALID = 0x400,
|
||||
/// <summary>Mask bits for just the status #</summary>
|
||||
CAM_STATUS_MASK = 0x3F,
|
||||
|
||||
/// <summary>Mask bits for just the status #</summary>
|
||||
CAM_STATUS_MASK = 0x3F,
|
||||
|
||||
/*
|
||||
* Target Specific Adjunct Status
|
||||
*/
|
||||
|
||||
/// <summary>sent sense with status</summary>
|
||||
CAM_SENT_SENSE = 0x40000000
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Target Specific Adjunct Status
|
||||
*/
|
||||
|
||||
/// <summary>sent sense with status</summary>
|
||||
CAM_SENT_SENSE = 0x40000000
|
||||
}
|
||||
}
|
||||
@@ -39,19 +39,13 @@ namespace DiscImageChef.Devices.FreeBSD
|
||||
static class Extern
|
||||
{
|
||||
[DllImport("libc", CharSet = CharSet.Ansi, SetLastError = true)]
|
||||
internal static extern int open(
|
||||
string pathname,
|
||||
[MarshalAs(UnmanagedType.U4)]
|
||||
FileFlags flags);
|
||||
internal static extern int open(string pathname, [MarshalAs(UnmanagedType.U4)] FileFlags flags);
|
||||
|
||||
[DllImport("libc")]
|
||||
internal static extern int close(int fd);
|
||||
|
||||
[DllImport("libcam", CharSet = CharSet.Ansi, SetLastError = true)]
|
||||
internal static extern IntPtr cam_open_device(
|
||||
string path,
|
||||
[MarshalAs(UnmanagedType.U4)]
|
||||
FileFlags flags);
|
||||
internal static extern IntPtr cam_open_device(string path, [MarshalAs(UnmanagedType.U4)] FileFlags flags);
|
||||
|
||||
[DllImport("libcam", CharSet = CharSet.Ansi, SetLastError = true)]
|
||||
internal static extern void cam_close_device(IntPtr dev);
|
||||
@@ -68,5 +62,4 @@ namespace DiscImageChef.Devices.FreeBSD
|
||||
[DllImport("libc")]
|
||||
internal static extern int ioctl(int fd, FreebsdIoctl request, IntPtr argp);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -121,7 +121,6 @@ namespace DiscImageChef.Devices.FreeBSD
|
||||
}
|
||||
case cam_proto.PROTO_SCSI:
|
||||
{
|
||||
|
||||
Decoders.SCSI.Inquiry.SCSIInquiry? inq = Decoders.SCSI.Inquiry.Decode(cgd.inq_data);
|
||||
if(inq.HasValue)
|
||||
{
|
||||
|
||||
@@ -165,10 +165,8 @@ namespace DiscImageChef.Devices.FreeBSD
|
||||
public ulong target_lun;
|
||||
public ccb_flags flags;
|
||||
public uint xflags;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
|
||||
public IntPtr[] periph_priv;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
|
||||
public IntPtr[] sim_priv;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public IntPtr[] periph_priv;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public IntPtr[] sim_priv;
|
||||
public ccb_qos_area qos;
|
||||
public uint timeout;
|
||||
public timeval softtimeout;
|
||||
@@ -257,7 +255,7 @@ namespace DiscImageChef.Devices.FreeBSD
|
||||
public sbyte sense_resid;
|
||||
/// <summary>Transfer residual length: 2's comp</summary>
|
||||
public int resid;
|
||||
public uint alignment;
|
||||
public uint alignment;
|
||||
/// <summary>
|
||||
/// Area for the CDB send, or pointer to the CDB bytes to send
|
||||
/// </summary>
|
||||
@@ -274,6 +272,7 @@ namespace DiscImageChef.Devices.FreeBSD
|
||||
/// <summary>initiator id of who selected</summary>
|
||||
public uint init_id;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ATA I/O Request CCB used for the XPT_ATA_IO function code.
|
||||
/// </summary>
|
||||
@@ -787,5 +786,4 @@ namespace DiscImageChef.Devices.FreeBSD
|
||||
public byte serial_num_len;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public IntPtr[] padding;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -51,14 +51,14 @@ namespace DiscImageChef.Devices.Linux
|
||||
/// <param name="direction">SCSI command transfer direction</param>
|
||||
/// <param name="duration">Time it took to execute the command in milliseconds</param>
|
||||
/// <param name="sense"><c>True</c> if SCSI error returned non-OK status and <paramref name="senseBuffer"/> contains SCSI sense</param>
|
||||
internal static int SendScsiCommand(int fd, byte[] cdb, ref byte[] buffer, out byte[] senseBuffer, uint timeout, ScsiIoctlDirection direction, out double duration, out bool sense)
|
||||
internal static int SendScsiCommand(int fd, byte[] cdb, ref byte[] buffer, out byte[] senseBuffer, uint timeout,
|
||||
ScsiIoctlDirection direction, out double duration, out bool sense)
|
||||
{
|
||||
senseBuffer = null;
|
||||
duration = 0;
|
||||
sense = false;
|
||||
|
||||
if(buffer == null)
|
||||
return -1;
|
||||
if(buffer == null) return -1;
|
||||
|
||||
sg_io_hdr_t io_hdr = new sg_io_hdr_t();
|
||||
|
||||
@@ -82,8 +82,7 @@ namespace DiscImageChef.Devices.Linux
|
||||
int error = Extern.ioctlSg(fd, LinuxIoctl.SG_IO, ref io_hdr);
|
||||
DateTime end = DateTime.UtcNow;
|
||||
|
||||
if(error < 0)
|
||||
error = Marshal.GetLastWin32Error();
|
||||
if(error < 0) error = Marshal.GetLastWin32Error();
|
||||
|
||||
Marshal.Copy(io_hdr.dxferp, buffer, 0, buffer.Length);
|
||||
Marshal.Copy(io_hdr.cmdp, cdb, 0, cdb.Length);
|
||||
@@ -91,10 +90,8 @@ namespace DiscImageChef.Devices.Linux
|
||||
|
||||
sense |= (io_hdr.info & SgInfo.OkMask) != SgInfo.Ok;
|
||||
|
||||
if(io_hdr.duration > 0)
|
||||
duration = io_hdr.duration;
|
||||
else
|
||||
duration = (end - start).TotalMilliseconds;
|
||||
if(io_hdr.duration > 0) duration = io_hdr.duration;
|
||||
else duration = (end - start).TotalMilliseconds;
|
||||
|
||||
Marshal.FreeHGlobal(io_hdr.dxferp);
|
||||
Marshal.FreeHGlobal(io_hdr.cmdp);
|
||||
@@ -112,36 +109,30 @@ namespace DiscImageChef.Devices.Linux
|
||||
case AtaProtocol.HardReset:
|
||||
case AtaProtocol.NonData:
|
||||
case AtaProtocol.SoftReset:
|
||||
case AtaProtocol.ReturnResponse:
|
||||
return ScsiIoctlDirection.None;
|
||||
case AtaProtocol.ReturnResponse: return ScsiIoctlDirection.None;
|
||||
case AtaProtocol.PioIn:
|
||||
case AtaProtocol.UDmaIn:
|
||||
return ScsiIoctlDirection.In;
|
||||
case AtaProtocol.UDmaIn: return ScsiIoctlDirection.In;
|
||||
case AtaProtocol.PioOut:
|
||||
case AtaProtocol.UDmaOut:
|
||||
return ScsiIoctlDirection.Out;
|
||||
default:
|
||||
return ScsiIoctlDirection.Unspecified;
|
||||
case AtaProtocol.UDmaOut: return ScsiIoctlDirection.Out;
|
||||
default: return ScsiIoctlDirection.Unspecified;
|
||||
}
|
||||
}
|
||||
|
||||
internal static int SendAtaCommand(int 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(int fd, AtaRegistersCHS registers, out AtaErrorRegistersCHS errorRegisters,
|
||||
AtaProtocol protocol, AtaTransferRegister transferRegister,
|
||||
ref byte[] buffer, uint timeout, bool transferBlocks, out double duration,
|
||||
out bool sense)
|
||||
{
|
||||
duration = 0;
|
||||
sense = false;
|
||||
errorRegisters = new AtaErrorRegistersCHS();
|
||||
|
||||
if(buffer == null)
|
||||
return -1;
|
||||
if(buffer == null) return -1;
|
||||
|
||||
byte[] cdb = new byte[16];
|
||||
cdb[0] = (byte)ScsiCommands.AtaPassThrough16;
|
||||
cdb[1] = (byte)(((byte)protocol << 1) & 0x1E);
|
||||
if(transferRegister != AtaTransferRegister.NoTransfer &&
|
||||
protocol != AtaProtocol.NonData)
|
||||
if(transferRegister != AtaTransferRegister.NoTransfer && protocol != AtaProtocol.NonData)
|
||||
{
|
||||
switch(protocol)
|
||||
{
|
||||
@@ -154,8 +145,7 @@ namespace DiscImageChef.Devices.Linux
|
||||
break;
|
||||
}
|
||||
|
||||
if(transferBlocks)
|
||||
cdb[2] |= 0x04;
|
||||
if(transferBlocks) cdb[2] |= 0x04;
|
||||
|
||||
cdb[2] |= (byte)((int)transferRegister & 0x03);
|
||||
}
|
||||
@@ -171,10 +161,10 @@ namespace DiscImageChef.Devices.Linux
|
||||
cdb[14] = registers.command;
|
||||
|
||||
byte[] senseBuffer;
|
||||
int error = SendScsiCommand(fd, cdb, ref buffer, out senseBuffer, timeout, AtaProtocolToScsiDirection(protocol), out duration, out sense);
|
||||
int error = SendScsiCommand(fd, cdb, ref buffer, out senseBuffer, timeout,
|
||||
AtaProtocolToScsiDirection(protocol), out duration, out sense);
|
||||
|
||||
if(senseBuffer.Length < 22 || (senseBuffer[8] != 0x09 && senseBuffer[9] != 0x0C))
|
||||
return error;
|
||||
if(senseBuffer.Length < 22 || (senseBuffer[8] != 0x09 && senseBuffer[9] != 0x0C)) return error;
|
||||
|
||||
errorRegisters.error = senseBuffer[11];
|
||||
|
||||
@@ -191,22 +181,20 @@ namespace DiscImageChef.Devices.Linux
|
||||
}
|
||||
|
||||
internal static int SendAtaCommand(int fd, AtaRegistersLBA28 registers,
|
||||
out AtaErrorRegistersLBA28 errorRegisters, AtaProtocol protocol,
|
||||
AtaTransferRegister transferRegister, ref byte[] buffer, uint timeout,
|
||||
bool transferBlocks, out double duration, out bool sense)
|
||||
out AtaErrorRegistersLBA28 errorRegisters, AtaProtocol protocol,
|
||||
AtaTransferRegister transferRegister, ref byte[] buffer, uint timeout,
|
||||
bool transferBlocks, out double duration, out bool sense)
|
||||
{
|
||||
duration = 0;
|
||||
sense = false;
|
||||
errorRegisters = new AtaErrorRegistersLBA28();
|
||||
|
||||
if(buffer == null)
|
||||
return -1;
|
||||
if(buffer == null) return -1;
|
||||
|
||||
byte[] cdb = new byte[16];
|
||||
cdb[0] = (byte)ScsiCommands.AtaPassThrough16;
|
||||
cdb[1] = (byte)(((byte)protocol << 1) & 0x1E);
|
||||
if(transferRegister != AtaTransferRegister.NoTransfer &&
|
||||
protocol != AtaProtocol.NonData)
|
||||
if(transferRegister != AtaTransferRegister.NoTransfer && protocol != AtaProtocol.NonData)
|
||||
{
|
||||
switch(protocol)
|
||||
{
|
||||
@@ -219,8 +207,7 @@ namespace DiscImageChef.Devices.Linux
|
||||
break;
|
||||
}
|
||||
|
||||
if(transferBlocks)
|
||||
cdb[2] |= 0x04;
|
||||
if(transferBlocks) cdb[2] |= 0x04;
|
||||
|
||||
cdb[2] |= (byte)((int)transferRegister & 0x03);
|
||||
}
|
||||
@@ -236,10 +223,10 @@ namespace DiscImageChef.Devices.Linux
|
||||
cdb[14] = registers.command;
|
||||
|
||||
byte[] senseBuffer;
|
||||
int error = SendScsiCommand(fd, cdb, ref buffer, out senseBuffer, timeout, AtaProtocolToScsiDirection(protocol), out duration, out sense);
|
||||
int error = SendScsiCommand(fd, cdb, ref buffer, out senseBuffer, timeout,
|
||||
AtaProtocolToScsiDirection(protocol), out duration, out sense);
|
||||
|
||||
if(senseBuffer.Length < 22 || (senseBuffer[8] != 0x09 && senseBuffer[9] != 0x0C))
|
||||
return error;
|
||||
if(senseBuffer.Length < 22 || (senseBuffer[8] != 0x09 && senseBuffer[9] != 0x0C)) return error;
|
||||
|
||||
errorRegisters.error = senseBuffer[11];
|
||||
|
||||
@@ -256,23 +243,21 @@ namespace DiscImageChef.Devices.Linux
|
||||
}
|
||||
|
||||
internal static int SendAtaCommand(int fd, AtaRegistersLBA48 registers,
|
||||
out AtaErrorRegistersLBA48 errorRegisters, AtaProtocol protocol,
|
||||
AtaTransferRegister transferRegister, ref byte[] buffer, uint timeout,
|
||||
bool transferBlocks, out double duration, out bool sense)
|
||||
out AtaErrorRegistersLBA48 errorRegisters, AtaProtocol protocol,
|
||||
AtaTransferRegister transferRegister, ref byte[] buffer, uint timeout,
|
||||
bool transferBlocks, out double duration, out bool sense)
|
||||
{
|
||||
duration = 0;
|
||||
sense = false;
|
||||
errorRegisters = new AtaErrorRegistersLBA48();
|
||||
|
||||
if(buffer == null)
|
||||
return -1;
|
||||
if(buffer == null) return -1;
|
||||
|
||||
byte[] cdb = new byte[16];
|
||||
cdb[0] = (byte)ScsiCommands.AtaPassThrough16;
|
||||
cdb[1] = (byte)(((byte)protocol << 1) & 0x1E);
|
||||
cdb[1] |= 0x01;
|
||||
if(transferRegister != AtaTransferRegister.NoTransfer &&
|
||||
protocol != AtaProtocol.NonData)
|
||||
if(transferRegister != AtaTransferRegister.NoTransfer && protocol != AtaProtocol.NonData)
|
||||
{
|
||||
switch(protocol)
|
||||
{
|
||||
@@ -285,8 +270,7 @@ namespace DiscImageChef.Devices.Linux
|
||||
break;
|
||||
}
|
||||
|
||||
if(transferBlocks)
|
||||
cdb[2] |= 0x04;
|
||||
if(transferBlocks) cdb[2] |= 0x04;
|
||||
|
||||
cdb[2] |= (byte)((int)transferRegister & 0x03);
|
||||
}
|
||||
@@ -307,10 +291,10 @@ namespace DiscImageChef.Devices.Linux
|
||||
cdb[14] = registers.command;
|
||||
|
||||
byte[] senseBuffer;
|
||||
int error = SendScsiCommand(fd, cdb, ref buffer, out senseBuffer, timeout, AtaProtocolToScsiDirection(protocol), out duration, out sense);
|
||||
int error = SendScsiCommand(fd, cdb, ref buffer, out senseBuffer, timeout,
|
||||
AtaProtocolToScsiDirection(protocol), out duration, out sense);
|
||||
|
||||
if(senseBuffer.Length < 22 || (senseBuffer[8] != 0x09 && senseBuffer[9] != 0x0C))
|
||||
return error;
|
||||
if(senseBuffer.Length < 22 || (senseBuffer[8] != 0x09 && senseBuffer[9] != 0x0C)) return error;
|
||||
|
||||
errorRegisters.error = senseBuffer[11];
|
||||
|
||||
@@ -345,14 +329,15 @@ namespace DiscImageChef.Devices.Linux
|
||||
/// <param name="argument">Command argument</param>
|
||||
/// <param name="response">Response registers</param>
|
||||
/// <param name="blockSize">Size of block in bytes</param>
|
||||
internal static int SendMmcCommand(int 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(int 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)
|
||||
{
|
||||
response = null;
|
||||
duration = 0;
|
||||
sense = false;
|
||||
|
||||
if(buffer == null)
|
||||
return -1;
|
||||
if(buffer == null) return -1;
|
||||
|
||||
mmc_ioc_cmd io_cmd = new mmc_ioc_cmd();
|
||||
|
||||
@@ -380,8 +365,7 @@ namespace DiscImageChef.Devices.Linux
|
||||
|
||||
sense |= error < 0;
|
||||
|
||||
if(error < 0)
|
||||
error = Marshal.GetLastWin32Error();
|
||||
if(error < 0) error = Marshal.GetLastWin32Error();
|
||||
|
||||
Marshal.Copy(bufPtr, buffer, 0, buffer.Length);
|
||||
|
||||
@@ -401,16 +385,14 @@ namespace DiscImageChef.Devices.Linux
|
||||
if(Interop.DetectOS.Is64Bit())
|
||||
{
|
||||
long result64 = Extern.readlink64(path, buf, 4096);
|
||||
if(result64 <= 0)
|
||||
return null;
|
||||
if(result64 <= 0) return null;
|
||||
|
||||
resultSize = (int)result64;
|
||||
}
|
||||
else
|
||||
{
|
||||
int result = Extern.readlink(path, buf, 4096);
|
||||
if(result <= 0)
|
||||
return null;
|
||||
if(result <= 0) return null;
|
||||
|
||||
resultSize = result;
|
||||
}
|
||||
@@ -421,5 +403,4 @@ namespace DiscImageChef.Devices.Linux
|
||||
return System.Text.Encoding.ASCII.GetString(resultString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -182,5 +182,4 @@ namespace DiscImageChef.Devices.Linux
|
||||
/// </summary>
|
||||
MixedIo = 0x04
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -39,10 +39,7 @@ namespace DiscImageChef.Devices.Linux
|
||||
static class Extern
|
||||
{
|
||||
[DllImport("libc", CharSet = CharSet.Ansi, SetLastError = true)]
|
||||
internal static extern int open(
|
||||
string pathname,
|
||||
[MarshalAs(UnmanagedType.U4)]
|
||||
FileFlags flags);
|
||||
internal static extern int open(string pathname, [MarshalAs(UnmanagedType.U4)] FileFlags flags);
|
||||
|
||||
[DllImport("libc")]
|
||||
internal static extern int close(int fd);
|
||||
@@ -66,10 +63,10 @@ namespace DiscImageChef.Devices.Linux
|
||||
internal static extern IntPtr udev_new();
|
||||
|
||||
[DllImport("libudev", CharSet = CharSet.Ansi, SetLastError = true)]
|
||||
internal static extern IntPtr udev_device_new_from_subsystem_sysname(IntPtr udev, string subsystem, string sysname);
|
||||
internal static extern IntPtr udev_device_new_from_subsystem_sysname(
|
||||
IntPtr udev, string subsystem, string sysname);
|
||||
|
||||
[DllImport("libudev", CharSet = CharSet.Ansi, SetLastError = true)]
|
||||
internal static extern string udev_device_get_property_value(IntPtr udev_device, string key);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -55,10 +55,7 @@ namespace DiscImageChef.Devices.Linux
|
||||
udev = Extern.udev_new();
|
||||
hasUdev = udev != IntPtr.Zero;
|
||||
}
|
||||
catch
|
||||
{
|
||||
hasUdev = false;
|
||||
}
|
||||
catch { hasUdev = false; }
|
||||
|
||||
for(int i = 0; i < sysdevs.Length; i++)
|
||||
{
|
||||
@@ -67,11 +64,11 @@ namespace DiscImageChef.Devices.Linux
|
||||
|
||||
if(hasUdev)
|
||||
{
|
||||
udevDev = Extern.udev_device_new_from_subsystem_sysname(udev, "block", Path.GetFileName(sysdevs[i]));
|
||||
udevDev = Extern.udev_device_new_from_subsystem_sysname(udev, "block",
|
||||
Path.GetFileName(sysdevs[i]));
|
||||
devices[i].vendor = Extern.udev_device_get_property_value(udevDev, "ID_VENDOR");
|
||||
devices[i].model = Extern.udev_device_get_property_value(udevDev, "ID_MODEL");
|
||||
if(!string.IsNullOrEmpty(devices[i].model))
|
||||
devices[i].model = devices[i].model.Replace('_', ' ');
|
||||
if(!string.IsNullOrEmpty(devices[i].model)) devices[i].model = devices[i].model.Replace('_', ' ');
|
||||
devices[i].serial = Extern.udev_device_get_property_value(udevDev, "ID_SCSI_SERIAL");
|
||||
if(string.IsNullOrEmpty(devices[i].serial))
|
||||
devices[i].serial = Extern.udev_device_get_property_value(udevDev, "ID_SERIAL_SHORT");
|
||||
@@ -86,7 +83,8 @@ namespace DiscImageChef.Devices.Linux
|
||||
else if(devices[i].path.StartsWith("/dev/loop", StringComparison.CurrentCulture))
|
||||
devices[i].vendor = "Linux";
|
||||
|
||||
if(File.Exists(Path.Combine(sysdevs[i], "device/model")) && (string.IsNullOrEmpty(devices[i].model) || devices[i].bus == "ata"))
|
||||
if(File.Exists(Path.Combine(sysdevs[i], "device/model")) &&
|
||||
(string.IsNullOrEmpty(devices[i].model) || devices[i].bus == "ata"))
|
||||
{
|
||||
sr = new StreamReader(Path.Combine(sysdevs[i], "device/model"), Encoding.ASCII);
|
||||
devices[i].model = sr.ReadLine().Trim();
|
||||
@@ -123,8 +121,7 @@ namespace DiscImageChef.Devices.Linux
|
||||
else if(devices[i].path.StartsWith("/dev/mmc", StringComparison.CurrentCulture))
|
||||
devices[i].bus = "MMC/SD";
|
||||
}
|
||||
else
|
||||
devices[i].bus = devices[i].bus.ToUpper();
|
||||
else devices[i].bus = devices[i].bus.ToUpper();
|
||||
|
||||
switch(devices[i].bus)
|
||||
{
|
||||
@@ -143,4 +140,4 @@ namespace DiscImageChef.Devices.Linux
|
||||
return devices;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -42,28 +42,28 @@ namespace DiscImageChef.Devices.Linux
|
||||
/// <summary>
|
||||
/// Always 'S' for SG v3
|
||||
/// </summary>
|
||||
public int interface_id; /* [i] 'S' (required) */
|
||||
public ScsiIoctlDirection dxfer_direction; /* [i] */
|
||||
public byte cmd_len; /* [i] */
|
||||
public byte mx_sb_len; /* [i] */
|
||||
public int interface_id; /* [i] 'S' (required) */
|
||||
public ScsiIoctlDirection dxfer_direction; /* [i] */
|
||||
public byte cmd_len; /* [i] */
|
||||
public byte mx_sb_len; /* [i] */
|
||||
public ushort iovec_count; /* [i] */
|
||||
public uint dxfer_len; /* [i] */
|
||||
public IntPtr dxferp; /* [i], [*io] */
|
||||
public IntPtr cmdp; /* [i], [*i] */
|
||||
public IntPtr sbp; /* [i], [*o] */
|
||||
public uint timeout; /* [i] unit: millisecs */
|
||||
public uint flags; /* [i] */
|
||||
public int pack_id; /* [i->o] */
|
||||
public IntPtr usr_ptr; /* [i->o] */
|
||||
public byte status; /* [o] */
|
||||
public byte masked_status;/* [o] */
|
||||
public byte msg_status; /* [o] */
|
||||
public byte sb_len_wr; /* [o] */
|
||||
public uint dxfer_len; /* [i] */
|
||||
public IntPtr dxferp; /* [i], [*io] */
|
||||
public IntPtr cmdp; /* [i], [*i] */
|
||||
public IntPtr sbp; /* [i], [*o] */
|
||||
public uint timeout; /* [i] unit: millisecs */
|
||||
public uint flags; /* [i] */
|
||||
public int pack_id; /* [i->o] */
|
||||
public IntPtr usr_ptr; /* [i->o] */
|
||||
public byte status; /* [o] */
|
||||
public byte masked_status; /* [o] */
|
||||
public byte msg_status; /* [o] */
|
||||
public byte sb_len_wr; /* [o] */
|
||||
public ushort host_status; /* [o] */
|
||||
public ushort driver_status;/* [o] */
|
||||
public int resid; /* [o] */
|
||||
public uint duration; /* [o] */
|
||||
public SgInfo info; /* [o] */
|
||||
public ushort driver_status; /* [o] */
|
||||
public int resid; /* [o] */
|
||||
public uint duration; /* [o] */
|
||||
public SgInfo info; /* [o] */
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
@@ -82,8 +82,7 @@ namespace DiscImageChef.Devices.Linux
|
||||
/// <summary>
|
||||
/// CMD response
|
||||
/// </summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
|
||||
public uint[] response;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public uint[] response;
|
||||
public MmcFlags flags;
|
||||
public uint blksz;
|
||||
public uint blocks;
|
||||
@@ -122,5 +121,4 @@ namespace DiscImageChef.Devices.Linux
|
||||
/// </summary>
|
||||
public ulong data_ptr;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -54,5 +54,4 @@ using System.Reflection;
|
||||
// if desired. See the Mono documentation for more information about signing.
|
||||
|
||||
//[assembly: AssemblyDelaySign(false)]
|
||||
//[assembly: AssemblyKeyFile("")]
|
||||
|
||||
//[assembly: AssemblyKeyFile("")]
|
||||
@@ -53,14 +53,15 @@ namespace DiscImageChef.Devices.Windows
|
||||
/// <param name="direction">SCSI command transfer direction</param>
|
||||
/// <param name="duration">Time it took to execute the command in milliseconds</param>
|
||||
/// <param name="sense"><c>True</c> if SCSI error returned non-OK status and <paramref name="senseBuffer"/> contains SCSI sense</param>
|
||||
internal static int SendScsiCommand(SafeFileHandle fd, byte[] cdb, ref byte[] buffer, out byte[] senseBuffer, uint timeout, ScsiIoctlDirection direction, out double duration, out bool sense)
|
||||
internal static int SendScsiCommand(SafeFileHandle fd, byte[] cdb, ref byte[] buffer, out byte[] senseBuffer,
|
||||
uint timeout, ScsiIoctlDirection direction, out double duration,
|
||||
out bool sense)
|
||||
{
|
||||
senseBuffer = null;
|
||||
duration = 0;
|
||||
sense = false;
|
||||
|
||||
if(buffer == null)
|
||||
return -1;
|
||||
if(buffer == null) return -1;
|
||||
|
||||
ScsiPassThroughDirectAndSenseBuffer sptd_sb = new ScsiPassThroughDirectAndSenseBuffer();
|
||||
sptd_sb.sptd = new ScsiPassThroughDirect();
|
||||
@@ -82,12 +83,12 @@ namespace DiscImageChef.Devices.Windows
|
||||
Marshal.Copy(buffer, 0, sptd_sb.sptd.DataBuffer, buffer.Length);
|
||||
|
||||
DateTime start = DateTime.Now;
|
||||
bool hasError = !Extern.DeviceIoControlScsi(fd, WindowsIoctl.IOCTL_SCSI_PASS_THROUGH_DIRECT, ref sptd_sb, (uint)Marshal.SizeOf(sptd_sb), ref sptd_sb,
|
||||
(uint)Marshal.SizeOf(sptd_sb), ref k, IntPtr.Zero);
|
||||
bool hasError = !Extern.DeviceIoControlScsi(fd, WindowsIoctl.IOCTL_SCSI_PASS_THROUGH_DIRECT, ref sptd_sb,
|
||||
(uint)Marshal.SizeOf(sptd_sb), ref sptd_sb,
|
||||
(uint)Marshal.SizeOf(sptd_sb), ref k, IntPtr.Zero);
|
||||
DateTime end = DateTime.Now;
|
||||
|
||||
if(hasError)
|
||||
error = Marshal.GetLastWin32Error();
|
||||
if(hasError) error = Marshal.GetLastWin32Error();
|
||||
|
||||
Marshal.Copy(sptd_sb.sptd.DataBuffer, buffer, 0, buffer.Length);
|
||||
|
||||
@@ -103,15 +104,15 @@ namespace DiscImageChef.Devices.Windows
|
||||
return error;
|
||||
}
|
||||
|
||||
internal static int SendAtaCommand(SafeFileHandle fd, AtaRegistersCHS registers, out AtaErrorRegistersCHS errorRegisters,
|
||||
AtaProtocol protocol, ref byte[] buffer, uint timeout, out double duration, out bool sense)
|
||||
internal static int SendAtaCommand(SafeFileHandle fd, AtaRegistersCHS registers,
|
||||
out AtaErrorRegistersCHS errorRegisters, AtaProtocol protocol,
|
||||
ref byte[] buffer, uint timeout, out double duration, out bool sense)
|
||||
{
|
||||
duration = 0;
|
||||
sense = false;
|
||||
errorRegisters = new AtaErrorRegistersCHS();
|
||||
|
||||
if(buffer == null)
|
||||
return -1;
|
||||
if(buffer == null) return -1;
|
||||
|
||||
uint offsetForBuffer = (uint)(Marshal.SizeOf(typeof(AtaPassThroughDirect)) + Marshal.SizeOf(typeof(uint)));
|
||||
|
||||
@@ -138,7 +139,7 @@ namespace DiscImageChef.Devices.Windows
|
||||
dataBuffer = new byte[64 * 512]
|
||||
};
|
||||
|
||||
if (protocol == AtaProtocol.PioIn || protocol == AtaProtocol.UDmaIn || protocol == AtaProtocol.Dma)
|
||||
if(protocol == AtaProtocol.PioIn || protocol == AtaProtocol.UDmaIn || protocol == AtaProtocol.Dma)
|
||||
aptd_buf.aptd.AtaFlags = AtaFlags.DataIn;
|
||||
else if(protocol == AtaProtocol.PioOut || protocol == AtaProtocol.UDmaOut)
|
||||
aptd_buf.aptd.AtaFlags = AtaFlags.DataOut;
|
||||
@@ -163,12 +164,12 @@ namespace DiscImageChef.Devices.Windows
|
||||
Array.Copy(buffer, 0, aptd_buf.dataBuffer, 0, buffer.Length);
|
||||
|
||||
DateTime start = DateTime.Now;
|
||||
sense = !Extern.DeviceIoControlAta(fd, WindowsIoctl.IOCTL_ATA_PASS_THROUGH, ref aptd_buf, (uint)Marshal.SizeOf(aptd_buf), ref aptd_buf,
|
||||
(uint)Marshal.SizeOf(aptd_buf), ref k, IntPtr.Zero);
|
||||
sense = !Extern.DeviceIoControlAta(fd, WindowsIoctl.IOCTL_ATA_PASS_THROUGH, ref aptd_buf,
|
||||
(uint)Marshal.SizeOf(aptd_buf), ref aptd_buf,
|
||||
(uint)Marshal.SizeOf(aptd_buf), ref k, IntPtr.Zero);
|
||||
DateTime end = DateTime.Now;
|
||||
|
||||
if(sense)
|
||||
error = Marshal.GetLastWin32Error();
|
||||
if(sense) error = Marshal.GetLastWin32Error();
|
||||
|
||||
Array.Copy(aptd_buf.dataBuffer, 0, buffer, 0, buffer.Length);
|
||||
|
||||
@@ -188,15 +189,15 @@ namespace DiscImageChef.Devices.Windows
|
||||
return error;
|
||||
}
|
||||
|
||||
internal static int SendAtaCommand(SafeFileHandle fd, AtaRegistersLBA28 registers, out AtaErrorRegistersLBA28 errorRegisters,
|
||||
AtaProtocol protocol, ref byte[] buffer, uint timeout, out double duration, out bool sense)
|
||||
internal static int SendAtaCommand(SafeFileHandle fd, AtaRegistersLBA28 registers,
|
||||
out AtaErrorRegistersLBA28 errorRegisters, AtaProtocol protocol,
|
||||
ref byte[] buffer, uint timeout, out double duration, out bool sense)
|
||||
{
|
||||
duration = 0;
|
||||
sense = false;
|
||||
errorRegisters = new AtaErrorRegistersLBA28();
|
||||
|
||||
if(buffer == null)
|
||||
return -1;
|
||||
if(buffer == null) return -1;
|
||||
|
||||
uint offsetForBuffer = (uint)(Marshal.SizeOf(typeof(AtaPassThroughDirect)) + Marshal.SizeOf(typeof(uint)));
|
||||
|
||||
@@ -248,12 +249,12 @@ namespace DiscImageChef.Devices.Windows
|
||||
Array.Copy(buffer, 0, aptd_buf.dataBuffer, 0, buffer.Length);
|
||||
|
||||
DateTime start = DateTime.Now;
|
||||
sense = !Extern.DeviceIoControlAta(fd, WindowsIoctl.IOCTL_ATA_PASS_THROUGH, ref aptd_buf, (uint)Marshal.SizeOf(aptd_buf), ref aptd_buf,
|
||||
(uint)Marshal.SizeOf(aptd_buf), ref k, IntPtr.Zero);
|
||||
sense = !Extern.DeviceIoControlAta(fd, WindowsIoctl.IOCTL_ATA_PASS_THROUGH, ref aptd_buf,
|
||||
(uint)Marshal.SizeOf(aptd_buf), ref aptd_buf,
|
||||
(uint)Marshal.SizeOf(aptd_buf), ref k, IntPtr.Zero);
|
||||
DateTime end = DateTime.Now;
|
||||
|
||||
if(sense)
|
||||
error = Marshal.GetLastWin32Error();
|
||||
if(sense) error = Marshal.GetLastWin32Error();
|
||||
|
||||
Array.Copy(aptd_buf.dataBuffer, 0, buffer, 0, buffer.Length);
|
||||
|
||||
@@ -273,15 +274,15 @@ namespace DiscImageChef.Devices.Windows
|
||||
return error;
|
||||
}
|
||||
|
||||
internal static int SendAtaCommand(SafeFileHandle fd, AtaRegistersLBA48 registers, out AtaErrorRegistersLBA48 errorRegisters,
|
||||
AtaProtocol protocol, ref byte[] buffer, uint timeout, out double duration, out bool sense)
|
||||
internal static int SendAtaCommand(SafeFileHandle fd, AtaRegistersLBA48 registers,
|
||||
out AtaErrorRegistersLBA48 errorRegisters, AtaProtocol protocol,
|
||||
ref byte[] buffer, uint timeout, out double duration, out bool sense)
|
||||
{
|
||||
duration = 0;
|
||||
sense = false;
|
||||
errorRegisters = new AtaErrorRegistersLBA48();
|
||||
|
||||
if(buffer == null)
|
||||
return -1;
|
||||
if(buffer == null) return -1;
|
||||
|
||||
uint offsetForBuffer = (uint)(Marshal.SizeOf(typeof(AtaPassThroughDirect)) + Marshal.SizeOf(typeof(uint)));
|
||||
|
||||
@@ -293,14 +294,15 @@ namespace DiscImageChef.Devices.Windows
|
||||
DataBuffer = (IntPtr)offsetForBuffer,
|
||||
Length = (ushort)Marshal.SizeOf(typeof(AtaPassThroughDirect)),
|
||||
DataTransferLength = (uint)buffer.Length,
|
||||
PreviousTaskFile = new AtaTaskFile
|
||||
{
|
||||
CylinderHigh = (byte)((registers.lbaHigh & 0xFF00) >> 8),
|
||||
CylinderLow = (byte)((registers.lbaMid & 0xFF00) >> 8),
|
||||
Features = (byte)((registers.feature & 0xFF00) >> 8),
|
||||
SectorCount = (byte)((registers.sectorCount & 0xFF00) >> 8),
|
||||
SectorNumber = (byte)((registers.lbaLow & 0xFF00) >> 8)
|
||||
},
|
||||
PreviousTaskFile =
|
||||
new AtaTaskFile
|
||||
{
|
||||
CylinderHigh = (byte)((registers.lbaHigh & 0xFF00) >> 8),
|
||||
CylinderLow = (byte)((registers.lbaMid & 0xFF00) >> 8),
|
||||
Features = (byte)((registers.feature & 0xFF00) >> 8),
|
||||
SectorCount = (byte)((registers.sectorCount & 0xFF00) >> 8),
|
||||
SectorNumber = (byte)((registers.lbaLow & 0xFF00) >> 8)
|
||||
},
|
||||
CurrentTaskFile = new AtaTaskFile
|
||||
{
|
||||
Command = registers.command,
|
||||
@@ -340,21 +342,25 @@ namespace DiscImageChef.Devices.Windows
|
||||
Array.Copy(buffer, 0, aptd_buf.dataBuffer, 0, buffer.Length);
|
||||
|
||||
DateTime start = DateTime.Now;
|
||||
sense = !Extern.DeviceIoControlAta(fd, WindowsIoctl.IOCTL_ATA_PASS_THROUGH, ref aptd_buf, (uint)Marshal.SizeOf(aptd_buf), ref aptd_buf,
|
||||
(uint)Marshal.SizeOf(aptd_buf), ref k, IntPtr.Zero);
|
||||
sense = !Extern.DeviceIoControlAta(fd, WindowsIoctl.IOCTL_ATA_PASS_THROUGH, ref aptd_buf,
|
||||
(uint)Marshal.SizeOf(aptd_buf), ref aptd_buf,
|
||||
(uint)Marshal.SizeOf(aptd_buf), ref k, IntPtr.Zero);
|
||||
DateTime end = DateTime.Now;
|
||||
|
||||
if(sense)
|
||||
error = Marshal.GetLastWin32Error();
|
||||
if(sense) error = Marshal.GetLastWin32Error();
|
||||
|
||||
Array.Copy(aptd_buf.dataBuffer, 0, buffer, 0, buffer.Length);
|
||||
|
||||
duration = (end - start).TotalMilliseconds;
|
||||
|
||||
errorRegisters.sectorCount = (ushort)((aptd_buf.aptd.PreviousTaskFile.SectorCount << 8) + aptd_buf.aptd.CurrentTaskFile.SectorCount);
|
||||
errorRegisters.lbaLow = (ushort)((aptd_buf.aptd.PreviousTaskFile.SectorNumber << 8) + aptd_buf.aptd.CurrentTaskFile.SectorNumber);
|
||||
errorRegisters.lbaMid = (ushort)((aptd_buf.aptd.PreviousTaskFile.CylinderLow << 8) + aptd_buf.aptd.CurrentTaskFile.CylinderLow);
|
||||
errorRegisters.lbaHigh = (ushort)((aptd_buf.aptd.PreviousTaskFile.CylinderHigh << 8) + aptd_buf.aptd.CurrentTaskFile.CylinderHigh);
|
||||
errorRegisters.sectorCount = (ushort)((aptd_buf.aptd.PreviousTaskFile.SectorCount << 8) +
|
||||
aptd_buf.aptd.CurrentTaskFile.SectorCount);
|
||||
errorRegisters.lbaLow = (ushort)((aptd_buf.aptd.PreviousTaskFile.SectorNumber << 8) +
|
||||
aptd_buf.aptd.CurrentTaskFile.SectorNumber);
|
||||
errorRegisters.lbaMid = (ushort)((aptd_buf.aptd.PreviousTaskFile.CylinderLow << 8) +
|
||||
aptd_buf.aptd.CurrentTaskFile.CylinderLow);
|
||||
errorRegisters.lbaHigh = (ushort)((aptd_buf.aptd.PreviousTaskFile.CylinderHigh << 8) +
|
||||
aptd_buf.aptd.CurrentTaskFile.CylinderHigh);
|
||||
errorRegisters.command = aptd_buf.aptd.CurrentTaskFile.Command;
|
||||
errorRegisters.deviceHead = aptd_buf.aptd.CurrentTaskFile.DeviceHead;
|
||||
errorRegisters.error = aptd_buf.aptd.CurrentTaskFile.Error;
|
||||
@@ -365,15 +371,15 @@ namespace DiscImageChef.Devices.Windows
|
||||
return error;
|
||||
}
|
||||
|
||||
internal static int SendIdeCommand(SafeFileHandle fd, AtaRegistersCHS registers, out AtaErrorRegistersCHS errorRegisters,
|
||||
AtaProtocol protocol, ref byte[] buffer, uint timeout, out double duration, out bool sense)
|
||||
internal static int SendIdeCommand(SafeFileHandle fd, AtaRegistersCHS registers,
|
||||
out AtaErrorRegistersCHS errorRegisters, AtaProtocol protocol,
|
||||
ref byte[] buffer, uint timeout, out double duration, out bool sense)
|
||||
{
|
||||
duration = 0;
|
||||
sense = false;
|
||||
errorRegisters = new AtaErrorRegistersCHS();
|
||||
|
||||
if(buffer == null || buffer.Length > 512)
|
||||
return -1;
|
||||
if(buffer == null || buffer.Length > 512) return -1;
|
||||
|
||||
IdePassThroughDirect iptd = new IdePassThroughDirect
|
||||
{
|
||||
@@ -397,12 +403,12 @@ namespace DiscImageChef.Devices.Windows
|
||||
Array.Copy(buffer, 0, iptd.DataBuffer, 0, buffer.Length);
|
||||
|
||||
DateTime start = DateTime.Now;
|
||||
sense = !Extern.DeviceIoControlIde(fd, WindowsIoctl.IOCTL_IDE_PASS_THROUGH, ref iptd, (uint)Marshal.SizeOf(iptd), ref iptd,
|
||||
(uint)Marshal.SizeOf(iptd), ref k, IntPtr.Zero);
|
||||
sense = !Extern.DeviceIoControlIde(fd, WindowsIoctl.IOCTL_IDE_PASS_THROUGH, ref iptd,
|
||||
(uint)Marshal.SizeOf(iptd), ref iptd, (uint)Marshal.SizeOf(iptd), ref k,
|
||||
IntPtr.Zero);
|
||||
DateTime end = DateTime.Now;
|
||||
|
||||
if(sense)
|
||||
error = Marshal.GetLastWin32Error();
|
||||
if(sense) error = Marshal.GetLastWin32Error();
|
||||
|
||||
buffer = new byte[k - 12];
|
||||
Array.Copy(iptd.DataBuffer, 0, buffer, 0, buffer.Length);
|
||||
@@ -423,15 +429,15 @@ namespace DiscImageChef.Devices.Windows
|
||||
return error;
|
||||
}
|
||||
|
||||
internal static int SendIdeCommand(SafeFileHandle fd, AtaRegistersLBA28 registers, out AtaErrorRegistersLBA28 errorRegisters,
|
||||
AtaProtocol protocol, ref byte[] buffer, uint timeout, out double duration, out bool sense)
|
||||
internal static int SendIdeCommand(SafeFileHandle fd, AtaRegistersLBA28 registers,
|
||||
out AtaErrorRegistersLBA28 errorRegisters, AtaProtocol protocol,
|
||||
ref byte[] buffer, uint timeout, out double duration, out bool sense)
|
||||
{
|
||||
duration = 0;
|
||||
sense = false;
|
||||
errorRegisters = new AtaErrorRegistersLBA28();
|
||||
|
||||
if(buffer == null)
|
||||
return -1;
|
||||
if(buffer == null) return -1;
|
||||
|
||||
uint offsetForBuffer = (uint)(Marshal.SizeOf(typeof(AtaPassThroughDirect)) + Marshal.SizeOf(typeof(uint)));
|
||||
|
||||
@@ -457,12 +463,12 @@ namespace DiscImageChef.Devices.Windows
|
||||
Array.Copy(buffer, 0, iptd.DataBuffer, 0, buffer.Length);
|
||||
|
||||
DateTime start = DateTime.Now;
|
||||
sense = !Extern.DeviceIoControlIde(fd, WindowsIoctl.IOCTL_IDE_PASS_THROUGH, ref iptd, (uint)Marshal.SizeOf(iptd), ref iptd,
|
||||
(uint)Marshal.SizeOf(iptd), ref k, IntPtr.Zero);
|
||||
sense = !Extern.DeviceIoControlIde(fd, WindowsIoctl.IOCTL_IDE_PASS_THROUGH, ref iptd,
|
||||
(uint)Marshal.SizeOf(iptd), ref iptd, (uint)Marshal.SizeOf(iptd), ref k,
|
||||
IntPtr.Zero);
|
||||
DateTime end = DateTime.Now;
|
||||
|
||||
if(sense)
|
||||
error = Marshal.GetLastWin32Error();
|
||||
if(sense) error = Marshal.GetLastWin32Error();
|
||||
|
||||
buffer = new byte[k - 12];
|
||||
Array.Copy(iptd.DataBuffer, 0, buffer, 0, buffer.Length);
|
||||
@@ -486,13 +492,11 @@ namespace DiscImageChef.Devices.Windows
|
||||
internal static uint GetDeviceNumber(SafeFileHandle deviceHandle)
|
||||
{
|
||||
StorageDeviceNumber sdn = new StorageDeviceNumber();
|
||||
sdn.deviceNumber = - 1;
|
||||
sdn.deviceNumber = -1;
|
||||
uint k = 0;
|
||||
if(!Extern.DeviceIoControlGetDeviceNumber(deviceHandle, WindowsIoctl.IOCTL_STORAGE_GET_DEVICE_NUMBER, IntPtr.Zero,
|
||||
0, ref sdn, (uint)Marshal.SizeOf(sdn), ref k, IntPtr.Zero))
|
||||
{
|
||||
return uint.MaxValue;
|
||||
}
|
||||
if(!Extern.DeviceIoControlGetDeviceNumber(deviceHandle, WindowsIoctl.IOCTL_STORAGE_GET_DEVICE_NUMBER,
|
||||
IntPtr.Zero, 0, ref sdn, (uint)Marshal.SizeOf(sdn), ref k,
|
||||
IntPtr.Zero)) { return uint.MaxValue; }
|
||||
|
||||
return (uint)sdn.deviceNumber;
|
||||
}
|
||||
@@ -501,28 +505,27 @@ namespace DiscImageChef.Devices.Windows
|
||||
{
|
||||
uint devNumber = GetDeviceNumber(fd);
|
||||
|
||||
if(devNumber == uint.MaxValue)
|
||||
return null;
|
||||
if(devNumber == uint.MaxValue) return null;
|
||||
|
||||
SafeFileHandle hDevInfo = Extern.SetupDiGetClassDevs(ref Consts.GUID_DEVINTERFACE_DISK, IntPtr.Zero,
|
||||
IntPtr.Zero, DeviceGetClassFlags.Present | DeviceGetClassFlags.DeviceInterface);
|
||||
IntPtr.Zero,
|
||||
DeviceGetClassFlags.Present |
|
||||
DeviceGetClassFlags.DeviceInterface);
|
||||
|
||||
if(hDevInfo.IsInvalid)
|
||||
return null;
|
||||
if(hDevInfo.IsInvalid) return null;
|
||||
|
||||
uint index = 0;
|
||||
DeviceInterfaceData spdid = new DeviceInterfaceData();
|
||||
spdid.cbSize = Marshal.SizeOf(spdid);
|
||||
|
||||
|
||||
byte[] buffer;
|
||||
|
||||
|
||||
while(true)
|
||||
{
|
||||
buffer = new byte[2048];
|
||||
|
||||
|
||||
if(!Extern.SetupDiEnumDeviceInterfaces(hDevInfo, IntPtr.Zero, ref Consts.GUID_DEVINTERFACE_DISK, index,
|
||||
ref spdid))
|
||||
break;
|
||||
ref spdid)) break;
|
||||
|
||||
uint size = 0;
|
||||
|
||||
@@ -530,13 +533,16 @@ namespace DiscImageChef.Devices.Windows
|
||||
|
||||
if(size > 0 && size < buffer.Length)
|
||||
{
|
||||
buffer[0] = (byte)(IntPtr.Size == 8 ? IntPtr.Size : IntPtr.Size + Marshal.SystemDefaultCharSize); // Funny...
|
||||
buffer[0] = (byte)(IntPtr.Size == 8
|
||||
? IntPtr.Size
|
||||
: IntPtr.Size + Marshal.SystemDefaultCharSize); // Funny...
|
||||
|
||||
IntPtr pspdidd = Marshal.AllocHGlobal(buffer.Length);
|
||||
Marshal.Copy(buffer, 0, pspdidd, buffer.Length);
|
||||
|
||||
bool result =
|
||||
Extern.SetupDiGetDeviceInterfaceDetail(hDevInfo, ref spdid, pspdidd, size, ref size, IntPtr.Zero);
|
||||
Extern.SetupDiGetDeviceInterfaceDetail(hDevInfo, ref spdid, pspdidd, size, ref size,
|
||||
IntPtr.Zero);
|
||||
|
||||
buffer = new byte[size];
|
||||
Marshal.Copy(pspdidd, buffer, 0, buffer.Length);
|
||||
@@ -546,7 +552,7 @@ namespace DiscImageChef.Devices.Windows
|
||||
{
|
||||
string devicePath = Encoding.Unicode.GetString(buffer, 4, (int)size - 4);
|
||||
SafeFileHandle hDrive = Extern.CreateFile(devicePath, 0, FileShare.Read | FileShare.Write,
|
||||
IntPtr.Zero, FileMode.OpenExisting, 0, IntPtr.Zero);
|
||||
IntPtr.Zero, FileMode.OpenExisting, 0, IntPtr.Zero);
|
||||
|
||||
if(!hDrive.IsInvalid)
|
||||
{
|
||||
@@ -558,11 +564,11 @@ namespace DiscImageChef.Devices.Windows
|
||||
return devicePath;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Extern.CloseHandle(hDrive);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
@@ -575,8 +581,8 @@ namespace DiscImageChef.Devices.Windows
|
||||
SffdiskQueryDeviceProtocolData queryData1 = new SffdiskQueryDeviceProtocolData();
|
||||
queryData1.size = (ushort)Marshal.SizeOf(queryData1);
|
||||
uint bytesReturned;
|
||||
Extern.DeviceIoControl(fd, WindowsIoctl.IOCTL_SFFDISK_QUERY_DEVICE_PROTOCOL, IntPtr.Zero, 0,
|
||||
ref queryData1, queryData1.size, out bytesReturned, IntPtr.Zero);
|
||||
Extern.DeviceIoControl(fd, WindowsIoctl.IOCTL_SFFDISK_QUERY_DEVICE_PROTOCOL, IntPtr.Zero, 0, ref queryData1,
|
||||
queryData1.size, out bytesReturned, IntPtr.Zero);
|
||||
return queryData1.protocolGuid.Equals(Consts.GUID_SFF_PROTOCOL_SD);
|
||||
}
|
||||
|
||||
@@ -598,8 +604,9 @@ namespace DiscImageChef.Devices.Windows
|
||||
/// <param name="response">Response registers</param>
|
||||
/// <param name="blockSize">Size of block in bytes</param>
|
||||
internal static int SendMmcCommand(SafeFileHandle 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)
|
||||
MmcFlags flags, uint argument, uint blockSize, uint blocks,
|
||||
ref byte[] buffer, out uint[] response, out double duration, out bool sense,
|
||||
uint timeout = 0)
|
||||
{
|
||||
SffdiskDeviceCommandData commandData = new SffdiskDeviceCommandData();
|
||||
SdCmdDescriptor commandDescriptor = new SdCmdDescriptor();
|
||||
@@ -610,7 +617,9 @@ namespace DiscImageChef.Devices.Windows
|
||||
commandDescriptor.commandCode = (byte)command;
|
||||
commandDescriptor.cmdClass = isApplication ? SdCommandClass.AppCmd : SdCommandClass.Standard;
|
||||
commandDescriptor.transferDirection = write ? SdTransferDirection.Write : SdTransferDirection.Read;
|
||||
commandDescriptor.transferType = flags.HasFlag(MmcFlags.CommandADTC) ? SdTransferType.SingleBlock : SdTransferType.CmdOnly;
|
||||
commandDescriptor.transferType = flags.HasFlag(MmcFlags.CommandADTC)
|
||||
? SdTransferType.SingleBlock
|
||||
: SdTransferType.CmdOnly;
|
||||
commandDescriptor.responseType = 0;
|
||||
|
||||
if(flags.HasFlag(MmcFlags.Response_R1) || flags.HasFlag(MmcFlags.ResponseSPI_R1))
|
||||
@@ -625,10 +634,10 @@ namespace DiscImageChef.Devices.Windows
|
||||
commandDescriptor.responseType = SdResponseType.R4;
|
||||
if(flags.HasFlag(MmcFlags.Response_R5) || flags.HasFlag(MmcFlags.ResponseSPI_R5))
|
||||
commandDescriptor.responseType = SdResponseType.R5;
|
||||
if(flags.HasFlag(MmcFlags.Response_R6))
|
||||
commandDescriptor.responseType = SdResponseType.R6;
|
||||
if(flags.HasFlag(MmcFlags.Response_R6)) commandDescriptor.responseType = SdResponseType.R6;
|
||||
|
||||
byte[] command_b = new byte[commandData.size + commandData.protocolArgumentSize + commandData.deviceDataBufferSize];
|
||||
byte[] command_b = new byte[commandData.size + commandData.protocolArgumentSize +
|
||||
commandData.deviceDataBufferSize];
|
||||
IntPtr hBuf = Marshal.AllocHGlobal(command_b.Length);
|
||||
Marshal.StructureToPtr(commandData, hBuf, true);
|
||||
IntPtr descriptorOffset = new IntPtr(hBuf.ToInt32() + commandData.size);
|
||||
@@ -640,20 +649,19 @@ namespace DiscImageChef.Devices.Windows
|
||||
int error = 0;
|
||||
DateTime start = DateTime.Now;
|
||||
sense = !Extern.DeviceIoControl(fd, WindowsIoctl.IOCTL_SFFDISK_DEVICE_COMMAND, command_b,
|
||||
(uint)command_b.Length, command_b, (uint)command_b.Length, out bytesReturned, IntPtr.Zero);
|
||||
(uint)command_b.Length, command_b, (uint)command_b.Length,
|
||||
out bytesReturned, IntPtr.Zero);
|
||||
DateTime end = DateTime.Now;
|
||||
|
||||
if(sense)
|
||||
error = Marshal.GetLastWin32Error();
|
||||
if(sense) error = Marshal.GetLastWin32Error();
|
||||
|
||||
buffer = new byte[blockSize * blocks];
|
||||
Buffer.BlockCopy(command_b, command_b.Length - buffer.Length, buffer, 0, buffer.Length);
|
||||
|
||||
|
||||
response = new uint[4];
|
||||
duration = (end - start).TotalMilliseconds;
|
||||
|
||||
return error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -343,8 +343,8 @@ namespace DiscImageChef.Devices.Windows
|
||||
IOCTL_STORAGE_QUERY_PROPERTY = 0x2D1400,
|
||||
IOCTL_IDE_PASS_THROUGH = 0x4D028,
|
||||
IOCTL_STORAGE_GET_DEVICE_NUMBER = 0x2D1080,
|
||||
IOCTL_SFFDISK_QUERY_DEVICE_PROTOCOL = 0x71E80,
|
||||
IOCTL_SFFDISK_DEVICE_COMMAND = 0x79E84,
|
||||
IOCTL_SFFDISK_QUERY_DEVICE_PROTOCOL = 0x71E80,
|
||||
IOCTL_SFFDISK_DEVICE_COMMAND = 0x79E84,
|
||||
}
|
||||
|
||||
[Flags]
|
||||
@@ -423,7 +423,7 @@ namespace DiscImageChef.Devices.Windows
|
||||
FileBackedVirtual = 0xF,
|
||||
NVMe = 0x11,
|
||||
}
|
||||
|
||||
|
||||
[Flags]
|
||||
enum DeviceGetClassFlags : uint
|
||||
{
|
||||
@@ -448,7 +448,7 @@ namespace DiscImageChef.Devices.Windows
|
||||
/// </summary>
|
||||
DeviceInterface = 0x10,
|
||||
}
|
||||
|
||||
|
||||
public enum SdCommandClass : uint
|
||||
{
|
||||
Standard,
|
||||
@@ -492,10 +492,11 @@ namespace DiscImageChef.Devices.Windows
|
||||
UnlockChannel,
|
||||
DeviceCommand
|
||||
};
|
||||
|
||||
|
||||
static class Consts
|
||||
{
|
||||
public static Guid GUID_SFF_PROTOCOL_SD = new Guid("AD7536A8-D055-4C40-AA4D-96312DDB6B38");
|
||||
public static Guid GUID_DEVINTERFACE_DISK = new Guid(0x53F56307, 0xB6BF, 0x11D0, 0x94, 0xF2, 0x00, 0xA0, 0xC9, 0x1E, 0xFB, 0x8B);
|
||||
public static Guid GUID_DEVINTERFACE_DISK =
|
||||
new Guid(0x53F56307, 0xB6BF, 0x11D0, 0x94, 0xF2, 0x00, 0xA0, 0xC9, 0x1E, 0xFB, 0x8B);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -40,123 +40,77 @@ namespace DiscImageChef.Devices.Windows
|
||||
static class Extern
|
||||
{
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
internal static extern SafeFileHandle CreateFile(
|
||||
[MarshalAs(UnmanagedType.LPTStr)] string filename,
|
||||
[MarshalAs(UnmanagedType.U4)] FileAccess access,
|
||||
[MarshalAs(UnmanagedType.U4)] FileShare share,
|
||||
IntPtr securityAttributes, // optional SECURITY_ATTRIBUTES struct or IntPtr.Zero
|
||||
[MarshalAs(UnmanagedType.U4)] FileMode creationDisposition,
|
||||
[MarshalAs(UnmanagedType.U4)] FileAttributes flagsAndAttributes,
|
||||
IntPtr templateFile);
|
||||
internal static extern SafeFileHandle CreateFile([MarshalAs(UnmanagedType.LPTStr)] string filename,
|
||||
[MarshalAs(UnmanagedType.U4)] FileAccess access,
|
||||
[MarshalAs(UnmanagedType.U4)] FileShare share,
|
||||
IntPtr securityAttributes, // optional SECURITY_ATTRIBUTES struct or IntPtr.Zero
|
||||
[MarshalAs(UnmanagedType.U4)] FileMode creationDisposition,
|
||||
[MarshalAs(UnmanagedType.U4)]
|
||||
FileAttributes flagsAndAttributes, IntPtr templateFile);
|
||||
|
||||
[DllImport("Kernel32.dll", SetLastError = true, EntryPoint = "DeviceIoControl", CharSet = CharSet.Auto)]
|
||||
internal static extern bool DeviceIoControlScsi(
|
||||
SafeFileHandle hDevice,
|
||||
WindowsIoctl IoControlCode,
|
||||
ref ScsiPassThroughDirectAndSenseBuffer InBuffer,
|
||||
uint nInBufferSize,
|
||||
ref ScsiPassThroughDirectAndSenseBuffer OutBuffer,
|
||||
uint nOutBufferSize,
|
||||
ref uint pBytesReturned,
|
||||
IntPtr Overlapped
|
||||
);
|
||||
internal static extern bool DeviceIoControlScsi(SafeFileHandle hDevice, WindowsIoctl IoControlCode,
|
||||
ref ScsiPassThroughDirectAndSenseBuffer InBuffer,
|
||||
uint nInBufferSize,
|
||||
ref ScsiPassThroughDirectAndSenseBuffer OutBuffer,
|
||||
uint nOutBufferSize, ref uint pBytesReturned,
|
||||
IntPtr Overlapped);
|
||||
|
||||
[DllImport("Kernel32.dll", SetLastError = true, EntryPoint = "DeviceIoControl", CharSet = CharSet.Auto)]
|
||||
internal static extern bool DeviceIoControlAta(
|
||||
SafeFileHandle hDevice,
|
||||
WindowsIoctl IoControlCode,
|
||||
ref AtaPassThroughDirectWithBuffer InBuffer,
|
||||
uint nInBufferSize,
|
||||
ref AtaPassThroughDirectWithBuffer OutBuffer,
|
||||
uint nOutBufferSize,
|
||||
ref uint pBytesReturned,
|
||||
IntPtr Overlapped
|
||||
);
|
||||
internal static extern bool DeviceIoControlAta(SafeFileHandle hDevice, WindowsIoctl IoControlCode,
|
||||
ref AtaPassThroughDirectWithBuffer InBuffer, uint nInBufferSize,
|
||||
ref AtaPassThroughDirectWithBuffer OutBuffer,
|
||||
uint nOutBufferSize, ref uint pBytesReturned, IntPtr Overlapped);
|
||||
|
||||
[DllImport("Kernel32.dll", SetLastError = true, EntryPoint = "DeviceIoControl", CharSet = CharSet.Auto)]
|
||||
internal static extern bool DeviceIoControlStorageQuery(
|
||||
SafeFileHandle hDevice,
|
||||
WindowsIoctl IoControlCode,
|
||||
ref StoragePropertyQuery InBuffer,
|
||||
uint nInBufferSize,
|
||||
IntPtr OutBuffer,
|
||||
uint nOutBufferSize,
|
||||
ref uint pBytesReturned,
|
||||
IntPtr Overlapped
|
||||
);
|
||||
internal static extern bool DeviceIoControlStorageQuery(SafeFileHandle hDevice, WindowsIoctl IoControlCode,
|
||||
ref StoragePropertyQuery InBuffer, uint nInBufferSize,
|
||||
IntPtr OutBuffer, uint nOutBufferSize,
|
||||
ref uint pBytesReturned, IntPtr Overlapped);
|
||||
|
||||
[DllImport("Kernel32.dll", SetLastError = true, EntryPoint = "DeviceIoControl", CharSet = CharSet.Auto)]
|
||||
internal static extern bool DeviceIoControlIde(
|
||||
SafeFileHandle hDevice,
|
||||
WindowsIoctl IoControlCode,
|
||||
ref IdePassThroughDirect InBuffer,
|
||||
uint nInBufferSize,
|
||||
ref IdePassThroughDirect OutBuffer,
|
||||
uint nOutBufferSize,
|
||||
ref uint pBytesReturned,
|
||||
IntPtr Overlapped
|
||||
);
|
||||
internal static extern bool DeviceIoControlIde(SafeFileHandle hDevice, WindowsIoctl IoControlCode,
|
||||
ref IdePassThroughDirect InBuffer, uint nInBufferSize,
|
||||
ref IdePassThroughDirect OutBuffer, uint nOutBufferSize,
|
||||
ref uint pBytesReturned, IntPtr Overlapped);
|
||||
|
||||
[DllImport("Kernel32.dll", SetLastError = true, EntryPoint = "DeviceIoControl", CharSet = CharSet.Auto)]
|
||||
internal static extern bool DeviceIoControlGetDeviceNumber(
|
||||
SafeFileHandle hDevice,
|
||||
WindowsIoctl IoControlCode,
|
||||
IntPtr InBuffer,
|
||||
uint nInBufferSize,
|
||||
ref StorageDeviceNumber OutBuffer,
|
||||
uint nOutBufferSize,
|
||||
ref uint pBytesReturned,
|
||||
IntPtr Overlapped
|
||||
);
|
||||
internal static extern bool DeviceIoControlGetDeviceNumber(SafeFileHandle hDevice, WindowsIoctl IoControlCode,
|
||||
IntPtr InBuffer, uint nInBufferSize,
|
||||
ref StorageDeviceNumber OutBuffer,
|
||||
uint nOutBufferSize, ref uint pBytesReturned,
|
||||
IntPtr Overlapped);
|
||||
|
||||
[DllImport("Kernel32.dll", SetLastError = true, EntryPoint = "DeviceIoControl", CharSet = CharSet.Auto)]
|
||||
internal static extern bool DeviceIoControl(
|
||||
SafeFileHandle hDevice,
|
||||
WindowsIoctl IoControlCode,
|
||||
IntPtr InBuffer,
|
||||
uint nInBufferSize,
|
||||
ref SffdiskQueryDeviceProtocolData OutBuffer,
|
||||
uint nOutBufferSize,
|
||||
out uint pBytesReturned,
|
||||
IntPtr Overlapped
|
||||
);
|
||||
internal static extern bool DeviceIoControl(SafeFileHandle hDevice, WindowsIoctl IoControlCode, IntPtr InBuffer,
|
||||
uint nInBufferSize, ref SffdiskQueryDeviceProtocolData OutBuffer,
|
||||
uint nOutBufferSize, out uint pBytesReturned, IntPtr Overlapped);
|
||||
|
||||
[DllImport("Kernel32.dll", SetLastError = true, EntryPoint = "DeviceIoControl", CharSet = CharSet.Auto)]
|
||||
internal static extern bool DeviceIoControl(SafeFileHandle hDevice, WindowsIoctl IoControlCode, byte[] InBuffer,
|
||||
uint nInBufferSize, byte[] OutBuffer, uint nOutBufferSize, out uint pBytesReturned, IntPtr Overlapped);
|
||||
uint nInBufferSize, byte[] OutBuffer, uint nOutBufferSize,
|
||||
out uint pBytesReturned, IntPtr Overlapped);
|
||||
|
||||
[DllImport("setupapi.dll", CharSet = CharSet.Auto)]
|
||||
internal static extern SafeFileHandle SetupDiGetClassDevs(
|
||||
ref Guid ClassGuid,
|
||||
IntPtr Enumerator,
|
||||
IntPtr hwndParent,
|
||||
DeviceGetClassFlags Flags
|
||||
);
|
||||
|
||||
internal static extern SafeFileHandle SetupDiGetClassDevs(ref Guid ClassGuid, IntPtr Enumerator,
|
||||
IntPtr hwndParent, DeviceGetClassFlags Flags);
|
||||
|
||||
[DllImport("setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
public static extern bool SetupDiEnumDeviceInterfaces(
|
||||
SafeFileHandle hDevInfo,
|
||||
IntPtr devInfo,
|
||||
ref Guid interfaceClassGuid,
|
||||
uint memberIndex,
|
||||
ref DeviceInterfaceData deviceInterfaceData
|
||||
);
|
||||
|
||||
public static extern bool SetupDiEnumDeviceInterfaces(SafeFileHandle hDevInfo, IntPtr devInfo,
|
||||
ref Guid interfaceClassGuid, uint memberIndex,
|
||||
ref DeviceInterfaceData deviceInterfaceData);
|
||||
|
||||
[DllImport("setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
public static extern bool SetupDiGetDeviceInterfaceDetail(
|
||||
SafeFileHandle hDevInfo,
|
||||
ref DeviceInterfaceData deviceInterfaceData,
|
||||
IntPtr deviceInterfaceDetailData,
|
||||
UInt32 deviceInterfaceDetailDataSize,
|
||||
ref UInt32 requiredSize,
|
||||
IntPtr deviceInfoData
|
||||
);
|
||||
|
||||
public static extern bool SetupDiGetDeviceInterfaceDetail(SafeFileHandle hDevInfo,
|
||||
ref DeviceInterfaceData deviceInterfaceData,
|
||||
IntPtr deviceInterfaceDetailData,
|
||||
UInt32 deviceInterfaceDetailDataSize,
|
||||
ref UInt32 requiredSize, IntPtr deviceInfoData);
|
||||
|
||||
[DllImport("setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
public static extern bool SetupDiDestroyDeviceInfoList(SafeFileHandle hDevInfo);
|
||||
|
||||
[DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
||||
internal static extern bool CloseHandle(SafeFileHandle hDevice);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -47,23 +47,21 @@ namespace DiscImageChef.Devices.Windows
|
||||
|
||||
try
|
||||
{
|
||||
ManagementObjectSearcher mgmtObjSearcher = new ManagementObjectSearcher("SELECT * FROM Win32_DiskDrive");
|
||||
ManagementObjectSearcher mgmtObjSearcher =
|
||||
new ManagementObjectSearcher("SELECT * FROM Win32_DiskDrive");
|
||||
ManagementObjectCollection objCol = mgmtObjSearcher.Get();
|
||||
|
||||
foreach (ManagementObject drive in objCol)
|
||||
DeviceIDs.Add((string)drive["DeviceID"]);
|
||||
foreach(ManagementObject drive in objCol) DeviceIDs.Add((string)drive["DeviceID"]);
|
||||
|
||||
mgmtObjSearcher = new ManagementObjectSearcher("SELECT * FROM Win32_TapeDrive");
|
||||
objCol = mgmtObjSearcher.Get();
|
||||
|
||||
foreach (ManagementObject drive in objCol)
|
||||
DeviceIDs.Add((string)drive["DeviceID"]);
|
||||
foreach(ManagementObject drive in objCol) DeviceIDs.Add((string)drive["DeviceID"]);
|
||||
|
||||
mgmtObjSearcher = new ManagementObjectSearcher("SELECT * FROM Win32_CDROMDrive");
|
||||
objCol = mgmtObjSearcher.Get();
|
||||
|
||||
foreach (ManagementObject drive in objCol)
|
||||
DeviceIDs.Add((string)drive["Drive"]);
|
||||
foreach(ManagementObject drive in objCol) DeviceIDs.Add((string)drive["Drive"]);
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
@@ -76,15 +74,14 @@ namespace DiscImageChef.Devices.Windows
|
||||
|
||||
List<DeviceInfo> dev_list = new List<DeviceInfo>();
|
||||
|
||||
foreach (string devId in DeviceIDs)
|
||||
foreach(string devId in DeviceIDs)
|
||||
{
|
||||
string physId = devId;
|
||||
// TODO: This can be done better
|
||||
if (devId.Length == 2 && devId[1] == ':')
|
||||
physId = "\\\\?\\" + devId;
|
||||
SafeFileHandle fd = Extern.CreateFile(physId, 0, FileShare.Read | FileShare.Write, IntPtr.Zero, FileMode.OpenExisting, 0, IntPtr.Zero);
|
||||
if (fd.IsInvalid)
|
||||
continue;
|
||||
if(devId.Length == 2 && devId[1] == ':') physId = "\\\\?\\" + devId;
|
||||
SafeFileHandle fd = Extern.CreateFile(physId, 0, FileShare.Read | FileShare.Write, IntPtr.Zero,
|
||||
FileMode.OpenExisting, 0, IntPtr.Zero);
|
||||
if(fd.IsInvalid) continue;
|
||||
|
||||
StoragePropertyQuery query = new StoragePropertyQuery();
|
||||
query.PropertyId = StoragePropertyId.Device;
|
||||
@@ -100,15 +97,15 @@ namespace DiscImageChef.Devices.Windows
|
||||
uint returned = 0;
|
||||
int error = 0;
|
||||
|
||||
bool hasError = !Extern.DeviceIoControlStorageQuery(fd, WindowsIoctl.IOCTL_STORAGE_QUERY_PROPERTY, ref query, (uint)Marshal.SizeOf(query), descriptorPtr, 1000, ref returned, IntPtr.Zero);
|
||||
bool hasError = !Extern.DeviceIoControlStorageQuery(fd, WindowsIoctl.IOCTL_STORAGE_QUERY_PROPERTY,
|
||||
ref query, (uint)Marshal.SizeOf(query),
|
||||
descriptorPtr, 1000, ref returned, IntPtr.Zero);
|
||||
|
||||
if (hasError)
|
||||
error = Marshal.GetLastWin32Error();
|
||||
if(hasError) error = Marshal.GetLastWin32Error();
|
||||
|
||||
Marshal.Copy(descriptorPtr, descriptor_b, 0, 1000);
|
||||
|
||||
if (hasError && error != 0)
|
||||
continue;
|
||||
if(hasError && error != 0) continue;
|
||||
|
||||
StorageDeviceDescriptor descriptor = new StorageDeviceDescriptor();
|
||||
descriptor.Version = BitConverter.ToUInt32(descriptor_b, 0);
|
||||
@@ -116,7 +113,7 @@ namespace DiscImageChef.Devices.Windows
|
||||
descriptor.DeviceType = descriptor_b[8];
|
||||
descriptor.DeviceTypeModifier = descriptor_b[9];
|
||||
descriptor.RemovableMedia = BitConverter.ToBoolean(descriptor_b, 10);
|
||||
descriptor.CommandQueueing= BitConverter.ToBoolean(descriptor_b, 11);
|
||||
descriptor.CommandQueueing = BitConverter.ToBoolean(descriptor_b, 11);
|
||||
descriptor.VendorIdOffset = BitConverter.ToUInt32(descriptor_b, 12);
|
||||
descriptor.ProductIdOffset = BitConverter.ToUInt32(descriptor_b, 16);
|
||||
descriptor.ProductRevisionOffset = BitConverter.ToUInt32(descriptor_b, 20);
|
||||
@@ -124,31 +121,31 @@ namespace DiscImageChef.Devices.Windows
|
||||
descriptor.BusType = (StorageBusType)BitConverter.ToUInt32(descriptor_b, 28);
|
||||
descriptor.RawPropertiesLength = BitConverter.ToUInt32(descriptor_b, 32);
|
||||
|
||||
DeviceInfo info = new DeviceInfo
|
||||
{
|
||||
path = physId,
|
||||
bus = descriptor.BusType.ToString()
|
||||
};
|
||||
DeviceInfo info = new DeviceInfo {path = physId, bus = descriptor.BusType.ToString()};
|
||||
|
||||
if (descriptor.VendorIdOffset > 0)
|
||||
info.vendor = StringHandlers.CToString(descriptor_b, Encoding.ASCII, start: (int)descriptor.VendorIdOffset);
|
||||
if (descriptor.ProductIdOffset > 0)
|
||||
info.model = StringHandlers.CToString(descriptor_b, Encoding.ASCII, start: (int)descriptor.ProductIdOffset);
|
||||
if(descriptor.VendorIdOffset > 0)
|
||||
info.vendor =
|
||||
StringHandlers.CToString(descriptor_b, Encoding.ASCII, start: (int)descriptor.VendorIdOffset);
|
||||
if(descriptor.ProductIdOffset > 0)
|
||||
info.model =
|
||||
StringHandlers.CToString(descriptor_b, Encoding.ASCII, start: (int)descriptor.ProductIdOffset);
|
||||
// TODO: Get serial number of SCSI and USB devices, probably also FireWire (untested)
|
||||
if (descriptor.SerialNumberOffset > 0)
|
||||
info.serial = StringHandlers.CToString(descriptor_b, Encoding.ASCII, start: (int)descriptor.SerialNumberOffset);
|
||||
if(descriptor.SerialNumberOffset > 0)
|
||||
info.serial =
|
||||
StringHandlers.CToString(descriptor_b, Encoding.ASCII,
|
||||
start: (int)descriptor.SerialNumberOffset);
|
||||
|
||||
if (string.IsNullOrEmpty(info.vendor) || info.vendor == "ATA")
|
||||
if(string.IsNullOrEmpty(info.vendor) || info.vendor == "ATA")
|
||||
{
|
||||
string[] pieces = info.model.Split(' ');
|
||||
if (pieces.Length > 1)
|
||||
if(pieces.Length > 1)
|
||||
{
|
||||
info.vendor = pieces[0];
|
||||
info.model = info.model.Substring(pieces[0].Length + 1);
|
||||
}
|
||||
}
|
||||
|
||||
switch (descriptor.BusType)
|
||||
switch(descriptor.BusType)
|
||||
{
|
||||
case StorageBusType.SCSI:
|
||||
case StorageBusType.ATAPI:
|
||||
@@ -173,4 +170,4 @@ namespace DiscImageChef.Devices.Windows
|
||||
return devices;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -46,22 +46,19 @@ namespace DiscImageChef.Devices.Windows
|
||||
public byte Lun;
|
||||
public byte CdbLength;
|
||||
public byte SenseInfoLength;
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public ScsiIoctlDirection DataIn;
|
||||
[MarshalAs(UnmanagedType.U1)] public ScsiIoctlDirection DataIn;
|
||||
public uint DataTransferLength;
|
||||
public uint TimeOutValue;
|
||||
public IntPtr DataBuffer;
|
||||
public uint SenseInfoOffset;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
|
||||
public byte[] Cdb;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] Cdb;
|
||||
};
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
struct ScsiPassThroughDirectAndSenseBuffer
|
||||
{
|
||||
public ScsiPassThroughDirect sptd;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
|
||||
public byte[] SenseBuf;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public byte[] SenseBuf;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
@@ -74,8 +71,7 @@ namespace DiscImageChef.Devices.Windows
|
||||
/// <summary>
|
||||
/// Indicates transfer direction and kind of operation
|
||||
/// </summary>
|
||||
[MarshalAs(UnmanagedType.U2)]
|
||||
public AtaFlags AtaFlags;
|
||||
[MarshalAs(UnmanagedType.U2)] public AtaFlags AtaFlags;
|
||||
/// <summary>
|
||||
/// Indicates IDE port or bus, set by driver
|
||||
/// </summary>
|
||||
@@ -123,49 +119,35 @@ namespace DiscImageChef.Devices.Windows
|
||||
{
|
||||
public AtaPassThroughDirect aptd;
|
||||
public uint filler;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64 * 512)]
|
||||
public byte[] dataBuffer;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64 * 512)] public byte[] dataBuffer;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
struct AtaTaskFile
|
||||
{
|
||||
// Fields for commands sent
|
||||
[FieldOffset(0)]
|
||||
public byte Features;
|
||||
[FieldOffset(6)]
|
||||
public byte Command;
|
||||
[FieldOffset(0)] public byte Features;
|
||||
[FieldOffset(6)] public byte Command;
|
||||
|
||||
// Fields on command return
|
||||
[FieldOffset(0)]
|
||||
public byte Error;
|
||||
[FieldOffset(6)]
|
||||
public byte Status;
|
||||
[FieldOffset(0)] public byte Error;
|
||||
[FieldOffset(6)] public byte Status;
|
||||
|
||||
// Common fields
|
||||
[FieldOffset(1)]
|
||||
public byte SectorCount;
|
||||
[FieldOffset(2)]
|
||||
public byte SectorNumber;
|
||||
[FieldOffset(3)]
|
||||
public byte CylinderLow;
|
||||
[FieldOffset(4)]
|
||||
public byte CylinderHigh;
|
||||
[FieldOffset(5)]
|
||||
public byte DeviceHead;
|
||||
[FieldOffset(7)]
|
||||
public byte Reserved;
|
||||
[FieldOffset(1)] public byte SectorCount;
|
||||
[FieldOffset(2)] public byte SectorNumber;
|
||||
[FieldOffset(3)] public byte CylinderLow;
|
||||
[FieldOffset(4)] public byte CylinderHigh;
|
||||
[FieldOffset(5)] public byte DeviceHead;
|
||||
[FieldOffset(7)] public byte Reserved;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
struct StoragePropertyQuery
|
||||
{
|
||||
[MarshalAs(UnmanagedType.U4)]
|
||||
public StoragePropertyId PropertyId;
|
||||
[MarshalAs(UnmanagedType.U4)]
|
||||
public StorageQueryType QueryType;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
|
||||
public byte[] AdditionalParameters;
|
||||
[MarshalAs(UnmanagedType.U4)] public StoragePropertyId PropertyId;
|
||||
[MarshalAs(UnmanagedType.U4)] public StorageQueryType QueryType;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] public byte[] AdditionalParameters;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
@@ -182,10 +164,8 @@ namespace DiscImageChef.Devices.Windows
|
||||
public uint Size;
|
||||
public byte DeviceType;
|
||||
public byte DeviceTypeModifier;
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool RemovableMedia;
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool CommandQueueing;
|
||||
[MarshalAs(UnmanagedType.U1)] public bool RemovableMedia;
|
||||
[MarshalAs(UnmanagedType.U1)] public bool CommandQueueing;
|
||||
public uint VendorIdOffset;
|
||||
public uint ProductIdOffset;
|
||||
public uint ProductRevisionOffset;
|
||||
@@ -209,8 +189,7 @@ namespace DiscImageChef.Devices.Windows
|
||||
/// <summary>
|
||||
/// Data buffer
|
||||
/// </summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)]
|
||||
public byte[] DataBuffer;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)] public byte[] DataBuffer;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
@@ -220,7 +199,7 @@ namespace DiscImageChef.Devices.Windows
|
||||
public int deviceNumber;
|
||||
public int partitionNumber;
|
||||
}
|
||||
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
struct DeviceInfoData
|
||||
{
|
||||
@@ -229,7 +208,7 @@ namespace DiscImageChef.Devices.Windows
|
||||
public uint devInst;
|
||||
public IntPtr reserved;
|
||||
}
|
||||
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
struct DeviceInterfaceData
|
||||
{
|
||||
@@ -238,7 +217,7 @@ namespace DiscImageChef.Devices.Windows
|
||||
public uint flags;
|
||||
private IntPtr reserved;
|
||||
}
|
||||
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
struct USB_SETUP_PACKET
|
||||
{
|
||||
@@ -248,7 +227,7 @@ namespace DiscImageChef.Devices.Windows
|
||||
public short wIndex;
|
||||
public short wLength;
|
||||
}
|
||||
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
struct USB_DESCRIPTOR_REQUEST
|
||||
{
|
||||
@@ -256,7 +235,7 @@ namespace DiscImageChef.Devices.Windows
|
||||
public USB_SETUP_PACKET SetupPacket;
|
||||
//public byte[] Data;
|
||||
}
|
||||
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
struct SffdiskQueryDeviceProtocolData
|
||||
{
|
||||
@@ -264,7 +243,7 @@ namespace DiscImageChef.Devices.Windows
|
||||
public ushort reserved;
|
||||
public Guid protocolGuid;
|
||||
}
|
||||
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
struct SffdiskDeviceCommandData
|
||||
{
|
||||
@@ -275,7 +254,7 @@ namespace DiscImageChef.Devices.Windows
|
||||
public uint deviceDataBufferSize;
|
||||
public uint information;
|
||||
}
|
||||
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
struct SdCmdDescriptor
|
||||
{
|
||||
@@ -285,5 +264,4 @@ namespace DiscImageChef.Devices.Windows
|
||||
public SdTransferType transferType;
|
||||
public SdResponseType responseType;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -41,7 +41,6 @@ namespace DiscImageChef.Devices.Windows
|
||||
public partial class Usb
|
||||
{
|
||||
#region "API Region"
|
||||
|
||||
// ********************** Constants ************************
|
||||
|
||||
const int GENERIC_WRITE = 0x40000000;
|
||||
@@ -373,19 +372,10 @@ namespace DiscImageChef.Devices.Windows
|
||||
//);
|
||||
[DllImport("setupapi.dll", CharSet = CharSet.Auto)]
|
||||
static extern IntPtr SetupDiGetClassDevs( // 1st form using a ClassGUID
|
||||
ref Guid ClassGuid,
|
||||
int Enumerator,
|
||||
IntPtr hwndParent,
|
||||
int Flags
|
||||
);
|
||||
ref Guid ClassGuid, int Enumerator, IntPtr hwndParent, int Flags);
|
||||
|
||||
[DllImport("setupapi.dll", CharSet = CharSet.Auto)] // 2nd form uses an Enumerator
|
||||
static extern IntPtr SetupDiGetClassDevs(
|
||||
int ClassGuid,
|
||||
string Enumerator,
|
||||
IntPtr hwndParent,
|
||||
int Flags
|
||||
);
|
||||
static extern IntPtr SetupDiGetClassDevs(int ClassGuid, string Enumerator, IntPtr hwndParent, int Flags);
|
||||
|
||||
//BOOL SetupDiEnumDeviceInterfaces(
|
||||
// HDEVINFO DeviceInfoSet,
|
||||
@@ -395,13 +385,9 @@ namespace DiscImageChef.Devices.Windows
|
||||
// PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData
|
||||
//);
|
||||
[DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
||||
static extern bool SetupDiEnumDeviceInterfaces(
|
||||
IntPtr DeviceInfoSet,
|
||||
IntPtr DeviceInfoData,
|
||||
ref Guid InterfaceClassGuid,
|
||||
int MemberIndex,
|
||||
ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData
|
||||
);
|
||||
static extern bool SetupDiEnumDeviceInterfaces(IntPtr DeviceInfoSet, IntPtr DeviceInfoData,
|
||||
ref Guid InterfaceClassGuid, int MemberIndex,
|
||||
ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData);
|
||||
|
||||
//BOOL SetupDiGetDeviceInterfaceDetail(
|
||||
// HDEVINFO DeviceInfoSet,
|
||||
@@ -412,14 +398,12 @@ namespace DiscImageChef.Devices.Windows
|
||||
// PSP_DEVINFO_DATA DeviceInfoData
|
||||
//);
|
||||
[DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
||||
static extern bool SetupDiGetDeviceInterfaceDetail(
|
||||
IntPtr DeviceInfoSet,
|
||||
ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
|
||||
ref SP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailData,
|
||||
int DeviceInterfaceDetailDataSize,
|
||||
ref int RequiredSize,
|
||||
ref SP_DEVINFO_DATA DeviceInfoData
|
||||
);
|
||||
static extern bool SetupDiGetDeviceInterfaceDetail(IntPtr DeviceInfoSet,
|
||||
ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
|
||||
ref SP_DEVICE_INTERFACE_DETAIL_DATA
|
||||
DeviceInterfaceDetailData,
|
||||
int DeviceInterfaceDetailDataSize, ref int RequiredSize,
|
||||
ref SP_DEVINFO_DATA DeviceInfoData);
|
||||
|
||||
//BOOL SetupDiGetDeviceRegistryProperty(
|
||||
// HDEVINFO DeviceInfoSet,
|
||||
@@ -431,15 +415,10 @@ namespace DiscImageChef.Devices.Windows
|
||||
// PDWORD RequiredSize
|
||||
//);
|
||||
[DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
||||
static extern bool SetupDiGetDeviceRegistryProperty(
|
||||
IntPtr DeviceInfoSet,
|
||||
ref SP_DEVINFO_DATA DeviceInfoData,
|
||||
int iProperty,
|
||||
ref int PropertyRegDataType,
|
||||
IntPtr PropertyBuffer,
|
||||
int PropertyBufferSize,
|
||||
ref int RequiredSize
|
||||
);
|
||||
static extern bool SetupDiGetDeviceRegistryProperty(IntPtr DeviceInfoSet, ref SP_DEVINFO_DATA DeviceInfoData,
|
||||
int iProperty, ref int PropertyRegDataType,
|
||||
IntPtr PropertyBuffer, int PropertyBufferSize,
|
||||
ref int RequiredSize);
|
||||
|
||||
//BOOL SetupDiEnumDeviceInfo(
|
||||
// HDEVINFO DeviceInfoSet,
|
||||
@@ -447,19 +426,14 @@ namespace DiscImageChef.Devices.Windows
|
||||
// PSP_DEVINFO_DATA DeviceInfoData
|
||||
//);
|
||||
[DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
||||
static extern bool SetupDiEnumDeviceInfo(
|
||||
IntPtr DeviceInfoSet,
|
||||
int MemberIndex,
|
||||
ref SP_DEVINFO_DATA DeviceInfoData
|
||||
);
|
||||
static extern bool SetupDiEnumDeviceInfo(IntPtr DeviceInfoSet, int MemberIndex,
|
||||
ref SP_DEVINFO_DATA DeviceInfoData);
|
||||
|
||||
//BOOL SetupDiDestroyDeviceInfoList(
|
||||
// HDEVINFO DeviceInfoSet
|
||||
//);
|
||||
[DllImport("setupapi.dll", SetLastError = true)]
|
||||
static extern bool SetupDiDestroyDeviceInfoList(
|
||||
IntPtr DeviceInfoSet
|
||||
);
|
||||
static extern bool SetupDiDestroyDeviceInfoList(IntPtr DeviceInfoSet);
|
||||
|
||||
//WINSETUPAPI BOOL WINAPI SetupDiGetDeviceInstanceId(
|
||||
// IN HDEVINFO DeviceInfoSet,
|
||||
@@ -469,13 +443,9 @@ namespace DiscImageChef.Devices.Windows
|
||||
// OUT PDWORD RequiredSize OPTIONAL
|
||||
//);
|
||||
[DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
||||
static extern bool SetupDiGetDeviceInstanceId(
|
||||
IntPtr DeviceInfoSet,
|
||||
ref SP_DEVINFO_DATA DeviceInfoData,
|
||||
StringBuilder DeviceInstanceId,
|
||||
int DeviceInstanceIdSize,
|
||||
out int RequiredSize
|
||||
);
|
||||
static extern bool SetupDiGetDeviceInstanceId(IntPtr DeviceInfoSet, ref SP_DEVINFO_DATA DeviceInfoData,
|
||||
StringBuilder DeviceInstanceId, int DeviceInstanceIdSize,
|
||||
out int RequiredSize);
|
||||
|
||||
//BOOL DeviceIoControl(
|
||||
// HANDLE hDevice,
|
||||
@@ -488,16 +458,9 @@ namespace DiscImageChef.Devices.Windows
|
||||
// LPOVERLAPPED lpOverlapped
|
||||
//);
|
||||
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
||||
static extern bool DeviceIoControl(
|
||||
IntPtr hDevice,
|
||||
int dwIoControlCode,
|
||||
IntPtr lpInBuffer,
|
||||
int nInBufferSize,
|
||||
IntPtr lpOutBuffer,
|
||||
int nOutBufferSize,
|
||||
out int lpBytesReturned,
|
||||
IntPtr lpOverlapped
|
||||
);
|
||||
static extern bool DeviceIoControl(IntPtr hDevice, int dwIoControlCode, IntPtr lpInBuffer, int nInBufferSize,
|
||||
IntPtr lpOutBuffer, int nOutBufferSize, out int lpBytesReturned,
|
||||
IntPtr lpOverlapped);
|
||||
|
||||
//HANDLE CreateFile(
|
||||
// LPCTSTR lpFileName,
|
||||
@@ -509,24 +472,15 @@ namespace DiscImageChef.Devices.Windows
|
||||
// HANDLE hTemplateFile
|
||||
//);
|
||||
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
||||
static extern IntPtr CreateFile(
|
||||
string lpFileName,
|
||||
int dwDesiredAccess,
|
||||
int dwShareMode,
|
||||
IntPtr lpSecurityAttributes,
|
||||
int dwCreationDisposition,
|
||||
int dwFlagsAndAttributes,
|
||||
IntPtr hTemplateFile
|
||||
);
|
||||
static extern IntPtr CreateFile(string lpFileName, int dwDesiredAccess, int dwShareMode,
|
||||
IntPtr lpSecurityAttributes, int dwCreationDisposition,
|
||||
int dwFlagsAndAttributes, IntPtr hTemplateFile);
|
||||
|
||||
//BOOL CloseHandle(
|
||||
// HANDLE hObject
|
||||
//);
|
||||
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
||||
static extern bool CloseHandle(
|
||||
IntPtr hObject
|
||||
);
|
||||
|
||||
static extern bool CloseHandle(IntPtr hObject);
|
||||
#endregion
|
||||
|
||||
//
|
||||
@@ -578,12 +532,12 @@ namespace DiscImageChef.Devices.Windows
|
||||
int RegType = REG_SZ;
|
||||
|
||||
if(SetupDiGetDeviceRegistryProperty(h, ref da, SPDRP_DEVICEDESC, ref RegType, ptrBuf,
|
||||
BUFFER_SIZE, ref RequiredSize))
|
||||
BUFFER_SIZE, ref RequiredSize))
|
||||
{
|
||||
host.ControllerDeviceDesc = Marshal.PtrToStringAuto(ptrBuf);
|
||||
}
|
||||
if(SetupDiGetDeviceRegistryProperty(h, ref da, SPDRP_DRIVER, ref RegType, ptrBuf,
|
||||
BUFFER_SIZE, ref RequiredSize))
|
||||
BUFFER_SIZE, ref RequiredSize))
|
||||
{
|
||||
host.ControllerDriverKeyName = Marshal.PtrToStringAuto(ptrBuf);
|
||||
}
|
||||
@@ -591,7 +545,8 @@ namespace DiscImageChef.Devices.Windows
|
||||
HostList.Add(host);
|
||||
}
|
||||
i++;
|
||||
} while(Success);
|
||||
}
|
||||
while(Success);
|
||||
|
||||
Marshal.FreeHGlobal(ptrBuf);
|
||||
SetupDiDestroyDeviceInfoList(h);
|
||||
@@ -652,7 +607,7 @@ namespace DiscImageChef.Devices.Windows
|
||||
|
||||
// Open a handle to the Host Controller
|
||||
h = CreateFile(ControllerDevicePath, GENERIC_WRITE, FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0,
|
||||
IntPtr.Zero);
|
||||
IntPtr.Zero);
|
||||
if(h.ToInt32() != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
int nBytesReturned;
|
||||
@@ -662,7 +617,7 @@ namespace DiscImageChef.Devices.Windows
|
||||
|
||||
// get the Hub Name
|
||||
if(DeviceIoControl(h, IOCTL_USB_GET_ROOT_HUB_NAME, ptrHubName, nBytes, ptrHubName, nBytes,
|
||||
out nBytesReturned, IntPtr.Zero))
|
||||
out nBytesReturned, IntPtr.Zero))
|
||||
{
|
||||
HubName = (USB_ROOT_HUB_NAME)Marshal.PtrToStructure(ptrHubName, typeof(USB_ROOT_HUB_NAME));
|
||||
Root.HubDevicePath = @"\\.\" + HubName.RootHubName;
|
||||
@@ -672,7 +627,7 @@ namespace DiscImageChef.Devices.Windows
|
||||
|
||||
// Now let's open the Hub (based upon the HubName we got above)
|
||||
h2 = CreateFile(Root.HubDevicePath, GENERIC_WRITE, FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0,
|
||||
IntPtr.Zero);
|
||||
IntPtr.Zero);
|
||||
if(h2.ToInt32() != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
USB_NODE_INFORMATION NodeInfo = new USB_NODE_INFORMATION();
|
||||
@@ -683,10 +638,10 @@ namespace DiscImageChef.Devices.Windows
|
||||
|
||||
// get the Hub Information
|
||||
if(DeviceIoControl(h2, IOCTL_USB_GET_NODE_INFORMATION, ptrNodeInfo, nBytes, ptrNodeInfo, nBytes,
|
||||
out nBytesReturned, IntPtr.Zero))
|
||||
out nBytesReturned, IntPtr.Zero))
|
||||
{
|
||||
NodeInfo = (USB_NODE_INFORMATION)Marshal.PtrToStructure(ptrNodeInfo,
|
||||
typeof(USB_NODE_INFORMATION));
|
||||
typeof(USB_NODE_INFORMATION));
|
||||
Root.HubIsBusPowered = Convert.ToBoolean(NodeInfo.HubInformation.HubIsBusPowered);
|
||||
Root.HubPortCount = NodeInfo.HubInformation.HubDescriptor.bNumberOfPorts;
|
||||
}
|
||||
@@ -790,7 +745,7 @@ namespace DiscImageChef.Devices.Windows
|
||||
|
||||
// Open a handle to the Hub device
|
||||
IntPtr h = CreateFile(HubDevicePath, GENERIC_WRITE, FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0,
|
||||
IntPtr.Zero);
|
||||
IntPtr.Zero);
|
||||
if(h.ToInt32() != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
int nBytes = Marshal.SizeOf(typeof(USB_NODE_CONNECTION_INFORMATION_EX));
|
||||
@@ -806,11 +761,13 @@ namespace DiscImageChef.Devices.Windows
|
||||
Marshal.StructureToPtr(NodeConnection, ptrNodeConnection, true);
|
||||
|
||||
if(DeviceIoControl(h, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX, ptrNodeConnection, nBytes,
|
||||
ptrNodeConnection, nBytes, out nBytesReturned, IntPtr.Zero))
|
||||
ptrNodeConnection, nBytes, out nBytesReturned, IntPtr.Zero))
|
||||
{
|
||||
NodeConnection =
|
||||
(USB_NODE_CONNECTION_INFORMATION_EX)Marshal.PtrToStructure(ptrNodeConnection,
|
||||
typeof(USB_NODE_CONNECTION_INFORMATION_EX));
|
||||
typeof(
|
||||
USB_NODE_CONNECTION_INFORMATION_EX
|
||||
));
|
||||
|
||||
// load up the USBPort class
|
||||
USBPort port = new USBPort();
|
||||
@@ -829,6 +786,7 @@ namespace DiscImageChef.Devices.Windows
|
||||
PortList.Add(port);
|
||||
}
|
||||
}
|
||||
|
||||
Marshal.FreeHGlobal(ptrNodeConnection);
|
||||
CloseHandle(h);
|
||||
}
|
||||
@@ -897,10 +855,8 @@ namespace DiscImageChef.Devices.Windows
|
||||
// return a down stream external hub
|
||||
public USBDevice GetDevice()
|
||||
{
|
||||
if(!PortIsDeviceConnected)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if(!PortIsDeviceConnected) { return null; }
|
||||
|
||||
USBDevice Device = new USBDevice();
|
||||
|
||||
// Copy over some values from the Port class
|
||||
@@ -911,7 +867,7 @@ namespace DiscImageChef.Devices.Windows
|
||||
|
||||
// Open a handle to the Hub device
|
||||
IntPtr h = CreateFile(PortHubDevicePath, GENERIC_WRITE, FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0,
|
||||
IntPtr.Zero);
|
||||
IntPtr.Zero);
|
||||
if(h.ToInt32() != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
int nBytesReturned;
|
||||
@@ -938,7 +894,7 @@ namespace DiscImageChef.Devices.Windows
|
||||
|
||||
// Use an IOCTL call to request the String Descriptor
|
||||
if(DeviceIoControl(h, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, ptrRequest, nBytes,
|
||||
ptrRequest, nBytes, out nBytesReturned, IntPtr.Zero))
|
||||
ptrRequest, nBytes, out nBytesReturned, IntPtr.Zero))
|
||||
{
|
||||
// The location of the string descriptor is immediately after
|
||||
// the Request structure. Because this location is not "covered"
|
||||
@@ -947,7 +903,7 @@ namespace DiscImageChef.Devices.Windows
|
||||
IntPtr ptrStringDesc = new IntPtr(ptrRequest.ToInt32() + Marshal.SizeOf(Request));
|
||||
USB_STRING_DESCRIPTOR StringDesc =
|
||||
(USB_STRING_DESCRIPTOR)Marshal.PtrToStructure(ptrStringDesc,
|
||||
typeof(USB_STRING_DESCRIPTOR));
|
||||
typeof(USB_STRING_DESCRIPTOR));
|
||||
Device.DeviceManufacturer = StringDesc.bString;
|
||||
}
|
||||
Marshal.FreeHGlobal(ptrRequest);
|
||||
@@ -967,13 +923,13 @@ namespace DiscImageChef.Devices.Windows
|
||||
|
||||
// Use an IOCTL call to request the String Descriptor
|
||||
if(DeviceIoControl(h, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, ptrRequest, nBytes,
|
||||
ptrRequest, nBytes, out nBytesReturned, IntPtr.Zero))
|
||||
ptrRequest, nBytes, out nBytesReturned, IntPtr.Zero))
|
||||
{
|
||||
// the location of the string descriptor is immediately after the Request structure
|
||||
IntPtr ptrStringDesc = new IntPtr(ptrRequest.ToInt32() + Marshal.SizeOf(Request));
|
||||
USB_STRING_DESCRIPTOR StringDesc =
|
||||
(USB_STRING_DESCRIPTOR)Marshal.PtrToStructure(ptrStringDesc,
|
||||
typeof(USB_STRING_DESCRIPTOR));
|
||||
typeof(USB_STRING_DESCRIPTOR));
|
||||
Device.DeviceProduct = StringDesc.bString;
|
||||
}
|
||||
Marshal.FreeHGlobal(ptrRequest);
|
||||
@@ -993,13 +949,13 @@ namespace DiscImageChef.Devices.Windows
|
||||
|
||||
// Use an IOCTL call to request the String Descriptor
|
||||
if(DeviceIoControl(h, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, ptrRequest, nBytes,
|
||||
ptrRequest, nBytes, out nBytesReturned, IntPtr.Zero))
|
||||
ptrRequest, nBytes, out nBytesReturned, IntPtr.Zero))
|
||||
{
|
||||
// the location of the string descriptor is immediately after the Request structure
|
||||
IntPtr ptrStringDesc = new IntPtr(ptrRequest.ToInt32() + Marshal.SizeOf(Request));
|
||||
USB_STRING_DESCRIPTOR StringDesc =
|
||||
(USB_STRING_DESCRIPTOR)Marshal.PtrToStructure(ptrStringDesc,
|
||||
typeof(USB_STRING_DESCRIPTOR));
|
||||
typeof(USB_STRING_DESCRIPTOR));
|
||||
Device.DeviceSerialNumber = StringDesc.bString;
|
||||
}
|
||||
Marshal.FreeHGlobal(ptrRequest);
|
||||
@@ -1010,14 +966,14 @@ namespace DiscImageChef.Devices.Windows
|
||||
dcrRequest.ConnectionIndex = PortPortNumber;
|
||||
dcrRequest.SetupPacket.wValue = (short)((USB_CONFIGURATION_DESCRIPTOR_TYPE << 8));
|
||||
dcrRequest.SetupPacket.wLength = (short)(nBytes - Marshal.SizeOf(dcrRequest));
|
||||
dcrRequest.SetupPacket.wIndex = 0;
|
||||
dcrRequest.SetupPacket.wIndex = 0;
|
||||
// Geez, I wish C# had a Marshal.MemSet() method
|
||||
IntPtr dcrPtrRequest = Marshal.StringToHGlobalAuto(NullString);
|
||||
Marshal.StructureToPtr(dcrRequest, dcrPtrRequest, true);
|
||||
|
||||
// Use an IOCTL call to request the String Descriptor
|
||||
if(DeviceIoControl(h, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, dcrPtrRequest, nBytes,
|
||||
dcrPtrRequest, nBytes, out nBytesReturned, IntPtr.Zero))
|
||||
dcrPtrRequest, nBytes, out nBytesReturned, IntPtr.Zero))
|
||||
{
|
||||
IntPtr ptrStringDesc = new IntPtr(dcrPtrRequest.ToInt32() + Marshal.SizeOf(dcrRequest));
|
||||
Device.BinaryDeviceDescriptors = new byte[nBytesReturned];
|
||||
@@ -1034,10 +990,12 @@ namespace DiscImageChef.Devices.Windows
|
||||
|
||||
// Use an IOCTL call to request the Driver Key Name
|
||||
if(DeviceIoControl(h, IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME, ptrDriverKey, nBytes,
|
||||
ptrDriverKey, nBytes, out nBytesReturned, IntPtr.Zero))
|
||||
ptrDriverKey, nBytes, out nBytesReturned, IntPtr.Zero))
|
||||
{
|
||||
DriverKey = (USB_NODE_CONNECTION_DRIVERKEY_NAME)Marshal.PtrToStructure(ptrDriverKey,
|
||||
typeof(USB_NODE_CONNECTION_DRIVERKEY_NAME));
|
||||
typeof(
|
||||
USB_NODE_CONNECTION_DRIVERKEY_NAME
|
||||
));
|
||||
Device.DeviceDriverKey = DriverKey.DriverKeyName;
|
||||
|
||||
// use the DriverKeyName to get the Device Description and Instance ID
|
||||
@@ -1053,10 +1011,8 @@ namespace DiscImageChef.Devices.Windows
|
||||
// return a down stream external hub
|
||||
public USBHub GetHub()
|
||||
{
|
||||
if(!PortIsHub)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if(!PortIsHub) { return null; }
|
||||
|
||||
USBHub Hub = new USBHub();
|
||||
IntPtr h, h2;
|
||||
Hub.HubIsRootHub = false;
|
||||
@@ -1064,7 +1020,7 @@ namespace DiscImageChef.Devices.Windows
|
||||
|
||||
// Open a handle to the Host Controller
|
||||
h = CreateFile(PortHubDevicePath, GENERIC_WRITE, FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0,
|
||||
IntPtr.Zero);
|
||||
IntPtr.Zero);
|
||||
if(h.ToInt32() != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
// Get the DevicePath for downstream hub
|
||||
@@ -1077,16 +1033,16 @@ namespace DiscImageChef.Devices.Windows
|
||||
|
||||
// Use an IOCTL call to request the Node Name
|
||||
if(DeviceIoControl(h, IOCTL_USB_GET_NODE_CONNECTION_NAME, ptrNodeName, nBytes, ptrNodeName, nBytes,
|
||||
out nBytesReturned, IntPtr.Zero))
|
||||
out nBytesReturned, IntPtr.Zero))
|
||||
{
|
||||
NodeName = (USB_NODE_CONNECTION_NAME)Marshal.PtrToStructure(ptrNodeName,
|
||||
typeof(USB_NODE_CONNECTION_NAME));
|
||||
typeof(USB_NODE_CONNECTION_NAME));
|
||||
Hub.HubDevicePath = @"\\.\" + NodeName.NodeName;
|
||||
}
|
||||
|
||||
// Now let's open the Hub (based upon the HubName we got above)
|
||||
h2 = CreateFile(Hub.HubDevicePath, GENERIC_WRITE, FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0,
|
||||
IntPtr.Zero);
|
||||
IntPtr.Zero);
|
||||
if(h2.ToInt32() != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
USB_NODE_INFORMATION NodeInfo = new USB_NODE_INFORMATION();
|
||||
@@ -1097,10 +1053,10 @@ namespace DiscImageChef.Devices.Windows
|
||||
|
||||
// get the Hub Information
|
||||
if(DeviceIoControl(h2, IOCTL_USB_GET_NODE_INFORMATION, ptrNodeInfo, nBytes, ptrNodeInfo, nBytes,
|
||||
out nBytesReturned, IntPtr.Zero))
|
||||
out nBytesReturned, IntPtr.Zero))
|
||||
{
|
||||
NodeInfo = (USB_NODE_INFORMATION)Marshal.PtrToStructure(ptrNodeInfo,
|
||||
typeof(USB_NODE_INFORMATION));
|
||||
typeof(USB_NODE_INFORMATION));
|
||||
Hub.HubIsBusPowered = Convert.ToBoolean(NodeInfo.HubInformation.HubIsBusPowered);
|
||||
Hub.HubPortCount = NodeInfo.HubInformation.HubDescriptor.bNumberOfPorts;
|
||||
}
|
||||
@@ -1193,7 +1149,7 @@ namespace DiscImageChef.Devices.Windows
|
||||
{
|
||||
get { return DeviceSerialNumber; }
|
||||
}
|
||||
|
||||
|
||||
public byte[] BinaryDescriptors
|
||||
{
|
||||
get { return BinaryDeviceDescriptors; }
|
||||
@@ -1233,7 +1189,7 @@ namespace DiscImageChef.Devices.Windows
|
||||
KeyName = "";
|
||||
|
||||
if(SetupDiGetDeviceRegistryProperty(h, ref da, SPDRP_DRIVER, ref RegType, ptrBuf, BUFFER_SIZE,
|
||||
ref RequiredSize))
|
||||
ref RequiredSize))
|
||||
{
|
||||
KeyName = Marshal.PtrToStringAuto(ptrBuf);
|
||||
}
|
||||
@@ -1242,19 +1198,22 @@ namespace DiscImageChef.Devices.Windows
|
||||
if(KeyName == DriverKeyName)
|
||||
{
|
||||
if(SetupDiGetDeviceRegistryProperty(h, ref da, SPDRP_DEVICEDESC, ref RegType, ptrBuf,
|
||||
BUFFER_SIZE, ref RequiredSize))
|
||||
BUFFER_SIZE, ref RequiredSize))
|
||||
{
|
||||
ans = Marshal.PtrToStringAuto(ptrBuf);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
i++;
|
||||
} while(Success);
|
||||
}
|
||||
while(Success);
|
||||
|
||||
Marshal.FreeHGlobal(ptrBuf);
|
||||
SetupDiDestroyDeviceInfoList(h);
|
||||
}
|
||||
|
||||
return ans;
|
||||
}
|
||||
|
||||
@@ -1291,7 +1250,7 @@ namespace DiscImageChef.Devices.Windows
|
||||
|
||||
KeyName = "";
|
||||
if(SetupDiGetDeviceRegistryProperty(h, ref da, SPDRP_DRIVER, ref RegType, ptrBuf, BUFFER_SIZE,
|
||||
ref RequiredSize))
|
||||
ref RequiredSize))
|
||||
{
|
||||
KeyName = Marshal.PtrToStringAuto(ptrBuf);
|
||||
}
|
||||
@@ -1306,13 +1265,16 @@ namespace DiscImageChef.Devices.Windows
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
i++;
|
||||
} while(Success);
|
||||
}
|
||||
while(Success);
|
||||
|
||||
Marshal.FreeHGlobal(ptrBuf);
|
||||
SetupDiDestroyDeviceInfoList(h);
|
||||
}
|
||||
|
||||
return ans;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -37,14 +37,12 @@ using System.Runtime.InteropServices;
|
||||
// Copyright "Fort Hood TX", public domain, 2007
|
||||
namespace DiscImageChef.Devices.Windows
|
||||
{
|
||||
|
||||
//
|
||||
// A place for "higher level" related functions
|
||||
// You might not want to keep these in the USB class... your choice
|
||||
//
|
||||
public partial class Usb
|
||||
{
|
||||
|
||||
//
|
||||
// Get a list of all connected devices
|
||||
//
|
||||
@@ -52,10 +50,8 @@ namespace DiscImageChef.Devices.Windows
|
||||
{
|
||||
List<USBDevice> DevList = new List<USBDevice>();
|
||||
|
||||
foreach(USBController Controller in GetHostControllers())
|
||||
{
|
||||
ListHub(Controller.GetRootHub(), DevList);
|
||||
}
|
||||
foreach(USBController Controller in GetHostControllers()) { ListHub(Controller.GetRootHub(), DevList); }
|
||||
|
||||
return DevList;
|
||||
}
|
||||
|
||||
@@ -69,13 +65,7 @@ namespace DiscImageChef.Devices.Windows
|
||||
// recursive
|
||||
ListHub(Port.GetHub(), DevList);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(Port.IsDeviceConnected)
|
||||
{
|
||||
DevList.Add(Port.GetDevice());
|
||||
}
|
||||
}
|
||||
else { if(Port.IsDeviceConnected) { DevList.Add(Port.GetDevice()); } }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,9 +79,9 @@ namespace DiscImageChef.Devices.Windows
|
||||
foreach(USBController Controller in GetHostControllers())
|
||||
{
|
||||
SearchHubDriverKeyName(Controller.GetRootHub(), ref FoundDevice, DriverKeyName);
|
||||
if(FoundDevice != null)
|
||||
break;
|
||||
if(FoundDevice != null) break;
|
||||
}
|
||||
|
||||
return FoundDevice;
|
||||
}
|
||||
|
||||
@@ -130,9 +120,9 @@ namespace DiscImageChef.Devices.Windows
|
||||
foreach(USBController Controller in GetHostControllers())
|
||||
{
|
||||
SearchHubInstanceID(Controller.GetRootHub(), ref FoundDevice, InstanceID);
|
||||
if(FoundDevice != null)
|
||||
break;
|
||||
if(FoundDevice != null) break;
|
||||
}
|
||||
|
||||
return FoundDevice;
|
||||
}
|
||||
|
||||
@@ -185,11 +175,7 @@ namespace DiscImageChef.Devices.Windows
|
||||
// IN ULONG ulFlags
|
||||
//);
|
||||
[DllImport("setupapi.dll")]
|
||||
static extern int CM_Get_Parent(
|
||||
out IntPtr pdnDevInst,
|
||||
IntPtr dnDevInst,
|
||||
int ulFlags
|
||||
);
|
||||
static extern int CM_Get_Parent(out IntPtr pdnDevInst, IntPtr dnDevInst, int ulFlags);
|
||||
|
||||
//CMAPI CONFIGRET WINAPI CM_Get_Device_ID(
|
||||
// IN DEVINST dnDevInst,
|
||||
@@ -198,12 +184,7 @@ namespace DiscImageChef.Devices.Windows
|
||||
// IN ULONG ulFlags
|
||||
//);
|
||||
[DllImport("setupapi.dll", CharSet = CharSet.Auto)]
|
||||
static extern int CM_Get_Device_ID(
|
||||
IntPtr dnDevInst,
|
||||
IntPtr Buffer,
|
||||
int BufferLen,
|
||||
int ulFlags
|
||||
);
|
||||
static extern int CM_Get_Device_ID(IntPtr dnDevInst, IntPtr Buffer, int BufferLen, int ulFlags);
|
||||
|
||||
//
|
||||
// Find a device based upon a Drive Letter
|
||||
@@ -217,10 +198,7 @@ namespace DiscImageChef.Devices.Windows
|
||||
// DriveLetter. We'll use this later to find a matching
|
||||
// DevicePath "symbolic name"
|
||||
int DevNum = GetDeviceNumber(@"\\.\" + DriveLetter.TrimEnd('\\'));
|
||||
if(DevNum < 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if(DevNum < 0) { return null; }
|
||||
|
||||
return FindDeviceNumber(DevNum, deviceGuid);
|
||||
}
|
||||
@@ -234,10 +212,7 @@ namespace DiscImageChef.Devices.Windows
|
||||
// DriveLetter. We'll use this later to find a matching
|
||||
// DevicePath "symbolic name"
|
||||
int DevNum = GetDeviceNumber(DrivePath);
|
||||
if(DevNum < 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if(DevNum < 0) { return null; }
|
||||
|
||||
return FindDeviceNumber(DevNum, deviceGuid);
|
||||
}
|
||||
@@ -304,15 +279,14 @@ namespace DiscImageChef.Devices.Windows
|
||||
}
|
||||
}
|
||||
i++;
|
||||
} while(Success);
|
||||
}
|
||||
while(Success);
|
||||
|
||||
SetupDiDestroyDeviceInfoList(h);
|
||||
}
|
||||
|
||||
// Did we find an InterfaceID of a USB device?
|
||||
if(InstanceID.StartsWith("USB\\"))
|
||||
{
|
||||
FoundDevice = FindDeviceByInstanceID(InstanceID);
|
||||
}
|
||||
if(InstanceID.StartsWith("USB\\")) { FoundDevice = FindDeviceByInstanceID(InstanceID); }
|
||||
return FoundDevice;
|
||||
}
|
||||
|
||||
@@ -330,7 +304,7 @@ namespace DiscImageChef.Devices.Windows
|
||||
IntPtr ptrSdn = Marshal.AllocHGlobal(nBytes);
|
||||
|
||||
if(DeviceIoControl(h, IOCTL_STORAGE_GET_DEVICE_NUMBER, IntPtr.Zero, 0, ptrSdn, nBytes, out requiredSize,
|
||||
IntPtr.Zero))
|
||||
IntPtr.Zero))
|
||||
{
|
||||
Sdn = (STORAGE_DEVICE_NUMBER)Marshal.PtrToStructure(ptrSdn, typeof(STORAGE_DEVICE_NUMBER));
|
||||
// just my way of combining the relevant parts of the
|
||||
@@ -343,4 +317,4 @@ namespace DiscImageChef.Devices.Windows
|
||||
return ans;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user