Remove DiscImageChef.CommonTypes dependence on DiscImageChef.Decoders.

This commit is contained in:
2020-01-11 20:55:54 +00:00
parent 53f92aa111
commit 6b1033317a
40 changed files with 1640 additions and 776 deletions

View File

@@ -184,6 +184,18 @@
<e p="Partition.cs" t="Include" /> <e p="Partition.cs" t="Include" />
<e p="PluginBase.cs" t="Include" /> <e p="PluginBase.cs" t="Include" />
<e p="Structs" t="Include"> <e p="Structs" t="Include">
<e p="Devices" t="Include">
<e p="ATA" t="Include">
<e p="Identify.cs" t="Include" />
</e>
<e p="SCSI" t="Include">
<e p="Enums.cs" t="Include" />
<e p="Inquiry.cs" t="Include" />
<e p="Modes" t="Include">
<e p="2A.cs" t="Include" />
</e>
</e>
</e>
<e p="Filesystems.cs" t="Include" /> <e p="Filesystems.cs" t="Include" />
<e p="Images.cs" t="Include" /> <e p="Images.cs" t="Include" />
<e p="TapeFile.cs" t="Include" /> <e p="TapeFile.cs" t="Include" />
@@ -515,7 +527,6 @@
<e p="SCSI" t="Include"> <e p="SCSI" t="Include">
<e p="DiscStructureCapabilities.cs" t="Include" /> <e p="DiscStructureCapabilities.cs" t="Include" />
<e p="EVPD.cs" t="Include" /> <e p="EVPD.cs" t="Include" />
<e p="Enums.cs" t="Include" />
<e p="Inquiry.cs" t="Include" /> <e p="Inquiry.cs" t="Include" />
<e p="MMC" t="Include"> <e p="MMC" t="Include">
<e p="AACS.cs" t="Include" /> <e p="AACS.cs" t="Include" />

View File

@@ -39,8 +39,8 @@ using DiscImageChef.CommonTypes;
using DiscImageChef.CommonTypes.Enums; using DiscImageChef.CommonTypes.Enums;
using DiscImageChef.CommonTypes.Extents; using DiscImageChef.CommonTypes.Extents;
using DiscImageChef.CommonTypes.Interfaces; using DiscImageChef.CommonTypes.Interfaces;
using DiscImageChef.CommonTypes.Structs.Devices.ATA;
using DiscImageChef.Core.Logging; using DiscImageChef.Core.Logging;
using DiscImageChef.Decoders.ATA;
using DiscImageChef.Decoders.PCMCIA; using DiscImageChef.Decoders.PCMCIA;
using Schemas; using Schemas;
using Tuple = DiscImageChef.Decoders.PCMCIA.Tuple; using Tuple = DiscImageChef.Decoders.PCMCIA.Tuple;

View File

@@ -34,6 +34,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using DiscImageChef.CommonTypes.Enums; using DiscImageChef.CommonTypes.Enums;
using DiscImageChef.CommonTypes.Extents; using DiscImageChef.CommonTypes.Extents;
using DiscImageChef.CommonTypes.Structs.Devices.SCSI;
using DiscImageChef.Console; using DiscImageChef.Console;
using DiscImageChef.Decoders.SCSI; using DiscImageChef.Decoders.SCSI;
using DiscImageChef.Devices; using DiscImageChef.Devices;

View File

@@ -34,9 +34,9 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using DiscImageChef.CommonTypes; using DiscImageChef.CommonTypes;
using DiscImageChef.CommonTypes.Enums; using DiscImageChef.CommonTypes.Enums;
using DiscImageChef.CommonTypes.Structs.Devices.SCSI;
using DiscImageChef.Decoders.Bluray; using DiscImageChef.Decoders.Bluray;
using DiscImageChef.Decoders.DVD; using DiscImageChef.Decoders.DVD;
using DiscImageChef.Decoders.SCSI;
using DiscImageChef.Decoders.SCSI.MMC; using DiscImageChef.Decoders.SCSI.MMC;
using DiscImageChef.Devices; using DiscImageChef.Devices;
using Schemas; using Schemas;

View File

@@ -10,6 +10,7 @@ using DiscImageChef.CommonTypes.Extents;
using DiscImageChef.CommonTypes.Interfaces; using DiscImageChef.CommonTypes.Interfaces;
using DiscImageChef.CommonTypes.Metadata; using DiscImageChef.CommonTypes.Metadata;
using DiscImageChef.CommonTypes.Structs; using DiscImageChef.CommonTypes.Structs;
using DiscImageChef.CommonTypes.Structs.Devices.SCSI;
using DiscImageChef.Console; using DiscImageChef.Console;
using DiscImageChef.Core.Logging; using DiscImageChef.Core.Logging;
using DiscImageChef.Decoders.SCSI; using DiscImageChef.Decoders.SCSI;

View File

@@ -41,6 +41,7 @@ using DiscImageChef.CommonTypes.Extents;
using DiscImageChef.CommonTypes.Interfaces; using DiscImageChef.CommonTypes.Interfaces;
using DiscImageChef.CommonTypes.Metadata; using DiscImageChef.CommonTypes.Metadata;
using DiscImageChef.CommonTypes.Structs; using DiscImageChef.CommonTypes.Structs;
using DiscImageChef.CommonTypes.Structs.Devices.SCSI;
using DiscImageChef.Console; using DiscImageChef.Console;
using DiscImageChef.Core.Logging; using DiscImageChef.Core.Logging;
using DiscImageChef.Decoders.SCSI; using DiscImageChef.Decoders.SCSI;

View File

@@ -33,6 +33,7 @@
using System.Threading; using System.Threading;
using DiscImageChef.CommonTypes; using DiscImageChef.CommonTypes;
using DiscImageChef.CommonTypes.Interfaces; using DiscImageChef.CommonTypes.Interfaces;
using DiscImageChef.CommonTypes.Structs.Devices.SCSI;
using DiscImageChef.Decoders.SCSI; using DiscImageChef.Decoders.SCSI;
namespace DiscImageChef.Core.Devices.Dumping namespace DiscImageChef.Core.Devices.Dumping

View File

@@ -39,6 +39,7 @@ using DiscImageChef.CommonTypes.Extents;
using DiscImageChef.CommonTypes.Interfaces; using DiscImageChef.CommonTypes.Interfaces;
using DiscImageChef.CommonTypes.Interop; using DiscImageChef.CommonTypes.Interop;
using DiscImageChef.CommonTypes.Structs; using DiscImageChef.CommonTypes.Structs;
using DiscImageChef.CommonTypes.Structs.Devices.SCSI;
using DiscImageChef.Console; using DiscImageChef.Console;
using DiscImageChef.Core.Logging; using DiscImageChef.Core.Logging;
using DiscImageChef.Decoders.DVD; using DiscImageChef.Decoders.DVD;

View File

@@ -33,10 +33,12 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using DiscImageChef.CommonTypes.Enums; using DiscImageChef.CommonTypes.Enums;
using DiscImageChef.CommonTypes.Structs.Devices.SCSI;
using DiscImageChef.Console; using DiscImageChef.Console;
using DiscImageChef.Decoders.ATA; using DiscImageChef.Decoders.ATA;
using DiscImageChef.Decoders.SCSI; using DiscImageChef.Decoders.SCSI;
using DiscImageChef.Devices; using DiscImageChef.Devices;
using Inquiry = DiscImageChef.CommonTypes.Structs.Devices.SCSI.Inquiry;
namespace DiscImageChef.Core.Devices.Info namespace DiscImageChef.Core.Devices.Info
{ {

View File

@@ -32,10 +32,12 @@
using System.Collections.Generic; using System.Collections.Generic;
using DiscImageChef.CommonTypes.Enums; using DiscImageChef.CommonTypes.Enums;
using DiscImageChef.CommonTypes.Structs.Devices.SCSI;
using DiscImageChef.Decoders.ATA; using DiscImageChef.Decoders.ATA;
using DiscImageChef.Decoders.SCSI; using DiscImageChef.Decoders.SCSI;
using DiscImageChef.Decoders.SCSI.SSC; using DiscImageChef.Decoders.SCSI.SSC;
using DiscImageChef.Devices; using DiscImageChef.Devices;
using Inquiry = DiscImageChef.CommonTypes.Structs.Devices.SCSI.Inquiry;
namespace DiscImageChef.Core.Devices.Info namespace DiscImageChef.Core.Devices.Info
{ {
@@ -44,7 +46,7 @@ namespace DiscImageChef.Core.Devices.Info
public byte[] AtaIdentify { get; } public byte[] AtaIdentify { get; }
public byte[] AtapiIdentify { get; } public byte[] AtapiIdentify { get; }
public byte[] ScsiInquiryData { get; } public byte[] ScsiInquiryData { get; }
public Inquiry.SCSIInquiry? ScsiInquiry { get; } public Inquiry? ScsiInquiry { get; }
public AtaErrorRegistersChs? AtaMcptError { get; } public AtaErrorRegistersChs? AtaMcptError { get; }
public Dictionary<byte, byte[]> ScsiEvpdPages { get; } public Dictionary<byte, byte[]> ScsiEvpdPages { get; }
public Modes.DecodedMode? ScsiMode { get; } public Modes.DecodedMode? ScsiMode { get; }

View File

@@ -32,7 +32,7 @@
using System; using System;
using DiscImageChef.CommonTypes.Enums; using DiscImageChef.CommonTypes.Enums;
using DiscImageChef.Decoders.ATA; using DiscImageChef.CommonTypes.Structs.Devices.ATA;
using DiscImageChef.Devices; using DiscImageChef.Devices;
namespace DiscImageChef.Core.Devices namespace DiscImageChef.Core.Devices

View File

@@ -34,10 +34,11 @@ using System;
using DiscImageChef.CommonTypes.Enums; using DiscImageChef.CommonTypes.Enums;
using DiscImageChef.Console; using DiscImageChef.Console;
using DiscImageChef.Decoders.ATA; using DiscImageChef.Decoders.ATA;
using Identify = DiscImageChef.CommonTypes.Structs.Devices.ATA.Identify;
namespace DiscImageChef.Core.Devices namespace DiscImageChef.Core.Devices
{ {
partial class Reader internal partial class Reader
{ {
Identify.IdentifyDevice ataId; Identify.IdentifyDevice ataId;
bool ataRead; bool ataRead;
@@ -60,9 +61,12 @@ namespace DiscImageChef.Core.Devices
(uint, byte, byte) GetDeviceChs() (uint, byte, byte) GetDeviceChs()
{ {
if(dev.Type != DeviceType.ATA) return (0, 0, 0); if(dev.Type != DeviceType.ATA)
return(0, 0, 0);
if(ataId.CurrentCylinders > 0 && ataId.CurrentHeads > 0 && ataId.CurrentSectorsPerTrack > 0) if(ataId.CurrentCylinders > 0 &&
ataId.CurrentHeads > 0 &&
ataId.CurrentSectorsPerTrack > 0)
{ {
Cylinders = ataId.CurrentCylinders; Cylinders = ataId.CurrentCylinders;
Heads = (byte)ataId.CurrentHeads; Heads = (byte)ataId.CurrentHeads;
@@ -70,17 +74,18 @@ namespace DiscImageChef.Core.Devices
Blocks = (ulong)(Cylinders * Heads * Sectors); Blocks = (ulong)(Cylinders * Heads * Sectors);
} }
if(ataId.CurrentCylinders != 0 && ataId.CurrentHeads != 0 && ataId.CurrentSectorsPerTrack != 0 || if((ataId.CurrentCylinders != 0 && ataId.CurrentHeads != 0 && ataId.CurrentSectorsPerTrack != 0) ||
ataId.Cylinders <= 0 || ataId.Cylinders <= 0 ||
ataId.Heads <= 0 || ataId.Heads <= 0 ||
ataId.SectorsPerTrack <= 0) return (Cylinders, Heads, Sectors); ataId.SectorsPerTrack <= 0)
return(Cylinders, Heads, Sectors);
Cylinders = ataId.Cylinders; Cylinders = ataId.Cylinders;
Heads = (byte)ataId.Heads; Heads = (byte)ataId.Heads;
Sectors = (byte)ataId.SectorsPerTrack; Sectors = (byte)ataId.SectorsPerTrack;
Blocks = (ulong)(Cylinders * Heads * Sectors); Blocks = (ulong)(Cylinders * Heads * Sectors);
return (Cylinders, Heads, Sectors); return(Cylinders, Heads, Sectors);
} }
ulong AtaGetBlocks() ulong AtaGetBlocks()
@@ -93,7 +98,8 @@ namespace DiscImageChef.Core.Devices
IsLba = true; IsLba = true;
} }
if(!ataId.CommandSet2.HasFlag(Identify.CommandSetBit2.LBA48)) return Blocks; if(!ataId.CommandSet2.HasFlag(Identify.CommandSetBit2.LBA48))
return Blocks;
Blocks = ataId.LBA48Sectors; Blocks = ataId.LBA48Sectors;
IsLba = true; IsLba = true;
@@ -105,6 +111,7 @@ namespace DiscImageChef.Core.Devices
{ {
bool sense = dev.Read(out byte[] cmdBuf, out AtaErrorRegistersChs errorChs, false, 0, 0, 1, 1, timeout, bool sense = dev.Read(out byte[] cmdBuf, out AtaErrorRegistersChs errorChs, false, 0, 0, 1, 1, timeout,
out _); out _);
ataRead = !sense && (errorChs.Status & 0x27) == 0 && errorChs.Error == 0 && cmdBuf.Length > 0; ataRead = !sense && (errorChs.Status & 0x27) == 0 && errorChs.Error == 0 && cmdBuf.Length > 0;
sense = dev.Read(out cmdBuf, out errorChs, true, 0, 0, 1, 1, timeout, out _); sense = dev.Read(out cmdBuf, out errorChs, true, 0, 0, 1, 1, timeout, out _);
ataReadRetry = !sense && (errorChs.Status & 0x27) == 0 && errorChs.Error == 0 && cmdBuf.Length > 0; ataReadRetry = !sense && (errorChs.Status & 0x27) == 0 && errorChs.Error == 0 && cmdBuf.Length > 0;
@@ -134,40 +141,62 @@ namespace DiscImageChef.Core.Devices
if(IsLba) if(IsLba)
{ {
if(Blocks > 0xFFFFFFF && !ataReadLba48 && !ataReadDmaLba48) if(Blocks > 0xFFFFFFF &&
!ataReadLba48 &&
!ataReadDmaLba48)
{ {
ErrorMessage = "Device needs 48-bit LBA commands but I can't issue them... Aborting."; ErrorMessage = "Device needs 48-bit LBA commands but I can't issue them... Aborting.";
return true; return true;
} }
if(!ataReadLba && !ataReadRetryLba && !ataReadDmaLba && !ataReadDmaRetryLba) if(!ataReadLba &&
!ataReadRetryLba &&
!ataReadDmaLba &&
!ataReadDmaRetryLba)
{ {
ErrorMessage = "Device needs 28-bit LBA commands but I can't issue them... Aborting."; ErrorMessage = "Device needs 28-bit LBA commands but I can't issue them... Aborting.";
return true; return true;
} }
} }
else else
{ {
if(!ataRead && !ataReadRetry && !ataReadDma && !ataReadDmaRetry) if(!ataRead &&
!ataReadRetry &&
!ataReadDma &&
!ataReadDmaRetry)
{ {
ErrorMessage = "Device needs CHS commands but I can't issue them... Aborting."; ErrorMessage = "Device needs CHS commands but I can't issue them... Aborting.";
return true; return true;
} }
} }
if(ataReadDmaLba48) DicConsole.WriteLine("Using ATA READ DMA EXT command."); if(ataReadDmaLba48)
else if(ataReadLba48) DicConsole.WriteLine("Using ATA READ EXT command."); DicConsole.WriteLine("Using ATA READ DMA EXT command.");
else if(ataReadDmaRetryLba) DicConsole.WriteLine("Using ATA READ DMA command with retries (LBA)."); else if(ataReadLba48)
else if(ataReadDmaLba) DicConsole.WriteLine("Using ATA READ DMA command (LBA)."); DicConsole.WriteLine("Using ATA READ EXT command.");
else if(ataReadRetryLba) DicConsole.WriteLine("Using ATA READ command with retries (LBA)."); else if(ataReadDmaRetryLba)
else if(ataReadLba) DicConsole.WriteLine("Using ATA READ command (LBA)."); DicConsole.WriteLine("Using ATA READ DMA command with retries (LBA).");
else if(ataReadDmaRetry) DicConsole.WriteLine("Using ATA READ DMA command with retries (CHS)."); else if(ataReadDmaLba)
else if(ataReadDma) DicConsole.WriteLine("Using ATA READ DMA command (CHS)."); DicConsole.WriteLine("Using ATA READ DMA command (LBA).");
else if(ataReadRetry) DicConsole.WriteLine("Using ATA READ command with retries (CHS)."); else if(ataReadRetryLba)
else if(ataRead) DicConsole.WriteLine("Using ATA READ command (CHS)."); DicConsole.WriteLine("Using ATA READ command with retries (LBA).");
else if(ataReadLba)
DicConsole.WriteLine("Using ATA READ command (LBA).");
else if(ataReadDmaRetry)
DicConsole.WriteLine("Using ATA READ DMA command with retries (CHS).");
else if(ataReadDma)
DicConsole.WriteLine("Using ATA READ DMA command (CHS).");
else if(ataReadRetry)
DicConsole.WriteLine("Using ATA READ command with retries (CHS).");
else if(ataRead)
DicConsole.WriteLine("Using ATA READ command (CHS).");
else else
{ {
ErrorMessage = "Could not get a working read command!"; ErrorMessage = "Could not get a working read command!";
return true; return true;
} }
@@ -176,18 +205,22 @@ namespace DiscImageChef.Core.Devices
bool AtaGetBlockSize() bool AtaGetBlockSize()
{ {
if((ataId.PhysLogSectorSize & 0x8000) == 0x0000 && (ataId.PhysLogSectorSize & 0x4000) == 0x4000) if((ataId.PhysLogSectorSize & 0x8000) == 0x0000 &&
(ataId.PhysLogSectorSize & 0x4000) == 0x4000)
{ {
if((ataId.PhysLogSectorSize & 0x1000) == 0x1000) if((ataId.PhysLogSectorSize & 0x1000) == 0x1000)
if(ataId.LogicalSectorWords <= 255 || ataId.LogicalAlignment == 0xFFFF) if(ataId.LogicalSectorWords <= 255 ||
ataId.LogicalAlignment == 0xFFFF)
LogicalBlockSize = 512; LogicalBlockSize = 512;
else else
LogicalBlockSize = ataId.LogicalSectorWords * 2; LogicalBlockSize = ataId.LogicalSectorWords * 2;
else LogicalBlockSize = 512; else
LogicalBlockSize = 512;
if((ataId.PhysLogSectorSize & 0x2000) == 0x2000) if((ataId.PhysLogSectorSize & 0x2000) == 0x2000)
PhysicalBlockSize = LogicalBlockSize * (uint)Math.Pow(2, ataId.PhysLogSectorSize & 0xF); PhysicalBlockSize = LogicalBlockSize * (uint)Math.Pow(2, ataId.PhysLogSectorSize & 0xF);
else PhysicalBlockSize = LogicalBlockSize; else
PhysicalBlockSize = LogicalBlockSize;
} }
else else
{ {
@@ -208,6 +241,7 @@ namespace DiscImageChef.Core.Devices
if(!IsLba) if(!IsLba)
{ {
BlocksToRead = 1; BlocksToRead = 1;
return false; return false;
} }
@@ -218,6 +252,7 @@ namespace DiscImageChef.Core.Devices
byte[] cmdBuf; byte[] cmdBuf;
bool sense; bool sense;
AtaErrorRegistersLba48 errorLba48; AtaErrorRegistersLba48 errorLba48;
if(ataReadDmaLba48) if(ataReadDmaLba48)
{ {
sense = dev.ReadDma(out cmdBuf, out errorLba48, 0, (byte)BlocksToRead, timeout, out _); sense = dev.ReadDma(out cmdBuf, out errorLba48, 0, (byte)BlocksToRead, timeout, out _);
@@ -231,6 +266,7 @@ namespace DiscImageChef.Core.Devices
else else
{ {
AtaErrorRegistersLba28 errorLba; AtaErrorRegistersLba28 errorLba;
if(ataReadDmaRetryLba) if(ataReadDmaRetryLba)
{ {
sense = dev.ReadDma(out cmdBuf, out errorLba, true, 0, (byte)BlocksToRead, timeout, out _); sense = dev.ReadDma(out cmdBuf, out errorLba, true, 0, (byte)BlocksToRead, timeout, out _);
@@ -253,15 +289,21 @@ namespace DiscImageChef.Core.Devices
} }
} }
if(error) BlocksToRead /= 2; if(error)
BlocksToRead /= 2;
if(!error || BlocksToRead == 1) break; if(!error ||
BlocksToRead == 1)
break;
} }
if(!error || !IsLba) return false; if(!error ||
!IsLba)
return false;
BlocksToRead = 1; BlocksToRead = 1;
ErrorMessage = $"Device error {dev.LastError} trying to guess ideal transfer length."; ErrorMessage = $"Device error {dev.LastError} trying to guess ideal transfer length.";
return true; return true;
} }
@@ -293,6 +335,7 @@ namespace DiscImageChef.Core.Devices
{ {
sense = dev.ReadDma(out buffer, out errorLba, true, (uint)block, (byte)count, timeout, sense = dev.ReadDma(out buffer, out errorLba, true, (uint)block, (byte)count, timeout,
out duration); out duration);
error = !(!sense && (errorLba.Status & 0x27) == 0 && errorLba.Error == 0 && buffer.Length > 0); error = !(!sense && (errorLba.Status & 0x27) == 0 && errorLba.Error == 0 && buffer.Length > 0);
status = errorLba.Status; status = errorLba.Status;
errorByte = errorLba.Error; errorByte = errorLba.Error;
@@ -301,6 +344,7 @@ namespace DiscImageChef.Core.Devices
{ {
sense = dev.ReadDma(out buffer, out errorLba, false, (uint)block, (byte)count, timeout, sense = dev.ReadDma(out buffer, out errorLba, false, (uint)block, (byte)count, timeout,
out duration); out duration);
error = !(!sense && (errorLba.Status & 0x27) == 0 && errorLba.Error == 0 && buffer.Length > 0); error = !(!sense && (errorLba.Status & 0x27) == 0 && errorLba.Error == 0 && buffer.Length > 0);
status = errorLba.Status; status = errorLba.Status;
errorByte = errorLba.Error; errorByte = errorLba.Error;
@@ -320,7 +364,8 @@ namespace DiscImageChef.Core.Devices
errorByte = errorLba.Error; errorByte = errorLba.Error;
} }
if(error) DicConsole.DebugWriteLine("ATA Reader", "ATA ERROR: {0} STATUS: {1}", errorByte, status); if(error)
DicConsole.DebugWriteLine("ATA Reader", "ATA ERROR: {0} STATUS: {1}", errorByte, status);
return error; return error;
} }
@@ -338,6 +383,7 @@ namespace DiscImageChef.Core.Devices
{ {
sense = dev.ReadDma(out buffer, out errorChs, true, cylinder, head, sectir, 1, timeout, sense = dev.ReadDma(out buffer, out errorChs, true, cylinder, head, sectir, 1, timeout,
out duration); out duration);
error = !(!sense && (errorChs.Status & 0x27) == 0 && errorChs.Error == 0 && buffer.Length > 0); error = !(!sense && (errorChs.Status & 0x27) == 0 && errorChs.Error == 0 && buffer.Length > 0);
status = errorChs.Status; status = errorChs.Status;
errorByte = errorChs.Error; errorByte = errorChs.Error;
@@ -346,6 +392,7 @@ namespace DiscImageChef.Core.Devices
{ {
sense = dev.ReadDma(out buffer, out errorChs, false, cylinder, head, sectir, 1, timeout, sense = dev.ReadDma(out buffer, out errorChs, false, cylinder, head, sectir, 1, timeout,
out duration); out duration);
error = !(!sense && (errorChs.Status & 0x27) == 0 && errorChs.Error == 0 && buffer.Length > 0); error = !(!sense && (errorChs.Status & 0x27) == 0 && errorChs.Error == 0 && buffer.Length > 0);
status = errorChs.Status; status = errorChs.Status;
errorByte = errorChs.Error; errorByte = errorChs.Error;
@@ -365,7 +412,8 @@ namespace DiscImageChef.Core.Devices
errorByte = errorChs.Error; errorByte = errorChs.Error;
} }
if(error) DicConsole.DebugWriteLine("ATA Reader", "ATA ERROR: {0} STATUS: {1}", errorByte, status); if(error)
DicConsole.DebugWriteLine("ATA Reader", "ATA ERROR: {0} STATUS: {1}", errorByte, status);
return error; return error;
} }
@@ -373,13 +421,15 @@ namespace DiscImageChef.Core.Devices
bool AtaSeek(ulong block, out double duration) bool AtaSeek(ulong block, out double duration)
{ {
bool sense = dev.Seek(out AtaErrorRegistersLba28 errorLba, (uint)block, timeout, out duration); bool sense = dev.Seek(out AtaErrorRegistersLba28 errorLba, (uint)block, timeout, out duration);
return !(!sense && (errorLba.Status & 0x27) == 0 && errorLba.Error == 0);
return!(!sense && (errorLba.Status & 0x27) == 0 && errorLba.Error == 0);
} }
bool AtaSeekChs(ushort cylinder, byte head, byte sector, out double duration) bool AtaSeekChs(ushort cylinder, byte head, byte sector, out double duration)
{ {
bool sense = dev.Seek(out AtaErrorRegistersChs errorChs, cylinder, head, sector, timeout, out duration); bool sense = dev.Seek(out AtaErrorRegistersChs errorChs, cylinder, head, sector, timeout, out duration);
return !(!sense && (errorChs.Status & 0x27) == 0 && errorChs.Error == 0);
return!(!sense && (errorChs.Status & 0x27) == 0 && errorChs.Error == 0);
} }
} }
} }

View File

@@ -31,12 +31,13 @@
// ****************************************************************************/ // ****************************************************************************/
using System; using System;
using DiscImageChef.CommonTypes.Structs.Devices.SCSI;
using DiscImageChef.Console; using DiscImageChef.Console;
using DiscImageChef.Decoders.SCSI; using DiscImageChef.Decoders.SCSI;
namespace DiscImageChef.Core.Devices namespace DiscImageChef.Core.Devices
{ {
partial class Reader internal partial class Reader
{ {
// TODO: Raw reading // TODO: Raw reading
bool hldtstReadRaw; bool hldtstReadRaw;
@@ -72,23 +73,34 @@ namespace DiscImageChef.Core.Devices
seek10 = !dev.Seek10(out senseBuf, 0, timeout, out _); seek10 = !dev.Seek10(out senseBuf, 0, timeout, out _);
if(!read6 && !read10 && !read12 && !read16) if(!read6 &&
!read10 &&
!read12 &&
!read16)
{ {
ErrorMessage = "Cannot read medium, aborting scan..."; ErrorMessage = "Cannot read medium, aborting scan...";
return true; return true;
} }
if(read6 && !read10 && !read12 && !read16 && Blocks > 0x001FFFFF + 1) if(read6 &&
!read10 &&
!read12 &&
!read16 &&
Blocks > 0x001FFFFF + 1)
{ {
ErrorMessage = ErrorMessage =
$"Device only supports SCSI READ (6) but has more than {0x001FFFFF + 1} blocks ({Blocks} blocks total)"; $"Device only supports SCSI READ (6) but has more than {0x001FFFFF + 1} blocks ({Blocks} blocks total)";
return true; return true;
} }
if(!read16 && Blocks > 0xFFFFFFFF + (long)1) if(!read16 &&
Blocks > 0xFFFFFFFF + (long)1)
{ {
ErrorMessage = ErrorMessage =
$"Device only supports SCSI READ (10) but has more than {0xFFFFFFFF + (long)1} blocks ({Blocks} blocks total)"; $"Device only supports SCSI READ (10) but has more than {0xFFFFFFFF + (long)1} blocks ({Blocks} blocks total)";
return true; return true;
} }
@@ -120,17 +132,23 @@ namespace DiscImageChef.Core.Devices
testSense = dev.ReadLong10(out _, out senseBuf, false, false, 0, 0xFFFF, timeout, out _); testSense = dev.ReadLong10(out _, out senseBuf, false, false, 0, 0xFFFF, timeout, out _);
FixedSense? decSense; FixedSense? decSense;
if(testSense && !dev.Error) if(testSense && !dev.Error)
{ {
decSense = Sense.DecodeFixed(senseBuf); decSense = Sense.DecodeFixed(senseBuf);
if(decSense.HasValue) if(decSense.HasValue)
if(decSense.Value.SenseKey == SenseKeys.IllegalRequest && decSense.Value.ASC == 0x24 && if(decSense.Value.SenseKey == SenseKeys.IllegalRequest &&
decSense.Value.ASC == 0x24 &&
decSense.Value.ASCQ == 0x00) decSense.Value.ASCQ == 0x00)
{ {
CanReadRaw = true; CanReadRaw = true;
if(decSense.Value.InformationValid && decSense.Value.ILI)
if(decSense.Value.InformationValid &&
decSense.Value.ILI)
{ {
LongBlockSize = 0xFFFF - (decSense.Value.Information & 0xFFFF); LongBlockSize = 0xFFFF - (decSense.Value.Information & 0xFFFF);
readLong10 = !dev.ReadLong10(out _, out senseBuf, false, false, 0, readLong10 = !dev.ReadLong10(out _, out senseBuf, false, false, 0,
(ushort)LongBlockSize, timeout, out _); (ushort)LongBlockSize, timeout, out _);
} }
@@ -143,29 +161,37 @@ namespace DiscImageChef.Core.Devices
{ {
// Long sector sizes for floppies // Long sector sizes for floppies
514, 514,
// Long sector sizes for SuperDisk // Long sector sizes for SuperDisk
536, 558, 536, 558,
// Long sector sizes for 512-byte magneto-opticals // Long sector sizes for 512-byte magneto-opticals
600, 610, 630 600, 610, 630
}) })
{ {
ushort testSize = (ushort)i; ushort testSize = (ushort)i;
testSense = dev.ReadLong16(out _, out senseBuf, false, 0, testSize, timeout, out _); testSense = dev.ReadLong16(out _, out senseBuf, false, 0, testSize, timeout, out _);
if(!testSense && !dev.Error)
if(!testSense &&
!dev.Error)
{ {
readLong16 = true; readLong16 = true;
LongBlockSize = testSize; LongBlockSize = testSize;
CanReadRaw = true; CanReadRaw = true;
break; break;
} }
testSense = dev.ReadLong10(out _, out senseBuf, false, false, 0, testSize, timeout, testSense = dev.ReadLong10(out _, out senseBuf, false, false, 0, testSize, timeout,
out _); out _);
if(testSense || dev.Error) continue;
if(testSense || dev.Error)
continue;
readLong10 = true; readLong10 = true;
LongBlockSize = testSize; LongBlockSize = testSize;
CanReadRaw = true; CanReadRaw = true;
break; break;
} }
else if(LogicalBlockSize == 1024) else if(LogicalBlockSize == 1024)
@@ -173,33 +199,42 @@ namespace DiscImageChef.Core.Devices
{ {
// Long sector sizes for floppies // Long sector sizes for floppies
1026, 1026,
// Long sector sizes for 1024-byte magneto-opticals // Long sector sizes for 1024-byte magneto-opticals
1200 1200
}) })
{ {
ushort testSize = (ushort)i; ushort testSize = (ushort)i;
testSense = dev.ReadLong16(out _, out senseBuf, false, 0, testSize, timeout, out _); testSense = dev.ReadLong16(out _, out senseBuf, false, 0, testSize, timeout, out _);
if(!testSense && !dev.Error)
if(!testSense &&
!dev.Error)
{ {
readLong16 = true; readLong16 = true;
LongBlockSize = testSize; LongBlockSize = testSize;
CanReadRaw = true; CanReadRaw = true;
break; break;
} }
testSense = dev.ReadLong10(out _, out senseBuf, false, false, 0, testSize, timeout, testSense = dev.ReadLong10(out _, out senseBuf, false, false, 0, testSize, timeout,
out _); out _);
if(testSense || dev.Error) continue;
if(testSense || dev.Error)
continue;
readLong10 = true; readLong10 = true;
LongBlockSize = testSize; LongBlockSize = testSize;
CanReadRaw = true; CanReadRaw = true;
break; break;
} }
else if(LogicalBlockSize == 2048) else if(LogicalBlockSize == 2048)
{ {
testSense = dev.ReadLong16(out _, out senseBuf, false, 0, 2380, timeout, out _); testSense = dev.ReadLong16(out _, out senseBuf, false, 0, 2380, timeout, out _);
if(!testSense && !dev.Error)
if(!testSense &&
!dev.Error)
{ {
readLong16 = true; readLong16 = true;
LongBlockSize = 2380; LongBlockSize = 2380;
@@ -208,7 +243,9 @@ namespace DiscImageChef.Core.Devices
else else
{ {
testSense = dev.ReadLong10(out _, out senseBuf, false, false, 0, 2380, timeout, out _); testSense = dev.ReadLong10(out _, out senseBuf, false, false, 0, 2380, timeout, out _);
if(!testSense && !dev.Error)
if(!testSense &&
!dev.Error)
{ {
readLong10 = true; readLong10 = true;
LongBlockSize = 2380; LongBlockSize = 2380;
@@ -219,7 +256,9 @@ namespace DiscImageChef.Core.Devices
else if(LogicalBlockSize == 4096) else if(LogicalBlockSize == 4096)
{ {
testSense = dev.ReadLong16(out _, out senseBuf, false, 0, 4760, timeout, out _); testSense = dev.ReadLong16(out _, out senseBuf, false, 0, 4760, timeout, out _);
if(!testSense && !dev.Error)
if(!testSense &&
!dev.Error)
{ {
readLong16 = true; readLong16 = true;
LongBlockSize = 4760; LongBlockSize = 4760;
@@ -228,7 +267,9 @@ namespace DiscImageChef.Core.Devices
else else
{ {
testSense = dev.ReadLong10(out _, out senseBuf, false, false, 0, 4760, timeout, out _); testSense = dev.ReadLong10(out _, out senseBuf, false, false, 0, 4760, timeout, out _);
if(!testSense && !dev.Error)
if(!testSense &&
!dev.Error)
{ {
readLong10 = true; readLong10 = true;
LongBlockSize = 4760; LongBlockSize = 4760;
@@ -239,7 +280,9 @@ namespace DiscImageChef.Core.Devices
else if(LogicalBlockSize == 8192) else if(LogicalBlockSize == 8192)
{ {
testSense = dev.ReadLong16(out _, out senseBuf, false, 0, 9424, timeout, out _); testSense = dev.ReadLong16(out _, out senseBuf, false, 0, 9424, timeout, out _);
if(!testSense && !dev.Error)
if(!testSense &&
!dev.Error)
{ {
readLong16 = true; readLong16 = true;
LongBlockSize = 9424; LongBlockSize = 9424;
@@ -248,7 +291,9 @@ namespace DiscImageChef.Core.Devices
else else
{ {
testSense = dev.ReadLong10(out _, out senseBuf, false, false, 0, 9424, timeout, out _); testSense = dev.ReadLong10(out _, out senseBuf, false, false, 0, 9424, timeout, out _);
if(!testSense && !dev.Error)
if(!testSense &&
!dev.Error)
{ {
readLong10 = true; readLong10 = true;
LongBlockSize = 9424; LongBlockSize = 9424;
@@ -257,20 +302,27 @@ namespace DiscImageChef.Core.Devices
} }
} }
if(!CanReadRaw && dev.Manufacturer == "SYQUEST") if(!CanReadRaw &&
dev.Manufacturer == "SYQUEST")
{ {
testSense = dev.SyQuestReadLong10(out _, out senseBuf, 0, 0xFFFF, timeout, out _); testSense = dev.SyQuestReadLong10(out _, out senseBuf, 0, 0xFFFF, timeout, out _);
if(testSense) if(testSense)
{ {
decSense = Sense.DecodeFixed(senseBuf); decSense = Sense.DecodeFixed(senseBuf);
if(decSense.HasValue) if(decSense.HasValue)
if(decSense.Value.SenseKey == SenseKeys.IllegalRequest && decSense.Value.ASC == 0x24 && if(decSense.Value.SenseKey == SenseKeys.IllegalRequest &&
decSense.Value.ASC == 0x24 &&
decSense.Value.ASCQ == 0x00) decSense.Value.ASCQ == 0x00)
{ {
CanReadRaw = true; CanReadRaw = true;
if(decSense.Value.InformationValid && decSense.Value.ILI)
if(decSense.Value.InformationValid &&
decSense.Value.ILI)
{ {
LongBlockSize = 0xFFFF - (decSense.Value.Information & 0xFFFF); LongBlockSize = 0xFFFF - (decSense.Value.Information & 0xFFFF);
syqReadLong10 = syqReadLong10 =
!dev.SyQuestReadLong10(out _, out senseBuf, 0, LongBlockSize, timeout, !dev.SyQuestReadLong10(out _, out senseBuf, 0, LongBlockSize, timeout,
out _); out _);
@@ -279,18 +331,23 @@ namespace DiscImageChef.Core.Devices
else else
{ {
testSense = dev.SyQuestReadLong6(out _, out senseBuf, 0, 0xFFFF, timeout, out _); testSense = dev.SyQuestReadLong6(out _, out senseBuf, 0, 0xFFFF, timeout, out _);
if(testSense) if(testSense)
{ {
decSense = Sense.DecodeFixed(senseBuf); decSense = Sense.DecodeFixed(senseBuf);
if(decSense.HasValue) if(decSense.HasValue)
if(decSense.Value.SenseKey == SenseKeys.IllegalRequest && if(decSense.Value.SenseKey == SenseKeys.IllegalRequest &&
decSense.Value.ASC == 0x24 && decSense.Value.ASC == 0x24 &&
decSense.Value.ASCQ == 0x00) decSense.Value.ASCQ == 0x00)
{ {
CanReadRaw = true; CanReadRaw = true;
if(decSense.Value.InformationValid && decSense.Value.ILI)
if(decSense.Value.InformationValid &&
decSense.Value.ILI)
{ {
LongBlockSize = 0xFFFF - (decSense.Value.Information & 0xFFFF); LongBlockSize = 0xFFFF - (decSense.Value.Information & 0xFFFF);
syqReadLong6 = syqReadLong6 =
!dev.SyQuestReadLong6(out _, out senseBuf, 0, LongBlockSize, !dev.SyQuestReadLong6(out _, out senseBuf, 0, LongBlockSize,
timeout, out _); timeout, out _);
@@ -300,10 +357,13 @@ namespace DiscImageChef.Core.Devices
} }
} }
if(!CanReadRaw && LogicalBlockSize == 256) if(!CanReadRaw &&
LogicalBlockSize == 256)
{ {
testSense = dev.SyQuestReadLong6(out _, out senseBuf, 0, 262, timeout, out _); testSense = dev.SyQuestReadLong6(out _, out senseBuf, 0, 262, timeout, out _);
if(!testSense && !dev.Error)
if(!testSense &&
!dev.Error)
{ {
syqReadLong6 = true; syqReadLong6 = true;
LongBlockSize = 262; LongBlockSize = 262;
@@ -316,11 +376,13 @@ namespace DiscImageChef.Core.Devices
{ {
switch(dev.Manufacturer) switch(dev.Manufacturer)
{ {
case "HL-DT-ST": case"HL-DT-ST":
hldtstReadRaw = !dev.HlDtStReadRawDvd(out _, out senseBuf, 0, 1, timeout, out _); hldtstReadRaw = !dev.HlDtStReadRawDvd(out _, out senseBuf, 0, 1, timeout, out _);
break; break;
case "PLEXTOR": case"PLEXTOR":
plextorReadRaw = !dev.PlextorReadRawDvd(out _, out senseBuf, 0, 1, timeout, out _); plextorReadRaw = !dev.PlextorReadRawDvd(out _, out senseBuf, 0, 1, timeout, out _);
break; break;
} }
@@ -331,10 +393,13 @@ namespace DiscImageChef.Core.Devices
} }
// READ LONG (10) for some DVD drives // READ LONG (10) for some DVD drives
if(!CanReadRaw && dev.Manufacturer == "MATSHITA") if(!CanReadRaw &&
dev.Manufacturer == "MATSHITA")
{ {
testSense = dev.ReadLong10(out _, out senseBuf, false, false, 0, 37856, timeout, out _); testSense = dev.ReadLong10(out _, out senseBuf, false, false, 0, 37856, timeout, out _);
if(!testSense && !dev.Error)
if(!testSense &&
!dev.Error)
{ {
readLongDvd = true; readLongDvd = true;
LongBlockSize = 37856; LongBlockSize = 37856;
@@ -346,17 +411,27 @@ namespace DiscImageChef.Core.Devices
if(CanReadRaw) if(CanReadRaw)
{ {
if(readLong16) DicConsole.WriteLine("Using SCSI READ LONG (16) command."); if(readLong16)
else if(readLong10 || readLongDvd) DicConsole.WriteLine("Using SCSI READ LONG (10) command."); DicConsole.WriteLine("Using SCSI READ LONG (16) command.");
else if(syqReadLong10) DicConsole.WriteLine("Using SyQuest READ LONG (10) command."); else if(readLong10 || readLongDvd)
else if(syqReadLong6) DicConsole.WriteLine("Using SyQuest READ LONG (6) command."); DicConsole.WriteLine("Using SCSI READ LONG (10) command.");
else if(hldtstReadRaw) DicConsole.WriteLine("Using HL-DT-ST raw DVD reading."); else if(syqReadLong10)
else if(plextorReadRaw) DicConsole.WriteLine("Using Plextor raw DVD reading."); DicConsole.WriteLine("Using SyQuest READ LONG (10) command.");
else if(syqReadLong6)
DicConsole.WriteLine("Using SyQuest READ LONG (6) command.");
else if(hldtstReadRaw)
DicConsole.WriteLine("Using HL-DT-ST raw DVD reading.");
else if(plextorReadRaw)
DicConsole.WriteLine("Using Plextor raw DVD reading.");
} }
else if(read16) DicConsole.WriteLine("Using SCSI READ (16) command."); else if(read16)
else if(read12) DicConsole.WriteLine("Using SCSI READ (12) command."); DicConsole.WriteLine("Using SCSI READ (16) command.");
else if(read10) DicConsole.WriteLine("Using SCSI READ (10) command."); else if(read12)
else if(read6) DicConsole.WriteLine("Using SCSI READ (6) command."); DicConsole.WriteLine("Using SCSI READ (12) command.");
else if(read10)
DicConsole.WriteLine("Using SCSI READ (10) command.");
else if(read6)
DicConsole.WriteLine("Using SCSI READ (6) command.");
return false; return false;
} }
@@ -367,6 +442,7 @@ namespace DiscImageChef.Core.Devices
Blocks = 0; Blocks = 0;
sense = dev.ReadCapacity(out byte[] cmdBuf, out byte[] senseBuf, timeout, out _); sense = dev.ReadCapacity(out byte[] cmdBuf, out byte[] senseBuf, timeout, out _);
if(!sense) if(!sense)
{ {
Blocks = (ulong)((cmdBuf[0] << 24) + (cmdBuf[1] << 16) + (cmdBuf[2] << 8) + cmdBuf[3]); Blocks = (ulong)((cmdBuf[0] << 24) + (cmdBuf[1] << 16) + (cmdBuf[2] << 8) + cmdBuf[3]);
@@ -398,6 +474,7 @@ namespace DiscImageChef.Core.Devices
PhysicalBlockSize = LogicalBlockSize; PhysicalBlockSize = LogicalBlockSize;
LongBlockSize = LogicalBlockSize; LongBlockSize = LogicalBlockSize;
return false; return false;
} }
@@ -411,33 +488,45 @@ namespace DiscImageChef.Core.Devices
{ {
dev.Read16(out _, out _, 0, false, true, false, 0, LogicalBlockSize, 0, BlocksToRead, false, dev.Read16(out _, out _, 0, false, true, false, 0, LogicalBlockSize, 0, BlocksToRead, false,
timeout, out _); timeout, out _);
if(dev.Error) BlocksToRead /= 2;
if(dev.Error)
BlocksToRead /= 2;
} }
else if(read12) else if(read12)
{ {
dev.Read12(out _, out _, 0, false, false, false, false, 0, LogicalBlockSize, 0, BlocksToRead, false, dev.Read12(out _, out _, 0, false, false, false, false, 0, LogicalBlockSize, 0, BlocksToRead, false,
timeout, out _); timeout, out _);
if(dev.Error) BlocksToRead /= 2;
if(dev.Error)
BlocksToRead /= 2;
} }
else if(read10) else if(read10)
{ {
dev.Read10(out _, out _, 0, false, true, false, false, 0, LogicalBlockSize, 0, (ushort)BlocksToRead, dev.Read10(out _, out _, 0, false, true, false, false, 0, LogicalBlockSize, 0, (ushort)BlocksToRead,
timeout, out _); timeout, out _);
if(dev.Error) BlocksToRead /= 2;
if(dev.Error)
BlocksToRead /= 2;
} }
else if(read6) else if(read6)
{ {
dev.Read6(out _, out _, 0, LogicalBlockSize, (byte)BlocksToRead, timeout, out _); dev.Read6(out _, out _, 0, LogicalBlockSize, (byte)BlocksToRead, timeout, out _);
if(dev.Error) BlocksToRead /= 2;
if(dev.Error)
BlocksToRead /= 2;
} }
if(!dev.Error || BlocksToRead == 1) break; if(!dev.Error ||
BlocksToRead == 1)
break;
} }
if(!dev.Error) return false; if(!dev.Error)
return false;
BlocksToRead = 1; BlocksToRead = 1;
ErrorMessage = $"Device error {dev.LastError} trying to guess ideal transfer length."; ErrorMessage = $"Device error {dev.LastError} trying to guess ideal transfer length.";
return true; return true;
} }
@@ -467,7 +556,8 @@ namespace DiscImageChef.Core.Devices
else if(plextorReadRaw) else if(plextorReadRaw)
sense = dev.PlextorReadRawDvd(out buffer, out senseBuf, (uint)block, LongBlockSize, timeout, sense = dev.PlextorReadRawDvd(out buffer, out senseBuf, (uint)block, LongBlockSize, timeout,
out duration); out duration);
else return true; else
return true;
else else
{ {
if(read16) if(read16)
@@ -482,12 +572,16 @@ namespace DiscImageChef.Core.Devices
else if(read6) else if(read6)
sense = dev.Read6(out buffer, out senseBuf, (uint)block, LogicalBlockSize, (byte)count, timeout, sense = dev.Read6(out buffer, out senseBuf, (uint)block, LogicalBlockSize, (byte)count, timeout,
out duration); out duration);
else return true; else
return true;
} }
if(!sense && !dev.Error) return false; if(!sense &&
!dev.Error)
return false;
DicConsole.DebugWriteLine("SCSI Reader", "READ error:\n{0}", Sense.PrettifySense(senseBuf)); DicConsole.DebugWriteLine("SCSI Reader", "READ error:\n{0}", Sense.PrettifySense(senseBuf));
return sense; return sense;
} }
@@ -496,8 +590,10 @@ namespace DiscImageChef.Core.Devices
bool sense = true; bool sense = true;
duration = 0; duration = 0;
if(seek6) sense = dev.Seek6(out _, (uint)block, timeout, out duration); if(seek6)
else if(seek10) sense = dev.Seek10(out _, (uint)block, timeout, out duration); sense = dev.Seek6(out _, (uint)block, timeout, out duration);
else if(seek10)
sense = dev.Seek10(out _, (uint)block, timeout, out duration);
return sense; return sense;
} }

View File

@@ -35,6 +35,7 @@ using DiscImageChef.CommonTypes.Metadata;
using DiscImageChef.Console; using DiscImageChef.Console;
using DiscImageChef.Decoders.ATA; using DiscImageChef.Decoders.ATA;
using DiscImageChef.Devices; using DiscImageChef.Devices;
using Identify = DiscImageChef.CommonTypes.Structs.Devices.ATA.Identify;
namespace DiscImageChef.Core.Devices.Report namespace DiscImageChef.Core.Devices.Report
{ {

View File

@@ -34,9 +34,11 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using DiscImageChef.CommonTypes.Metadata; using DiscImageChef.CommonTypes.Metadata;
using DiscImageChef.CommonTypes.Structs.Devices.SCSI;
using DiscImageChef.Console; using DiscImageChef.Console;
using DiscImageChef.Decoders.SCSI; using DiscImageChef.Decoders.SCSI;
using DiscImageChef.Devices; using DiscImageChef.Devices;
using Inquiry = DiscImageChef.CommonTypes.Structs.Devices.SCSI.Inquiry;
namespace DiscImageChef.Core.Devices.Report namespace DiscImageChef.Core.Devices.Report
{ {
@@ -52,12 +54,12 @@ namespace DiscImageChef.Core.Devices.Report
if(sense) if(sense)
return null; return null;
Inquiry.SCSIInquiry? decodedNullable = Inquiry.Decode(buffer); Inquiry? decodedNullable = Inquiry.Decode(buffer);
if(!decodedNullable.HasValue) if(!decodedNullable.HasValue)
return null; return null;
Inquiry.SCSIInquiry decoded = decodedNullable.Value; Inquiry decoded = decodedNullable.Value;
// Clear Seagate serial number // Clear Seagate serial number
if(decoded.SeagatePresent && if(decoded.SeagatePresent &&

View File

@@ -32,38 +32,39 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using DiscImageChef.CommonTypes.Structs.Devices.ATA;
using DiscImageChef.Core.Logging; using DiscImageChef.Core.Logging;
using DiscImageChef.Decoders.ATA;
namespace DiscImageChef.Core.Devices.Scanning namespace DiscImageChef.Core.Devices.Scanning
{ {
/// <summary> /// <summary>Implements scanning the media from an ATA device</summary>
/// Implements scanning the media from an ATA device
/// </summary>
public partial class MediaScan public partial class MediaScan
{ {
/// <summary> /// <summary>Scans the media from an ATA device</summary>
/// Scans the media from an ATA device
/// </summary>
/// <returns>Scanning results</returns> /// <returns>Scanning results</returns>
ScanResults Ata() ScanResults Ata()
{ {
ScanResults results = new ScanResults(); var results = new ScanResults();
bool sense; bool sense;
results.Blocks = 0; results.Blocks = 0;
const ushort ATA_PROFILE = 0x0001; const ushort ATA_PROFILE = 0x0001;
const uint TIMEOUT = 5; const uint TIMEOUT = 5;
sense = dev.AtaIdentify(out byte[] cmdBuf, out _); sense = dev.AtaIdentify(out byte[] cmdBuf, out _);
if(!sense && Identify.Decode(cmdBuf).HasValue)
if(!sense &&
Identify.Decode(cmdBuf).HasValue)
{ {
// Initializate reader // Initializate reader
Reader ataReader = new Reader(dev, TIMEOUT, cmdBuf); var ataReader = new Reader(dev, TIMEOUT, cmdBuf);
// Fill reader blocks // Fill reader blocks
results.Blocks = ataReader.GetDeviceBlocks(); results.Blocks = ataReader.GetDeviceBlocks();
if(ataReader.FindReadCommand()) if(ataReader.FindReadCommand())
{ {
StoppingErrorMessage?.Invoke(ataReader.ErrorMessage); StoppingErrorMessage?.Invoke(ataReader.ErrorMessage);
return results; return results;
} }
@@ -71,14 +72,17 @@ namespace DiscImageChef.Core.Devices.Scanning
if(ataReader.GetBlockSize()) if(ataReader.GetBlockSize())
{ {
StoppingErrorMessage?.Invoke(ataReader.ErrorMessage); StoppingErrorMessage?.Invoke(ataReader.ErrorMessage);
return results; return results;
} }
uint blockSize = ataReader.LogicalBlockSize; uint blockSize = ataReader.LogicalBlockSize;
// Check how many blocks to read, if error show and return // Check how many blocks to read, if error show and return
if(ataReader.GetBlocksToRead()) if(ataReader.GetBlocksToRead())
{ {
StoppingErrorMessage?.Invoke(ataReader.ErrorMessage); StoppingErrorMessage?.Invoke(ataReader.ErrorMessage);
return results; return results;
} }
@@ -108,11 +112,12 @@ namespace DiscImageChef.Core.Devices.Scanning
double seekCur; double seekCur;
Random rnd = new Random(); var rnd = new Random();
MhddLog mhddLog; MhddLog mhddLog;
IbgLog ibgLog; IbgLog ibgLog;
double duration; double duration;
if(ataReader.IsLba) if(ataReader.IsLba)
{ {
UpdateStatus?.Invoke($"Reading {blocksToRead} sectors at a time."); UpdateStatus?.Invoke($"Reading {blocksToRead} sectors at a time.");
@@ -125,15 +130,23 @@ namespace DiscImageChef.Core.Devices.Scanning
DateTime timeSpeedStart = DateTime.UtcNow; DateTime timeSpeedStart = DateTime.UtcNow;
ulong sectorSpeedStart = 0; ulong sectorSpeedStart = 0;
InitProgress?.Invoke(); InitProgress?.Invoke();
for(ulong i = 0; i < results.Blocks; i += blocksToRead) for(ulong i = 0; i < results.Blocks; i += blocksToRead)
{ {
if(aborted) break; if(aborted)
break;
if(results.Blocks - i < blocksToRead) blocksToRead = (byte)(results.Blocks - i); if(results.Blocks - i < blocksToRead)
blocksToRead = (byte)(results.Blocks - i);
#pragma warning disable RECS0018 // Comparison of floating point numbers with equality operator #pragma warning disable RECS0018 // Comparison of floating point numbers with equality operator
if(currentSpeed > results.MaxSpeed && currentSpeed != 0) results.MaxSpeed = currentSpeed; if(currentSpeed > results.MaxSpeed &&
if(currentSpeed < results.MinSpeed && currentSpeed != 0) results.MinSpeed = currentSpeed; currentSpeed != 0)
results.MaxSpeed = currentSpeed;
if(currentSpeed < results.MinSpeed &&
currentSpeed != 0)
results.MinSpeed = currentSpeed;
#pragma warning restore RECS0018 // Comparison of floating point numbers with equality operator #pragma warning restore RECS0018 // Comparison of floating point numbers with equality operator
UpdateProgress?.Invoke($"Reading sector {i} of {results.Blocks} ({currentSpeed:F3} MiB/sec.)", UpdateProgress?.Invoke($"Reading sector {i} of {results.Blocks} ({currentSpeed:F3} MiB/sec.)",
@@ -143,12 +156,18 @@ namespace DiscImageChef.Core.Devices.Scanning
if(!error) if(!error)
{ {
if(duration >= 500) results.F += blocksToRead; if(duration >= 500)
else if(duration >= 150) results.E += blocksToRead; results.F += blocksToRead;
else if(duration >= 50) results.D += blocksToRead; else if(duration >= 150)
else if(duration >= 10) results.C += blocksToRead; results.E += blocksToRead;
else if(duration >= 3) results.B += blocksToRead; else if(duration >= 50)
else results.A += blocksToRead; results.D += blocksToRead;
else if(duration >= 10)
results.C += blocksToRead;
else if(duration >= 3)
results.B += blocksToRead;
else
results.A += blocksToRead;
ScanTime?.Invoke(i, duration); ScanTime?.Invoke(i, duration);
mhddLog.Write(i, duration); mhddLog.Write(i, duration);
@@ -158,7 +177,9 @@ namespace DiscImageChef.Core.Devices.Scanning
{ {
ScanUnreadable?.Invoke(i); ScanUnreadable?.Invoke(i);
results.Errored += blocksToRead; results.Errored += blocksToRead;
for(ulong b = i; b < i + blocksToRead; b++) results.UnreadableSectors.Add(b);
for(ulong b = i; b < i + blocksToRead; b++)
results.UnreadableSectors.Add(b);
mhddLog.Write(i, duration < 500 ? 65535 : duration); mhddLog.Write(i, duration < 500 ? 65535 : duration);
@@ -168,10 +189,12 @@ namespace DiscImageChef.Core.Devices.Scanning
sectorSpeedStart += blocksToRead; sectorSpeedStart += blocksToRead;
double elapsed = (DateTime.UtcNow - timeSpeedStart).TotalSeconds; double elapsed = (DateTime.UtcNow - timeSpeedStart).TotalSeconds;
if(elapsed < 1) continue;
currentSpeed = sectorSpeedStart * blockSize / (1048576 * elapsed); if(elapsed < 1)
ScanSpeed?.Invoke(i, currentSpeed * 1024); continue;
currentSpeed = (sectorSpeedStart * blockSize) / (1048576 * elapsed);
ScanSpeed?.Invoke(i, currentSpeed * 1024);
sectorSpeedStart = 0; sectorSpeedStart = 0;
timeSpeedStart = DateTime.UtcNow; timeSpeedStart = DateTime.UtcNow;
} }
@@ -179,16 +202,19 @@ namespace DiscImageChef.Core.Devices.Scanning
end = DateTime.UtcNow; end = DateTime.UtcNow;
EndProgress?.Invoke(); EndProgress?.Invoke();
mhddLog.Close(); mhddLog.Close();
ibgLog.Close(dev, results.Blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024, ibgLog.Close(dev, results.Blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024,
blockSize * (double)(results.Blocks + 1) / 1024 / (blockSize * (double)(results.Blocks + 1)) / 1024 /
(results.ProcessingTime / 1000), (results.ProcessingTime / 1000),
devicePath); devicePath);
InitProgress?.Invoke(); InitProgress?.Invoke();
if(ataReader.CanSeekLba) if(ataReader.CanSeekLba)
for(int i = 0; i < SEEK_TIMES; i++) for(int i = 0; i < SEEK_TIMES; i++)
{ {
if(aborted) break; if(aborted)
break;
uint seekPos = (uint)rnd.Next((int)results.Blocks); uint seekPos = (uint)rnd.Next((int)results.Blocks);
@@ -197,8 +223,13 @@ namespace DiscImageChef.Core.Devices.Scanning
ataReader.Seek(seekPos, out seekCur); ataReader.Seek(seekPos, out seekCur);
#pragma warning disable RECS0018 // Comparison of floating point numbers with equality operator #pragma warning disable RECS0018 // Comparison of floating point numbers with equality operator
if(seekCur > results.SeekMax && seekCur != 0) results.SeekMax = seekCur; if(seekCur > results.SeekMax &&
if(seekCur < results.SeekMin && seekCur != 0) results.SeekMin = seekCur; seekCur != 0)
results.SeekMax = seekCur;
if(seekCur < results.SeekMin &&
seekCur != 0)
results.SeekMin = seekCur;
#pragma warning restore RECS0018 // Comparison of floating point numbers with equality operator #pragma warning restore RECS0018 // Comparison of floating point numbers with equality operator
results.SeekTotal += seekCur; results.SeekTotal += seekCur;
@@ -219,34 +250,45 @@ namespace DiscImageChef.Core.Devices.Scanning
DateTime timeSpeedStart = DateTime.UtcNow; DateTime timeSpeedStart = DateTime.UtcNow;
ulong sectorSpeedStart = 0; ulong sectorSpeedStart = 0;
InitProgress?.Invoke(); InitProgress?.Invoke();
for(ushort cy = 0; cy < cylinders; cy++) for(ushort cy = 0; cy < cylinders; cy++)
{ {
for(byte hd = 0; hd < heads; hd++) for(byte hd = 0; hd < heads; hd++)
{ {
for(byte sc = 1; sc < sectors; sc++) for(byte sc = 1; sc < sectors; sc++)
{ {
if(aborted) break; if(aborted)
break;
#pragma warning disable RECS0018 // Comparison of floating point numbers with equality operator #pragma warning disable RECS0018 // Comparison of floating point numbers with equality operator
if(currentSpeed > results.MaxSpeed && currentSpeed != 0) if(currentSpeed > results.MaxSpeed &&
currentSpeed != 0)
results.MaxSpeed = currentSpeed; results.MaxSpeed = currentSpeed;
if(currentSpeed < results.MinSpeed && currentSpeed != 0)
if(currentSpeed < results.MinSpeed &&
currentSpeed != 0)
results.MinSpeed = currentSpeed; results.MinSpeed = currentSpeed;
#pragma warning restore RECS0018 // Comparison of floating point numbers with equality operator #pragma warning restore RECS0018 // Comparison of floating point numbers with equality operator
PulseProgress PulseProgress?.
?.Invoke($"Reading cylinder {cy} head {hd} sector {sc} ({currentSpeed:F3} MiB/sec.)"); Invoke($"Reading cylinder {cy} head {hd} sector {sc} ({currentSpeed:F3} MiB/sec.)");
bool error = ataReader.ReadChs(out cmdBuf, cy, hd, sc, out duration); bool error = ataReader.ReadChs(out cmdBuf, cy, hd, sc, out duration);
if(!error) if(!error)
{ {
if(duration >= 500) results.F += blocksToRead; if(duration >= 500)
else if(duration >= 150) results.E += blocksToRead; results.F += blocksToRead;
else if(duration >= 50) results.D += blocksToRead; else if(duration >= 150)
else if(duration >= 10) results.C += blocksToRead; results.E += blocksToRead;
else if(duration >= 3) results.B += blocksToRead; else if(duration >= 50)
else results.A += blocksToRead; results.D += blocksToRead;
else if(duration >= 10)
results.C += blocksToRead;
else if(duration >= 3)
results.B += blocksToRead;
else
results.A += blocksToRead;
ScanTime?.Invoke(currentBlock, duration); ScanTime?.Invoke(currentBlock, duration);
mhddLog.Write(currentBlock, duration); mhddLog.Write(currentBlock, duration);
@@ -266,10 +308,12 @@ namespace DiscImageChef.Core.Devices.Scanning
currentBlock++; currentBlock++;
double elapsed = (DateTime.UtcNow - timeSpeedStart).TotalSeconds; double elapsed = (DateTime.UtcNow - timeSpeedStart).TotalSeconds;
if(elapsed < 1) continue;
currentSpeed = sectorSpeedStart * blockSize / (1048576 * elapsed); if(elapsed < 1)
ScanSpeed?.Invoke(currentBlock, currentSpeed * 1024); continue;
currentSpeed = (sectorSpeedStart * blockSize) / (1048576 * elapsed);
ScanSpeed?.Invoke(currentBlock, currentSpeed * 1024);
sectorSpeedStart = 0; sectorSpeedStart = 0;
timeSpeedStart = DateTime.UtcNow; timeSpeedStart = DateTime.UtcNow;
} }
@@ -279,29 +323,37 @@ namespace DiscImageChef.Core.Devices.Scanning
end = DateTime.UtcNow; end = DateTime.UtcNow;
EndProgress?.Invoke(); EndProgress?.Invoke();
mhddLog.Close(); mhddLog.Close();
ibgLog.Close(dev, results.Blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024, ibgLog.Close(dev, results.Blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024,
blockSize * (double)(results.Blocks + 1) / 1024 / (blockSize * (double)(results.Blocks + 1)) / 1024 /
(results.ProcessingTime / 1000), (results.ProcessingTime / 1000),
devicePath); devicePath);
InitProgress?.Invoke(); InitProgress?.Invoke();
if(ataReader.CanSeek) if(ataReader.CanSeek)
for(int i = 0; i < SEEK_TIMES; i++) for(int i = 0; i < SEEK_TIMES; i++)
{ {
if(aborted) break; if(aborted)
break;
ushort seekCy = (ushort)rnd.Next(cylinders); ushort seekCy = (ushort)rnd.Next(cylinders);
byte seekHd = (byte)rnd.Next(heads); byte seekHd = (byte)rnd.Next(heads);
byte seekSc = (byte)rnd.Next(sectors); byte seekSc = (byte)rnd.Next(sectors);
PulseProgress PulseProgress?.
?.Invoke($"\rSeeking to cylinder {seekCy}, head {seekHd}, sector {seekSc}...\t\t"); Invoke($"\rSeeking to cylinder {seekCy}, head {seekHd}, sector {seekSc}...\t\t");
ataReader.SeekChs(seekCy, seekHd, seekSc, out seekCur); ataReader.SeekChs(seekCy, seekHd, seekSc, out seekCur);
#pragma warning disable RECS0018 // Comparison of floating point numbers with equality operator #pragma warning disable RECS0018 // Comparison of floating point numbers with equality operator
if(seekCur > results.SeekMax && seekCur != 0) results.SeekMax = seekCur; if(seekCur > results.SeekMax &&
if(seekCur < results.SeekMin && seekCur != 0) results.SeekMin = seekCur; seekCur != 0)
results.SeekMax = seekCur;
if(seekCur < results.SeekMin &&
seekCur != 0)
results.SeekMin = seekCur;
#pragma warning restore RECS0018 // Comparison of floating point numbers with equality operator #pragma warning restore RECS0018 // Comparison of floating point numbers with equality operator
results.SeekTotal += seekCur; results.SeekTotal += seekCur;
@@ -313,13 +365,14 @@ namespace DiscImageChef.Core.Devices.Scanning
results.ProcessingTime /= 1000; results.ProcessingTime /= 1000;
results.TotalTime = (end - start).TotalSeconds; results.TotalTime = (end - start).TotalSeconds;
results.AvgSpeed = blockSize * (double)(results.Blocks + 1) / 1048576 / results.ProcessingTime; results.AvgSpeed = (blockSize * (double)(results.Blocks + 1)) / 1048576 / results.ProcessingTime;
results.SeekTimes = SEEK_TIMES; results.SeekTimes = SEEK_TIMES;
return results; return results;
} }
StoppingErrorMessage?.Invoke("Unable to communicate with ATA device."); StoppingErrorMessage?.Invoke("Unable to communicate with ATA device.");
return results; return results;
} }
} }

View File

@@ -33,6 +33,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading; using System.Threading;
using DiscImageChef.CommonTypes.Structs.Devices.SCSI;
using DiscImageChef.Console; using DiscImageChef.Console;
using DiscImageChef.Core.Logging; using DiscImageChef.Core.Logging;
using DiscImageChef.Decoders.CD; using DiscImageChef.Decoders.CD;
@@ -42,18 +43,16 @@ using DiscImageChef.Devices;
namespace DiscImageChef.Core.Devices.Scanning namespace DiscImageChef.Core.Devices.Scanning
{ {
/// <summary> /// <summary>Implements scanning the media from an SCSI device</summary>
/// Implements scanning the media from an SCSI device
/// </summary>
public partial class MediaScan public partial class MediaScan
{ {
ScanResults Scsi() ScanResults Scsi()
{ {
ScanResults results = new ScanResults(); var results = new ScanResults();
MhddLog mhddLog; MhddLog mhddLog;
IbgLog ibgLog; IbgLog ibgLog;
byte[] senseBuf; byte[] senseBuf;
bool sense = false; bool sense = false;
results.Blocks = 0; results.Blocks = 0;
uint blockSize = 0; uint blockSize = 0;
ushort currentProfile = 0x0001; ushort currentProfile = 0x0001;
@@ -61,20 +60,25 @@ namespace DiscImageChef.Core.Devices.Scanning
if(dev.IsRemovable) if(dev.IsRemovable)
{ {
sense = dev.ScsiTestUnitReady(out senseBuf, dev.Timeout, out _); sense = dev.ScsiTestUnitReady(out senseBuf, dev.Timeout, out _);
if(sense) if(sense)
{ {
InitProgress?.Invoke(); InitProgress?.Invoke();
FixedSense? decSense = Sense.DecodeFixed(senseBuf); FixedSense? decSense = Sense.DecodeFixed(senseBuf);
if(decSense.HasValue) if(decSense.HasValue)
if(decSense.Value.ASC == 0x3A) if(decSense.Value.ASC == 0x3A)
{ {
int leftRetries = 5; int leftRetries = 5;
while(leftRetries > 0) while(leftRetries > 0)
{ {
PulseProgress?.Invoke("Waiting for drive to become ready"); PulseProgress?.Invoke("Waiting for drive to become ready");
Thread.Sleep(2000); Thread.Sleep(2000);
sense = dev.ScsiTestUnitReady(out senseBuf, dev.Timeout, out _); sense = dev.ScsiTestUnitReady(out senseBuf, dev.Timeout, out _);
if(!sense) break;
if(!sense)
break;
leftRetries--; leftRetries--;
} }
@@ -82,59 +86,72 @@ namespace DiscImageChef.Core.Devices.Scanning
if(sense) if(sense)
{ {
StoppingErrorMessage?.Invoke("Please insert media in drive"); StoppingErrorMessage?.Invoke("Please insert media in drive");
return results; return results;
} }
} }
else if(decSense.Value.ASC == 0x04 && decSense.Value.ASCQ == 0x01) else if(decSense.Value.ASC == 0x04 &&
decSense.Value.ASCQ == 0x01)
{ {
int leftRetries = 10; int leftRetries = 10;
while(leftRetries > 0) while(leftRetries > 0)
{ {
PulseProgress?.Invoke("Waiting for drive to become ready"); PulseProgress?.Invoke("Waiting for drive to become ready");
Thread.Sleep(2000); Thread.Sleep(2000);
sense = dev.ScsiTestUnitReady(out senseBuf, dev.Timeout, out _); sense = dev.ScsiTestUnitReady(out senseBuf, dev.Timeout, out _);
if(!sense) break;
if(!sense)
break;
leftRetries--; leftRetries--;
} }
if(sense) if(sense)
{ {
StoppingErrorMessage StoppingErrorMessage?.
?.Invoke($"Error testing unit was ready:\n{Sense.PrettifySense(senseBuf)}"); Invoke($"Error testing unit was ready:\n{Sense.PrettifySense(senseBuf)}");
return results; return results;
} }
} }
// These should be trapped by the OS but seems in some cases they're not // These should be trapped by the OS but seems in some cases they're not
else if(decSense.Value.ASC == 0x28) else if(decSense.Value.ASC == 0x28)
{ {
int leftRetries = 10; int leftRetries = 10;
while(leftRetries > 0) while(leftRetries > 0)
{ {
PulseProgress?.Invoke("Waiting for drive to become ready"); PulseProgress?.Invoke("Waiting for drive to become ready");
Thread.Sleep(2000); Thread.Sleep(2000);
sense = dev.ScsiTestUnitReady(out senseBuf, dev.Timeout, out _); sense = dev.ScsiTestUnitReady(out senseBuf, dev.Timeout, out _);
if(!sense) break;
if(!sense)
break;
leftRetries--; leftRetries--;
} }
if(sense) if(sense)
{ {
StoppingErrorMessage StoppingErrorMessage?.
?.Invoke($"Error testing unit was ready:\n{Sense.PrettifySense(senseBuf)}"); Invoke($"Error testing unit was ready:\n{Sense.PrettifySense(senseBuf)}");
return results; return results;
} }
} }
else else
{ {
StoppingErrorMessage StoppingErrorMessage?.
?.Invoke($"Error testing unit was ready:\n{Sense.PrettifySense(senseBuf)}"); Invoke($"Error testing unit was ready:\n{Sense.PrettifySense(senseBuf)}");
return results; return results;
} }
else else
{ {
StoppingErrorMessage?.Invoke("Unknown testing unit was ready."); StoppingErrorMessage?.Invoke("Unknown testing unit was ready.");
return results; return results;
} }
@@ -154,19 +171,23 @@ namespace DiscImageChef.Core.Devices.Scanning
case PeripheralDeviceTypes.WriteOnceDevice: case PeripheralDeviceTypes.WriteOnceDevice:
scsiReader = new Reader(dev, dev.Timeout, null); scsiReader = new Reader(dev, dev.Timeout, null);
results.Blocks = scsiReader.GetDeviceBlocks(); results.Blocks = scsiReader.GetDeviceBlocks();
if(scsiReader.FindReadCommand()) if(scsiReader.FindReadCommand())
{ {
StoppingErrorMessage?.Invoke("Unable to read medium."); StoppingErrorMessage?.Invoke("Unable to read medium.");
return results; return results;
} }
blockSize = scsiReader.LogicalBlockSize; blockSize = scsiReader.LogicalBlockSize;
if(results.Blocks != 0 && blockSize != 0) if(results.Blocks != 0 &&
blockSize != 0)
{ {
results.Blocks++; results.Blocks++;
UpdateStatus
?.Invoke($"Media has {results.Blocks} blocks of {blockSize} bytes/each. (for a total of {results.Blocks * (ulong)blockSize} bytes)"); UpdateStatus?.
Invoke($"Media has {results.Blocks} blocks of {blockSize} bytes/each. (for a total of {results.Blocks * (ulong)blockSize} bytes)");
} }
break; break;
@@ -174,12 +195,14 @@ namespace DiscImageChef.Core.Devices.Scanning
StoppingErrorMessage?.Invoke("Scanning will never be supported on SCSI Streaming Devices." + StoppingErrorMessage?.Invoke("Scanning will never be supported on SCSI Streaming Devices." +
Environment.NewLine + Environment.NewLine +
"It has no sense to do it, and it will put too much strain on the tape."); "It has no sense to do it, and it will put too much strain on the tape.");
return results; return results;
} }
if(results.Blocks == 0) if(results.Blocks == 0)
{ {
StoppingErrorMessage?.Invoke("Unable to read medium or empty medium present..."); StoppingErrorMessage?.Invoke("Unable to read medium or empty medium present...");
return results; return results;
} }
@@ -190,6 +213,7 @@ namespace DiscImageChef.Core.Devices.Scanning
{ {
sense = dev.GetConfiguration(out byte[] cmdBuf, out senseBuf, 0, MmcGetConfigurationRt.Current, sense = dev.GetConfiguration(out byte[] cmdBuf, out senseBuf, 0, MmcGetConfigurationRt.Current,
dev.Timeout, out _); dev.Timeout, out _);
if(!sense) if(!sense)
{ {
Features.SeparatedFeatures ftr = Features.Separate(cmdBuf); Features.SeparatedFeatures ftr = Features.Separate(cmdBuf);
@@ -207,6 +231,7 @@ namespace DiscImageChef.Core.Devices.Scanning
case 0x0022: break; case 0x0022: break;
default: default:
compactDisc = false; compactDisc = false;
break; break;
} }
} }
@@ -214,13 +239,17 @@ namespace DiscImageChef.Core.Devices.Scanning
if(compactDisc) if(compactDisc)
{ {
currentProfile = 0x0008; currentProfile = 0x0008;
// We discarded all discs that falsify a TOC before requesting a real TOC // We discarded all discs that falsify a TOC before requesting a real TOC
// No TOC, no CD (or an empty one) // No TOC, no CD (or an empty one)
bool tocSense = dev.ReadRawToc(out cmdBuf, out senseBuf, 1, dev.Timeout, out _); bool tocSense = dev.ReadRawToc(out cmdBuf, out senseBuf, 1, dev.Timeout, out _);
if(!tocSense) toc = FullTOC.Decode(cmdBuf);
if(!tocSense)
toc = FullTOC.Decode(cmdBuf);
} }
} }
else compactDisc = false; else
compactDisc = false;
uint blocksToRead = 64; uint blocksToRead = 64;
@@ -245,6 +274,7 @@ namespace DiscImageChef.Core.Devices.Scanning
if(toc == null) if(toc == null)
{ {
StoppingErrorMessage?.Invoke("Error trying to decode TOC..."); StoppingErrorMessage?.Invoke("Error trying to decode TOC...");
return results; return results;
} }
@@ -252,7 +282,8 @@ namespace DiscImageChef.Core.Devices.Scanning
MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None, MmcSubchannel.None, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None, MmcSubchannel.None,
dev.Timeout, out _); dev.Timeout, out _);
if(readcd) UpdateStatus?.Invoke("Using MMC READ CD command."); if(readcd)
UpdateStatus?.Invoke("Using MMC READ CD command.");
start = DateTime.UtcNow; start = DateTime.UtcNow;
@@ -263,16 +294,21 @@ namespace DiscImageChef.Core.Devices.Scanning
sense = dev.ReadCd(out _, out senseBuf, 0, 2352, blocksToRead, MmcSectorTypes.AllTypes, false, sense = dev.ReadCd(out _, out senseBuf, 0, 2352, blocksToRead, MmcSectorTypes.AllTypes, false,
false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None, false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None,
MmcSubchannel.None, dev.Timeout, out _); MmcSubchannel.None, dev.Timeout, out _);
if(dev.Error) blocksToRead /= 2;
if(dev.Error)
blocksToRead /= 2;
} }
if(!dev.Error || blocksToRead == 1) break; if(!dev.Error ||
blocksToRead == 1)
break;
} }
if(dev.Error) if(dev.Error)
{ {
StoppingErrorMessage StoppingErrorMessage?.
?.Invoke($"Device error {dev.LastError} trying to guess ideal transfer length."); Invoke($"Device error {dev.LastError} trying to guess ideal transfer length.");
return results; return results;
} }
@@ -285,17 +321,25 @@ namespace DiscImageChef.Core.Devices.Scanning
ulong sectorSpeedStart = 0; ulong sectorSpeedStart = 0;
InitProgress?.Invoke(); InitProgress?.Invoke();
for(ulong i = 0; i < results.Blocks; i += blocksToRead) for(ulong i = 0; i < results.Blocks; i += blocksToRead)
{ {
if(aborted) break; if(aborted)
break;
double cmdDuration = 0; double cmdDuration = 0;
if(results.Blocks - i < blocksToRead) blocksToRead = (uint)(results.Blocks - i); if(results.Blocks - i < blocksToRead)
blocksToRead = (uint)(results.Blocks - i);
#pragma warning disable RECS0018 // Comparison of floating point numbers with equality operator #pragma warning disable RECS0018 // Comparison of floating point numbers with equality operator
if(currentSpeed > results.MaxSpeed && currentSpeed != 0) results.MaxSpeed = currentSpeed; if(currentSpeed > results.MaxSpeed &&
if(currentSpeed < results.MinSpeed && currentSpeed != 0) results.MinSpeed = currentSpeed; currentSpeed != 0)
results.MaxSpeed = currentSpeed;
if(currentSpeed < results.MinSpeed &&
currentSpeed != 0)
results.MinSpeed = currentSpeed;
#pragma warning restore RECS0018 // Comparison of floating point numbers with equality operator #pragma warning restore RECS0018 // Comparison of floating point numbers with equality operator
UpdateProgress?.Invoke($"Reading sector {i} of {results.Blocks} ({currentSpeed:F3} MiB/sec.)", UpdateProgress?.Invoke($"Reading sector {i} of {results.Blocks} ({currentSpeed:F3} MiB/sec.)",
@@ -306,17 +350,24 @@ namespace DiscImageChef.Core.Devices.Scanning
sense = dev.ReadCd(out _, out senseBuf, (uint)i, 2352, blocksToRead, MmcSectorTypes.AllTypes, sense = dev.ReadCd(out _, out senseBuf, (uint)i, 2352, blocksToRead, MmcSectorTypes.AllTypes,
false, false, true, MmcHeaderCodes.AllHeaders, true, true, false, false, true, MmcHeaderCodes.AllHeaders, true, true,
MmcErrorField.None, MmcSubchannel.None, dev.Timeout, out cmdDuration); MmcErrorField.None, MmcSubchannel.None, dev.Timeout, out cmdDuration);
results.ProcessingTime += cmdDuration; results.ProcessingTime += cmdDuration;
} }
if(!sense) if(!sense)
{ {
if(cmdDuration >= 500) results.F += blocksToRead; if(cmdDuration >= 500)
else if(cmdDuration >= 150) results.E += blocksToRead; results.F += blocksToRead;
else if(cmdDuration >= 50) results.D += blocksToRead; else if(cmdDuration >= 150)
else if(cmdDuration >= 10) results.C += blocksToRead; results.E += blocksToRead;
else if(cmdDuration >= 3) results.B += blocksToRead; else if(cmdDuration >= 50)
else results.A += blocksToRead; results.D += blocksToRead;
else if(cmdDuration >= 10)
results.C += blocksToRead;
else if(cmdDuration >= 3)
results.B += blocksToRead;
else
results.A += blocksToRead;
ScanTime?.Invoke(i, cmdDuration); ScanTime?.Invoke(i, cmdDuration);
mhddLog.Write(i, cmdDuration); mhddLog.Write(i, cmdDuration);
@@ -327,17 +378,21 @@ namespace DiscImageChef.Core.Devices.Scanning
DicConsole.DebugWriteLine("Media-Scan", "READ CD error:\n{0}", Sense.PrettifySense(senseBuf)); DicConsole.DebugWriteLine("Media-Scan", "READ CD error:\n{0}", Sense.PrettifySense(senseBuf));
FixedSense? senseDecoded = Sense.DecodeFixed(senseBuf); FixedSense? senseDecoded = Sense.DecodeFixed(senseBuf);
if(senseDecoded.HasValue) if(senseDecoded.HasValue)
{ {
// TODO: This error happens when changing from track type afaik. Need to solve that more cleanly // TODO: This error happens when changing from track type afaik. Need to solve that more cleanly
// LOGICAL BLOCK ADDRESS OUT OF RANGE // LOGICAL BLOCK ADDRESS OUT OF RANGE
if((senseDecoded.Value.ASC != 0x21 || senseDecoded.Value.ASCQ != 0x00) && if((senseDecoded.Value.ASC != 0x21 || senseDecoded.Value.ASCQ != 0x00) &&
// ILLEGAL MODE FOR THIS TRACK (requesting sectors as-is, this is a firmware misconception when audio sectors // ILLEGAL MODE FOR THIS TRACK (requesting sectors as-is, this is a firmware misconception when audio sectors
// are in a track where subchannel indicates data) // are in a track where subchannel indicates data)
(senseDecoded.Value.ASC != 0x64 || senseDecoded.Value.ASCQ != 0x00)) (senseDecoded.Value.ASC != 0x64 || senseDecoded.Value.ASCQ != 0x00))
{ {
results.Errored += blocksToRead; results.Errored += blocksToRead;
for(ulong b = i; b < i + blocksToRead; b++) results.UnreadableSectors.Add(b);
for(ulong b = i; b < i + blocksToRead; b++)
results.UnreadableSectors.Add(b);
ScanUnreadable?.Invoke(i); ScanUnreadable?.Invoke(i);
mhddLog.Write(i, cmdDuration < 500 ? 65535 : cmdDuration); mhddLog.Write(i, cmdDuration < 500 ? 65535 : cmdDuration);
@@ -349,7 +404,9 @@ namespace DiscImageChef.Core.Devices.Scanning
{ {
ScanUnreadable?.Invoke(i); ScanUnreadable?.Invoke(i);
results.Errored += blocksToRead; results.Errored += blocksToRead;
for(ulong b = i; b < i + blocksToRead; b++) results.UnreadableSectors.Add(b);
for(ulong b = i; b < i + blocksToRead; b++)
results.UnreadableSectors.Add(b);
mhddLog.Write(i, cmdDuration < 500 ? 65535 : cmdDuration); mhddLog.Write(i, cmdDuration < 500 ? 65535 : cmdDuration);
@@ -360,10 +417,12 @@ namespace DiscImageChef.Core.Devices.Scanning
sectorSpeedStart += blocksToRead; sectorSpeedStart += blocksToRead;
double elapsed = (DateTime.UtcNow - timeSpeedStart).TotalSeconds; double elapsed = (DateTime.UtcNow - timeSpeedStart).TotalSeconds;
if(elapsed < 1) continue;
currentSpeed = sectorSpeedStart * blockSize / (1048576 * elapsed); if(elapsed < 1)
ScanSpeed?.Invoke(i, currentSpeed * 1024); continue;
currentSpeed = (sectorSpeedStart * blockSize) / (1048576 * elapsed);
ScanSpeed?.Invoke(i, currentSpeed * 1024);
sectorSpeedStart = 0; sectorSpeedStart = 0;
timeSpeedStart = DateTime.UtcNow; timeSpeedStart = DateTime.UtcNow;
} }
@@ -371,8 +430,9 @@ namespace DiscImageChef.Core.Devices.Scanning
end = DateTime.UtcNow; end = DateTime.UtcNow;
EndProgress?.Invoke(); EndProgress?.Invoke();
mhddLog.Close(); mhddLog.Close();
ibgLog.Close(dev, results.Blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024, ibgLog.Close(dev, results.Blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024,
blockSize * (double)(results.Blocks + 1) / 1024 / (blockSize * (double)(results.Blocks + 1)) / 1024 /
(results.ProcessingTime / 1000), (results.ProcessingTime / 1000),
devicePath); devicePath);
} }
@@ -389,15 +449,23 @@ namespace DiscImageChef.Core.Devices.Scanning
ulong sectorSpeedStart = 0; ulong sectorSpeedStart = 0;
InitProgress?.Invoke(); InitProgress?.Invoke();
for(ulong i = 0; i < results.Blocks; i += blocksToRead) for(ulong i = 0; i < results.Blocks; i += blocksToRead)
{ {
if(aborted) break; if(aborted)
break;
if(results.Blocks - i < blocksToRead) blocksToRead = (uint)(results.Blocks - i); if(results.Blocks - i < blocksToRead)
blocksToRead = (uint)(results.Blocks - i);
#pragma warning disable RECS0018 // Comparison of floating point numbers with equality operator #pragma warning disable RECS0018 // Comparison of floating point numbers with equality operator
if(currentSpeed > results.MaxSpeed && currentSpeed != 0) results.MaxSpeed = currentSpeed; if(currentSpeed > results.MaxSpeed &&
if(currentSpeed < results.MinSpeed && currentSpeed != 0) results.MinSpeed = currentSpeed; currentSpeed != 0)
results.MaxSpeed = currentSpeed;
if(currentSpeed < results.MinSpeed &&
currentSpeed != 0)
results.MinSpeed = currentSpeed;
#pragma warning restore RECS0018 // Comparison of floating point numbers with equality operator #pragma warning restore RECS0018 // Comparison of floating point numbers with equality operator
UpdateProgress?.Invoke($"Reading sector {i} of {results.Blocks} ({currentSpeed:F3} MiB/sec.)", UpdateProgress?.Invoke($"Reading sector {i} of {results.Blocks} ({currentSpeed:F3} MiB/sec.)",
@@ -406,25 +474,35 @@ namespace DiscImageChef.Core.Devices.Scanning
sense = scsiReader.ReadBlocks(out _, i, blocksToRead, out double cmdDuration); sense = scsiReader.ReadBlocks(out _, i, blocksToRead, out double cmdDuration);
results.ProcessingTime += cmdDuration; results.ProcessingTime += cmdDuration;
if(!sense && !dev.Error) if(!sense &&
!dev.Error)
{ {
if(cmdDuration >= 500) results.F += blocksToRead; if(cmdDuration >= 500)
else if(cmdDuration >= 150) results.E += blocksToRead; results.F += blocksToRead;
else if(cmdDuration >= 50) results.D += blocksToRead; else if(cmdDuration >= 150)
else if(cmdDuration >= 10) results.C += blocksToRead; results.E += blocksToRead;
else if(cmdDuration >= 3) results.B += blocksToRead; else if(cmdDuration >= 50)
else results.A += blocksToRead; results.D += blocksToRead;
else if(cmdDuration >= 10)
results.C += blocksToRead;
else if(cmdDuration >= 3)
results.B += blocksToRead;
else
results.A += blocksToRead;
ScanTime?.Invoke(i, cmdDuration); ScanTime?.Invoke(i, cmdDuration);
mhddLog.Write(i, cmdDuration); mhddLog.Write(i, cmdDuration);
ibgLog.Write(i, currentSpeed * 1024); ibgLog.Write(i, currentSpeed * 1024);
} }
// TODO: Separate errors on kind of errors. // TODO: Separate errors on kind of errors.
else else
{ {
ScanUnreadable?.Invoke(i); ScanUnreadable?.Invoke(i);
results.Errored += blocksToRead; results.Errored += blocksToRead;
for(ulong b = i; b < i + blocksToRead; b++) results.UnreadableSectors.Add(b);
for(ulong b = i; b < i + blocksToRead; b++)
results.UnreadableSectors.Add(b);
mhddLog.Write(i, cmdDuration < 500 ? 65535 : cmdDuration); mhddLog.Write(i, cmdDuration < 500 ? 65535 : cmdDuration);
ibgLog.Write(i, 0); ibgLog.Write(i, 0);
@@ -433,10 +511,12 @@ namespace DiscImageChef.Core.Devices.Scanning
sectorSpeedStart += blocksToRead; sectorSpeedStart += blocksToRead;
double elapsed = (DateTime.UtcNow - timeSpeedStart).TotalSeconds; double elapsed = (DateTime.UtcNow - timeSpeedStart).TotalSeconds;
if(elapsed < 1) continue;
currentSpeed = sectorSpeedStart * blockSize / (1048576 * elapsed); if(elapsed < 1)
ScanSpeed?.Invoke(i, currentSpeed * 1024); continue;
currentSpeed = (sectorSpeedStart * blockSize) / (1048576 * elapsed);
ScanSpeed?.Invoke(i, currentSpeed * 1024);
sectorSpeedStart = 0; sectorSpeedStart = 0;
timeSpeedStart = DateTime.UtcNow; timeSpeedStart = DateTime.UtcNow;
} }
@@ -444,8 +524,9 @@ namespace DiscImageChef.Core.Devices.Scanning
end = DateTime.UtcNow; end = DateTime.UtcNow;
EndProgress?.Invoke(); EndProgress?.Invoke();
mhddLog.Close(); mhddLog.Close();
ibgLog.Close(dev, results.Blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024, ibgLog.Close(dev, results.Blocks, blockSize, (end - start).TotalSeconds, currentSpeed * 1024,
blockSize * (double)(results.Blocks + 1) / 1024 / (blockSize * (double)(results.Blocks + 1)) / 1024 /
(results.ProcessingTime / 1000), (results.ProcessingTime / 1000),
devicePath); devicePath);
} }
@@ -455,24 +536,34 @@ namespace DiscImageChef.Core.Devices.Scanning
results.SeekTotal = 0; results.SeekTotal = 0;
const int SEEK_TIMES = 1000; const int SEEK_TIMES = 1000;
Random rnd = new Random(); var rnd = new Random();
InitProgress?.Invoke(); InitProgress?.Invoke();
for(int i = 0; i < SEEK_TIMES; i++) for(int i = 0; i < SEEK_TIMES; i++)
{ {
if(aborted) break; if(aborted)
break;
uint seekPos = (uint)rnd.Next((int)results.Blocks); uint seekPos = (uint)rnd.Next((int)results.Blocks);
PulseProgress?.Invoke($"Seeking to sector {seekPos}...\t\t"); PulseProgress?.Invoke($"Seeking to sector {seekPos}...\t\t");
double seekCur; double seekCur;
if(scsiReader.CanSeek) scsiReader.Seek(seekPos, out seekCur);
else scsiReader.ReadBlock(out _, seekPos, out seekCur); if(scsiReader.CanSeek)
scsiReader.Seek(seekPos, out seekCur);
else
scsiReader.ReadBlock(out _, seekPos, out seekCur);
#pragma warning disable RECS0018 // Comparison of floating point numbers with equality operator #pragma warning disable RECS0018 // Comparison of floating point numbers with equality operator
if(seekCur > results.SeekMax && seekCur != 0) results.SeekMax = seekCur; if(seekCur > results.SeekMax &&
if(seekCur < results.SeekMin && seekCur != 0) results.SeekMin = seekCur; seekCur != 0)
results.SeekMax = seekCur;
if(seekCur < results.SeekMin &&
seekCur != 0)
results.SeekMin = seekCur;
#pragma warning restore RECS0018 // Comparison of floating point numbers with equality operator #pragma warning restore RECS0018 // Comparison of floating point numbers with equality operator
results.SeekTotal += seekCur; results.SeekTotal += seekCur;
@@ -483,7 +574,7 @@ namespace DiscImageChef.Core.Devices.Scanning
results.ProcessingTime /= 1000; results.ProcessingTime /= 1000;
results.TotalTime = (end - start).TotalSeconds; results.TotalTime = (end - start).TotalSeconds;
results.AvgSpeed = blockSize * (double)(results.Blocks + 1) / 1048576 / results.ProcessingTime; results.AvgSpeed = (blockSize * (double)(results.Blocks + 1)) / 1048576 / results.ProcessingTime;
results.SeekTimes = SEEK_TIMES; results.SeekTimes = SEEK_TIMES;
return results; return results;

View File

@@ -36,6 +36,7 @@ using System.Text;
using DiscImageChef.CommonTypes.Enums; using DiscImageChef.CommonTypes.Enums;
using DiscImageChef.CommonTypes.Interfaces; using DiscImageChef.CommonTypes.Interfaces;
using DiscImageChef.CommonTypes.Structs; using DiscImageChef.CommonTypes.Structs;
using DiscImageChef.CommonTypes.Structs.Devices.SCSI;
using DiscImageChef.Console; using DiscImageChef.Console;
using DiscImageChef.Decoders.ATA; using DiscImageChef.Decoders.ATA;
using DiscImageChef.Decoders.Bluray; using DiscImageChef.Decoders.Bluray;
@@ -47,6 +48,7 @@ using DiscImageChef.Decoders.Xbox;
using Schemas; using Schemas;
using DDS = DiscImageChef.Decoders.DVD.DDS; using DDS = DiscImageChef.Decoders.DVD.DDS;
using DMI = DiscImageChef.Decoders.Xbox.DMI; using DMI = DiscImageChef.Decoders.Xbox.DMI;
using Inquiry = DiscImageChef.Decoders.SCSI.Inquiry;
using Session = DiscImageChef.CommonTypes.Structs.Session; using Session = DiscImageChef.CommonTypes.Structs.Session;
using Tuple = DiscImageChef.Decoders.PCMCIA.Tuple; using Tuple = DiscImageChef.Decoders.PCMCIA.Tuple;
@@ -57,55 +59,80 @@ namespace DiscImageChef.Core
public static void PrintImageInfo(IMediaImage imageFormat) public static void PrintImageInfo(IMediaImage imageFormat)
{ {
DicConsole.WriteLine("Image information:"); DicConsole.WriteLine("Image information:");
if(!string.IsNullOrWhiteSpace(imageFormat.Info.Version)) if(!string.IsNullOrWhiteSpace(imageFormat.Info.Version))
DicConsole.WriteLine("Format: {0} version {1}", imageFormat.Format, imageFormat.Info.Version); DicConsole.WriteLine("Format: {0} version {1}", imageFormat.Format, imageFormat.Info.Version);
else DicConsole.WriteLine("Format: {0}", imageFormat.Format); else
DicConsole.WriteLine("Format: {0}", imageFormat.Format);
if(!string.IsNullOrWhiteSpace(imageFormat.Info.Application) && if(!string.IsNullOrWhiteSpace(imageFormat.Info.Application) &&
!string.IsNullOrWhiteSpace(imageFormat.Info.ApplicationVersion)) !string.IsNullOrWhiteSpace(imageFormat.Info.ApplicationVersion))
DicConsole.WriteLine("Was created with {0} version {1}", imageFormat.Info.Application, DicConsole.WriteLine("Was created with {0} version {1}", imageFormat.Info.Application,
imageFormat.Info.ApplicationVersion); imageFormat.Info.ApplicationVersion);
else if(!string.IsNullOrWhiteSpace(imageFormat.Info.Application)) else if(!string.IsNullOrWhiteSpace(imageFormat.Info.Application))
DicConsole.WriteLine("Was created with {0}", imageFormat.Info.Application); DicConsole.WriteLine("Was created with {0}", imageFormat.Info.Application);
DicConsole.WriteLine("Image without headers is {0} bytes long", imageFormat.Info.ImageSize); DicConsole.WriteLine("Image without headers is {0} bytes long", imageFormat.Info.ImageSize);
DicConsole.WriteLine("Contains a media of {0} sectors with a maximum sector size of {1} bytes (if all sectors are of the same size this would be {2} bytes)", DicConsole.WriteLine("Contains a media of {0} sectors with a maximum sector size of {1} bytes (if all sectors are of the same size this would be {2} bytes)",
imageFormat.Info.Sectors, imageFormat.Info.SectorSize, imageFormat.Info.Sectors, imageFormat.Info.SectorSize,
imageFormat.Info.Sectors * imageFormat.Info.SectorSize); imageFormat.Info.Sectors * imageFormat.Info.SectorSize);
if(!string.IsNullOrWhiteSpace(imageFormat.Info.Creator)) if(!string.IsNullOrWhiteSpace(imageFormat.Info.Creator))
DicConsole.WriteLine("Created by: {0}", imageFormat.Info.Creator); DicConsole.WriteLine("Created by: {0}", imageFormat.Info.Creator);
if(imageFormat.Info.CreationTime != DateTime.MinValue) if(imageFormat.Info.CreationTime != DateTime.MinValue)
DicConsole.WriteLine("Created on {0}", imageFormat.Info.CreationTime); DicConsole.WriteLine("Created on {0}", imageFormat.Info.CreationTime);
if(imageFormat.Info.LastModificationTime != DateTime.MinValue) if(imageFormat.Info.LastModificationTime != DateTime.MinValue)
DicConsole.WriteLine("Last modified on {0}", imageFormat.Info.LastModificationTime); DicConsole.WriteLine("Last modified on {0}", imageFormat.Info.LastModificationTime);
DicConsole.WriteLine("Contains a media of type {0} and XML type {1}", imageFormat.Info.MediaType, DicConsole.WriteLine("Contains a media of type {0} and XML type {1}", imageFormat.Info.MediaType,
imageFormat.Info.XmlMediaType); imageFormat.Info.XmlMediaType);
DicConsole.WriteLine("{0} partitions", imageFormat.Info.HasPartitions ? "Has" : "Doesn't have"); DicConsole.WriteLine("{0} partitions", imageFormat.Info.HasPartitions ? "Has" : "Doesn't have");
DicConsole.WriteLine("{0} sessions", imageFormat.Info.HasSessions ? "Has" : "Doesn't have"); DicConsole.WriteLine("{0} sessions", imageFormat.Info.HasSessions ? "Has" : "Doesn't have");
if(!string.IsNullOrWhiteSpace(imageFormat.Info.Comments)) if(!string.IsNullOrWhiteSpace(imageFormat.Info.Comments))
DicConsole.WriteLine("Comments: {0}", imageFormat.Info.Comments); DicConsole.WriteLine("Comments: {0}", imageFormat.Info.Comments);
if(imageFormat.Info.MediaSequence != 0 && imageFormat.Info.LastMediaSequence != 0)
if(imageFormat.Info.MediaSequence != 0 &&
imageFormat.Info.LastMediaSequence != 0)
DicConsole.WriteLine("Media is number {0} on a set of {1} medias", imageFormat.Info.MediaSequence, DicConsole.WriteLine("Media is number {0} on a set of {1} medias", imageFormat.Info.MediaSequence,
imageFormat.Info.LastMediaSequence); imageFormat.Info.LastMediaSequence);
if(!string.IsNullOrWhiteSpace(imageFormat.Info.MediaTitle)) if(!string.IsNullOrWhiteSpace(imageFormat.Info.MediaTitle))
DicConsole.WriteLine("Media title: {0}", imageFormat.Info.MediaTitle); DicConsole.WriteLine("Media title: {0}", imageFormat.Info.MediaTitle);
if(!string.IsNullOrWhiteSpace(imageFormat.Info.MediaManufacturer)) if(!string.IsNullOrWhiteSpace(imageFormat.Info.MediaManufacturer))
DicConsole.WriteLine("Media manufacturer: {0}", imageFormat.Info.MediaManufacturer); DicConsole.WriteLine("Media manufacturer: {0}", imageFormat.Info.MediaManufacturer);
if(!string.IsNullOrWhiteSpace(imageFormat.Info.MediaModel)) if(!string.IsNullOrWhiteSpace(imageFormat.Info.MediaModel))
DicConsole.WriteLine("Media model: {0}", imageFormat.Info.MediaModel); DicConsole.WriteLine("Media model: {0}", imageFormat.Info.MediaModel);
if(!string.IsNullOrWhiteSpace(imageFormat.Info.MediaSerialNumber)) if(!string.IsNullOrWhiteSpace(imageFormat.Info.MediaSerialNumber))
DicConsole.WriteLine("Media serial number: {0}", imageFormat.Info.MediaSerialNumber); DicConsole.WriteLine("Media serial number: {0}", imageFormat.Info.MediaSerialNumber);
if(!string.IsNullOrWhiteSpace(imageFormat.Info.MediaBarcode)) if(!string.IsNullOrWhiteSpace(imageFormat.Info.MediaBarcode))
DicConsole.WriteLine("Media barcode: {0}", imageFormat.Info.MediaBarcode); DicConsole.WriteLine("Media barcode: {0}", imageFormat.Info.MediaBarcode);
if(!string.IsNullOrWhiteSpace(imageFormat.Info.MediaPartNumber)) if(!string.IsNullOrWhiteSpace(imageFormat.Info.MediaPartNumber))
DicConsole.WriteLine("Media part number: {0}", imageFormat.Info.MediaPartNumber); DicConsole.WriteLine("Media part number: {0}", imageFormat.Info.MediaPartNumber);
if(!string.IsNullOrWhiteSpace(imageFormat.Info.DriveManufacturer)) if(!string.IsNullOrWhiteSpace(imageFormat.Info.DriveManufacturer))
DicConsole.WriteLine("Drive manufacturer: {0}", imageFormat.Info.DriveManufacturer); DicConsole.WriteLine("Drive manufacturer: {0}", imageFormat.Info.DriveManufacturer);
if(!string.IsNullOrWhiteSpace(imageFormat.Info.DriveModel)) if(!string.IsNullOrWhiteSpace(imageFormat.Info.DriveModel))
DicConsole.WriteLine("Drive model: {0}", imageFormat.Info.DriveModel); DicConsole.WriteLine("Drive model: {0}", imageFormat.Info.DriveModel);
if(!string.IsNullOrWhiteSpace(imageFormat.Info.DriveSerialNumber)) if(!string.IsNullOrWhiteSpace(imageFormat.Info.DriveSerialNumber))
DicConsole.WriteLine("Drive serial number: {0}", imageFormat.Info.DriveSerialNumber); DicConsole.WriteLine("Drive serial number: {0}", imageFormat.Info.DriveSerialNumber);
if(!string.IsNullOrWhiteSpace(imageFormat.Info.DriveFirmwareRevision)) if(!string.IsNullOrWhiteSpace(imageFormat.Info.DriveFirmwareRevision))
DicConsole.WriteLine("Drive firmware info: {0}", imageFormat.Info.DriveFirmwareRevision); DicConsole.WriteLine("Drive firmware info: {0}", imageFormat.Info.DriveFirmwareRevision);
if(imageFormat.Info.Cylinders > 0 && imageFormat.Info.Heads > 0 &&
if(imageFormat.Info.Cylinders > 0 &&
imageFormat.Info.Heads > 0 &&
imageFormat.Info.SectorsPerTrack > 0 && imageFormat.Info.SectorsPerTrack > 0 &&
imageFormat.Info.XmlMediaType != XmlMediaType.OpticalDisc && imageFormat.Info.XmlMediaType != XmlMediaType.OpticalDisc &&
(!(imageFormat is ITapeImage tapeImage) || !tapeImage.IsTape)) (!(imageFormat is ITapeImage tapeImage) || !tapeImage.IsTape))
@@ -113,19 +140,25 @@ namespace DiscImageChef.Core
imageFormat.Info.Cylinders, imageFormat.Info.Heads, imageFormat.Info.Cylinders, imageFormat.Info.Heads,
imageFormat.Info.SectorsPerTrack); imageFormat.Info.SectorsPerTrack);
if(imageFormat.Info.ReadableMediaTags != null && imageFormat.Info.ReadableMediaTags.Count > 0) if(imageFormat.Info.ReadableMediaTags != null &&
imageFormat.Info.ReadableMediaTags.Count > 0)
{ {
DicConsole.WriteLine("Contains {0} readable media tags:", imageFormat.Info.ReadableMediaTags.Count); DicConsole.WriteLine("Contains {0} readable media tags:", imageFormat.Info.ReadableMediaTags.Count);
foreach(MediaTagType tag in imageFormat.Info.ReadableMediaTags.OrderBy(t => t)) foreach(MediaTagType tag in imageFormat.Info.ReadableMediaTags.OrderBy(t => t))
DicConsole.Write("{0} ", tag); DicConsole.Write("{0} ", tag);
DicConsole.WriteLine(); DicConsole.WriteLine();
} }
if(imageFormat.Info.ReadableSectorTags != null && imageFormat.Info.ReadableSectorTags.Count > 0) if(imageFormat.Info.ReadableSectorTags != null &&
imageFormat.Info.ReadableSectorTags.Count > 0)
{ {
DicConsole.WriteLine("Contains {0} readable sector tags:", imageFormat.Info.ReadableSectorTags.Count); DicConsole.WriteLine("Contains {0} readable sector tags:", imageFormat.Info.ReadableSectorTags.Count);
foreach(SectorTagType tag in imageFormat.Info.ReadableSectorTags.OrderBy(t => t)) foreach(SectorTagType tag in imageFormat.Info.ReadableSectorTags.OrderBy(t => t))
DicConsole.Write("{0} ", tag); DicConsole.Write("{0} ", tag);
DicConsole.WriteLine(); DicConsole.WriteLine();
} }
@@ -139,6 +172,7 @@ namespace DiscImageChef.Core
byte[] inquiry = imageFormat.ReadDiskTag(MediaTagType.SCSI_INQUIRY); byte[] inquiry = imageFormat.ReadDiskTag(MediaTagType.SCSI_INQUIRY);
scsiDeviceType = (PeripheralDeviceTypes)(inquiry[0] & 0x1F); scsiDeviceType = (PeripheralDeviceTypes)(inquiry[0] & 0x1F);
if(inquiry.Length >= 16) if(inquiry.Length >= 16)
{ {
scsiVendorId = new byte[8]; scsiVendorId = new byte[8];
@@ -213,6 +247,7 @@ namespace DiscImageChef.Core
if(toc.Length > 0) if(toc.Length > 0)
{ {
ushort dataLen = Swapping.Swap(BitConverter.ToUInt16(toc, 0)); ushort dataLen = Swapping.Swap(BitConverter.ToUInt16(toc, 0));
if(dataLen + 2 != toc.Length) if(dataLen + 2 != toc.Length)
{ {
byte[] tmp = new byte[toc.Length + 2]; byte[] tmp = new byte[toc.Length + 2];
@@ -236,6 +271,7 @@ namespace DiscImageChef.Core
if(pma.Length > 0) if(pma.Length > 0)
{ {
ushort dataLen = Swapping.Swap(BitConverter.ToUInt16(pma, 0)); ushort dataLen = Swapping.Swap(BitConverter.ToUInt16(pma, 0));
if(dataLen + 2 != pma.Length) if(dataLen + 2 != pma.Length)
{ {
byte[] tmp = new byte[pma.Length + 2]; byte[] tmp = new byte[pma.Length + 2];
@@ -257,6 +293,7 @@ namespace DiscImageChef.Core
byte[] atip = imageFormat.ReadDiskTag(MediaTagType.CD_ATIP); byte[] atip = imageFormat.ReadDiskTag(MediaTagType.CD_ATIP);
uint dataLen = Swapping.Swap(BitConverter.ToUInt32(atip, 0)); uint dataLen = Swapping.Swap(BitConverter.ToUInt32(atip, 0));
if(dataLen + 4 != atip.Length) if(dataLen + 4 != atip.Length)
{ {
byte[] tmp = new byte[atip.Length + 4]; byte[] tmp = new byte[atip.Length + 4];
@@ -279,6 +316,7 @@ namespace DiscImageChef.Core
byte[] cdtext = imageFormat.ReadDiskTag(MediaTagType.CD_TEXT); byte[] cdtext = imageFormat.ReadDiskTag(MediaTagType.CD_TEXT);
uint dataLen = Swapping.Swap(BitConverter.ToUInt32(cdtext, 0)); uint dataLen = Swapping.Swap(BitConverter.ToUInt32(cdtext, 0));
if(dataLen + 4 != cdtext.Length) if(dataLen + 4 != cdtext.Length)
{ {
byte[] tmp = new byte[cdtext.Length + 4]; byte[] tmp = new byte[cdtext.Length + 4];
@@ -302,6 +340,7 @@ namespace DiscImageChef.Core
DicConsole.WriteLine("CompactDisc Media Catalogue Number contained in image: {0}", DicConsole.WriteLine("CompactDisc Media Catalogue Number contained in image: {0}",
Encoding.UTF8.GetString(mcn)); Encoding.UTF8.GetString(mcn));
DicConsole.WriteLine(); DicConsole.WriteLine();
} }
@@ -362,6 +401,7 @@ namespace DiscImageChef.Core
DicConsole.WriteLine("PCMCIA CIS:"); DicConsole.WriteLine("PCMCIA CIS:");
Tuple[] tuples = CIS.GetTuples(cis); Tuple[] tuples = CIS.GetTuples(cis);
if(tuples != null) if(tuples != null)
foreach(Tuple tuple in tuples) foreach(Tuple tuple in tuples)
switch(tuple.Code) switch(tuple.Code)
@@ -371,12 +411,15 @@ namespace DiscImageChef.Core
case TupleCodes.CISTPL_DEVICEGEO: case TupleCodes.CISTPL_DEVICEGEO:
case TupleCodes.CISTPL_DEVICEGEO_A: case TupleCodes.CISTPL_DEVICEGEO_A:
DicConsole.WriteLine("{0}", CIS.PrettifyDeviceGeometryTuple(tuple)); DicConsole.WriteLine("{0}", CIS.PrettifyDeviceGeometryTuple(tuple));
break; break;
case TupleCodes.CISTPL_MANFID: case TupleCodes.CISTPL_MANFID:
DicConsole.WriteLine("{0}", CIS.PrettifyManufacturerIdentificationTuple(tuple)); DicConsole.WriteLine("{0}", CIS.PrettifyManufacturerIdentificationTuple(tuple));
break; break;
case TupleCodes.CISTPL_VERS_1: case TupleCodes.CISTPL_VERS_1:
DicConsole.WriteLine("{0}", CIS.PrettifyLevel1VersionTuple(tuple)); DicConsole.WriteLine("{0}", CIS.PrettifyLevel1VersionTuple(tuple));
break; break;
case TupleCodes.CISTPL_ALTSTR: case TupleCodes.CISTPL_ALTSTR:
case TupleCodes.CISTPL_BAR: case TupleCodes.CISTPL_BAR:
@@ -414,13 +457,16 @@ namespace DiscImageChef.Core
case TupleCodes.CISTPL_VERS_2: case TupleCodes.CISTPL_VERS_2:
DicConsole.DebugWriteLine("Device-Info command", "Found undecoded tuple ID {0}", DicConsole.DebugWriteLine("Device-Info command", "Found undecoded tuple ID {0}",
tuple.Code); tuple.Code);
break; break;
default: default:
DicConsole.DebugWriteLine("Device-Info command", "Found unknown tuple ID 0x{0:X2}", DicConsole.DebugWriteLine("Device-Info command", "Found unknown tuple ID 0x{0:X2}",
(byte)tuple.Code); (byte)tuple.Code);
break; break;
} }
else DicConsole.DebugWriteLine("Device-Info command", "Could not get tuples"); else
DicConsole.DebugWriteLine("Device-Info command", "Could not get tuples");
} }
if(imageFormat.Info.ReadableMediaTags != null && if(imageFormat.Info.ReadableMediaTags != null &&
@@ -521,6 +567,7 @@ namespace DiscImageChef.Core
if(DMI.IsXbox(xdmi)) if(DMI.IsXbox(xdmi))
{ {
DMI.XboxDMI? xmi = DMI.DecodeXbox(xdmi); DMI.XboxDMI? xmi = DMI.DecodeXbox(xdmi);
if(xmi.HasValue) if(xmi.HasValue)
{ {
DicConsole.WriteLine("Xbox DMI contained in image:"); DicConsole.WriteLine("Xbox DMI contained in image:");
@@ -532,6 +579,7 @@ namespace DiscImageChef.Core
if(DMI.IsXbox360(xdmi)) if(DMI.IsXbox360(xdmi))
{ {
DMI.Xbox360DMI? xmi = DMI.DecodeXbox360(xdmi); DMI.Xbox360DMI? xmi = DMI.DecodeXbox360(xdmi);
if(xmi.HasValue) if(xmi.HasValue)
{ {
DicConsole.WriteLine("Xbox 360 DMI contained in image:"); DicConsole.WriteLine("Xbox 360 DMI contained in image:");
@@ -555,16 +603,21 @@ namespace DiscImageChef.Core
{ {
try try
{ {
if(opticalImage.Sessions != null && opticalImage.Sessions.Count > 0) if(opticalImage.Sessions != null &&
opticalImage.Sessions.Count > 0)
{ {
DicConsole.WriteLine("Image sessions:"); DicConsole.WriteLine("Image sessions:");
DicConsole.WriteLine("{0,-9}{1,-13}{2,-12}{3,-12}{4,-12}", "Session", "First track", DicConsole.WriteLine("{0,-9}{1,-13}{2,-12}{3,-12}{4,-12}", "Session", "First track",
"Last track", "Start", "End"); "Last track", "Start", "End");
DicConsole.WriteLine("========================================================="); DicConsole.WriteLine("=========================================================");
foreach(Session session in opticalImage.Sessions) foreach(Session session in opticalImage.Sessions)
DicConsole.WriteLine("{0,-9}{1,-13}{2,-12}{3,-12}{4,-12}", session.SessionSequence, DicConsole.WriteLine("{0,-9}{1,-13}{2,-12}{3,-12}{4,-12}", session.SessionSequence,
session.StartTrack, session.EndTrack, session.StartSector, session.StartTrack, session.EndTrack, session.StartSector,
session.EndSector); session.EndSector);
DicConsole.WriteLine(); DicConsole.WriteLine();
} }
} }
@@ -575,18 +628,23 @@ namespace DiscImageChef.Core
try try
{ {
if(opticalImage.Tracks != null && opticalImage.Tracks.Count > 0) if(opticalImage.Tracks != null &&
opticalImage.Tracks.Count > 0)
{ {
DicConsole.WriteLine("Image tracks:"); DicConsole.WriteLine("Image tracks:");
DicConsole.WriteLine("{0,-7}{1,-17}{2,-6}{3,-8}{4,-12}{5,-8}{6,-12}{7,-12}", "Track", "Type", DicConsole.WriteLine("{0,-7}{1,-17}{2,-6}{3,-8}{4,-12}{5,-8}{6,-12}{7,-12}", "Track", "Type",
"Bps", "Raw bps", "Subchannel", "Pregap", "Start", "End"); "Bps", "Raw bps", "Subchannel", "Pregap", "Start", "End");
DicConsole
.WriteLine("================================================================================="); DicConsole.
WriteLine("=================================================================================");
foreach(Track track in opticalImage.Tracks) foreach(Track track in opticalImage.Tracks)
DicConsole.WriteLine("{0,-7}{1,-17}{2,-6}{3,-8}{4,-12}{5,-8}{6,-12}{7,-12}", DicConsole.WriteLine("{0,-7}{1,-17}{2,-6}{3,-8}{4,-12}{5,-8}{6,-12}{7,-12}",
track.TrackSequence, track.TrackType, track.TrackBytesPerSector, track.TrackSequence, track.TrackType, track.TrackBytesPerSector,
track.TrackRawBytesPerSector, track.TrackSubchannelType, track.TrackRawBytesPerSector, track.TrackSubchannelType,
track.TrackPregap, track.TrackStartSector, track.TrackEndSector); track.TrackPregap, track.TrackStartSector, track.TrackEndSector);
DicConsole.WriteLine(); DicConsole.WriteLine();
} }
} }
@@ -596,7 +654,8 @@ namespace DiscImageChef.Core
} }
} }
if(imageFormat.DumpHardware == null) return; if(imageFormat.DumpHardware == null)
return;
const string MANUFACTURER_STRING = "Manufacturer"; const string MANUFACTURER_STRING = "Manufacturer";
const string MODEL_STRING = "Model"; const string MODEL_STRING = "Model";
@@ -616,19 +675,31 @@ namespace DiscImageChef.Core
foreach(DumpHardwareType dump in imageFormat.DumpHardware) foreach(DumpHardwareType dump in imageFormat.DumpHardware)
{ {
if(dump.Manufacturer?.Length > manufacturerLen) manufacturerLen = dump.Manufacturer.Length; if(dump.Manufacturer?.Length > manufacturerLen)
if(dump.Model?.Length > modelLen) modelLen = dump.Model.Length; manufacturerLen = dump.Manufacturer.Length;
if(dump.Serial?.Length > serialLen) serialLen = dump.Serial.Length;
if(dump.Model?.Length > modelLen)
modelLen = dump.Model.Length;
if(dump.Serial?.Length > serialLen)
serialLen = dump.Serial.Length;
if(dump.Software?.Name?.Length > softwareLen) if(dump.Software?.Name?.Length > softwareLen)
softwareLen = dump.Software.Name.Length; softwareLen = dump.Software.Name.Length;
if(dump.Software?.Version?.Length > versionLen) if(dump.Software?.Version?.Length > versionLen)
versionLen = dump.Software.Version.Length; versionLen = dump.Software.Version.Length;
if(dump.Software?.OperatingSystem?.Length > osLen) if(dump.Software?.OperatingSystem?.Length > osLen)
osLen = dump.Software.OperatingSystem.Length; osLen = dump.Software.OperatingSystem.Length;
foreach(ExtentType extent in dump.Extents) foreach(ExtentType extent in dump.Extents)
{ {
if($"{extent.Start}".Length > sectorLen) sectorLen = $"{extent.Start}".Length; if($"{extent.Start}".Length > sectorLen)
if($"{extent.End}".Length > sectorLen) sectorLen = $"{extent.End}".Length; sectorLen = $"{extent.Start}".Length;
if($"{extent.End}".Length > sectorLen)
sectorLen = $"{extent.End}".Length;
} }
} }
@@ -643,14 +714,20 @@ namespace DiscImageChef.Core
char[] separator = new char[manufacturerLen + modelLen + serialLen + softwareLen + versionLen + osLen + char[] separator = new char[manufacturerLen + modelLen + serialLen + softwareLen + versionLen + osLen +
sectorLen + sectorLen]; sectorLen + sectorLen];
for(int i = 0; i < separator.Length; i++) separator[i] = '=';
for(int i = 0; i < separator.Length; i++)
separator[i] = '=';
string format = string format =
$"{{0,-{manufacturerLen}}}{{1,-{modelLen}}}{{2,-{serialLen}}}{{3,-{softwareLen}}}{{4,-{versionLen}}}{{5,-{osLen}}}{{6,-{sectorLen}}}{{7,-{sectorLen}}}"; $"{{0,-{manufacturerLen}}}{{1,-{modelLen}}}{{2,-{serialLen}}}{{3,-{softwareLen}}}{{4,-{versionLen}}}{{5,-{osLen}}}{{6,-{sectorLen}}}{{7,-{sectorLen}}}";
DicConsole.WriteLine("Dump hardware information:"); DicConsole.WriteLine("Dump hardware information:");
DicConsole.WriteLine(format, MANUFACTURER_STRING, MODEL_STRING, SERIAL_STRING, SOFTWARE_STRING, DicConsole.WriteLine(format, MANUFACTURER_STRING, MODEL_STRING, SERIAL_STRING, SOFTWARE_STRING,
VERSION_STRING, OS_STRING, START_STRING, END_STRING); VERSION_STRING, OS_STRING, START_STRING, END_STRING);
DicConsole.WriteLine(new string(separator)); DicConsole.WriteLine(new string(separator));
foreach(DumpHardwareType dump in imageFormat.DumpHardware) foreach(DumpHardwareType dump in imageFormat.DumpHardware)
{ {
foreach(ExtentType extent in dump.Extents) foreach(ExtentType extent in dump.Extents)

View File

@@ -36,6 +36,7 @@ using System.Linq;
using System.Threading; using System.Threading;
using DiscImageChef.CommonTypes; using DiscImageChef.CommonTypes;
using DiscImageChef.CommonTypes.Enums; using DiscImageChef.CommonTypes.Enums;
using DiscImageChef.CommonTypes.Structs.Devices.SCSI;
using DiscImageChef.Console; using DiscImageChef.Console;
using DiscImageChef.Core.Media.Detection; using DiscImageChef.Core.Media.Detection;
using DiscImageChef.Decoders.CD; using DiscImageChef.Decoders.CD;
@@ -47,6 +48,7 @@ using DiscImageChef.Decoders.Xbox;
using DiscImageChef.Devices; using DiscImageChef.Devices;
using DeviceInfo = DiscImageChef.Core.Devices.Info.DeviceInfo; using DeviceInfo = DiscImageChef.Core.Devices.Info.DeviceInfo;
using DMI = DiscImageChef.Decoders.Xbox.DMI; using DMI = DiscImageChef.Decoders.Xbox.DMI;
using Inquiry = DiscImageChef.Decoders.SCSI.Inquiry;
namespace DiscImageChef.Core.Media.Info namespace DiscImageChef.Core.Media.Info
{ {
@@ -1289,7 +1291,7 @@ namespace DiscImageChef.Core.Media.Info
if(!sense) if(!sense)
{ {
Inquiry.SCSIInquiry? inq = Inquiry.Decode(inqBuffer); var inq = CommonTypes.Structs.Devices.SCSI.Inquiry.Decode(inqBuffer);
if(inq.HasValue && if(inq.HasValue &&
inq.Value.KreonPresent) inq.Value.KreonPresent)

View File

@@ -30,6 +30,7 @@
// Copyright © 2011-2020 Natalia Portillo // Copyright © 2011-2020 Natalia Portillo
// ****************************************************************************/ // ****************************************************************************/
using DiscImageChef.CommonTypes.Structs.Devices.SCSI;
using DiscImageChef.Console; using DiscImageChef.Console;
using DiscImageChef.Decoders.SCSI; using DiscImageChef.Decoders.SCSI;
@@ -41,22 +42,26 @@ namespace DiscImageChef.Core
{ {
DicConsole.WriteLine(Modes.PrettifyModeHeader(decMode.Header, devType)); DicConsole.WriteLine(Modes.PrettifyModeHeader(decMode.Header, devType));
if(decMode.Pages == null) return; if(decMode.Pages == null)
return;
foreach(Modes.ModePage page in decMode.Pages) foreach(Modes.ModePage page in decMode.Pages)
//DicConsole.WriteLine("Page {0:X2}h subpage {1:X2}h is {2} bytes long", page.Page, page.Subpage, page.PageResponse.Length); //DicConsole.WriteLine("Page {0:X2}h subpage {1:X2}h is {2} bytes long", page.Page, page.Subpage, page.PageResponse.Length);
switch(page.Page) switch(page.Page)
{ {
case 0x00: case 0x00:
{ {
if(devType == PeripheralDeviceTypes.MultiMediaDevice && page.Subpage == 0) if(devType == PeripheralDeviceTypes.MultiMediaDevice &&
page.Subpage == 0)
DicConsole.WriteLine(Modes.PrettifyModePage_00_SFF(page.PageResponse)); DicConsole.WriteLine(Modes.PrettifyModePage_00_SFF(page.PageResponse));
else else
{ {
if(page.Subpage != 0) if(page.Subpage != 0)
DicConsole.WriteLine("Found unknown vendor mode page {0:X2}h subpage {1:X2}h", DicConsole.WriteLine("Found unknown vendor mode page {0:X2}h subpage {1:X2}h",
page.Page, page.Subpage); page.Page, page.Subpage);
else DicConsole.WriteLine("Found unknown vendor mode page {0:X2}h", page.Page); else
DicConsole.WriteLine("Found unknown vendor mode page {0:X2}h", page.Page);
} }
break; break;
@@ -67,42 +72,53 @@ namespace DiscImageChef.Core
DicConsole.WriteLine(devType == PeripheralDeviceTypes.MultiMediaDevice DicConsole.WriteLine(devType == PeripheralDeviceTypes.MultiMediaDevice
? Modes.PrettifyModePage_01_MMC(page.PageResponse) ? Modes.PrettifyModePage_01_MMC(page.PageResponse)
: Modes.PrettifyModePage_01(page.PageResponse)); : Modes.PrettifyModePage_01(page.PageResponse));
else goto default; else
goto default;
break; break;
} }
case 0x02: case 0x02:
{ {
if(page.Subpage == 0) DicConsole.WriteLine(Modes.PrettifyModePage_02(page.PageResponse)); if(page.Subpage == 0)
else goto default; DicConsole.WriteLine(Modes.PrettifyModePage_02(page.PageResponse));
else
goto default;
break; break;
} }
case 0x03: case 0x03:
{ {
if(page.Subpage == 0) DicConsole.WriteLine(Modes.PrettifyModePage_03(page.PageResponse)); if(page.Subpage == 0)
else goto default; DicConsole.WriteLine(Modes.PrettifyModePage_03(page.PageResponse));
else
goto default;
break; break;
} }
case 0x04: case 0x04:
{ {
if(page.Subpage == 0) DicConsole.WriteLine(Modes.PrettifyModePage_04(page.PageResponse)); if(page.Subpage == 0)
else goto default; DicConsole.WriteLine(Modes.PrettifyModePage_04(page.PageResponse));
else
goto default;
break; break;
} }
case 0x05: case 0x05:
{ {
if(page.Subpage == 0) DicConsole.WriteLine(Modes.PrettifyModePage_05(page.PageResponse)); if(page.Subpage == 0)
else goto default; DicConsole.WriteLine(Modes.PrettifyModePage_05(page.PageResponse));
else
goto default;
break; break;
} }
case 0x06: case 0x06:
{ {
if(page.Subpage == 0) DicConsole.WriteLine(Modes.PrettifyModePage_06(page.PageResponse)); if(page.Subpage == 0)
else goto default; DicConsole.WriteLine(Modes.PrettifyModePage_06(page.PageResponse));
else
goto default;
break; break;
} }
@@ -112,51 +128,64 @@ namespace DiscImageChef.Core
DicConsole.WriteLine(devType == PeripheralDeviceTypes.MultiMediaDevice DicConsole.WriteLine(devType == PeripheralDeviceTypes.MultiMediaDevice
? Modes.PrettifyModePage_07_MMC(page.PageResponse) ? Modes.PrettifyModePage_07_MMC(page.PageResponse)
: Modes.PrettifyModePage_07(page.PageResponse)); : Modes.PrettifyModePage_07(page.PageResponse));
else goto default; else
goto default;
break; break;
} }
case 0x08: case 0x08:
{ {
if(page.Subpage == 0) DicConsole.WriteLine(Modes.PrettifyModePage_08(page.PageResponse)); if(page.Subpage == 0)
else goto default; DicConsole.WriteLine(Modes.PrettifyModePage_08(page.PageResponse));
else
goto default;
break; break;
} }
case 0x0A: case 0x0A:
{ {
if(page.Subpage == 0) DicConsole.WriteLine(Modes.PrettifyModePage_0A(page.PageResponse)); if(page.Subpage == 0)
DicConsole.WriteLine(Modes.PrettifyModePage_0A(page.PageResponse));
else if(page.Subpage == 1) else if(page.Subpage == 1)
DicConsole.WriteLine(Modes.PrettifyModePage_0A_S01(page.PageResponse)); DicConsole.WriteLine(Modes.PrettifyModePage_0A_S01(page.PageResponse));
else goto default; else
goto default;
break; break;
} }
case 0x0B: case 0x0B:
{ {
if(page.Subpage == 0) DicConsole.WriteLine(Modes.PrettifyModePage_0B(page.PageResponse)); if(page.Subpage == 0)
else goto default; DicConsole.WriteLine(Modes.PrettifyModePage_0B(page.PageResponse));
else
goto default;
break; break;
} }
case 0x0D: case 0x0D:
{ {
if(page.Subpage == 0) DicConsole.WriteLine(Modes.PrettifyModePage_0D(page.PageResponse)); if(page.Subpage == 0)
else goto default; DicConsole.WriteLine(Modes.PrettifyModePage_0D(page.PageResponse));
else
goto default;
break; break;
} }
case 0x0E: case 0x0E:
{ {
if(page.Subpage == 0) DicConsole.WriteLine(Modes.PrettifyModePage_0E(page.PageResponse)); if(page.Subpage == 0)
else goto default; DicConsole.WriteLine(Modes.PrettifyModePage_0E(page.PageResponse));
else
goto default;
break; break;
} }
case 0x0F: case 0x0F:
{ {
if(page.Subpage == 0) DicConsole.WriteLine(Modes.PrettifyModePage_0F(page.PageResponse)); if(page.Subpage == 0)
else goto default; DicConsole.WriteLine(Modes.PrettifyModePage_0F(page.PageResponse));
else
goto default;
break; break;
} }
@@ -166,14 +195,17 @@ namespace DiscImageChef.Core
DicConsole.WriteLine(devType == PeripheralDeviceTypes.SequentialAccess DicConsole.WriteLine(devType == PeripheralDeviceTypes.SequentialAccess
? Modes.PrettifyModePage_10_SSC(page.PageResponse) ? Modes.PrettifyModePage_10_SSC(page.PageResponse)
: Modes.PrettifyModePage_10(page.PageResponse)); : Modes.PrettifyModePage_10(page.PageResponse));
else goto default; else
goto default;
break; break;
} }
case 0x11: case 0x11:
{ {
if(page.Subpage == 0) DicConsole.WriteLine(Modes.PrettifyModePage_11(page.PageResponse)); if(page.Subpage == 0)
else goto default; DicConsole.WriteLine(Modes.PrettifyModePage_11(page.PageResponse));
else
goto default;
break; break;
} }
@@ -181,24 +213,30 @@ namespace DiscImageChef.Core
case 0x13: case 0x13:
case 0x14: case 0x14:
{ {
if(page.Subpage == 0) DicConsole.WriteLine(Modes.PrettifyModePage_12_13_14(page.PageResponse)); if(page.Subpage == 0)
else goto default; DicConsole.WriteLine(Modes.PrettifyModePage_12_13_14(page.PageResponse));
else
goto default;
break; break;
} }
case 0x1A: case 0x1A:
{ {
if(page.Subpage == 0) DicConsole.WriteLine(Modes.PrettifyModePage_1A(page.PageResponse)); if(page.Subpage == 0)
DicConsole.WriteLine(Modes.PrettifyModePage_1A(page.PageResponse));
else if(page.Subpage == 1) else if(page.Subpage == 1)
DicConsole.WriteLine(Modes.PrettifyModePage_1A_S01(page.PageResponse)); DicConsole.WriteLine(Modes.PrettifyModePage_1A_S01(page.PageResponse));
else goto default; else
goto default;
break; break;
} }
case 0x1B: case 0x1B:
{ {
if(page.Subpage == 0) DicConsole.WriteLine(Modes.PrettifyModePage_1B(page.PageResponse)); if(page.Subpage == 0)
else goto default; DicConsole.WriteLine(Modes.PrettifyModePage_1B(page.PageResponse));
else
goto default;
break; break;
} }
@@ -210,14 +248,17 @@ namespace DiscImageChef.Core
: Modes.PrettifyModePage_1C(page.PageResponse)); : Modes.PrettifyModePage_1C(page.PageResponse));
else if(page.Subpage == 1) else if(page.Subpage == 1)
DicConsole.WriteLine(Modes.PrettifyModePage_1C_S01(page.PageResponse)); DicConsole.WriteLine(Modes.PrettifyModePage_1C_S01(page.PageResponse));
else goto default; else
goto default;
break; break;
} }
case 0x1D: case 0x1D:
{ {
if(page.Subpage == 0) DicConsole.WriteLine(Modes.PrettifyModePage_1D(page.PageResponse)); if(page.Subpage == 0)
else goto default; DicConsole.WriteLine(Modes.PrettifyModePage_1D(page.PageResponse));
else
goto default;
break; break;
} }
@@ -225,7 +266,8 @@ namespace DiscImageChef.Core
{ {
if(StringHandlers.CToString(vendorId).Trim() == "CERTANCE") if(StringHandlers.CToString(vendorId).Trim() == "CERTANCE")
DicConsole.WriteLine(Modes.PrettifyCertanceModePage_21(page.PageResponse)); DicConsole.WriteLine(Modes.PrettifyCertanceModePage_21(page.PageResponse));
else goto default; else
goto default;
break; break;
} }
@@ -233,7 +275,8 @@ namespace DiscImageChef.Core
{ {
if(StringHandlers.CToString(vendorId).Trim() == "CERTANCE") if(StringHandlers.CToString(vendorId).Trim() == "CERTANCE")
DicConsole.WriteLine(Modes.PrettifyCertanceModePage_22(page.PageResponse)); DicConsole.WriteLine(Modes.PrettifyCertanceModePage_22(page.PageResponse));
else goto default; else
goto default;
break; break;
} }
@@ -241,14 +284,17 @@ namespace DiscImageChef.Core
{ {
if(StringHandlers.CToString(vendorId).Trim() == "IBM") if(StringHandlers.CToString(vendorId).Trim() == "IBM")
DicConsole.WriteLine(Modes.PrettifyIBMModePage_24(page.PageResponse)); DicConsole.WriteLine(Modes.PrettifyIBMModePage_24(page.PageResponse));
else goto default; else
goto default;
break; break;
} }
case 0x2A: case 0x2A:
{ {
if(page.Subpage == 0) DicConsole.WriteLine(Modes.PrettifyModePage_2A(page.PageResponse)); if(page.Subpage == 0)
else goto default; DicConsole.WriteLine(Modes.PrettifyModePage_2A(page.PageResponse));
else
goto default;
break; break;
} }
@@ -256,7 +302,8 @@ namespace DiscImageChef.Core
{ {
if(StringHandlers.CToString(vendorId).Trim() == "IBM") if(StringHandlers.CToString(vendorId).Trim() == "IBM")
DicConsole.WriteLine(Modes.PrettifyIBMModePage_2F(page.PageResponse)); DicConsole.WriteLine(Modes.PrettifyIBMModePage_2F(page.PageResponse));
else goto default; else
goto default;
break; break;
} }
@@ -264,7 +311,8 @@ namespace DiscImageChef.Core
{ {
if(Modes.IsAppleModePage_30(page.PageResponse)) if(Modes.IsAppleModePage_30(page.PageResponse))
DicConsole.WriteLine("Drive identifies as Apple OEM drive"); DicConsole.WriteLine("Drive identifies as Apple OEM drive");
else goto default; else
goto default;
break; break;
} }
@@ -272,7 +320,8 @@ namespace DiscImageChef.Core
{ {
if(StringHandlers.CToString(vendorId).Trim() == "HP") if(StringHandlers.CToString(vendorId).Trim() == "HP")
DicConsole.WriteLine(Modes.PrettifyHPModePage_3B(page.PageResponse)); DicConsole.WriteLine(Modes.PrettifyHPModePage_3B(page.PageResponse));
else goto default; else
goto default;
break; break;
} }
@@ -280,7 +329,8 @@ namespace DiscImageChef.Core
{ {
if(StringHandlers.CToString(vendorId).Trim() == "HP") if(StringHandlers.CToString(vendorId).Trim() == "HP")
DicConsole.WriteLine(Modes.PrettifyHPModePage_3C(page.PageResponse)); DicConsole.WriteLine(Modes.PrettifyHPModePage_3C(page.PageResponse));
else goto default; else
goto default;
break; break;
} }
@@ -290,7 +340,8 @@ namespace DiscImageChef.Core
DicConsole.WriteLine(Modes.PrettifyIBMModePage_3D(page.PageResponse)); DicConsole.WriteLine(Modes.PrettifyIBMModePage_3D(page.PageResponse));
else if(StringHandlers.CToString(vendorId).Trim() == "HP") else if(StringHandlers.CToString(vendorId).Trim() == "HP")
DicConsole.WriteLine(Modes.PrettifyHPModePage_3D(page.PageResponse)); DicConsole.WriteLine(Modes.PrettifyHPModePage_3D(page.PageResponse));
else goto default; else
goto default;
break; break;
} }
@@ -300,7 +351,8 @@ namespace DiscImageChef.Core
DicConsole.WriteLine(Modes.PrettifyFujitsuModePage_3E(page.PageResponse)); DicConsole.WriteLine(Modes.PrettifyFujitsuModePage_3E(page.PageResponse));
else if(StringHandlers.CToString(vendorId).Trim() == "HP") else if(StringHandlers.CToString(vendorId).Trim() == "HP")
DicConsole.WriteLine(Modes.PrettifyHPModePage_3E(page.PageResponse)); DicConsole.WriteLine(Modes.PrettifyHPModePage_3E(page.PageResponse));
else goto default; else
goto default;
break; break;
} }
@@ -309,7 +361,9 @@ namespace DiscImageChef.Core
if(page.Subpage != 0) if(page.Subpage != 0)
DicConsole.WriteLine("Found unknown mode page {0:X2}h subpage {1:X2}h", page.Page, DicConsole.WriteLine("Found unknown mode page {0:X2}h subpage {1:X2}h", page.Page,
page.Subpage); page.Subpage);
else DicConsole.WriteLine("Found unknown mode page {0:X2}h", page.Page); else
DicConsole.WriteLine("Found unknown mode page {0:X2}h", page.Page);
break; break;
} }
} }

View File

@@ -681,7 +681,7 @@ namespace DiscImageChef.Core
if(image.Info.ReadableMediaTags.Contains(MediaTagType.ATA_IDENTIFY)) if(image.Info.ReadableMediaTags.Contains(MediaTagType.ATA_IDENTIFY))
{ {
Identify.IdentifyDevice? ataId = Identify.Decode(image.ReadDiskTag(MediaTagType.ATA_IDENTIFY)); CommonTypes.Structs.Devices.ATA.Identify.IdentifyDevice? ataId = CommonTypes.Structs.Devices.ATA.Identify.Decode(image.ReadDiskTag(MediaTagType.ATA_IDENTIFY));
if(ataId.HasValue) if(ataId.HasValue)
if(ataId.Value.CurrentCylinders > 0 && if(ataId.Value.CurrentCylinders > 0 &&

View File

@@ -37,7 +37,8 @@ using System.Linq;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using DiscImageChef.CommonTypes.Enums; using DiscImageChef.CommonTypes.Enums;
using DiscImageChef.CommonTypes.Interop; using DiscImageChef.CommonTypes.Interop;
using DiscImageChef.Decoders.ATA; using DiscImageChef.CommonTypes.Structs.Devices.ATA;
using DiscImageChef.CommonTypes.Structs.Devices.SCSI;
using DiscImageChef.Decoders.SCSI; using DiscImageChef.Decoders.SCSI;
using DiscImageChef.Decoders.SCSI.MMC; using DiscImageChef.Decoders.SCSI.MMC;
using DiscImageChef.Decoders.SecureDigital; using DiscImageChef.Decoders.SecureDigital;
@@ -50,6 +51,7 @@ using FileAttributes = DiscImageChef.Devices.Windows.FileAttributes;
using FileFlags = DiscImageChef.Devices.Linux.FileFlags; using FileFlags = DiscImageChef.Devices.Linux.FileFlags;
using FileMode = DiscImageChef.Devices.Windows.FileMode; using FileMode = DiscImageChef.Devices.Windows.FileMode;
using FileShare = DiscImageChef.Devices.Windows.FileShare; using FileShare = DiscImageChef.Devices.Windows.FileShare;
using Inquiry = DiscImageChef.CommonTypes.Structs.Devices.SCSI.Inquiry;
using PlatformID = DiscImageChef.CommonTypes.Interop.PlatformID; using PlatformID = DiscImageChef.CommonTypes.Interop.PlatformID;
using VendorString = DiscImageChef.Decoders.SecureDigital.VendorString; using VendorString = DiscImageChef.Decoders.SecureDigital.VendorString;
@@ -761,7 +763,7 @@ namespace DiscImageChef.Devices
if(!scsiSense) if(!scsiSense)
{ {
Inquiry.SCSIInquiry? inquiry = Inquiry.Decode(inqBuf); Inquiry? inquiry = Inquiry.Decode(inqBuf);
Type = DeviceType.SCSI; Type = DeviceType.SCSI;
bool serialSense = ScsiInquiry(out inqBuf, out _, 0x80); bool serialSense = ScsiInquiry(out inqBuf, out _, 0x80);

View File

@@ -32,211 +32,156 @@
using DiscImageChef.CommonTypes.Enums; using DiscImageChef.CommonTypes.Enums;
using DiscImageChef.CommonTypes.Interop; using DiscImageChef.CommonTypes.Interop;
using DiscImageChef.Decoders.SCSI; using DiscImageChef.CommonTypes.Structs.Devices.SCSI;
namespace DiscImageChef.Devices namespace DiscImageChef.Devices
{ {
public partial class Device public partial class Device
{ {
private readonly ushort usbVendor; readonly ushort usbVendor;
private readonly ushort usbProduct; readonly ushort usbProduct;
private readonly ulong firewireGuid; readonly ulong firewireGuid;
private readonly uint firewireModel; readonly uint firewireModel;
private readonly uint firewireVendor; readonly uint firewireVendor;
// MMC and SecureDigital, values that need to be get with card idle, something that may // 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. // not be possible to do but usually is already done by the SDHCI driver.
private readonly byte[] cachedCsd; readonly byte[] cachedCsd;
private readonly byte[] cachedCid; readonly byte[] cachedCid;
private readonly byte[] cachedScr; readonly byte[] cachedScr;
private readonly byte[] cachedOcr; readonly byte[] cachedOcr;
/// <summary> /// <summary>Gets the Platform ID for this device</summary>
/// Gets the Platform ID for this device
/// </summary>
/// <value>The Platform ID</value> /// <value>The Platform ID</value>
public PlatformID PlatformId { get; } public PlatformID PlatformId { get; }
/// <summary> /// <summary>Gets the file handle representing this device</summary>
/// Gets the file handle representing this device
/// </summary>
/// <value>The file handle</value> /// <value>The file handle</value>
public object FileHandle { get; private set; } public object FileHandle { get; private set; }
/// <summary> /// <summary>Gets or sets the standard timeout for commands sent to this device</summary>
/// Gets or sets the standard timeout for commands sent to this device
/// </summary>
/// <value>The timeout in seconds</value> /// <value>The timeout in seconds</value>
public uint Timeout { get; } public uint Timeout { get; }
/// <summary> /// <summary>Gets a value indicating whether this <see cref="Device" /> is in error.</summary>
/// Gets a value indicating whether this <see cref="Device" /> is in error.
/// </summary>
/// <value><c>true</c> if error; otherwise, <c>false</c>.</value> /// <value><c>true</c> if error; otherwise, <c>false</c>.</value>
public bool Error { get; private set; } public bool Error { get; private set; }
/// <summary> /// <summary>Gets the last error number.</summary>
/// Gets the last error number.
/// </summary>
/// <value>The last error.</value> /// <value>The last error.</value>
public int LastError { get; private set; } public int LastError { get; private set; }
/// <summary> /// <summary>Gets the device type.</summary>
/// Gets the device type.
/// </summary>
/// <value>The device type.</value> /// <value>The device type.</value>
public DeviceType Type { get; } public DeviceType Type { get; }
/// <summary> /// <summary>Gets the device's manufacturer</summary>
/// Gets the device's manufacturer
/// </summary>
/// <value>The manufacturer.</value> /// <value>The manufacturer.</value>
public string Manufacturer { get; } public string Manufacturer { get; }
/// <summary> /// <summary>Gets the device model</summary>
/// Gets the device model
/// </summary>
/// <value>The model.</value> /// <value>The model.</value>
public string Model { get; } public string Model { get; }
/// <summary> /// <summary>Gets the device's firmware version.</summary>
/// Gets the device's firmware version.
/// </summary>
/// <value>The firmware version.</value> /// <value>The firmware version.</value>
public string FirmwareRevision { get; } public string FirmwareRevision { get; }
/// <summary> /// <summary>Gets the device's serial number.</summary>
/// Gets the device's serial number.
/// </summary>
/// <value>The serial number.</value> /// <value>The serial number.</value>
public string Serial { get; } public string Serial { get; }
/// <summary> /// <summary>Gets the device's SCSI peripheral device type</summary>
/// Gets the device's SCSI peripheral device type
/// </summary>
/// <value>The SCSI peripheral device type.</value> /// <value>The SCSI peripheral device type.</value>
public PeripheralDeviceTypes ScsiType { get; } public PeripheralDeviceTypes ScsiType { get; }
/// <summary> /// <summary>Gets a value indicating whether this device's media is removable.</summary>
/// Gets a value indicating whether this device's media is removable.
/// </summary>
/// <value><c>true</c> if this device's media is removable; otherwise, <c>false</c>.</value> /// <value><c>true</c> if this device's media is removable; otherwise, <c>false</c>.</value>
public bool IsRemovable { get; } public bool IsRemovable { get; }
/// <summary> /// <summary>Gets a value indicating whether this device is attached via USB.</summary>
/// Gets a value indicating whether this device is attached via USB.
/// </summary>
/// <value><c>true</c> if this device is attached via USB; otherwise, <c>false</c>.</value> /// <value><c>true</c> if this device is attached via USB; otherwise, <c>false</c>.</value>
public bool IsUsb { get; } public bool IsUsb { get; }
/// <summary> /// <summary>Gets the USB vendor ID.</summary>
/// Gets the USB vendor ID.
/// </summary>
/// <value>The USB vendor ID.</value> /// <value>The USB vendor ID.</value>
public ushort UsbVendorId => usbVendor; public ushort UsbVendorId => usbVendor;
/// <summary> /// <summary>Gets the USB product ID.</summary>
/// Gets the USB product ID.
/// </summary>
/// <value>The USB product ID.</value> /// <value>The USB product ID.</value>
public ushort UsbProductId => usbProduct; public ushort UsbProductId => usbProduct;
/// <summary> /// <summary>Gets the USB descriptors.</summary>
/// Gets the USB descriptors.
/// </summary>
/// <value>The USB descriptors.</value> /// <value>The USB descriptors.</value>
public byte[] UsbDescriptors { get; } public byte[] UsbDescriptors { get; }
/// <summary> /// <summary>Gets the USB manufacturer string.</summary>
/// Gets the USB manufacturer string.
/// </summary>
/// <value>The USB manufacturer string.</value> /// <value>The USB manufacturer string.</value>
public string UsbManufacturerString { get; } public string UsbManufacturerString { get; }
/// <summary> /// <summary>Gets the USB product string.</summary>
/// Gets the USB product string.
/// </summary>
/// <value>The USB product string.</value> /// <value>The USB product string.</value>
public string UsbProductString { get; } public string UsbProductString { get; }
/// <summary> /// <summary>Gets the USB serial string.</summary>
/// Gets the USB serial string.
/// </summary>
/// <value>The USB serial string.</value> /// <value>The USB serial string.</value>
public string UsbSerialString { get; } public string UsbSerialString { get; }
/// <summary> /// <summary>Gets a value indicating whether this device is attached via FireWire.</summary>
/// Gets a value indicating whether this device is attached via FireWire.
/// </summary>
/// <value><c>true</c> if this device is attached via FireWire; otherwise, <c>false</c>.</value> /// <value><c>true</c> if this device is attached via FireWire; otherwise, <c>false</c>.</value>
public bool IsFireWire { get; } public bool IsFireWire { get; }
/// <summary> /// <summary>Gets the FireWire GUID</summary>
/// Gets the FireWire GUID
/// </summary>
/// <value>The FireWire GUID.</value> /// <value>The FireWire GUID.</value>
public ulong FireWireGuid => firewireGuid; public ulong FireWireGuid => firewireGuid;
/// <summary> /// <summary>Gets the FireWire model number</summary>
/// Gets the FireWire model number
/// </summary>
/// <value>The FireWire model.</value> /// <value>The FireWire model.</value>
public uint FireWireModel => firewireModel; public uint FireWireModel => firewireModel;
/// <summary> /// <summary>Gets the FireWire model name.</summary>
/// Gets the FireWire model name.
/// </summary>
/// <value>The FireWire model name.</value> /// <value>The FireWire model name.</value>
public string FireWireModelName { get; } public string FireWireModelName { get; }
/// <summary> /// <summary>Gets the FireWire vendor number.</summary>
/// Gets the FireWire vendor number.
/// </summary>
/// <value>The FireWire vendor number.</value> /// <value>The FireWire vendor number.</value>
public uint FireWireVendor => firewireVendor; public uint FireWireVendor => firewireVendor;
/// <summary> /// <summary>Gets the FireWire vendor name.</summary>
/// Gets the FireWire vendor name.
/// </summary>
/// <value>The FireWire vendor name.</value> /// <value>The FireWire vendor name.</value>
public string FireWireVendorName { get; } public string FireWireVendorName { get; }
/// <summary> /// <summary>Gets a value indicating whether this device is a CompactFlash device.</summary>
/// Gets a value indicating whether this device is a CompactFlash device.
/// </summary>
/// <value><c>true</c> if this device is a CompactFlash device; otherwise, <c>false</c>.</value> /// <value><c>true</c> if this device is a CompactFlash device; otherwise, <c>false</c>.</value>
public bool IsCompactFlash { get; } public bool IsCompactFlash { get; }
/// <summary> /// <summary>Gets a value indicating whether this device is a PCMCIA device.</summary>
/// Gets a value indicating whether this device is a PCMCIA device.
/// </summary>
/// <value><c>true</c> if this device is a PCMCIA device; otherwise, <c>false</c>.</value> /// <value><c>true</c> if this device is a PCMCIA device; otherwise, <c>false</c>.</value>
public bool IsPcmcia { get; } public bool IsPcmcia { get; }
/// <summary> /// <summary>Contains the PCMCIA CIS if applicable</summary>
/// Contains the PCMCIA CIS if applicable
/// </summary>
public byte[] Cis { get; } public byte[] Cis { get; }
private readonly Remote.Remote _remote; readonly Remote.Remote _remote;
private bool? _isRemoteAdmin; bool? _isRemoteAdmin;
public bool IsRemoteAdmin public bool IsRemoteAdmin
{ {
get get
{ {
if (_isRemoteAdmin is null) _isRemoteAdmin = _remote.IsRoot; if(_isRemoteAdmin is null)
_isRemoteAdmin = _remote.IsRoot;
return _isRemoteAdmin == true; return _isRemoteAdmin == true;
} }
} }
public bool IsRemote => _remote != null; public bool IsRemote => _remote != null;
public string RemoteApplication => _remote?.ServerApplication; public string RemoteApplication => _remote?.ServerApplication;
public string RemoteVersion => _remote?.ServerVersion; public string RemoteVersion => _remote?.ServerVersion;
public string RemoteOperatingSystem => _remote?.ServerOperatingSystem; public string RemoteOperatingSystem => _remote?.ServerOperatingSystem;
public string RemoteOperatingSystemVersion => _remote?.ServerOperatingSystemVersion; public string RemoteOperatingSystemVersion => _remote?.ServerOperatingSystemVersion;
public string RemoteArchitecture => _remote?.ServerArchitecture; public string RemoteArchitecture => _remote?.ServerArchitecture;
public int RemoteProtocolVersion => _remote?.ServerProtocolVersion ?? 0; public int RemoteProtocolVersion => _remote?.ServerProtocolVersion ?? 0;
} }
} }

View File

@@ -35,17 +35,15 @@ using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using DiscImageChef.Decoders.ATA; using DiscImageChef.CommonTypes.Structs.Devices.ATA;
using DiscImageChef.Decoders.SCSI; using DiscImageChef.CommonTypes.Structs.Devices.SCSI;
using static DiscImageChef.Devices.FreeBSD.Extern; using static DiscImageChef.Devices.FreeBSD.Extern;
namespace DiscImageChef.Devices.FreeBSD namespace DiscImageChef.Devices.FreeBSD
{ {
static class ListDevices internal static class ListDevices
{ {
/// <summary> /// <summary>Gets a list of all known storage devices on FreeBSD</summary>
/// Gets a list of all known storage devices on FreeBSD
/// </summary>
/// <returns>List of devices</returns> /// <returns>List of devices</returns>
internal static DeviceInfo[] GetList() internal static DeviceInfo[] GetList()
{ {
@@ -54,15 +52,16 @@ namespace DiscImageChef.Devices.FreeBSD
foreach(string passDevice in passDevices) foreach(string passDevice in passDevices)
{ {
DeviceInfo deviceInfo = new DeviceInfo(); var deviceInfo = new DeviceInfo();
IntPtr dev = cam_open_device(passDevice, FileFlags.ReadWrite); IntPtr dev = cam_open_device(passDevice, FileFlags.ReadWrite);
CamDevice camDevice = (CamDevice)Marshal.PtrToStructure(dev, typeof(CamDevice)); var camDevice = (CamDevice)Marshal.PtrToStructure(dev, typeof(CamDevice));
IntPtr ccbPtr = cam_getccb(dev); IntPtr ccbPtr = cam_getccb(dev);
if(ccbPtr.ToInt64() == 0) continue; if(ccbPtr.ToInt64() == 0)
continue;
CcbGetdev cgd = (CcbGetdev)Marshal.PtrToStructure(ccbPtr, typeof(CcbGetdev)); var cgd = (CcbGetdev)Marshal.PtrToStructure(ccbPtr, typeof(CcbGetdev));
cgd.ccb_h.func_code = XptOpcode.XptGdevType; cgd.ccb_h.func_code = XptOpcode.XptGdevType;
@@ -73,6 +72,7 @@ namespace DiscImageChef.Devices.FreeBSD
if(error < 0) if(error < 0)
{ {
cam_freeccb(ccbPtr); cam_freeccb(ccbPtr);
continue; continue;
} }
@@ -96,6 +96,7 @@ namespace DiscImageChef.Devices.FreeBSD
// Little-endian FreeBSD gives it resorted // Little-endian FreeBSD gives it resorted
// Big-endian FreeBSD, no idea // Big-endian FreeBSD, no idea
byte[] atadTneid = new byte[512]; byte[] atadTneid = new byte[512];
for(int aIndex = 0; aIndex < 512; aIndex += 2) for(int aIndex = 0; aIndex < 512; aIndex += 2)
{ {
atadTneid[aIndex] = cgd.ident_data[aIndex + 1]; atadTneid[aIndex] = cgd.ident_data[aIndex + 1];
@@ -103,6 +104,7 @@ namespace DiscImageChef.Devices.FreeBSD
} }
Identify.IdentifyDevice? idt = Identify.Decode(atadTneid); Identify.IdentifyDevice? idt = Identify.Decode(atadTneid);
if(idt.HasValue) if(idt.HasValue)
{ {
string[] separated = idt.Value.Model.Split(' '); string[] separated = idt.Value.Model.Split(' ');
@@ -123,12 +125,15 @@ namespace DiscImageChef.Devices.FreeBSD
deviceInfo.Supported = simName != "ata"; deviceInfo.Supported = simName != "ata";
} }
if(cgd.protocol == CamProto.ProtoAtapi) goto case CamProto.ProtoScsi; if(cgd.protocol == CamProto.ProtoAtapi)
goto case CamProto.ProtoScsi;
break; break;
} }
case CamProto.ProtoScsi: case CamProto.ProtoScsi:
{ {
Inquiry.SCSIInquiry? inq = Inquiry.Decode(cgd.inq_data); Inquiry? inq = Inquiry.Decode(cgd.inq_data);
if(inq.HasValue) if(inq.HasValue)
{ {
deviceInfo.Vendor = StringHandlers.CToString(inq.Value.VendorIdentification).Trim(); deviceInfo.Vendor = StringHandlers.CToString(inq.Value.VendorIdentification).Trim();
@@ -142,11 +147,13 @@ namespace DiscImageChef.Devices.FreeBSD
case CamProto.ProtoNvme: case CamProto.ProtoNvme:
deviceInfo.Bus = "NVMe"; deviceInfo.Bus = "NVMe";
deviceInfo.Supported = false; deviceInfo.Supported = false;
break; break;
case CamProto.ProtoMmcsd: case CamProto.ProtoMmcsd:
deviceInfo.Model = "Unknown card"; deviceInfo.Model = "Unknown card";
deviceInfo.Bus = "MMC/SD"; deviceInfo.Bus = "MMC/SD";
deviceInfo.Supported = false; deviceInfo.Supported = false;
break; break;
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -33,31 +33,33 @@
using System; using System;
using DiscImageChef.CommonTypes; using DiscImageChef.CommonTypes;
using DiscImageChef.CommonTypes.Enums; using DiscImageChef.CommonTypes.Enums;
using DiscImageChef.Decoders.ATA; using DiscImageChef.CommonTypes.Structs.Devices.ATA;
using DiscImageChef.Decoders.SCSI; using DiscImageChef.CommonTypes.Structs.Devices.SCSI;
using DiscImageChef.Decoders.SecureDigital; using DiscImageChef.Decoders.SecureDigital;
using DiscImageChef.Helpers; using DiscImageChef.Helpers;
using VendorString = DiscImageChef.Decoders.SecureDigital.VendorString;
namespace DiscImageChef.DiscImages namespace DiscImageChef.DiscImages
{ {
public partial class DiscImageChef public partial class DiscImageChef
{ {
/// <summary> /// <summary>Checks for media tags that may contain metadata and sets it up if not already set</summary>
/// Checks for media tags that may contain metadata and sets it up if not already set
/// </summary>
void SetMetadataFromTags() void SetMetadataFromTags()
{ {
// Search for SecureDigital CID // Search for SecureDigital CID
if(mediaTags.TryGetValue(MediaTagType.SD_CID, out byte[] sdCid)) if(mediaTags.TryGetValue(MediaTagType.SD_CID, out byte[] sdCid))
{ {
CID decoded = Decoders.SecureDigital.Decoders.DecodeCID(sdCid); CID decoded = Decoders.SecureDigital.Decoders.DecodeCID(sdCid);
if(string.IsNullOrWhiteSpace(imageInfo.DriveManufacturer)) if(string.IsNullOrWhiteSpace(imageInfo.DriveManufacturer))
imageInfo.DriveManufacturer = VendorString.Prettify(decoded.Manufacturer); imageInfo.DriveManufacturer = VendorString.Prettify(decoded.Manufacturer);
if(string.IsNullOrWhiteSpace(imageInfo.DriveModel)) imageInfo.DriveModel = decoded.ProductName;
if(string.IsNullOrWhiteSpace(imageInfo.DriveModel))
imageInfo.DriveModel = decoded.ProductName;
if(string.IsNullOrWhiteSpace(imageInfo.DriveFirmwareRevision)) if(string.IsNullOrWhiteSpace(imageInfo.DriveFirmwareRevision))
imageInfo.DriveFirmwareRevision = imageInfo.DriveFirmwareRevision =
$"{(decoded.ProductRevision & 0xF0) >> 4:X2}.{decoded.ProductRevision & 0x0F:X2}"; $"{(decoded.ProductRevision & 0xF0) >> 4:X2}.{decoded.ProductRevision & 0x0F:X2}";
if(string.IsNullOrWhiteSpace(imageInfo.DriveSerialNumber)) if(string.IsNullOrWhiteSpace(imageInfo.DriveSerialNumber))
imageInfo.DriveSerialNumber = $"{decoded.ProductSerialNumber}"; imageInfo.DriveSerialNumber = $"{decoded.ProductSerialNumber}";
} }
@@ -66,12 +68,17 @@ namespace DiscImageChef.DiscImages
if(mediaTags.TryGetValue(MediaTagType.MMC_CID, out byte[] mmcCid)) if(mediaTags.TryGetValue(MediaTagType.MMC_CID, out byte[] mmcCid))
{ {
Decoders.MMC.CID decoded = Decoders.MMC.Decoders.DecodeCID(mmcCid); Decoders.MMC.CID decoded = Decoders.MMC.Decoders.DecodeCID(mmcCid);
if(string.IsNullOrWhiteSpace(imageInfo.DriveManufacturer)) if(string.IsNullOrWhiteSpace(imageInfo.DriveManufacturer))
imageInfo.DriveManufacturer = Decoders.MMC.VendorString.Prettify(decoded.Manufacturer); imageInfo.DriveManufacturer = Decoders.MMC.VendorString.Prettify(decoded.Manufacturer);
if(string.IsNullOrWhiteSpace(imageInfo.DriveModel)) imageInfo.DriveModel = decoded.ProductName;
if(string.IsNullOrWhiteSpace(imageInfo.DriveModel))
imageInfo.DriveModel = decoded.ProductName;
if(string.IsNullOrWhiteSpace(imageInfo.DriveFirmwareRevision)) if(string.IsNullOrWhiteSpace(imageInfo.DriveFirmwareRevision))
imageInfo.DriveFirmwareRevision = imageInfo.DriveFirmwareRevision =
$"{(decoded.ProductRevision & 0xF0) >> 4:X2}.{decoded.ProductRevision & 0x0F:X2}"; $"{(decoded.ProductRevision & 0xF0) >> 4:X2}.{decoded.ProductRevision & 0x0F:X2}";
if(string.IsNullOrWhiteSpace(imageInfo.DriveSerialNumber)) if(string.IsNullOrWhiteSpace(imageInfo.DriveSerialNumber))
imageInfo.DriveSerialNumber = $"{decoded.ProductSerialNumber}"; imageInfo.DriveSerialNumber = $"{decoded.ProductSerialNumber}";
} }
@@ -79,15 +86,18 @@ namespace DiscImageChef.DiscImages
// Search for SCSI INQUIRY // Search for SCSI INQUIRY
if(mediaTags.TryGetValue(MediaTagType.SCSI_INQUIRY, out byte[] scsiInquiry)) if(mediaTags.TryGetValue(MediaTagType.SCSI_INQUIRY, out byte[] scsiInquiry))
{ {
Inquiry.SCSIInquiry? nullableInquiry = Inquiry.Decode(scsiInquiry); Inquiry? nullableInquiry = Inquiry.Decode(scsiInquiry);
if(nullableInquiry.HasValue) if(nullableInquiry.HasValue)
{ {
Inquiry.SCSIInquiry inquiry = nullableInquiry.Value; Inquiry inquiry = nullableInquiry.Value;
if(string.IsNullOrWhiteSpace(imageInfo.DriveManufacturer)) if(string.IsNullOrWhiteSpace(imageInfo.DriveManufacturer))
imageInfo.DriveManufacturer = StringHandlers.CToString(inquiry.VendorIdentification)?.Trim(); imageInfo.DriveManufacturer = StringHandlers.CToString(inquiry.VendorIdentification)?.Trim();
if(string.IsNullOrWhiteSpace(imageInfo.DriveModel)) if(string.IsNullOrWhiteSpace(imageInfo.DriveModel))
imageInfo.DriveModel = StringHandlers.CToString(inquiry.ProductIdentification)?.Trim(); imageInfo.DriveModel = StringHandlers.CToString(inquiry.ProductIdentification)?.Trim();
if(string.IsNullOrWhiteSpace(imageInfo.DriveFirmwareRevision)) if(string.IsNullOrWhiteSpace(imageInfo.DriveFirmwareRevision))
imageInfo.DriveFirmwareRevision = imageInfo.DriveFirmwareRevision =
StringHandlers.CToString(inquiry.ProductRevisionLevel)?.Trim(); StringHandlers.CToString(inquiry.ProductRevisionLevel)?.Trim();
@@ -95,29 +105,34 @@ namespace DiscImageChef.DiscImages
} }
// Search for ATA or ATAPI IDENTIFY // Search for ATA or ATAPI IDENTIFY
if(!mediaTags.TryGetValue(MediaTagType.ATA_IDENTIFY, out byte[] ataIdentify) && if(!mediaTags.TryGetValue(MediaTagType.ATA_IDENTIFY, out byte[] ataIdentify) &&
!mediaTags.TryGetValue(MediaTagType.ATAPI_IDENTIFY, out ataIdentify)) return; !mediaTags.TryGetValue(MediaTagType.ATAPI_IDENTIFY, out ataIdentify))
return;
Identify.IdentifyDevice? nullableIdentify = Decoders.ATA.Identify.Decode(ataIdentify); Identify.IdentifyDevice? nullableIdentify = CommonTypes.Structs.Devices.ATA.Identify.Decode(ataIdentify);
if(!nullableIdentify.HasValue) return; if(!nullableIdentify.HasValue)
return;
Identify.IdentifyDevice identify = nullableIdentify.Value; Identify.IdentifyDevice identify = nullableIdentify.Value;
string[] separated = identify.Model.Split(' '); string[] separated = identify.Model.Split(' ');
if(separated.Length == 1) if(separated.Length == 1)
if(string.IsNullOrWhiteSpace(imageInfo.DriveModel)) imageInfo.DriveModel = separated[0]; if(string.IsNullOrWhiteSpace(imageInfo.DriveModel))
imageInfo.DriveModel = separated[0];
else else
{ {
if(string.IsNullOrWhiteSpace(imageInfo.DriveManufacturer)) if(string.IsNullOrWhiteSpace(imageInfo.DriveManufacturer))
imageInfo.DriveManufacturer = separated[0]; imageInfo.DriveManufacturer = separated[0];
if(string.IsNullOrWhiteSpace(imageInfo.DriveModel)) if(string.IsNullOrWhiteSpace(imageInfo.DriveModel))
imageInfo.DriveModel = separated[separated.Length - 1]; imageInfo.DriveModel = separated[separated.Length - 1];
} }
if(string.IsNullOrWhiteSpace(imageInfo.DriveFirmwareRevision)) if(string.IsNullOrWhiteSpace(imageInfo.DriveFirmwareRevision))
imageInfo.DriveFirmwareRevision = identify.FirmwareRevision; imageInfo.DriveFirmwareRevision = identify.FirmwareRevision;
if(string.IsNullOrWhiteSpace(imageInfo.DriveSerialNumber)) if(string.IsNullOrWhiteSpace(imageInfo.DriveSerialNumber))
imageInfo.DriveSerialNumber = identify.SerialNumber; imageInfo.DriveSerialNumber = identify.SerialNumber;
} }
@@ -225,9 +240,11 @@ namespace DiscImageChef.DiscImages
// Gets a DDT entry // Gets a DDT entry
ulong GetDdtEntry(ulong sectorAddress) ulong GetDdtEntry(ulong sectorAddress)
{ {
if(inMemoryDdt) return userDataDdt[sectorAddress]; if(inMemoryDdt)
return userDataDdt[sectorAddress];
if(ddtEntryCache.TryGetValue(sectorAddress, out ulong entry)) return entry; if(ddtEntryCache.TryGetValue(sectorAddress, out ulong entry))
return entry;
long oldPosition = imageStream.Position; long oldPosition = imageStream.Position;
imageStream.Position = outMemoryDdtPosition + Marshal.SizeOf<DdtHeader>(); imageStream.Position = outMemoryDdtPosition + Marshal.SizeOf<DdtHeader>();
@@ -237,9 +254,11 @@ namespace DiscImageChef.DiscImages
imageStream.Position = oldPosition; imageStream.Position = oldPosition;
entry = BitConverter.ToUInt64(temp, 0); entry = BitConverter.ToUInt64(temp, 0);
if(ddtEntryCache.Count >= MAX_DDT_ENTRY_CACHE) ddtEntryCache.Clear(); if(ddtEntryCache.Count >= MAX_DDT_ENTRY_CACHE)
ddtEntryCache.Clear();
ddtEntryCache.Add(sectorAddress, entry); ddtEntryCache.Add(sectorAddress, entry);
return entry; return entry;
} }
@@ -248,8 +267,11 @@ namespace DiscImageChef.DiscImages
{ {
if(inMemoryDdt) if(inMemoryDdt)
{ {
if(IsTape) tapeDdt[sectorAddress] = pointer; if(IsTape)
else userDataDdt[sectorAddress] = pointer; tapeDdt[sectorAddress] = pointer;
else
userDataDdt[sectorAddress] = pointer;
return; return;
} }

View File

@@ -37,7 +37,7 @@ using DiscImageChef.CommonTypes;
using DiscImageChef.CommonTypes.Enums; using DiscImageChef.CommonTypes.Enums;
using DiscImageChef.CommonTypes.Exceptions; using DiscImageChef.CommonTypes.Exceptions;
using DiscImageChef.CommonTypes.Interfaces; using DiscImageChef.CommonTypes.Interfaces;
using DiscImageChef.Decoders.ATA; using DiscImageChef.CommonTypes.Structs.Devices.ATA;
using DiscImageChef.Helpers; using DiscImageChef.Helpers;
namespace DiscImageChef.DiscImages namespace DiscImageChef.DiscImages
@@ -54,7 +54,8 @@ namespace DiscImageChef.DiscImages
RsIdeHeader hdr = Marshal.ByteArrayToStructureLittleEndian<RsIdeHeader>(hdrB); RsIdeHeader hdr = Marshal.ByteArrayToStructureLittleEndian<RsIdeHeader>(hdrB);
if(!hdr.magic.SequenceEqual(signature)) return false; if(!hdr.magic.SequenceEqual(signature))
return false;
dataOff = hdr.dataOff; dataOff = hdr.dataOff;
@@ -72,7 +73,7 @@ namespace DiscImageChef.DiscImages
{ {
identify = new byte[512]; identify = new byte[512];
Array.Copy(hdr.identify, 0, identify, 0, hdr.identify.Length); Array.Copy(hdr.identify, 0, identify, 0, hdr.identify.Length);
Identify.IdentifyDevice? ataId = Decoders.ATA.Identify.Decode(identify); Identify.IdentifyDevice? ataId = CommonTypes.Structs.Devices.ATA.Identify.Decode(identify);
if(ataId.HasValue) if(ataId.HasValue)
{ {
@@ -88,7 +89,9 @@ namespace DiscImageChef.DiscImages
} }
} }
if(imageInfo.Cylinders == 0 || imageInfo.Heads == 0 || imageInfo.SectorsPerTrack == 0) if(imageInfo.Cylinders == 0 ||
imageInfo.Heads == 0 ||
imageInfo.SectorsPerTrack == 0)
{ {
imageInfo.Cylinders = (uint)(imageInfo.Sectors / 16 / 63); imageInfo.Cylinders = (uint)(imageInfo.Sectors / 16 / 63);
imageInfo.Heads = 16; imageInfo.Heads = 16;
@@ -114,7 +117,7 @@ namespace DiscImageChef.DiscImages
Stream stream = rsIdeImageFilter.GetDataForkStream(); Stream stream = rsIdeImageFilter.GetDataForkStream();
stream.Seek((long)(dataOff + sectorAddress * imageInfo.SectorSize), SeekOrigin.Begin); stream.Seek((long)(dataOff + (sectorAddress * imageInfo.SectorSize)), SeekOrigin.Begin);
stream.Read(buffer, 0, (int)(length * imageInfo.SectorSize)); stream.Read(buffer, 0, (int)(length * imageInfo.SectorSize));
@@ -123,11 +126,13 @@ namespace DiscImageChef.DiscImages
public byte[] ReadDiskTag(MediaTagType tag) public byte[] ReadDiskTag(MediaTagType tag)
{ {
if(!imageInfo.ReadableMediaTags.Contains(tag) || tag != MediaTagType.ATA_IDENTIFY) if(!imageInfo.ReadableMediaTags.Contains(tag) ||
tag != MediaTagType.ATA_IDENTIFY)
throw new FeatureUnsupportedImageException("Feature not supported by image format"); throw new FeatureUnsupportedImageException("Feature not supported by image format");
byte[] buffer = new byte[512]; byte[] buffer = new byte[512];
Array.Copy(identify, 0, buffer, 0, 512); Array.Copy(identify, 0, buffer, 0, 512);
return buffer; return buffer;
} }
} }

View File

@@ -37,7 +37,7 @@ using System.Linq;
using DiscImageChef.CommonTypes; using DiscImageChef.CommonTypes;
using DiscImageChef.CommonTypes.Enums; using DiscImageChef.CommonTypes.Enums;
using DiscImageChef.CommonTypes.Structs; using DiscImageChef.CommonTypes.Structs;
using DiscImageChef.Decoders.ATA; using DiscImageChef.CommonTypes.Structs.Devices.ATA;
using DiscImageChef.Helpers; using DiscImageChef.Helpers;
using Schemas; using Schemas;
using Version = DiscImageChef.CommonTypes.Interop.Version; using Version = DiscImageChef.CommonTypes.Interop.Version;
@@ -47,37 +47,49 @@ namespace DiscImageChef.DiscImages
public partial class RsIde public partial class RsIde
{ {
public bool Create(string path, MediaType mediaType, Dictionary<string, string> options, ulong sectors, public bool Create(string path, MediaType mediaType, Dictionary<string, string> options, ulong sectors,
uint sectorSize) uint sectorSize)
{ {
if(sectorSize != 256 && sectorSize != 512) if(sectorSize != 256 &&
sectorSize != 512)
{ {
ErrorMessage = "Unsupported sector size"; ErrorMessage = "Unsupported sector size";
return false; return false;
} }
if(sectors > 63 * 16 * 1024) if(sectors > 63 * 16 * 1024)
{ {
ErrorMessage = "Too many sectors"; ErrorMessage = "Too many sectors";
return false; return false;
} }
if(!SupportedMediaTypes.Contains(mediaType)) if(!SupportedMediaTypes.Contains(mediaType))
{ {
ErrorMessage = $"Unsupport media format {mediaType}"; ErrorMessage = $"Unsupport media format {mediaType}";
return false; return false;
} }
imageInfo = new ImageInfo {MediaType = mediaType, SectorSize = sectorSize, Sectors = sectors}; imageInfo = new ImageInfo
{
MediaType = mediaType, SectorSize = sectorSize, Sectors = sectors
};
try { writingStream = new FileStream(path, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None); } try
{
writingStream = new FileStream(path, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);
}
catch(IOException e) catch(IOException e)
{ {
ErrorMessage = $"Could not create new image file, exception {e.Message}"; ErrorMessage = $"Could not create new image file, exception {e.Message}";
return false; return false;
} }
IsWriting = true; IsWriting = true;
ErrorMessage = null; ErrorMessage = null;
return true; return true;
} }
@@ -86,17 +98,20 @@ namespace DiscImageChef.DiscImages
if(tag != MediaTagType.ATA_IDENTIFY) if(tag != MediaTagType.ATA_IDENTIFY)
{ {
ErrorMessage = $"Unsupported media tag {tag}."; ErrorMessage = $"Unsupported media tag {tag}.";
return false; return false;
} }
if(!IsWriting) if(!IsWriting)
{ {
ErrorMessage = "Tried to write on a non-writable image"; ErrorMessage = "Tried to write on a non-writable image";
return false; return false;
} }
identify = new byte[106]; identify = new byte[106];
Array.Copy(data, 0, identify, 0, 106); Array.Copy(data, 0, identify, 0, 106);
return true; return true;
} }
@@ -105,26 +120,31 @@ namespace DiscImageChef.DiscImages
if(!IsWriting) if(!IsWriting)
{ {
ErrorMessage = "Tried to write on a non-writable image"; ErrorMessage = "Tried to write on a non-writable image";
return false; return false;
} }
if(data.Length != imageInfo.SectorSize) if(data.Length != imageInfo.SectorSize)
{ {
ErrorMessage = "Incorrect data size"; ErrorMessage = "Incorrect data size";
return false; return false;
} }
if(sectorAddress >= imageInfo.Sectors) if(sectorAddress >= imageInfo.Sectors)
{ {
ErrorMessage = "Tried to write past image size"; ErrorMessage = "Tried to write past image size";
return false; return false;
} }
writingStream.Seek((long)((ulong)Marshal.SizeOf<RsIdeHeader>() + sectorAddress * imageInfo.SectorSize), writingStream.Seek((long)((ulong)Marshal.SizeOf<RsIdeHeader>() + (sectorAddress * imageInfo.SectorSize)),
SeekOrigin.Begin); SeekOrigin.Begin);
writingStream.Write(data, 0, data.Length); writingStream.Write(data, 0, data.Length);
ErrorMessage = ""; ErrorMessage = "";
return true; return true;
} }
@@ -133,38 +153,45 @@ namespace DiscImageChef.DiscImages
if(!IsWriting) if(!IsWriting)
{ {
ErrorMessage = "Tried to write on a non-writable image"; ErrorMessage = "Tried to write on a non-writable image";
return false; return false;
} }
if(data.Length % imageInfo.SectorSize != 0) if(data.Length % imageInfo.SectorSize != 0)
{ {
ErrorMessage = "Incorrect data size"; ErrorMessage = "Incorrect data size";
return false; return false;
} }
if(sectorAddress + length > imageInfo.Sectors) if(sectorAddress + length > imageInfo.Sectors)
{ {
ErrorMessage = "Tried to write past image size"; ErrorMessage = "Tried to write past image size";
return false; return false;
} }
writingStream.Seek((long)((ulong)Marshal.SizeOf<RsIdeHeader>() + sectorAddress * imageInfo.SectorSize), writingStream.Seek((long)((ulong)Marshal.SizeOf<RsIdeHeader>() + (sectorAddress * imageInfo.SectorSize)),
SeekOrigin.Begin); SeekOrigin.Begin);
writingStream.Write(data, 0, data.Length); writingStream.Write(data, 0, data.Length);
ErrorMessage = ""; ErrorMessage = "";
return true; return true;
} }
public bool WriteSectorLong(byte[] data, ulong sectorAddress) public bool WriteSectorLong(byte[] data, ulong sectorAddress)
{ {
ErrorMessage = "Writing sectors with tags is not supported."; ErrorMessage = "Writing sectors with tags is not supported.";
return false; return false;
} }
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length) public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length)
{ {
ErrorMessage = "Writing sectors with tags is not supported."; ErrorMessage = "Writing sectors with tags is not supported.";
return false; return false;
} }
@@ -173,6 +200,7 @@ namespace DiscImageChef.DiscImages
if(!IsWriting) if(!IsWriting)
{ {
ErrorMessage = "Image is not opened for writing"; ErrorMessage = "Image is not opened for writing";
return false; return false;
} }
@@ -194,52 +222,53 @@ namespace DiscImageChef.DiscImages
imageInfo.Cylinders = (uint)(imageInfo.Sectors / imageInfo.Heads / imageInfo.SectorsPerTrack); imageInfo.Cylinders = (uint)(imageInfo.Sectors / imageInfo.Heads / imageInfo.SectorsPerTrack);
if(imageInfo.Cylinders == 0 && imageInfo.Heads == 0 && imageInfo.SectorsPerTrack == 0) break; if(imageInfo.Cylinders == 0 &&
imageInfo.Heads == 0 &&
imageInfo.SectorsPerTrack == 0)
break;
} }
} }
RsIdeHeader header = new RsIdeHeader var header = new RsIdeHeader
{ {
magic = signature, magic = signature, identify = new byte[106], dataOff = (ushort)Marshal.SizeOf<RsIdeHeader>(),
identify = new byte[106], revision = 1, reserved = new byte[11]
dataOff = (ushort)Marshal.SizeOf<RsIdeHeader>(),
revision = 1,
reserved = new byte[11]
}; };
if(imageInfo.SectorSize == 256) header.flags = RsIdeFlags.HalfSectors;
if(imageInfo.SectorSize == 256)
header.flags = RsIdeFlags.HalfSectors;
if(identify == null) if(identify == null)
{ {
Identify.IdentifyDevice ataId = new Identify.IdentifyDevice var ataId = new Identify.IdentifyDevice
{ {
GeneralConfiguration = GeneralConfiguration =
Decoders.ATA.Identify.GeneralConfigurationBit.UltraFastIDE | CommonTypes.Structs.Devices.ATA.Identify.GeneralConfigurationBit.UltraFastIDE |
Decoders.ATA.Identify.GeneralConfigurationBit.Fixed | CommonTypes.Structs.Devices.ATA.Identify.GeneralConfigurationBit.Fixed |
Decoders.ATA.Identify.GeneralConfigurationBit.NotMFM | CommonTypes.Structs.Devices.ATA.Identify.GeneralConfigurationBit.NotMFM |
Decoders.ATA.Identify.GeneralConfigurationBit.SoftSector, CommonTypes.Structs.Devices.ATA.Identify.GeneralConfigurationBit.SoftSector,
Cylinders = (ushort)imageInfo.Cylinders, Cylinders = (ushort)imageInfo.Cylinders, Heads = (ushort)imageInfo.Heads,
Heads = (ushort)imageInfo.Heads, SectorsPerTrack = (ushort)imageInfo.SectorsPerTrack, VendorWord47 = 0x80,
SectorsPerTrack = (ushort)imageInfo.SectorsPerTrack, Capabilities = CommonTypes.Structs.Devices.ATA.Identify.CapabilitiesBit.DMASupport |
VendorWord47 = 0x80, CommonTypes.Structs.Devices.ATA.Identify.CapabilitiesBit.IORDY |
Capabilities = CommonTypes.Structs.Devices.ATA.Identify.CapabilitiesBit.LBASupport,
Decoders.ATA.Identify.CapabilitiesBit.DMASupport | ExtendedIdentify =
Decoders.ATA.Identify.CapabilitiesBit.IORDY | CommonTypes.Structs.Devices.ATA.Identify.ExtendedIdentifyBit.Words54to58Valid,
Decoders.ATA.Identify.CapabilitiesBit.LBASupport, CurrentCylinders = (ushort)imageInfo.Cylinders, CurrentHeads = (ushort)imageInfo.Heads,
ExtendedIdentify = Decoders.ATA.Identify.ExtendedIdentifyBit.Words54to58Valid,
CurrentCylinders = (ushort)imageInfo.Cylinders,
CurrentHeads = (ushort)imageInfo.Heads,
CurrentSectorsPerTrack = (ushort)imageInfo.SectorsPerTrack, CurrentSectorsPerTrack = (ushort)imageInfo.SectorsPerTrack,
CurrentSectors = (uint)imageInfo.Sectors, CurrentSectors = (uint)imageInfo.Sectors, LBASectors = (uint)imageInfo.Sectors,
LBASectors = (uint)imageInfo.Sectors, DMASupported = CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode0,
DMASupported = Decoders.ATA.Identify.TransferMode.Mode0, DMAActive = CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode0
DMAActive = Decoders.ATA.Identify.TransferMode.Mode0
}; };
if(string.IsNullOrEmpty(imageInfo.DriveManufacturer)) imageInfo.DriveManufacturer = "DiscImageChef"; if(string.IsNullOrEmpty(imageInfo.DriveManufacturer))
imageInfo.DriveManufacturer = "DiscImageChef";
if(string.IsNullOrEmpty(imageInfo.DriveModel)) imageInfo.DriveModel = ""; if(string.IsNullOrEmpty(imageInfo.DriveModel))
imageInfo.DriveModel = "";
if(string.IsNullOrEmpty(imageInfo.DriveFirmwareRevision)) Version.GetVersion(); if(string.IsNullOrEmpty(imageInfo.DriveFirmwareRevision))
Version.GetVersion();
if(string.IsNullOrEmpty(imageInfo.DriveSerialNumber)) if(string.IsNullOrEmpty(imageInfo.DriveSerialNumber))
imageInfo.DriveSerialNumber = $"{new Random().NextDouble():16X}"; imageInfo.DriveSerialNumber = $"{new Random().NextDouble():16X}";
@@ -247,17 +276,21 @@ namespace DiscImageChef.DiscImages
byte[] ataIdBytes = new byte[Marshal.SizeOf<Identify.IdentifyDevice>()]; byte[] ataIdBytes = new byte[Marshal.SizeOf<Identify.IdentifyDevice>()];
IntPtr ptr = System.Runtime.InteropServices.Marshal.AllocHGlobal(512); IntPtr ptr = System.Runtime.InteropServices.Marshal.AllocHGlobal(512);
System.Runtime.InteropServices.Marshal.StructureToPtr(ataId, ptr, true); System.Runtime.InteropServices.Marshal.StructureToPtr(ataId, ptr, true);
System.Runtime.InteropServices.Marshal.Copy(ptr, ataIdBytes, 0, System.Runtime.InteropServices.Marshal.Copy(ptr, ataIdBytes, 0,
Marshal.SizeOf<Identify.IdentifyDevice>()); Marshal.SizeOf<Identify.IdentifyDevice>());
System.Runtime.InteropServices.Marshal.FreeHGlobal(ptr); System.Runtime.InteropServices.Marshal.FreeHGlobal(ptr);
Array.Copy(ScrambleAtaString(imageInfo.DriveManufacturer + " " + imageInfo.DriveModel, 40), 0, Array.Copy(ScrambleAtaString(imageInfo.DriveManufacturer + " " + imageInfo.DriveModel, 40), 0,
ataIdBytes, 27 * 2, 40); ataIdBytes, 27 * 2, 40);
Array.Copy(ScrambleAtaString(imageInfo.DriveFirmwareRevision, 8), 0, ataIdBytes, 23 * 2, 8);
Array.Copy(ScrambleAtaString(imageInfo.DriveSerialNumber, 20), 0, ataIdBytes, 10 * 2, 20); Array.Copy(ScrambleAtaString(imageInfo.DriveFirmwareRevision, 8), 0, ataIdBytes, 23 * 2, 8);
Array.Copy(ataIdBytes, 0, header.identify, 0, 106); Array.Copy(ScrambleAtaString(imageInfo.DriveSerialNumber, 20), 0, ataIdBytes, 10 * 2, 20);
Array.Copy(ataIdBytes, 0, header.identify, 0, 106);
} }
else Array.Copy(identify, 0, header.identify, 0, 106); else
Array.Copy(identify, 0, header.identify, 0, 106);
byte[] hdr = new byte[Marshal.SizeOf<RsIdeHeader>()]; byte[] hdr = new byte[Marshal.SizeOf<RsIdeHeader>()];
IntPtr hdrPtr = System.Runtime.InteropServices.Marshal.AllocHGlobal(Marshal.SizeOf<RsIdeHeader>()); IntPtr hdrPtr = System.Runtime.InteropServices.Marshal.AllocHGlobal(Marshal.SizeOf<RsIdeHeader>());
@@ -273,6 +306,7 @@ namespace DiscImageChef.DiscImages
IsWriting = false; IsWriting = false;
ErrorMessage = ""; ErrorMessage = "";
return true; return true;
} }
@@ -291,18 +325,21 @@ namespace DiscImageChef.DiscImages
if(cylinders > ushort.MaxValue) if(cylinders > ushort.MaxValue)
{ {
ErrorMessage = "Too many cylinders."; ErrorMessage = "Too many cylinders.";
return false; return false;
} }
if(heads > ushort.MaxValue) if(heads > ushort.MaxValue)
{ {
ErrorMessage = "Too many heads."; ErrorMessage = "Too many heads.";
return false; return false;
} }
if(sectorsPerTrack > ushort.MaxValue) if(sectorsPerTrack > ushort.MaxValue)
{ {
ErrorMessage = "Too many sectors per track."; ErrorMessage = "Too many sectors per track.";
return false; return false;
} }
@@ -316,12 +353,14 @@ namespace DiscImageChef.DiscImages
public bool WriteSectorTag(byte[] data, ulong sectorAddress, SectorTagType tag) public bool WriteSectorTag(byte[] data, ulong sectorAddress, SectorTagType tag)
{ {
ErrorMessage = "Unsupported feature"; ErrorMessage = "Unsupported feature";
return false; return false;
} }
public bool WriteSectorsTag(byte[] data, ulong sectorAddress, uint length, SectorTagType tag) public bool WriteSectorsTag(byte[] data, ulong sectorAddress, uint length, SectorTagType tag)
{ {
ErrorMessage = "Unsupported feature"; ErrorMessage = "Unsupported feature";
return false; return false;
} }

View File

@@ -40,12 +40,14 @@ using DiscImageChef.CommonTypes.Enums;
using DiscImageChef.CommonTypes.Exceptions; using DiscImageChef.CommonTypes.Exceptions;
using DiscImageChef.CommonTypes.Interfaces; using DiscImageChef.CommonTypes.Interfaces;
using DiscImageChef.CommonTypes.Structs; using DiscImageChef.CommonTypes.Structs;
using DiscImageChef.CommonTypes.Structs.Devices.SCSI;
using DiscImageChef.Console; using DiscImageChef.Console;
using DiscImageChef.Decoders.CD; using DiscImageChef.Decoders.CD;
using DiscImageChef.Decoders.DVD; using DiscImageChef.Decoders.DVD;
using DiscImageChef.Decoders.SCSI; using DiscImageChef.Decoders.SCSI;
using Schemas; using Schemas;
using DMI = DiscImageChef.Decoders.Xbox.DMI; using DMI = DiscImageChef.Decoders.Xbox.DMI;
using Inquiry = DiscImageChef.CommonTypes.Structs.Devices.SCSI.Inquiry;
using Session = DiscImageChef.CommonTypes.Structs.Session; using Session = DiscImageChef.CommonTypes.Structs.Session;
using TrackType = DiscImageChef.CommonTypes.Enums.TrackType; using TrackType = DiscImageChef.CommonTypes.Enums.TrackType;
@@ -781,7 +783,7 @@ namespace DiscImageChef.DiscImages
if (mediaTags.ContainsKey(MediaTagType.SCSI_INQUIRY)) if (mediaTags.ContainsKey(MediaTagType.SCSI_INQUIRY))
{ {
var devType = PeripheralDeviceTypes.DirectAccess; var devType = PeripheralDeviceTypes.DirectAccess;
Inquiry.SCSIInquiry? scsiInq = null; Inquiry? scsiInq = null;
if (mediaTags.TryGetValue(MediaTagType.SCSI_INQUIRY, out var inq)) if (mediaTags.TryGetValue(MediaTagType.SCSI_INQUIRY, out var inq))
{ {
scsiInq = Inquiry.Decode(inq); scsiInq = Inquiry.Decode(inq);
@@ -858,7 +860,7 @@ namespace DiscImageChef.DiscImages
// It's ATA, check tags // It's ATA, check tags
if (mediaTags.TryGetValue(MediaTagType.ATA_IDENTIFY, out var identifyBuf)) if (mediaTags.TryGetValue(MediaTagType.ATA_IDENTIFY, out var identifyBuf))
{ {
var ataId = Decoders.ATA.Identify.Decode(identifyBuf); var ataId = CommonTypes.Structs.Devices.ATA.Identify.Decode(identifyBuf);
if (ataId.HasValue) if (ataId.HasValue)
{ {
imageInfo.MediaType = (ushort) ataId.Value.GeneralConfiguration == 0x848A imageInfo.MediaType = (ushort) ataId.Value.GeneralConfiguration == 0x848A

View File

@@ -35,6 +35,7 @@ using System.Collections.ObjectModel;
using System.Text; using System.Text;
using DiscImageChef.CommonTypes.Enums; using DiscImageChef.CommonTypes.Enums;
using DiscImageChef.CommonTypes.Interfaces; using DiscImageChef.CommonTypes.Interfaces;
using DiscImageChef.CommonTypes.Structs.Devices.SCSI;
using DiscImageChef.Decoders.ATA; using DiscImageChef.Decoders.ATA;
using DiscImageChef.Decoders.Bluray; using DiscImageChef.Decoders.Bluray;
using DiscImageChef.Decoders.CD; using DiscImageChef.Decoders.CD;
@@ -48,6 +49,7 @@ using BCA = DiscImageChef.Decoders.Bluray.BCA;
using Cartridge = DiscImageChef.Decoders.Bluray.Cartridge; using Cartridge = DiscImageChef.Decoders.Bluray.Cartridge;
using DDS = DiscImageChef.Decoders.DVD.DDS; using DDS = DiscImageChef.Decoders.DVD.DDS;
using DMI = DiscImageChef.Decoders.Xbox.DMI; using DMI = DiscImageChef.Decoders.Xbox.DMI;
using Inquiry = DiscImageChef.Decoders.SCSI.Inquiry;
using Spare = DiscImageChef.Decoders.DVD.Spare; using Spare = DiscImageChef.Decoders.DVD.Spare;
namespace DiscImageChef.Gui.Forms namespace DiscImageChef.Gui.Forms

View File

@@ -39,6 +39,7 @@ using DiscImageChef.CommonTypes;
using DiscImageChef.CommonTypes.Enums; using DiscImageChef.CommonTypes.Enums;
using DiscImageChef.CommonTypes.Interfaces; using DiscImageChef.CommonTypes.Interfaces;
using DiscImageChef.CommonTypes.Structs; using DiscImageChef.CommonTypes.Structs;
using DiscImageChef.CommonTypes.Structs.Devices.SCSI;
using DiscImageChef.Console; using DiscImageChef.Console;
using DiscImageChef.Core; using DiscImageChef.Core;
using DiscImageChef.Core.Media.Info; using DiscImageChef.Core.Media.Info;

View File

@@ -37,6 +37,7 @@ using System.Text;
using DiscImageChef.CommonTypes.Enums; using DiscImageChef.CommonTypes.Enums;
using DiscImageChef.CommonTypes.Interfaces; using DiscImageChef.CommonTypes.Interfaces;
using DiscImageChef.CommonTypes.Structs; using DiscImageChef.CommonTypes.Structs;
using DiscImageChef.CommonTypes.Structs.Devices.SCSI;
using DiscImageChef.Decoders.CD; using DiscImageChef.Decoders.CD;
using DiscImageChef.Decoders.DVD; using DiscImageChef.Decoders.DVD;
using DiscImageChef.Decoders.SCSI; using DiscImageChef.Decoders.SCSI;
@@ -48,6 +49,7 @@ using Eto.Drawing;
using Eto.Forms; using Eto.Forms;
using Eto.Serialization.Xaml; using Eto.Serialization.Xaml;
using Schemas; using Schemas;
using Inquiry = DiscImageChef.Decoders.SCSI.Inquiry;
using Session = DiscImageChef.CommonTypes.Structs.Session; using Session = DiscImageChef.CommonTypes.Structs.Session;
namespace DiscImageChef.Gui.Panels namespace DiscImageChef.Gui.Panels
@@ -258,7 +260,7 @@ namespace DiscImageChef.Gui.Panels
PeripheralDeviceTypes scsiDeviceType = PeripheralDeviceTypes.DirectAccess; PeripheralDeviceTypes scsiDeviceType = PeripheralDeviceTypes.DirectAccess;
byte[] scsiInquiryData = null; byte[] scsiInquiryData = null;
Inquiry.SCSIInquiry? scsiInquiry = null; CommonTypes.Structs.Devices.SCSI.Inquiry? scsiInquiry = null;
Modes.DecodedMode? scsiMode = null; Modes.DecodedMode? scsiMode = null;
byte[] scsiModeSense6 = null; byte[] scsiModeSense6 = null;
byte[] scsiModeSense10 = null; byte[] scsiModeSense10 = null;
@@ -270,7 +272,7 @@ namespace DiscImageChef.Gui.Panels
scsiDeviceType = (PeripheralDeviceTypes)(scsiInquiryData[0] & 0x1F); scsiDeviceType = (PeripheralDeviceTypes)(scsiInquiryData[0] & 0x1F);
scsiInquiry = Inquiry.Decode(scsiInquiryData); scsiInquiry = CommonTypes.Structs.Devices.SCSI.Inquiry.Decode(scsiInquiryData);
} }
if(imageFormat.Info.ReadableMediaTags != null && if(imageFormat.Info.ReadableMediaTags != null &&

View File

@@ -34,11 +34,13 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using DiscImageChef.CommonTypes.Structs.Devices.SCSI;
using DiscImageChef.Console; using DiscImageChef.Console;
using DiscImageChef.Decoders.SCSI; using DiscImageChef.Decoders.SCSI;
using DiscImageChef.Decoders.SCSI.MMC; using DiscImageChef.Decoders.SCSI.MMC;
using Eto.Forms; using Eto.Forms;
using Eto.Serialization.Xaml; using Eto.Serialization.Xaml;
using Inquiry = DiscImageChef.Decoders.SCSI.Inquiry;
namespace DiscImageChef.Gui.Tabs namespace DiscImageChef.Gui.Tabs
{ {
@@ -46,7 +48,7 @@ namespace DiscImageChef.Gui.Tabs
{ {
private byte[] configuration; private byte[] configuration;
private Dictionary<byte, byte[]> evpdPages; private Dictionary<byte, byte[]> evpdPages;
private Inquiry.SCSIInquiry? inquiry; private CommonTypes.Structs.Devices.SCSI.Inquiry? inquiry;
private byte[] inquiryData; private byte[] inquiryData;
private Modes.DecodedMode? mode; private Modes.DecodedMode? mode;
private byte[] modeSense10; private byte[] modeSense10;
@@ -58,7 +60,7 @@ namespace DiscImageChef.Gui.Tabs
XamlReader.Load(this); XamlReader.Load(this);
} }
internal void LoadData(byte[] scsiInquiryData, Inquiry.SCSIInquiry? scsiInquiry, internal void LoadData(byte[] scsiInquiryData, CommonTypes.Structs.Devices.SCSI.Inquiry? scsiInquiry,
Dictionary<byte, byte[]> scsiEvpdPages, Modes.DecodedMode? scsiMode, Dictionary<byte, byte[]> scsiEvpdPages, Modes.DecodedMode? scsiMode,
PeripheralDeviceTypes scsiType, byte[] scsiModeSense6, PeripheralDeviceTypes scsiType, byte[] scsiModeSense6,
byte[] scsiModeSense10, byte[] scsiModeSense10,

View File

@@ -251,6 +251,7 @@
<s:Boolean x:Key="/Default/UserDictionary/Words/=leadout/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=leadout/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=manuallj/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=manuallj/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=mapfile/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=mapfile/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=MDMA/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=mediaid/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=mediaid/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=mediaserialnumber/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=mediaserialnumber/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=mhdd/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=mhdd/@EntryIndexedValue">True</s:Boolean>
@@ -287,6 +288,7 @@
<s:Boolean x:Key="/Default/UserDictionary/Words/=Reiser/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=Reiser/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=remapanchor/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=remapanchor/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=reportdensitysupport/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=reportdensitysupport/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=SATA/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=SCMS/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=SCMS/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=SDHCI/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=SDHCI/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Secu/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=Secu/@EntryIndexedValue">True</s:Boolean>

View File

@@ -39,11 +39,12 @@ using System.Threading;
using DiscImageChef.CommonTypes.Enums; using DiscImageChef.CommonTypes.Enums;
using DiscImageChef.CommonTypes.Interop; using DiscImageChef.CommonTypes.Interop;
using DiscImageChef.CommonTypes.Metadata; using DiscImageChef.CommonTypes.Metadata;
using DiscImageChef.CommonTypes.Structs.Devices.ATA;
using DiscImageChef.CommonTypes.Structs.Devices.SCSI;
using DiscImageChef.Console; using DiscImageChef.Console;
using DiscImageChef.Core; using DiscImageChef.Core;
using DiscImageChef.Database; using DiscImageChef.Database;
using DiscImageChef.Database.Models; using DiscImageChef.Database.Models;
using DiscImageChef.Decoders.ATA;
using DiscImageChef.Decoders.SCSI; using DiscImageChef.Decoders.SCSI;
using DiscImageChef.Devices; using DiscImageChef.Devices;
using Newtonsoft.Json; using Newtonsoft.Json;

View File

@@ -35,6 +35,7 @@ using System.CommandLine;
using System.CommandLine.Invocation; using System.CommandLine.Invocation;
using System.Linq; using System.Linq;
using DiscImageChef.CommonTypes.Enums; using DiscImageChef.CommonTypes.Enums;
using DiscImageChef.CommonTypes.Structs.Devices.SCSI;
using DiscImageChef.Console; using DiscImageChef.Console;
using DiscImageChef.Core; using DiscImageChef.Core;
using DiscImageChef.Database; using DiscImageChef.Database;
@@ -47,6 +48,7 @@ using DiscImageChef.Decoders.SCSI.SSC;
using DiscImageChef.Devices; using DiscImageChef.Devices;
using Command = System.CommandLine.Command; using Command = System.CommandLine.Command;
using DeviceInfo = DiscImageChef.Core.Devices.Info.DeviceInfo; using DeviceInfo = DiscImageChef.Core.Devices.Info.DeviceInfo;
using Inquiry = DiscImageChef.Decoders.SCSI.Inquiry;
namespace DiscImageChef.Commands.Device namespace DiscImageChef.Commands.Device
{ {

View File

@@ -37,6 +37,7 @@ using System.CommandLine.Invocation;
using System.Linq; using System.Linq;
using DiscImageChef.CommonTypes.Enums; using DiscImageChef.CommonTypes.Enums;
using DiscImageChef.CommonTypes.Structs; using DiscImageChef.CommonTypes.Structs;
using DiscImageChef.CommonTypes.Structs.Devices.SCSI;
using DiscImageChef.Console; using DiscImageChef.Console;
using DiscImageChef.Core; using DiscImageChef.Core;
using DiscImageChef.Core.Devices.Dumping; using DiscImageChef.Core.Devices.Dumping;
@@ -46,7 +47,6 @@ using DiscImageChef.Database.Models;
using DiscImageChef.Decoders.Bluray; using DiscImageChef.Decoders.Bluray;
using DiscImageChef.Decoders.CD; using DiscImageChef.Decoders.CD;
using DiscImageChef.Decoders.DVD; using DiscImageChef.Decoders.DVD;
using DiscImageChef.Decoders.SCSI;
using DiscImageChef.Decoders.SCSI.MMC; using DiscImageChef.Decoders.SCSI.MMC;
using DiscImageChef.Decoders.SCSI.SSC; using DiscImageChef.Decoders.SCSI.SSC;
using DiscImageChef.Decoders.Xbox; using DiscImageChef.Decoders.Xbox;