mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
Remove DiscImageChef.CommonTypes dependence on DiscImageChef.Decoders.
This commit is contained in:
13
.idea/.idea.DiscImageChef/.idea/contentModel.xml
generated
13
.idea/.idea.DiscImageChef/.idea/contentModel.xml
generated
@@ -184,6 +184,18 @@
|
||||
<e p="Partition.cs" t="Include" />
|
||||
<e p="PluginBase.cs" 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="Images.cs" t="Include" />
|
||||
<e p="TapeFile.cs" t="Include" />
|
||||
@@ -515,7 +527,6 @@
|
||||
<e p="SCSI" t="Include">
|
||||
<e p="DiscStructureCapabilities.cs" t="Include" />
|
||||
<e p="EVPD.cs" t="Include" />
|
||||
<e p="Enums.cs" t="Include" />
|
||||
<e p="Inquiry.cs" t="Include" />
|
||||
<e p="MMC" t="Include">
|
||||
<e p="AACS.cs" t="Include" />
|
||||
|
||||
Submodule DiscImageChef.CommonTypes updated: afa1525f0c...1a2a4242eb
@@ -39,8 +39,8 @@ using DiscImageChef.CommonTypes;
|
||||
using DiscImageChef.CommonTypes.Enums;
|
||||
using DiscImageChef.CommonTypes.Extents;
|
||||
using DiscImageChef.CommonTypes.Interfaces;
|
||||
using DiscImageChef.CommonTypes.Structs.Devices.ATA;
|
||||
using DiscImageChef.Core.Logging;
|
||||
using DiscImageChef.Decoders.ATA;
|
||||
using DiscImageChef.Decoders.PCMCIA;
|
||||
using Schemas;
|
||||
using Tuple = DiscImageChef.Decoders.PCMCIA.Tuple;
|
||||
|
||||
@@ -34,6 +34,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using DiscImageChef.CommonTypes.Enums;
|
||||
using DiscImageChef.CommonTypes.Extents;
|
||||
using DiscImageChef.CommonTypes.Structs.Devices.SCSI;
|
||||
using DiscImageChef.Console;
|
||||
using DiscImageChef.Decoders.SCSI;
|
||||
using DiscImageChef.Devices;
|
||||
|
||||
@@ -34,9 +34,9 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using DiscImageChef.CommonTypes;
|
||||
using DiscImageChef.CommonTypes.Enums;
|
||||
using DiscImageChef.CommonTypes.Structs.Devices.SCSI;
|
||||
using DiscImageChef.Decoders.Bluray;
|
||||
using DiscImageChef.Decoders.DVD;
|
||||
using DiscImageChef.Decoders.SCSI;
|
||||
using DiscImageChef.Decoders.SCSI.MMC;
|
||||
using DiscImageChef.Devices;
|
||||
using Schemas;
|
||||
|
||||
@@ -10,6 +10,7 @@ using DiscImageChef.CommonTypes.Extents;
|
||||
using DiscImageChef.CommonTypes.Interfaces;
|
||||
using DiscImageChef.CommonTypes.Metadata;
|
||||
using DiscImageChef.CommonTypes.Structs;
|
||||
using DiscImageChef.CommonTypes.Structs.Devices.SCSI;
|
||||
using DiscImageChef.Console;
|
||||
using DiscImageChef.Core.Logging;
|
||||
using DiscImageChef.Decoders.SCSI;
|
||||
|
||||
@@ -41,6 +41,7 @@ using DiscImageChef.CommonTypes.Extents;
|
||||
using DiscImageChef.CommonTypes.Interfaces;
|
||||
using DiscImageChef.CommonTypes.Metadata;
|
||||
using DiscImageChef.CommonTypes.Structs;
|
||||
using DiscImageChef.CommonTypes.Structs.Devices.SCSI;
|
||||
using DiscImageChef.Console;
|
||||
using DiscImageChef.Core.Logging;
|
||||
using DiscImageChef.Decoders.SCSI;
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
using System.Threading;
|
||||
using DiscImageChef.CommonTypes;
|
||||
using DiscImageChef.CommonTypes.Interfaces;
|
||||
using DiscImageChef.CommonTypes.Structs.Devices.SCSI;
|
||||
using DiscImageChef.Decoders.SCSI;
|
||||
|
||||
namespace DiscImageChef.Core.Devices.Dumping
|
||||
|
||||
@@ -39,6 +39,7 @@ using DiscImageChef.CommonTypes.Extents;
|
||||
using DiscImageChef.CommonTypes.Interfaces;
|
||||
using DiscImageChef.CommonTypes.Interop;
|
||||
using DiscImageChef.CommonTypes.Structs;
|
||||
using DiscImageChef.CommonTypes.Structs.Devices.SCSI;
|
||||
using DiscImageChef.Console;
|
||||
using DiscImageChef.Core.Logging;
|
||||
using DiscImageChef.Decoders.DVD;
|
||||
|
||||
@@ -33,10 +33,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using DiscImageChef.CommonTypes.Enums;
|
||||
using DiscImageChef.CommonTypes.Structs.Devices.SCSI;
|
||||
using DiscImageChef.Console;
|
||||
using DiscImageChef.Decoders.ATA;
|
||||
using DiscImageChef.Decoders.SCSI;
|
||||
using DiscImageChef.Devices;
|
||||
using Inquiry = DiscImageChef.CommonTypes.Structs.Devices.SCSI.Inquiry;
|
||||
|
||||
namespace DiscImageChef.Core.Devices.Info
|
||||
{
|
||||
|
||||
@@ -32,10 +32,12 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
using DiscImageChef.CommonTypes.Enums;
|
||||
using DiscImageChef.CommonTypes.Structs.Devices.SCSI;
|
||||
using DiscImageChef.Decoders.ATA;
|
||||
using DiscImageChef.Decoders.SCSI;
|
||||
using DiscImageChef.Decoders.SCSI.SSC;
|
||||
using DiscImageChef.Devices;
|
||||
using Inquiry = DiscImageChef.CommonTypes.Structs.Devices.SCSI.Inquiry;
|
||||
|
||||
namespace DiscImageChef.Core.Devices.Info
|
||||
{
|
||||
@@ -44,7 +46,7 @@ namespace DiscImageChef.Core.Devices.Info
|
||||
public byte[] AtaIdentify { get; }
|
||||
public byte[] AtapiIdentify { get; }
|
||||
public byte[] ScsiInquiryData { get; }
|
||||
public Inquiry.SCSIInquiry? ScsiInquiry { get; }
|
||||
public Inquiry? ScsiInquiry { get; }
|
||||
public AtaErrorRegistersChs? AtaMcptError { get; }
|
||||
public Dictionary<byte, byte[]> ScsiEvpdPages { get; }
|
||||
public Modes.DecodedMode? ScsiMode { get; }
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
using System;
|
||||
using DiscImageChef.CommonTypes.Enums;
|
||||
using DiscImageChef.Decoders.ATA;
|
||||
using DiscImageChef.CommonTypes.Structs.Devices.ATA;
|
||||
using DiscImageChef.Devices;
|
||||
|
||||
namespace DiscImageChef.Core.Devices
|
||||
|
||||
@@ -34,10 +34,11 @@ using System;
|
||||
using DiscImageChef.CommonTypes.Enums;
|
||||
using DiscImageChef.Console;
|
||||
using DiscImageChef.Decoders.ATA;
|
||||
using Identify = DiscImageChef.CommonTypes.Structs.Devices.ATA.Identify;
|
||||
|
||||
namespace DiscImageChef.Core.Devices
|
||||
{
|
||||
partial class Reader
|
||||
internal partial class Reader
|
||||
{
|
||||
Identify.IdentifyDevice ataId;
|
||||
bool ataRead;
|
||||
@@ -60,9 +61,12 @@ namespace DiscImageChef.Core.Devices
|
||||
|
||||
(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;
|
||||
Heads = (byte)ataId.CurrentHeads;
|
||||
@@ -70,17 +74,18 @@ namespace DiscImageChef.Core.Devices
|
||||
Blocks = (ulong)(Cylinders * Heads * Sectors);
|
||||
}
|
||||
|
||||
if(ataId.CurrentCylinders != 0 && ataId.CurrentHeads != 0 && ataId.CurrentSectorsPerTrack != 0 ||
|
||||
ataId.Cylinders <= 0 ||
|
||||
ataId.Heads <= 0 ||
|
||||
ataId.SectorsPerTrack <= 0) return (Cylinders, Heads, Sectors);
|
||||
if((ataId.CurrentCylinders != 0 && ataId.CurrentHeads != 0 && ataId.CurrentSectorsPerTrack != 0) ||
|
||||
ataId.Cylinders <= 0 ||
|
||||
ataId.Heads <= 0 ||
|
||||
ataId.SectorsPerTrack <= 0)
|
||||
return(Cylinders, Heads, Sectors);
|
||||
|
||||
Cylinders = ataId.Cylinders;
|
||||
Heads = (byte)ataId.Heads;
|
||||
Sectors = (byte)ataId.SectorsPerTrack;
|
||||
Blocks = (ulong)(Cylinders * Heads * Sectors);
|
||||
|
||||
return (Cylinders, Heads, Sectors);
|
||||
return(Cylinders, Heads, Sectors);
|
||||
}
|
||||
|
||||
ulong AtaGetBlocks()
|
||||
@@ -93,7 +98,8 @@ namespace DiscImageChef.Core.Devices
|
||||
IsLba = true;
|
||||
}
|
||||
|
||||
if(!ataId.CommandSet2.HasFlag(Identify.CommandSetBit2.LBA48)) return Blocks;
|
||||
if(!ataId.CommandSet2.HasFlag(Identify.CommandSetBit2.LBA48))
|
||||
return Blocks;
|
||||
|
||||
Blocks = ataId.LBA48Sectors;
|
||||
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,
|
||||
out _);
|
||||
|
||||
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 _);
|
||||
ataReadRetry = !sense && (errorChs.Status & 0x27) == 0 && errorChs.Error == 0 && cmdBuf.Length > 0;
|
||||
@@ -134,40 +141,62 @@ namespace DiscImageChef.Core.Devices
|
||||
|
||||
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.";
|
||||
|
||||
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.";
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!ataRead && !ataReadRetry && !ataReadDma && !ataReadDmaRetry)
|
||||
if(!ataRead &&
|
||||
!ataReadRetry &&
|
||||
!ataReadDma &&
|
||||
!ataReadDmaRetry)
|
||||
{
|
||||
ErrorMessage = "Device needs CHS commands but I can't issue them... Aborting.";
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if(ataReadDmaLba48) DicConsole.WriteLine("Using ATA READ DMA EXT command.");
|
||||
else if(ataReadLba48) DicConsole.WriteLine("Using ATA READ EXT command.");
|
||||
else if(ataReadDmaRetryLba) DicConsole.WriteLine("Using ATA READ DMA command with retries (LBA).");
|
||||
else if(ataReadDmaLba) DicConsole.WriteLine("Using ATA READ DMA command (LBA).");
|
||||
else if(ataReadRetryLba) 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).");
|
||||
if(ataReadDmaLba48)
|
||||
DicConsole.WriteLine("Using ATA READ DMA EXT command.");
|
||||
else if(ataReadLba48)
|
||||
DicConsole.WriteLine("Using ATA READ EXT command.");
|
||||
else if(ataReadDmaRetryLba)
|
||||
DicConsole.WriteLine("Using ATA READ DMA command with retries (LBA).");
|
||||
else if(ataReadDmaLba)
|
||||
DicConsole.WriteLine("Using ATA READ DMA command (LBA).");
|
||||
else if(ataReadRetryLba)
|
||||
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
|
||||
{
|
||||
ErrorMessage = "Could not get a working read command!";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -176,18 +205,22 @@ namespace DiscImageChef.Core.Devices
|
||||
|
||||
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.LogicalSectorWords <= 255 || ataId.LogicalAlignment == 0xFFFF)
|
||||
if(ataId.LogicalSectorWords <= 255 ||
|
||||
ataId.LogicalAlignment == 0xFFFF)
|
||||
LogicalBlockSize = 512;
|
||||
else
|
||||
LogicalBlockSize = ataId.LogicalSectorWords * 2;
|
||||
else LogicalBlockSize = 512;
|
||||
else
|
||||
LogicalBlockSize = 512;
|
||||
|
||||
if((ataId.PhysLogSectorSize & 0x2000) == 0x2000)
|
||||
PhysicalBlockSize = LogicalBlockSize * (uint)Math.Pow(2, ataId.PhysLogSectorSize & 0xF);
|
||||
else PhysicalBlockSize = LogicalBlockSize;
|
||||
PhysicalBlockSize = LogicalBlockSize * (uint)Math.Pow(2, ataId.PhysLogSectorSize & 0xF);
|
||||
else
|
||||
PhysicalBlockSize = LogicalBlockSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -208,6 +241,7 @@ namespace DiscImageChef.Core.Devices
|
||||
if(!IsLba)
|
||||
{
|
||||
BlocksToRead = 1;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -218,6 +252,7 @@ namespace DiscImageChef.Core.Devices
|
||||
byte[] cmdBuf;
|
||||
bool sense;
|
||||
AtaErrorRegistersLba48 errorLba48;
|
||||
|
||||
if(ataReadDmaLba48)
|
||||
{
|
||||
sense = dev.ReadDma(out cmdBuf, out errorLba48, 0, (byte)BlocksToRead, timeout, out _);
|
||||
@@ -231,6 +266,7 @@ namespace DiscImageChef.Core.Devices
|
||||
else
|
||||
{
|
||||
AtaErrorRegistersLba28 errorLba;
|
||||
|
||||
if(ataReadDmaRetryLba)
|
||||
{
|
||||
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;
|
||||
ErrorMessage = $"Device error {dev.LastError} trying to guess ideal transfer length.";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -293,6 +335,7 @@ namespace DiscImageChef.Core.Devices
|
||||
{
|
||||
sense = dev.ReadDma(out buffer, out errorLba, true, (uint)block, (byte)count, timeout,
|
||||
out duration);
|
||||
|
||||
error = !(!sense && (errorLba.Status & 0x27) == 0 && errorLba.Error == 0 && buffer.Length > 0);
|
||||
status = errorLba.Status;
|
||||
errorByte = errorLba.Error;
|
||||
@@ -301,6 +344,7 @@ namespace DiscImageChef.Core.Devices
|
||||
{
|
||||
sense = dev.ReadDma(out buffer, out errorLba, false, (uint)block, (byte)count, timeout,
|
||||
out duration);
|
||||
|
||||
error = !(!sense && (errorLba.Status & 0x27) == 0 && errorLba.Error == 0 && buffer.Length > 0);
|
||||
status = errorLba.Status;
|
||||
errorByte = errorLba.Error;
|
||||
@@ -320,7 +364,8 @@ namespace DiscImageChef.Core.Devices
|
||||
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;
|
||||
}
|
||||
@@ -338,6 +383,7 @@ namespace DiscImageChef.Core.Devices
|
||||
{
|
||||
sense = dev.ReadDma(out buffer, out errorChs, true, cylinder, head, sectir, 1, timeout,
|
||||
out duration);
|
||||
|
||||
error = !(!sense && (errorChs.Status & 0x27) == 0 && errorChs.Error == 0 && buffer.Length > 0);
|
||||
status = errorChs.Status;
|
||||
errorByte = errorChs.Error;
|
||||
@@ -346,6 +392,7 @@ namespace DiscImageChef.Core.Devices
|
||||
{
|
||||
sense = dev.ReadDma(out buffer, out errorChs, false, cylinder, head, sectir, 1, timeout,
|
||||
out duration);
|
||||
|
||||
error = !(!sense && (errorChs.Status & 0x27) == 0 && errorChs.Error == 0 && buffer.Length > 0);
|
||||
status = errorChs.Status;
|
||||
errorByte = errorChs.Error;
|
||||
@@ -365,7 +412,8 @@ namespace DiscImageChef.Core.Devices
|
||||
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;
|
||||
}
|
||||
@@ -373,13 +421,15 @@ namespace DiscImageChef.Core.Devices
|
||||
bool AtaSeek(ulong block, out double 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 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -31,12 +31,13 @@
|
||||
// ****************************************************************************/
|
||||
|
||||
using System;
|
||||
using DiscImageChef.CommonTypes.Structs.Devices.SCSI;
|
||||
using DiscImageChef.Console;
|
||||
using DiscImageChef.Decoders.SCSI;
|
||||
|
||||
namespace DiscImageChef.Core.Devices
|
||||
{
|
||||
partial class Reader
|
||||
internal partial class Reader
|
||||
{
|
||||
// TODO: Raw reading
|
||||
bool hldtstReadRaw;
|
||||
@@ -72,23 +73,34 @@ namespace DiscImageChef.Core.Devices
|
||||
|
||||
seek10 = !dev.Seek10(out senseBuf, 0, timeout, out _);
|
||||
|
||||
if(!read6 && !read10 && !read12 && !read16)
|
||||
if(!read6 &&
|
||||
!read10 &&
|
||||
!read12 &&
|
||||
!read16)
|
||||
{
|
||||
ErrorMessage = "Cannot read medium, aborting scan...";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if(read6 && !read10 && !read12 && !read16 && Blocks > 0x001FFFFF + 1)
|
||||
if(read6 &&
|
||||
!read10 &&
|
||||
!read12 &&
|
||||
!read16 &&
|
||||
Blocks > 0x001FFFFF + 1)
|
||||
{
|
||||
ErrorMessage =
|
||||
$"Device only supports SCSI READ (6) but has more than {0x001FFFFF + 1} blocks ({Blocks} blocks total)";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if(!read16 && Blocks > 0xFFFFFFFF + (long)1)
|
||||
if(!read16 &&
|
||||
Blocks > 0xFFFFFFFF + (long)1)
|
||||
{
|
||||
ErrorMessage =
|
||||
$"Device only supports SCSI READ (10) but has more than {0xFFFFFFFF + (long)1} blocks ({Blocks} blocks total)";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -120,17 +132,23 @@ namespace DiscImageChef.Core.Devices
|
||||
|
||||
testSense = dev.ReadLong10(out _, out senseBuf, false, false, 0, 0xFFFF, timeout, out _);
|
||||
FixedSense? decSense;
|
||||
|
||||
if(testSense && !dev.Error)
|
||||
{
|
||||
decSense = Sense.DecodeFixed(senseBuf);
|
||||
|
||||
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)
|
||||
{
|
||||
CanReadRaw = true;
|
||||
if(decSense.Value.InformationValid && decSense.Value.ILI)
|
||||
|
||||
if(decSense.Value.InformationValid &&
|
||||
decSense.Value.ILI)
|
||||
{
|
||||
LongBlockSize = 0xFFFF - (decSense.Value.Information & 0xFFFF);
|
||||
|
||||
readLong10 = !dev.ReadLong10(out _, out senseBuf, false, false, 0,
|
||||
(ushort)LongBlockSize, timeout, out _);
|
||||
}
|
||||
@@ -143,29 +161,37 @@ namespace DiscImageChef.Core.Devices
|
||||
{
|
||||
// Long sector sizes for floppies
|
||||
514,
|
||||
|
||||
// Long sector sizes for SuperDisk
|
||||
536, 558,
|
||||
|
||||
// Long sector sizes for 512-byte magneto-opticals
|
||||
600, 610, 630
|
||||
})
|
||||
{
|
||||
ushort testSize = (ushort)i;
|
||||
testSense = dev.ReadLong16(out _, out senseBuf, false, 0, testSize, timeout, out _);
|
||||
if(!testSense && !dev.Error)
|
||||
|
||||
if(!testSense &&
|
||||
!dev.Error)
|
||||
{
|
||||
readLong16 = true;
|
||||
LongBlockSize = testSize;
|
||||
CanReadRaw = true;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
testSense = dev.ReadLong10(out _, out senseBuf, false, false, 0, testSize, timeout,
|
||||
out _);
|
||||
if(testSense || dev.Error) continue;
|
||||
|
||||
if(testSense || dev.Error)
|
||||
continue;
|
||||
|
||||
readLong10 = true;
|
||||
LongBlockSize = testSize;
|
||||
CanReadRaw = true;
|
||||
|
||||
break;
|
||||
}
|
||||
else if(LogicalBlockSize == 1024)
|
||||
@@ -173,33 +199,42 @@ namespace DiscImageChef.Core.Devices
|
||||
{
|
||||
// Long sector sizes for floppies
|
||||
1026,
|
||||
|
||||
// Long sector sizes for 1024-byte magneto-opticals
|
||||
1200
|
||||
})
|
||||
{
|
||||
ushort testSize = (ushort)i;
|
||||
testSense = dev.ReadLong16(out _, out senseBuf, false, 0, testSize, timeout, out _);
|
||||
if(!testSense && !dev.Error)
|
||||
|
||||
if(!testSense &&
|
||||
!dev.Error)
|
||||
{
|
||||
readLong16 = true;
|
||||
LongBlockSize = testSize;
|
||||
CanReadRaw = true;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
testSense = dev.ReadLong10(out _, out senseBuf, false, false, 0, testSize, timeout,
|
||||
out _);
|
||||
if(testSense || dev.Error) continue;
|
||||
|
||||
if(testSense || dev.Error)
|
||||
continue;
|
||||
|
||||
readLong10 = true;
|
||||
LongBlockSize = testSize;
|
||||
CanReadRaw = true;
|
||||
|
||||
break;
|
||||
}
|
||||
else if(LogicalBlockSize == 2048)
|
||||
{
|
||||
testSense = dev.ReadLong16(out _, out senseBuf, false, 0, 2380, timeout, out _);
|
||||
if(!testSense && !dev.Error)
|
||||
|
||||
if(!testSense &&
|
||||
!dev.Error)
|
||||
{
|
||||
readLong16 = true;
|
||||
LongBlockSize = 2380;
|
||||
@@ -208,7 +243,9 @@ namespace DiscImageChef.Core.Devices
|
||||
else
|
||||
{
|
||||
testSense = dev.ReadLong10(out _, out senseBuf, false, false, 0, 2380, timeout, out _);
|
||||
if(!testSense && !dev.Error)
|
||||
|
||||
if(!testSense &&
|
||||
!dev.Error)
|
||||
{
|
||||
readLong10 = true;
|
||||
LongBlockSize = 2380;
|
||||
@@ -219,7 +256,9 @@ namespace DiscImageChef.Core.Devices
|
||||
else if(LogicalBlockSize == 4096)
|
||||
{
|
||||
testSense = dev.ReadLong16(out _, out senseBuf, false, 0, 4760, timeout, out _);
|
||||
if(!testSense && !dev.Error)
|
||||
|
||||
if(!testSense &&
|
||||
!dev.Error)
|
||||
{
|
||||
readLong16 = true;
|
||||
LongBlockSize = 4760;
|
||||
@@ -228,7 +267,9 @@ namespace DiscImageChef.Core.Devices
|
||||
else
|
||||
{
|
||||
testSense = dev.ReadLong10(out _, out senseBuf, false, false, 0, 4760, timeout, out _);
|
||||
if(!testSense && !dev.Error)
|
||||
|
||||
if(!testSense &&
|
||||
!dev.Error)
|
||||
{
|
||||
readLong10 = true;
|
||||
LongBlockSize = 4760;
|
||||
@@ -239,7 +280,9 @@ namespace DiscImageChef.Core.Devices
|
||||
else if(LogicalBlockSize == 8192)
|
||||
{
|
||||
testSense = dev.ReadLong16(out _, out senseBuf, false, 0, 9424, timeout, out _);
|
||||
if(!testSense && !dev.Error)
|
||||
|
||||
if(!testSense &&
|
||||
!dev.Error)
|
||||
{
|
||||
readLong16 = true;
|
||||
LongBlockSize = 9424;
|
||||
@@ -248,7 +291,9 @@ namespace DiscImageChef.Core.Devices
|
||||
else
|
||||
{
|
||||
testSense = dev.ReadLong10(out _, out senseBuf, false, false, 0, 9424, timeout, out _);
|
||||
if(!testSense && !dev.Error)
|
||||
|
||||
if(!testSense &&
|
||||
!dev.Error)
|
||||
{
|
||||
readLong10 = true;
|
||||
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 _);
|
||||
|
||||
if(testSense)
|
||||
{
|
||||
decSense = Sense.DecodeFixed(senseBuf);
|
||||
|
||||
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)
|
||||
{
|
||||
CanReadRaw = true;
|
||||
if(decSense.Value.InformationValid && decSense.Value.ILI)
|
||||
|
||||
if(decSense.Value.InformationValid &&
|
||||
decSense.Value.ILI)
|
||||
{
|
||||
LongBlockSize = 0xFFFF - (decSense.Value.Information & 0xFFFF);
|
||||
|
||||
syqReadLong10 =
|
||||
!dev.SyQuestReadLong10(out _, out senseBuf, 0, LongBlockSize, timeout,
|
||||
out _);
|
||||
@@ -279,18 +331,23 @@ namespace DiscImageChef.Core.Devices
|
||||
else
|
||||
{
|
||||
testSense = dev.SyQuestReadLong6(out _, out senseBuf, 0, 0xFFFF, timeout, out _);
|
||||
|
||||
if(testSense)
|
||||
{
|
||||
decSense = Sense.DecodeFixed(senseBuf);
|
||||
|
||||
if(decSense.HasValue)
|
||||
if(decSense.Value.SenseKey == SenseKeys.IllegalRequest &&
|
||||
decSense.Value.ASC == 0x24 &&
|
||||
decSense.Value.ASCQ == 0x00)
|
||||
{
|
||||
CanReadRaw = true;
|
||||
if(decSense.Value.InformationValid && decSense.Value.ILI)
|
||||
|
||||
if(decSense.Value.InformationValid &&
|
||||
decSense.Value.ILI)
|
||||
{
|
||||
LongBlockSize = 0xFFFF - (decSense.Value.Information & 0xFFFF);
|
||||
|
||||
syqReadLong6 =
|
||||
!dev.SyQuestReadLong6(out _, out senseBuf, 0, LongBlockSize,
|
||||
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 _);
|
||||
if(!testSense && !dev.Error)
|
||||
|
||||
if(!testSense &&
|
||||
!dev.Error)
|
||||
{
|
||||
syqReadLong6 = true;
|
||||
LongBlockSize = 262;
|
||||
@@ -316,11 +376,13 @@ namespace DiscImageChef.Core.Devices
|
||||
{
|
||||
switch(dev.Manufacturer)
|
||||
{
|
||||
case "HL-DT-ST":
|
||||
case"HL-DT-ST":
|
||||
hldtstReadRaw = !dev.HlDtStReadRawDvd(out _, out senseBuf, 0, 1, timeout, out _);
|
||||
|
||||
break;
|
||||
case "PLEXTOR":
|
||||
case"PLEXTOR":
|
||||
plextorReadRaw = !dev.PlextorReadRawDvd(out _, out senseBuf, 0, 1, timeout, out _);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -331,10 +393,13 @@ namespace DiscImageChef.Core.Devices
|
||||
}
|
||||
|
||||
// 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 _);
|
||||
if(!testSense && !dev.Error)
|
||||
|
||||
if(!testSense &&
|
||||
!dev.Error)
|
||||
{
|
||||
readLongDvd = true;
|
||||
LongBlockSize = 37856;
|
||||
@@ -346,17 +411,27 @@ namespace DiscImageChef.Core.Devices
|
||||
|
||||
if(CanReadRaw)
|
||||
{
|
||||
if(readLong16) DicConsole.WriteLine("Using SCSI READ LONG (16) command.");
|
||||
else if(readLong10 || readLongDvd) DicConsole.WriteLine("Using SCSI READ LONG (10) command.");
|
||||
else if(syqReadLong10) 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.");
|
||||
if(readLong16)
|
||||
DicConsole.WriteLine("Using SCSI READ LONG (16) command.");
|
||||
else if(readLong10 || readLongDvd)
|
||||
DicConsole.WriteLine("Using SCSI READ LONG (10) command.");
|
||||
else if(syqReadLong10)
|
||||
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(read12) 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.");
|
||||
else if(read16)
|
||||
DicConsole.WriteLine("Using SCSI READ (16) command.");
|
||||
else if(read12)
|
||||
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;
|
||||
}
|
||||
@@ -367,6 +442,7 @@ namespace DiscImageChef.Core.Devices
|
||||
Blocks = 0;
|
||||
|
||||
sense = dev.ReadCapacity(out byte[] cmdBuf, out byte[] senseBuf, timeout, out _);
|
||||
|
||||
if(!sense)
|
||||
{
|
||||
Blocks = (ulong)((cmdBuf[0] << 24) + (cmdBuf[1] << 16) + (cmdBuf[2] << 8) + cmdBuf[3]);
|
||||
@@ -398,6 +474,7 @@ namespace DiscImageChef.Core.Devices
|
||||
|
||||
PhysicalBlockSize = LogicalBlockSize;
|
||||
LongBlockSize = LogicalBlockSize;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -411,33 +488,45 @@ namespace DiscImageChef.Core.Devices
|
||||
{
|
||||
dev.Read16(out _, out _, 0, false, true, false, 0, LogicalBlockSize, 0, BlocksToRead, false,
|
||||
timeout, out _);
|
||||
if(dev.Error) BlocksToRead /= 2;
|
||||
|
||||
if(dev.Error)
|
||||
BlocksToRead /= 2;
|
||||
}
|
||||
else if(read12)
|
||||
{
|
||||
dev.Read12(out _, out _, 0, false, false, false, false, 0, LogicalBlockSize, 0, BlocksToRead, false,
|
||||
timeout, out _);
|
||||
if(dev.Error) BlocksToRead /= 2;
|
||||
|
||||
if(dev.Error)
|
||||
BlocksToRead /= 2;
|
||||
}
|
||||
else if(read10)
|
||||
{
|
||||
dev.Read10(out _, out _, 0, false, true, false, false, 0, LogicalBlockSize, 0, (ushort)BlocksToRead,
|
||||
timeout, out _);
|
||||
if(dev.Error) BlocksToRead /= 2;
|
||||
|
||||
if(dev.Error)
|
||||
BlocksToRead /= 2;
|
||||
}
|
||||
else if(read6)
|
||||
{
|
||||
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;
|
||||
ErrorMessage = $"Device error {dev.LastError} trying to guess ideal transfer length.";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -467,7 +556,8 @@ namespace DiscImageChef.Core.Devices
|
||||
else if(plextorReadRaw)
|
||||
sense = dev.PlextorReadRawDvd(out buffer, out senseBuf, (uint)block, LongBlockSize, timeout,
|
||||
out duration);
|
||||
else return true;
|
||||
else
|
||||
return true;
|
||||
else
|
||||
{
|
||||
if(read16)
|
||||
@@ -482,12 +572,16 @@ namespace DiscImageChef.Core.Devices
|
||||
else if(read6)
|
||||
sense = dev.Read6(out buffer, out senseBuf, (uint)block, LogicalBlockSize, (byte)count, timeout,
|
||||
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));
|
||||
|
||||
return sense;
|
||||
}
|
||||
|
||||
@@ -496,8 +590,10 @@ namespace DiscImageChef.Core.Devices
|
||||
bool sense = true;
|
||||
duration = 0;
|
||||
|
||||
if(seek6) sense = dev.Seek6(out _, (uint)block, timeout, out duration);
|
||||
else if(seek10) sense = dev.Seek10(out _, (uint)block, timeout, out duration);
|
||||
if(seek6)
|
||||
sense = dev.Seek6(out _, (uint)block, timeout, out duration);
|
||||
else if(seek10)
|
||||
sense = dev.Seek10(out _, (uint)block, timeout, out duration);
|
||||
|
||||
return sense;
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ using DiscImageChef.CommonTypes.Metadata;
|
||||
using DiscImageChef.Console;
|
||||
using DiscImageChef.Decoders.ATA;
|
||||
using DiscImageChef.Devices;
|
||||
using Identify = DiscImageChef.CommonTypes.Structs.Devices.ATA.Identify;
|
||||
|
||||
namespace DiscImageChef.Core.Devices.Report
|
||||
{
|
||||
|
||||
@@ -34,9 +34,11 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using DiscImageChef.CommonTypes.Metadata;
|
||||
using DiscImageChef.CommonTypes.Structs.Devices.SCSI;
|
||||
using DiscImageChef.Console;
|
||||
using DiscImageChef.Decoders.SCSI;
|
||||
using DiscImageChef.Devices;
|
||||
using Inquiry = DiscImageChef.CommonTypes.Structs.Devices.SCSI.Inquiry;
|
||||
|
||||
namespace DiscImageChef.Core.Devices.Report
|
||||
{
|
||||
@@ -52,12 +54,12 @@ namespace DiscImageChef.Core.Devices.Report
|
||||
if(sense)
|
||||
return null;
|
||||
|
||||
Inquiry.SCSIInquiry? decodedNullable = Inquiry.Decode(buffer);
|
||||
Inquiry? decodedNullable = Inquiry.Decode(buffer);
|
||||
|
||||
if(!decodedNullable.HasValue)
|
||||
return null;
|
||||
|
||||
Inquiry.SCSIInquiry decoded = decodedNullable.Value;
|
||||
Inquiry decoded = decodedNullable.Value;
|
||||
|
||||
// Clear Seagate serial number
|
||||
if(decoded.SeagatePresent &&
|
||||
|
||||
@@ -32,38 +32,39 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using DiscImageChef.CommonTypes.Structs.Devices.ATA;
|
||||
using DiscImageChef.Core.Logging;
|
||||
using DiscImageChef.Decoders.ATA;
|
||||
|
||||
namespace DiscImageChef.Core.Devices.Scanning
|
||||
{
|
||||
/// <summary>
|
||||
/// Implements scanning the media from an ATA device
|
||||
/// </summary>
|
||||
/// <summary>Implements scanning the media from an ATA device</summary>
|
||||
public partial class MediaScan
|
||||
{
|
||||
/// <summary>
|
||||
/// Scans the media from an ATA device
|
||||
/// </summary>
|
||||
/// <summary>Scans the media from an ATA device</summary>
|
||||
/// <returns>Scanning results</returns>
|
||||
ScanResults Ata()
|
||||
{
|
||||
ScanResults results = new ScanResults();
|
||||
bool sense;
|
||||
var results = new ScanResults();
|
||||
bool sense;
|
||||
results.Blocks = 0;
|
||||
const ushort ATA_PROFILE = 0x0001;
|
||||
const uint TIMEOUT = 5;
|
||||
|
||||
sense = dev.AtaIdentify(out byte[] cmdBuf, out _);
|
||||
if(!sense && Identify.Decode(cmdBuf).HasValue)
|
||||
|
||||
if(!sense &&
|
||||
Identify.Decode(cmdBuf).HasValue)
|
||||
{
|
||||
// Initializate reader
|
||||
Reader ataReader = new Reader(dev, TIMEOUT, cmdBuf);
|
||||
var ataReader = new Reader(dev, TIMEOUT, cmdBuf);
|
||||
|
||||
// Fill reader blocks
|
||||
results.Blocks = ataReader.GetDeviceBlocks();
|
||||
|
||||
if(ataReader.FindReadCommand())
|
||||
{
|
||||
StoppingErrorMessage?.Invoke(ataReader.ErrorMessage);
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
@@ -71,14 +72,17 @@ namespace DiscImageChef.Core.Devices.Scanning
|
||||
if(ataReader.GetBlockSize())
|
||||
{
|
||||
StoppingErrorMessage?.Invoke(ataReader.ErrorMessage);
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
uint blockSize = ataReader.LogicalBlockSize;
|
||||
|
||||
// Check how many blocks to read, if error show and return
|
||||
if(ataReader.GetBlocksToRead())
|
||||
{
|
||||
StoppingErrorMessage?.Invoke(ataReader.ErrorMessage);
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
@@ -108,11 +112,12 @@ namespace DiscImageChef.Core.Devices.Scanning
|
||||
|
||||
double seekCur;
|
||||
|
||||
Random rnd = new Random();
|
||||
var rnd = new Random();
|
||||
|
||||
MhddLog mhddLog;
|
||||
IbgLog ibgLog;
|
||||
double duration;
|
||||
|
||||
if(ataReader.IsLba)
|
||||
{
|
||||
UpdateStatus?.Invoke($"Reading {blocksToRead} sectors at a time.");
|
||||
@@ -125,15 +130,23 @@ namespace DiscImageChef.Core.Devices.Scanning
|
||||
DateTime timeSpeedStart = DateTime.UtcNow;
|
||||
ulong sectorSpeedStart = 0;
|
||||
InitProgress?.Invoke();
|
||||
|
||||
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
|
||||
if(currentSpeed > results.MaxSpeed && currentSpeed != 0) results.MaxSpeed = currentSpeed;
|
||||
if(currentSpeed < results.MinSpeed && currentSpeed != 0) results.MinSpeed = currentSpeed;
|
||||
if(currentSpeed > results.MaxSpeed &&
|
||||
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
|
||||
|
||||
UpdateProgress?.Invoke($"Reading sector {i} of {results.Blocks} ({currentSpeed:F3} MiB/sec.)",
|
||||
@@ -143,12 +156,18 @@ namespace DiscImageChef.Core.Devices.Scanning
|
||||
|
||||
if(!error)
|
||||
{
|
||||
if(duration >= 500) results.F += blocksToRead;
|
||||
else if(duration >= 150) results.E += blocksToRead;
|
||||
else if(duration >= 50) results.D += blocksToRead;
|
||||
else if(duration >= 10) results.C += blocksToRead;
|
||||
else if(duration >= 3) results.B += blocksToRead;
|
||||
else results.A += blocksToRead;
|
||||
if(duration >= 500)
|
||||
results.F += blocksToRead;
|
||||
else if(duration >= 150)
|
||||
results.E += blocksToRead;
|
||||
else if(duration >= 50)
|
||||
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);
|
||||
mhddLog.Write(i, duration);
|
||||
@@ -158,7 +177,9 @@ namespace DiscImageChef.Core.Devices.Scanning
|
||||
{
|
||||
ScanUnreadable?.Invoke(i);
|
||||
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);
|
||||
|
||||
@@ -168,10 +189,12 @@ namespace DiscImageChef.Core.Devices.Scanning
|
||||
sectorSpeedStart += blocksToRead;
|
||||
|
||||
double elapsed = (DateTime.UtcNow - timeSpeedStart).TotalSeconds;
|
||||
if(elapsed < 1) continue;
|
||||
|
||||
currentSpeed = sectorSpeedStart * blockSize / (1048576 * elapsed);
|
||||
ScanSpeed?.Invoke(i, currentSpeed * 1024);
|
||||
if(elapsed < 1)
|
||||
continue;
|
||||
|
||||
currentSpeed = (sectorSpeedStart * blockSize) / (1048576 * elapsed);
|
||||
ScanSpeed?.Invoke(i, currentSpeed * 1024);
|
||||
sectorSpeedStart = 0;
|
||||
timeSpeedStart = DateTime.UtcNow;
|
||||
}
|
||||
@@ -179,16 +202,19 @@ namespace DiscImageChef.Core.Devices.Scanning
|
||||
end = DateTime.UtcNow;
|
||||
EndProgress?.Invoke();
|
||||
mhddLog.Close();
|
||||
|
||||
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),
|
||||
devicePath);
|
||||
|
||||
InitProgress?.Invoke();
|
||||
|
||||
if(ataReader.CanSeekLba)
|
||||
for(int i = 0; i < SEEK_TIMES; i++)
|
||||
{
|
||||
if(aborted) break;
|
||||
if(aborted)
|
||||
break;
|
||||
|
||||
uint seekPos = (uint)rnd.Next((int)results.Blocks);
|
||||
|
||||
@@ -197,8 +223,13 @@ namespace DiscImageChef.Core.Devices.Scanning
|
||||
ataReader.Seek(seekPos, out seekCur);
|
||||
|
||||
#pragma warning disable RECS0018 // Comparison of floating point numbers with equality operator
|
||||
if(seekCur > results.SeekMax && seekCur != 0) results.SeekMax = seekCur;
|
||||
if(seekCur < results.SeekMin && seekCur != 0) results.SeekMin = seekCur;
|
||||
if(seekCur > results.SeekMax &&
|
||||
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
|
||||
|
||||
results.SeekTotal += seekCur;
|
||||
@@ -219,34 +250,45 @@ namespace DiscImageChef.Core.Devices.Scanning
|
||||
DateTime timeSpeedStart = DateTime.UtcNow;
|
||||
ulong sectorSpeedStart = 0;
|
||||
InitProgress?.Invoke();
|
||||
|
||||
for(ushort cy = 0; cy < cylinders; cy++)
|
||||
{
|
||||
for(byte hd = 0; hd < heads; hd++)
|
||||
{
|
||||
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
|
||||
if(currentSpeed > results.MaxSpeed && currentSpeed != 0)
|
||||
if(currentSpeed > results.MaxSpeed &&
|
||||
currentSpeed != 0)
|
||||
results.MaxSpeed = currentSpeed;
|
||||
if(currentSpeed < results.MinSpeed && currentSpeed != 0)
|
||||
|
||||
if(currentSpeed < results.MinSpeed &&
|
||||
currentSpeed != 0)
|
||||
results.MinSpeed = currentSpeed;
|
||||
#pragma warning restore RECS0018 // Comparison of floating point numbers with equality operator
|
||||
|
||||
PulseProgress
|
||||
?.Invoke($"Reading cylinder {cy} head {hd} sector {sc} ({currentSpeed:F3} MiB/sec.)");
|
||||
PulseProgress?.
|
||||
Invoke($"Reading cylinder {cy} head {hd} sector {sc} ({currentSpeed:F3} MiB/sec.)");
|
||||
|
||||
bool error = ataReader.ReadChs(out cmdBuf, cy, hd, sc, out duration);
|
||||
|
||||
if(!error)
|
||||
{
|
||||
if(duration >= 500) results.F += blocksToRead;
|
||||
else if(duration >= 150) results.E += blocksToRead;
|
||||
else if(duration >= 50) results.D += blocksToRead;
|
||||
else if(duration >= 10) results.C += blocksToRead;
|
||||
else if(duration >= 3) results.B += blocksToRead;
|
||||
else results.A += blocksToRead;
|
||||
if(duration >= 500)
|
||||
results.F += blocksToRead;
|
||||
else if(duration >= 150)
|
||||
results.E += blocksToRead;
|
||||
else if(duration >= 50)
|
||||
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);
|
||||
mhddLog.Write(currentBlock, duration);
|
||||
@@ -266,10 +308,12 @@ namespace DiscImageChef.Core.Devices.Scanning
|
||||
currentBlock++;
|
||||
|
||||
double elapsed = (DateTime.UtcNow - timeSpeedStart).TotalSeconds;
|
||||
if(elapsed < 1) continue;
|
||||
|
||||
currentSpeed = sectorSpeedStart * blockSize / (1048576 * elapsed);
|
||||
ScanSpeed?.Invoke(currentBlock, currentSpeed * 1024);
|
||||
if(elapsed < 1)
|
||||
continue;
|
||||
|
||||
currentSpeed = (sectorSpeedStart * blockSize) / (1048576 * elapsed);
|
||||
ScanSpeed?.Invoke(currentBlock, currentSpeed * 1024);
|
||||
sectorSpeedStart = 0;
|
||||
timeSpeedStart = DateTime.UtcNow;
|
||||
}
|
||||
@@ -279,29 +323,37 @@ namespace DiscImageChef.Core.Devices.Scanning
|
||||
end = DateTime.UtcNow;
|
||||
EndProgress?.Invoke();
|
||||
mhddLog.Close();
|
||||
|
||||
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),
|
||||
devicePath);
|
||||
|
||||
InitProgress?.Invoke();
|
||||
|
||||
if(ataReader.CanSeek)
|
||||
for(int i = 0; i < SEEK_TIMES; i++)
|
||||
{
|
||||
if(aborted) break;
|
||||
if(aborted)
|
||||
break;
|
||||
|
||||
ushort seekCy = (ushort)rnd.Next(cylinders);
|
||||
byte seekHd = (byte)rnd.Next(heads);
|
||||
byte seekSc = (byte)rnd.Next(sectors);
|
||||
|
||||
PulseProgress
|
||||
?.Invoke($"\rSeeking to cylinder {seekCy}, head {seekHd}, sector {seekSc}...\t\t");
|
||||
PulseProgress?.
|
||||
Invoke($"\rSeeking to cylinder {seekCy}, head {seekHd}, sector {seekSc}...\t\t");
|
||||
|
||||
ataReader.SeekChs(seekCy, seekHd, seekSc, out seekCur);
|
||||
|
||||
#pragma warning disable RECS0018 // Comparison of floating point numbers with equality operator
|
||||
if(seekCur > results.SeekMax && seekCur != 0) results.SeekMax = seekCur;
|
||||
if(seekCur < results.SeekMin && seekCur != 0) results.SeekMin = seekCur;
|
||||
if(seekCur > results.SeekMax &&
|
||||
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
|
||||
|
||||
results.SeekTotal += seekCur;
|
||||
@@ -313,13 +365,14 @@ namespace DiscImageChef.Core.Devices.Scanning
|
||||
|
||||
results.ProcessingTime /= 1000;
|
||||
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;
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
StoppingErrorMessage?.Invoke("Unable to communicate with ATA device.");
|
||||
|
||||
return results;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using DiscImageChef.CommonTypes.Structs.Devices.SCSI;
|
||||
using DiscImageChef.Console;
|
||||
using DiscImageChef.Core.Logging;
|
||||
using DiscImageChef.Decoders.CD;
|
||||
@@ -42,18 +43,16 @@ using DiscImageChef.Devices;
|
||||
|
||||
namespace DiscImageChef.Core.Devices.Scanning
|
||||
{
|
||||
/// <summary>
|
||||
/// Implements scanning the media from an SCSI device
|
||||
/// </summary>
|
||||
/// <summary>Implements scanning the media from an SCSI device</summary>
|
||||
public partial class MediaScan
|
||||
{
|
||||
ScanResults Scsi()
|
||||
{
|
||||
ScanResults results = new ScanResults();
|
||||
MhddLog mhddLog;
|
||||
IbgLog ibgLog;
|
||||
byte[] senseBuf;
|
||||
bool sense = false;
|
||||
var results = new ScanResults();
|
||||
MhddLog mhddLog;
|
||||
IbgLog ibgLog;
|
||||
byte[] senseBuf;
|
||||
bool sense = false;
|
||||
results.Blocks = 0;
|
||||
uint blockSize = 0;
|
||||
ushort currentProfile = 0x0001;
|
||||
@@ -61,20 +60,25 @@ namespace DiscImageChef.Core.Devices.Scanning
|
||||
if(dev.IsRemovable)
|
||||
{
|
||||
sense = dev.ScsiTestUnitReady(out senseBuf, dev.Timeout, out _);
|
||||
|
||||
if(sense)
|
||||
{
|
||||
InitProgress?.Invoke();
|
||||
FixedSense? decSense = Sense.DecodeFixed(senseBuf);
|
||||
|
||||
if(decSense.HasValue)
|
||||
if(decSense.Value.ASC == 0x3A)
|
||||
{
|
||||
int leftRetries = 5;
|
||||
|
||||
while(leftRetries > 0)
|
||||
{
|
||||
PulseProgress?.Invoke("Waiting for drive to become ready");
|
||||
Thread.Sleep(2000);
|
||||
sense = dev.ScsiTestUnitReady(out senseBuf, dev.Timeout, out _);
|
||||
if(!sense) break;
|
||||
|
||||
if(!sense)
|
||||
break;
|
||||
|
||||
leftRetries--;
|
||||
}
|
||||
@@ -82,59 +86,72 @@ namespace DiscImageChef.Core.Devices.Scanning
|
||||
if(sense)
|
||||
{
|
||||
StoppingErrorMessage?.Invoke("Please insert media in drive");
|
||||
|
||||
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;
|
||||
|
||||
while(leftRetries > 0)
|
||||
{
|
||||
PulseProgress?.Invoke("Waiting for drive to become ready");
|
||||
Thread.Sleep(2000);
|
||||
sense = dev.ScsiTestUnitReady(out senseBuf, dev.Timeout, out _);
|
||||
if(!sense) break;
|
||||
|
||||
if(!sense)
|
||||
break;
|
||||
|
||||
leftRetries--;
|
||||
}
|
||||
|
||||
if(sense)
|
||||
{
|
||||
StoppingErrorMessage
|
||||
?.Invoke($"Error testing unit was ready:\n{Sense.PrettifySense(senseBuf)}");
|
||||
StoppingErrorMessage?.
|
||||
Invoke($"Error testing unit was ready:\n{Sense.PrettifySense(senseBuf)}");
|
||||
|
||||
return results;
|
||||
}
|
||||
}
|
||||
|
||||
// These should be trapped by the OS but seems in some cases they're not
|
||||
else if(decSense.Value.ASC == 0x28)
|
||||
{
|
||||
int leftRetries = 10;
|
||||
|
||||
while(leftRetries > 0)
|
||||
{
|
||||
PulseProgress?.Invoke("Waiting for drive to become ready");
|
||||
Thread.Sleep(2000);
|
||||
sense = dev.ScsiTestUnitReady(out senseBuf, dev.Timeout, out _);
|
||||
if(!sense) break;
|
||||
|
||||
if(!sense)
|
||||
break;
|
||||
|
||||
leftRetries--;
|
||||
}
|
||||
|
||||
if(sense)
|
||||
{
|
||||
StoppingErrorMessage
|
||||
?.Invoke($"Error testing unit was ready:\n{Sense.PrettifySense(senseBuf)}");
|
||||
StoppingErrorMessage?.
|
||||
Invoke($"Error testing unit was ready:\n{Sense.PrettifySense(senseBuf)}");
|
||||
|
||||
return results;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
StoppingErrorMessage
|
||||
?.Invoke($"Error testing unit was ready:\n{Sense.PrettifySense(senseBuf)}");
|
||||
StoppingErrorMessage?.
|
||||
Invoke($"Error testing unit was ready:\n{Sense.PrettifySense(senseBuf)}");
|
||||
|
||||
return results;
|
||||
}
|
||||
else
|
||||
{
|
||||
StoppingErrorMessage?.Invoke("Unknown testing unit was ready.");
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
@@ -154,19 +171,23 @@ namespace DiscImageChef.Core.Devices.Scanning
|
||||
case PeripheralDeviceTypes.WriteOnceDevice:
|
||||
scsiReader = new Reader(dev, dev.Timeout, null);
|
||||
results.Blocks = scsiReader.GetDeviceBlocks();
|
||||
|
||||
if(scsiReader.FindReadCommand())
|
||||
{
|
||||
StoppingErrorMessage?.Invoke("Unable to read medium.");
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
blockSize = scsiReader.LogicalBlockSize;
|
||||
|
||||
if(results.Blocks != 0 && blockSize != 0)
|
||||
if(results.Blocks != 0 &&
|
||||
blockSize != 0)
|
||||
{
|
||||
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;
|
||||
@@ -174,12 +195,14 @@ namespace DiscImageChef.Core.Devices.Scanning
|
||||
StoppingErrorMessage?.Invoke("Scanning will never be supported on SCSI Streaming Devices." +
|
||||
Environment.NewLine +
|
||||
"It has no sense to do it, and it will put too much strain on the tape.");
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
if(results.Blocks == 0)
|
||||
{
|
||||
StoppingErrorMessage?.Invoke("Unable to read medium or empty medium present...");
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
@@ -190,6 +213,7 @@ namespace DiscImageChef.Core.Devices.Scanning
|
||||
{
|
||||
sense = dev.GetConfiguration(out byte[] cmdBuf, out senseBuf, 0, MmcGetConfigurationRt.Current,
|
||||
dev.Timeout, out _);
|
||||
|
||||
if(!sense)
|
||||
{
|
||||
Features.SeparatedFeatures ftr = Features.Separate(cmdBuf);
|
||||
@@ -207,6 +231,7 @@ namespace DiscImageChef.Core.Devices.Scanning
|
||||
case 0x0022: break;
|
||||
default:
|
||||
compactDisc = false;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -214,13 +239,17 @@ namespace DiscImageChef.Core.Devices.Scanning
|
||||
if(compactDisc)
|
||||
{
|
||||
currentProfile = 0x0008;
|
||||
|
||||
// We discarded all discs that falsify a TOC before requesting a real TOC
|
||||
// No TOC, no CD (or an empty one)
|
||||
bool tocSense = dev.ReadRawToc(out cmdBuf, out senseBuf, 1, dev.Timeout, out _);
|
||||
if(!tocSense) toc = FullTOC.Decode(cmdBuf);
|
||||
bool tocSense = dev.ReadRawToc(out cmdBuf, out senseBuf, 1, dev.Timeout, out _);
|
||||
|
||||
if(!tocSense)
|
||||
toc = FullTOC.Decode(cmdBuf);
|
||||
}
|
||||
}
|
||||
else compactDisc = false;
|
||||
else
|
||||
compactDisc = false;
|
||||
|
||||
uint blocksToRead = 64;
|
||||
|
||||
@@ -245,6 +274,7 @@ namespace DiscImageChef.Core.Devices.Scanning
|
||||
if(toc == null)
|
||||
{
|
||||
StoppingErrorMessage?.Invoke("Error trying to decode TOC...");
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
@@ -252,7 +282,8 @@ namespace DiscImageChef.Core.Devices.Scanning
|
||||
MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None, MmcSubchannel.None,
|
||||
dev.Timeout, out _);
|
||||
|
||||
if(readcd) UpdateStatus?.Invoke("Using MMC READ CD command.");
|
||||
if(readcd)
|
||||
UpdateStatus?.Invoke("Using MMC READ CD command.");
|
||||
|
||||
start = DateTime.UtcNow;
|
||||
|
||||
@@ -263,16 +294,21 @@ namespace DiscImageChef.Core.Devices.Scanning
|
||||
sense = dev.ReadCd(out _, out senseBuf, 0, 2352, blocksToRead, MmcSectorTypes.AllTypes, false,
|
||||
false, true, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None,
|
||||
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)
|
||||
{
|
||||
StoppingErrorMessage
|
||||
?.Invoke($"Device error {dev.LastError} trying to guess ideal transfer length.");
|
||||
StoppingErrorMessage?.
|
||||
Invoke($"Device error {dev.LastError} trying to guess ideal transfer length.");
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
@@ -285,17 +321,25 @@ namespace DiscImageChef.Core.Devices.Scanning
|
||||
ulong sectorSpeedStart = 0;
|
||||
|
||||
InitProgress?.Invoke();
|
||||
|
||||
for(ulong i = 0; i < results.Blocks; i += blocksToRead)
|
||||
{
|
||||
if(aborted) break;
|
||||
if(aborted)
|
||||
break;
|
||||
|
||||
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
|
||||
if(currentSpeed > results.MaxSpeed && currentSpeed != 0) results.MaxSpeed = currentSpeed;
|
||||
if(currentSpeed < results.MinSpeed && currentSpeed != 0) results.MinSpeed = currentSpeed;
|
||||
if(currentSpeed > results.MaxSpeed &&
|
||||
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
|
||||
|
||||
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,
|
||||
false, false, true, MmcHeaderCodes.AllHeaders, true, true,
|
||||
MmcErrorField.None, MmcSubchannel.None, dev.Timeout, out cmdDuration);
|
||||
|
||||
results.ProcessingTime += cmdDuration;
|
||||
}
|
||||
|
||||
if(!sense)
|
||||
{
|
||||
if(cmdDuration >= 500) results.F += blocksToRead;
|
||||
else if(cmdDuration >= 150) results.E += blocksToRead;
|
||||
else if(cmdDuration >= 50) results.D += blocksToRead;
|
||||
else if(cmdDuration >= 10) results.C += blocksToRead;
|
||||
else if(cmdDuration >= 3) results.B += blocksToRead;
|
||||
else results.A += blocksToRead;
|
||||
if(cmdDuration >= 500)
|
||||
results.F += blocksToRead;
|
||||
else if(cmdDuration >= 150)
|
||||
results.E += blocksToRead;
|
||||
else if(cmdDuration >= 50)
|
||||
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);
|
||||
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));
|
||||
|
||||
FixedSense? senseDecoded = Sense.DecodeFixed(senseBuf);
|
||||
|
||||
if(senseDecoded.HasValue)
|
||||
{
|
||||
// TODO: This error happens when changing from track type afaik. Need to solve that more cleanly
|
||||
// LOGICAL BLOCK ADDRESS OUT OF RANGE
|
||||
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
|
||||
// are in a track where subchannel indicates data)
|
||||
(senseDecoded.Value.ASC != 0x64 || senseDecoded.Value.ASCQ != 0x00))
|
||||
{
|
||||
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);
|
||||
mhddLog.Write(i, cmdDuration < 500 ? 65535 : cmdDuration);
|
||||
@@ -349,7 +404,9 @@ namespace DiscImageChef.Core.Devices.Scanning
|
||||
{
|
||||
ScanUnreadable?.Invoke(i);
|
||||
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);
|
||||
|
||||
@@ -360,10 +417,12 @@ namespace DiscImageChef.Core.Devices.Scanning
|
||||
sectorSpeedStart += blocksToRead;
|
||||
|
||||
double elapsed = (DateTime.UtcNow - timeSpeedStart).TotalSeconds;
|
||||
if(elapsed < 1) continue;
|
||||
|
||||
currentSpeed = sectorSpeedStart * blockSize / (1048576 * elapsed);
|
||||
ScanSpeed?.Invoke(i, currentSpeed * 1024);
|
||||
if(elapsed < 1)
|
||||
continue;
|
||||
|
||||
currentSpeed = (sectorSpeedStart * blockSize) / (1048576 * elapsed);
|
||||
ScanSpeed?.Invoke(i, currentSpeed * 1024);
|
||||
sectorSpeedStart = 0;
|
||||
timeSpeedStart = DateTime.UtcNow;
|
||||
}
|
||||
@@ -371,8 +430,9 @@ namespace DiscImageChef.Core.Devices.Scanning
|
||||
end = DateTime.UtcNow;
|
||||
EndProgress?.Invoke();
|
||||
mhddLog.Close();
|
||||
|
||||
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),
|
||||
devicePath);
|
||||
}
|
||||
@@ -389,15 +449,23 @@ namespace DiscImageChef.Core.Devices.Scanning
|
||||
ulong sectorSpeedStart = 0;
|
||||
|
||||
InitProgress?.Invoke();
|
||||
|
||||
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
|
||||
if(currentSpeed > results.MaxSpeed && currentSpeed != 0) results.MaxSpeed = currentSpeed;
|
||||
if(currentSpeed < results.MinSpeed && currentSpeed != 0) results.MinSpeed = currentSpeed;
|
||||
if(currentSpeed > results.MaxSpeed &&
|
||||
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
|
||||
|
||||
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);
|
||||
results.ProcessingTime += cmdDuration;
|
||||
|
||||
if(!sense && !dev.Error)
|
||||
if(!sense &&
|
||||
!dev.Error)
|
||||
{
|
||||
if(cmdDuration >= 500) results.F += blocksToRead;
|
||||
else if(cmdDuration >= 150) results.E += blocksToRead;
|
||||
else if(cmdDuration >= 50) results.D += blocksToRead;
|
||||
else if(cmdDuration >= 10) results.C += blocksToRead;
|
||||
else if(cmdDuration >= 3) results.B += blocksToRead;
|
||||
else results.A += blocksToRead;
|
||||
if(cmdDuration >= 500)
|
||||
results.F += blocksToRead;
|
||||
else if(cmdDuration >= 150)
|
||||
results.E += blocksToRead;
|
||||
else if(cmdDuration >= 50)
|
||||
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);
|
||||
mhddLog.Write(i, cmdDuration);
|
||||
ibgLog.Write(i, currentSpeed * 1024);
|
||||
}
|
||||
|
||||
// TODO: Separate errors on kind of errors.
|
||||
else
|
||||
{
|
||||
ScanUnreadable?.Invoke(i);
|
||||
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);
|
||||
ibgLog.Write(i, 0);
|
||||
@@ -433,10 +511,12 @@ namespace DiscImageChef.Core.Devices.Scanning
|
||||
sectorSpeedStart += blocksToRead;
|
||||
|
||||
double elapsed = (DateTime.UtcNow - timeSpeedStart).TotalSeconds;
|
||||
if(elapsed < 1) continue;
|
||||
|
||||
currentSpeed = sectorSpeedStart * blockSize / (1048576 * elapsed);
|
||||
ScanSpeed?.Invoke(i, currentSpeed * 1024);
|
||||
if(elapsed < 1)
|
||||
continue;
|
||||
|
||||
currentSpeed = (sectorSpeedStart * blockSize) / (1048576 * elapsed);
|
||||
ScanSpeed?.Invoke(i, currentSpeed * 1024);
|
||||
sectorSpeedStart = 0;
|
||||
timeSpeedStart = DateTime.UtcNow;
|
||||
}
|
||||
@@ -444,8 +524,9 @@ namespace DiscImageChef.Core.Devices.Scanning
|
||||
end = DateTime.UtcNow;
|
||||
EndProgress?.Invoke();
|
||||
mhddLog.Close();
|
||||
|
||||
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),
|
||||
devicePath);
|
||||
}
|
||||
@@ -455,24 +536,34 @@ namespace DiscImageChef.Core.Devices.Scanning
|
||||
results.SeekTotal = 0;
|
||||
const int SEEK_TIMES = 1000;
|
||||
|
||||
Random rnd = new Random();
|
||||
var rnd = new Random();
|
||||
|
||||
InitProgress?.Invoke();
|
||||
|
||||
for(int i = 0; i < SEEK_TIMES; i++)
|
||||
{
|
||||
if(aborted) break;
|
||||
if(aborted)
|
||||
break;
|
||||
|
||||
uint seekPos = (uint)rnd.Next((int)results.Blocks);
|
||||
|
||||
PulseProgress?.Invoke($"Seeking to sector {seekPos}...\t\t");
|
||||
|
||||
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
|
||||
if(seekCur > results.SeekMax && seekCur != 0) results.SeekMax = seekCur;
|
||||
if(seekCur < results.SeekMin && seekCur != 0) results.SeekMin = seekCur;
|
||||
if(seekCur > results.SeekMax &&
|
||||
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
|
||||
|
||||
results.SeekTotal += seekCur;
|
||||
@@ -483,7 +574,7 @@ namespace DiscImageChef.Core.Devices.Scanning
|
||||
|
||||
results.ProcessingTime /= 1000;
|
||||
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;
|
||||
|
||||
return results;
|
||||
|
||||
@@ -36,6 +36,7 @@ using System.Text;
|
||||
using DiscImageChef.CommonTypes.Enums;
|
||||
using DiscImageChef.CommonTypes.Interfaces;
|
||||
using DiscImageChef.CommonTypes.Structs;
|
||||
using DiscImageChef.CommonTypes.Structs.Devices.SCSI;
|
||||
using DiscImageChef.Console;
|
||||
using DiscImageChef.Decoders.ATA;
|
||||
using DiscImageChef.Decoders.Bluray;
|
||||
@@ -47,6 +48,7 @@ using DiscImageChef.Decoders.Xbox;
|
||||
using Schemas;
|
||||
using DDS = DiscImageChef.Decoders.DVD.DDS;
|
||||
using DMI = DiscImageChef.Decoders.Xbox.DMI;
|
||||
using Inquiry = DiscImageChef.Decoders.SCSI.Inquiry;
|
||||
using Session = DiscImageChef.CommonTypes.Structs.Session;
|
||||
using Tuple = DiscImageChef.Decoders.PCMCIA.Tuple;
|
||||
|
||||
@@ -57,55 +59,80 @@ namespace DiscImageChef.Core
|
||||
public static void PrintImageInfo(IMediaImage imageFormat)
|
||||
{
|
||||
DicConsole.WriteLine("Image information:");
|
||||
|
||||
if(!string.IsNullOrWhiteSpace(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) &&
|
||||
!string.IsNullOrWhiteSpace(imageFormat.Info.ApplicationVersion))
|
||||
DicConsole.WriteLine("Was created with {0} version {1}", imageFormat.Info.Application,
|
||||
imageFormat.Info.ApplicationVersion);
|
||||
else if(!string.IsNullOrWhiteSpace(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("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);
|
||||
|
||||
if(!string.IsNullOrWhiteSpace(imageFormat.Info.Creator))
|
||||
DicConsole.WriteLine("Created by: {0}", imageFormat.Info.Creator);
|
||||
|
||||
if(imageFormat.Info.CreationTime != DateTime.MinValue)
|
||||
DicConsole.WriteLine("Created on {0}", imageFormat.Info.CreationTime);
|
||||
|
||||
if(imageFormat.Info.LastModificationTime != DateTime.MinValue)
|
||||
DicConsole.WriteLine("Last modified on {0}", imageFormat.Info.LastModificationTime);
|
||||
|
||||
DicConsole.WriteLine("Contains a media of type {0} and XML type {1}", imageFormat.Info.MediaType,
|
||||
imageFormat.Info.XmlMediaType);
|
||||
|
||||
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))
|
||||
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,
|
||||
imageFormat.Info.LastMediaSequence);
|
||||
|
||||
if(!string.IsNullOrWhiteSpace(imageFormat.Info.MediaTitle))
|
||||
DicConsole.WriteLine("Media title: {0}", imageFormat.Info.MediaTitle);
|
||||
|
||||
if(!string.IsNullOrWhiteSpace(imageFormat.Info.MediaManufacturer))
|
||||
DicConsole.WriteLine("Media manufacturer: {0}", imageFormat.Info.MediaManufacturer);
|
||||
|
||||
if(!string.IsNullOrWhiteSpace(imageFormat.Info.MediaModel))
|
||||
DicConsole.WriteLine("Media model: {0}", imageFormat.Info.MediaModel);
|
||||
|
||||
if(!string.IsNullOrWhiteSpace(imageFormat.Info.MediaSerialNumber))
|
||||
DicConsole.WriteLine("Media serial number: {0}", imageFormat.Info.MediaSerialNumber);
|
||||
|
||||
if(!string.IsNullOrWhiteSpace(imageFormat.Info.MediaBarcode))
|
||||
DicConsole.WriteLine("Media barcode: {0}", imageFormat.Info.MediaBarcode);
|
||||
|
||||
if(!string.IsNullOrWhiteSpace(imageFormat.Info.MediaPartNumber))
|
||||
DicConsole.WriteLine("Media part number: {0}", imageFormat.Info.MediaPartNumber);
|
||||
|
||||
if(!string.IsNullOrWhiteSpace(imageFormat.Info.DriveManufacturer))
|
||||
DicConsole.WriteLine("Drive manufacturer: {0}", imageFormat.Info.DriveManufacturer);
|
||||
|
||||
if(!string.IsNullOrWhiteSpace(imageFormat.Info.DriveModel))
|
||||
DicConsole.WriteLine("Drive model: {0}", imageFormat.Info.DriveModel);
|
||||
|
||||
if(!string.IsNullOrWhiteSpace(imageFormat.Info.DriveSerialNumber))
|
||||
DicConsole.WriteLine("Drive serial number: {0}", imageFormat.Info.DriveSerialNumber);
|
||||
|
||||
if(!string.IsNullOrWhiteSpace(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.XmlMediaType != XmlMediaType.OpticalDisc &&
|
||||
(!(imageFormat is ITapeImage tapeImage) || !tapeImage.IsTape))
|
||||
@@ -113,19 +140,25 @@ namespace DiscImageChef.Core
|
||||
imageFormat.Info.Cylinders, imageFormat.Info.Heads,
|
||||
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);
|
||||
|
||||
foreach(MediaTagType tag in imageFormat.Info.ReadableMediaTags.OrderBy(t => t))
|
||||
DicConsole.Write("{0} ", tag);
|
||||
|
||||
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);
|
||||
|
||||
foreach(SectorTagType tag in imageFormat.Info.ReadableSectorTags.OrderBy(t => t))
|
||||
DicConsole.Write("{0} ", tag);
|
||||
|
||||
DicConsole.WriteLine();
|
||||
}
|
||||
|
||||
@@ -139,6 +172,7 @@ namespace DiscImageChef.Core
|
||||
byte[] inquiry = imageFormat.ReadDiskTag(MediaTagType.SCSI_INQUIRY);
|
||||
|
||||
scsiDeviceType = (PeripheralDeviceTypes)(inquiry[0] & 0x1F);
|
||||
|
||||
if(inquiry.Length >= 16)
|
||||
{
|
||||
scsiVendorId = new byte[8];
|
||||
@@ -213,6 +247,7 @@ namespace DiscImageChef.Core
|
||||
if(toc.Length > 0)
|
||||
{
|
||||
ushort dataLen = Swapping.Swap(BitConverter.ToUInt16(toc, 0));
|
||||
|
||||
if(dataLen + 2 != toc.Length)
|
||||
{
|
||||
byte[] tmp = new byte[toc.Length + 2];
|
||||
@@ -236,6 +271,7 @@ namespace DiscImageChef.Core
|
||||
if(pma.Length > 0)
|
||||
{
|
||||
ushort dataLen = Swapping.Swap(BitConverter.ToUInt16(pma, 0));
|
||||
|
||||
if(dataLen + 2 != pma.Length)
|
||||
{
|
||||
byte[] tmp = new byte[pma.Length + 2];
|
||||
@@ -257,6 +293,7 @@ namespace DiscImageChef.Core
|
||||
byte[] atip = imageFormat.ReadDiskTag(MediaTagType.CD_ATIP);
|
||||
|
||||
uint dataLen = Swapping.Swap(BitConverter.ToUInt32(atip, 0));
|
||||
|
||||
if(dataLen + 4 != atip.Length)
|
||||
{
|
||||
byte[] tmp = new byte[atip.Length + 4];
|
||||
@@ -279,6 +316,7 @@ namespace DiscImageChef.Core
|
||||
byte[] cdtext = imageFormat.ReadDiskTag(MediaTagType.CD_TEXT);
|
||||
|
||||
uint dataLen = Swapping.Swap(BitConverter.ToUInt32(cdtext, 0));
|
||||
|
||||
if(dataLen + 4 != cdtext.Length)
|
||||
{
|
||||
byte[] tmp = new byte[cdtext.Length + 4];
|
||||
@@ -302,6 +340,7 @@ namespace DiscImageChef.Core
|
||||
|
||||
DicConsole.WriteLine("CompactDisc Media Catalogue Number contained in image: {0}",
|
||||
Encoding.UTF8.GetString(mcn));
|
||||
|
||||
DicConsole.WriteLine();
|
||||
}
|
||||
|
||||
@@ -362,6 +401,7 @@ namespace DiscImageChef.Core
|
||||
|
||||
DicConsole.WriteLine("PCMCIA CIS:");
|
||||
Tuple[] tuples = CIS.GetTuples(cis);
|
||||
|
||||
if(tuples != null)
|
||||
foreach(Tuple tuple in tuples)
|
||||
switch(tuple.Code)
|
||||
@@ -371,12 +411,15 @@ namespace DiscImageChef.Core
|
||||
case TupleCodes.CISTPL_DEVICEGEO:
|
||||
case TupleCodes.CISTPL_DEVICEGEO_A:
|
||||
DicConsole.WriteLine("{0}", CIS.PrettifyDeviceGeometryTuple(tuple));
|
||||
|
||||
break;
|
||||
case TupleCodes.CISTPL_MANFID:
|
||||
DicConsole.WriteLine("{0}", CIS.PrettifyManufacturerIdentificationTuple(tuple));
|
||||
|
||||
break;
|
||||
case TupleCodes.CISTPL_VERS_1:
|
||||
DicConsole.WriteLine("{0}", CIS.PrettifyLevel1VersionTuple(tuple));
|
||||
|
||||
break;
|
||||
case TupleCodes.CISTPL_ALTSTR:
|
||||
case TupleCodes.CISTPL_BAR:
|
||||
@@ -414,13 +457,16 @@ namespace DiscImageChef.Core
|
||||
case TupleCodes.CISTPL_VERS_2:
|
||||
DicConsole.DebugWriteLine("Device-Info command", "Found undecoded tuple ID {0}",
|
||||
tuple.Code);
|
||||
|
||||
break;
|
||||
default:
|
||||
DicConsole.DebugWriteLine("Device-Info command", "Found unknown tuple ID 0x{0:X2}",
|
||||
(byte)tuple.Code);
|
||||
|
||||
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 &&
|
||||
@@ -521,6 +567,7 @@ namespace DiscImageChef.Core
|
||||
if(DMI.IsXbox(xdmi))
|
||||
{
|
||||
DMI.XboxDMI? xmi = DMI.DecodeXbox(xdmi);
|
||||
|
||||
if(xmi.HasValue)
|
||||
{
|
||||
DicConsole.WriteLine("Xbox DMI contained in image:");
|
||||
@@ -532,6 +579,7 @@ namespace DiscImageChef.Core
|
||||
if(DMI.IsXbox360(xdmi))
|
||||
{
|
||||
DMI.Xbox360DMI? xmi = DMI.DecodeXbox360(xdmi);
|
||||
|
||||
if(xmi.HasValue)
|
||||
{
|
||||
DicConsole.WriteLine("Xbox 360 DMI contained in image:");
|
||||
@@ -555,16 +603,21 @@ namespace DiscImageChef.Core
|
||||
{
|
||||
try
|
||||
{
|
||||
if(opticalImage.Sessions != null && opticalImage.Sessions.Count > 0)
|
||||
if(opticalImage.Sessions != null &&
|
||||
opticalImage.Sessions.Count > 0)
|
||||
{
|
||||
DicConsole.WriteLine("Image sessions:");
|
||||
|
||||
DicConsole.WriteLine("{0,-9}{1,-13}{2,-12}{3,-12}{4,-12}", "Session", "First track",
|
||||
"Last track", "Start", "End");
|
||||
|
||||
DicConsole.WriteLine("=========================================================");
|
||||
|
||||
foreach(Session session in opticalImage.Sessions)
|
||||
DicConsole.WriteLine("{0,-9}{1,-13}{2,-12}{3,-12}{4,-12}", session.SessionSequence,
|
||||
session.StartTrack, session.EndTrack, session.StartSector,
|
||||
session.EndSector);
|
||||
|
||||
DicConsole.WriteLine();
|
||||
}
|
||||
}
|
||||
@@ -575,18 +628,23 @@ namespace DiscImageChef.Core
|
||||
|
||||
try
|
||||
{
|
||||
if(opticalImage.Tracks != null && opticalImage.Tracks.Count > 0)
|
||||
if(opticalImage.Tracks != null &&
|
||||
opticalImage.Tracks.Count > 0)
|
||||
{
|
||||
DicConsole.WriteLine("Image tracks:");
|
||||
|
||||
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");
|
||||
DicConsole
|
||||
.WriteLine("=================================================================================");
|
||||
|
||||
DicConsole.
|
||||
WriteLine("=================================================================================");
|
||||
|
||||
foreach(Track track in opticalImage.Tracks)
|
||||
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.TrackRawBytesPerSector, track.TrackSubchannelType,
|
||||
track.TrackPregap, track.TrackStartSector, track.TrackEndSector);
|
||||
|
||||
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 MODEL_STRING = "Model";
|
||||
@@ -616,19 +675,31 @@ namespace DiscImageChef.Core
|
||||
|
||||
foreach(DumpHardwareType dump in imageFormat.DumpHardware)
|
||||
{
|
||||
if(dump.Manufacturer?.Length > manufacturerLen) manufacturerLen = dump.Manufacturer.Length;
|
||||
if(dump.Model?.Length > modelLen) modelLen = dump.Model.Length;
|
||||
if(dump.Serial?.Length > serialLen) serialLen = dump.Serial.Length;
|
||||
if(dump.Manufacturer?.Length > manufacturerLen)
|
||||
manufacturerLen = dump.Manufacturer.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)
|
||||
softwareLen = dump.Software.Name.Length;
|
||||
|
||||
if(dump.Software?.Version?.Length > versionLen)
|
||||
versionLen = dump.Software.Version.Length;
|
||||
|
||||
if(dump.Software?.OperatingSystem?.Length > osLen)
|
||||
osLen = dump.Software.OperatingSystem.Length;
|
||||
|
||||
foreach(ExtentType extent in dump.Extents)
|
||||
{
|
||||
if($"{extent.Start}".Length > sectorLen) sectorLen = $"{extent.Start}".Length;
|
||||
if($"{extent.End}".Length > sectorLen) sectorLen = $"{extent.End}".Length;
|
||||
if($"{extent.Start}".Length > sectorLen)
|
||||
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 +
|
||||
sectorLen + sectorLen];
|
||||
for(int i = 0; i < separator.Length; i++) separator[i] = '=';
|
||||
|
||||
for(int i = 0; i < separator.Length; i++)
|
||||
separator[i] = '=';
|
||||
|
||||
string format =
|
||||
$"{{0,-{manufacturerLen}}}{{1,-{modelLen}}}{{2,-{serialLen}}}{{3,-{softwareLen}}}{{4,-{versionLen}}}{{5,-{osLen}}}{{6,-{sectorLen}}}{{7,-{sectorLen}}}";
|
||||
|
||||
DicConsole.WriteLine("Dump hardware information:");
|
||||
|
||||
DicConsole.WriteLine(format, MANUFACTURER_STRING, MODEL_STRING, SERIAL_STRING, SOFTWARE_STRING,
|
||||
VERSION_STRING, OS_STRING, START_STRING, END_STRING);
|
||||
|
||||
DicConsole.WriteLine(new string(separator));
|
||||
|
||||
foreach(DumpHardwareType dump in imageFormat.DumpHardware)
|
||||
{
|
||||
foreach(ExtentType extent in dump.Extents)
|
||||
|
||||
@@ -36,6 +36,7 @@ using System.Linq;
|
||||
using System.Threading;
|
||||
using DiscImageChef.CommonTypes;
|
||||
using DiscImageChef.CommonTypes.Enums;
|
||||
using DiscImageChef.CommonTypes.Structs.Devices.SCSI;
|
||||
using DiscImageChef.Console;
|
||||
using DiscImageChef.Core.Media.Detection;
|
||||
using DiscImageChef.Decoders.CD;
|
||||
@@ -47,6 +48,7 @@ using DiscImageChef.Decoders.Xbox;
|
||||
using DiscImageChef.Devices;
|
||||
using DeviceInfo = DiscImageChef.Core.Devices.Info.DeviceInfo;
|
||||
using DMI = DiscImageChef.Decoders.Xbox.DMI;
|
||||
using Inquiry = DiscImageChef.Decoders.SCSI.Inquiry;
|
||||
|
||||
namespace DiscImageChef.Core.Media.Info
|
||||
{
|
||||
@@ -1289,7 +1291,7 @@ namespace DiscImageChef.Core.Media.Info
|
||||
|
||||
if(!sense)
|
||||
{
|
||||
Inquiry.SCSIInquiry? inq = Inquiry.Decode(inqBuffer);
|
||||
var inq = CommonTypes.Structs.Devices.SCSI.Inquiry.Decode(inqBuffer);
|
||||
|
||||
if(inq.HasValue &&
|
||||
inq.Value.KreonPresent)
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
// Copyright © 2011-2020 Natalia Portillo
|
||||
// ****************************************************************************/
|
||||
|
||||
using DiscImageChef.CommonTypes.Structs.Devices.SCSI;
|
||||
using DiscImageChef.Console;
|
||||
using DiscImageChef.Decoders.SCSI;
|
||||
|
||||
@@ -41,22 +42,26 @@ namespace DiscImageChef.Core
|
||||
{
|
||||
DicConsole.WriteLine(Modes.PrettifyModeHeader(decMode.Header, devType));
|
||||
|
||||
if(decMode.Pages == null) return;
|
||||
if(decMode.Pages == null)
|
||||
return;
|
||||
|
||||
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);
|
||||
switch(page.Page)
|
||||
{
|
||||
case 0x00:
|
||||
{
|
||||
if(devType == PeripheralDeviceTypes.MultiMediaDevice && page.Subpage == 0)
|
||||
if(devType == PeripheralDeviceTypes.MultiMediaDevice &&
|
||||
page.Subpage == 0)
|
||||
DicConsole.WriteLine(Modes.PrettifyModePage_00_SFF(page.PageResponse));
|
||||
else
|
||||
{
|
||||
if(page.Subpage != 0)
|
||||
DicConsole.WriteLine("Found unknown vendor mode page {0:X2}h subpage {1:X2}h",
|
||||
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;
|
||||
@@ -67,42 +72,53 @@ namespace DiscImageChef.Core
|
||||
DicConsole.WriteLine(devType == PeripheralDeviceTypes.MultiMediaDevice
|
||||
? Modes.PrettifyModePage_01_MMC(page.PageResponse)
|
||||
: Modes.PrettifyModePage_01(page.PageResponse));
|
||||
else goto default;
|
||||
else
|
||||
goto default;
|
||||
|
||||
break;
|
||||
}
|
||||
case 0x02:
|
||||
{
|
||||
if(page.Subpage == 0) DicConsole.WriteLine(Modes.PrettifyModePage_02(page.PageResponse));
|
||||
else goto default;
|
||||
if(page.Subpage == 0)
|
||||
DicConsole.WriteLine(Modes.PrettifyModePage_02(page.PageResponse));
|
||||
else
|
||||
goto default;
|
||||
|
||||
break;
|
||||
}
|
||||
case 0x03:
|
||||
{
|
||||
if(page.Subpage == 0) DicConsole.WriteLine(Modes.PrettifyModePage_03(page.PageResponse));
|
||||
else goto default;
|
||||
if(page.Subpage == 0)
|
||||
DicConsole.WriteLine(Modes.PrettifyModePage_03(page.PageResponse));
|
||||
else
|
||||
goto default;
|
||||
|
||||
break;
|
||||
}
|
||||
case 0x04:
|
||||
{
|
||||
if(page.Subpage == 0) DicConsole.WriteLine(Modes.PrettifyModePage_04(page.PageResponse));
|
||||
else goto default;
|
||||
if(page.Subpage == 0)
|
||||
DicConsole.WriteLine(Modes.PrettifyModePage_04(page.PageResponse));
|
||||
else
|
||||
goto default;
|
||||
|
||||
break;
|
||||
}
|
||||
case 0x05:
|
||||
{
|
||||
if(page.Subpage == 0) DicConsole.WriteLine(Modes.PrettifyModePage_05(page.PageResponse));
|
||||
else goto default;
|
||||
if(page.Subpage == 0)
|
||||
DicConsole.WriteLine(Modes.PrettifyModePage_05(page.PageResponse));
|
||||
else
|
||||
goto default;
|
||||
|
||||
break;
|
||||
}
|
||||
case 0x06:
|
||||
{
|
||||
if(page.Subpage == 0) DicConsole.WriteLine(Modes.PrettifyModePage_06(page.PageResponse));
|
||||
else goto default;
|
||||
if(page.Subpage == 0)
|
||||
DicConsole.WriteLine(Modes.PrettifyModePage_06(page.PageResponse));
|
||||
else
|
||||
goto default;
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -112,51 +128,64 @@ namespace DiscImageChef.Core
|
||||
DicConsole.WriteLine(devType == PeripheralDeviceTypes.MultiMediaDevice
|
||||
? Modes.PrettifyModePage_07_MMC(page.PageResponse)
|
||||
: Modes.PrettifyModePage_07(page.PageResponse));
|
||||
else goto default;
|
||||
else
|
||||
goto default;
|
||||
|
||||
break;
|
||||
}
|
||||
case 0x08:
|
||||
{
|
||||
if(page.Subpage == 0) DicConsole.WriteLine(Modes.PrettifyModePage_08(page.PageResponse));
|
||||
else goto default;
|
||||
if(page.Subpage == 0)
|
||||
DicConsole.WriteLine(Modes.PrettifyModePage_08(page.PageResponse));
|
||||
else
|
||||
goto default;
|
||||
|
||||
break;
|
||||
}
|
||||
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)
|
||||
DicConsole.WriteLine(Modes.PrettifyModePage_0A_S01(page.PageResponse));
|
||||
else goto default;
|
||||
else
|
||||
goto default;
|
||||
|
||||
break;
|
||||
}
|
||||
case 0x0B:
|
||||
{
|
||||
if(page.Subpage == 0) DicConsole.WriteLine(Modes.PrettifyModePage_0B(page.PageResponse));
|
||||
else goto default;
|
||||
if(page.Subpage == 0)
|
||||
DicConsole.WriteLine(Modes.PrettifyModePage_0B(page.PageResponse));
|
||||
else
|
||||
goto default;
|
||||
|
||||
break;
|
||||
}
|
||||
case 0x0D:
|
||||
{
|
||||
if(page.Subpage == 0) DicConsole.WriteLine(Modes.PrettifyModePage_0D(page.PageResponse));
|
||||
else goto default;
|
||||
if(page.Subpage == 0)
|
||||
DicConsole.WriteLine(Modes.PrettifyModePage_0D(page.PageResponse));
|
||||
else
|
||||
goto default;
|
||||
|
||||
break;
|
||||
}
|
||||
case 0x0E:
|
||||
{
|
||||
if(page.Subpage == 0) DicConsole.WriteLine(Modes.PrettifyModePage_0E(page.PageResponse));
|
||||
else goto default;
|
||||
if(page.Subpage == 0)
|
||||
DicConsole.WriteLine(Modes.PrettifyModePage_0E(page.PageResponse));
|
||||
else
|
||||
goto default;
|
||||
|
||||
break;
|
||||
}
|
||||
case 0x0F:
|
||||
{
|
||||
if(page.Subpage == 0) DicConsole.WriteLine(Modes.PrettifyModePage_0F(page.PageResponse));
|
||||
else goto default;
|
||||
if(page.Subpage == 0)
|
||||
DicConsole.WriteLine(Modes.PrettifyModePage_0F(page.PageResponse));
|
||||
else
|
||||
goto default;
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -166,14 +195,17 @@ namespace DiscImageChef.Core
|
||||
DicConsole.WriteLine(devType == PeripheralDeviceTypes.SequentialAccess
|
||||
? Modes.PrettifyModePage_10_SSC(page.PageResponse)
|
||||
: Modes.PrettifyModePage_10(page.PageResponse));
|
||||
else goto default;
|
||||
else
|
||||
goto default;
|
||||
|
||||
break;
|
||||
}
|
||||
case 0x11:
|
||||
{
|
||||
if(page.Subpage == 0) DicConsole.WriteLine(Modes.PrettifyModePage_11(page.PageResponse));
|
||||
else goto default;
|
||||
if(page.Subpage == 0)
|
||||
DicConsole.WriteLine(Modes.PrettifyModePage_11(page.PageResponse));
|
||||
else
|
||||
goto default;
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -181,24 +213,30 @@ namespace DiscImageChef.Core
|
||||
case 0x13:
|
||||
case 0x14:
|
||||
{
|
||||
if(page.Subpage == 0) DicConsole.WriteLine(Modes.PrettifyModePage_12_13_14(page.PageResponse));
|
||||
else goto default;
|
||||
if(page.Subpage == 0)
|
||||
DicConsole.WriteLine(Modes.PrettifyModePage_12_13_14(page.PageResponse));
|
||||
else
|
||||
goto default;
|
||||
|
||||
break;
|
||||
}
|
||||
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)
|
||||
DicConsole.WriteLine(Modes.PrettifyModePage_1A_S01(page.PageResponse));
|
||||
else goto default;
|
||||
else
|
||||
goto default;
|
||||
|
||||
break;
|
||||
}
|
||||
case 0x1B:
|
||||
{
|
||||
if(page.Subpage == 0) DicConsole.WriteLine(Modes.PrettifyModePage_1B(page.PageResponse));
|
||||
else goto default;
|
||||
if(page.Subpage == 0)
|
||||
DicConsole.WriteLine(Modes.PrettifyModePage_1B(page.PageResponse));
|
||||
else
|
||||
goto default;
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -210,14 +248,17 @@ namespace DiscImageChef.Core
|
||||
: Modes.PrettifyModePage_1C(page.PageResponse));
|
||||
else if(page.Subpage == 1)
|
||||
DicConsole.WriteLine(Modes.PrettifyModePage_1C_S01(page.PageResponse));
|
||||
else goto default;
|
||||
else
|
||||
goto default;
|
||||
|
||||
break;
|
||||
}
|
||||
case 0x1D:
|
||||
{
|
||||
if(page.Subpage == 0) DicConsole.WriteLine(Modes.PrettifyModePage_1D(page.PageResponse));
|
||||
else goto default;
|
||||
if(page.Subpage == 0)
|
||||
DicConsole.WriteLine(Modes.PrettifyModePage_1D(page.PageResponse));
|
||||
else
|
||||
goto default;
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -225,7 +266,8 @@ namespace DiscImageChef.Core
|
||||
{
|
||||
if(StringHandlers.CToString(vendorId).Trim() == "CERTANCE")
|
||||
DicConsole.WriteLine(Modes.PrettifyCertanceModePage_21(page.PageResponse));
|
||||
else goto default;
|
||||
else
|
||||
goto default;
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -233,7 +275,8 @@ namespace DiscImageChef.Core
|
||||
{
|
||||
if(StringHandlers.CToString(vendorId).Trim() == "CERTANCE")
|
||||
DicConsole.WriteLine(Modes.PrettifyCertanceModePage_22(page.PageResponse));
|
||||
else goto default;
|
||||
else
|
||||
goto default;
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -241,14 +284,17 @@ namespace DiscImageChef.Core
|
||||
{
|
||||
if(StringHandlers.CToString(vendorId).Trim() == "IBM")
|
||||
DicConsole.WriteLine(Modes.PrettifyIBMModePage_24(page.PageResponse));
|
||||
else goto default;
|
||||
else
|
||||
goto default;
|
||||
|
||||
break;
|
||||
}
|
||||
case 0x2A:
|
||||
{
|
||||
if(page.Subpage == 0) DicConsole.WriteLine(Modes.PrettifyModePage_2A(page.PageResponse));
|
||||
else goto default;
|
||||
if(page.Subpage == 0)
|
||||
DicConsole.WriteLine(Modes.PrettifyModePage_2A(page.PageResponse));
|
||||
else
|
||||
goto default;
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -256,7 +302,8 @@ namespace DiscImageChef.Core
|
||||
{
|
||||
if(StringHandlers.CToString(vendorId).Trim() == "IBM")
|
||||
DicConsole.WriteLine(Modes.PrettifyIBMModePage_2F(page.PageResponse));
|
||||
else goto default;
|
||||
else
|
||||
goto default;
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -264,7 +311,8 @@ namespace DiscImageChef.Core
|
||||
{
|
||||
if(Modes.IsAppleModePage_30(page.PageResponse))
|
||||
DicConsole.WriteLine("Drive identifies as Apple OEM drive");
|
||||
else goto default;
|
||||
else
|
||||
goto default;
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -272,7 +320,8 @@ namespace DiscImageChef.Core
|
||||
{
|
||||
if(StringHandlers.CToString(vendorId).Trim() == "HP")
|
||||
DicConsole.WriteLine(Modes.PrettifyHPModePage_3B(page.PageResponse));
|
||||
else goto default;
|
||||
else
|
||||
goto default;
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -280,7 +329,8 @@ namespace DiscImageChef.Core
|
||||
{
|
||||
if(StringHandlers.CToString(vendorId).Trim() == "HP")
|
||||
DicConsole.WriteLine(Modes.PrettifyHPModePage_3C(page.PageResponse));
|
||||
else goto default;
|
||||
else
|
||||
goto default;
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -290,7 +340,8 @@ namespace DiscImageChef.Core
|
||||
DicConsole.WriteLine(Modes.PrettifyIBMModePage_3D(page.PageResponse));
|
||||
else if(StringHandlers.CToString(vendorId).Trim() == "HP")
|
||||
DicConsole.WriteLine(Modes.PrettifyHPModePage_3D(page.PageResponse));
|
||||
else goto default;
|
||||
else
|
||||
goto default;
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -300,7 +351,8 @@ namespace DiscImageChef.Core
|
||||
DicConsole.WriteLine(Modes.PrettifyFujitsuModePage_3E(page.PageResponse));
|
||||
else if(StringHandlers.CToString(vendorId).Trim() == "HP")
|
||||
DicConsole.WriteLine(Modes.PrettifyHPModePage_3E(page.PageResponse));
|
||||
else goto default;
|
||||
else
|
||||
goto default;
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -309,7 +361,9 @@ namespace DiscImageChef.Core
|
||||
if(page.Subpage != 0)
|
||||
DicConsole.WriteLine("Found unknown mode page {0:X2}h subpage {1:X2}h", page.Page,
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -681,7 +681,7 @@ namespace DiscImageChef.Core
|
||||
|
||||
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.Value.CurrentCylinders > 0 &&
|
||||
|
||||
Submodule DiscImageChef.Decoders updated: 785638f5f6...1856c6ddb4
@@ -37,7 +37,8 @@ using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using DiscImageChef.CommonTypes.Enums;
|
||||
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.MMC;
|
||||
using DiscImageChef.Decoders.SecureDigital;
|
||||
@@ -50,6 +51,7 @@ using FileAttributes = DiscImageChef.Devices.Windows.FileAttributes;
|
||||
using FileFlags = DiscImageChef.Devices.Linux.FileFlags;
|
||||
using FileMode = DiscImageChef.Devices.Windows.FileMode;
|
||||
using FileShare = DiscImageChef.Devices.Windows.FileShare;
|
||||
using Inquiry = DiscImageChef.CommonTypes.Structs.Devices.SCSI.Inquiry;
|
||||
using PlatformID = DiscImageChef.CommonTypes.Interop.PlatformID;
|
||||
using VendorString = DiscImageChef.Decoders.SecureDigital.VendorString;
|
||||
|
||||
@@ -761,7 +763,7 @@ namespace DiscImageChef.Devices
|
||||
|
||||
if(!scsiSense)
|
||||
{
|
||||
Inquiry.SCSIInquiry? inquiry = Inquiry.Decode(inqBuf);
|
||||
Inquiry? inquiry = Inquiry.Decode(inqBuf);
|
||||
|
||||
Type = DeviceType.SCSI;
|
||||
bool serialSense = ScsiInquiry(out inqBuf, out _, 0x80);
|
||||
|
||||
@@ -32,211 +32,156 @@
|
||||
|
||||
using DiscImageChef.CommonTypes.Enums;
|
||||
using DiscImageChef.CommonTypes.Interop;
|
||||
using DiscImageChef.Decoders.SCSI;
|
||||
using DiscImageChef.CommonTypes.Structs.Devices.SCSI;
|
||||
|
||||
namespace DiscImageChef.Devices
|
||||
{
|
||||
public partial class Device
|
||||
{
|
||||
private readonly ushort usbVendor;
|
||||
private readonly ushort usbProduct;
|
||||
private readonly ulong firewireGuid;
|
||||
private readonly uint firewireModel;
|
||||
private readonly uint firewireVendor;
|
||||
readonly ushort usbVendor;
|
||||
readonly ushort usbProduct;
|
||||
readonly ulong firewireGuid;
|
||||
readonly uint firewireModel;
|
||||
readonly uint firewireVendor;
|
||||
|
||||
// MMC and SecureDigital, values that need to be get with card idle, something that may
|
||||
// not be possible to do but usually is already done by the SDHCI driver.
|
||||
private readonly byte[] cachedCsd;
|
||||
private readonly byte[] cachedCid;
|
||||
private readonly byte[] cachedScr;
|
||||
private readonly byte[] cachedOcr;
|
||||
readonly byte[] cachedCsd;
|
||||
readonly byte[] cachedCid;
|
||||
readonly byte[] cachedScr;
|
||||
readonly byte[] cachedOcr;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Platform ID for this device
|
||||
/// </summary>
|
||||
/// <summary>Gets the Platform ID for this device</summary>
|
||||
/// <value>The Platform ID</value>
|
||||
public PlatformID PlatformId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the file handle representing this device
|
||||
/// </summary>
|
||||
/// <summary>Gets the file handle representing this device</summary>
|
||||
/// <value>The file handle</value>
|
||||
public object FileHandle { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the standard timeout for commands sent to this device
|
||||
/// </summary>
|
||||
/// <summary>Gets or sets the standard timeout for commands sent to this device</summary>
|
||||
/// <value>The timeout in seconds</value>
|
||||
public uint Timeout { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this <see cref="Device" /> is in error.
|
||||
/// </summary>
|
||||
/// <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>
|
||||
public bool Error { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the last error number.
|
||||
/// </summary>
|
||||
/// <summary>Gets the last error number.</summary>
|
||||
/// <value>The last error.</value>
|
||||
public int LastError { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the device type.
|
||||
/// </summary>
|
||||
/// <summary>Gets the device type.</summary>
|
||||
/// <value>The device type.</value>
|
||||
public DeviceType Type { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the device's manufacturer
|
||||
/// </summary>
|
||||
/// <summary>Gets the device's manufacturer</summary>
|
||||
/// <value>The manufacturer.</value>
|
||||
public string Manufacturer { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the device model
|
||||
/// </summary>
|
||||
/// <summary>Gets the device model</summary>
|
||||
/// <value>The model.</value>
|
||||
public string Model { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the device's firmware version.
|
||||
/// </summary>
|
||||
/// <summary>Gets the device's firmware version.</summary>
|
||||
/// <value>The firmware version.</value>
|
||||
public string FirmwareRevision { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the device's serial number.
|
||||
/// </summary>
|
||||
/// <summary>Gets the device's serial number.</summary>
|
||||
/// <value>The serial number.</value>
|
||||
public string Serial { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the device's SCSI peripheral device type
|
||||
/// </summary>
|
||||
/// <summary>Gets the device's SCSI peripheral device type</summary>
|
||||
/// <value>The SCSI peripheral device type.</value>
|
||||
public PeripheralDeviceTypes ScsiType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this device's media is removable.
|
||||
/// </summary>
|
||||
/// <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>
|
||||
public bool IsRemovable { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this device is attached via USB.
|
||||
/// </summary>
|
||||
/// <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>
|
||||
public bool IsUsb { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the USB vendor ID.
|
||||
/// </summary>
|
||||
/// <summary>Gets the USB vendor ID.</summary>
|
||||
/// <value>The USB vendor ID.</value>
|
||||
public ushort UsbVendorId => usbVendor;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the USB product ID.
|
||||
/// </summary>
|
||||
/// <summary>Gets the USB product ID.</summary>
|
||||
/// <value>The USB product ID.</value>
|
||||
public ushort UsbProductId => usbProduct;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the USB descriptors.
|
||||
/// </summary>
|
||||
/// <summary>Gets the USB descriptors.</summary>
|
||||
/// <value>The USB descriptors.</value>
|
||||
public byte[] UsbDescriptors { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the USB manufacturer string.
|
||||
/// </summary>
|
||||
/// <summary>Gets the USB manufacturer string.</summary>
|
||||
/// <value>The USB manufacturer string.</value>
|
||||
public string UsbManufacturerString { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the USB product string.
|
||||
/// </summary>
|
||||
/// <summary>Gets the USB product string.</summary>
|
||||
/// <value>The USB product string.</value>
|
||||
public string UsbProductString { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the USB serial string.
|
||||
/// </summary>
|
||||
/// <summary>Gets the USB serial string.</summary>
|
||||
/// <value>The USB serial string.</value>
|
||||
public string UsbSerialString { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this device is attached via FireWire.
|
||||
/// </summary>
|
||||
/// <summary>Gets a value indicating whether this device is attached via FireWire.</summary>
|
||||
/// <value><c>true</c> if this device is attached via FireWire; otherwise, <c>false</c>.</value>
|
||||
public bool IsFireWire { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the FireWire GUID
|
||||
/// </summary>
|
||||
/// <summary>Gets the FireWire GUID</summary>
|
||||
/// <value>The FireWire GUID.</value>
|
||||
public ulong FireWireGuid => firewireGuid;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the FireWire model number
|
||||
/// </summary>
|
||||
/// <summary>Gets the FireWire model number</summary>
|
||||
/// <value>The FireWire model.</value>
|
||||
public uint FireWireModel => firewireModel;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the FireWire model name.
|
||||
/// </summary>
|
||||
/// <summary>Gets the FireWire model name.</summary>
|
||||
/// <value>The FireWire model name.</value>
|
||||
public string FireWireModelName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the FireWire vendor number.
|
||||
/// </summary>
|
||||
/// <summary>Gets the FireWire vendor number.</summary>
|
||||
/// <value>The FireWire vendor number.</value>
|
||||
public uint FireWireVendor => firewireVendor;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the FireWire vendor name.
|
||||
/// </summary>
|
||||
/// <summary>Gets the FireWire vendor name.</summary>
|
||||
/// <value>The FireWire vendor name.</value>
|
||||
public string FireWireVendorName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this device is a CompactFlash device.
|
||||
/// </summary>
|
||||
/// <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>
|
||||
public bool IsCompactFlash { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this device is a PCMCIA device.
|
||||
/// </summary>
|
||||
/// <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>
|
||||
public bool IsPcmcia { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Contains the PCMCIA CIS if applicable
|
||||
/// </summary>
|
||||
/// <summary>Contains the PCMCIA CIS if applicable</summary>
|
||||
public byte[] Cis { get; }
|
||||
|
||||
private readonly Remote.Remote _remote;
|
||||
private bool? _isRemoteAdmin;
|
||||
readonly Remote.Remote _remote;
|
||||
bool? _isRemoteAdmin;
|
||||
|
||||
public bool IsRemoteAdmin
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_isRemoteAdmin is null) _isRemoteAdmin = _remote.IsRoot;
|
||||
if(_isRemoteAdmin is null)
|
||||
_isRemoteAdmin = _remote.IsRoot;
|
||||
|
||||
return _isRemoteAdmin == true;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsRemote => _remote != null;
|
||||
public string RemoteApplication => _remote?.ServerApplication;
|
||||
public string RemoteVersion => _remote?.ServerVersion;
|
||||
public string RemoteOperatingSystem => _remote?.ServerOperatingSystem;
|
||||
public bool IsRemote => _remote != null;
|
||||
public string RemoteApplication => _remote?.ServerApplication;
|
||||
public string RemoteVersion => _remote?.ServerVersion;
|
||||
public string RemoteOperatingSystem => _remote?.ServerOperatingSystem;
|
||||
public string RemoteOperatingSystemVersion => _remote?.ServerOperatingSystemVersion;
|
||||
public string RemoteArchitecture => _remote?.ServerArchitecture;
|
||||
public int RemoteProtocolVersion => _remote?.ServerProtocolVersion ?? 0;
|
||||
public string RemoteArchitecture => _remote?.ServerArchitecture;
|
||||
public int RemoteProtocolVersion => _remote?.ServerProtocolVersion ?? 0;
|
||||
}
|
||||
}
|
||||
@@ -35,17 +35,15 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using DiscImageChef.Decoders.ATA;
|
||||
using DiscImageChef.Decoders.SCSI;
|
||||
using DiscImageChef.CommonTypes.Structs.Devices.ATA;
|
||||
using DiscImageChef.CommonTypes.Structs.Devices.SCSI;
|
||||
using static DiscImageChef.Devices.FreeBSD.Extern;
|
||||
|
||||
namespace DiscImageChef.Devices.FreeBSD
|
||||
{
|
||||
static class ListDevices
|
||||
internal static class ListDevices
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a list of all known storage devices on FreeBSD
|
||||
/// </summary>
|
||||
/// <summary>Gets a list of all known storage devices on FreeBSD</summary>
|
||||
/// <returns>List of devices</returns>
|
||||
internal static DeviceInfo[] GetList()
|
||||
{
|
||||
@@ -54,15 +52,16 @@ namespace DiscImageChef.Devices.FreeBSD
|
||||
|
||||
foreach(string passDevice in passDevices)
|
||||
{
|
||||
DeviceInfo deviceInfo = new DeviceInfo();
|
||||
IntPtr dev = cam_open_device(passDevice, FileFlags.ReadWrite);
|
||||
CamDevice camDevice = (CamDevice)Marshal.PtrToStructure(dev, typeof(CamDevice));
|
||||
var deviceInfo = new DeviceInfo();
|
||||
IntPtr dev = cam_open_device(passDevice, FileFlags.ReadWrite);
|
||||
var camDevice = (CamDevice)Marshal.PtrToStructure(dev, typeof(CamDevice));
|
||||
|
||||
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;
|
||||
|
||||
@@ -73,6 +72,7 @@ namespace DiscImageChef.Devices.FreeBSD
|
||||
if(error < 0)
|
||||
{
|
||||
cam_freeccb(ccbPtr);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -96,6 +96,7 @@ namespace DiscImageChef.Devices.FreeBSD
|
||||
// Little-endian FreeBSD gives it resorted
|
||||
// Big-endian FreeBSD, no idea
|
||||
byte[] atadTneid = new byte[512];
|
||||
|
||||
for(int aIndex = 0; aIndex < 512; aIndex += 2)
|
||||
{
|
||||
atadTneid[aIndex] = cgd.ident_data[aIndex + 1];
|
||||
@@ -103,6 +104,7 @@ namespace DiscImageChef.Devices.FreeBSD
|
||||
}
|
||||
|
||||
Identify.IdentifyDevice? idt = Identify.Decode(atadTneid);
|
||||
|
||||
if(idt.HasValue)
|
||||
{
|
||||
string[] separated = idt.Value.Model.Split(' ');
|
||||
@@ -123,12 +125,15 @@ namespace DiscImageChef.Devices.FreeBSD
|
||||
deviceInfo.Supported = simName != "ata";
|
||||
}
|
||||
|
||||
if(cgd.protocol == CamProto.ProtoAtapi) goto case CamProto.ProtoScsi;
|
||||
if(cgd.protocol == CamProto.ProtoAtapi)
|
||||
goto case CamProto.ProtoScsi;
|
||||
|
||||
break;
|
||||
}
|
||||
case CamProto.ProtoScsi:
|
||||
{
|
||||
Inquiry.SCSIInquiry? inq = Inquiry.Decode(cgd.inq_data);
|
||||
Inquiry? inq = Inquiry.Decode(cgd.inq_data);
|
||||
|
||||
if(inq.HasValue)
|
||||
{
|
||||
deviceInfo.Vendor = StringHandlers.CToString(inq.Value.VendorIdentification).Trim();
|
||||
@@ -142,11 +147,13 @@ namespace DiscImageChef.Devices.FreeBSD
|
||||
case CamProto.ProtoNvme:
|
||||
deviceInfo.Bus = "NVMe";
|
||||
deviceInfo.Supported = false;
|
||||
|
||||
break;
|
||||
case CamProto.ProtoMmcsd:
|
||||
deviceInfo.Model = "Unknown card";
|
||||
deviceInfo.Bus = "MMC/SD";
|
||||
deviceInfo.Supported = false;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -33,31 +33,33 @@
|
||||
using System;
|
||||
using DiscImageChef.CommonTypes;
|
||||
using DiscImageChef.CommonTypes.Enums;
|
||||
using DiscImageChef.Decoders.ATA;
|
||||
using DiscImageChef.Decoders.SCSI;
|
||||
using DiscImageChef.CommonTypes.Structs.Devices.ATA;
|
||||
using DiscImageChef.CommonTypes.Structs.Devices.SCSI;
|
||||
using DiscImageChef.Decoders.SecureDigital;
|
||||
using DiscImageChef.Helpers;
|
||||
using VendorString = DiscImageChef.Decoders.SecureDigital.VendorString;
|
||||
|
||||
namespace DiscImageChef.DiscImages
|
||||
{
|
||||
public partial class DiscImageChef
|
||||
{
|
||||
/// <summary>
|
||||
/// Checks for media tags that may contain metadata and sets it up if not already set
|
||||
/// </summary>
|
||||
/// <summary>Checks for media tags that may contain metadata and sets it up if not already set</summary>
|
||||
void SetMetadataFromTags()
|
||||
{
|
||||
// Search for SecureDigital CID
|
||||
if(mediaTags.TryGetValue(MediaTagType.SD_CID, out byte[] sdCid))
|
||||
{
|
||||
CID decoded = Decoders.SecureDigital.Decoders.DecodeCID(sdCid);
|
||||
|
||||
if(string.IsNullOrWhiteSpace(imageInfo.DriveManufacturer))
|
||||
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))
|
||||
imageInfo.DriveFirmwareRevision =
|
||||
$"{(decoded.ProductRevision & 0xF0) >> 4:X2}.{decoded.ProductRevision & 0x0F:X2}";
|
||||
|
||||
if(string.IsNullOrWhiteSpace(imageInfo.DriveSerialNumber))
|
||||
imageInfo.DriveSerialNumber = $"{decoded.ProductSerialNumber}";
|
||||
}
|
||||
@@ -66,12 +68,17 @@ namespace DiscImageChef.DiscImages
|
||||
if(mediaTags.TryGetValue(MediaTagType.MMC_CID, out byte[] mmcCid))
|
||||
{
|
||||
Decoders.MMC.CID decoded = Decoders.MMC.Decoders.DecodeCID(mmcCid);
|
||||
|
||||
if(string.IsNullOrWhiteSpace(imageInfo.DriveManufacturer))
|
||||
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))
|
||||
imageInfo.DriveFirmwareRevision =
|
||||
$"{(decoded.ProductRevision & 0xF0) >> 4:X2}.{decoded.ProductRevision & 0x0F:X2}";
|
||||
|
||||
if(string.IsNullOrWhiteSpace(imageInfo.DriveSerialNumber))
|
||||
imageInfo.DriveSerialNumber = $"{decoded.ProductSerialNumber}";
|
||||
}
|
||||
@@ -79,15 +86,18 @@ namespace DiscImageChef.DiscImages
|
||||
// Search for SCSI INQUIRY
|
||||
if(mediaTags.TryGetValue(MediaTagType.SCSI_INQUIRY, out byte[] scsiInquiry))
|
||||
{
|
||||
Inquiry.SCSIInquiry? nullableInquiry = Inquiry.Decode(scsiInquiry);
|
||||
Inquiry? nullableInquiry = Inquiry.Decode(scsiInquiry);
|
||||
|
||||
if(nullableInquiry.HasValue)
|
||||
{
|
||||
Inquiry.SCSIInquiry inquiry = nullableInquiry.Value;
|
||||
Inquiry inquiry = nullableInquiry.Value;
|
||||
|
||||
if(string.IsNullOrWhiteSpace(imageInfo.DriveManufacturer))
|
||||
imageInfo.DriveManufacturer = StringHandlers.CToString(inquiry.VendorIdentification)?.Trim();
|
||||
|
||||
if(string.IsNullOrWhiteSpace(imageInfo.DriveModel))
|
||||
imageInfo.DriveModel = StringHandlers.CToString(inquiry.ProductIdentification)?.Trim();
|
||||
|
||||
if(string.IsNullOrWhiteSpace(imageInfo.DriveFirmwareRevision))
|
||||
imageInfo.DriveFirmwareRevision =
|
||||
StringHandlers.CToString(inquiry.ProductRevisionLevel)?.Trim();
|
||||
@@ -95,29 +105,34 @@ namespace DiscImageChef.DiscImages
|
||||
}
|
||||
|
||||
// Search for ATA or ATAPI IDENTIFY
|
||||
if(!mediaTags.TryGetValue(MediaTagType.ATA_IDENTIFY, out byte[] ataIdentify) &&
|
||||
!mediaTags.TryGetValue(MediaTagType.ATAPI_IDENTIFY, out ataIdentify)) return;
|
||||
if(!mediaTags.TryGetValue(MediaTagType.ATA_IDENTIFY, out byte[] ataIdentify) &&
|
||||
!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;
|
||||
|
||||
string[] separated = identify.Model.Split(' ');
|
||||
|
||||
if(separated.Length == 1)
|
||||
if(string.IsNullOrWhiteSpace(imageInfo.DriveModel)) imageInfo.DriveModel = separated[0];
|
||||
if(string.IsNullOrWhiteSpace(imageInfo.DriveModel))
|
||||
imageInfo.DriveModel = separated[0];
|
||||
else
|
||||
{
|
||||
if(string.IsNullOrWhiteSpace(imageInfo.DriveManufacturer))
|
||||
imageInfo.DriveManufacturer = separated[0];
|
||||
|
||||
if(string.IsNullOrWhiteSpace(imageInfo.DriveModel))
|
||||
imageInfo.DriveModel = separated[separated.Length - 1];
|
||||
}
|
||||
|
||||
if(string.IsNullOrWhiteSpace(imageInfo.DriveFirmwareRevision))
|
||||
imageInfo.DriveFirmwareRevision = identify.FirmwareRevision;
|
||||
|
||||
if(string.IsNullOrWhiteSpace(imageInfo.DriveSerialNumber))
|
||||
imageInfo.DriveSerialNumber = identify.SerialNumber;
|
||||
}
|
||||
@@ -225,9 +240,11 @@ namespace DiscImageChef.DiscImages
|
||||
// Gets a DDT entry
|
||||
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;
|
||||
imageStream.Position = outMemoryDdtPosition + Marshal.SizeOf<DdtHeader>();
|
||||
@@ -237,9 +254,11 @@ namespace DiscImageChef.DiscImages
|
||||
imageStream.Position = oldPosition;
|
||||
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);
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
@@ -248,8 +267,11 @@ namespace DiscImageChef.DiscImages
|
||||
{
|
||||
if(inMemoryDdt)
|
||||
{
|
||||
if(IsTape) tapeDdt[sectorAddress] = pointer;
|
||||
else userDataDdt[sectorAddress] = pointer;
|
||||
if(IsTape)
|
||||
tapeDdt[sectorAddress] = pointer;
|
||||
else
|
||||
userDataDdt[sectorAddress] = pointer;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ using DiscImageChef.CommonTypes;
|
||||
using DiscImageChef.CommonTypes.Enums;
|
||||
using DiscImageChef.CommonTypes.Exceptions;
|
||||
using DiscImageChef.CommonTypes.Interfaces;
|
||||
using DiscImageChef.Decoders.ATA;
|
||||
using DiscImageChef.CommonTypes.Structs.Devices.ATA;
|
||||
using DiscImageChef.Helpers;
|
||||
|
||||
namespace DiscImageChef.DiscImages
|
||||
@@ -54,7 +54,8 @@ namespace DiscImageChef.DiscImages
|
||||
|
||||
RsIdeHeader hdr = Marshal.ByteArrayToStructureLittleEndian<RsIdeHeader>(hdrB);
|
||||
|
||||
if(!hdr.magic.SequenceEqual(signature)) return false;
|
||||
if(!hdr.magic.SequenceEqual(signature))
|
||||
return false;
|
||||
|
||||
dataOff = hdr.dataOff;
|
||||
|
||||
@@ -72,7 +73,7 @@ namespace DiscImageChef.DiscImages
|
||||
{
|
||||
identify = new byte[512];
|
||||
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)
|
||||
{
|
||||
@@ -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.Heads = 16;
|
||||
@@ -114,7 +117,7 @@ namespace DiscImageChef.DiscImages
|
||||
|
||||
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));
|
||||
|
||||
@@ -123,11 +126,13 @@ namespace DiscImageChef.DiscImages
|
||||
|
||||
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");
|
||||
|
||||
byte[] buffer = new byte[512];
|
||||
Array.Copy(identify, 0, buffer, 0, 512);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ using System.Linq;
|
||||
using DiscImageChef.CommonTypes;
|
||||
using DiscImageChef.CommonTypes.Enums;
|
||||
using DiscImageChef.CommonTypes.Structs;
|
||||
using DiscImageChef.Decoders.ATA;
|
||||
using DiscImageChef.CommonTypes.Structs.Devices.ATA;
|
||||
using DiscImageChef.Helpers;
|
||||
using Schemas;
|
||||
using Version = DiscImageChef.CommonTypes.Interop.Version;
|
||||
@@ -47,37 +47,49 @@ namespace DiscImageChef.DiscImages
|
||||
public partial class RsIde
|
||||
{
|
||||
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";
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if(sectors > 63 * 16 * 1024)
|
||||
{
|
||||
ErrorMessage = "Too many sectors";
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!SupportedMediaTypes.Contains(mediaType))
|
||||
{
|
||||
ErrorMessage = $"Unsupport media format {mediaType}";
|
||||
|
||||
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)
|
||||
{
|
||||
ErrorMessage = $"Could not create new image file, exception {e.Message}";
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
IsWriting = true;
|
||||
ErrorMessage = null;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -86,17 +98,20 @@ namespace DiscImageChef.DiscImages
|
||||
if(tag != MediaTagType.ATA_IDENTIFY)
|
||||
{
|
||||
ErrorMessage = $"Unsupported media tag {tag}.";
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!IsWriting)
|
||||
{
|
||||
ErrorMessage = "Tried to write on a non-writable image";
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
identify = new byte[106];
|
||||
Array.Copy(data, 0, identify, 0, 106);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -105,26 +120,31 @@ namespace DiscImageChef.DiscImages
|
||||
if(!IsWriting)
|
||||
{
|
||||
ErrorMessage = "Tried to write on a non-writable image";
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if(data.Length != imageInfo.SectorSize)
|
||||
{
|
||||
ErrorMessage = "Incorrect data size";
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if(sectorAddress >= imageInfo.Sectors)
|
||||
{
|
||||
ErrorMessage = "Tried to write past image size";
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
writingStream.Seek((long)((ulong)Marshal.SizeOf<RsIdeHeader>() + sectorAddress * imageInfo.SectorSize),
|
||||
writingStream.Seek((long)((ulong)Marshal.SizeOf<RsIdeHeader>() + (sectorAddress * imageInfo.SectorSize)),
|
||||
SeekOrigin.Begin);
|
||||
|
||||
writingStream.Write(data, 0, data.Length);
|
||||
|
||||
ErrorMessage = "";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -133,38 +153,45 @@ namespace DiscImageChef.DiscImages
|
||||
if(!IsWriting)
|
||||
{
|
||||
ErrorMessage = "Tried to write on a non-writable image";
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if(data.Length % imageInfo.SectorSize != 0)
|
||||
{
|
||||
ErrorMessage = "Incorrect data size";
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if(sectorAddress + length > imageInfo.Sectors)
|
||||
{
|
||||
ErrorMessage = "Tried to write past image size";
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
writingStream.Seek((long)((ulong)Marshal.SizeOf<RsIdeHeader>() + sectorAddress * imageInfo.SectorSize),
|
||||
writingStream.Seek((long)((ulong)Marshal.SizeOf<RsIdeHeader>() + (sectorAddress * imageInfo.SectorSize)),
|
||||
SeekOrigin.Begin);
|
||||
|
||||
writingStream.Write(data, 0, data.Length);
|
||||
|
||||
ErrorMessage = "";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool WriteSectorLong(byte[] data, ulong sectorAddress)
|
||||
{
|
||||
ErrorMessage = "Writing sectors with tags is not supported.";
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length)
|
||||
{
|
||||
ErrorMessage = "Writing sectors with tags is not supported.";
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -173,6 +200,7 @@ namespace DiscImageChef.DiscImages
|
||||
if(!IsWriting)
|
||||
{
|
||||
ErrorMessage = "Image is not opened for writing";
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -194,52 +222,53 @@ namespace DiscImageChef.DiscImages
|
||||
|
||||
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,
|
||||
identify = new byte[106],
|
||||
dataOff = (ushort)Marshal.SizeOf<RsIdeHeader>(),
|
||||
revision = 1,
|
||||
reserved = new byte[11]
|
||||
magic = signature, identify = new byte[106], 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)
|
||||
{
|
||||
Identify.IdentifyDevice ataId = new Identify.IdentifyDevice
|
||||
var ataId = new Identify.IdentifyDevice
|
||||
{
|
||||
GeneralConfiguration =
|
||||
Decoders.ATA.Identify.GeneralConfigurationBit.UltraFastIDE |
|
||||
Decoders.ATA.Identify.GeneralConfigurationBit.Fixed |
|
||||
Decoders.ATA.Identify.GeneralConfigurationBit.NotMFM |
|
||||
Decoders.ATA.Identify.GeneralConfigurationBit.SoftSector,
|
||||
Cylinders = (ushort)imageInfo.Cylinders,
|
||||
Heads = (ushort)imageInfo.Heads,
|
||||
SectorsPerTrack = (ushort)imageInfo.SectorsPerTrack,
|
||||
VendorWord47 = 0x80,
|
||||
Capabilities =
|
||||
Decoders.ATA.Identify.CapabilitiesBit.DMASupport |
|
||||
Decoders.ATA.Identify.CapabilitiesBit.IORDY |
|
||||
Decoders.ATA.Identify.CapabilitiesBit.LBASupport,
|
||||
ExtendedIdentify = Decoders.ATA.Identify.ExtendedIdentifyBit.Words54to58Valid,
|
||||
CurrentCylinders = (ushort)imageInfo.Cylinders,
|
||||
CurrentHeads = (ushort)imageInfo.Heads,
|
||||
CommonTypes.Structs.Devices.ATA.Identify.GeneralConfigurationBit.UltraFastIDE |
|
||||
CommonTypes.Structs.Devices.ATA.Identify.GeneralConfigurationBit.Fixed |
|
||||
CommonTypes.Structs.Devices.ATA.Identify.GeneralConfigurationBit.NotMFM |
|
||||
CommonTypes.Structs.Devices.ATA.Identify.GeneralConfigurationBit.SoftSector,
|
||||
Cylinders = (ushort)imageInfo.Cylinders, Heads = (ushort)imageInfo.Heads,
|
||||
SectorsPerTrack = (ushort)imageInfo.SectorsPerTrack, VendorWord47 = 0x80,
|
||||
Capabilities = CommonTypes.Structs.Devices.ATA.Identify.CapabilitiesBit.DMASupport |
|
||||
CommonTypes.Structs.Devices.ATA.Identify.CapabilitiesBit.IORDY |
|
||||
CommonTypes.Structs.Devices.ATA.Identify.CapabilitiesBit.LBASupport,
|
||||
ExtendedIdentify =
|
||||
CommonTypes.Structs.Devices.ATA.Identify.ExtendedIdentifyBit.Words54to58Valid,
|
||||
CurrentCylinders = (ushort)imageInfo.Cylinders, CurrentHeads = (ushort)imageInfo.Heads,
|
||||
CurrentSectorsPerTrack = (ushort)imageInfo.SectorsPerTrack,
|
||||
CurrentSectors = (uint)imageInfo.Sectors,
|
||||
LBASectors = (uint)imageInfo.Sectors,
|
||||
DMASupported = Decoders.ATA.Identify.TransferMode.Mode0,
|
||||
DMAActive = Decoders.ATA.Identify.TransferMode.Mode0
|
||||
CurrentSectors = (uint)imageInfo.Sectors, LBASectors = (uint)imageInfo.Sectors,
|
||||
DMASupported = CommonTypes.Structs.Devices.ATA.Identify.TransferMode.Mode0,
|
||||
DMAActive = CommonTypes.Structs.Devices.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))
|
||||
imageInfo.DriveSerialNumber = $"{new Random().NextDouble():16X}";
|
||||
@@ -247,17 +276,21 @@ namespace DiscImageChef.DiscImages
|
||||
byte[] ataIdBytes = new byte[Marshal.SizeOf<Identify.IdentifyDevice>()];
|
||||
IntPtr ptr = System.Runtime.InteropServices.Marshal.AllocHGlobal(512);
|
||||
System.Runtime.InteropServices.Marshal.StructureToPtr(ataId, ptr, true);
|
||||
|
||||
System.Runtime.InteropServices.Marshal.Copy(ptr, ataIdBytes, 0,
|
||||
Marshal.SizeOf<Identify.IdentifyDevice>());
|
||||
|
||||
System.Runtime.InteropServices.Marshal.FreeHGlobal(ptr);
|
||||
|
||||
Array.Copy(ScrambleAtaString(imageInfo.DriveManufacturer + " " + imageInfo.DriveModel, 40), 0,
|
||||
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(ataIdBytes, 0, header.identify, 0, 106);
|
||||
|
||||
Array.Copy(ScrambleAtaString(imageInfo.DriveFirmwareRevision, 8), 0, ataIdBytes, 23 * 2, 8);
|
||||
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>()];
|
||||
IntPtr hdrPtr = System.Runtime.InteropServices.Marshal.AllocHGlobal(Marshal.SizeOf<RsIdeHeader>());
|
||||
@@ -273,6 +306,7 @@ namespace DiscImageChef.DiscImages
|
||||
|
||||
IsWriting = false;
|
||||
ErrorMessage = "";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -291,18 +325,21 @@ namespace DiscImageChef.DiscImages
|
||||
if(cylinders > ushort.MaxValue)
|
||||
{
|
||||
ErrorMessage = "Too many cylinders.";
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if(heads > ushort.MaxValue)
|
||||
{
|
||||
ErrorMessage = "Too many heads.";
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if(sectorsPerTrack > ushort.MaxValue)
|
||||
{
|
||||
ErrorMessage = "Too many sectors per track.";
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -316,12 +353,14 @@ namespace DiscImageChef.DiscImages
|
||||
public bool WriteSectorTag(byte[] data, ulong sectorAddress, SectorTagType tag)
|
||||
{
|
||||
ErrorMessage = "Unsupported feature";
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool WriteSectorsTag(byte[] data, ulong sectorAddress, uint length, SectorTagType tag)
|
||||
{
|
||||
ErrorMessage = "Unsupported feature";
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -40,12 +40,14 @@ using DiscImageChef.CommonTypes.Enums;
|
||||
using DiscImageChef.CommonTypes.Exceptions;
|
||||
using DiscImageChef.CommonTypes.Interfaces;
|
||||
using DiscImageChef.CommonTypes.Structs;
|
||||
using DiscImageChef.CommonTypes.Structs.Devices.SCSI;
|
||||
using DiscImageChef.Console;
|
||||
using DiscImageChef.Decoders.CD;
|
||||
using DiscImageChef.Decoders.DVD;
|
||||
using DiscImageChef.Decoders.SCSI;
|
||||
using Schemas;
|
||||
using DMI = DiscImageChef.Decoders.Xbox.DMI;
|
||||
using Inquiry = DiscImageChef.CommonTypes.Structs.Devices.SCSI.Inquiry;
|
||||
using Session = DiscImageChef.CommonTypes.Structs.Session;
|
||||
using TrackType = DiscImageChef.CommonTypes.Enums.TrackType;
|
||||
|
||||
@@ -781,7 +783,7 @@ namespace DiscImageChef.DiscImages
|
||||
if (mediaTags.ContainsKey(MediaTagType.SCSI_INQUIRY))
|
||||
{
|
||||
var devType = PeripheralDeviceTypes.DirectAccess;
|
||||
Inquiry.SCSIInquiry? scsiInq = null;
|
||||
Inquiry? scsiInq = null;
|
||||
if (mediaTags.TryGetValue(MediaTagType.SCSI_INQUIRY, out var inq))
|
||||
{
|
||||
scsiInq = Inquiry.Decode(inq);
|
||||
@@ -858,7 +860,7 @@ namespace DiscImageChef.DiscImages
|
||||
// It's ATA, check tags
|
||||
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)
|
||||
{
|
||||
imageInfo.MediaType = (ushort) ataId.Value.GeneralConfiguration == 0x848A
|
||||
|
||||
@@ -35,6 +35,7 @@ using System.Collections.ObjectModel;
|
||||
using System.Text;
|
||||
using DiscImageChef.CommonTypes.Enums;
|
||||
using DiscImageChef.CommonTypes.Interfaces;
|
||||
using DiscImageChef.CommonTypes.Structs.Devices.SCSI;
|
||||
using DiscImageChef.Decoders.ATA;
|
||||
using DiscImageChef.Decoders.Bluray;
|
||||
using DiscImageChef.Decoders.CD;
|
||||
@@ -48,6 +49,7 @@ using BCA = DiscImageChef.Decoders.Bluray.BCA;
|
||||
using Cartridge = DiscImageChef.Decoders.Bluray.Cartridge;
|
||||
using DDS = DiscImageChef.Decoders.DVD.DDS;
|
||||
using DMI = DiscImageChef.Decoders.Xbox.DMI;
|
||||
using Inquiry = DiscImageChef.Decoders.SCSI.Inquiry;
|
||||
using Spare = DiscImageChef.Decoders.DVD.Spare;
|
||||
|
||||
namespace DiscImageChef.Gui.Forms
|
||||
|
||||
@@ -39,6 +39,7 @@ using DiscImageChef.CommonTypes;
|
||||
using DiscImageChef.CommonTypes.Enums;
|
||||
using DiscImageChef.CommonTypes.Interfaces;
|
||||
using DiscImageChef.CommonTypes.Structs;
|
||||
using DiscImageChef.CommonTypes.Structs.Devices.SCSI;
|
||||
using DiscImageChef.Console;
|
||||
using DiscImageChef.Core;
|
||||
using DiscImageChef.Core.Media.Info;
|
||||
|
||||
@@ -37,6 +37,7 @@ using System.Text;
|
||||
using DiscImageChef.CommonTypes.Enums;
|
||||
using DiscImageChef.CommonTypes.Interfaces;
|
||||
using DiscImageChef.CommonTypes.Structs;
|
||||
using DiscImageChef.CommonTypes.Structs.Devices.SCSI;
|
||||
using DiscImageChef.Decoders.CD;
|
||||
using DiscImageChef.Decoders.DVD;
|
||||
using DiscImageChef.Decoders.SCSI;
|
||||
@@ -48,6 +49,7 @@ using Eto.Drawing;
|
||||
using Eto.Forms;
|
||||
using Eto.Serialization.Xaml;
|
||||
using Schemas;
|
||||
using Inquiry = DiscImageChef.Decoders.SCSI.Inquiry;
|
||||
using Session = DiscImageChef.CommonTypes.Structs.Session;
|
||||
|
||||
namespace DiscImageChef.Gui.Panels
|
||||
@@ -258,7 +260,7 @@ namespace DiscImageChef.Gui.Panels
|
||||
|
||||
PeripheralDeviceTypes scsiDeviceType = PeripheralDeviceTypes.DirectAccess;
|
||||
byte[] scsiInquiryData = null;
|
||||
Inquiry.SCSIInquiry? scsiInquiry = null;
|
||||
CommonTypes.Structs.Devices.SCSI.Inquiry? scsiInquiry = null;
|
||||
Modes.DecodedMode? scsiMode = null;
|
||||
byte[] scsiModeSense6 = null;
|
||||
byte[] scsiModeSense10 = null;
|
||||
@@ -270,7 +272,7 @@ namespace DiscImageChef.Gui.Panels
|
||||
|
||||
scsiDeviceType = (PeripheralDeviceTypes)(scsiInquiryData[0] & 0x1F);
|
||||
|
||||
scsiInquiry = Inquiry.Decode(scsiInquiryData);
|
||||
scsiInquiry = CommonTypes.Structs.Devices.SCSI.Inquiry.Decode(scsiInquiryData);
|
||||
}
|
||||
|
||||
if(imageFormat.Info.ReadableMediaTags != null &&
|
||||
|
||||
@@ -34,11 +34,13 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using DiscImageChef.CommonTypes.Structs.Devices.SCSI;
|
||||
using DiscImageChef.Console;
|
||||
using DiscImageChef.Decoders.SCSI;
|
||||
using DiscImageChef.Decoders.SCSI.MMC;
|
||||
using Eto.Forms;
|
||||
using Eto.Serialization.Xaml;
|
||||
using Inquiry = DiscImageChef.Decoders.SCSI.Inquiry;
|
||||
|
||||
namespace DiscImageChef.Gui.Tabs
|
||||
{
|
||||
@@ -46,7 +48,7 @@ namespace DiscImageChef.Gui.Tabs
|
||||
{
|
||||
private byte[] configuration;
|
||||
private Dictionary<byte, byte[]> evpdPages;
|
||||
private Inquiry.SCSIInquiry? inquiry;
|
||||
private CommonTypes.Structs.Devices.SCSI.Inquiry? inquiry;
|
||||
private byte[] inquiryData;
|
||||
private Modes.DecodedMode? mode;
|
||||
private byte[] modeSense10;
|
||||
@@ -58,7 +60,7 @@ namespace DiscImageChef.Gui.Tabs
|
||||
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,
|
||||
PeripheralDeviceTypes scsiType, byte[] scsiModeSense6,
|
||||
byte[] scsiModeSense10,
|
||||
|
||||
@@ -251,6 +251,7 @@
|
||||
<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/=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/=mediaserialnumber/@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/=remapanchor/@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/=SDHCI/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Secu/@EntryIndexedValue">True</s:Boolean>
|
||||
|
||||
@@ -39,11 +39,12 @@ using System.Threading;
|
||||
using DiscImageChef.CommonTypes.Enums;
|
||||
using DiscImageChef.CommonTypes.Interop;
|
||||
using DiscImageChef.CommonTypes.Metadata;
|
||||
using DiscImageChef.CommonTypes.Structs.Devices.ATA;
|
||||
using DiscImageChef.CommonTypes.Structs.Devices.SCSI;
|
||||
using DiscImageChef.Console;
|
||||
using DiscImageChef.Core;
|
||||
using DiscImageChef.Database;
|
||||
using DiscImageChef.Database.Models;
|
||||
using DiscImageChef.Decoders.ATA;
|
||||
using DiscImageChef.Decoders.SCSI;
|
||||
using DiscImageChef.Devices;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
@@ -35,6 +35,7 @@ using System.CommandLine;
|
||||
using System.CommandLine.Invocation;
|
||||
using System.Linq;
|
||||
using DiscImageChef.CommonTypes.Enums;
|
||||
using DiscImageChef.CommonTypes.Structs.Devices.SCSI;
|
||||
using DiscImageChef.Console;
|
||||
using DiscImageChef.Core;
|
||||
using DiscImageChef.Database;
|
||||
@@ -47,6 +48,7 @@ using DiscImageChef.Decoders.SCSI.SSC;
|
||||
using DiscImageChef.Devices;
|
||||
using Command = System.CommandLine.Command;
|
||||
using DeviceInfo = DiscImageChef.Core.Devices.Info.DeviceInfo;
|
||||
using Inquiry = DiscImageChef.Decoders.SCSI.Inquiry;
|
||||
|
||||
namespace DiscImageChef.Commands.Device
|
||||
{
|
||||
|
||||
@@ -37,6 +37,7 @@ using System.CommandLine.Invocation;
|
||||
using System.Linq;
|
||||
using DiscImageChef.CommonTypes.Enums;
|
||||
using DiscImageChef.CommonTypes.Structs;
|
||||
using DiscImageChef.CommonTypes.Structs.Devices.SCSI;
|
||||
using DiscImageChef.Console;
|
||||
using DiscImageChef.Core;
|
||||
using DiscImageChef.Core.Devices.Dumping;
|
||||
@@ -46,7 +47,6 @@ using DiscImageChef.Database.Models;
|
||||
using DiscImageChef.Decoders.Bluray;
|
||||
using DiscImageChef.Decoders.CD;
|
||||
using DiscImageChef.Decoders.DVD;
|
||||
using DiscImageChef.Decoders.SCSI;
|
||||
using DiscImageChef.Decoders.SCSI.MMC;
|
||||
using DiscImageChef.Decoders.SCSI.SSC;
|
||||
using DiscImageChef.Decoders.Xbox;
|
||||
|
||||
Reference in New Issue
Block a user