Code cleanup.

This commit is contained in:
2018-06-22 08:08:38 +01:00
parent 82f474c7e3
commit 88da8fc019
581 changed files with 22423 additions and 20839 deletions

View File

@@ -58,8 +58,10 @@ namespace DiscImageChef.Devices
/// sense
/// </param>
/// <exception cref="InvalidOperationException">If the specified platform is not supported</exception>
internal static int SendScsiCommand(object fd, byte[] cdb, ref byte[] buffer, out byte[] senseBuffer,
uint timeout, ScsiDirection direction, out double duration, out bool sense)
internal static int SendScsiCommand(object fd, byte[] cdb, ref byte[] buffer,
out byte[] senseBuffer,
uint timeout, ScsiDirection direction, out double duration,
out bool sense)
{
PlatformID ptId = DetectOS.GetRealPlatformID();
@@ -84,9 +86,10 @@ namespace DiscImageChef.Devices
/// sense
/// </param>
/// <exception cref="InvalidOperationException">If the specified platform is not supported</exception>
internal static int SendScsiCommand(PlatformID ptId, object fd, byte[] cdb, ref byte[] buffer,
out byte[] senseBuffer, uint timeout, ScsiDirection direction,
out double duration, out bool sense)
internal static int SendScsiCommand(PlatformID ptId, object fd, byte[] cdb,
ref byte[] buffer,
out byte[] senseBuffer, uint timeout, ScsiDirection direction,
out double duration, out bool sense)
{
switch(ptId)
{
@@ -181,14 +184,17 @@ namespace DiscImageChef.Devices
/// <param name="transferRegister">What register contains the transfer length</param>
/// <param name="transferBlocks">Set to <c>true</c> if the transfer length is in block, otherwise it is in bytes</param>
/// <exception cref="InvalidOperationException">If the specified platform is not supported</exception>
internal static int SendAtaCommand(object fd, AtaRegistersChs registers,
out AtaErrorRegistersChs errorRegisters, AtaProtocol protocol,
AtaTransferRegister transferRegister, ref byte[] buffer, uint timeout,
bool transferBlocks, out double duration, out bool sense)
internal static int SendAtaCommand(object fd, AtaRegistersChs registers,
out AtaErrorRegistersChs errorRegisters, AtaProtocol protocol,
AtaTransferRegister transferRegister, ref byte[] buffer,
uint timeout,
bool transferBlocks, out double duration,
out bool sense)
{
PlatformID ptId = DetectOS.GetRealPlatformID();
return SendAtaCommand(ptId, fd, registers, out errorRegisters, protocol, transferRegister, ref buffer,
return SendAtaCommand(ptId, fd, registers, out errorRegisters, protocol, transferRegister,
ref buffer,
timeout, transferBlocks, out duration, out sense);
}
@@ -208,10 +214,13 @@ namespace DiscImageChef.Devices
/// <param name="transferRegister">What register contains the transfer length</param>
/// <param name="transferBlocks">Set to <c>true</c> if the transfer length is in block, otherwise it is in bytes</param>
/// <exception cref="InvalidOperationException">If the specified platform is not supported</exception>
internal static int SendAtaCommand(PlatformID ptId, object fd, AtaRegistersChs registers,
out AtaErrorRegistersChs errorRegisters, AtaProtocol protocol,
AtaTransferRegister transferRegister, ref byte[] buffer, uint timeout,
bool transferBlocks, out double duration, out bool sense)
internal static int SendAtaCommand(PlatformID ptId, object fd,
AtaRegistersChs registers,
out AtaErrorRegistersChs errorRegisters, AtaProtocol protocol,
AtaTransferRegister transferRegister, ref byte[] buffer,
uint timeout,
bool transferBlocks, out double duration,
out bool sense)
{
switch(ptId)
{
@@ -223,6 +232,7 @@ namespace DiscImageChef.Devices
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.");
@@ -260,14 +270,17 @@ namespace DiscImageChef.Devices
/// <param name="transferRegister">What register contains the transfer length</param>
/// <param name="transferBlocks">Set to <c>true</c> if the transfer length is in block, otherwise it is in bytes</param>
/// <exception cref="InvalidOperationException">If the specified platform is not supported</exception>
internal static int SendAtaCommand(object fd, AtaRegistersLba28 registers,
out AtaErrorRegistersLba28 errorRegisters, AtaProtocol protocol,
AtaTransferRegister transferRegister, ref byte[] buffer, uint timeout,
bool transferBlocks, out double duration, out bool sense)
internal static int SendAtaCommand(object fd, AtaRegistersLba28 registers,
out AtaErrorRegistersLba28 errorRegisters, AtaProtocol protocol,
AtaTransferRegister transferRegister, ref byte[] buffer,
uint timeout,
bool transferBlocks, out double duration,
out bool sense)
{
PlatformID ptId = DetectOS.GetRealPlatformID();
return SendAtaCommand(ptId, fd, registers, out errorRegisters, protocol, transferRegister, ref buffer,
return SendAtaCommand(ptId, fd, registers, out errorRegisters, protocol, transferRegister,
ref buffer,
timeout, transferBlocks, out duration, out sense);
}
@@ -287,10 +300,13 @@ namespace DiscImageChef.Devices
/// <param name="transferRegister">What register contains the transfer length</param>
/// <param name="transferBlocks">Set to <c>true</c> if the transfer length is in block, otherwise it is in bytes</param>
/// <exception cref="InvalidOperationException">If the specified platform is not supported</exception>
internal static int SendAtaCommand(PlatformID ptId, object fd, AtaRegistersLba28 registers,
out AtaErrorRegistersLba28 errorRegisters, AtaProtocol protocol,
AtaTransferRegister transferRegister, ref byte[] buffer, uint timeout,
bool transferBlocks, out double duration, out bool sense)
internal static int SendAtaCommand(PlatformID ptId, object fd,
AtaRegistersLba28 registers,
out AtaErrorRegistersLba28 errorRegisters, AtaProtocol protocol,
AtaTransferRegister transferRegister, ref byte[] buffer,
uint timeout,
bool transferBlocks, out double duration,
out bool sense)
{
switch(ptId)
{
@@ -302,6 +318,7 @@ namespace DiscImageChef.Devices
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.");
@@ -339,14 +356,17 @@ namespace DiscImageChef.Devices
/// <param name="transferRegister">What register contains the transfer length</param>
/// <param name="transferBlocks">Set to <c>true</c> if the transfer length is in block, otherwise it is in bytes</param>
/// <exception cref="InvalidOperationException">If the specified platform is not supported</exception>
internal static int SendAtaCommand(object fd, AtaRegistersLba48 registers,
out AtaErrorRegistersLba48 errorRegisters, AtaProtocol protocol,
AtaTransferRegister transferRegister, ref byte[] buffer, uint timeout,
bool transferBlocks, out double duration, out bool sense)
internal static int SendAtaCommand(object fd, AtaRegistersLba48 registers,
out AtaErrorRegistersLba48 errorRegisters, AtaProtocol protocol,
AtaTransferRegister transferRegister, ref byte[] buffer,
uint timeout,
bool transferBlocks, out double duration,
out bool sense)
{
PlatformID ptId = DetectOS.GetRealPlatformID();
return SendAtaCommand(ptId, fd, registers, out errorRegisters, protocol, transferRegister, ref buffer,
return SendAtaCommand(ptId, fd, registers, out errorRegisters, protocol, transferRegister,
ref buffer,
timeout, transferBlocks, out duration, out sense);
}
@@ -366,10 +386,13 @@ namespace DiscImageChef.Devices
/// <param name="transferRegister">What register contains the transfer length</param>
/// <param name="transferBlocks">Set to <c>true</c> if the transfer length is in block, otherwise it is in bytes</param>
/// <exception cref="InvalidOperationException">If the specified platform is not supported</exception>
internal static int SendAtaCommand(PlatformID ptId, object fd, AtaRegistersLba48 registers,
out AtaErrorRegistersLba48 errorRegisters, AtaProtocol protocol,
AtaTransferRegister transferRegister, ref byte[] buffer, uint timeout,
bool transferBlocks, out double duration, out bool sense)
internal static int SendAtaCommand(PlatformID ptId, object fd,
AtaRegistersLba48 registers,
out AtaErrorRegistersLba48 errorRegisters, AtaProtocol protocol,
AtaTransferRegister transferRegister, ref byte[] buffer,
uint timeout,
bool transferBlocks, out double duration,
out bool sense)
{
switch(ptId)
{
@@ -412,14 +435,18 @@ namespace DiscImageChef.Devices
/// <param name="response">Response registers</param>
/// <param name="blockSize">Size of block in bytes</param>
/// <exception cref="InvalidOperationException">If the specified platform is not supported</exception>
internal static int SendMmcCommand(object fd, MmcCommands command, bool write, bool isApplication,
MmcFlags flags, uint argument, uint blockSize, uint blocks,
ref byte[] buffer, out uint[] response, out double duration, out bool sense,
uint timeout = 0)
internal static int SendMmcCommand(object fd, MmcCommands command, bool write,
bool isApplication,
MmcFlags flags, uint argument, uint blockSize,
uint blocks,
ref byte[] buffer, out uint[] response, out double duration,
out bool sense,
uint timeout = 0)
{
PlatformID ptId = DetectOS.GetRealPlatformID();
return SendMmcCommand(ptId, (int)fd, command, write, isApplication, flags, argument, blockSize, blocks,
return SendMmcCommand(ptId, (int)fd, command, write, isApplication, flags, argument,
blockSize, blocks,
ref buffer, out response, out duration, out sense, timeout);
}
@@ -442,10 +469,13 @@ namespace DiscImageChef.Devices
/// <param name="response">Response registers</param>
/// <param name="blockSize">Size of block in bytes</param>
/// <exception cref="InvalidOperationException">If the specified platform is not supported</exception>
internal static int SendMmcCommand(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)
internal static int SendMmcCommand(PlatformID ptId, object fd, MmcCommands command,
bool write,
bool isApplication, MmcFlags flags, uint argument,
uint blockSize,
uint blocks, ref byte[] buffer, out uint[] response,
out double duration,
out bool sense, uint timeout = 0)
{
switch(ptId)
{

View File

@@ -43,8 +43,9 @@ namespace DiscImageChef.Devices
buffer = new byte[512];
AtaRegistersLba28 registers = new AtaRegistersLba28 {Command = (byte)AtaCommands.ReadBuffer};
LastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.PioIn,
AtaTransferRegister.NoTransfer, ref buffer, timeout, false, out duration,
LastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.PioIn,
AtaTransferRegister.NoTransfer, ref buffer, timeout, false,
out duration,
out bool sense);
Error = LastError != 0;
@@ -59,8 +60,8 @@ namespace DiscImageChef.Devices
buffer = new byte[512];
AtaRegistersLba28 registers = new AtaRegistersLba28 {Command = (byte)AtaCommands.ReadBufferDma};
LastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.Dma, AtaTransferRegister.NoTransfer,
ref buffer, timeout, false, out duration, out bool sense);
LastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.Dma, AtaTransferRegister.NoTransfer,
ref buffer, timeout, false, out duration, out bool sense);
Error = LastError != 0;
DicConsole.DebugWriteLine("ATA Device", "READ BUFFER DMA took {0} ms.", duration);
@@ -68,29 +69,30 @@ 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)
{
buffer = count == 0 ? new byte[512 * 256] : new byte[512 * count];
AtaRegistersLba28 registers = new AtaRegistersLba28
{
SectorCount = count,
DeviceHead = (byte)((lba & 0xF000000) / 0x1000000),
LbaHigh = (byte)((lba & 0xFF0000) / 0x10000),
LbaMid = (byte)((lba & 0xFF00) / 0x100),
LbaLow = (byte)((lba & 0xFF) / 0x1),
Command = retry ? (byte)AtaCommands.ReadDmaRetry : (byte)AtaCommands.ReadDma
DeviceHead = (byte)((lba & 0xF000000) / 0x1000000),
LbaHigh = (byte)((lba & 0xFF0000) / 0x10000),
LbaMid = (byte)((lba & 0xFF00) / 0x100),
LbaLow = (byte)((lba & 0xFF) / 0x1),
Command = retry ? (byte)AtaCommands.ReadDmaRetry : (byte)AtaCommands.ReadDma
};
registers.DeviceHead += 0x40;
LastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.Dma, AtaTransferRegister.SectorCount,
LastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.Dma,
AtaTransferRegister.SectorCount,
ref buffer, timeout, true, out duration, out bool sense);
Error = LastError != 0;
@@ -99,24 +101,25 @@ 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)
{
buffer = count == 0 ? new byte[512 * 256] : new byte[512 * count];
AtaRegistersLba28 registers = new AtaRegistersLba28
{
Command = (byte)AtaCommands.ReadMultiple,
Command = (byte)AtaCommands.ReadMultiple,
SectorCount = count,
DeviceHead = (byte)((lba & 0xF000000) / 0x1000000),
LbaHigh = (byte)((lba & 0xFF0000) / 0x10000),
LbaMid = (byte)((lba & 0xFF00) / 0x100),
LbaLow = (byte)((lba & 0xFF) / 0x1)
DeviceHead = (byte)((lba & 0xF000000) / 0x1000000),
LbaHigh = (byte)((lba & 0xFF0000) / 0x10000),
LbaMid = (byte)((lba & 0xFF00) / 0x100),
LbaLow = (byte)((lba & 0xFF) / 0x1)
};
registers.DeviceHead += 0x40;
LastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.PioIn,
AtaTransferRegister.SectorCount, ref buffer, timeout, true, out duration,
LastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.PioIn,
AtaTransferRegister.SectorCount, ref buffer, timeout, true,
out duration,
out bool sense);
Error = LastError != 0;
@@ -125,17 +128,18 @@ namespace DiscImageChef.Devices
return sense;
}
public bool ReadNativeMaxAddress(out uint lba, out AtaErrorRegistersLba28 statusRegisters, uint timeout,
public bool ReadNativeMaxAddress(out uint lba, out AtaErrorRegistersLba28 statusRegisters, uint timeout,
out double duration)
{
lba = 0;
byte[] buffer = new byte[0];
byte[] buffer = new byte[0];
AtaRegistersLba28 registers = new AtaRegistersLba28 {Command = (byte)AtaCommands.ReadNativeMaxAddress};
registers.DeviceHead += 0x40;
LastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.NonData,
AtaTransferRegister.NoTransfer, ref buffer, timeout, false, out duration,
LastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.NonData,
AtaTransferRegister.NoTransfer, ref buffer, timeout, false,
out duration,
out bool sense);
Error = LastError != 0;
@@ -144,7 +148,7 @@ namespace DiscImageChef.Devices
lba += (uint)(statusRegisters.DeviceHead & 0xF);
lba *= 0x1000000;
lba += (uint)(statusRegisters.LbaHigh << 16);
lba += (uint)(statusRegisters.LbaMid << 8);
lba += (uint)(statusRegisters.LbaMid << 8);
lba += statusRegisters.LbaLow;
}
@@ -153,30 +157,31 @@ 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)
{
buffer = count == 0 ? new byte[512 * 256] : new byte[512 * count];
AtaRegistersLba28 registers = new AtaRegistersLba28
{
SectorCount = count,
DeviceHead = (byte)((lba & 0xF000000) / 0x1000000),
LbaHigh = (byte)((lba & 0xFF0000) / 0x10000),
LbaMid = (byte)((lba & 0xFF00) / 0x100),
LbaLow = (byte)((lba & 0xFF) / 0x1),
Command = retry ? (byte)AtaCommands.ReadRetry : (byte)AtaCommands.Read
DeviceHead = (byte)((lba & 0xF000000) / 0x1000000),
LbaHigh = (byte)((lba & 0xFF0000) / 0x10000),
LbaMid = (byte)((lba & 0xFF00) / 0x100),
LbaLow = (byte)((lba & 0xFF) / 0x1),
Command = retry ? (byte)AtaCommands.ReadRetry : (byte)AtaCommands.Read
};
registers.DeviceHead += 0x40;
LastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.PioIn,
AtaTransferRegister.SectorCount, ref buffer, timeout, true, out duration,
LastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.PioIn,
AtaTransferRegister.SectorCount, ref buffer, timeout, true,
out duration,
out bool sense);
Error = LastError != 0;
@@ -185,30 +190,32 @@ 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
{
SectorCount = 1,
DeviceHead = (byte)((lba & 0xF000000) / 0x1000000),
LbaHigh = (byte)((lba & 0xFF0000) / 0x10000),
LbaMid = (byte)((lba & 0xFF00) / 0x100),
LbaLow = (byte)((lba & 0xFF) / 0x1),
Command = retry ? (byte)AtaCommands.ReadLongRetry : (byte)AtaCommands.ReadLong
DeviceHead = (byte)((lba & 0xF000000) / 0x1000000),
LbaHigh = (byte)((lba & 0xFF0000) / 0x10000),
LbaMid = (byte)((lba & 0xFF00) / 0x100),
LbaLow = (byte)((lba & 0xFF) / 0x1),
Command = retry ? (byte)AtaCommands.ReadLongRetry : (byte)AtaCommands.ReadLong
};
registers.DeviceHead += 0x40;
LastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.PioIn,
AtaTransferRegister.SectorCount, ref buffer, timeout, true, out duration,
LastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.PioIn,
AtaTransferRegister.SectorCount, ref buffer, timeout, true,
out duration,
out bool sense);
Error = LastError != 0;
@@ -222,17 +229,18 @@ namespace DiscImageChef.Devices
byte[] buffer = new byte[0];
AtaRegistersLba28 registers = new AtaRegistersLba28
{
Command = (byte)AtaCommands.Seek,
Command = (byte)AtaCommands.Seek,
DeviceHead = (byte)((lba & 0xF000000) / 0x1000000),
LbaHigh = (byte)((lba & 0xFF0000) / 0x10000),
LbaMid = (byte)((lba & 0xFF00) / 0x100),
LbaLow = (byte)((lba & 0xFF) / 0x1)
LbaHigh = (byte)((lba & 0xFF0000) / 0x10000),
LbaMid = (byte)((lba & 0xFF00) / 0x100),
LbaLow = (byte)((lba & 0xFF) / 0x1)
};
registers.DeviceHead += 0x40;
LastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.NonData,
AtaTransferRegister.NoTransfer, ref buffer, timeout, false, out duration,
LastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.NonData,
AtaTransferRegister.NoTransfer, ref buffer, timeout, false,
out duration,
out bool sense);
Error = LastError != 0;

View File

@@ -37,7 +37,7 @@ namespace DiscImageChef.Devices
{
public partial class Device
{
public bool GetNativeMaxAddressExt(out ulong lba, out AtaErrorRegistersLba48 statusRegisters, uint timeout,
public bool GetNativeMaxAddressExt(out ulong lba, out AtaErrorRegistersLba48 statusRegisters, uint timeout,
out double duration)
{
lba = 0;
@@ -45,14 +45,15 @@ namespace DiscImageChef.Devices
AtaRegistersLba48 registers =
new AtaRegistersLba48 {Command = (byte)AtaCommands.NativeMaxAddress, Feature = 0x0000};
LastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.NonData,
AtaTransferRegister.NoTransfer, ref buffer, timeout, false, out duration,
LastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.NonData,
AtaTransferRegister.NoTransfer, ref buffer, timeout, false,
out duration,
out bool sense);
Error = LastError != 0;
if((statusRegisters.Status & 0x23) == 0)
{
lba = statusRegisters.LbaHigh;
lba = statusRegisters.LbaHigh;
lba *= 0x100000000;
lba += (ulong)(statusRegisters.LbaMid << 16);
lba += statusRegisters.LbaLow;
@@ -63,22 +64,23 @@ 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)
{
buffer = count == 0 ? new byte[512 * 65536] : new byte[512 * count];
AtaRegistersLba48 registers = new AtaRegistersLba48
{
Command = (byte)AtaCommands.ReadDmaExt,
Command = (byte)AtaCommands.ReadDmaExt,
SectorCount = count,
LbaHigh = (ushort)((lba & 0xFFFF00000000) / 0x100000000),
LbaMid = (ushort)((lba & 0xFFFF0000) / 0x10000),
LbaLow = (ushort)((lba & 0xFFFF) / 0x1)
LbaHigh = (ushort)((lba & 0xFFFF00000000) / 0x100000000),
LbaMid = (ushort)((lba & 0xFFFF0000) / 0x10000),
LbaLow = (ushort)((lba & 0xFFFF) / 0x1)
};
registers.DeviceHead += 0x40;
LastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.Dma, AtaTransferRegister.SectorCount,
LastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.Dma,
AtaTransferRegister.SectorCount,
ref buffer, timeout, true, out duration, out bool sense);
Error = LastError != 0;
@@ -87,22 +89,24 @@ 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
{
Command = (byte)AtaCommands.ReadLogExt,
Command = (byte)AtaCommands.ReadLogExt,
SectorCount = count,
LbaLow = (ushort)((pageNumber & 0xFF) * 0x100),
LbaHigh = (ushort)((pageNumber & 0xFF00) / 0x100)
LbaLow = (ushort)((pageNumber & 0xFF) * 0x100),
LbaHigh = (ushort)((pageNumber & 0xFF00) / 0x100)
};
registers.LbaLow += logAddress;
LastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.PioIn,
AtaTransferRegister.SectorCount, ref buffer, timeout, true, out duration,
LastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.PioIn,
AtaTransferRegister.SectorCount, ref buffer, timeout, true,
out duration,
out bool sense);
Error = LastError != 0;
@@ -111,21 +115,23 @@ 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
{
Command = (byte)AtaCommands.ReadLogDmaExt,
Command = (byte)AtaCommands.ReadLogDmaExt,
SectorCount = count,
LbaLow = (ushort)((pageNumber & 0xFF) * 0x100),
LbaHigh = (ushort)((pageNumber & 0xFF00) / 0x100)
LbaLow = (ushort)((pageNumber & 0xFF) * 0x100),
LbaHigh = (ushort)((pageNumber & 0xFF00) / 0x100)
};
registers.LbaLow += logAddress;
LastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.Dma, AtaTransferRegister.SectorCount,
LastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.Dma,
AtaTransferRegister.SectorCount,
ref buffer, timeout, true, out duration, out bool sense);
Error = LastError != 0;
@@ -134,23 +140,25 @@ 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)
{
buffer = count == 0 ? new byte[512 * 65536] : new byte[512 * count];
AtaRegistersLba48 registers = new AtaRegistersLba48
{
Command = (byte)AtaCommands.ReadMultipleExt,
Command = (byte)AtaCommands.ReadMultipleExt,
SectorCount = count,
LbaHigh = (ushort)((lba & 0xFFFF00000000) / 0x100000000),
LbaMid = (ushort)((lba & 0xFFFF0000) / 0x10000),
LbaLow = (ushort)((lba & 0xFFFF) / 0x1)
LbaHigh = (ushort)((lba & 0xFFFF00000000) / 0x100000000),
LbaMid = (ushort)((lba & 0xFFFF0000) / 0x10000),
LbaLow = (ushort)((lba & 0xFFFF) / 0x1)
};
registers.DeviceHead += 0x40;
LastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.PioIn,
AtaTransferRegister.SectorCount, ref buffer, timeout, true, out duration,
LastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.PioIn,
AtaTransferRegister.SectorCount, ref buffer, timeout, true,
out duration,
out bool sense);
Error = LastError != 0;
@@ -159,23 +167,24 @@ namespace DiscImageChef.Devices
return sense;
}
public bool ReadNativeMaxAddress(out ulong lba, out AtaErrorRegistersLba48 statusRegisters, uint timeout,
public bool ReadNativeMaxAddress(out ulong lba, out AtaErrorRegistersLba48 statusRegisters, uint timeout,
out double duration)
{
lba = 0;
byte[] buffer = new byte[0];
byte[] buffer = new byte[0];
AtaRegistersLba48 registers = new AtaRegistersLba48 {Command = (byte)AtaCommands.ReadNativeMaxAddressExt};
registers.DeviceHead += 0x40;
LastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.NonData,
AtaTransferRegister.NoTransfer, ref buffer, timeout, false, out duration,
LastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.NonData,
AtaTransferRegister.NoTransfer, ref buffer, timeout, false,
out duration,
out bool sense);
Error = LastError != 0;
if((statusRegisters.Status & 0x23) == 0)
{
lba = statusRegisters.LbaHigh;
lba = statusRegisters.LbaHigh;
lba *= 0x100000000;
lba += (ulong)(statusRegisters.LbaMid << 16);
lba += statusRegisters.LbaLow;
@@ -186,23 +195,24 @@ 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)
{
buffer = count == 0 ? new byte[512 * 65536] : new byte[512 * count];
AtaRegistersLba48 registers = new AtaRegistersLba48
{
Command = (byte)AtaCommands.ReadExt,
Command = (byte)AtaCommands.ReadExt,
SectorCount = count,
LbaHigh = (ushort)((lba & 0xFFFF00000000) / 0x100000000),
LbaMid = (ushort)((lba & 0xFFFF0000) / 0x10000),
LbaLow = (ushort)((lba & 0xFFFF) / 0x1)
LbaHigh = (ushort)((lba & 0xFFFF00000000) / 0x100000000),
LbaMid = (ushort)((lba & 0xFFFF0000) / 0x10000),
LbaLow = (ushort)((lba & 0xFFFF) / 0x1)
};
registers.DeviceHead += 0x40;
LastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.PioIn,
AtaTransferRegister.SectorCount, ref buffer, timeout, true, out duration,
LastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.PioIn,
AtaTransferRegister.SectorCount, ref buffer, timeout, true,
out duration,
out bool sense);
Error = LastError != 0;

View File

@@ -83,7 +83,7 @@ namespace DiscImageChef.Devices
public bool AtaIdentify(out byte[] buffer, out AtaErrorRegistersChs statusRegisters, uint timeout,
out double duration)
{
buffer = new byte[512];
buffer = new byte[512];
AtaRegistersChs registers = new AtaRegistersChs {Command = (byte)AtaCommands.IdentifyDevice};
LastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.PioIn,
@@ -106,16 +106,16 @@ namespace DiscImageChef.Devices
}
public bool ReadDma(out byte[] buffer, out AtaErrorRegistersChs statusRegisters, bool retry, ushort cylinder,
byte head, byte sector, byte count, uint timeout,
byte head, byte sector, byte count, uint timeout,
out double duration)
{
buffer = count == 0 ? new byte[512 * 256] : new byte[512 * count];
buffer = count == 0 ? new byte[512 * 256] : new byte[512 * count];
AtaRegistersChs registers = new AtaRegistersChs
{
SectorCount = count,
CylinderHigh = (byte)((cylinder & 0xFF00) / 0x100),
CylinderLow = (byte)((cylinder & 0xFF) / 0x1),
DeviceHead = (byte)(head & 0x0F),
DeviceHead = (byte)(head & 0x0F),
Sector = sector,
Command = retry ? (byte)AtaCommands.ReadDmaRetry : (byte)AtaCommands.ReadDma
};
@@ -130,18 +130,18 @@ 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)
{
buffer = count == 0 ? new byte[512 * 256] : new byte[512 * count];
buffer = count == 0 ? new byte[512 * 256] : new byte[512 * count];
AtaRegistersChs registers = new AtaRegistersChs
{
Command = (byte)AtaCommands.ReadMultiple,
SectorCount = count,
CylinderHigh = (byte)((cylinder & 0xFF00) / 0x100),
CylinderLow = (byte)((cylinder & 0xFF) / 0x1),
DeviceHead = (byte)(head & 0x0F),
DeviceHead = (byte)(head & 0x0F),
Sector = sector
};
@@ -157,24 +157,24 @@ namespace DiscImageChef.Devices
}
public bool Read(out byte[] buffer, out AtaErrorRegistersChs statusRegisters, ushort cylinder, byte head,
byte sector, byte count, uint timeout,
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,
byte head, byte sector, byte count, uint timeout,
out double duration)
{
buffer = count == 0 ? new byte[512 * 256] : new byte[512 * count];
buffer = count == 0 ? new byte[512 * 256] : new byte[512 * count];
AtaRegistersChs registers = new AtaRegistersChs
{
Command = retry ? (byte)AtaCommands.ReadRetry : (byte)AtaCommands.Read,
SectorCount = count,
CylinderHigh = (byte)((cylinder & 0xFF00) / 0x100),
CylinderLow = (byte)((cylinder & 0xFF) / 0x1),
DeviceHead = (byte)(head & 0x0F),
DeviceHead = (byte)(head & 0x0F),
Sector = sector
};
@@ -198,18 +198,19 @@ namespace DiscImageChef.Devices
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];
buffer = new byte[blockSize];
AtaRegistersChs registers = new AtaRegistersChs
{
Command = retry ? (byte)AtaCommands.ReadLongRetry : (byte)AtaCommands.ReadLong,
SectorCount = 1,
CylinderHigh = (byte)((cylinder & 0xFF00) / 0x100),
CylinderLow = (byte)((cylinder & 0xFF) / 0x1),
DeviceHead = (byte)(head & 0x0F),
DeviceHead = (byte)(head & 0x0F),
Sector = sector
};
@@ -224,16 +225,16 @@ 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];
byte[] buffer = new byte[0];
AtaRegistersChs registers = new AtaRegistersChs
{
Command = (byte)AtaCommands.Seek,
CylinderHigh = (byte)((cylinder & 0xFF00) / 0x100),
CylinderLow = (byte)((cylinder & 0xFF) / 0x1),
DeviceHead = (byte)(head & 0x0F),
DeviceHead = (byte)(head & 0x0F),
Sector = sector
};
@@ -254,16 +255,16 @@ namespace DiscImageChef.Devices
}
public bool SetFeatures(out AtaErrorRegistersChs statusRegisters, AtaFeatures feature, ushort cylinder,
byte head, byte sector, byte sectorCount,
uint timeout, out double duration)
byte head, byte sector, byte sectorCount,
uint timeout, out double duration)
{
byte[] buffer = new byte[0];
byte[] buffer = new byte[0];
AtaRegistersChs registers = new AtaRegistersChs
{
Command = (byte)AtaCommands.SetFeatures,
CylinderHigh = (byte)((cylinder & 0xFF00) / 0x100),
CylinderLow = (byte)((cylinder & 0xFF) / 0x1),
DeviceHead = (byte)(head & 0x0F),
DeviceHead = (byte)(head & 0x0F),
Sector = sector,
SectorCount = sectorCount,
Feature = (byte)feature

View File

@@ -86,8 +86,9 @@ namespace DiscImageChef.Devices
buffer = new byte[512];
AtaRegistersChs registers = new AtaRegistersChs {Command = (byte)AtaCommands.IdentifyPacketDevice};
LastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.PioIn,
AtaTransferRegister.NoTransfer, ref buffer, timeout, false, out duration,
LastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.PioIn,
AtaTransferRegister.NoTransfer, ref buffer, timeout, false,
out duration,
out bool sense);
Error = LastError != 0;

View File

@@ -37,23 +37,24 @@ 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
{
Command = (byte)AtaCommands.TranslateSector,
Command = (byte)AtaCommands.TranslateSector,
DeviceHead = (byte)((lba & 0xF000000) / 0x1000000),
LbaHigh = (byte)((lba & 0xFF0000) / 0x10000),
LbaMid = (byte)((lba & 0xFF00) / 0x100),
LbaLow = (byte)((lba & 0xFF) / 0x1)
LbaHigh = (byte)((lba & 0xFF0000) / 0x10000),
LbaMid = (byte)((lba & 0xFF00) / 0x100),
LbaLow = (byte)((lba & 0xFF) / 0x1)
};
registers.DeviceHead += 0x40;
LastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.PioIn,
AtaTransferRegister.NoTransfer, ref buffer, timeout, false, out duration,
LastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.PioIn,
AtaTransferRegister.NoTransfer, ref buffer, timeout, false,
out duration,
out bool sense);
Error = LastError != 0;
@@ -63,20 +64,22 @@ namespace DiscImageChef.Devices
}
public bool TranslateSector(out byte[] buffer, out AtaErrorRegistersChs statusRegisters, ushort cylinder,
byte head, byte sector, uint timeout, out double duration)
byte head, byte sector, uint timeout,
out double duration)
{
buffer = new byte[512];
AtaRegistersChs registers = new AtaRegistersChs
{
Command = (byte)AtaCommands.TranslateSector,
Command = (byte)AtaCommands.TranslateSector,
CylinderHigh = (byte)((cylinder & 0xFF00) / 0x100),
CylinderLow = (byte)((cylinder & 0xFF) / 0x1),
Sector = sector,
DeviceHead = (byte)(head & 0x0F)
CylinderLow = (byte)((cylinder & 0xFF) / 0x1),
Sector = sector,
DeviceHead = (byte)(head & 0x0F)
};
LastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.PioIn,
AtaTransferRegister.NoTransfer, ref buffer, timeout, false, out duration,
LastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.PioIn,
AtaTransferRegister.NoTransfer, ref buffer, timeout, false,
out duration,
out bool sense);
Error = LastError != 0;
@@ -86,13 +89,14 @@ namespace DiscImageChef.Devices
}
public bool RequestExtendedErrorCode(out byte errorCode, out AtaErrorRegistersLba28 statusRegisters,
uint timeout, out double duration)
uint timeout, out double duration)
{
byte[] buffer = new byte[0];
byte[] buffer = new byte[0];
AtaRegistersLba28 registers = new AtaRegistersLba28 {Command = (byte)AtaCommands.RequestSense};
LastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.PioIn,
AtaTransferRegister.NoTransfer, ref buffer, timeout, false, out duration,
LastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.PioIn,
AtaTransferRegister.NoTransfer, ref buffer, timeout, false,
out duration,
out bool sense);
Error = LastError != 0;

View File

@@ -38,26 +38,27 @@ namespace DiscImageChef.Devices
public partial class Device
{
public bool EnableMediaCardPassThrough(out AtaErrorRegistersChs statusRegisters, uint timeout,
out double duration)
out double duration)
{
return CheckMediaCardType(1, out statusRegisters, timeout, out duration);
}
public bool DisableMediaCardPassThrough(out AtaErrorRegistersChs statusRegisters, uint timeout,
out double duration)
out double duration)
{
return CheckMediaCardType(0, out statusRegisters, timeout, out duration);
}
public bool CheckMediaCardType(byte feature, out AtaErrorRegistersChs statusRegisters, uint timeout,
public bool CheckMediaCardType(byte feature, out AtaErrorRegistersChs statusRegisters, uint timeout,
out double duration)
{
byte[] buffer = new byte[0];
AtaRegistersChs registers =
new AtaRegistersChs {Command = (byte)AtaCommands.CheckMediaCardType, Feature = feature};
LastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.NonData,
AtaTransferRegister.NoTransfer, ref buffer, timeout, false, out duration,
LastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.NonData,
AtaTransferRegister.NoTransfer, ref buffer, timeout, false,
out duration,
out bool sense);
Error = LastError != 0;

View File

@@ -45,11 +45,12 @@ namespace DiscImageChef.Devices
Command = (byte)AtaCommands.Smart,
Feature = (byte)AtaSmartSubCommands.Disable,
LbaHigh = 0xC2,
LbaMid = 0x4F
LbaMid = 0x4F
};
LastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.NonData,
AtaTransferRegister.NoTransfer, ref buffer, timeout, false, out duration,
LastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.NonData,
AtaTransferRegister.NoTransfer, ref buffer, timeout, false,
out duration,
out bool sense);
Error = LastError != 0;
@@ -59,20 +60,21 @@ namespace DiscImageChef.Devices
}
public bool SmartEnableAttributeAutosave(out AtaErrorRegistersLba28 statusRegisters, uint timeout,
out double duration)
out double duration)
{
byte[] buffer = new byte[0];
AtaRegistersLba28 registers = new AtaRegistersLba28
{
Command = (byte)AtaCommands.Smart,
Feature = (byte)AtaSmartSubCommands.EnableDisableAttributeAutosave,
LbaHigh = 0xC2,
LbaMid = 0x4F,
Command = (byte)AtaCommands.Smart,
Feature = (byte)AtaSmartSubCommands.EnableDisableAttributeAutosave,
LbaHigh = 0xC2,
LbaMid = 0x4F,
SectorCount = 0xF1
};
LastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.NonData,
AtaTransferRegister.NoTransfer, ref buffer, timeout, false, out duration,
LastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.NonData,
AtaTransferRegister.NoTransfer, ref buffer, timeout, false,
out duration,
out bool sense);
Error = LastError != 0;
@@ -82,7 +84,7 @@ namespace DiscImageChef.Devices
}
public bool SmartDisableAttributeAutosave(out AtaErrorRegistersLba28 statusRegisters, uint timeout,
out double duration)
out double duration)
{
byte[] buffer = new byte[0];
AtaRegistersLba28 registers = new AtaRegistersLba28
@@ -90,11 +92,12 @@ namespace DiscImageChef.Devices
Command = (byte)AtaCommands.Smart,
Feature = (byte)AtaSmartSubCommands.EnableDisableAttributeAutosave,
LbaHigh = 0xC2,
LbaMid = 0x4F
LbaMid = 0x4F
};
LastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.NonData,
AtaTransferRegister.NoTransfer, ref buffer, timeout, false, out duration,
LastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.NonData,
AtaTransferRegister.NoTransfer, ref buffer, timeout, false,
out duration,
out bool sense);
Error = LastError != 0;
@@ -111,11 +114,12 @@ namespace DiscImageChef.Devices
Command = (byte)AtaCommands.Smart,
Feature = (byte)AtaSmartSubCommands.Enable,
LbaHigh = 0xC2,
LbaMid = 0x4F
LbaMid = 0x4F
};
LastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.NonData,
AtaTransferRegister.NoTransfer, ref buffer, timeout, false, out duration,
LastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.NonData,
AtaTransferRegister.NoTransfer, ref buffer, timeout, false,
out duration,
out bool sense);
Error = LastError != 0;
@@ -124,8 +128,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
@@ -133,12 +137,13 @@ namespace DiscImageChef.Devices
Command = (byte)AtaCommands.Smart,
Feature = (byte)AtaSmartSubCommands.ExecuteOfflineImmediate,
LbaHigh = 0xC2,
LbaMid = 0x4F,
LbaLow = subcommand
LbaMid = 0x4F,
LbaLow = subcommand
};
LastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.NonData,
AtaTransferRegister.NoTransfer, ref buffer, timeout, false, out duration,
LastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.NonData,
AtaTransferRegister.NoTransfer, ref buffer, timeout, false,
out duration,
out bool sense);
Error = LastError != 0;
@@ -156,11 +161,12 @@ namespace DiscImageChef.Devices
Command = (byte)AtaCommands.Smart,
Feature = (byte)AtaSmartSubCommands.ReadData,
LbaHigh = 0xC2,
LbaMid = 0x4F
LbaMid = 0x4F
};
LastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.PioIn,
AtaTransferRegister.NoTransfer, ref buffer, timeout, false, out duration,
LastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.PioIn,
AtaTransferRegister.NoTransfer, ref buffer, timeout, false,
out duration,
out bool sense);
Error = LastError != 0;
@@ -169,8 +175,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
@@ -178,12 +184,13 @@ namespace DiscImageChef.Devices
Command = (byte)AtaCommands.Smart,
Feature = (byte)AtaSmartSubCommands.ReadLog,
LbaHigh = 0xC2,
LbaMid = 0x4F,
LbaLow = logAddress
LbaMid = 0x4F,
LbaLow = logAddress
};
LastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.PioIn,
AtaTransferRegister.NoTransfer, ref buffer, timeout, false, out duration,
LastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.PioIn,
AtaTransferRegister.NoTransfer, ref buffer, timeout, false,
out duration,
out bool sense);
Error = LastError != 0;
@@ -200,11 +207,12 @@ namespace DiscImageChef.Devices
Command = (byte)AtaCommands.Smart,
Feature = (byte)AtaSmartSubCommands.ReturnStatus,
LbaHigh = 0xC2,
LbaMid = 0x4F
LbaMid = 0x4F
};
LastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.NonData,
AtaTransferRegister.NoTransfer, ref buffer, timeout, false, out duration,
LastError = SendAtaCommand(registers, out statusRegisters, AtaProtocol.NonData,
AtaTransferRegister.NoTransfer, ref buffer, timeout, false,
out duration,
out bool sense);
Error = LastError != 0;

View File

@@ -53,8 +53,8 @@ namespace DiscImageChef.Devices
/// <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, FileHandle, cdb, ref buffer, out senseBuffer, timeout, direction,
out duration, out sense);
@@ -77,8 +77,10 @@ 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, FileHandle, registers, out errorRegisters, protocol,
transferRegister, ref buffer, timeout, transferBlocks, out duration,
@@ -102,8 +104,10 @@ 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, FileHandle, registers, out errorRegisters, protocol,
transferRegister, ref buffer, timeout, transferBlocks, out duration,
@@ -127,8 +131,10 @@ 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, FileHandle, registers, out errorRegisters, protocol,
transferRegister, ref buffer, timeout, transferBlocks, out duration,
@@ -151,9 +157,10 @@ 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,
out double duration, out bool sense, uint timeout = 0)
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)
{
switch(command)
{
@@ -163,7 +170,7 @@ namespace DiscImageChef.Devices
buffer = new byte[cachedCid.Length];
Array.Copy(cachedCid, buffer, buffer.Length);
response = new uint[4];
sense = false;
sense = false;
DateTime end = DateTime.Now;
duration = (end - start).TotalMilliseconds;
return 0;
@@ -174,7 +181,7 @@ namespace DiscImageChef.Devices
buffer = new byte[cachedCsd.Length];
Array.Copy(cachedCsd, buffer, buffer.Length);
response = new uint[4];
sense = false;
sense = false;
DateTime end = DateTime.Now;
duration = (end - start).TotalMilliseconds;
return 0;
@@ -185,7 +192,7 @@ namespace DiscImageChef.Devices
buffer = new byte[cachedScr.Length];
Array.Copy(cachedScr, buffer, buffer.Length);
response = new uint[4];
sense = false;
sense = false;
DateTime end = DateTime.Now;
duration = (end - start).TotalMilliseconds;
return 0;
@@ -203,7 +210,7 @@ namespace DiscImageChef.Devices
buffer = new byte[cachedOcr.Length];
Array.Copy(cachedOcr, buffer, buffer.Length);
response = new uint[4];
sense = false;
sense = false;
DateTime end = DateTime.Now;
duration = (end - start).TotalMilliseconds;
return 0;

View File

@@ -43,7 +43,7 @@ namespace DiscImageChef.Devices
public string Model;
public string Serial;
public string Bus;
public bool Supported;
public bool Supported;
}
public partial class Device
@@ -53,7 +53,7 @@ namespace DiscImageChef.Devices
switch(DetectOS.GetRealPlatformID())
{
case PlatformID.Win32NT: return Windows.ListDevices.GetList();
case PlatformID.Linux: return Linux.ListDevices.GetList();
case PlatformID.Linux: return Linux.ListDevices.GetList();
case PlatformID.FreeBSD: return FreeBSD.ListDevices.GetList();
default:
throw new InvalidOperationException($"Platform {DetectOS.GetRealPlatformID()} not yet supported.");

View File

@@ -40,9 +40,12 @@ namespace DiscImageChef.Devices
{
buffer = new byte[16];
LastError = SendMmcCommand(MmcCommands.SendCsd, false, false,
MmcFlags.ResponseSpiR2 | MmcFlags.ResponseR2 | MmcFlags.CommandAc, 0, 16, 1,
ref buffer, out response, out duration, out bool sense, timeout);
LastError = SendMmcCommand(MmcCommands.SendCsd, false,
false,
MmcFlags.ResponseSpiR2 | MmcFlags.ResponseR2 | MmcFlags.CommandAc, 0,
16, 1,
ref buffer, out response,
out duration, out bool sense, timeout);
Error = LastError != 0;
DicConsole.DebugWriteLine("MMC Device", "SEND_CSD took {0} ms.", duration);
@@ -54,9 +57,12 @@ namespace DiscImageChef.Devices
{
buffer = new byte[16];
LastError = SendMmcCommand(MmcCommands.SendCid, false, false,
MmcFlags.ResponseSpiR2 | MmcFlags.ResponseR2 | MmcFlags.CommandAc, 0, 16, 1,
ref buffer, out response, out duration, out bool sense, timeout);
LastError = SendMmcCommand(MmcCommands.SendCid, false,
false,
MmcFlags.ResponseSpiR2 | MmcFlags.ResponseR2 | MmcFlags.CommandAc, 0,
16, 1,
ref buffer, out response,
out duration, out bool sense, timeout);
Error = LastError != 0;
DicConsole.DebugWriteLine("MMC Device", "SEND_CID took {0} ms.", duration);
@@ -68,9 +74,12 @@ namespace DiscImageChef.Devices
{
buffer = new byte[4];
LastError = SendMmcCommand(MmcCommands.SendOpCond, false, true,
MmcFlags.ResponseSpiR3 | MmcFlags.ResponseR3 | MmcFlags.CommandBcr, 0, 4, 1,
ref buffer, out response, out duration, out bool sense, timeout);
LastError = SendMmcCommand(MmcCommands.SendOpCond, false,
true,
MmcFlags.ResponseSpiR3 | MmcFlags.ResponseR3 | MmcFlags.CommandBcr, 0,
4, 1,
ref buffer, out response,
out duration, out bool sense, timeout);
Error = LastError != 0;
DicConsole.DebugWriteLine("SecureDigital Device", "SEND_OP_COND took {0} ms.", duration);
@@ -82,9 +91,12 @@ namespace DiscImageChef.Devices
{
buffer = new byte[512];
LastError = SendMmcCommand(MmcCommands.SendExtCsd, false, false,
MmcFlags.ResponseSpiR1 | MmcFlags.ResponseR1 | MmcFlags.CommandAdtc, 0, 512, 1,
ref buffer, out response, out duration, out bool sense, timeout);
LastError = SendMmcCommand(MmcCommands.SendExtCsd, false,
false,
MmcFlags.ResponseSpiR1 | MmcFlags.ResponseR1 | MmcFlags.CommandAdtc, 0,
512, 1,
ref buffer,
out response, out duration, out bool sense, timeout);
Error = LastError != 0;
DicConsole.DebugWriteLine("MMC Device", "SEND_EXT_CSD took {0} ms.", duration);
@@ -96,9 +108,12 @@ namespace DiscImageChef.Devices
{
byte[] buffer = new byte[0];
LastError = SendMmcCommand(MmcCommands.SetBlocklen, false, false,
MmcFlags.ResponseSpiR1 | MmcFlags.ResponseR1 | MmcFlags.CommandAc, length, 0, 0,
ref buffer, out response, out duration, out bool sense, timeout);
LastError = SendMmcCommand(MmcCommands.SetBlocklen, false,
false,
MmcFlags.ResponseSpiR1 | MmcFlags.ResponseR1 | MmcFlags.CommandAc, length,
0, 0,
ref buffer, out response,
out duration, out bool sense, timeout);
Error = LastError != 0;
DicConsole.DebugWriteLine("MMC Device", "SET_BLOCKLEN took {0} ms.", duration);
@@ -106,28 +121,34 @@ 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];
uint address;
if(byteAddressed) address = lba * blockSize;
else address = lba;
else address = lba;
MmcCommands command = transferLength > 1 ? MmcCommands.ReadMultipleBlock : MmcCommands.ReadSingleBlock;
LastError = SendMmcCommand(command, false, false,
LastError = SendMmcCommand(command, false,
false,
MmcFlags.ResponseSpiR1 | MmcFlags.ResponseR1 | MmcFlags.CommandAdtc, address,
blockSize, transferLength, ref buffer, out response, out duration,
blockSize,
transferLength, ref buffer, out response, out duration,
out bool sense, timeout);
Error = LastError != 0;
if(transferLength > 1)
{
byte[] foo = new byte[0];
SendMmcCommand(MmcCommands.StopTransmission, false, false,
MmcFlags.ResponseR1B | MmcFlags.ResponseSpiR1B | MmcFlags.CommandAc, 0, 0, 0, ref foo,
out _, out double stopDuration, out bool _, timeout);
SendMmcCommand(MmcCommands.StopTransmission, false,
false,
MmcFlags.ResponseR1B | MmcFlags.ResponseSpiR1B | MmcFlags.CommandAc, 0,
0, 0, ref foo,
out _,
out double stopDuration, out bool _, timeout);
duration += stopDuration;
DicConsole.DebugWriteLine("MMC Device", "READ_MULTIPLE_BLOCK took {0} ms.", duration);
}
@@ -140,9 +161,12 @@ namespace DiscImageChef.Devices
{
buffer = new byte[4];
LastError = SendMmcCommand(MmcCommands.SendStatus, false, true,
MmcFlags.ResponseSpiR1 | MmcFlags.ResponseR1 | MmcFlags.CommandAc, 0, 4, 1,
ref buffer, out response, out duration, out bool sense, timeout);
LastError = SendMmcCommand(MmcCommands.SendStatus, false,
true,
MmcFlags.ResponseSpiR1 | MmcFlags.ResponseR1 | MmcFlags.CommandAc, 0,
4, 1,
ref buffer, out response,
out duration, out bool sense, timeout);
Error = LastError != 0;
DicConsole.DebugWriteLine("SecureDigital Device", "SEND_STATUS took {0} ms.", duration);

View File

@@ -40,9 +40,12 @@ namespace DiscImageChef.Devices
{
buffer = new byte[64];
LastError = SendMmcCommand((MmcCommands)SecureDigitalCommands.SendStatus, false, true,
MmcFlags.ResponseSpiR1 | MmcFlags.ResponseR1 | MmcFlags.CommandAdtc, 0, 64, 1,
ref buffer, out response, out duration, out bool sense, timeout);
LastError = SendMmcCommand((MmcCommands)SecureDigitalCommands.SendStatus, false,
true,
MmcFlags.ResponseSpiR1 | MmcFlags.ResponseR1 | MmcFlags.CommandAdtc, 0,
64, 1,
ref buffer,
out response, out duration, out bool sense, timeout);
Error = LastError != 0;
DicConsole.DebugWriteLine("SecureDigital Device", "SD_STATUS took {0} ms.", duration);
@@ -54,9 +57,12 @@ namespace DiscImageChef.Devices
{
buffer = new byte[4];
LastError = SendMmcCommand((MmcCommands)SecureDigitalCommands.SendOperatingCondition, false, true,
MmcFlags.ResponseSpiR3 | MmcFlags.ResponseR3 | MmcFlags.CommandBcr, 0, 4, 1,
ref buffer, out response, out duration, out bool sense, timeout);
LastError = SendMmcCommand((MmcCommands)SecureDigitalCommands.SendOperatingCondition, false,
true,
MmcFlags.ResponseSpiR3 | MmcFlags.ResponseR3 | MmcFlags.CommandBcr, 0,
4, 1,
ref buffer, out response,
out duration, out bool sense, timeout);
Error = LastError != 0;
DicConsole.DebugWriteLine("SecureDigital Device", "SD_SEND_OP_COND took {0} ms.", duration);
@@ -68,9 +74,12 @@ namespace DiscImageChef.Devices
{
buffer = new byte[8];
LastError = SendMmcCommand((MmcCommands)SecureDigitalCommands.SendScr, false, true,
MmcFlags.ResponseSpiR1 | MmcFlags.ResponseR1 | MmcFlags.CommandAdtc, 0, 8, 1,
ref buffer, out response, out duration, out bool sense, timeout);
LastError = SendMmcCommand((MmcCommands)SecureDigitalCommands.SendScr, false,
true,
MmcFlags.ResponseSpiR1 | MmcFlags.ResponseR1 | MmcFlags.CommandAdtc, 0,
8, 1,
ref buffer,
out response, out duration, out bool sense, timeout);
Error = LastError != 0;
DicConsole.DebugWriteLine("SecureDigital Device", "SEND_SCR took {0} ms.", duration);

View File

@@ -70,7 +70,7 @@ namespace DiscImageChef.Devices
cdb[0] = (byte)ScsiCommands.AdaptecTranslate;
cdb[1] = (byte)((lba & 0x1F0000) >> 16);
cdb[2] = (byte)((lba & 0xFF00) >> 8);
cdb[2] = (byte)((lba & 0xFF00) >> 8);
cdb[3] = (byte)(lba & 0xFF);
if(drive1) cdb[1] += 0x20;
@@ -105,7 +105,7 @@ 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,
public bool AdaptecSetErrorThreshold(byte threshold, out byte[] senseBuffer, bool drive1, uint timeout,
out double duration)
{
byte[] buffer = new byte[1];

View File

@@ -53,7 +53,7 @@ namespace DiscImageChef.Devices
cdb[0] = (byte)ScsiCommands.ArchiveRequestBlockAddress;
cdb[1] = (byte)((lba & 0x1F0000) >> 16);
cdb[2] = (byte)((lba & 0xFF00) >> 8);
cdb[2] = (byte)((lba & 0xFF00) >> 8);
cdb[3] = (byte)(lba & 0xFF);
cdb[4] = 3;
@@ -90,12 +90,12 @@ namespace DiscImageChef.Devices
out double duration)
{
byte[] buffer = new byte[0];
byte[] cdb = new byte[6];
byte[] cdb = new byte[6];
senseBuffer = new byte[32];
cdb[0] = (byte)ScsiCommands.ArchiveSeekBlock;
cdb[1] = (byte)((lba & 0x1F0000) >> 16);
cdb[2] = (byte)((lba & 0xFF00) >> 8);
cdb[2] = (byte)((lba & 0xFF00) >> 8);
cdb[3] = (byte)(lba & 0xFF);
if(immediate) cdb[1] += 0x01;

View File

@@ -70,7 +70,7 @@ namespace DiscImageChef.Devices
public bool CertanceParkUnpark(out byte[] senseBuffer, bool park, uint timeout, out double duration)
{
byte[] buffer = new byte[0];
byte[] cdb = new byte[6];
byte[] cdb = new byte[6];
senseBuffer = new byte[32];
cdb[0] = (byte)ScsiCommands.CertanceParkUnpark;

View File

@@ -38,22 +38,23 @@ 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];
byte[] firstHalfBytes = new byte[8];
byte[] secondHalfBytes = new byte[8];
byte[] buffer = new byte[17];
bool displayLen = false;
bool halfMsg = false;
byte[] cdb = new byte[10];
byte[] buffer = new byte[17];
bool displayLen = false;
bool halfMsg = false;
byte[] cdb = new byte[10];
if(!string.IsNullOrWhiteSpace(firstHalf))
{
tmp = Encoding.ASCII.GetBytes(firstHalf);
Array.Copy(tmp, 0, firstHalfBytes, 0, 8);
}
if(!string.IsNullOrWhiteSpace(secondHalf))
{
tmp = Encoding.ASCII.GetBytes(secondHalf);
@@ -62,17 +63,18 @@ namespace DiscImageChef.Devices
if(mode != FujitsuDisplayModes.Half)
if(!ArrayHelpers.ArrayIsNullOrWhiteSpace(firstHalfBytes) &&
!ArrayHelpers.ArrayIsNullOrWhiteSpace(secondHalfBytes)) displayLen = true;
!ArrayHelpers.ArrayIsNullOrWhiteSpace(secondHalfBytes))
displayLen = true;
else if(!ArrayHelpers.ArrayIsNullOrWhiteSpace(firstHalfBytes) &&
ArrayHelpers.ArrayIsNullOrWhiteSpace(secondHalfBytes)) halfMsg = true;
buffer[0] = (byte)((byte)mode << 5);
if(displayLen) buffer[0] += 0x10;
if(flash) buffer[0] += 0x08;
if(halfMsg) buffer[0] += 0x04;
if(flash) buffer[0] += 0x08;
if(halfMsg) buffer[0] += 0x04;
buffer[0] += 0x01; // Always ASCII
Array.Copy(firstHalfBytes, 0, buffer, 1, 8);
Array.Copy(firstHalfBytes, 0, buffer, 1, 8);
Array.Copy(secondHalfBytes, 0, buffer, 9, 8);
cdb[0] = (byte)ScsiCommands.FujitsuDisplay;

View File

@@ -46,22 +46,22 @@ 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];
buffer = new byte[2064 * transferLength];
cdb[0] = (byte)ScsiCommands.HlDtStVendor;
cdb[1] = 0x48;
cdb[2] = 0x49;
cdb[3] = 0x54;
cdb[4] = 0x01;
cdb[6] = (byte)((lba & 0xFF000000) >> 24);
cdb[7] = (byte)((lba & 0xFF0000) >> 16);
cdb[8] = (byte)((lba & 0xFF00) >> 8);
cdb[9] = (byte)(lba & 0xFF);
cdb[0] = (byte)ScsiCommands.HlDtStVendor;
cdb[1] = 0x48;
cdb[2] = 0x49;
cdb[3] = 0x54;
cdb[4] = 0x01;
cdb[6] = (byte)((lba & 0xFF000000) >> 24);
cdb[7] = (byte)((lba & 0xFF0000) >> 16);
cdb[8] = (byte)((lba & 0xFF00) >> 8);
cdb[9] = (byte)(lba & 0xFF);
cdb[10] = (byte)((buffer.Length & 0xFF00) >> 8);
cdb[11] = (byte)(buffer.Length & 0xFF);

View File

@@ -48,8 +48,9 @@ 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);
@@ -72,8 +73,9 @@ namespace DiscImageChef.Devices
/// </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,
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];
@@ -82,12 +84,12 @@ namespace DiscImageChef.Devices
cdb[0] = (byte)ScsiCommands.ReadLong;
if(relAddr) cdb[1] += 0x01;
cdb[2] = (byte)((address & 0xFF000000) >> 24);
cdb[3] = (byte)((address & 0xFF0000) >> 16);
cdb[4] = (byte)((address & 0xFF00) >> 8);
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(pba) cdb[9] += 0x80;
if(sectorCount) cdb[9] += 0x40;
buffer = sectorCount ? new byte[blockBytes * transferLen] : new byte[transferLen];

View File

@@ -47,7 +47,7 @@ namespace DiscImageChef.Devices
public bool KreonDeprecatedUnlock(out byte[] senseBuffer, uint timeout, out double duration)
{
senseBuffer = new byte[32];
byte[] cdb = new byte[6];
byte[] cdb = new byte[6];
byte[] buffer = new byte[0];
cdb[0] = (byte)ScsiCommands.KreonCommand;
@@ -111,7 +111,7 @@ namespace DiscImageChef.Devices
public bool KreonSetLockState(out byte[] senseBuffer, KreonLockStates state, uint timeout, out double duration)
{
senseBuffer = new byte[32];
byte[] cdb = new byte[6];
byte[] cdb = new byte[6];
byte[] buffer = new byte[0];
cdb[0] = (byte)ScsiCommands.KreonCommand;
@@ -141,7 +141,7 @@ namespace DiscImageChef.Devices
out double duration)
{
senseBuffer = new byte[32];
byte[] cdb = new byte[6];
byte[] cdb = new byte[6];
byte[] buffer = new byte[26];
features = 0;
@@ -214,22 +214,22 @@ namespace DiscImageChef.Devices
/// <param name="buffer">The SS sector.</param>
/// <param name="requestNumber">Request number.</param>
public bool KreonExtractSs(out byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration,
byte requestNumber = 0x00)
byte requestNumber = 0x00)
{
buffer = new byte[2048];
byte[] cdb = new byte[12];
senseBuffer = new byte[32];
cdb[0] = (byte)ScsiCommands.KreonSsCommand;
cdb[1] = 0x00;
cdb[2] = 0xFF;
cdb[3] = 0x02;
cdb[4] = 0xFD;
cdb[5] = 0xFF;
cdb[6] = 0xFE;
cdb[7] = 0x00;
cdb[8] = 0x08;
cdb[9] = 0x00;
cdb[0] = (byte)ScsiCommands.KreonSsCommand;
cdb[1] = 0x00;
cdb[2] = 0xFF;
cdb[3] = 0x02;
cdb[4] = 0xFD;
cdb[5] = 0xFF;
cdb[6] = 0xFE;
cdb[7] = 0x00;
cdb[8] = 0x08;
cdb[9] = 0x00;
cdb[10] = requestNumber;
cdb[11] = 0xC0;

View File

@@ -61,7 +61,7 @@ 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,
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,
@@ -78,19 +78,20 @@ 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];
buffer = new byte[8];
byte[] cdb = new byte[10];
buffer = new byte[8];
cdb[0] = (byte)ScsiCommands.GetConfiguration;
cdb[1] = (byte)((byte)rt & 0x03);
cdb[1] = (byte)((byte)rt & 0x03);
cdb[2] = (byte)((startingFeatureNumber & 0xFF00) >> 8);
cdb[3] = (byte)(startingFeatureNumber & 0xFF);
cdb[7] = (byte)((buffer.Length & 0xFF00) >> 8);
cdb[8] = (byte)(buffer.Length & 0xFF);
cdb[3] = (byte)(startingFeatureNumber & 0xFF);
cdb[7] = (byte)((buffer.Length & 0xFF00) >> 8);
cdb[8] = (byte)(buffer.Length & 0xFF);
cdb[9] = 0;
LastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
@@ -100,10 +101,10 @@ namespace DiscImageChef.Devices
if(sense) return true;
ushort confLength = (ushort)((buffer[2] << 8) + buffer[3] + 4);
buffer = new byte[confLength];
cdb[7] = (byte)((buffer.Length & 0xFF00) >> 8);
cdb[8] = (byte)(buffer.Length & 0xFF);
senseBuffer = new byte[32];
buffer = new byte[confLength];
cdb[7] = (byte)((buffer.Length & 0xFF00) >> 8);
cdb[8] = (byte)(buffer.Length & 0xFF);
senseBuffer = new byte[32];
LastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
out sense);
@@ -127,26 +128,26 @@ 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,
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];
buffer = new byte[8];
byte[] cdb = new byte[12];
buffer = new byte[8];
cdb[0] = (byte)ScsiCommands.ReadDiscStructure;
cdb[1] = (byte)((byte)mediaType & 0x0F);
cdb[2] = (byte)((address & 0xFF000000) >> 24);
cdb[3] = (byte)((address & 0xFF0000) >> 16);
cdb[4] = (byte)((address & 0xFF00) >> 8);
cdb[5] = (byte)(address & 0xFF);
cdb[2] = (byte)((address & 0xFF000000) >> 24);
cdb[3] = (byte)((address & 0xFF0000) >> 16);
cdb[4] = (byte)((address & 0xFF00) >> 8);
cdb[5] = (byte)(address & 0xFF);
cdb[6] = layerNumber;
cdb[7] = (byte)format;
cdb[8] = (byte)((buffer.Length & 0xFF00) >> 8);
cdb[9] = (byte)(buffer.Length & 0xFF);
cdb[10] = (byte)((agid & 0x03) << 6);
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 bool sense);
@@ -155,10 +156,9 @@ namespace DiscImageChef.Devices
if(sense) return true;
ushort strctLength = (ushort)((buffer[0] << 8) + buffer[1] + 2);
// WORKAROUND: Some drives return incorrect length information. As these structures are fixed length just apply known length.
if(mediaType == MmcDiscStructureMediaType.Bd)
{
switch(format)
{
case MmcDiscStructureFormat.DiscInformation:
@@ -180,12 +180,10 @@ namespace DiscImageChef.Devices
buffer = new byte[strctLength];
break;
}
}
else
buffer = new byte[strctLength];
cdb[8] = (byte)((buffer.Length & 0xFF00) >> 8);
cdb[9] = (byte)(buffer.Length & 0xFF);
senseBuffer = new byte[32];
else buffer = new byte[strctLength];
cdb[8] = (byte)((buffer.Length & 0xFF00) >> 8);
cdb[9] = (byte)(buffer.Length & 0xFF);
senseBuffer = new byte[32];
LastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
out sense);
@@ -319,27 +317,27 @@ 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[] cdb = new byte[10];
byte[] tmpBuffer = (format & 0x0F) == 5 ? new byte[32768] : new byte[1024];
cdb[0] = (byte)ScsiCommands.ReadTocPmaAtip;
cdb[0] = (byte)ScsiCommands.ReadTocPmaAtip;
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);
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 bool sense);
Error = LastError != 0;
uint strctLength = (uint)((tmpBuffer[0] << 8) + tmpBuffer[1] + 2);
buffer = new byte[strctLength];
buffer = new byte[strctLength];
if(buffer.Length <= tmpBuffer.Length)
{
@@ -386,23 +384,23 @@ namespace DiscImageChef.Devices
MmcDiscInformationDataTypes dataType,
uint timeout, out double duration)
{
senseBuffer = new byte[32];
senseBuffer = new byte[32];
byte[] cdb = new byte[10];
byte[] tmpBuffer = new byte[804];
cdb[0] = (byte)ScsiCommands.ReadDiscInformation;
cdb[1] = (byte)dataType;
cdb[7] = (byte)((tmpBuffer.Length & 0xFF00) >> 8);
cdb[8] = (byte)(tmpBuffer.Length & 0xFF);
cdb[8] = (byte)(tmpBuffer.Length & 0xFF);
LastError = SendScsiCommand(cdb, ref tmpBuffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
out bool sense);
Error = LastError != 0;
uint strctLength = (uint)((tmpBuffer[0] << 8) + tmpBuffer[1] + 2);
uint strctLength = (uint)((tmpBuffer[0] << 8) + tmpBuffer[1] + 2);
if(strctLength > tmpBuffer.Length) strctLength = (uint)tmpBuffer.Length;
buffer = new byte[strctLength];
buffer = new byte[strctLength];
Array.Copy(tmpBuffer, 0, buffer, 0, buffer.Length);
DicConsole.DebugWriteLine("SCSI Device", "READ DISC INFORMATION took {0} ms.", duration);
@@ -430,32 +428,34 @@ 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];
byte[] cdb = new byte[12];
cdb[0] = (byte)ScsiCommands.ReadCd;
cdb[1] = (byte)((byte)expectedSectorType << 2);
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);
cdb[5] = (byte)(lba & 0xFF);
cdb[6] = (byte)((transferLength & 0xFF0000) >> 16);
cdb[7] = (byte)((transferLength & 0xFF00) >> 8);
cdb[8] = (byte)(transferLength & 0xFF);
cdb[9] = (byte)((byte)c2Error << 1);
cdb[9] += (byte)((byte)headerCodes << 5);
cdb[0] = (byte)ScsiCommands.ReadCd;
cdb[1] = (byte)((byte)expectedSectorType << 2);
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);
cdb[5] = (byte)(lba & 0xFF);
cdb[6] = (byte)((transferLength & 0xFF0000) >> 16);
cdb[7] = (byte)((transferLength & 0xFF00) >> 8);
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;
cdb[10] = (byte)subchannel;
cdb[10] = (byte)subchannel;
buffer = new byte[blockSize * transferLength];
@@ -487,32 +487,32 @@ 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,
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,
bool userData, bool edcEcc, MmcErrorField c2Error,
MmcSubchannel subchannel, uint timeout,
out double duration)
{
senseBuffer = new byte[32];
byte[] cdb = new byte[12];
byte[] cdb = new byte[12];
cdb[0] = (byte)ScsiCommands.ReadCdMsf;
cdb[1] = (byte)((byte)expectedSectorType << 2);
if(dap) cdb[1] += 0x02;
cdb[3] = (byte)((startMsf & 0xFF0000) >> 16);
cdb[4] = (byte)((startMsf & 0xFF00) >> 8);
cdb[5] = (byte)(startMsf & 0xFF);
cdb[6] = (byte)((endMsf & 0xFF0000) >> 16);
cdb[7] = (byte)((endMsf & 0xFF00) >> 8);
cdb[8] = (byte)(endMsf & 0xFF);
cdb[9] = (byte)((byte)c2Error << 1);
cdb[9] += (byte)((byte)headerCodes << 5);
cdb[0] = (byte)ScsiCommands.ReadCdMsf;
cdb[1] = (byte)((byte)expectedSectorType << 2);
if(dap) cdb[1] += 0x02;
cdb[3] = (byte)((startMsf & 0xFF0000) >> 16);
cdb[4] = (byte)((startMsf & 0xFF00) >> 8);
cdb[5] = (byte)(startMsf & 0xFF);
cdb[6] = (byte)((endMsf & 0xFF0000) >> 16);
cdb[7] = (byte)((endMsf & 0xFF00) >> 8);
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;
cdb[10] = (byte)subchannel;
cdb[10] = (byte)subchannel;
uint transferLength = (uint)((cdb[6] - cdb[3]) * 60 * 75 + (cdb[7] - cdb[4]) * 75 + (cdb[8] - cdb[5]));
@@ -540,11 +540,11 @@ namespace DiscImageChef.Devices
public bool PreventAllowMediumRemoval(out byte[] senseBuffer, bool persistent, bool prevent, uint timeout,
out double duration)
{
senseBuffer = new byte[32];
senseBuffer = new byte[32];
byte[] cdb = new byte[6];
byte[] buffer = new byte[0];
cdb[0] = (byte)ScsiCommands.PreventAllowMediumRemoval;
cdb[0] = (byte)ScsiCommands.PreventAllowMediumRemoval;
if(prevent) cdb[4] += 0x01;
if(persistent) cdb[4] += 0x02;
@@ -577,15 +577,15 @@ 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,
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];
senseBuffer = new byte[32];
byte[] cdb = new byte[6];
byte[] buffer = new byte[0];
cdb[0] = (byte)ScsiCommands.StartStopUnit;
cdb[0] = (byte)ScsiCommands.StartStopUnit;
if(immediate) cdb[1] += 0x01;
if(changeFormatLayer)
{
@@ -613,15 +613,15 @@ namespace DiscImageChef.Devices
out double duration)
{
senseBuffer = new byte[32];
byte[] cdb = new byte[10];
mcn = null;
byte[] cdb = new byte[10];
mcn = null;
cdb[0] = (byte)ScsiCommands.ReadSubChannel;
cdb[1] = 0;
cdb[2] = 0x40;
cdb[3] = 0x02;
cdb[7] = (23 & 0xFF00) >> 8;
cdb[8] = 23 & 0xFF;
cdb[8] = 23 & 0xFF;
buffer = new byte[23];
@@ -636,12 +636,13 @@ namespace DiscImageChef.Devices
return sense;
}
public bool ReadIsrc(byte trackNumber, out string isrc, out byte[] buffer, out byte[] senseBuffer, uint timeout,
out double duration)
public bool ReadIsrc(byte trackNumber, out string isrc, out byte[] buffer, out byte[] senseBuffer,
uint timeout,
out double duration)
{
senseBuffer = new byte[32];
byte[] cdb = new byte[10];
isrc = null;
byte[] cdb = new byte[10];
isrc = null;
cdb[0] = (byte)ScsiCommands.ReadSubChannel;
cdb[1] = 0;
@@ -649,7 +650,7 @@ namespace DiscImageChef.Devices
cdb[3] = 0x03;
cdb[6] = trackNumber;
cdb[7] = (23 & 0xFF00) >> 8;
cdb[8] = 23 & 0xFF;
cdb[8] = 23 & 0xFF;
buffer = new byte[23];

View File

@@ -54,8 +54,8 @@ namespace DiscImageChef.Devices
cdb[0] = (byte)ScsiCommands.NecReadCdDa;
cdb[2] = (byte)((lba & 0xFF000000) >> 24);
cdb[3] = (byte)((lba & 0xFF0000) >> 16);
cdb[4] = (byte)((lba & 0xFF00) >> 8);
cdb[3] = (byte)((lba & 0xFF0000) >> 16);
cdb[4] = (byte)((lba & 0xFF00) >> 8);
cdb[5] = (byte)(lba & 0xFF);
cdb[7] = (byte)((transferLength & 0xFF00) >> 8);
cdb[8] = (byte)(transferLength & 0xFF);

View File

@@ -48,21 +48,21 @@ 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,
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];
cdb[0] = (byte)ScsiCommands.ReadCdDa;
cdb[2] = (byte)((lba & 0xFF000000) >> 24);
cdb[3] = (byte)((lba & 0xFF0000) >> 16);
cdb[4] = (byte)((lba & 0xFF00) >> 8);
cdb[5] = (byte)(lba & 0xFF);
cdb[7] = (byte)((transferLength & 0xFF0000) >> 16);
cdb[8] = (byte)((transferLength & 0xFF00) >> 8);
cdb[9] = (byte)(transferLength & 0xFF);
cdb[0] = (byte)ScsiCommands.ReadCdDa;
cdb[2] = (byte)((lba & 0xFF000000) >> 24);
cdb[3] = (byte)((lba & 0xFF0000) >> 16);
cdb[4] = (byte)((lba & 0xFF00) >> 8);
cdb[5] = (byte)(lba & 0xFF);
cdb[7] = (byte)((transferLength & 0xFF0000) >> 16);
cdb[8] = (byte)((transferLength & 0xFF00) >> 8);
cdb[9] = (byte)(transferLength & 0xFF);
cdb[10] = (byte)subchannel;
buffer = new byte[blockSize * transferLength];
@@ -88,19 +88,21 @@ 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];
cdb[0] = (byte)ScsiCommands.ReadCdDaMsf;
cdb[3] = (byte)((startMsf & 0xFF0000) >> 16);
cdb[4] = (byte)((startMsf & 0xFF00) >> 8);
cdb[5] = (byte)(startMsf & 0xFF);
cdb[7] = (byte)((endMsf & 0xFF0000) >> 16);
cdb[8] = (byte)((endMsf & 0xFF00) >> 8);
cdb[9] = (byte)(endMsf & 0xFF);
cdb[0] = (byte)ScsiCommands.ReadCdDaMsf;
cdb[3] = (byte)((startMsf & 0xFF0000) >> 16);
cdb[4] = (byte)((startMsf & 0xFF00) >> 8);
cdb[5] = (byte)(startMsf & 0xFF);
cdb[7] = (byte)((endMsf & 0xFF0000) >> 16);
cdb[8] = (byte)((endMsf & 0xFF00) >> 8);
cdb[9] = (byte)(endMsf & 0xFF);
cdb[10] = (byte)subchannel;
uint transferLength = (uint)((cdb[7] - cdb[3]) * 60 * 75 + (cdb[8] - cdb[4]) * 75 + (cdb[9] - cdb[5]));
@@ -130,19 +132,20 @@ 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];
cdb[0] = (byte)ScsiCommands.ReadCdXa;
cdb[2] = (byte)((lba & 0xFF000000) >> 24);
cdb[3] = (byte)((lba & 0xFF0000) >> 16);
cdb[4] = (byte)((lba & 0xFF00) >> 8);
cdb[3] = (byte)((lba & 0xFF0000) >> 16);
cdb[4] = (byte)((lba & 0xFF00) >> 8);
cdb[5] = (byte)(lba & 0xFF);
cdb[7] = (byte)((transferLength & 0xFF0000) >> 16);
cdb[8] = (byte)((transferLength & 0xFF00) >> 8);
cdb[8] = (byte)((transferLength & 0xFF00) >> 8);
cdb[9] = (byte)(transferLength & 0xFF);
if(errorFlags)

View File

@@ -48,8 +48,8 @@ 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);
@@ -72,12 +72,13 @@ namespace DiscImageChef.Devices
/// </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,
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);
timeout, out duration);
}
/// <summary>
@@ -90,16 +91,16 @@ 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];
cdb[0] = (byte)ScsiCommands.PlasmonReadSectorLocation;
cdb[2] = (byte)((address & 0xFF000000) >> 24);
cdb[3] = (byte)((address & 0xFF0000) >> 16);
cdb[4] = (byte)((address & 0xFF00) >> 8);
cdb[3] = (byte)((address & 0xFF0000) >> 16);
cdb[4] = (byte)((address & 0xFF00) >> 8);
cdb[5] = (byte)(address & 0xFF);
if(pba) cdb[9] += 0x80;

View File

@@ -49,22 +49,22 @@ 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,
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];
cdb[0] = (byte)ScsiCommands.ReadCdDa;
cdb[2] = (byte)((lba & 0xFF000000) >> 24);
cdb[3] = (byte)((lba & 0xFF0000) >> 16);
cdb[4] = (byte)((lba & 0xFF00) >> 8);
cdb[5] = (byte)(lba & 0xFF);
cdb[6] = (byte)((transferLength & 0xFF000000) >> 24);
cdb[7] = (byte)((transferLength & 0xFF0000) >> 16);
cdb[8] = (byte)((transferLength & 0xFF00) >> 8);
cdb[9] = (byte)(transferLength & 0xFF);
cdb[0] = (byte)ScsiCommands.ReadCdDa;
cdb[2] = (byte)((lba & 0xFF000000) >> 24);
cdb[3] = (byte)((lba & 0xFF0000) >> 16);
cdb[4] = (byte)((lba & 0xFF00) >> 8);
cdb[5] = (byte)(lba & 0xFF);
cdb[6] = (byte)((transferLength & 0xFF000000) >> 24);
cdb[7] = (byte)((transferLength & 0xFF0000) >> 16);
cdb[8] = (byte)((transferLength & 0xFF00) >> 8);
cdb[9] = (byte)(transferLength & 0xFF);
cdb[10] = (byte)subchannel;
buffer = new byte[blockSize * transferLength];
@@ -88,8 +88,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];
@@ -98,10 +98,10 @@ namespace DiscImageChef.Devices
cdb[0] = (byte)ScsiCommands.ReadBuffer;
cdb[1] = 0x02;
cdb[3] = (byte)((lba & 0xFF0000) >> 16);
cdb[4] = (byte)((lba & 0xFF00) >> 8);
cdb[4] = (byte)((lba & 0xFF00) >> 8);
cdb[5] = (byte)(lba & 0xFF);
cdb[3] = (byte)((buffer.Length & 0xFF0000) >> 16);
cdb[4] = (byte)((buffer.Length & 0xFF00) >> 8);
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,
@@ -123,7 +123,7 @@ namespace DiscImageChef.Devices
/// <param name="duration">Duration.</param>
public bool PlextorReadEepromCdr(out byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration)
{
buffer = new byte[256];
buffer = new byte[256];
senseBuffer = new byte[32];
byte[] cdb = new byte[12];
@@ -149,7 +149,7 @@ namespace DiscImageChef.Devices
/// <param name="duration">Duration.</param>
public bool PlextorReadEeprom(out byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration)
{
buffer = new byte[512];
buffer = new byte[512];
senseBuffer = new byte[32];
byte[] cdb = new byte[12];
@@ -175,10 +175,10 @@ 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];
buffer = new byte[blockSize];
senseBuffer = new byte[32];
byte[] cdb = new byte[12];
@@ -208,15 +208,15 @@ namespace DiscImageChef.Devices
/// <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)
uint timeout, out double duration)
{
byte[] buf = new byte[10];
senseBuffer = new byte[32];
byte[] cdb = new byte[12];
selected = 0;
max = 0;
last = 0;
max = 0;
last = 0;
cdb[0] = (byte)ScsiCommands.PlextorPoweRec;
cdb[9] = (byte)buf.Length;
@@ -230,9 +230,9 @@ namespace DiscImageChef.Devices
if(sense || Error) return sense;
BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian;
selected = BigEndianBitConverter.ToUInt16(buf, 4);
max = BigEndianBitConverter.ToUInt16(buf, 6);
last = BigEndianBitConverter.ToUInt16(buf, 8);
selected = BigEndianBitConverter.ToUInt16(buf, 4);
max = BigEndianBitConverter.ToUInt16(buf, 6);
last = BigEndianBitConverter.ToUInt16(buf, 8);
return false;
}
@@ -254,7 +254,7 @@ namespace DiscImageChef.Devices
byte[] cdb = new byte[12];
enabled = false;
speed = 0;
speed = 0;
cdb[0] = (byte)ScsiCommands.PlextorExtend2;
cdb[1] = (byte)PlextorSubCommands.GetMode;
@@ -269,8 +269,8 @@ namespace DiscImageChef.Devices
if(sense || Error) return sense;
BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian;
enabled = buf[2] != 0;
speed = BigEndianBitConverter.ToUInt16(buf, 4);
enabled = buf[2] != 0;
speed = BigEndianBitConverter.ToUInt16(buf, 4);
return false;
}
@@ -285,14 +285,14 @@ namespace DiscImageChef.Devices
/// <param name="duration">Duration.</param>
public bool PlextorGetSilentMode(out byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration)
{
buffer = new byte[8];
buffer = new byte[8];
senseBuffer = new byte[32];
byte[] cdb = new byte[12];
cdb[0] = (byte)ScsiCommands.PlextorExtend;
cdb[1] = (byte)PlextorSubCommands.GetMode;
cdb[2] = (byte)PlextorSubCommands.Silent;
cdb[3] = 4;
cdb[0] = (byte)ScsiCommands.PlextorExtend;
cdb[1] = (byte)PlextorSubCommands.GetMode;
cdb[2] = (byte)PlextorSubCommands.Silent;
cdb[3] = 4;
cdb[10] = (byte)buffer.Length;
LastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
@@ -314,13 +314,13 @@ namespace DiscImageChef.Devices
/// <param name="duration">Duration.</param>
public bool PlextorGetGigaRec(out byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration)
{
buffer = new byte[8];
buffer = new byte[8];
senseBuffer = new byte[32];
byte[] cdb = new byte[12];
cdb[0] = (byte)ScsiCommands.PlextorExtend;
cdb[1] = (byte)PlextorSubCommands.GetMode;
cdb[2] = (byte)PlextorSubCommands.GigaRec;
cdb[0] = (byte)ScsiCommands.PlextorExtend;
cdb[1] = (byte)PlextorSubCommands.GetMode;
cdb[2] = (byte)PlextorSubCommands.GigaRec;
cdb[10] = (byte)buffer.Length;
LastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
@@ -344,17 +344,17 @@ namespace DiscImageChef.Devices
public bool PlextorGetVariRec(out byte[] buffer, out byte[] senseBuffer, bool dvd, uint timeout,
out double duration)
{
buffer = new byte[8];
buffer = new byte[8];
senseBuffer = new byte[32];
byte[] cdb = new byte[12];
cdb[0] = (byte)ScsiCommands.PlextorExtend;
cdb[1] = (byte)PlextorSubCommands.GetMode;
cdb[2] = (byte)PlextorSubCommands.VariRec;
cdb[0] = (byte)ScsiCommands.PlextorExtend;
cdb[1] = (byte)PlextorSubCommands.GetMode;
cdb[2] = (byte)PlextorSubCommands.VariRec;
cdb[10] = (byte)buffer.Length;
if(dvd) cdb[3] = 0x12;
else cdb[3] = 0x02;
else cdb[3] = 0x02;
LastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
out bool sense);
@@ -375,12 +375,12 @@ namespace DiscImageChef.Devices
/// <param name="duration">Duration.</param>
public bool PlextorGetSecuRec(out byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration)
{
buffer = new byte[8];
buffer = new byte[8];
senseBuffer = new byte[32];
byte[] cdb = new byte[12];
cdb[0] = (byte)ScsiCommands.PlextorExtend;
cdb[2] = (byte)PlextorSubCommands.SecuRec;
cdb[0] = (byte)ScsiCommands.PlextorExtend;
cdb[2] = (byte)PlextorSubCommands.SecuRec;
cdb[10] = (byte)buffer.Length;
LastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
@@ -402,13 +402,13 @@ namespace DiscImageChef.Devices
/// <param name="duration">Duration.</param>
public bool PlextorGetSpeedRead(out byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration)
{
buffer = new byte[8];
buffer = new byte[8];
senseBuffer = new byte[32];
byte[] cdb = new byte[12];
cdb[0] = (byte)ScsiCommands.PlextorExtend;
cdb[1] = (byte)PlextorSubCommands.GetMode;
cdb[2] = (byte)PlextorSubCommands.SpeedRead;
cdb[0] = (byte)ScsiCommands.PlextorExtend;
cdb[1] = (byte)PlextorSubCommands.GetMode;
cdb[2] = (byte)PlextorSubCommands.SpeedRead;
cdb[10] = (byte)buffer.Length;
LastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
@@ -430,7 +430,7 @@ namespace DiscImageChef.Devices
/// <param name="duration">Duration.</param>
public bool PlextorGetHiding(out byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration)
{
buffer = new byte[8];
buffer = new byte[8];
senseBuffer = new byte[32];
byte[] cdb = new byte[12];
@@ -460,7 +460,7 @@ namespace DiscImageChef.Devices
public bool PlextorGetBitsetting(out byte[] buffer, out byte[] senseBuffer, bool dualLayer, uint timeout,
out double duration)
{
buffer = new byte[8];
buffer = new byte[8];
senseBuffer = new byte[32];
byte[] cdb = new byte[12];
@@ -470,7 +470,7 @@ namespace DiscImageChef.Devices
cdb[9] = (byte)buffer.Length;
if(dualLayer) cdb[3] = (byte)PlextorSubCommands.BitSetRdl;
else cdb[3] = (byte)PlextorSubCommands.BitSetR;
else cdb[3] = (byte)PlextorSubCommands.BitSetR;
LastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
out bool sense);
@@ -492,13 +492,13 @@ namespace DiscImageChef.Devices
public bool PlextorGetTestWriteDvdPlus(out byte[] buffer, out byte[] senseBuffer, uint timeout,
out double duration)
{
buffer = new byte[8];
buffer = new byte[8];
senseBuffer = new byte[32];
byte[] cdb = new byte[12];
cdb[0] = (byte)ScsiCommands.PlextorExtend;
cdb[1] = (byte)PlextorSubCommands.GetMode;
cdb[2] = (byte)PlextorSubCommands.TestWriteDvdPlus;
cdb[0] = (byte)ScsiCommands.PlextorExtend;
cdb[1] = (byte)PlextorSubCommands.GetMode;
cdb[2] = (byte)PlextorSubCommands.TestWriteDvdPlus;
cdb[10] = (byte)buffer.Length;
LastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,

View File

@@ -64,20 +64,20 @@ 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];
cdb[0] = (byte)ScsiCommands.Read6;
cdb[1] = (byte)((lba & 0x1F0000) >> 16);
cdb[2] = (byte)((lba & 0xFF00) >> 8);
cdb[2] = (byte)((lba & 0xFF00) >> 8);
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 bool sense);
@@ -111,23 +111,25 @@ 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];
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(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);
cdb[5] = (byte)(lba & 0xFF);
cdb[3] = (byte)((lba & 0xFF0000) >> 16);
cdb[4] = (byte)((lba & 0xFF00) >> 8);
cdb[5] = (byte)(lba & 0xFF);
cdb[6] = (byte)(groupNumber & 0x1F);
cdb[7] = (byte)((transferLength & 0xFF00) >> 8);
cdb[8] = (byte)(transferLength & 0xFF);
@@ -167,28 +169,30 @@ 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];
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(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);
cdb[5] = (byte)(lba & 0xFF);
cdb[6] = (byte)((transferLength & 0xFF000000) >> 24);
cdb[7] = (byte)((transferLength & 0xFF0000) >> 16);
cdb[8] = (byte)((transferLength & 0xFF00) >> 8);
cdb[9] = (byte)(transferLength & 0xFF);
cdb[10] = (byte)(groupNumber & 0x1F);
cdb[2] = (byte)((lba & 0xFF000000) >> 24);
cdb[3] = (byte)((lba & 0xFF0000) >> 16);
cdb[4] = (byte)((lba & 0xFF00) >> 8);
cdb[5] = (byte)(lba & 0xFF);
cdb[6] = (byte)((transferLength & 0xFF000000) >> 24);
cdb[7] = (byte)((transferLength & 0xFF0000) >> 16);
cdb[8] = (byte)((transferLength & 0xFF00) >> 8);
cdb[9] = (byte)(transferLength & 0xFF);
cdb[10] = (byte)(groupNumber & 0x1F);
if(streaming) cdb[10] += 0x80;
buffer = new byte[transferLength * blockSize];
@@ -225,32 +229,34 @@ 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];
byte[] cdb = new byte[16];
byte[] lbaBytes = BitConverter.GetBytes(lba);
cdb[0] = (byte)ScsiCommands.Read16;
cdb[1] = (byte)((rdprotect & 0x07) << 5);
if(dpo) cdb[1] += 0x10;
if(fua) cdb[1] += 0x08;
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];
cdb[5] = lbaBytes[4];
cdb[6] = lbaBytes[3];
cdb[7] = lbaBytes[2];
cdb[8] = lbaBytes[1];
cdb[9] = lbaBytes[0];
cdb[2] = lbaBytes[7];
cdb[3] = lbaBytes[6];
cdb[4] = lbaBytes[5];
cdb[5] = lbaBytes[4];
cdb[6] = lbaBytes[3];
cdb[7] = lbaBytes[2];
cdb[8] = lbaBytes[1];
cdb[9] = lbaBytes[0];
cdb[10] = (byte)((transferLength & 0xFF000000) >> 24);
cdb[11] = (byte)((transferLength & 0xFF0000) >> 16);
cdb[12] = (byte)((transferLength & 0xFF00) >> 8);
cdb[11] = (byte)((transferLength & 0xFF0000) >> 16);
cdb[12] = (byte)((transferLength & 0xFF00) >> 8);
cdb[13] = (byte)(transferLength & 0xFF);
cdb[14] = (byte)(groupNumber & 0x1F);
cdb[14] = (byte)(groupNumber & 0x1F);
if(streaming) cdb[14] += 0x80;
buffer = new byte[transferLength * blockSize];
@@ -279,8 +285,9 @@ namespace DiscImageChef.Devices
/// 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];
@@ -289,8 +296,8 @@ namespace DiscImageChef.Devices
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);
cdb[3] = (byte)((lba & 0xFF0000) >> 16);
cdb[4] = (byte)((lba & 0xFF00) >> 8);
cdb[5] = (byte)(lba & 0xFF);
cdb[7] = (byte)((transferBytes & 0xFF00) >> 8);
cdb[8] = (byte)(transferBytes & 0xFF);
@@ -320,23 +327,23 @@ namespace DiscImageChef.Devices
/// 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];
byte[] cdb = new byte[16];
byte[] lbaBytes = BitConverter.GetBytes(lba);
cdb[0] = (byte)ScsiCommands.ServiceActionIn;
cdb[1] = (byte)ScsiServiceActions.ReadLong16;
cdb[2] = lbaBytes[7];
cdb[3] = lbaBytes[6];
cdb[4] = lbaBytes[5];
cdb[5] = lbaBytes[4];
cdb[6] = lbaBytes[3];
cdb[7] = lbaBytes[2];
cdb[8] = lbaBytes[1];
cdb[9] = lbaBytes[0];
cdb[0] = (byte)ScsiCommands.ServiceActionIn;
cdb[1] = (byte)ScsiServiceActions.ReadLong16;
cdb[2] = lbaBytes[7];
cdb[3] = lbaBytes[6];
cdb[4] = lbaBytes[5];
cdb[5] = lbaBytes[4];
cdb[6] = lbaBytes[3];
cdb[7] = lbaBytes[2];
cdb[8] = lbaBytes[1];
cdb[9] = lbaBytes[0];
cdb[12] = (byte)((transferBytes & 0xFF00) >> 8);
cdb[13] = (byte)(transferBytes & 0xFF);
if(correct) cdb[14] += 0x01;
@@ -362,12 +369,12 @@ namespace DiscImageChef.Devices
public bool Seek6(out byte[] senseBuffer, uint lba, uint timeout, out double duration)
{
senseBuffer = new byte[32];
byte[] cdb = new byte[6];
byte[] cdb = new byte[6];
byte[] buffer = new byte[0];
cdb[0] = (byte)ScsiCommands.Seek6;
cdb[1] = (byte)((lba & 0x1F0000) >> 16);
cdb[2] = (byte)((lba & 0xFF00) >> 8);
cdb[2] = (byte)((lba & 0xFF00) >> 8);
cdb[3] = (byte)(lba & 0xFF);
LastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.None, out duration,
@@ -389,13 +396,13 @@ namespace DiscImageChef.Devices
public bool Seek10(out byte[] senseBuffer, uint lba, uint timeout, out double duration)
{
senseBuffer = new byte[32];
byte[] cdb = new byte[10];
byte[] cdb = new byte[10];
byte[] buffer = new byte[0];
cdb[0] = (byte)ScsiCommands.Seek10;
cdb[2] = (byte)((lba & 0xFF000000) >> 24);
cdb[3] = (byte)((lba & 0xFF0000) >> 16);
cdb[4] = (byte)((lba & 0xFF00) >> 8);
cdb[3] = (byte)((lba & 0xFF0000) >> 16);
cdb[4] = (byte)((lba & 0xFF00) >> 8);
cdb[5] = (byte)(lba & 0xFF);
LastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.None, out duration,

View File

@@ -50,26 +50,28 @@ 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];
senseBuffer = new byte[32];
cdb[0] = (byte)ScsiCommands.ReadAttribute;
cdb[1] = (byte)((byte)action & 0x1F);
cdb[2] = (byte)((element & 0xFF00) >> 8);
cdb[3] = (byte)(element & 0xFF);
cdb[4] = (byte)(elementType & 0x0F);
cdb[5] = volume;
cdb[7] = partition;
cdb[8] = (byte)((firstAttribute & 0xFF00) >> 8);
cdb[9] = (byte)(firstAttribute & 0xFF);
cdb[0] = (byte)ScsiCommands.ReadAttribute;
cdb[1] = (byte)((byte)action & 0x1F);
cdb[2] = (byte)((element & 0xFF00) >> 8);
cdb[3] = (byte)(element & 0xFF);
cdb[4] = (byte)(elementType & 0x0F);
cdb[5] = volume;
cdb[7] = partition;
cdb[8] = (byte)((firstAttribute & 0xFF00) >> 8);
cdb[9] = (byte)(firstAttribute & 0xFF);
cdb[10] = (byte)((buffer.Length & 0xFF000000) >> 24);
cdb[11] = (byte)((buffer.Length & 0xFF0000) >> 16);
cdb[12] = (byte)((buffer.Length & 0xFF00) >> 8);
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;
@@ -80,11 +82,11 @@ namespace DiscImageChef.Devices
if(sense) return true;
uint attrLen = (uint)((buffer[0] << 24) + (buffer[1] << 16) + (buffer[2] << 8) + buffer[3] + 4);
buffer = new byte[attrLen];
cdb[10] = (byte)((buffer.Length & 0xFF000000) >> 24);
cdb[11] = (byte)((buffer.Length & 0xFF0000) >> 16);
cdb[12] = (byte)((buffer.Length & 0xFF00) >> 8);
cdb[13] = (byte)(buffer.Length & 0xFF);
buffer = new byte[attrLen];
cdb[10] = (byte)((buffer.Length & 0xFF000000) >> 24);
cdb[11] = (byte)((buffer.Length & 0xFF0000) >> 16);
cdb[12] = (byte)((buffer.Length & 0xFF00) >> 8);
cdb[13] = (byte)(buffer.Length & 0xFF);
senseBuffer = new byte[32];
LastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,

View File

@@ -85,7 +85,7 @@ namespace DiscImageChef.Devices
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
public bool ScsiInquiry(out byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration)
{
buffer = new byte[36];
buffer = new byte[36];
senseBuffer = new byte[32];
byte[] cdb = {(byte)ScsiCommands.Inquiry, 0, 0, 0, 36, 0};
@@ -97,8 +97,8 @@ namespace DiscImageChef.Devices
byte pagesLength = (byte)(buffer[4] + 5);
cdb = new byte[] {(byte)ScsiCommands.Inquiry, 0, 0, 0, pagesLength, 0};
buffer = new byte[pagesLength];
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,
@@ -159,7 +159,7 @@ namespace DiscImageChef.Devices
/// <param name="page">The Extended Vital Product Data</param>
public bool ScsiInquiry(out byte[] buffer, out byte[] senseBuffer, byte page, uint timeout, out double duration)
{
buffer = new byte[36];
buffer = new byte[36];
senseBuffer = new byte[32];
byte[] cdb = {(byte)ScsiCommands.Inquiry, 1, page, 0, 36, 0};
@@ -174,8 +174,8 @@ namespace DiscImageChef.Devices
byte pagesLength = (byte)(buffer[3] + 4);
cdb = new byte[] {(byte)ScsiCommands.Inquiry, 1, page, 0, pagesLength, 0};
buffer = new byte[pagesLength];
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,
@@ -197,7 +197,7 @@ 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};
byte[] buffer = new byte[0];
LastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.None, out duration,
@@ -234,8 +234,9 @@ 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);
}
@@ -252,9 +253,10 @@ 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];
@@ -264,9 +266,9 @@ namespace DiscImageChef.Devices
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;
cdb[3] = subPageCode;
cdb[4] = (byte)buffer.Length;
cdb[5] = 0;
LastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
out bool sense);
@@ -275,8 +277,8 @@ namespace DiscImageChef.Devices
if(sense) return true;
byte modeLength = (byte)(buffer[0] + 1);
buffer = new byte[modeLength];
cdb[4] = (byte)buffer.Length;
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,
@@ -299,8 +301,9 @@ 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);
@@ -318,8 +321,10 @@ 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);
@@ -338,9 +343,11 @@ 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];
@@ -348,13 +355,13 @@ namespace DiscImageChef.Devices
cdb[0] = (byte)ScsiCommands.ModeSense10;
if(llbaa) cdb[1] |= 0x10;
if(dbd) cdb[1] |= 0x08;
if(dbd) cdb[1] |= 0x08;
cdb[2] |= (byte)pageControl;
cdb[2] |= (byte)(pageCode & 0x3F);
cdb[3] = subPageCode;
cdb[7] = (byte)((buffer.Length & 0xFF00) >> 8);
cdb[8] = (byte)(buffer.Length & 0xFF);
cdb[9] = 0;
cdb[3] = subPageCode;
cdb[7] = (byte)((buffer.Length & 0xFF00) >> 8);
cdb[8] = (byte)(buffer.Length & 0xFF);
cdb[9] = 0;
LastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
out bool sense);
@@ -363,9 +370,9 @@ namespace DiscImageChef.Devices
if(sense) return true;
ushort modeLength = (ushort)((buffer[0] << 8) + buffer[1] + 2);
buffer = new byte[modeLength];
cdb[7] = (byte)((buffer.Length & 0xFF00) >> 8);
cdb[8] = (byte)(buffer.Length & 0xFF);
buffer = new byte[modeLength];
cdb[7] = (byte)((buffer.Length & 0xFF00) >> 8);
cdb[8] = (byte)(buffer.Length & 0xFF);
senseBuffer = new byte[32];
LastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
@@ -431,7 +438,7 @@ namespace DiscImageChef.Devices
out double duration)
{
senseBuffer = new byte[32];
byte[] cdb = new byte[6];
byte[] cdb = new byte[6];
byte[] buffer = new byte[0];
cdb[0] = (byte)ScsiCommands.PreventAllowMediumRemoval;
@@ -470,8 +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];
@@ -485,8 +492,8 @@ namespace DiscImageChef.Devices
if(relAddr) cdb[1] = 0x01;
cdb[2] = (byte)((address & 0xFF000000) >> 24);
cdb[3] = (byte)((address & 0xFF0000) >> 16);
cdb[4] = (byte)((address & 0xFF00) >> 8);
cdb[3] = (byte)((address & 0xFF0000) >> 16);
cdb[4] = (byte)((address & 0xFF00) >> 8);
cdb[5] = (byte)(address & 0xFF);
}
@@ -547,8 +554,8 @@ namespace DiscImageChef.Devices
}
cdb[10] = (byte)((buffer.Length & 0xFF000000) >> 24);
cdb[11] = (byte)((buffer.Length & 0xFF0000) >> 16);
cdb[12] = (byte)((buffer.Length & 0xFF00) >> 8);
cdb[11] = (byte)((buffer.Length & 0xFF0000) >> 16);
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,
@@ -577,8 +584,8 @@ namespace DiscImageChef.Devices
cdb[0] = (byte)ScsiCommands.ReadSerialNumber;
cdb[1] = 0x01;
cdb[6] = (byte)((buffer.Length & 0xFF000000) >> 24);
cdb[7] = (byte)((buffer.Length & 0xFF0000) >> 16);
cdb[8] = (byte)((buffer.Length & 0xFF00) >> 8);
cdb[7] = (byte)((buffer.Length & 0xFF0000) >> 16);
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,
@@ -588,11 +595,11 @@ namespace DiscImageChef.Devices
if(sense) return true;
uint strctLength = (uint)((buffer[0] << 24) + (buffer[1] << 16) + (buffer[2] << 8) + buffer[3] + 4);
buffer = new byte[strctLength];
cdb[6] = (byte)((buffer.Length & 0xFF000000) >> 24);
cdb[7] = (byte)((buffer.Length & 0xFF0000) >> 16);
cdb[8] = (byte)((buffer.Length & 0xFF00) >> 8);
cdb[9] = (byte)(buffer.Length & 0xFF);
buffer = new byte[strctLength];
cdb[6] = (byte)((buffer.Length & 0xFF000000) >> 24);
cdb[7] = (byte)((buffer.Length & 0xFF0000) >> 16);
cdb[8] = (byte)((buffer.Length & 0xFF00) >> 8);
cdb[9] = (byte)(buffer.Length & 0xFF);
senseBuffer = new byte[32];
LastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
@@ -615,11 +622,13 @@ 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);
timeout, out duration);
}
/// <summary>
@@ -632,8 +641,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 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);
@@ -649,11 +659,12 @@ 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);
timeout, out duration);
}
/// <summary>
@@ -665,8 +676,8 @@ 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);
@@ -683,11 +694,13 @@ 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);
timeout, out duration);
}
/// <summary>
@@ -702,11 +715,13 @@ 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);
timeout, out duration);
}
/// <summary>
@@ -719,7 +734,7 @@ 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="pageFormat">Set if page is formatted.</param>
public bool ModeSelect(byte[] buffer, out byte[] senseBuffer, bool pageFormat, bool savePages, uint timeout,
public bool ModeSelect(byte[] buffer, out byte[] senseBuffer, bool pageFormat, bool savePages, uint timeout,
out double duration)
{
senseBuffer = new byte[32];
@@ -727,11 +742,11 @@ namespace DiscImageChef.Devices
// Prevent overflows
if(buffer.Length > 255)
{
if(PlatformId != PlatformID.Win32NT && PlatformId != PlatformID.Win32S &&
PlatformId != PlatformID.Win32Windows && PlatformId != PlatformID.WinCE &&
if(PlatformId != PlatformID.Win32NT && PlatformId != PlatformID.Win32S &&
PlatformId != PlatformID.Win32Windows && PlatformId != PlatformID.WinCE &&
PlatformId != PlatformID.WindowsPhone && PlatformId != PlatformID.Xbox) LastError = 75;
else LastError = 111;
Error = true;
else LastError = 111;
Error = true;
duration = 0;
return true;
}
@@ -740,7 +755,7 @@ namespace DiscImageChef.Devices
cdb[0] = (byte)ScsiCommands.ModeSelect;
if(pageFormat) cdb[1] += 0x10;
if(savePages) cdb[1] += 0x01;
if(savePages) cdb[1] += 0x01;
cdb[4] = (byte)buffer.Length;
LastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.Out, out duration,
@@ -762,7 +777,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="pageFormat">Set if page is formatted.</param>
public bool ModeSelect10(byte[] buffer, out byte[] senseBuffer, bool pageFormat, bool savePages, uint timeout,
public bool ModeSelect10(byte[] buffer, out byte[] senseBuffer, bool pageFormat, bool savePages,
uint timeout,
out double duration)
{
senseBuffer = new byte[32];
@@ -770,11 +786,11 @@ namespace DiscImageChef.Devices
// Prevent overflows
if(buffer.Length > 65535)
{
if(PlatformId != PlatformID.Win32NT && PlatformId != PlatformID.Win32S &&
PlatformId != PlatformID.Win32Windows && PlatformId != PlatformID.WinCE &&
if(PlatformId != PlatformID.Win32NT && PlatformId != PlatformID.Win32S &&
PlatformId != PlatformID.Win32Windows && PlatformId != PlatformID.WinCE &&
PlatformId != PlatformID.WindowsPhone && PlatformId != PlatformID.Xbox) LastError = 75;
else LastError = 111;
Error = true;
else LastError = 111;
Error = true;
duration = 0;
return true;
}
@@ -783,7 +799,7 @@ namespace DiscImageChef.Devices
cdb[0] = (byte)ScsiCommands.ModeSelect10;
if(pageFormat) cdb[1] += 0x10;
if(savePages) cdb[1] += 0x01;
if(savePages) cdb[1] += 0x01;
cdb[7] = (byte)((buffer.Length & 0xFF00) << 8);
cdb[8] = (byte)(buffer.Length & 0xFF);

View File

@@ -76,19 +76,19 @@ namespace DiscImageChef.Devices
/// </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];
byte[] cdb = new byte[6];
byte[] buffer = new byte[0];
cdb[0] = (byte)ScsiCommands.LoadUnload;
if(immediate) cdb[1] = 0x01;
if(load) cdb[4] += 0x01;
if(retense) cdb[4] += 0x02;
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(hold) cdb[4] += 0x08;
LastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.None, out duration,
out bool sense);
@@ -163,20 +163,21 @@ 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];
byte[] cdb = new byte[10];
byte[] buffer = new byte[0];
cdb[0] = (byte)ScsiCommands.Locate;
if(immediate) cdb[1] += 0x01;
if(immediate) cdb[1] += 0x01;
if(changePartition) cdb[1] += 0x02;
if(blockType) cdb[1] += 0x04;
if(blockType) cdb[1] += 0x04;
cdb[3] = (byte)((objectId & 0xFF000000) >> 24);
cdb[4] = (byte)((objectId & 0xFF0000) >> 16);
cdb[5] = (byte)((objectId & 0xFF00) >> 8);
cdb[4] = (byte)((objectId & 0xFF0000) >> 16);
cdb[5] = (byte)((objectId & 0xFF00) >> 8);
cdb[6] = (byte)(objectId & 0xFF);
cdb[8] = partition;
@@ -243,7 +244,7 @@ namespace DiscImageChef.Devices
out double duration)
{
return Locate16(out senseBuffer, immediate, true, SscLogicalIdTypes.ObjectId, false, partition, lba,
timeout, out duration);
timeout, out duration);
}
/// <summary>
@@ -258,27 +259,28 @@ 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];
byte[] buffer = new byte[0];
byte[] cdb = new byte[16];
byte[] buffer = new byte[0];
byte[] idBytes = BitConverter.GetBytes(identifier);
cdb[0] = (byte)ScsiCommands.Locate16;
cdb[1] = (byte)((byte)destType << 3);
if(immediate) cdb[1] += 0x01;
if(immediate) cdb[1] += 0x01;
if(changePartition) cdb[1] += 0x02;
if(bam) cdb[2] = 0x01;
if(bam) cdb[2] = 0x01;
cdb[3] = partition;
cdb[4] = idBytes[7];
cdb[5] = idBytes[6];
cdb[6] = idBytes[5];
cdb[7] = idBytes[4];
cdb[8] = idBytes[3];
cdb[9] = idBytes[2];
cdb[4] = idBytes[7];
cdb[5] = idBytes[6];
cdb[6] = idBytes[5];
cdb[7] = idBytes[4];
cdb[8] = idBytes[3];
cdb[9] = idBytes[2];
cdb[10] = idBytes[1];
cdb[11] = idBytes[0];
@@ -315,8 +317,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);
}
@@ -338,8 +340,9 @@ 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)
{
buffer = fixedLen ? new byte[blockSize * transferLen] : new byte[transferLen];
byte[] cdb = new byte[6];
@@ -347,9 +350,9 @@ namespace DiscImageChef.Devices
cdb[0] = (byte)ScsiCommands.Read6;
if(fixedLen) cdb[1] += 0x01;
if(sili) cdb[1] += 0x02;
if(sili) cdb[1] += 0x02;
cdb[2] = (byte)((transferLen & 0xFF0000) >> 16);
cdb[3] = (byte)((transferLen & 0xFF00) >> 8);
cdb[3] = (byte)((transferLen & 0xFF00) >> 8);
cdb[4] = (byte)(transferLen & 0xFF);
LastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
@@ -372,8 +375,8 @@ 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);
@@ -391,8 +394,9 @@ 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);
@@ -408,8 +412,8 @@ 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);
@@ -426,8 +430,9 @@ 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);
@@ -452,8 +457,10 @@ 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)
{
buffer = fixedLen ? new byte[objectSize * transferLen] : new byte[transferLen];
byte[] cdb = new byte[6];
@@ -462,18 +469,18 @@ namespace DiscImageChef.Devices
cdb[0] = (byte)ScsiCommands.Read16;
if(fixedLen) cdb[1] += 0x01;
if(sili) cdb[1] += 0x02;
cdb[3] = partition;
cdb[4] = idBytes[7];
cdb[5] = idBytes[6];
cdb[6] = idBytes[5];
cdb[7] = idBytes[4];
cdb[8] = idBytes[3];
cdb[9] = idBytes[2];
if(sili) cdb[1] += 0x02;
cdb[3] = partition;
cdb[4] = idBytes[7];
cdb[5] = idBytes[6];
cdb[6] = idBytes[5];
cdb[7] = idBytes[4];
cdb[8] = idBytes[3];
cdb[9] = idBytes[2];
cdb[10] = idBytes[1];
cdb[11] = idBytes[0];
cdb[12] = (byte)((transferLen & 0xFF0000) >> 16);
cdb[13] = (byte)((transferLen & 0xFF00) >> 8);
cdb[13] = (byte)((transferLen & 0xFF00) >> 8);
cdb[14] = (byte)(transferLen & 0xFF);
LastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
@@ -543,12 +550,12 @@ 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;
byte responseForm = 0;
if(vendorType) responseForm += 0x01;
if(longForm) responseForm += 0x02;
if(totalPosition) responseForm += 0x04;
return ReadPosition(out buffer, out senseBuffer, (SscPositionForms)responseForm, timeout, out duration);
@@ -631,8 +638,9 @@ 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);
@@ -656,19 +664,20 @@ 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)
{
buffer = fixedLen ? new byte[blockSize * transferLen] : new byte[transferLen];
byte[] cdb = new byte[6];
senseBuffer = new byte[32];
cdb[0] = (byte)ScsiCommands.ReadReverse;
if(fixedLen) cdb[1] += 0x01;
if(sili) cdb[1] += 0x02;
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[3] = (byte)((transferLen & 0xFF00) >> 8);
cdb[4] = (byte)(transferLen & 0xFF);
LastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
@@ -691,11 +700,12 @@ 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);
timeout, out duration);
}
/// <summary>
@@ -710,11 +720,12 @@ 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);
blockSize, timeout, out duration);
}
/// <summary>
@@ -727,11 +738,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);
timeout, out duration);
}
/// <summary>
@@ -745,11 +756,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);
blockSize, timeout, out duration);
}
/// <summary>
@@ -772,8 +783,10 @@ 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,
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)
{
buffer = fixedLen ? new byte[objectSize * transferLen] : new byte[transferLen];
@@ -782,20 +795,20 @@ namespace DiscImageChef.Devices
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;
if(byteOrder) cdb[1] += 0x04;
cdb[3] = partition;
cdb[4] = idBytes[7];
cdb[5] = idBytes[6];
cdb[6] = idBytes[5];
cdb[7] = idBytes[4];
cdb[8] = idBytes[3];
cdb[9] = idBytes[2];
cdb[3] = partition;
cdb[4] = idBytes[7];
cdb[5] = idBytes[6];
cdb[6] = idBytes[5];
cdb[7] = idBytes[4];
cdb[8] = idBytes[3];
cdb[9] = idBytes[2];
cdb[10] = idBytes[1];
cdb[11] = idBytes[0];
cdb[12] = (byte)((transferLen & 0xFF0000) >> 16);
cdb[13] = (byte)((transferLen & 0xFF00) >> 8);
cdb[13] = (byte)((transferLen & 0xFF00) >> 8);
cdb[14] = (byte)(transferLen & 0xFF);
LastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
@@ -816,8 +829,8 @@ 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);
@@ -833,8 +846,8 @@ 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);
@@ -857,8 +870,10 @@ 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)
{
buffer = fixedLen ? new byte[blockSize * transferLen] : new byte[transferLen];
byte[] cdb = new byte[6];
@@ -866,9 +881,9 @@ namespace DiscImageChef.Devices
cdb[0] = (byte)ScsiCommands.RecoverBufferedData;
if(fixedLen) cdb[1] += 0x01;
if(sili) cdb[1] += 0x02;
if(sili) cdb[1] += 0x02;
cdb[2] = (byte)((transferLen & 0xFF0000) >> 16);
cdb[3] = (byte)((transferLen & 0xFF00) >> 8);
cdb[3] = (byte)((transferLen & 0xFF00) >> 8);
cdb[4] = (byte)(transferLen & 0xFF);
LastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
@@ -915,8 +930,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];
@@ -924,7 +939,7 @@ namespace DiscImageChef.Devices
cdb[0] = (byte)ScsiCommands.ReportDensitySupport;
if(currentMedia) cdb[1] += 0x01;
if(mediumType) cdb[1] += 0x02;
if(mediumType) cdb[1] += 0x02;
cdb[7] = (byte)((buffer.Length & 0xFF00) >> 8);
cdb[8] = (byte)(buffer.Length & 0xFF);
@@ -935,9 +950,9 @@ namespace DiscImageChef.Devices
if(sense) return true;
ushort availableLength = (ushort)((buffer[0] << 8) + buffer[1] + 2);
buffer = new byte[availableLength];
cdb[7] = (byte)((buffer.Length & 0xFF00) >> 8);
cdb[8] = (byte)(buffer.Length & 0xFF);
buffer = new byte[availableLength];
cdb[7] = (byte)((buffer.Length & 0xFF00) >> 8);
cdb[8] = (byte)(buffer.Length & 0xFF);
senseBuffer = new byte[32];
LastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
@@ -970,7 +985,7 @@ namespace DiscImageChef.Devices
public bool Rewind(out byte[] senseBuffer, bool immediate, uint timeout, out double duration)
{
senseBuffer = new byte[32];
byte[] cdb = new byte[6];
byte[] cdb = new byte[6];
byte[] buffer = new byte[0];
cdb[0] = (byte)ScsiCommands.Rewind;
@@ -996,7 +1011,7 @@ namespace DiscImageChef.Devices
public bool TrackSelect(out byte[] senseBuffer, byte track, uint timeout, out double duration)
{
senseBuffer = new byte[32];
byte[] cdb = new byte[6];
byte[] cdb = new byte[6];
byte[] buffer = new byte[0];
cdb[0] = (byte)ScsiCommands.TrackSelect;
@@ -1014,7 +1029,7 @@ namespace DiscImageChef.Devices
public bool Space(out byte[] senseBuffer, SscSpaceCodes code, int count, uint timeout, out double duration)
{
senseBuffer = new byte[32];
byte[] cdb = new byte[6];
byte[] cdb = new byte[6];
byte[] buffer = new byte[0];
byte[] countB = BitConverter.GetBytes(count);

View File

@@ -81,20 +81,21 @@ 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];
bool sense;
bool sense;
cdb[0] = (byte)ScsiCommands.Read6;
cdb[1] = (byte)((lba & 0x1F0000) >> 16);
cdb[2] = (byte)((lba & 0xFF00) >> 8);
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(readLong) cdb[5] += 0x40;
if(!inhibitDma && !readLong)
buffer = transferLength == 0 ? new byte[256 * blockSize] : new byte[transferLength * blockSize];
@@ -161,23 +162,23 @@ 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,
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];
bool sense;
bool sense;
cdb[0] = (byte)ScsiCommands.Read10;
cdb[2] = (byte)((lba & 0xFF000000) >> 24);
cdb[3] = (byte)((lba & 0xFF0000) >> 16);
cdb[4] = (byte)((lba & 0xFF00) >> 8);
cdb[3] = (byte)((lba & 0xFF0000) >> 16);
cdb[4] = (byte)((lba & 0xFF00) >> 8);
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(readLong) cdb[9] += 0x40;
if(!inhibitDma && !readLong) buffer = new byte[transferLength * blockSize];
else if(readLong)

View File

@@ -39,9 +39,9 @@ namespace DiscImageChef.Devices
{
readonly ushort usbVendor;
readonly ushort usbProduct;
readonly ulong firewireGuid;
readonly uint firewireModel;
readonly uint firewireVendor;
readonly ulong firewireGuid;
readonly uint firewireModel;
readonly uint firewireVendor;
// MMC and SecureDigital, values that need to be get with card idle, something that may
// not be possible to do but usually is already done by the SDHCI driver.

View File

@@ -640,7 +640,7 @@ namespace DiscImageChef.Devices
/// Requests SPC-4 style error data
/// </summary>
RequestSenseDataExt = 0x0B,
SanitizeCommands = 0xB4,
SanitizeCommands = 0xB4,
/// <summary>
/// Executes a Security Protocol command that does not require a transfer of data
/// </summary>
@@ -2394,7 +2394,7 @@ namespace DiscImageChef.Devices
/// Sets the spindle speed to be used while reading/writing data to a CD
/// </summary>
SetCdSpeed = 0xDA,
WriteCdp = 0xE3,
WriteCdp = 0xE3,
#endregion
#region ATA Command Pass-Through
@@ -2841,7 +2841,7 @@ namespace DiscImageChef.Devices
/// <summary>
/// Drive shall return only the Feature Header with the chosen Feature Descriptor
/// </summary>
Single = 0x02,
Single = 0x02,
Reserved = 0x03
}
@@ -3505,8 +3505,8 @@ namespace DiscImageChef.Devices
/// The host sends the bus testing data pattern to a device (ADTC, R1)
/// </summary>
BusTestWrite = 19,
SpiReadOcr = 58,
SpicrcOnOff = 59,
SpiReadOcr = 58,
SpicrcOnOff = 59,
#endregion Class 1 MMC Commands (Basic and read-stream)
#region Class 2 MMC Commands (Block-oriented read)
@@ -3756,9 +3756,9 @@ namespace DiscImageChef.Devices
ResponseSpiB4 = 1 << 9,
ResponseSpiBusy = 1 << 10,
ResponseNone = 0,
ResponseR1 = ResponsePresent | ResponseCrc | ResponseOpcode,
ResponseR1 = ResponsePresent | ResponseCrc | ResponseOpcode,
ResponseR1B = ResponsePresent | ResponseCrc | ResponseOpcode | ResponseBusy,
ResponseR2 = ResponsePresent | Response136 | ResponseCrc,
ResponseR2 = ResponsePresent | Response136 | ResponseCrc,
ResponseR3 = ResponsePresent,
ResponseR4 = ResponsePresent,
ResponseR5 = ResponsePresent | ResponseCrc | ResponseOpcode,
@@ -3916,7 +3916,7 @@ namespace DiscImageChef.Devices
DisableReleaseInterrupt = 0xDD,
/// <summary>Disable SERVICE interrupt</summary>
DisableServiceInterrupt = 0xDE,
VendorSpecific = 0xE0
VendorSpecific = 0xE0
}
public enum KreonLockStates : byte

View File

@@ -60,12 +60,13 @@ namespace DiscImageChef.Devices.FreeBSD
/// <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, CcbFlags direction, out double duration, out bool sense)
internal static int SendScsiCommand64(IntPtr dev, byte[] cdb, ref byte[] buffer,
out byte[] senseBuffer,
uint timeout, CcbFlags direction, out double duration, out bool sense)
{
senseBuffer = null;
duration = 0;
sense = false;
duration = 0;
sense = false;
if(buffer == null) return -1;
@@ -79,19 +80,19 @@ namespace DiscImageChef.Devices.FreeBSD
}
CcbScsiio64 csio = (CcbScsiio64)Marshal.PtrToStructure(ccbPtr, typeof(CcbScsiio64));
csio.ccb_h.func_code = XptOpcode.XptScsiIo;
csio.ccb_h.flags = direction;
csio.ccb_h.xflags = 0;
csio.ccb_h.func_code = XptOpcode.XptScsiIo;
csio.ccb_h.flags = direction;
csio.ccb_h.xflags = 0;
csio.ccb_h.retry_count = 1;
csio.ccb_h.cbfcnp = IntPtr.Zero;
csio.ccb_h.timeout = timeout;
csio.data_ptr = Marshal.AllocHGlobal(buffer.Length);
csio.dxfer_len = (uint)buffer.Length;
csio.sense_len = 32;
csio.cdb_len = (byte)cdb.Length;
csio.ccb_h.cbfcnp = IntPtr.Zero;
csio.ccb_h.timeout = timeout;
csio.data_ptr = Marshal.AllocHGlobal(buffer.Length);
csio.dxfer_len = (uint)buffer.Length;
csio.sense_len = 32;
csio.cdb_len = (byte)cdb.Length;
// TODO: Create enum?
csio.tag_action = 0x20;
csio.cdb_bytes = new byte[CAM_MAX_CDBLEN];
csio.cdb_bytes = new byte[CAM_MAX_CDBLEN];
if(cdb.Length <= CAM_MAX_CDBLEN) Array.Copy(cdb, 0, csio.cdb_bytes, 0, cdb.Length);
else
{
@@ -100,14 +101,15 @@ namespace DiscImageChef.Devices.FreeBSD
Array.Copy(cdbPtrBytes, 0, csio.cdb_bytes, 0, IntPtr.Size);
csio.ccb_h.flags |= CcbFlags.CamCdbPointer;
}
csio.ccb_h.flags |= CcbFlags.CamDevQfrzdis;
Marshal.Copy(buffer, 0, csio.data_ptr, buffer.Length);
Marshal.StructureToPtr(csio, ccbPtr, false);
DateTime start = DateTime.UtcNow;
int error = cam_send_ccb(dev, ccbPtr);
DateTime end = DateTime.UtcNow;
int error = cam_send_ccb(dev, ccbPtr);
DateTime end = DateTime.UtcNow;
if(error < 0) error = Marshal.GetLastWin32Error();
@@ -123,22 +125,22 @@ namespace DiscImageChef.Devices.FreeBSD
if((csio.ccb_h.status & CamStatus.CamStatusMask) == CamStatus.CamScsiStatusError)
{
sense = true;
senseBuffer = new byte[1];
sense = true;
senseBuffer = new byte[1];
senseBuffer[0] = csio.scsi_status;
}
if((csio.ccb_h.status & CamStatus.CamAutosnsValid) != 0)
if(csio.sense_len - csio.sense_resid > 0)
{
sense = (csio.ccb_h.status & CamStatus.CamStatusMask) == CamStatus.CamScsiStatusError;
senseBuffer = new byte[csio.sense_len - csio.sense_resid];
sense = (csio.ccb_h.status & CamStatus.CamStatusMask) == CamStatus.CamScsiStatusError;
senseBuffer = new byte[csio.sense_len - csio.sense_resid];
senseBuffer[0] = csio.sense_data.error_code;
Array.Copy(csio.sense_data.sense_buf, 0, senseBuffer, 1, senseBuffer.Length - 1);
}
buffer = new byte[csio.dxfer_len];
cdb = new byte[csio.cdb_len];
cdb = new byte[csio.cdb_len];
Marshal.Copy(csio.data_ptr, buffer, 0, buffer.Length);
if(csio.ccb_h.flags.HasFlag(CcbFlags.CamCdbPointer))
@@ -168,12 +170,13 @@ namespace DiscImageChef.Devices.FreeBSD
/// <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, CcbFlags direction, out double duration, out bool sense)
internal static int SendScsiCommand(IntPtr dev, byte[] cdb, ref byte[] buffer,
out byte[] senseBuffer,
uint timeout, CcbFlags direction, out double duration, out bool sense)
{
senseBuffer = null;
duration = 0;
sense = false;
duration = 0;
sense = false;
if(buffer == null) return -1;
@@ -187,19 +190,19 @@ namespace DiscImageChef.Devices.FreeBSD
}
CcbScsiio csio = (CcbScsiio)Marshal.PtrToStructure(ccbPtr, typeof(CcbScsiio));
csio.ccb_h.func_code = XptOpcode.XptScsiIo;
csio.ccb_h.flags = direction;
csio.ccb_h.xflags = 0;
csio.ccb_h.func_code = XptOpcode.XptScsiIo;
csio.ccb_h.flags = direction;
csio.ccb_h.xflags = 0;
csio.ccb_h.retry_count = 1;
csio.ccb_h.cbfcnp = IntPtr.Zero;
csio.ccb_h.timeout = timeout;
csio.data_ptr = Marshal.AllocHGlobal(buffer.Length);
csio.dxfer_len = (uint)buffer.Length;
csio.sense_len = 32;
csio.cdb_len = (byte)cdb.Length;
csio.ccb_h.cbfcnp = IntPtr.Zero;
csio.ccb_h.timeout = timeout;
csio.data_ptr = Marshal.AllocHGlobal(buffer.Length);
csio.dxfer_len = (uint)buffer.Length;
csio.sense_len = 32;
csio.cdb_len = (byte)cdb.Length;
// TODO: Create enum?
csio.tag_action = 0x20;
csio.cdb_bytes = new byte[CAM_MAX_CDBLEN];
csio.cdb_bytes = new byte[CAM_MAX_CDBLEN];
if(cdb.Length <= CAM_MAX_CDBLEN) Array.Copy(cdb, 0, csio.cdb_bytes, 0, cdb.Length);
else
{
@@ -208,14 +211,15 @@ namespace DiscImageChef.Devices.FreeBSD
Array.Copy(cdbPtrBytes, 0, csio.cdb_bytes, 0, IntPtr.Size);
csio.ccb_h.flags |= CcbFlags.CamCdbPointer;
}
csio.ccb_h.flags |= CcbFlags.CamDevQfrzdis;
Marshal.Copy(buffer, 0, csio.data_ptr, buffer.Length);
Marshal.StructureToPtr(csio, ccbPtr, false);
DateTime start = DateTime.UtcNow;
int error = cam_send_ccb(dev, ccbPtr);
DateTime end = DateTime.UtcNow;
int error = cam_send_ccb(dev, ccbPtr);
DateTime end = DateTime.UtcNow;
if(error < 0) error = Marshal.GetLastWin32Error();
@@ -231,22 +235,22 @@ namespace DiscImageChef.Devices.FreeBSD
if((csio.ccb_h.status & CamStatus.CamStatusMask) == CamStatus.CamScsiStatusError)
{
sense = true;
senseBuffer = new byte[1];
sense = true;
senseBuffer = new byte[1];
senseBuffer[0] = csio.scsi_status;
}
if((csio.ccb_h.status & CamStatus.CamAutosnsValid) != 0)
if(csio.sense_len - csio.sense_resid > 0)
{
sense = (csio.ccb_h.status & CamStatus.CamStatusMask) == CamStatus.CamScsiStatusError;
senseBuffer = new byte[csio.sense_len - csio.sense_resid];
sense = (csio.ccb_h.status & CamStatus.CamStatusMask) == CamStatus.CamScsiStatusError;
senseBuffer = new byte[csio.sense_len - csio.sense_resid];
senseBuffer[0] = csio.sense_data.error_code;
Array.Copy(csio.sense_data.sense_buf, 0, senseBuffer, 1, senseBuffer.Length - 1);
}
buffer = new byte[csio.dxfer_len];
cdb = new byte[csio.cdb_len];
cdb = new byte[csio.cdb_len];
Marshal.Copy(csio.data_ptr, buffer, 0, buffer.Length);
if(csio.ccb_h.flags.HasFlag(CcbFlags.CamCdbPointer))
@@ -296,12 +300,13 @@ namespace DiscImageChef.Devices.FreeBSD
/// <param name="registers">Registers to send to drive</param>
/// <param name="errorRegisters">Registers returned by drive</param>
/// <param name="protocol">ATA protocol to use</param>
internal static int SendAtaCommand(IntPtr dev, AtaRegistersChs registers,
out AtaErrorRegistersChs errorRegisters, AtaProtocol protocol,
ref byte[] buffer, uint timeout, out double duration, out bool sense)
internal static int SendAtaCommand(IntPtr dev, AtaRegistersChs registers,
out AtaErrorRegistersChs errorRegisters, AtaProtocol protocol,
ref byte[] buffer, uint timeout,
out double duration, out bool sense)
{
duration = 0;
sense = false;
duration = 0;
sense = false;
errorRegisters = new AtaErrorRegistersChs();
if(buffer == null) return -1;
@@ -309,16 +314,16 @@ namespace DiscImageChef.Devices.FreeBSD
IntPtr ccbPtr = cam_getccb(dev);
CcbAtaio ataio = (CcbAtaio)Marshal.PtrToStructure(ccbPtr, typeof(CcbAtaio));
ataio.ccb_h.func_code = XptOpcode.XptAtaIo;
ataio.ccb_h.flags = AtaProtocolToCamFlags(protocol);
ataio.ccb_h.xflags = 0;
ataio.ccb_h.retry_count = 1;
ataio.ccb_h.cbfcnp = IntPtr.Zero;
ataio.ccb_h.timeout = timeout;
ataio.data_ptr = Marshal.AllocHGlobal(buffer.Length);
ataio.dxfer_len = (uint)buffer.Length;
ataio.ccb_h.flags |= CcbFlags.CamDevQfrzdis;
ataio.cmd.flags = CamAtaIoFlags.NeedResult;
ataio.ccb_h.func_code = XptOpcode.XptAtaIo;
ataio.ccb_h.flags = AtaProtocolToCamFlags(protocol);
ataio.ccb_h.xflags = 0;
ataio.ccb_h.retry_count = 1;
ataio.ccb_h.cbfcnp = IntPtr.Zero;
ataio.ccb_h.timeout = timeout;
ataio.data_ptr = Marshal.AllocHGlobal(buffer.Length);
ataio.dxfer_len = (uint)buffer.Length;
ataio.ccb_h.flags |= CcbFlags.CamDevQfrzdis;
ataio.cmd.flags = CamAtaIoFlags.NeedResult;
switch(protocol)
{
case AtaProtocol.Dma:
@@ -332,20 +337,20 @@ namespace DiscImageChef.Devices.FreeBSD
break;
}
ataio.cmd.command = registers.Command;
ataio.cmd.lba_high = registers.CylinderHigh;
ataio.cmd.lba_mid = registers.CylinderLow;
ataio.cmd.device = (byte)(0x40 | registers.DeviceHead);
ataio.cmd.features = registers.Feature;
ataio.cmd.command = registers.Command;
ataio.cmd.lba_high = registers.CylinderHigh;
ataio.cmd.lba_mid = registers.CylinderLow;
ataio.cmd.device = (byte)(0x40 | registers.DeviceHead);
ataio.cmd.features = registers.Feature;
ataio.cmd.sector_count = registers.SectorCount;
ataio.cmd.lba_low = registers.Sector;
ataio.cmd.lba_low = registers.Sector;
Marshal.Copy(buffer, 0, ataio.data_ptr, buffer.Length);
Marshal.StructureToPtr(ataio, ccbPtr, false);
DateTime start = DateTime.UtcNow;
int error = cam_send_ccb(dev, ccbPtr);
DateTime end = DateTime.UtcNow;
int error = cam_send_ccb(dev, ccbPtr);
DateTime end = DateTime.UtcNow;
if(error < 0) error = Marshal.GetLastWin32Error();
@@ -362,12 +367,12 @@ namespace DiscImageChef.Devices.FreeBSD
if((ataio.ccb_h.status & CamStatus.CamStatusMask) == CamStatus.CamAtaStatusError) sense = true;
errorRegisters.CylinderHigh = ataio.res.lba_high;
errorRegisters.CylinderLow = ataio.res.lba_mid;
errorRegisters.DeviceHead = ataio.res.device;
errorRegisters.Error = ataio.res.error;
errorRegisters.Sector = ataio.res.lba_low;
errorRegisters.SectorCount = ataio.res.sector_count;
errorRegisters.Status = ataio.res.status;
errorRegisters.CylinderLow = ataio.res.lba_mid;
errorRegisters.DeviceHead = ataio.res.device;
errorRegisters.Error = ataio.res.error;
errorRegisters.Sector = ataio.res.lba_low;
errorRegisters.SectorCount = ataio.res.sector_count;
errorRegisters.Status = ataio.res.status;
buffer = new byte[ataio.dxfer_len];
@@ -394,12 +399,13 @@ namespace DiscImageChef.Devices.FreeBSD
/// <param name="registers">Registers to send to drive</param>
/// <param name="errorRegisters">Registers returned by drive</param>
/// <param name="protocol">ATA protocol to use</param>
internal static int SendAtaCommand(IntPtr dev, AtaRegistersLba28 registers,
out AtaErrorRegistersLba28 errorRegisters, AtaProtocol protocol,
ref byte[] buffer, uint timeout, out double duration, out bool sense)
internal static int SendAtaCommand(IntPtr dev, AtaRegistersLba28 registers,
out AtaErrorRegistersLba28 errorRegisters, AtaProtocol protocol,
ref byte[] buffer, uint timeout,
out double duration, out bool sense)
{
duration = 0;
sense = false;
duration = 0;
sense = false;
errorRegisters = new AtaErrorRegistersLba28();
if(buffer == null) return -1;
@@ -407,16 +413,16 @@ namespace DiscImageChef.Devices.FreeBSD
IntPtr ccbPtr = cam_getccb(dev);
CcbAtaio ataio = (CcbAtaio)Marshal.PtrToStructure(ccbPtr, typeof(CcbAtaio));
ataio.ccb_h.func_code = XptOpcode.XptAtaIo;
ataio.ccb_h.flags = AtaProtocolToCamFlags(protocol);
ataio.ccb_h.xflags = 0;
ataio.ccb_h.retry_count = 1;
ataio.ccb_h.cbfcnp = IntPtr.Zero;
ataio.ccb_h.timeout = timeout;
ataio.data_ptr = Marshal.AllocHGlobal(buffer.Length);
ataio.dxfer_len = (uint)buffer.Length;
ataio.ccb_h.flags |= CcbFlags.CamDevQfrzdis;
ataio.cmd.flags = CamAtaIoFlags.NeedResult;
ataio.ccb_h.func_code = XptOpcode.XptAtaIo;
ataio.ccb_h.flags = AtaProtocolToCamFlags(protocol);
ataio.ccb_h.xflags = 0;
ataio.ccb_h.retry_count = 1;
ataio.ccb_h.cbfcnp = IntPtr.Zero;
ataio.ccb_h.timeout = timeout;
ataio.data_ptr = Marshal.AllocHGlobal(buffer.Length);
ataio.dxfer_len = (uint)buffer.Length;
ataio.ccb_h.flags |= CcbFlags.CamDevQfrzdis;
ataio.cmd.flags = CamAtaIoFlags.NeedResult;
switch(protocol)
{
case AtaProtocol.Dma:
@@ -430,20 +436,20 @@ namespace DiscImageChef.Devices.FreeBSD
break;
}
ataio.cmd.command = registers.Command;
ataio.cmd.lba_high = registers.LbaHigh;
ataio.cmd.lba_mid = registers.LbaMid;
ataio.cmd.device = (byte)(0x40 | registers.DeviceHead);
ataio.cmd.features = registers.Feature;
ataio.cmd.command = registers.Command;
ataio.cmd.lba_high = registers.LbaHigh;
ataio.cmd.lba_mid = registers.LbaMid;
ataio.cmd.device = (byte)(0x40 | registers.DeviceHead);
ataio.cmd.features = registers.Feature;
ataio.cmd.sector_count = registers.SectorCount;
ataio.cmd.lba_low = registers.LbaLow;
ataio.cmd.lba_low = registers.LbaLow;
Marshal.Copy(buffer, 0, ataio.data_ptr, buffer.Length);
Marshal.StructureToPtr(ataio, ccbPtr, false);
DateTime start = DateTime.UtcNow;
int error = cam_send_ccb(dev, ccbPtr);
DateTime end = DateTime.UtcNow;
int error = cam_send_ccb(dev, ccbPtr);
DateTime end = DateTime.UtcNow;
if(error < 0) error = Marshal.GetLastWin32Error();
@@ -459,13 +465,13 @@ namespace DiscImageChef.Devices.FreeBSD
if((ataio.ccb_h.status & CamStatus.CamStatusMask) == CamStatus.CamAtaStatusError) sense = true;
errorRegisters.LbaHigh = ataio.res.lba_high;
errorRegisters.LbaMid = ataio.res.lba_mid;
errorRegisters.DeviceHead = ataio.res.device;
errorRegisters.Error = ataio.res.error;
errorRegisters.LbaLow = ataio.res.lba_low;
errorRegisters.LbaHigh = ataio.res.lba_high;
errorRegisters.LbaMid = ataio.res.lba_mid;
errorRegisters.DeviceHead = ataio.res.device;
errorRegisters.Error = ataio.res.error;
errorRegisters.LbaLow = ataio.res.lba_low;
errorRegisters.SectorCount = ataio.res.sector_count;
errorRegisters.Status = ataio.res.status;
errorRegisters.Status = ataio.res.status;
buffer = new byte[ataio.dxfer_len];
@@ -492,12 +498,13 @@ namespace DiscImageChef.Devices.FreeBSD
/// <param name="registers">Registers to send to drive</param>
/// <param name="errorRegisters">Registers returned by drive</param>
/// <param name="protocol">ATA protocol to use</param>
internal static int SendAtaCommand(IntPtr dev, AtaRegistersLba48 registers,
out AtaErrorRegistersLba48 errorRegisters, AtaProtocol protocol,
ref byte[] buffer, uint timeout, out double duration, out bool sense)
internal static int SendAtaCommand(IntPtr dev, AtaRegistersLba48 registers,
out AtaErrorRegistersLba48 errorRegisters, AtaProtocol protocol,
ref byte[] buffer, uint timeout,
out double duration, out bool sense)
{
duration = 0;
sense = false;
duration = 0;
sense = false;
errorRegisters = new AtaErrorRegistersLba48();
// 48-bit ATA CAM commands can crash FreeBSD < 9.2-RELEASE
@@ -509,16 +516,16 @@ namespace DiscImageChef.Devices.FreeBSD
IntPtr ccbPtr = cam_getccb(dev);
CcbAtaio ataio = (CcbAtaio)Marshal.PtrToStructure(ccbPtr, typeof(CcbAtaio));
ataio.ccb_h.func_code = XptOpcode.XptAtaIo;
ataio.ccb_h.flags = AtaProtocolToCamFlags(protocol);
ataio.ccb_h.xflags = 0;
ataio.ccb_h.retry_count = 1;
ataio.ccb_h.cbfcnp = IntPtr.Zero;
ataio.ccb_h.timeout = timeout;
ataio.data_ptr = Marshal.AllocHGlobal(buffer.Length);
ataio.dxfer_len = (uint)buffer.Length;
ataio.ccb_h.flags |= CcbFlags.CamDevQfrzdis;
ataio.cmd.flags = CamAtaIoFlags.NeedResult | CamAtaIoFlags.ExtendedCommand;
ataio.ccb_h.func_code = XptOpcode.XptAtaIo;
ataio.ccb_h.flags = AtaProtocolToCamFlags(protocol);
ataio.ccb_h.xflags = 0;
ataio.ccb_h.retry_count = 1;
ataio.ccb_h.cbfcnp = IntPtr.Zero;
ataio.ccb_h.timeout = timeout;
ataio.data_ptr = Marshal.AllocHGlobal(buffer.Length);
ataio.dxfer_len = (uint)buffer.Length;
ataio.ccb_h.flags |= CcbFlags.CamDevQfrzdis;
ataio.cmd.flags = CamAtaIoFlags.NeedResult | CamAtaIoFlags.ExtendedCommand;
switch(protocol)
{
case AtaProtocol.Dma:
@@ -532,25 +539,25 @@ namespace DiscImageChef.Devices.FreeBSD
break;
}
ataio.cmd.lba_high_exp = (byte)((registers.LbaHigh & 0xFF00) >> 8);
ataio.cmd.lba_mid_exp = (byte)((registers.LbaMid & 0xFF00) >> 8);
ataio.cmd.features_exp = (byte)((registers.Feature & 0xFF00) >> 8);
ataio.cmd.lba_high_exp = (byte)((registers.LbaHigh & 0xFF00) >> 8);
ataio.cmd.lba_mid_exp = (byte)((registers.LbaMid & 0xFF00) >> 8);
ataio.cmd.features_exp = (byte)((registers.Feature & 0xFF00) >> 8);
ataio.cmd.sector_count_exp = (byte)((registers.SectorCount & 0xFF00) >> 8);
ataio.cmd.lba_low_exp = (byte)((registers.LbaLow & 0xFF00) >> 8);
ataio.cmd.lba_high = (byte)(registers.LbaHigh & 0xFF);
ataio.cmd.lba_mid = (byte)(registers.LbaMid & 0xFF);
ataio.cmd.features = (byte)(registers.Feature & 0xFF);
ataio.cmd.sector_count = (byte)(registers.SectorCount & 0xFF);
ataio.cmd.lba_low = (byte)(registers.LbaLow & 0xFF);
ataio.cmd.command = registers.Command;
ataio.cmd.device = (byte)(0x40 | registers.DeviceHead);
ataio.cmd.lba_low_exp = (byte)((registers.LbaLow & 0xFF00) >> 8);
ataio.cmd.lba_high = (byte)(registers.LbaHigh & 0xFF);
ataio.cmd.lba_mid = (byte)(registers.LbaMid & 0xFF);
ataio.cmd.features = (byte)(registers.Feature & 0xFF);
ataio.cmd.sector_count = (byte)(registers.SectorCount & 0xFF);
ataio.cmd.lba_low = (byte)(registers.LbaLow & 0xFF);
ataio.cmd.command = registers.Command;
ataio.cmd.device = (byte)(0x40 | registers.DeviceHead);
Marshal.Copy(buffer, 0, ataio.data_ptr, buffer.Length);
Marshal.StructureToPtr(ataio, ccbPtr, false);
DateTime start = DateTime.UtcNow;
int error = cam_send_ccb(dev, ccbPtr);
DateTime end = DateTime.UtcNow;
int error = cam_send_ccb(dev, ccbPtr);
DateTime end = DateTime.UtcNow;
if(error < 0) error = Marshal.GetLastWin32Error();
@@ -567,12 +574,12 @@ namespace DiscImageChef.Devices.FreeBSD
if((ataio.ccb_h.status & CamStatus.CamStatusMask) == CamStatus.CamAtaStatusError) sense = true;
errorRegisters.SectorCount = (ushort)((ataio.res.sector_count_exp << 8) + ataio.res.sector_count);
errorRegisters.LbaLow = (ushort)((ataio.res.lba_low_exp << 8) + ataio.res.lba_low);
errorRegisters.LbaMid = (ushort)((ataio.res.lba_mid_exp << 8) + ataio.res.lba_mid);
errorRegisters.LbaHigh = (ushort)((ataio.res.lba_high_exp << 8) + ataio.res.lba_high);
errorRegisters.DeviceHead = ataio.res.device;
errorRegisters.Error = ataio.res.error;
errorRegisters.Status = ataio.res.status;
errorRegisters.LbaLow = (ushort)((ataio.res.lba_low_exp << 8) + ataio.res.lba_low);
errorRegisters.LbaMid = (ushort)((ataio.res.lba_mid_exp << 8) + ataio.res.lba_mid);
errorRegisters.LbaHigh = (ushort)((ataio.res.lba_high_exp << 8) + ataio.res.lba_high);
errorRegisters.DeviceHead = ataio.res.device;
errorRegisters.Error = ataio.res.error;
errorRegisters.Status = ataio.res.status;
buffer = new byte[ataio.dxfer_len];

View File

@@ -269,34 +269,34 @@ namespace DiscImageChef.Devices.FreeBSD
[Flags]
enum PeriphPatternFlags
{
PeriphMatchNone = 0x000,
PeriphMatchPath = 0x001,
PeriphMatchNone = 0x000,
PeriphMatchPath = 0x001,
PeriphMatchTarget = 0x002,
PeriphMatchLun = 0x004,
PeriphMatchName = 0x008,
PeriphMatchUnit = 0x010
PeriphMatchLun = 0x004,
PeriphMatchName = 0x008,
PeriphMatchUnit = 0x010
// PERIPH_MATCH_ANY = 0x01f
}
[Flags]
enum DevPatternFlags
{
DevMatchNone = 0x000,
DevMatchPath = 0x001,
DevMatchTarget = 0x002,
DevMatchLun = 0x004,
DevMatchNone = 0x000,
DevMatchPath = 0x001,
DevMatchTarget = 0x002,
DevMatchLun = 0x004,
DevMatchInquiry = 0x008,
DevMatchDevid = 0x010
DevMatchDevid = 0x010
// DEV_MATCH_ANY = 0x00f
}
[Flags]
enum BusPatternFlags
{
BusMatchNone = 0x000,
BusMatchPath = 0x001,
BusMatchName = 0x002,
BusMatchUnit = 0x004,
BusMatchNone = 0x000,
BusMatchPath = 0x001,
BusMatchName = 0x002,
BusMatchUnit = 0x004,
BusMatchBusId = 0x008
// BUS_MATCH_ANY = 0x00f
}
@@ -304,7 +304,7 @@ namespace DiscImageChef.Devices.FreeBSD
[Flags]
enum DevResultFlags
{
DevResultNoflag = 0x00,
DevResultNoflag = 0x00,
DevResultUnconfigured = 0x01
}
@@ -353,32 +353,32 @@ namespace DiscImageChef.Devices.FreeBSD
enum MmcCardFeatures
{
CardFeatureMemory = 0x1,
CardFeatureSdhc = 0x1 << 1,
CardFeatureSdio = 0x1 << 2,
CardFeatureSd20 = 0x1 << 3,
CardFeatureMmc = 0x1 << 4,
CardFeature18V = 0x1 << 5
CardFeatureSdhc = 0x1 << 1,
CardFeatureSdio = 0x1 << 2,
CardFeatureSd20 = 0x1 << 3,
CardFeatureMmc = 0x1 << 4,
CardFeature18V = 0x1 << 5
}
enum CamGenerations : uint
{
CamBusGeneration = 0x00,
CamBusGeneration = 0x00,
CamTargetGeneration = 0x01,
CamDevGeneration = 0x02,
CamDevGeneration = 0x02,
CamPeriphGeneration = 0x03
}
[Flags]
enum DevPosType
{
CamDevPosNone = 0x000,
CamDevPosBus = 0x001,
CamDevPosNone = 0x000,
CamDevPosBus = 0x001,
CamDevPosTarget = 0x002,
CamDevPosDevice = 0x004,
CamDevPosPeriph = 0x008,
CamDevPosPdptr = 0x010,
CamDevPosPdptr = 0x010,
// CAM_DEV_POS_TYPEMASK = 0xf00,
CamDevPosEdt = 0x100,
CamDevPosEdt = 0x100,
CamDevPosPdrv = 0x200
}

View File

@@ -49,14 +49,14 @@ namespace DiscImageChef.Devices.FreeBSD
/// <returns>List of devices</returns>
internal static DeviceInfo[] GetList()
{
string[] passDevices = Directory.GetFiles("/dev/", "pass*", SearchOption.TopDirectoryOnly);
string[] passDevices = Directory.GetFiles("/dev/", "pass*", SearchOption.TopDirectoryOnly);
List<DeviceInfo> listDevices = new List<DeviceInfo>();
foreach(string passDevice in passDevices)
{
DeviceInfo deviceInfo = new DeviceInfo();
IntPtr dev = cam_open_device(passDevice, FileFlags.ReadWrite);
CamDevice camDevice = (CamDevice)Marshal.PtrToStructure(dev, typeof(CamDevice));
IntPtr dev = cam_open_device(passDevice, FileFlags.ReadWrite);
CamDevice camDevice = (CamDevice)Marshal.PtrToStructure(dev, typeof(CamDevice));
IntPtr ccbPtr = cam_getccb(dev);
@@ -99,7 +99,7 @@ namespace DiscImageChef.Devices.FreeBSD
for(int aIndex = 0; aIndex < 512; aIndex += 2)
{
atadTneid[aIndex] = cgd.ident_data[aIndex + 1];
atadTneid[aIndex + 1] = cgd.ident_data[aIndex];
atadTneid[aIndex + 1] = cgd.ident_data[aIndex];
}
Identify.IdentifyDevice? idt = Identify.Decode(atadTneid);
@@ -110,18 +110,19 @@ namespace DiscImageChef.Devices.FreeBSD
if(separated.Length == 1)
{
deviceInfo.Vendor = "ATA";
deviceInfo.Model = separated[0];
deviceInfo.Model = separated[0];
}
else
{
deviceInfo.Vendor = separated[0];
deviceInfo.Model = separated[separated.Length - 1];
deviceInfo.Model = separated[separated.Length - 1];
}
deviceInfo.Serial = idt.Value.SerialNumber;
deviceInfo.Bus = simName == "ahcich" ? "SATA" : "ATA";
deviceInfo.Serial = idt.Value.SerialNumber;
deviceInfo.Bus = simName == "ahcich" ? "SATA" : "ATA";
deviceInfo.Supported = simName != "ata";
}
if(cgd.protocol == CamProto.ProtoAtapi) goto case CamProto.ProtoScsi;
break;
}
@@ -130,20 +131,21 @@ namespace DiscImageChef.Devices.FreeBSD
Inquiry.SCSIInquiry? inq = Inquiry.Decode(cgd.inq_data);
if(inq.HasValue)
{
deviceInfo.Vendor = StringHandlers.CToString(inq.Value.VendorIdentification).Trim();
deviceInfo.Model = StringHandlers.CToString(inq.Value.ProductIdentification).Trim();
deviceInfo.Bus = simName == "ata" || simName == "ahcich" ? "ATAPI" : "SCSI";
deviceInfo.Vendor = StringHandlers.CToString(inq.Value.VendorIdentification).Trim();
deviceInfo.Model = StringHandlers.CToString(inq.Value.ProductIdentification).Trim();
deviceInfo.Bus = simName == "ata" || simName == "ahcich" ? "ATAPI" : "SCSI";
deviceInfo.Supported = simName != "ata";
}
break;
}
case CamProto.ProtoNvme:
deviceInfo.Bus = "NVMe";
deviceInfo.Bus = "NVMe";
deviceInfo.Supported = false;
break;
case CamProto.ProtoMmcsd:
deviceInfo.Model = "Unknown card";
deviceInfo.Bus = "MMC/SD";
deviceInfo.Model = "Unknown card";
deviceInfo.Bus = "MMC/SD";
deviceInfo.Supported = false;
break;
}

View File

@@ -50,19 +50,19 @@ namespace DiscImageChef.Devices.FreeBSD
struct AtaCmd
{
public CamAtaIoFlags flags;
public byte command;
public byte features;
public byte lba_low;
public byte lba_mid;
public byte lba_high;
public byte device;
public byte lba_low_exp;
public byte lba_mid_exp;
public byte lba_high_exp;
public byte features_exp;
public byte sector_count;
public byte sector_count_exp;
public byte control;
public byte command;
public byte features;
public byte lba_low;
public byte lba_mid;
public byte lba_high;
public byte device;
public byte lba_low_exp;
public byte lba_mid_exp;
public byte lba_high_exp;
public byte features_exp;
public byte sector_count;
public byte sector_count_exp;
public byte control;
}
[StructLayout(LayoutKind.Sequential)]
@@ -70,17 +70,17 @@ namespace DiscImageChef.Devices.FreeBSD
struct AtaRes
{
public CamAtaIoFlags flags;
public byte status;
public byte error;
public byte lba_low;
public byte lba_mid;
public byte lba_high;
public byte device;
public byte lba_low_exp;
public byte lba_mid_exp;
public byte lba_high_exp;
public byte sector_count;
public byte sector_count_exp;
public byte status;
public byte error;
public byte lba_low;
public byte lba_mid;
public byte lba_high;
public byte device;
public byte lba_low_exp;
public byte lba_mid_exp;
public byte lba_high_exp;
public byte sector_count;
public byte sector_count_exp;
}
[StructLayout(LayoutKind.Sequential)]
@@ -89,7 +89,7 @@ namespace DiscImageChef.Devices.FreeBSD
{
public uint priority;
public uint generation;
public int index;
public int index;
}
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
@@ -140,9 +140,9 @@ namespace DiscImageChef.Devices.FreeBSD
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
struct CamqEntry
{
[FieldOffset(0)] public ListEntry le;
[FieldOffset(0)] public SlistEntry sle;
[FieldOffset(0)] public TailqEntry tqe;
[FieldOffset(0)] public ListEntry le;
[FieldOffset(0)] public SlistEntry sle;
[FieldOffset(0)] public TailqEntry tqe;
[FieldOffset(0)] public StailqEntry stqe;
}
@@ -168,34 +168,37 @@ namespace DiscImageChef.Devices.FreeBSD
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
struct CcbHdr
{
public CamPinfo pinfo;
public CamPinfo pinfo;
public CamqEntry xpt_links;
public CamqEntry sim_links;
public CamqEntry periph_links;
public uint retry_count;
public IntPtr cbfcnp;
public uint retry_count;
public IntPtr cbfcnp;
public XptOpcode func_code;
public CamStatus status;
public IntPtr path;
public uint path_id;
public uint target_id;
public ulong target_lun;
public CcbFlags flags;
public uint xflags;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public IntPtr[] periph_priv;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public IntPtr[] sim_priv;
public IntPtr path;
public uint path_id;
public uint target_id;
public ulong target_lun;
public CcbFlags flags;
public uint xflags;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public IntPtr[] periph_priv;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public IntPtr[] sim_priv;
public CcbQosArea qos;
public uint timeout;
public Timeval softtimeout;
public uint timeout;
public Timeval softtimeout;
}
[StructLayout(LayoutKind.Sequential)]
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
struct ScsiSenseData
{
const int SSD_FULL_SIZE = 252;
const int SSD_FULL_SIZE = 252;
public byte error_code;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = SSD_FULL_SIZE - 1)] public byte[] sense_buf;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = SSD_FULL_SIZE - 1)]
public byte[] sense_buf;
}
/// <summary>
@@ -232,7 +235,8 @@ namespace DiscImageChef.Devices.FreeBSD
/// Area for the CDB send, or pointer to the CDB bytes to send
/// </summary>
const int IOCDBLEN = 16;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = IOCDBLEN)] public byte[] cdb_bytes;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = IOCDBLEN)]
public byte[] cdb_bytes;
/// <summary>Pointer to the message buffer</summary>
public IntPtr msg_ptr;
/// <summary>Number of bytes for the Message</summary>
@@ -283,7 +287,8 @@ namespace DiscImageChef.Devices.FreeBSD
/// Area for the CDB send, or pointer to the CDB bytes to send
/// </summary>
const int IOCDBLEN = 16;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = IOCDBLEN)] public byte[] cdb_bytes;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = IOCDBLEN)]
public byte[] cdb_bytes;
/// <summary>Pointer to the message buffer</summary>
public IntPtr msg_ptr;
/// <summary>Number of bytes for the Message</summary>
@@ -496,11 +501,12 @@ namespace DiscImageChef.Devices.FreeBSD
{
const int DEV_IDLEN = 16;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = DEV_IDLEN)] public byte[] periph_name;
public uint unit_number;
public path_id_t path_id;
public target_id_t target_id;
public lun_id_t target_lun;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = DEV_IDLEN)]
public byte[] periph_name;
public uint unit_number;
public path_id_t path_id;
public target_id_t target_id;
public lun_id_t target_lun;
public PeriphPatternFlags flags;
}
@@ -509,21 +515,25 @@ namespace DiscImageChef.Devices.FreeBSD
struct DeviceIdMatchPattern
{
public byte id_len;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)] public byte[] id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
public byte[] id;
}
[StructLayout(LayoutKind.Sequential)]
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
struct ScsiStaticInquiryPattern
{
const int SID_VENDOR_SIZE = 8;
const int SID_PRODUCT_SIZE = 16;
const int SID_REVISION_SIZE = 4;
const int SID_VENDOR_SIZE = 8;
const int SID_PRODUCT_SIZE = 16;
const int SID_REVISION_SIZE = 4;
public byte type;
public byte media_type;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = SID_VENDOR_SIZE + 1)] public byte[] vendor;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = SID_PRODUCT_SIZE + 1)] public byte[] product;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = SID_REVISION_SIZE + 1)] public byte[] revision;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = SID_VENDOR_SIZE + 1)]
public byte[] vendor;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = SID_PRODUCT_SIZE + 1)]
public byte[] product;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = SID_REVISION_SIZE + 1)]
public byte[] revision;
}
[StructLayout(LayoutKind.Explicit)]
@@ -531,17 +541,17 @@ namespace DiscImageChef.Devices.FreeBSD
struct DeviceMatchPatternData
{
[FieldOffset(0)] public ScsiStaticInquiryPattern inq_pat;
[FieldOffset(0)] public DeviceIdMatchPattern devid_pat;
[FieldOffset(0)] public DeviceIdMatchPattern devid_pat;
}
[StructLayout(LayoutKind.Sequential)]
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
struct DeviceMatchPattern
{
public uint path_id;
public uint target_id;
public uint target_lun;
public DevPatternFlags flags;
public uint path_id;
public uint target_id;
public uint target_lun;
public DevPatternFlags flags;
public DeviceMatchPatternData data;
}
@@ -552,9 +562,10 @@ namespace DiscImageChef.Devices.FreeBSD
const int DEV_IDLEN = 16;
public path_id_t path_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = DEV_IDLEN)] public byte[] dev_name;
public uint unit_number;
public uint bus_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = DEV_IDLEN)]
public byte[] dev_name;
public uint unit_number;
public uint bus_id;
BusPatternFlags flags;
}
@@ -564,7 +575,7 @@ namespace DiscImageChef.Devices.FreeBSD
{
[FieldOffset(0)] public PeriphMatchPattern periph_pattern;
[FieldOffset(0)] public DeviceMatchPattern device_pattern;
[FieldOffset(0)] public BusMatchPattern bus_pattern;
[FieldOffset(0)] public BusMatchPattern bus_pattern;
}
[StructLayout(LayoutKind.Sequential)]
@@ -579,11 +590,12 @@ namespace DiscImageChef.Devices.FreeBSD
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
struct PeriphMatchResult
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] periph_name;
public uint unit_number;
public path_id_t path_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] periph_name;
public uint unit_number;
public path_id_t path_id;
public target_id_t target_id;
public lun_id_t target_lun;
public lun_id_t target_lun;
}
[StructLayout(LayoutKind.Sequential)]
@@ -591,13 +603,14 @@ namespace DiscImageChef.Devices.FreeBSD
struct MmcCid
{
public uint mid;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public byte[] pnm;
public uint psn;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] pnm;
public uint psn;
public ushort oid;
public ushort mdt_year;
public byte mdt_month;
public byte prv;
public byte fwrev;
public byte mdt_month;
public byte prv;
public byte fwrev;
}
[StructLayout(LayoutKind.Sequential)]
@@ -607,7 +620,8 @@ namespace DiscImageChef.Devices.FreeBSD
/// <summary>
/// Card model
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 40)] public byte[] model;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 40)]
public byte[] model;
/// <summary>
/// Card OCR
@@ -622,7 +636,8 @@ namespace DiscImageChef.Devices.FreeBSD
/// <summary>
/// Card CID -- raw
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public uint[] card_cid;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public uint[] card_cid;
/// <summary>
/// Card CID -- parsed
@@ -632,7 +647,8 @@ namespace DiscImageChef.Devices.FreeBSD
/// <summary>
/// Card CSD -- raw
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public uint[] card_csd;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public uint[] card_csd;
/// <summary>
/// Card RCA
@@ -651,14 +667,16 @@ namespace DiscImageChef.Devices.FreeBSD
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
struct DeviceMatchResult
{
public path_id_t path_id;
public path_id_t path_id;
public target_id_t target_id;
public lun_id_t target_lun;
public CamProto protocol;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)] public byte[] inq_data;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)] public byte[] ident_data;
public lun_id_t target_lun;
public CamProto protocol;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
public byte[] inq_data;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)]
public byte[] ident_data;
public DevResultFlags flags;
public MmcParams mmc_ident_data;
public MmcParams mmc_ident_data;
}
[StructLayout(LayoutKind.Sequential)]
@@ -666,8 +684,9 @@ namespace DiscImageChef.Devices.FreeBSD
struct BusMatchResult
{
public path_id_t path_id;
const int DEV_IDLEN = 16;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = DEV_IDLEN)] public byte[] dev_name;
const int DEV_IDLEN = 16;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = DEV_IDLEN)]
public byte[] dev_name;
public uint unit_number;
public uint bus_id;
}
@@ -678,7 +697,7 @@ namespace DiscImageChef.Devices.FreeBSD
{
[FieldOffset(0)] public PeriphMatchResult periph_result;
[FieldOffset(0)] public DeviceMatchResult device_result;
[FieldOffset(0)] public BusMatchResult bus_result;
[FieldOffset(0)] public BusMatchResult bus_result;
}
[StructLayout(LayoutKind.Sequential)]
@@ -686,7 +705,7 @@ namespace DiscImageChef.Devices.FreeBSD
struct DevMatchResult
{
public DevMatchType type;
public MatchResult result;
public MatchResult result;
}
[StructLayout(LayoutKind.Sequential)]
@@ -704,8 +723,9 @@ namespace DiscImageChef.Devices.FreeBSD
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
struct CcbDevPosition
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public CamGenerations[] generations;
DevPosType position_type;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public CamGenerations[] generations;
DevPosType position_type;
public CcbDmCookie cookie;
}
@@ -713,10 +733,10 @@ namespace DiscImageChef.Devices.FreeBSD
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
struct CcbDevMatch
{
public CcbHdr ccb_h;
public CcbHdr ccb_h;
CcbDevMatchStatus status;
public uint num_patterns;
public uint pattern_buf_len;
public uint num_patterns;
public uint pattern_buf_len;
/// <summary>
/// dev_match_pattern*
@@ -738,17 +758,19 @@ namespace DiscImageChef.Devices.FreeBSD
struct CamDevice
{
const int MAXPATHLEN = 1024;
const int DEV_IDLEN = 16;
const int SIM_IDLEN = 16;
const int DEV_IDLEN = 16;
const int SIM_IDLEN = 16;
/// <summary>
/// Pathname of the device given by the user. This may be null if the user states the device name and unit number
/// separately.
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = MAXPATHLEN)] public byte[] DevicePath;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = MAXPATHLEN)]
public byte[] DevicePath;
/// <summary>
/// Device name given by the user.
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = DEV_IDLEN + 1)] public byte[] GivenDevName;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = DEV_IDLEN + 1)]
public byte[] GivenDevName;
/// <summary>
/// Unit number given by the user.
/// </summary>
@@ -756,7 +778,8 @@ namespace DiscImageChef.Devices.FreeBSD
/// <summary>
/// Name of the device, e.g. 'pass'
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = DEV_IDLEN + 1)] public byte[] DeviceName;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = DEV_IDLEN + 1)]
public byte[] DeviceName;
/// <summary>
/// Unit number of the passthrough device associated with this particular device.
/// </summary>
@@ -764,7 +787,8 @@ namespace DiscImageChef.Devices.FreeBSD
/// <summary>
/// Controller name, e.g. 'ahc'
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = SIM_IDLEN + 1)] public byte[] SimName;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = SIM_IDLEN + 1)]
public byte[] SimName;
/// <summary>
/// Controller unit number
/// </summary>
@@ -792,11 +816,13 @@ namespace DiscImageChef.Devices.FreeBSD
/// <summary>
/// SCSI Inquiry data
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)] public byte[] InqData;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
public byte[] InqData;
/// <summary>
/// device serial number
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 252)] public byte[] SerialNum;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 252)]
public byte[] SerialNum;
/// <summary>
/// length of the serial number
/// </summary>
@@ -823,19 +849,23 @@ namespace DiscImageChef.Devices.FreeBSD
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
struct CcbGetdev
{
public CcbHdr ccb_h;
public CcbHdr ccb_h;
public CamProto protocol;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)] public byte[] inq_data;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)] public byte[] ident_data;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
public byte[] inq_data;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)]
public byte[] ident_data;
/// <summary>
/// device serial number
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 252)] public byte[] serial_num;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 252)]
public byte[] serial_num;
public byte inq_flags;
/// <summary>
/// length of the serial number
/// </summary>
public byte serial_num_len;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public IntPtr[] padding;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public IntPtr[] padding;
}
}

View File

@@ -46,15 +46,16 @@ namespace DiscImageChef.Devices.Linux
/// <returns>List of devices</returns>
internal static DeviceInfo[] GetList()
{
string[] sysdevs = Directory.GetFileSystemEntries(PATH_SYS_DEVBLOCK, "*", SearchOption.TopDirectoryOnly);
string[] sysdevs =
Directory.GetFileSystemEntries(PATH_SYS_DEVBLOCK, "*", SearchOption.TopDirectoryOnly);
DeviceInfo[] devices = new DeviceInfo[sysdevs.Length];
bool hasUdev;
bool hasUdev;
IntPtr udev = IntPtr.Zero;
try
{
udev = Extern.udev_new();
udev = Extern.udev_new();
hasUdev = udev != IntPtr.Zero;
}
catch { hasUdev = false; }
@@ -68,7 +69,7 @@ namespace DiscImageChef.Devices.Linux
IntPtr 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");
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('_', ' ');
devices[i].Serial = Extern.udev_device_get_property_value(udevDev, "ID_SCSI_SERIAL");
if(string.IsNullOrEmpty(devices[i].Serial))
@@ -79,7 +80,7 @@ namespace DiscImageChef.Devices.Linux
StreamReader sr;
if(File.Exists(Path.Combine(sysdevs[i], "device/vendor")) && string.IsNullOrEmpty(devices[i].Vendor))
{
sr = new StreamReader(Path.Combine(sysdevs[i], "device/vendor"), Encoding.ASCII);
sr = new StreamReader(Path.Combine(sysdevs[i], "device/vendor"), Encoding.ASCII);
devices[i].Vendor = sr.ReadLine()?.Trim();
}
else if(devices[i].Path.StartsWith("/dev/loop", StringComparison.CurrentCulture))
@@ -88,7 +89,7 @@ namespace DiscImageChef.Devices.Linux
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);
sr = new StreamReader(Path.Combine(sysdevs[i], "device/model"), Encoding.ASCII);
devices[i].Model = sr.ReadLine()?.Trim();
}
else if(devices[i].Path.StartsWith("/dev/loop", StringComparison.CurrentCulture))
@@ -96,7 +97,7 @@ namespace DiscImageChef.Devices.Linux
if(File.Exists(Path.Combine(sysdevs[i], "device/serial")) && string.IsNullOrEmpty(devices[i].Serial))
{
sr = new StreamReader(Path.Combine(sysdevs[i], "device/serial"), Encoding.ASCII);
sr = new StreamReader(Path.Combine(sysdevs[i], "device/serial"), Encoding.ASCII);
devices[i].Serial = sr.ReadLine()?.Trim();
}
@@ -107,7 +108,7 @@ namespace DiscImageChef.Devices.Linux
if(pieces.Length > 1)
{
devices[i].Vendor = pieces[0];
devices[i].Model = devices[i].Model.Substring(pieces[0].Length + 1);
devices[i].Model = devices[i].Model.Substring(pieces[0].Length + 1);
}
}

View File

@@ -44,28 +44,28 @@ namespace DiscImageChef.Devices.Linux
/// <summary>
/// Always 'S' for SG v3
/// </summary>
public int interface_id; /* [i] 'S' (required) */
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 ushort host_status; /* [o] */
public ushort driver_status; /* [o] */
public int resid; /* [o] */
public uint duration; /* [o] */
public SgInfo info; /* [o] */
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 ushort host_status; /* [o] */
public ushort driver_status; /* [o] */
public int resid; /* [o] */
public uint duration; /* [o] */
public SgInfo info; /* [o] */
}
[StructLayout(LayoutKind.Sequential)]
@@ -85,10 +85,11 @@ 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;
public uint blksz;
public uint blocks;
/// <summary>
/// Sleep at least <see cref="postsleep_min_us" /> useconds, and at most
/// <see cref="postsleep_max_us" /> useconds *after* issuing command.Needed for

View File

@@ -58,13 +58,14 @@ namespace DiscImageChef.Devices.Windows
/// <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;
duration = 0;
sense = false;
if(buffer == null) return -1;
@@ -73,21 +74,21 @@ namespace DiscImageChef.Devices.Windows
SenseBuf = new byte[32],
sptd = new ScsiPassThroughDirect
{
Cdb = new byte[16],
CdbLength = (byte)cdb.Length,
SenseInfoLength = 32,
DataIn = direction,
Cdb = new byte[16],
CdbLength = (byte)cdb.Length,
SenseInfoLength = 32,
DataIn = direction,
DataTransferLength = (uint)buffer.Length,
TimeOutValue = timeout,
DataBuffer = Marshal.AllocHGlobal(buffer.Length)
TimeOutValue = timeout,
DataBuffer = Marshal.AllocHGlobal(buffer.Length)
}
};
sptdSb.sptd.Length = (ushort)Marshal.SizeOf(sptdSb.sptd);
sptdSb.sptd.Length = (ushort)Marshal.SizeOf(sptdSb.sptd);
sptdSb.sptd.SenseInfoOffset = (uint)Marshal.SizeOf(sptdSb.sptd);
Array.Copy(cdb, sptdSb.sptd.Cdb, cdb.Length);
uint k = 0;
int error = 0;
uint k = 0;
int error = 0;
Marshal.Copy(buffer, 0, sptdSb.sptd.DataBuffer, buffer.Length);
@@ -125,12 +126,13 @@ namespace DiscImageChef.Devices.Windows
/// <param name="registers">Registers to send to drive</param>
/// <param name="errorRegisters">Registers returned by drive</param>
/// <param name="protocol">ATA protocol to use</param>
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;
duration = 0;
sense = false;
errorRegisters = new AtaErrorRegistersChs();
if(buffer == null) return -1;
@@ -141,19 +143,19 @@ namespace DiscImageChef.Devices.Windows
{
aptd = new AtaPassThroughDirect
{
TimeOutValue = timeout,
DataBuffer = (IntPtr)offsetForBuffer,
Length = (ushort)Marshal.SizeOf(typeof(AtaPassThroughDirect)),
TimeOutValue = timeout,
DataBuffer = (IntPtr)offsetForBuffer,
Length = (ushort)Marshal.SizeOf(typeof(AtaPassThroughDirect)),
DataTransferLength = (uint)buffer.Length,
PreviousTaskFile = new AtaTaskFile(),
PreviousTaskFile = new AtaTaskFile(),
CurrentTaskFile = new AtaTaskFile
{
Command = registers.Command,
Command = registers.Command,
CylinderHigh = registers.CylinderHigh,
CylinderLow = registers.CylinderLow,
DeviceHead = registers.DeviceHead,
Features = registers.Feature,
SectorCount = registers.SectorCount,
CylinderLow = registers.CylinderLow,
DeviceHead = registers.DeviceHead,
Features = registers.Feature,
SectorCount = registers.SectorCount,
SectorNumber = registers.Sector
}
},
@@ -187,8 +189,8 @@ namespace DiscImageChef.Devices.Windows
// Unknown if needed
aptdBuf.aptd.AtaFlags |= AtaFlags.DrdyRequired;
uint k = 0;
int error = 0;
uint k = 0;
int error = 0;
Array.Copy(buffer, 0, aptdBuf.dataBuffer, 0, buffer.Length);
@@ -205,12 +207,12 @@ namespace DiscImageChef.Devices.Windows
duration = (end - start).TotalMilliseconds;
errorRegisters.CylinderHigh = aptdBuf.aptd.CurrentTaskFile.CylinderHigh;
errorRegisters.CylinderLow = aptdBuf.aptd.CurrentTaskFile.CylinderLow;
errorRegisters.DeviceHead = aptdBuf.aptd.CurrentTaskFile.DeviceHead;
errorRegisters.Error = aptdBuf.aptd.CurrentTaskFile.Error;
errorRegisters.Sector = aptdBuf.aptd.CurrentTaskFile.SectorNumber;
errorRegisters.SectorCount = aptdBuf.aptd.CurrentTaskFile.SectorCount;
errorRegisters.Status = aptdBuf.aptd.CurrentTaskFile.Status;
errorRegisters.CylinderLow = aptdBuf.aptd.CurrentTaskFile.CylinderLow;
errorRegisters.DeviceHead = aptdBuf.aptd.CurrentTaskFile.DeviceHead;
errorRegisters.Error = aptdBuf.aptd.CurrentTaskFile.Error;
errorRegisters.Sector = aptdBuf.aptd.CurrentTaskFile.SectorNumber;
errorRegisters.SectorCount = aptdBuf.aptd.CurrentTaskFile.SectorCount;
errorRegisters.Status = aptdBuf.aptd.CurrentTaskFile.Status;
sense = errorRegisters.Error != 0 || (errorRegisters.Status & 0xA5) != 0;
@@ -229,12 +231,13 @@ namespace DiscImageChef.Devices.Windows
/// <param name="registers">Registers to send to drive</param>
/// <param name="errorRegisters">Registers returned by drive</param>
/// <param name="protocol">ATA protocol to use</param>
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;
duration = 0;
sense = false;
errorRegisters = new AtaErrorRegistersLba28();
if(buffer == null) return -1;
@@ -245,19 +248,19 @@ namespace DiscImageChef.Devices.Windows
{
aptd = new AtaPassThroughDirect
{
TimeOutValue = timeout,
DataBuffer = (IntPtr)offsetForBuffer,
Length = (ushort)Marshal.SizeOf(typeof(AtaPassThroughDirect)),
TimeOutValue = timeout,
DataBuffer = (IntPtr)offsetForBuffer,
Length = (ushort)Marshal.SizeOf(typeof(AtaPassThroughDirect)),
DataTransferLength = (uint)buffer.Length,
PreviousTaskFile = new AtaTaskFile(),
PreviousTaskFile = new AtaTaskFile(),
CurrentTaskFile = new AtaTaskFile
{
Command = registers.Command,
Command = registers.Command,
CylinderHigh = registers.LbaHigh,
CylinderLow = registers.LbaMid,
DeviceHead = registers.DeviceHead,
Features = registers.Feature,
SectorCount = registers.SectorCount,
CylinderLow = registers.LbaMid,
DeviceHead = registers.DeviceHead,
Features = registers.Feature,
SectorCount = registers.SectorCount,
SectorNumber = registers.LbaLow
}
},
@@ -291,8 +294,8 @@ namespace DiscImageChef.Devices.Windows
// Unknown if needed
aptdBuf.aptd.AtaFlags |= AtaFlags.DrdyRequired;
uint k = 0;
int error = 0;
uint k = 0;
int error = 0;
Array.Copy(buffer, 0, aptdBuf.dataBuffer, 0, buffer.Length);
@@ -308,13 +311,13 @@ namespace DiscImageChef.Devices.Windows
duration = (end - start).TotalMilliseconds;
errorRegisters.LbaHigh = aptdBuf.aptd.CurrentTaskFile.CylinderHigh;
errorRegisters.LbaMid = aptdBuf.aptd.CurrentTaskFile.CylinderLow;
errorRegisters.DeviceHead = aptdBuf.aptd.CurrentTaskFile.DeviceHead;
errorRegisters.Error = aptdBuf.aptd.CurrentTaskFile.Error;
errorRegisters.LbaLow = aptdBuf.aptd.CurrentTaskFile.SectorNumber;
errorRegisters.LbaHigh = aptdBuf.aptd.CurrentTaskFile.CylinderHigh;
errorRegisters.LbaMid = aptdBuf.aptd.CurrentTaskFile.CylinderLow;
errorRegisters.DeviceHead = aptdBuf.aptd.CurrentTaskFile.DeviceHead;
errorRegisters.Error = aptdBuf.aptd.CurrentTaskFile.Error;
errorRegisters.LbaLow = aptdBuf.aptd.CurrentTaskFile.SectorNumber;
errorRegisters.SectorCount = aptdBuf.aptd.CurrentTaskFile.SectorCount;
errorRegisters.Status = aptdBuf.aptd.CurrentTaskFile.Status;
errorRegisters.Status = aptdBuf.aptd.CurrentTaskFile.Status;
sense = errorRegisters.Error != 0 || (errorRegisters.Status & 0xA5) != 0;
@@ -333,12 +336,13 @@ namespace DiscImageChef.Devices.Windows
/// <param name="registers">Registers to send to drive</param>
/// <param name="errorRegisters">Registers returned by drive</param>
/// <param name="protocol">ATA protocol to use</param>
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;
duration = 0;
sense = false;
errorRegisters = new AtaErrorRegistersLba48();
if(buffer == null) return -1;
@@ -349,28 +353,28 @@ namespace DiscImageChef.Devices.Windows
{
aptd = new AtaPassThroughDirect
{
TimeOutValue = timeout,
DataBuffer = (IntPtr)offsetForBuffer,
Length = (ushort)Marshal.SizeOf(typeof(AtaPassThroughDirect)),
TimeOutValue = timeout,
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)
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,
Command = registers.Command,
CylinderHigh = (byte)(registers.LbaHigh & 0xFF),
CylinderLow = (byte)(registers.LbaMid & 0xFF),
DeviceHead = registers.DeviceHead,
Features = (byte)(registers.Feature & 0xFF),
SectorCount = (byte)(registers.SectorCount & 0xFF),
SectorNumber = (byte)(registers.LbaLow & 0xFF)
CylinderLow = (byte)(registers.LbaMid & 0xFF),
DeviceHead = registers.DeviceHead,
Features = (byte)(registers.Feature & 0xFF),
SectorCount = (byte)(registers.SectorCount & 0xFF),
SectorNumber = (byte)(registers.LbaLow & 0xFF)
}
},
dataBuffer = new byte[64 * 512]
@@ -403,8 +407,8 @@ namespace DiscImageChef.Devices.Windows
// Unknown if needed
aptdBuf.aptd.AtaFlags |= AtaFlags.DrdyRequired;
uint k = 0;
int error = 0;
uint k = 0;
int error = 0;
Array.Copy(buffer, 0, aptdBuf.dataBuffer, 0, buffer.Length);
@@ -429,8 +433,8 @@ namespace DiscImageChef.Devices.Windows
errorRegisters.LbaHigh = (ushort)((aptdBuf.aptd.PreviousTaskFile.CylinderHigh << 8) +
aptdBuf.aptd.CurrentTaskFile.CylinderHigh);
errorRegisters.DeviceHead = aptdBuf.aptd.CurrentTaskFile.DeviceHead;
errorRegisters.Error = aptdBuf.aptd.CurrentTaskFile.Error;
errorRegisters.Status = aptdBuf.aptd.CurrentTaskFile.Status;
errorRegisters.Error = aptdBuf.aptd.CurrentTaskFile.Error;
errorRegisters.Status = aptdBuf.aptd.CurrentTaskFile.Status;
sense = errorRegisters.Error != 0 || (errorRegisters.Status & 0xA5) != 0;
@@ -449,12 +453,13 @@ namespace DiscImageChef.Devices.Windows
/// <param name="registers">Registers to send to drive</param>
/// <param name="errorRegisters">Registers returned by drive</param>
/// <param name="protocol">ATA protocol to use</param>
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;
duration = 0;
sense = false;
errorRegisters = new AtaErrorRegistersChs();
if(buffer == null || buffer.Length > 512) return -1;
@@ -463,20 +468,20 @@ namespace DiscImageChef.Devices.Windows
{
CurrentTaskFile = new AtaTaskFile
{
Command = registers.Command,
Command = registers.Command,
CylinderHigh = registers.CylinderHigh,
CylinderLow = registers.CylinderLow,
DeviceHead = registers.DeviceHead,
Features = registers.Feature,
SectorCount = registers.SectorCount,
CylinderLow = registers.CylinderLow,
DeviceHead = registers.DeviceHead,
Features = registers.Feature,
SectorCount = registers.SectorCount,
SectorNumber = registers.Sector
},
DataBufferSize = 512,
DataBuffer = new byte[512]
DataBuffer = new byte[512]
};
uint k = 0;
int error = 0;
uint k = 0;
int error = 0;
Array.Copy(buffer, 0, iptd.DataBuffer, 0, buffer.Length);
@@ -494,12 +499,12 @@ namespace DiscImageChef.Devices.Windows
duration = (end - start).TotalMilliseconds;
errorRegisters.CylinderHigh = iptd.CurrentTaskFile.CylinderHigh;
errorRegisters.CylinderLow = iptd.CurrentTaskFile.CylinderLow;
errorRegisters.DeviceHead = iptd.CurrentTaskFile.DeviceHead;
errorRegisters.Error = iptd.CurrentTaskFile.Error;
errorRegisters.Sector = iptd.CurrentTaskFile.SectorNumber;
errorRegisters.SectorCount = iptd.CurrentTaskFile.SectorCount;
errorRegisters.Status = iptd.CurrentTaskFile.Status;
errorRegisters.CylinderLow = iptd.CurrentTaskFile.CylinderLow;
errorRegisters.DeviceHead = iptd.CurrentTaskFile.DeviceHead;
errorRegisters.Error = iptd.CurrentTaskFile.Error;
errorRegisters.Sector = iptd.CurrentTaskFile.SectorNumber;
errorRegisters.SectorCount = iptd.CurrentTaskFile.SectorCount;
errorRegisters.Status = iptd.CurrentTaskFile.Status;
sense = errorRegisters.Error != 0 || (errorRegisters.Status & 0xA5) != 0;
@@ -518,12 +523,13 @@ namespace DiscImageChef.Devices.Windows
/// <param name="registers">Registers to send to drive</param>
/// <param name="errorRegisters">Registers returned by drive</param>
/// <param name="protocol">ATA protocol to use</param>
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;
duration = 0;
sense = false;
errorRegisters = new AtaErrorRegistersLba28();
if(buffer == null) return -1;
@@ -532,20 +538,20 @@ namespace DiscImageChef.Devices.Windows
{
CurrentTaskFile = new AtaTaskFile
{
Command = registers.Command,
Command = registers.Command,
CylinderHigh = registers.LbaHigh,
CylinderLow = registers.LbaMid,
DeviceHead = registers.DeviceHead,
Features = registers.Feature,
SectorCount = registers.SectorCount,
CylinderLow = registers.LbaMid,
DeviceHead = registers.DeviceHead,
Features = registers.Feature,
SectorCount = registers.SectorCount,
SectorNumber = registers.LbaLow
},
DataBufferSize = 512,
DataBuffer = new byte[512]
DataBuffer = new byte[512]
};
uint k = 0;
int error = 0;
uint k = 0;
int error = 0;
Array.Copy(buffer, 0, iptd.DataBuffer, 0, buffer.Length);
@@ -562,13 +568,13 @@ namespace DiscImageChef.Devices.Windows
duration = (end - start).TotalMilliseconds;
errorRegisters.LbaHigh = iptd.CurrentTaskFile.CylinderHigh;
errorRegisters.LbaMid = iptd.CurrentTaskFile.CylinderLow;
errorRegisters.DeviceHead = iptd.CurrentTaskFile.DeviceHead;
errorRegisters.Error = iptd.CurrentTaskFile.Error;
errorRegisters.LbaLow = iptd.CurrentTaskFile.SectorNumber;
errorRegisters.LbaHigh = iptd.CurrentTaskFile.CylinderHigh;
errorRegisters.LbaMid = iptd.CurrentTaskFile.CylinderLow;
errorRegisters.DeviceHead = iptd.CurrentTaskFile.DeviceHead;
errorRegisters.Error = iptd.CurrentTaskFile.Error;
errorRegisters.LbaLow = iptd.CurrentTaskFile.SectorNumber;
errorRegisters.SectorCount = iptd.CurrentTaskFile.SectorCount;
errorRegisters.Status = iptd.CurrentTaskFile.Status;
errorRegisters.Status = iptd.CurrentTaskFile.Status;
sense = errorRegisters.Error != 0 || (errorRegisters.Status & 0xA5) != 0;
@@ -583,7 +589,7 @@ namespace DiscImageChef.Devices.Windows
static uint GetDeviceNumber(SafeFileHandle deviceHandle)
{
StorageDeviceNumber sdn = new StorageDeviceNumber {deviceNumber = -1};
uint k = 0;
uint k = 0;
if(!Extern.DeviceIoControlGetDeviceNumber(deviceHandle, WindowsIoctl.IoctlStorageGetDeviceNumber,
IntPtr.Zero, 0, ref sdn, (uint)Marshal.SizeOf(sdn), ref k,
IntPtr.Zero)) return uint.MaxValue;
@@ -609,7 +615,7 @@ namespace DiscImageChef.Devices.Windows
if(hDevInfo.IsInvalid) return null;
uint index = 0;
uint index = 0;
DeviceInterfaceData spdid = new DeviceInterfaceData();
spdid.cbSize = Marshal.SizeOf(spdid);
@@ -700,19 +706,22 @@ namespace DiscImageChef.Devices.Windows
/// <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(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)
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)
{
SffdiskDeviceCommandData commandData = new SffdiskDeviceCommandData();
SdCmdDescriptor commandDescriptor = new SdCmdDescriptor();
commandData.size = (ushort)Marshal.SizeOf(commandData);
commandData.command = SffdiskDcmd.DeviceCommand;
commandData.protocolArgumentSize = (ushort)Marshal.SizeOf(commandDescriptor);
commandData.deviceDataBufferSize = blockSize * blocks;
commandDescriptor.commandCode = (byte)command;
commandDescriptor.cmdClass = isApplication ? SdCommandClass.AppCmd : SdCommandClass.Standard;
SffdiskDeviceCommandData commandData = new SffdiskDeviceCommandData();
SdCmdDescriptor commandDescriptor = new SdCmdDescriptor();
commandData.size = (ushort)Marshal.SizeOf(commandData);
commandData.command = SffdiskDcmd.DeviceCommand;
commandData.protocolArgumentSize = (ushort)Marshal.SizeOf(commandDescriptor);
commandData.deviceDataBufferSize = blockSize * blocks;
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
@@ -742,7 +751,7 @@ namespace DiscImageChef.Devices.Windows
Marshal.Copy(hBuf, commandB, 0, commandB.Length);
Marshal.FreeHGlobal(hBuf);
int error = 0;
int error = 0;
DateTime start = DateTime.Now;
sense = !Extern.DeviceIoControl(fd, WindowsIoctl.IoctlSffdiskDeviceCommand, commandB, (uint)commandB.Length,
commandB, (uint)commandB.Length, out _, IntPtr.Zero);

View File

@@ -327,7 +327,7 @@ namespace DiscImageChef.Devices.Windows
enum WindowsIoctl : uint
{
IoctlAtaPassThrough = 0x4D02C,
IoctlAtaPassThrough = 0x4D02C,
IoctlAtaPassThroughDirect = 0x4D030,
/// <summary>
/// ScsiPassThrough
@@ -341,11 +341,11 @@ namespace DiscImageChef.Devices.Windows
/// ScsiGetAddress
/// </summary>
IoctlScsiGetAddress = 0x41018,
IoctlStorageQueryProperty = 0x2D1400,
IoctlIdePassThrough = 0x4D028,
IoctlStorageGetDeviceNumber = 0x2D1080,
IoctlStorageQueryProperty = 0x2D1400,
IoctlIdePassThrough = 0x4D028,
IoctlStorageGetDeviceNumber = 0x2D1080,
IoctlSffdiskQueryDeviceProtocol = 0x71E80,
IoctlSffdiskDeviceCommand = 0x79E84
IoctlSffdiskDeviceCommand = 0x79E84
}
[Flags]
@@ -379,51 +379,51 @@ namespace DiscImageChef.Devices.Windows
enum StoragePropertyId
{
Device = 0,
Adapter = 1,
Id = 2,
UniqueId = 3,
WriteCache = 4,
Miniport = 5,
AccessAlignment = 6,
SeekPenalty = 7,
Trim = 8,
Device = 0,
Adapter = 1,
Id = 2,
UniqueId = 3,
WriteCache = 4,
Miniport = 5,
AccessAlignment = 6,
SeekPenalty = 7,
Trim = 8,
WriteAggregation = 9,
Telemetry = 10,
LbProvisioning = 11,
Power = 12,
Copyoffload = 13,
Resiliency = 14
Telemetry = 10,
LbProvisioning = 11,
Power = 12,
Copyoffload = 13,
Resiliency = 14
}
enum StorageQueryType
{
Standard = 0,
Exists = 1,
Mask = 2,
Max = 3
Exists = 1,
Mask = 2,
Max = 3
}
[SuppressMessage("ReSharper", "InconsistentNaming")]
enum StorageBusType
{
Unknown = 0,
SCSI = 1,
ATAPI = 2,
ATA = 3,
FireWire = 4,
SSA = 5,
Fibre = 6,
USB = 7,
RAID = 8,
iSCSI = 9,
SAS = 0xA,
SATA = 0xB,
SecureDigital = 0xC,
MultiMediaCard = 0xD,
Virtual = 0xE,
Unknown = 0,
SCSI = 1,
ATAPI = 2,
ATA = 3,
FireWire = 4,
SSA = 5,
Fibre = 6,
USB = 7,
RAID = 8,
iSCSI = 9,
SAS = 0xA,
SATA = 0xB,
SecureDigital = 0xC,
MultiMediaCard = 0xD,
Virtual = 0xE,
FileBackedVirtual = 0xF,
NVMe = 0x11
NVMe = 0x11
}
[Flags]

View File

@@ -40,72 +40,99 @@ 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,
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,
internal static extern bool DeviceIoControlScsi(SafeFileHandle hDevice,
WindowsIoctl ioControlCode,
ref ScsiPassThroughDirectAndSenseBuffer inBuffer,
uint nInBufferSize,
uint nInBufferSize,
ref ScsiPassThroughDirectAndSenseBuffer outBuffer,
uint nOutBufferSize, ref uint pBytesReturned,
IntPtr overlapped);
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,
internal static extern bool DeviceIoControlAta(SafeFileHandle hDevice,
WindowsIoctl ioControlCode,
ref AtaPassThroughDirectWithBuffer inBuffer,
uint nInBufferSize,
ref AtaPassThroughDirectWithBuffer outBuffer,
uint nOutBufferSize, ref uint pBytesReturned, IntPtr overlapped);
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,
internal static extern bool DeviceIoControlGetDeviceNumber(SafeFileHandle hDevice,
WindowsIoctl ioControlCode,
IntPtr inBuffer,
uint nInBufferSize,
ref StorageDeviceNumber outBuffer,
uint nOutBufferSize, ref uint pBytesReturned,
IntPtr overlapped);
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);
internal static extern bool DeviceIoControl(SafeFileHandle hDevice, WindowsIoctl ioControlCode,
byte[] inBuffer,
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,
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,
public static extern bool SetupDiGetDeviceInterfaceDetail(SafeFileHandle hDevInfo,
ref DeviceInterfaceData deviceInterfaceData,
IntPtr deviceInterfaceDetailData,
uint deviceInterfaceDetailDataSize,
ref uint requiredSize, IntPtr deviceInfoData);
IntPtr deviceInterfaceDetailData,
uint deviceInterfaceDetailDataSize,
ref uint requiredSize,
IntPtr deviceInfoData);
[DllImport("setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool SetupDiDestroyDeviceInfoList(SafeFileHandle hDevInfo);

View File

@@ -50,8 +50,8 @@ namespace DiscImageChef.Devices.Windows
/// <returns>Decoded string</returns>
static string HexStringToString(string hex)
{
StringBuilder result = new StringBuilder();
const string HEXTABLE = "0123456789abcdef";
StringBuilder result = new StringBuilder();
const string HEXTABLE = "0123456789abcdef";
for(int i = 0; i < hex.Length / 2; i++)
result.Append((char)(16 * HEXTABLE.IndexOf(hex[2 * i]) + HEXTABLE.IndexOf(hex[2 * i + 1])));
@@ -77,20 +77,20 @@ namespace DiscImageChef.Devices.Windows
deviceIDs.AddRange(from ManagementObject drive in objCol select (string)drive["DeviceID"]);
mgmtObjSearcher = new ManagementObjectSearcher("SELECT * FROM Win32_TapeDrive");
objCol = mgmtObjSearcher.Get();
objCol = mgmtObjSearcher.Get();
deviceIDs.AddRange(from ManagementObject drive in objCol select (string)drive["DeviceID"]);
mgmtObjSearcher = new ManagementObjectSearcher("SELECT * FROM Win32_CDROMDrive");
objCol = mgmtObjSearcher.Get();
objCol = mgmtObjSearcher.Get();
deviceIDs.AddRange(from ManagementObject drive in objCol select (string)drive["Drive"]);
}
catch(Exception)
{
#if DEBUG
#if DEBUG
throw;
#else
#else
return null;
#endif
}
@@ -108,8 +108,8 @@ namespace DiscImageChef.Devices.Windows
StoragePropertyQuery query = new StoragePropertyQuery
{
PropertyId = StoragePropertyId.Device,
QueryType = StorageQueryType.Standard,
PropertyId = StoragePropertyId.Device,
QueryType = StorageQueryType.Standard,
AdditionalParameters = new byte[1]
};
@@ -117,10 +117,10 @@ namespace DiscImageChef.Devices.Windows
//descriptor.RawDeviceProperties = new byte[16384];
IntPtr descriptorPtr = Marshal.AllocHGlobal(1000);
byte[] descriptorB = new byte[1000];
byte[] descriptorB = new byte[1000];
uint returned = 0;
int error = 0;
int error = 0;
bool hasError = !Extern.DeviceIoControlStorageQuery(fd, WindowsIoctl.IoctlStorageQueryProperty,
ref query, (uint)Marshal.SizeOf(query),
@@ -134,18 +134,18 @@ namespace DiscImageChef.Devices.Windows
StorageDeviceDescriptor descriptor = new StorageDeviceDescriptor
{
Version = BitConverter.ToUInt32(descriptorB, 0),
Size = BitConverter.ToUInt32(descriptorB, 4),
DeviceType = descriptorB[8],
DeviceTypeModifier = descriptorB[9],
RemovableMedia = BitConverter.ToBoolean(descriptorB, 10),
CommandQueueing = BitConverter.ToBoolean(descriptorB, 11),
VendorIdOffset = BitConverter.ToInt32(descriptorB, 12),
ProductIdOffset = BitConverter.ToInt32(descriptorB, 16),
Version = BitConverter.ToUInt32(descriptorB, 0),
Size = BitConverter.ToUInt32(descriptorB, 4),
DeviceType = descriptorB[8],
DeviceTypeModifier = descriptorB[9],
RemovableMedia = BitConverter.ToBoolean(descriptorB, 10),
CommandQueueing = BitConverter.ToBoolean(descriptorB, 11),
VendorIdOffset = BitConverter.ToInt32(descriptorB, 12),
ProductIdOffset = BitConverter.ToInt32(descriptorB, 16),
ProductRevisionOffset = BitConverter.ToInt32(descriptorB, 20),
SerialNumberOffset = BitConverter.ToInt32(descriptorB, 24),
BusType = (StorageBusType)BitConverter.ToUInt32(descriptorB, 28),
RawPropertiesLength = BitConverter.ToUInt32(descriptorB, 32)
SerialNumberOffset = BitConverter.ToInt32(descriptorB, 24),
BusType = (StorageBusType)BitConverter.ToUInt32(descriptorB, 28),
RawPropertiesLength = BitConverter.ToUInt32(descriptorB, 32)
};
DeviceInfo info = new DeviceInfo {Path = physId, Bus = descriptor.BusType.ToString()};
@@ -173,7 +173,7 @@ namespace DiscImageChef.Devices.Windows
if(pieces.Length > 1)
{
info.Vendor = pieces[0];
info.Model = info.Model.Substring(pieces[0].Length + 1);
info.Model = info.Model.Substring(pieces[0].Length + 1);
}
}

View File

@@ -41,26 +41,28 @@ namespace DiscImageChef.Devices.Windows
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
struct ScsiPassThroughDirect
{
public ushort Length;
public byte ScsiStatus;
public byte PathId;
public byte TargetId;
public byte Lun;
public byte CdbLength;
public byte SenseInfoLength;
public ushort Length;
public byte ScsiStatus;
public byte PathId;
public byte TargetId;
public byte Lun;
public byte CdbLength;
public byte SenseInfoLength;
[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;
public uint DataTransferLength;
public uint TimeOutValue;
public IntPtr DataBuffer;
public uint SenseInfoOffset;
[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)]
@@ -122,8 +124,9 @@ namespace DiscImageChef.Devices.Windows
struct AtaPassThroughDirectWithBuffer
{
public AtaPassThroughDirect aptd;
public uint filler;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64 * 512)] public byte[] dataBuffer;
public uint filler;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64 * 512)]
public byte[] dataBuffer;
}
[StructLayout(LayoutKind.Explicit)]
@@ -151,8 +154,9 @@ namespace DiscImageChef.Devices.Windows
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 StorageQueryType QueryType;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
public byte[] AdditionalParameters;
}
[StructLayout(LayoutKind.Sequential)]
@@ -166,19 +170,19 @@ namespace DiscImageChef.Devices.Windows
[StructLayout(LayoutKind.Sequential)]
struct StorageDeviceDescriptor
{
public uint Version;
public uint Size;
public byte DeviceType;
public byte DeviceTypeModifier;
[MarshalAs(UnmanagedType.U1)] public bool RemovableMedia;
[MarshalAs(UnmanagedType.U1)] public bool CommandQueueing;
public int VendorIdOffset;
public int ProductIdOffset;
public int ProductRevisionOffset;
public int SerialNumberOffset;
public StorageBusType BusType;
public uint RawPropertiesLength;
public byte[] RawDeviceProperties;
public uint Version;
public uint Size;
public byte DeviceType;
public byte DeviceTypeModifier;
[MarshalAs(UnmanagedType.U1)] public bool RemovableMedia;
[MarshalAs(UnmanagedType.U1)] public bool CommandQueueing;
public int VendorIdOffset;
public int ProductIdOffset;
public int ProductRevisionOffset;
public int SerialNumberOffset;
public StorageBusType BusType;
public uint RawPropertiesLength;
public byte[] RawDeviceProperties;
}
[StructLayout(LayoutKind.Sequential)]
@@ -195,7 +199,8 @@ 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)]
@@ -211,9 +216,9 @@ namespace DiscImageChef.Devices.Windows
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
struct DeviceInfoData
{
public int cbSize;
public Guid classGuid;
public uint devInst;
public int cbSize;
public Guid classGuid;
public uint devInst;
public IntPtr reserved;
}
@@ -221,18 +226,18 @@ namespace DiscImageChef.Devices.Windows
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
struct DeviceInterfaceData
{
public int cbSize;
public int cbSize;
public Guid interfaceClassGuid;
public uint flags;
IntPtr reserved;
IntPtr reserved;
}
[StructLayout(LayoutKind.Sequential)]
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
struct UsbSetupPacket
{
public byte bmRequest;
public byte bRequest;
public byte bmRequest;
public byte bRequest;
public short wValue;
public short wIndex;
public short wLength;
@@ -242,7 +247,7 @@ namespace DiscImageChef.Devices.Windows
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
struct UsbDescriptorRequest
{
public int ConnectionIndex;
public int ConnectionIndex;
public UsbSetupPacket SetupPacket;
//public byte[] Data;
}
@@ -253,28 +258,28 @@ namespace DiscImageChef.Devices.Windows
{
public ushort size;
public ushort reserved;
public Guid protocolGuid;
public Guid protocolGuid;
}
[StructLayout(LayoutKind.Sequential)]
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
struct SffdiskDeviceCommandData
{
public ushort size;
public ushort reserved;
public ushort size;
public ushort reserved;
public SffdiskDcmd command;
public ushort protocolArgumentSize;
public uint deviceDataBufferSize;
public uint information;
public ushort protocolArgumentSize;
public uint deviceDataBufferSize;
public uint information;
}
[StructLayout(LayoutKind.Sequential)]
struct SdCmdDescriptor
{
public byte commandCode;
public SdCommandClass cmdClass;
public byte commandCode;
public SdCommandClass cmdClass;
public SdTransferDirection transferDirection;
public SdTransferType transferType;
public SdResponseType responseType;
public SdTransferType transferType;
public SdResponseType responseType;
}
}

View File

@@ -53,7 +53,7 @@ namespace DiscImageChef.Devices.Windows
static IEnumerable<UsbController> GetHostControllers()
{
List<UsbController> hostList = new List<UsbController>();
Guid hostGuid = new Guid(GUID_DEVINTERFACE_HUBCONTROLLER);
Guid hostGuid = new Guid(GUID_DEVINTERFACE_HUBCONTROLLER);
// We start at the "root" of the device tree and look for all
// devices that match the interface GUID of a Hub Controller
@@ -61,8 +61,8 @@ namespace DiscImageChef.Devices.Windows
if(h == INVALID_HANDLE_VALUE) return new ReadOnlyCollection<UsbController>(hostList);
IntPtr ptrBuf = Marshal.AllocHGlobal(BUFFER_SIZE);
bool success;
int i = 0;
bool success;
int i = 0;
do
{
UsbController host = new UsbController {ControllerIndex = i};
@@ -85,25 +85,27 @@ namespace DiscImageChef.Devices.Windows
// trust me :)
// now we can get some more detailed information
int nRequiredSize = 0;
const int N_BYTES = BUFFER_SIZE;
int nRequiredSize = 0;
const int N_BYTES = BUFFER_SIZE;
if(SetupDiGetDeviceInterfaceDetail(h, ref dia, ref didd, N_BYTES, ref nRequiredSize, ref da))
{
host.ControllerDevicePath = didd.DevicePath;
// get the Device Description and DriverKeyName
int requiredSize = 0;
int regType = REG_SZ;
int regType = REG_SZ;
if(SetupDiGetDeviceRegistryProperty(h, ref da, SPDRP_DEVICEDESC, ref regType, ptrBuf,
if(SetupDiGetDeviceRegistryProperty(h, ref da, SPDRP_DEVICEDESC, ref regType, ptrBuf,
BUFFER_SIZE, ref requiredSize))
host.ControllerDeviceDesc = Marshal.PtrToStringAuto(ptrBuf);
if(SetupDiGetDeviceRegistryProperty(h, ref da, SPDRP_DRIVER, ref regType, ptrBuf, BUFFER_SIZE,
ref requiredSize))
host.ControllerDriverKeyName = Marshal.PtrToStringAuto(ptrBuf);
}
hostList.Add(host);
}
i++;
}
while(success);
@@ -122,7 +124,7 @@ namespace DiscImageChef.Devices.Windows
/// <returns>USB device description</returns>
static string GetDescriptionByKeyName(string driverKeyName)
{
string ans = "";
string ans = "";
const string DEV_ENUM = REGSTR_KEY_USB;
// Use the "enumerator form" of the SetupDiGetClassDevs API
@@ -133,7 +135,7 @@ namespace DiscImageChef.Devices.Windows
IntPtr ptrBuf = Marshal.AllocHGlobal(BUFFER_SIZE);
bool success;
int i = 0;
int i = 0;
do
{
// create a Device Interface Data structure
@@ -144,9 +146,9 @@ namespace DiscImageChef.Devices.Windows
success = SetupDiEnumDeviceInfo(h, i, ref da);
if(success)
{
int requiredSize = 0;
int regType = REG_SZ;
string keyName = "";
int requiredSize = 0;
int regType = REG_SZ;
string keyName = "";
if(SetupDiGetDeviceRegistryProperty(h, ref da, SPDRP_DRIVER, ref regType, ptrBuf, BUFFER_SIZE,
ref requiredSize)) keyName = Marshal.PtrToStringAuto(ptrBuf);
@@ -154,7 +156,7 @@ namespace DiscImageChef.Devices.Windows
// is it a match?
if(keyName == driverKeyName)
{
if(SetupDiGetDeviceRegistryProperty(h, ref da, SPDRP_DEVICEDESC, ref regType, ptrBuf,
if(SetupDiGetDeviceRegistryProperty(h, ref da, SPDRP_DEVICEDESC, ref regType, ptrBuf,
BUFFER_SIZE, ref requiredSize))
ans = Marshal.PtrToStringAuto(ptrBuf);
break;
@@ -178,7 +180,7 @@ namespace DiscImageChef.Devices.Windows
/// <returns>Device instance ID</returns>
static string GetInstanceIdByKeyName(string driverKeyName)
{
string ans = "";
string ans = "";
const string DEV_ENUM = REGSTR_KEY_USB;
// Use the "enumerator form" of the SetupDiGetClassDevs API
@@ -189,7 +191,7 @@ namespace DiscImageChef.Devices.Windows
IntPtr ptrBuf = Marshal.AllocHGlobal(BUFFER_SIZE);
bool success;
int i = 0;
int i = 0;
do
{
// create a Device Interface Data structure
@@ -201,7 +203,7 @@ namespace DiscImageChef.Devices.Windows
if(success)
{
int requiredSize = 0;
int regType = REG_SZ;
int regType = REG_SZ;
string keyName = "";
if(SetupDiGetDeviceRegistryProperty(h, ref da, SPDRP_DRIVER, ref regType, ptrBuf, BUFFER_SIZE,
@@ -210,8 +212,8 @@ namespace DiscImageChef.Devices.Windows
// is it a match?
if(keyName == driverKeyName)
{
const int N_BYTES = BUFFER_SIZE;
StringBuilder sb = new StringBuilder(N_BYTES);
const int N_BYTES = BUFFER_SIZE;
StringBuilder sb = new StringBuilder(N_BYTES);
SetupDiGetDeviceInstanceId(h, ref da, sb, N_BYTES, out requiredSize);
ans = sb.ToString();
break;
@@ -234,16 +236,16 @@ namespace DiscImageChef.Devices.Windows
class UsbController
{
internal string ControllerDriverKeyName, ControllerDevicePath, ControllerDeviceDesc;
internal int ControllerIndex;
internal int ControllerIndex;
/// <summary>
/// A simple default constructor
/// </summary>
internal UsbController()
{
ControllerIndex = 0;
ControllerDevicePath = "";
ControllerDeviceDesc = "";
ControllerIndex = 0;
ControllerDevicePath = "";
ControllerDeviceDesc = "";
ControllerDriverKeyName = "";
}
@@ -273,15 +275,15 @@ namespace DiscImageChef.Devices.Windows
IntPtr.Zero);
if(h == INVALID_HANDLE_VALUE) return root;
UsbRootHubName hubName = new UsbRootHubName();
int nBytes = Marshal.SizeOf(hubName);
IntPtr ptrHubName = Marshal.AllocHGlobal(nBytes);
UsbRootHubName hubName = new UsbRootHubName();
int nBytes = Marshal.SizeOf(hubName);
IntPtr ptrHubName = Marshal.AllocHGlobal(nBytes);
// get the Hub Name
if(DeviceIoControl(h, IOCTL_USB_GET_ROOT_HUB_NAME, ptrHubName, nBytes, ptrHubName, nBytes, out _,
IntPtr.Zero))
{
hubName = (UsbRootHubName)Marshal.PtrToStructure(ptrHubName, typeof(UsbRootHubName));
hubName = (UsbRootHubName)Marshal.PtrToStructure(ptrHubName, typeof(UsbRootHubName));
root.HubDevicePath = @"\\.\" + hubName.RootHubName;
}
@@ -298,13 +300,15 @@ namespace DiscImageChef.Devices.Windows
Marshal.StructureToPtr(nodeInfo, ptrNodeInfo, true);
// get the Hub Information
if(DeviceIoControl(h2, IOCTL_USB_GET_NODE_INFORMATION, ptrNodeInfo, nBytes, ptrNodeInfo, nBytes,
if(DeviceIoControl(h2, IOCTL_USB_GET_NODE_INFORMATION, ptrNodeInfo, nBytes, ptrNodeInfo, nBytes,
out _, IntPtr.Zero))
{
nodeInfo = (UsbNodeInformation)Marshal.PtrToStructure(ptrNodeInfo, typeof(UsbNodeInformation));
nodeInfo =
(UsbNodeInformation)Marshal.PtrToStructure(ptrNodeInfo, typeof(UsbNodeInformation));
root.HubIsBusPowered = Convert.ToBoolean(nodeInfo.HubInformation.HubIsBusPowered);
root.HubPortCount = nodeInfo.HubInformation.HubDescriptor.bNumberOfPorts;
root.HubPortCount = nodeInfo.HubInformation.HubDescriptor.bNumberOfPorts;
}
Marshal.FreeHGlobal(ptrNodeInfo);
CloseHandle(h2);
}
@@ -318,24 +322,24 @@ namespace DiscImageChef.Devices.Windows
/// <summary>The Hub class</summary>
internal class UsbHub
{
internal string HubDriverKey, HubDevicePath, HubDeviceDesc;
internal bool HubIsBusPowered, HubIsRootHub;
internal string HubDriverKey, HubDevicePath, HubDeviceDesc;
internal bool HubIsBusPowered, HubIsRootHub;
internal string HubManufacturer, HubProduct, HubSerialNumber, HubInstanceId;
internal int HubPortCount;
internal int HubPortCount;
/// <summary>a simple default constructor</summary>
internal UsbHub()
{
HubPortCount = 0;
HubDevicePath = "";
HubDeviceDesc = "";
HubDriverKey = "";
HubPortCount = 0;
HubDevicePath = "";
HubDeviceDesc = "";
HubDriverKey = "";
HubIsBusPowered = false;
HubIsRootHub = false;
HubIsRootHub = false;
HubManufacturer = "";
HubProduct = "";
HubProduct = "";
HubSerialNumber = "";
HubInstanceId = "";
HubInstanceId = "";
}
/// <summary>return Port Count</summary>
@@ -381,7 +385,7 @@ namespace DiscImageChef.Devices.Windows
IntPtr.Zero);
if(h == INVALID_HANDLE_VALUE) return new ReadOnlyCollection<UsbPort>(portList);
int nBytes = Marshal.SizeOf(typeof(UsbNodeConnectionInformationEx));
int nBytes = Marshal.SizeOf(typeof(UsbNodeConnectionInformationEx));
IntPtr ptrNodeConnection = Marshal.AllocHGlobal(nBytes);
// loop thru all of the ports on the hub
@@ -392,8 +396,10 @@ namespace DiscImageChef.Devices.Windows
new UsbNodeConnectionInformationEx {ConnectionIndex = i};
Marshal.StructureToPtr(nodeConnection, ptrNodeConnection, true);
if(!DeviceIoControl(h, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX, ptrNodeConnection, nBytes,
ptrNodeConnection, nBytes, out _, IntPtr.Zero)) continue;
if(!DeviceIoControl(h, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX,
ptrNodeConnection, nBytes,
ptrNodeConnection, nBytes, out _,
IntPtr.Zero)) continue;
nodeConnection =
(UsbNodeConnectionInformationEx)Marshal.PtrToStructure(ptrNodeConnection,
@@ -402,13 +408,13 @@ namespace DiscImageChef.Devices.Windows
// load up the USBPort class
UsbPort port = new UsbPort
{
PortPortNumber = i,
PortPortNumber = i,
PortHubDevicePath = HubDevicePath,
PortStatus = ((UsbConnectionStatus)nodeConnection.ConnectionStatus).ToString(),
PortSpeed = ((UsbDeviceSpeed)nodeConnection.Speed).ToString(),
PortStatus = ((UsbConnectionStatus)nodeConnection.ConnectionStatus).ToString(),
PortSpeed = ((UsbDeviceSpeed)nodeConnection.Speed).ToString(),
PortIsDeviceConnected =
nodeConnection.ConnectionStatus == (int)UsbConnectionStatus.DeviceConnected,
PortIsHub = Convert.ToBoolean(nodeConnection.DeviceIsHub),
PortIsHub = Convert.ToBoolean(nodeConnection.DeviceIsHub),
PortDeviceDescriptor = nodeConnection.DeviceDescriptor
};
@@ -429,18 +435,18 @@ namespace DiscImageChef.Devices.Windows
internal class UsbPort
{
internal UsbDeviceDescriptor PortDeviceDescriptor;
internal bool PortIsHub, PortIsDeviceConnected;
internal int PortPortNumber;
internal string PortStatus, PortHubDevicePath, PortSpeed;
internal bool PortIsHub, PortIsDeviceConnected;
internal int PortPortNumber;
internal string PortStatus, PortHubDevicePath, PortSpeed;
/// <summary>a simple default constructor</summary>
internal UsbPort()
{
PortPortNumber = 0;
PortStatus = "";
PortHubDevicePath = "";
PortSpeed = "";
PortIsHub = false;
PortPortNumber = 0;
PortStatus = "";
PortHubDevicePath = "";
PortSpeed = "";
PortIsHub = false;
PortIsDeviceConnected = false;
}
@@ -474,9 +480,9 @@ namespace DiscImageChef.Devices.Windows
// Ya know, I've given some thought about making Device a derived class...
UsbDevice device = new UsbDevice
{
DevicePortNumber = PortPortNumber,
DevicePortNumber = PortPortNumber,
DeviceHubDevicePath = PortHubDevicePath,
DeviceDescriptor = PortDeviceDescriptor
DeviceDescriptor = PortDeviceDescriptor
};
// Open a handle to the Hub device
@@ -512,7 +518,8 @@ namespace DiscImageChef.Devices.Windows
Marshal.StructureToPtr(request, ptrRequest, true);
// Use an IOCTL call to request the String Descriptor
if(DeviceIoControl(h, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, ptrRequest, nBytes, ptrRequest,
if(DeviceIoControl(h, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, ptrRequest, nBytes,
ptrRequest,
nBytes, out nBytesReturned, IntPtr.Zero))
{
// The location of the string descriptor is immediately after
@@ -524,8 +531,10 @@ namespace DiscImageChef.Devices.Windows
(UsbStringDescriptor)Marshal.PtrToStructure(ptrStringDesc, typeof(UsbStringDescriptor));
device.DeviceManufacturer = stringDesc.bString;
}
Marshal.FreeHGlobal(ptrRequest);
}
if(PortDeviceDescriptor.iProduct > 0)
{
// build a request for string descriptor
@@ -545,7 +554,8 @@ namespace DiscImageChef.Devices.Windows
Marshal.StructureToPtr(request, ptrRequest, true);
// Use an IOCTL call to request the String Descriptor
if(DeviceIoControl(h, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, ptrRequest, nBytes, ptrRequest,
if(DeviceIoControl(h, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, ptrRequest, nBytes,
ptrRequest,
nBytes, out nBytesReturned, IntPtr.Zero))
{
// the location of the string descriptor is immediately after the Request structure
@@ -554,8 +564,10 @@ namespace DiscImageChef.Devices.Windows
(UsbStringDescriptor)Marshal.PtrToStructure(ptrStringDesc, typeof(UsbStringDescriptor));
device.DeviceProduct = stringDesc.bString;
}
Marshal.FreeHGlobal(ptrRequest);
}
if(PortDeviceDescriptor.iSerialNumber > 0)
{
// build a request for string descriptor
@@ -575,7 +587,8 @@ namespace DiscImageChef.Devices.Windows
Marshal.StructureToPtr(request, ptrRequest, true);
// Use an IOCTL call to request the String Descriptor
if(DeviceIoControl(h, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, ptrRequest, nBytes, ptrRequest,
if(DeviceIoControl(h, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, ptrRequest, nBytes,
ptrRequest,
nBytes, out nBytesReturned, IntPtr.Zero))
{
// the location of the string descriptor is immediately after the Request structure
@@ -584,6 +597,7 @@ namespace DiscImageChef.Devices.Windows
(UsbStringDescriptor)Marshal.PtrToStructure(ptrStringDesc, typeof(UsbStringDescriptor));
device.DeviceSerialNumber = stringDesc.bString;
}
Marshal.FreeHGlobal(ptrRequest);
}
@@ -591,7 +605,7 @@ namespace DiscImageChef.Devices.Windows
UsbDescriptorRequest dcrRequest = new UsbDescriptorRequest
{
ConnectionIndex = PortPortNumber,
SetupPacket = {wIndex = 0, wValue = USB_CONFIGURATION_DESCRIPTOR_TYPE << 8}
SetupPacket = {wIndex = 0, wValue = USB_CONFIGURATION_DESCRIPTOR_TYPE << 8}
};
dcrRequest.SetupPacket.wLength = (short)(nBytes - Marshal.SizeOf(dcrRequest));
// Geez, I wish C# had a Marshal.MemSet() method
@@ -599,13 +613,16 @@ namespace DiscImageChef.Devices.Windows
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))
if(DeviceIoControl(h, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, dcrPtrRequest,
nBytes,
dcrPtrRequest, nBytes, out nBytesReturned,
IntPtr.Zero))
{
IntPtr ptrStringDesc = IntPtr.Add(dcrPtrRequest, Marshal.SizeOf(dcrRequest));
device.BinaryDeviceDescriptors = new byte[nBytesReturned];
Marshal.Copy(ptrStringDesc, device.BinaryDeviceDescriptors, 0, nBytesReturned);
}
Marshal.FreeHGlobal(dcrPtrRequest);
// Get the Driver Key Name (usefull in locating a device)
@@ -616,7 +633,8 @@ namespace DiscImageChef.Devices.Windows
Marshal.StructureToPtr(driverKey, ptrDriverKey, true);
// Use an IOCTL call to request the Driver Key Name
if(DeviceIoControl(h, IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME, ptrDriverKey, nBytes, ptrDriverKey,
if(DeviceIoControl(h, IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME, ptrDriverKey, nBytes,
ptrDriverKey,
nBytes, out nBytesReturned, IntPtr.Zero))
{
driverKey = (UsbNodeConnectionDriverkeyName)Marshal.PtrToStructure(ptrDriverKey,
@@ -626,9 +644,10 @@ namespace DiscImageChef.Devices.Windows
device.DeviceDriverKey = driverKey.DriverKeyName;
// use the DriverKeyName to get the Device Description and Instance ID
device.DeviceName = GetDescriptionByKeyName(device.DeviceDriverKey);
device.DeviceName = GetDescriptionByKeyName(device.DeviceDriverKey);
device.DeviceInstanceId = GetInstanceIdByKeyName(device.DeviceDriverKey);
}
Marshal.FreeHGlobal(ptrDriverKey);
CloseHandle(h);
return device;
@@ -644,21 +663,22 @@ namespace DiscImageChef.Devices.Windows
UsbHub hub = new UsbHub();
IntPtr h, h2;
hub.HubIsRootHub = false;
hub.HubIsRootHub = false;
hub.HubDeviceDesc = "External Hub";
// Open a handle to the Host Controller
h = CreateFile(PortHubDevicePath, GENERIC_WRITE, FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0,
IntPtr.Zero);
if(h == INVALID_HANDLE_VALUE) return hub;
// Get the DevicePath for downstream hub
UsbNodeConnectionName nodeName = new UsbNodeConnectionName {ConnectionIndex = PortPortNumber};
int nBytes = Marshal.SizeOf(nodeName);
IntPtr ptrNodeName = Marshal.AllocHGlobal(nBytes);
UsbNodeConnectionName nodeName = new UsbNodeConnectionName {ConnectionIndex = PortPortNumber};
int nBytes = Marshal.SizeOf(nodeName);
IntPtr ptrNodeName = Marshal.AllocHGlobal(nBytes);
Marshal.StructureToPtr(nodeName, ptrNodeName, true);
// Use an IOCTL call to request the Node Name
if(DeviceIoControl(h, IOCTL_USB_GET_NODE_CONNECTION_NAME, ptrNodeName, nBytes, ptrNodeName, nBytes,
if(DeviceIoControl(h, IOCTL_USB_GET_NODE_CONNECTION_NAME, ptrNodeName, nBytes, ptrNodeName, nBytes,
out _, IntPtr.Zero))
{
nodeName = (UsbNodeConnectionName)Marshal.PtrToStructure(ptrNodeName,
@@ -677,13 +697,15 @@ namespace DiscImageChef.Devices.Windows
Marshal.StructureToPtr(nodeInfo, ptrNodeInfo, true);
// get the Hub Information
if(DeviceIoControl(h2, IOCTL_USB_GET_NODE_INFORMATION, ptrNodeInfo, nBytes, ptrNodeInfo, nBytes,
if(DeviceIoControl(h2, IOCTL_USB_GET_NODE_INFORMATION, ptrNodeInfo, nBytes, ptrNodeInfo, nBytes,
out _, IntPtr.Zero))
{
nodeInfo = (UsbNodeInformation)Marshal.PtrToStructure(ptrNodeInfo, typeof(UsbNodeInformation));
nodeInfo =
(UsbNodeInformation)Marshal.PtrToStructure(ptrNodeInfo, typeof(UsbNodeInformation));
hub.HubIsBusPowered = Convert.ToBoolean(nodeInfo.HubInformation.HubIsBusPowered);
hub.HubPortCount = nodeInfo.HubInformation.HubDescriptor.bNumberOfPorts;
hub.HubPortCount = nodeInfo.HubInformation.HubDescriptor.bNumberOfPorts;
}
Marshal.FreeHGlobal(ptrNodeInfo);
CloseHandle(h2);
}
@@ -691,11 +713,11 @@ namespace DiscImageChef.Devices.Windows
// Fill in the missing Manufacture, Product, and SerialNumber values
// values by just creating a Device instance and copying the values
UsbDevice device = GetDevice();
hub.HubInstanceId = device.DeviceInstanceId;
hub.HubInstanceId = device.DeviceInstanceId;
hub.HubManufacturer = device.Manufacturer;
hub.HubProduct = device.Product;
hub.HubProduct = device.Product;
hub.HubSerialNumber = device.SerialNumber;
hub.HubDriverKey = device.DriverKey;
hub.HubDriverKey = device.DriverKey;
Marshal.FreeHGlobal(ptrNodeName);
CloseHandle(h);
@@ -708,23 +730,23 @@ namespace DiscImageChef.Devices.Windows
/// </summary>
internal class UsbDevice
{
internal byte[] BinaryDeviceDescriptors;
internal byte[] BinaryDeviceDescriptors;
internal UsbDeviceDescriptor DeviceDescriptor;
internal string DeviceDriverKey, DeviceHubDevicePath, DeviceInstanceId, DeviceName;
internal string DeviceManufacturer, DeviceProduct, DeviceSerialNumber;
internal int DevicePortNumber;
internal string DeviceDriverKey, DeviceHubDevicePath, DeviceInstanceId, DeviceName;
internal string DeviceManufacturer, DeviceProduct, DeviceSerialNumber;
internal int DevicePortNumber;
/// <summary>a simple default constructor</summary>
internal UsbDevice()
{
DevicePortNumber = 0;
DeviceHubDevicePath = "";
DeviceDriverKey = "";
DeviceManufacturer = "";
DeviceProduct = "Unknown USB Device";
DeviceSerialNumber = "";
DeviceName = "";
DeviceInstanceId = "";
DevicePortNumber = 0;
DeviceHubDevicePath = "";
DeviceDriverKey = "";
DeviceManufacturer = "";
DeviceProduct = "Unknown USB Device";
DeviceSerialNumber = "";
DeviceName = "";
DeviceInstanceId = "";
BinaryDeviceDescriptors = null;
}
@@ -755,35 +777,35 @@ namespace DiscImageChef.Devices.Windows
#region "API Region"
// ********************** Constants ************************
const int GENERIC_WRITE = 0x40000000;
const int FILE_SHARE_READ = 0x1;
const int FILE_SHARE_WRITE = 0x2;
const int OPEN_EXISTING = 0x3;
const int GENERIC_WRITE = 0x40000000;
const int FILE_SHARE_READ = 0x1;
const int FILE_SHARE_WRITE = 0x2;
const int OPEN_EXISTING = 0x3;
static readonly IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
const int IOCTL_GET_HCD_DRIVERKEY_NAME = 0x220424;
const int IOCTL_USB_GET_ROOT_HUB_NAME = 0x220408;
const int IOCTL_USB_GET_NODE_INFORMATION = 0x220408; // same as above... strange, eh?
const int IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX = 0x220448;
const int IOCTL_GET_HCD_DRIVERKEY_NAME = 0x220424;
const int IOCTL_USB_GET_ROOT_HUB_NAME = 0x220408;
const int IOCTL_USB_GET_NODE_INFORMATION = 0x220408; // same as above... strange, eh?
const int IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX = 0x220448;
const int IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION = 0x220410;
const int IOCTL_USB_GET_NODE_CONNECTION_NAME = 0x220414;
const int IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME = 0x220420;
const int IOCTL_USB_GET_NODE_CONNECTION_NAME = 0x220414;
const int IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME = 0x220420;
const int USB_DEVICE_DESCRIPTOR_TYPE = 0x1;
const int USB_DEVICE_DESCRIPTOR_TYPE = 0x1;
const int USB_CONFIGURATION_DESCRIPTOR_TYPE = 0x2;
const int USB_STRING_DESCRIPTOR_TYPE = 0x3;
const int USB_STRING_DESCRIPTOR_TYPE = 0x3;
const int BUFFER_SIZE = 2048;
const int BUFFER_SIZE = 2048;
const int MAXIMUM_USB_STRING_LENGTH = 255;
const string GUID_DEVINTERFACE_HUBCONTROLLER = "3abf6f2d-71c4-462a-8a92-1e6861e6af27";
const string REGSTR_KEY_USB = "USB";
const int DIGCF_PRESENT = 0x2;
const int DIGCF_ALLCLASSES = 0x4;
const int DIGCF_DEVICEINTERFACE = 0x10;
const int SPDRP_DRIVER = 0x9;
const int SPDRP_DEVICEDESC = 0x0;
const int REG_SZ = 1;
const string REGSTR_KEY_USB = "USB";
const int DIGCF_PRESENT = 0x2;
const int DIGCF_ALLCLASSES = 0x4;
const int DIGCF_DEVICEINTERFACE = 0x10;
const int SPDRP_DRIVER = 0x9;
const int SPDRP_DEVICEDESC = 0x0;
const int REG_SZ = 1;
// ********************** Enumerations ************************
@@ -818,8 +840,8 @@ namespace DiscImageChef.Devices.Windows
[StructLayout(LayoutKind.Sequential)]
struct SpDevinfoData
{
internal int cbSize;
internal Guid ClassGuid;
internal int cbSize;
internal Guid ClassGuid;
internal IntPtr DevInst;
internal IntPtr Reserved;
}
@@ -827,9 +849,9 @@ namespace DiscImageChef.Devices.Windows
[StructLayout(LayoutKind.Sequential)]
struct SpDeviceInterfaceData
{
internal int cbSize;
internal Guid InterfaceClassGuid;
internal int Flags;
internal int cbSize;
internal Guid InterfaceClassGuid;
internal int Flags;
internal IntPtr Reserved;
}
@@ -837,59 +859,63 @@ namespace DiscImageChef.Devices.Windows
struct SpDeviceInterfaceDetailData
{
internal int cbSize;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = BUFFER_SIZE)] internal string DevicePath;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = BUFFER_SIZE)]
internal string DevicePath;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
struct UsbHcdDriverkeyName
{
internal int ActualLength;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = BUFFER_SIZE)] internal string DriverKeyName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = BUFFER_SIZE)]
internal string DriverKeyName;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
struct UsbRootHubName
{
internal int ActualLength;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = BUFFER_SIZE)] internal string RootHubName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = BUFFER_SIZE)]
internal string RootHubName;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct UsbHubDescriptor
{
internal byte bDescriptorLength;
internal byte bDescriptorType;
internal byte bNumberOfPorts;
internal byte bDescriptorLength;
internal byte bDescriptorType;
internal byte bNumberOfPorts;
internal short wHubCharacteristics;
internal byte bPowerOnToPowerGood;
internal byte bHubControlCurrent;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] internal byte[] bRemoveAndPowerMask;
internal byte bPowerOnToPowerGood;
internal byte bHubControlCurrent;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
internal byte[] bRemoveAndPowerMask;
}
[StructLayout(LayoutKind.Sequential)]
struct UsbHubInformation
{
internal UsbHubDescriptor HubDescriptor;
internal byte HubIsBusPowered;
internal byte HubIsBusPowered;
}
[StructLayout(LayoutKind.Sequential)]
struct UsbNodeInformation
{
internal int NodeType;
internal int NodeType;
internal UsbHubInformation HubInformation; // Yeah, I'm assuming we'll just use the first form
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct UsbNodeConnectionInformationEx
{
internal int ConnectionIndex;
internal int ConnectionIndex;
internal UsbDeviceDescriptor DeviceDescriptor;
internal byte CurrentConfigurationValue;
internal byte Speed;
internal byte DeviceIsHub;
internal short DeviceAddress;
internal int NumberOfOpenPipes;
internal byte CurrentConfigurationValue;
internal byte Speed;
internal byte DeviceIsHub;
internal short DeviceAddress;
internal int NumberOfOpenPipes;
internal int ConnectionStatus;
//internal IntPtr PipeList;
@@ -899,20 +925,20 @@ namespace DiscImageChef.Devices.Windows
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
internal struct UsbDeviceDescriptor
{
internal byte bLength;
internal byte bDescriptorType;
internal byte bLength;
internal byte bDescriptorType;
internal short bcdUSB;
internal byte bDeviceClass;
internal byte bDeviceSubClass;
internal byte bDeviceProtocol;
internal byte bMaxPacketSize0;
internal byte bDeviceClass;
internal byte bDeviceSubClass;
internal byte bDeviceProtocol;
internal byte bMaxPacketSize0;
internal short idVendor;
internal short idProduct;
internal short bcdDevice;
internal byte iManufacturer;
internal byte iProduct;
internal byte iSerialNumber;
internal byte bNumConfigurations;
internal byte iManufacturer;
internal byte iProduct;
internal byte iSerialNumber;
internal byte bNumConfigurations;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
@@ -920,14 +946,15 @@ namespace DiscImageChef.Devices.Windows
{
internal byte bLength;
internal byte bDescriptorType;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAXIMUM_USB_STRING_LENGTH)] internal string bString;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAXIMUM_USB_STRING_LENGTH)]
internal string bString;
}
[StructLayout(LayoutKind.Sequential)]
struct UsbSetupPacket
{
internal byte bmRequest;
internal byte bRequest;
internal byte bmRequest;
internal byte bRequest;
internal short wValue;
internal short wIndex;
internal short wLength;
@@ -947,7 +974,8 @@ namespace DiscImageChef.Devices.Windows
{
internal int ConnectionIndex;
internal int ActualLength;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = BUFFER_SIZE)] internal string NodeName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = BUFFER_SIZE)]
internal string NodeName;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
@@ -955,7 +983,8 @@ namespace DiscImageChef.Devices.Windows
{
internal int ConnectionIndex;
internal int ActualLength;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = BUFFER_SIZE)] internal string DriverKeyName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = BUFFER_SIZE)]
internal string DriverKeyName;
}
// ********************** API Definitions ************************
@@ -968,44 +997,50 @@ namespace DiscImageChef.Devices.Windows
static extern IntPtr SetupDiGetClassDevs(int classGuid, string enumerator, IntPtr hwndParent, int flags);
[DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern bool SetupDiEnumDeviceInterfaces(IntPtr deviceInfoSet, IntPtr deviceInfoData,
ref Guid interfaceClassGuid, int memberIndex,
static extern bool SetupDiEnumDeviceInterfaces(IntPtr deviceInfoSet,
IntPtr deviceInfoData,
ref Guid interfaceClassGuid, int memberIndex,
ref SpDeviceInterfaceData deviceInterfaceData);
[DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern bool SetupDiGetDeviceInterfaceDetail(IntPtr deviceInfoSet,
ref SpDeviceInterfaceData deviceInterfaceData,
static extern bool SetupDiGetDeviceInterfaceDetail(IntPtr deviceInfoSet,
ref SpDeviceInterfaceData deviceInterfaceData,
ref SpDeviceInterfaceDetailData deviceInterfaceDetailData,
int deviceInterfaceDetailDataSize, ref int requiredSize,
int
deviceInterfaceDetailDataSize, ref int requiredSize,
ref SpDevinfoData deviceInfoData);
[DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern bool SetupDiGetDeviceRegistryProperty(IntPtr deviceInfoSet, ref SpDevinfoData deviceInfoData,
int iProperty, ref int propertyRegDataType,
IntPtr propertyBuffer, int propertyBufferSize,
static extern bool SetupDiGetDeviceRegistryProperty(IntPtr deviceInfoSet, ref SpDevinfoData deviceInfoData,
int iProperty,
ref int propertyRegDataType,
IntPtr propertyBuffer,
int propertyBufferSize,
ref int requiredSize);
[DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern bool SetupDiEnumDeviceInfo(IntPtr deviceInfoSet, int memberIndex,
static extern bool SetupDiEnumDeviceInfo(IntPtr deviceInfoSet, int memberIndex,
ref SpDevinfoData deviceInfoData);
[DllImport("setupapi.dll", SetLastError = true)]
static extern bool SetupDiDestroyDeviceInfoList(IntPtr deviceInfoSet);
[DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern bool SetupDiGetDeviceInstanceId(IntPtr deviceInfoSet, ref SpDevinfoData deviceInfoData,
StringBuilder deviceInstanceId, int deviceInstanceIdSize,
out int requiredSize);
static extern bool SetupDiGetDeviceInstanceId(IntPtr deviceInfoSet, ref SpDevinfoData deviceInfoData,
StringBuilder deviceInstanceId,
int deviceInstanceIdSize,
out int requiredSize);
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern bool DeviceIoControl(IntPtr hDevice, int dwIoControlCode, IntPtr lpInBuffer, int nInBufferSize,
static extern bool DeviceIoControl(IntPtr hDevice, int dwIoControlCode, IntPtr lpInBuffer,
int nInBufferSize,
IntPtr lpOutBuffer, int nOutBufferSize, out int lpBytesReturned,
IntPtr lpOverlapped);
[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);
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern bool CloseHandle(IntPtr hObject);

View File

@@ -47,10 +47,10 @@ namespace DiscImageChef.Devices.Windows
/// </summary>
static partial class Usb
{
const int IOCTL_STORAGE_GET_DEVICE_NUMBER = 0x2D1080;
internal const string GuidDevinterfaceDisk = "53f56307-b6bf-11d0-94f2-00a0c91efb8b";
internal const string GuidDevinterfaceCdrom = "53f56308-b6bf-11d0-94f2-00a0c91efb8b";
internal const string GuidDevinterfaceFloppy = "53f56311-b6bf-11d0-94f2-00a0c91efb8b";
const int IOCTL_STORAGE_GET_DEVICE_NUMBER = 0x2D1080;
internal const string GuidDevinterfaceDisk = "53f56307-b6bf-11d0-94f2-00a0c91efb8b";
internal const string GuidDevinterfaceCdrom = "53f56308-b6bf-11d0-94f2-00a0c91efb8b";
internal const string GuidDevinterfaceFloppy = "53f56311-b6bf-11d0-94f2-00a0c91efb8b";
/// <summary>
/// Get a list of all connected devices
@@ -73,8 +73,12 @@ namespace DiscImageChef.Devices.Windows
static void ListHub(UsbHub hub, ICollection<UsbDevice> devList)
{
foreach(UsbPort port in hub.GetPorts())
if(port.IsHub) ListHub(port.GetHub(), devList);
else { if(port.IsDeviceConnected) devList.Add(port.GetDevice()); }
if(port.IsHub)
ListHub(port.GetHub(), devList);
else
{
if(port.IsDeviceConnected) devList.Add(port.GetDevice());
}
}
/// <summary>
@@ -104,7 +108,8 @@ namespace DiscImageChef.Devices.Windows
static void SearchHubDriverKeyName(UsbHub hub, ref UsbDevice foundDevice, string driverKeyName)
{
foreach(UsbPort port in hub.GetPorts())
if(port.IsHub) SearchHubDriverKeyName(port.GetHub(), ref foundDevice, driverKeyName);
if(port.IsHub)
SearchHubDriverKeyName(port.GetHub(), ref foundDevice, driverKeyName);
else
{
if(!port.IsDeviceConnected) continue;
@@ -144,7 +149,8 @@ namespace DiscImageChef.Devices.Windows
static void SearchHubInstanceId(UsbHub hub, ref UsbDevice foundDevice, string instanceId)
{
foreach(UsbPort port in hub.GetPorts())
if(port.IsHub) SearchHubInstanceId(port.GetHub(), ref foundDevice, instanceId);
if(port.IsHub)
SearchHubInstanceId(port.GetHub(), ref foundDevice, instanceId);
else
{
if(!port.IsDeviceConnected) continue;
@@ -202,7 +208,7 @@ namespace DiscImageChef.Devices.Windows
static UsbDevice FindDeviceNumber(int devNum, string deviceGuid)
{
UsbDevice foundDevice = null;
string instanceId = "";
string instanceId = "";
Guid diskGuid = new Guid(deviceGuid);
@@ -212,7 +218,7 @@ namespace DiscImageChef.Devices.Windows
if(h != INVALID_HANDLE_VALUE)
{
bool success;
int i = 0;
int i = 0;
do
{
// create a Device Interface Data structure
@@ -232,8 +238,8 @@ namespace DiscImageChef.Devices.Windows
new SpDeviceInterfaceDetailData {cbSize = 4 + Marshal.SystemDefaultCharSize}; // trust me :)
// now we can get some more detailed information
int nRequiredSize = 0;
const int N_BYTES = BUFFER_SIZE;
int nRequiredSize = 0;
const int N_BYTES = BUFFER_SIZE;
if(SetupDiGetDeviceInterfaceDetail(h, ref dia, ref didd, N_BYTES, ref nRequiredSize, ref da))
if(GetDeviceNumber(didd.DevicePath) == devNum)
{
@@ -251,6 +257,7 @@ namespace DiscImageChef.Devices.Windows
//break;
}
}
i++;
}
while(success);
@@ -276,9 +283,9 @@ namespace DiscImageChef.Devices.Windows
IntPtr h = CreateFile(devicePath.TrimEnd('\\'), 0, 0, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
if(h == INVALID_HANDLE_VALUE) return ans;
StorageDeviceNumber sdn = new StorageDeviceNumber();
int nBytes = Marshal.SizeOf(sdn);
IntPtr ptrSdn = Marshal.AllocHGlobal(nBytes);
StorageDeviceNumber sdn = new StorageDeviceNumber();
int nBytes = Marshal.SizeOf(sdn);
IntPtr ptrSdn = Marshal.AllocHGlobal(nBytes);
if(DeviceIoControl(h, IOCTL_STORAGE_GET_DEVICE_NUMBER, IntPtr.Zero, 0, ptrSdn, nBytes, out _, IntPtr.Zero))
{
@@ -287,6 +294,7 @@ namespace DiscImageChef.Devices.Windows
// STORAGE_DEVICE_NUMBER into a single number
ans = (sdn.DeviceType << 8) + sdn.DeviceNumber;
}
Marshal.FreeHGlobal(ptrSdn);
CloseHandle(h);
return ans;