REFACTOR: Reformat code.

This commit is contained in:
2017-12-19 20:33:03 +00:00
parent 77edc7c91c
commit e6f6ace80b
704 changed files with 82627 additions and 83641 deletions

View File

@@ -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));
}
}
}
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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);

View File

@@ -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;
}
}
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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);

View File

@@ -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);
}
}
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -60,5 +60,4 @@ namespace DiscImageChef.Devices
}
}
}
}
}

View File

@@ -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()));
}
}
}
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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; }
}
}
}
}

View File

@@ -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
}
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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
}
}

View File

@@ -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);
}
}
}

View File

@@ -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)
{

View File

@@ -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;
}
}
}

View File

@@ -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);
}
}
}
}

View File

@@ -182,5 +182,4 @@ namespace DiscImageChef.Devices.Linux
/// </summary>
MixedIo = 0x04
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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("")]

View File

@@ -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;
}
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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;
}
}
}
}