mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
Implements verification on all currently supported disk
images. Implements DC42 CRC calculation. Calculates TeleDisk CRC for disk sectors. Resolves #2 and bumps version to 2.1.
This commit is contained in:
@@ -27,6 +27,6 @@ Global
|
||||
GlobalSection(MonoDevelopProperties) = preSolution
|
||||
StartupItem = DiscImageChef\DiscImageChef.csproj
|
||||
description = The Disc Image Chef.
|
||||
version = 2.0
|
||||
version = 2.1
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
||||
@@ -54,7 +54,7 @@ using System.Reflection;
|
||||
// The form "{Major}.{Minor}.*" will automatically update the build and revision,
|
||||
// and "{Major}.{Minor}.{Build}.*" will update just the revision.
|
||||
|
||||
[assembly: AssemblyVersion("2.0.*")]
|
||||
[assembly: AssemblyVersion("2.1.*")]
|
||||
|
||||
// The following attributes are used to specify the signing key for the assembly,
|
||||
// if desired. See the Mono documentation for more information about signing.
|
||||
|
||||
@@ -36,6 +36,8 @@ Copyright (C) 2011-2014 Claunia.com
|
||||
****************************************************************************/
|
||||
//$Id$
|
||||
using System;
|
||||
using DiscImageChef.ImagePlugins;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace DiscImageChef.Commands
|
||||
{
|
||||
@@ -51,7 +53,211 @@ namespace DiscImageChef.Commands
|
||||
Console.WriteLine("--verify-disc={0}", options.VerifyDisc);
|
||||
Console.WriteLine("--verify-sectors={0}", options.VerifySectors);
|
||||
}
|
||||
Console.WriteLine("Verifying not yet implemented."); return;
|
||||
|
||||
ImagePlugin inputFormat = ImageFormat.Detect(options.InputFile);
|
||||
|
||||
if (inputFormat == null)
|
||||
{
|
||||
Console.WriteLine("Unable to recognize image format, not verifying");
|
||||
return;
|
||||
}
|
||||
|
||||
inputFormat.OpenImage(options.InputFile);
|
||||
|
||||
if (options.VerifyDisc)
|
||||
{
|
||||
DateTime StartCheck = DateTime.UtcNow;
|
||||
bool? discCheckStatus = inputFormat.VerifyDiskImage();
|
||||
DateTime EndCheck = DateTime.UtcNow;
|
||||
|
||||
TimeSpan CheckTime = EndCheck - StartCheck;
|
||||
|
||||
switch (discCheckStatus)
|
||||
{
|
||||
case true:
|
||||
Console.WriteLine("Disc image checksums are correct");
|
||||
break;
|
||||
case false:
|
||||
Console.WriteLine("Disc image checksums are incorrect");
|
||||
break;
|
||||
case null:
|
||||
Console.WriteLine("Disc image does not contain checksums");
|
||||
break;
|
||||
}
|
||||
|
||||
if (MainClass.isVerbose)
|
||||
Console.WriteLine("Checking disc image checksums took {0} seconds", CheckTime.TotalSeconds);
|
||||
}
|
||||
|
||||
if (options.VerifySectors)
|
||||
{
|
||||
bool formatHasTracks;
|
||||
try
|
||||
{
|
||||
List<Track> inputTracks = inputFormat.GetTracks();
|
||||
if (inputTracks.Count > 0)
|
||||
formatHasTracks = true;
|
||||
else
|
||||
formatHasTracks = false;
|
||||
}
|
||||
catch
|
||||
{
|
||||
formatHasTracks = false;
|
||||
}
|
||||
|
||||
DateTime StartCheck;
|
||||
DateTime EndCheck;
|
||||
List<UInt64> FailingLBAs = new List<UInt64>();
|
||||
List<UInt64> UnknownLBAs = new List<UInt64>();
|
||||
bool? checkStatus = null;
|
||||
|
||||
if (formatHasTracks)
|
||||
{
|
||||
List<Track> inputTracks = inputFormat.GetTracks();
|
||||
UInt64 currentSectorAll = 0;
|
||||
|
||||
StartCheck = DateTime.UtcNow;
|
||||
foreach (Track currentTrack in inputTracks)
|
||||
{
|
||||
UInt64 remainingSectors = currentTrack.TrackEndSector - currentTrack.TrackStartSector;
|
||||
UInt64 currentSector = 0;
|
||||
|
||||
while (remainingSectors > 0)
|
||||
{
|
||||
Console.Write("\rChecking sector {0} of {1}, on track {2}", currentSectorAll, inputFormat.GetSectors(), currentTrack.TrackSequence);
|
||||
|
||||
List<UInt64> tempFailingLBAs;
|
||||
List<UInt64> tempUnknownLBAs;
|
||||
bool? tempStatus;
|
||||
|
||||
if (remainingSectors < 512)
|
||||
tempStatus = inputFormat.VerifySectors(currentSector, (uint)remainingSectors, currentTrack.TrackSequence, out tempFailingLBAs, out tempUnknownLBAs);
|
||||
else
|
||||
tempStatus = inputFormat.VerifySectors(currentSector, 512, currentTrack.TrackSequence, out tempFailingLBAs, out tempUnknownLBAs);
|
||||
|
||||
if (checkStatus == null || tempStatus == null)
|
||||
checkStatus = null;
|
||||
else if (checkStatus == false || tempStatus == false)
|
||||
checkStatus = false;
|
||||
else if (checkStatus == true && tempStatus == true)
|
||||
checkStatus = true;
|
||||
else
|
||||
checkStatus = null;
|
||||
|
||||
foreach (UInt64 failLBA in tempFailingLBAs)
|
||||
FailingLBAs.Add(failLBA);
|
||||
|
||||
foreach (UInt64 unknownLBA in tempUnknownLBAs)
|
||||
UnknownLBAs.Add(unknownLBA);
|
||||
|
||||
if (remainingSectors < 512)
|
||||
{
|
||||
currentSector += remainingSectors;
|
||||
currentSectorAll += remainingSectors;
|
||||
remainingSectors = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentSector += 512;
|
||||
currentSectorAll += 512;
|
||||
remainingSectors -= 512;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
EndCheck = DateTime.UtcNow;
|
||||
}
|
||||
else
|
||||
{
|
||||
UInt64 remainingSectors = inputFormat.GetSectors();
|
||||
UInt64 currentSector = 0;
|
||||
|
||||
StartCheck = DateTime.UtcNow;
|
||||
while (remainingSectors > 0)
|
||||
{
|
||||
Console.Write("\rChecking sector {0} of {1}", currentSector, inputFormat.GetSectors());
|
||||
|
||||
List<UInt64> tempFailingLBAs;
|
||||
List<UInt64> tempUnknownLBAs;
|
||||
bool? tempStatus;
|
||||
|
||||
if (remainingSectors < 512)
|
||||
tempStatus = inputFormat.VerifySectors(currentSector, (uint)remainingSectors, out tempFailingLBAs, out tempUnknownLBAs);
|
||||
else
|
||||
tempStatus = inputFormat.VerifySectors(currentSector, 512, out tempFailingLBAs, out tempUnknownLBAs);
|
||||
|
||||
if (checkStatus == null || tempStatus == null)
|
||||
checkStatus = null;
|
||||
else if (checkStatus == false || tempStatus == false)
|
||||
checkStatus = false;
|
||||
else if (checkStatus == true && tempStatus == true)
|
||||
checkStatus = true;
|
||||
else
|
||||
checkStatus = null;
|
||||
|
||||
foreach (UInt64 failLBA in tempFailingLBAs)
|
||||
FailingLBAs.Add(failLBA);
|
||||
|
||||
foreach (UInt64 unknownLBA in tempUnknownLBAs)
|
||||
UnknownLBAs.Add(unknownLBA);
|
||||
|
||||
if (remainingSectors < 512)
|
||||
{
|
||||
currentSector += remainingSectors;
|
||||
remainingSectors = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentSector += 512;
|
||||
remainingSectors -= 512;
|
||||
}
|
||||
|
||||
}
|
||||
EndCheck = DateTime.UtcNow;
|
||||
}
|
||||
|
||||
TimeSpan CheckTime = EndCheck - StartCheck;
|
||||
|
||||
Console.Write("\r");
|
||||
|
||||
switch (checkStatus)
|
||||
{
|
||||
case true:
|
||||
Console.WriteLine("All sector checksums are correct");
|
||||
break;
|
||||
case false:
|
||||
Console.WriteLine("There is at least one sector with incorrect checksum or errors");
|
||||
break;
|
||||
case null:
|
||||
Console.WriteLine("There is at least one sector that does not contain a checksum");
|
||||
break;
|
||||
}
|
||||
|
||||
if (MainClass.isVerbose)
|
||||
Console.WriteLine("Checking sector checksums took {0} seconds", CheckTime.TotalSeconds);
|
||||
|
||||
if (MainClass.isVerbose)
|
||||
{
|
||||
Console.WriteLine("LBAs with error:");
|
||||
if (FailingLBAs.Count == (int)inputFormat.GetSectors())
|
||||
Console.WriteLine("\tall sectors.");
|
||||
else
|
||||
for (int i = 0; i < FailingLBAs.Count; i++)
|
||||
Console.WriteLine("\t{0}", FailingLBAs[i]);
|
||||
|
||||
Console.WriteLine("LBAs without checksum:");
|
||||
if (UnknownLBAs.Count == (int)inputFormat.GetSectors())
|
||||
Console.WriteLine("\tall sectors.");
|
||||
else
|
||||
for (int i = 0; i < UnknownLBAs.Count; i++)
|
||||
Console.WriteLine("\t{0}", UnknownLBAs[i]);
|
||||
}
|
||||
|
||||
Console.WriteLine("Total sectors........... {0}", inputFormat.GetSectors());
|
||||
Console.WriteLine("Total errors............ {0}", FailingLBAs.Count);
|
||||
Console.WriteLine("Total unknowns.......... {0}", UnknownLBAs.Count);
|
||||
Console.WriteLine("Total errors+unknowns... {0}", FailingLBAs.Count + UnknownLBAs.Count);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<RootNamespace>DiscImageChef</RootNamespace>
|
||||
<AssemblyName>DiscImageChef</AssemblyName>
|
||||
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
|
||||
<ReleaseVersion>2.0</ReleaseVersion>
|
||||
<ReleaseVersion>2.1</ReleaseVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
|
||||
<DebugSymbols>True</DebugSymbols>
|
||||
|
||||
@@ -1251,70 +1251,68 @@ namespace DiscImageChef.ImagePlugins
|
||||
_imageInfo.diskBarcode = discimage.barcode;
|
||||
_imageInfo.diskType = discimage.disktype;
|
||||
|
||||
foreach(CDRWinTrack track in discimage.tracks)
|
||||
foreach (CDRWinTrack track in discimage.tracks)
|
||||
{
|
||||
switch(track.tracktype)
|
||||
switch (track.tracktype)
|
||||
{
|
||||
case CDRWinTrackTypeAudio:
|
||||
{
|
||||
if(!_imageInfo.readableSectorTags.Contains(SectorTagType.CDTrackISRC))
|
||||
if (!_imageInfo.readableSectorTags.Contains(SectorTagType.CDTrackISRC))
|
||||
_imageInfo.readableSectorTags.Add(SectorTagType.CDTrackISRC);
|
||||
if(!_imageInfo.readableSectorTags.Contains(SectorTagType.CDTrackFlags))
|
||||
if (!_imageInfo.readableSectorTags.Contains(SectorTagType.CDTrackFlags))
|
||||
_imageInfo.readableSectorTags.Add(SectorTagType.CDTrackFlags);
|
||||
break;
|
||||
}
|
||||
case CDRWinTrackTypeCDG:
|
||||
{
|
||||
if(!_imageInfo.readableSectorTags.Contains(SectorTagType.CDTrackISRC))
|
||||
if (!_imageInfo.readableSectorTags.Contains(SectorTagType.CDTrackISRC))
|
||||
_imageInfo.readableSectorTags.Add(SectorTagType.CDTrackISRC);
|
||||
if(!_imageInfo.readableSectorTags.Contains(SectorTagType.CDTrackFlags))
|
||||
if (!_imageInfo.readableSectorTags.Contains(SectorTagType.CDTrackFlags))
|
||||
_imageInfo.readableSectorTags.Add(SectorTagType.CDTrackFlags);
|
||||
if(!_imageInfo.readableSectorTags.Contains(SectorTagType.CDSectorSubchannel))
|
||||
if (!_imageInfo.readableSectorTags.Contains(SectorTagType.CDSectorSubchannel))
|
||||
_imageInfo.readableSectorTags.Add(SectorTagType.CDSectorSubchannel);
|
||||
break;
|
||||
}
|
||||
case CDRWinTrackTypeMode2Formless:
|
||||
case CDRWinTrackTypeCDI:
|
||||
{
|
||||
if(!_imageInfo.readableSectorTags.Contains(SectorTagType.CDSectorSubHeader))
|
||||
if (!_imageInfo.readableSectorTags.Contains(SectorTagType.CDSectorSubHeader))
|
||||
_imageInfo.readableSectorTags.Add(SectorTagType.CDSectorSubHeader);
|
||||
if(!_imageInfo.readableSectorTags.Contains(SectorTagType.CDSectorEDC))
|
||||
if (!_imageInfo.readableSectorTags.Contains(SectorTagType.CDSectorEDC))
|
||||
_imageInfo.readableSectorTags.Add(SectorTagType.CDSectorEDC);
|
||||
break;
|
||||
}
|
||||
case CDRWinTrackTypeMode2Raw:
|
||||
case CDRWinTrackTypeCDIRaw:
|
||||
{
|
||||
if(!_imageInfo.readableSectorTags.Contains(SectorTagType.CDSectorSync))
|
||||
if (!_imageInfo.readableSectorTags.Contains(SectorTagType.CDSectorSync))
|
||||
_imageInfo.readableSectorTags.Add(SectorTagType.CDSectorSync);
|
||||
if(!_imageInfo.readableSectorTags.Contains(SectorTagType.CDSectorHeader))
|
||||
if (!_imageInfo.readableSectorTags.Contains(SectorTagType.CDSectorHeader))
|
||||
_imageInfo.readableSectorTags.Add(SectorTagType.CDSectorHeader);
|
||||
if(!_imageInfo.readableSectorTags.Contains(SectorTagType.CDSectorSubHeader))
|
||||
if (!_imageInfo.readableSectorTags.Contains(SectorTagType.CDSectorSubHeader))
|
||||
_imageInfo.readableSectorTags.Add(SectorTagType.CDSectorSubHeader);
|
||||
if(!_imageInfo.readableSectorTags.Contains(SectorTagType.CDSectorEDC))
|
||||
if (!_imageInfo.readableSectorTags.Contains(SectorTagType.CDSectorEDC))
|
||||
_imageInfo.readableSectorTags.Add(SectorTagType.CDSectorEDC);
|
||||
break;
|
||||
}
|
||||
case CDRWinTrackTypeMode1Raw:
|
||||
{
|
||||
if(!_imageInfo.readableSectorTags.Contains(SectorTagType.CDSectorSync))
|
||||
if (!_imageInfo.readableSectorTags.Contains(SectorTagType.CDSectorSync))
|
||||
_imageInfo.readableSectorTags.Add(SectorTagType.CDSectorSync);
|
||||
if(!_imageInfo.readableSectorTags.Contains(SectorTagType.CDSectorHeader))
|
||||
if (!_imageInfo.readableSectorTags.Contains(SectorTagType.CDSectorHeader))
|
||||
_imageInfo.readableSectorTags.Add(SectorTagType.CDSectorHeader);
|
||||
if(!_imageInfo.readableSectorTags.Contains(SectorTagType.CDSectorSubHeader))
|
||||
if (!_imageInfo.readableSectorTags.Contains(SectorTagType.CDSectorSubHeader))
|
||||
_imageInfo.readableSectorTags.Add(SectorTagType.CDSectorSubHeader);
|
||||
if(!_imageInfo.readableSectorTags.Contains(SectorTagType.CDSectorECC))
|
||||
if (!_imageInfo.readableSectorTags.Contains(SectorTagType.CDSectorECC))
|
||||
_imageInfo.readableSectorTags.Add(SectorTagType.CDSectorECC);
|
||||
if(!_imageInfo.readableSectorTags.Contains(SectorTagType.CDSectorECC_P))
|
||||
if (!_imageInfo.readableSectorTags.Contains(SectorTagType.CDSectorECC_P))
|
||||
_imageInfo.readableSectorTags.Add(SectorTagType.CDSectorECC_P);
|
||||
if(!_imageInfo.readableSectorTags.Contains(SectorTagType.CDSectorECC_Q))
|
||||
if (!_imageInfo.readableSectorTags.Contains(SectorTagType.CDSectorECC_Q))
|
||||
_imageInfo.readableSectorTags.Add(SectorTagType.CDSectorECC_Q);
|
||||
if(!_imageInfo.readableSectorTags.Contains(SectorTagType.CDSectorEDC))
|
||||
if (!_imageInfo.readableSectorTags.Contains(SectorTagType.CDSectorEDC))
|
||||
_imageInfo.readableSectorTags.Add(SectorTagType.CDSectorEDC);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1928,6 +1926,8 @@ namespace DiscImageChef.ImagePlugins
|
||||
{
|
||||
List<Track> tracks = new List<Track>();
|
||||
|
||||
UInt64 previousStartSector = 0;
|
||||
|
||||
foreach (CDRWinTrack cdr_track in discimage.tracks)
|
||||
{
|
||||
Track _track = new Track();
|
||||
@@ -1936,6 +1936,7 @@ namespace DiscImageChef.ImagePlugins
|
||||
_track.TrackDescription = cdr_track.title;
|
||||
if (!cdr_track.indexes.TryGetValue(0, out _track.TrackStartSector))
|
||||
cdr_track.indexes.TryGetValue(1, out _track.TrackStartSector);
|
||||
_track.TrackStartSector += previousStartSector;
|
||||
_track.TrackEndSector = _track.TrackStartSector + cdr_track.sectors - 1;
|
||||
_track.TrackPregap = cdr_track.pregap;
|
||||
_track.TrackSession = cdr_track.session;
|
||||
@@ -1943,6 +1944,7 @@ namespace DiscImageChef.ImagePlugins
|
||||
_track.TrackType = CDRWinTrackTypeToTrackType(cdr_track.tracktype);
|
||||
|
||||
tracks.Add(_track);
|
||||
previousStartSector = _track.TrackEndSector + 1;
|
||||
}
|
||||
|
||||
return tracks;
|
||||
@@ -1989,6 +1991,85 @@ namespace DiscImageChef.ImagePlugins
|
||||
return discimage.sessions;
|
||||
}
|
||||
|
||||
public override bool? VerifySector(UInt64 sectorAddress)
|
||||
{
|
||||
byte[] buffer = ReadSectorLong(sectorAddress);
|
||||
return Checksums.CDChecksums.CheckCDSector(buffer);
|
||||
}
|
||||
|
||||
public override bool? VerifySector(UInt64 sectorAddress, UInt32 track)
|
||||
{
|
||||
byte[] buffer = ReadSectorLong(sectorAddress, track);
|
||||
return Checksums.CDChecksums.CheckCDSector(buffer);
|
||||
}
|
||||
|
||||
public override bool? VerifySectors(UInt64 sectorAddress, UInt32 length, out List<UInt64> FailingLBAs, out List<UInt64> UnknownLBAs)
|
||||
{
|
||||
byte[] buffer = ReadSectorsLong(sectorAddress, length);
|
||||
int bps = (int)(buffer.Length / length);
|
||||
byte[] sector = new byte[bps];
|
||||
FailingLBAs = new List<UInt64>();
|
||||
UnknownLBAs = new List<UInt64>();
|
||||
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
Array.Copy(buffer, i * bps, sector, 0, bps);
|
||||
bool? sectorStatus = Checksums.CDChecksums.CheckCDSector(sector);
|
||||
|
||||
switch (sectorStatus)
|
||||
{
|
||||
case null:
|
||||
UnknownLBAs.Add((ulong)i + sectorAddress);
|
||||
break;
|
||||
case false:
|
||||
FailingLBAs.Add((ulong)i + sectorAddress);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (UnknownLBAs.Count > 0)
|
||||
return null;
|
||||
if (FailingLBAs.Count > 0)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool? VerifySectors(UInt64 sectorAddress, UInt32 length, UInt32 track, out List<UInt64> FailingLBAs, out List<UInt64> UnknownLBAs)
|
||||
{
|
||||
byte[] buffer = ReadSectorsLong(sectorAddress, length, track);
|
||||
int bps = (int)(buffer.Length / length);
|
||||
byte[] sector = new byte[bps];
|
||||
FailingLBAs = new List<UInt64>();
|
||||
UnknownLBAs = new List<UInt64>();
|
||||
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
Array.Copy(buffer, i * bps, sector, 0, bps);
|
||||
bool? sectorStatus = Checksums.CDChecksums.CheckCDSector(sector);
|
||||
|
||||
switch (sectorStatus)
|
||||
{
|
||||
case null:
|
||||
UnknownLBAs.Add((ulong)i + sectorAddress);
|
||||
break;
|
||||
case false:
|
||||
FailingLBAs.Add((ulong)i + sectorAddress);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (UnknownLBAs.Count > 0)
|
||||
return null;
|
||||
if (FailingLBAs.Count > 0)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool? VerifyDiskImage()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private methods
|
||||
@@ -2168,6 +2249,7 @@ namespace DiscImageChef.ImagePlugins
|
||||
{
|
||||
return _imageInfo.imageCreator;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -373,6 +373,83 @@ namespace DiscImageChef.ImagePlugins
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool? VerifySector(UInt64 sectorAddress)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public override bool? VerifySector(UInt64 sectorAddress, UInt32 track)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public override bool? VerifySectors(UInt64 sectorAddress, UInt32 length, out List<UInt64> FailingLBAs, out List<UInt64> UnknownLBAs)
|
||||
{
|
||||
FailingLBAs = new List<UInt64>();
|
||||
UnknownLBAs = new List<UInt64>();
|
||||
|
||||
for (UInt64 i = sectorAddress; i < sectorAddress + length; i++)
|
||||
UnknownLBAs.Add(i);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public override bool? VerifySectors(UInt64 sectorAddress, UInt32 length, UInt32 track, out List<UInt64> FailingLBAs, out List<UInt64> UnknownLBAs)
|
||||
{
|
||||
FailingLBAs = new List<UInt64>();
|
||||
UnknownLBAs = new List<UInt64>();
|
||||
|
||||
for (UInt64 i = sectorAddress; i < sectorAddress + length; i++)
|
||||
UnknownLBAs.Add(i);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public override bool? VerifyDiskImage()
|
||||
{
|
||||
byte[] data = new byte[header.dataSize];
|
||||
byte[] tags = new byte[header.tagSize];
|
||||
UInt32 dataChk;
|
||||
UInt32 tagsChk = 0;
|
||||
|
||||
if (MainClass.isDebug)
|
||||
Console.WriteLine("DEBUG (DC42 plugin): Reading data");
|
||||
FileStream datastream = new FileStream(dc42ImagePath, FileMode.Open, FileAccess.Read);
|
||||
datastream.Seek((long)(dataOffset), SeekOrigin.Begin);
|
||||
datastream.Read(data, 0, (int)header.dataSize);
|
||||
datastream.Close();
|
||||
|
||||
if (MainClass.isDebug)
|
||||
Console.WriteLine("DEBUG (DC42 plugin): Calculating data checksum");
|
||||
dataChk = DC42CheckSum(data);
|
||||
if (MainClass.isDebug)
|
||||
{
|
||||
Console.WriteLine("DEBUG (DC42 plugin): Calculated data checksum = 0x{0:X8}", dataChk);
|
||||
Console.WriteLine("DEBUG (DC42 plugin): Stored data checksum = 0x{0:X8}", header.dataChecksum);
|
||||
}
|
||||
|
||||
if (header.tagSize > 0)
|
||||
{
|
||||
if (MainClass.isDebug)
|
||||
Console.WriteLine("DEBUG (DC42 plugin): Reading tags");
|
||||
FileStream tagstream = new FileStream(dc42ImagePath, FileMode.Open, FileAccess.Read);
|
||||
tagstream.Seek((long)(tagOffset), SeekOrigin.Begin);
|
||||
tagstream.Read(tags, 0, (int)header.tagSize);
|
||||
tagstream.Close();
|
||||
|
||||
if (MainClass.isDebug)
|
||||
Console.WriteLine("DEBUG (DC42 plugin): Calculating data checksum");
|
||||
tagsChk = DC42CheckSum(data);
|
||||
if (MainClass.isDebug)
|
||||
{
|
||||
Console.WriteLine("DEBUG (DC42 plugin): Calculated data checksum = 0x{0:X8}", tagsChk);
|
||||
Console.WriteLine("DEBUG (DC42 plugin): Stored data checksum = 0x{0:X8}", header.tagChecksum);
|
||||
}
|
||||
}
|
||||
|
||||
return dataChk == header.dataChecksum && tagsChk == header.tagChecksum;
|
||||
}
|
||||
|
||||
public override bool ImageHasPartitions()
|
||||
{
|
||||
return _imageInfo.imageHasPartitions;
|
||||
@@ -640,6 +717,25 @@ namespace DiscImageChef.ImagePlugins
|
||||
}
|
||||
|
||||
#endregion Unsupported features
|
||||
|
||||
#region Private methods
|
||||
|
||||
private static UInt32 DC42CheckSum(byte[] buffer)
|
||||
{
|
||||
UInt32 dc42chk = 0;
|
||||
if ((buffer.Length & 0x01) == 0x01)
|
||||
return 0xFFFFFFFF;
|
||||
|
||||
for (UInt32 i = 0; i < buffer.Length; i += 2)
|
||||
{
|
||||
dc42chk += (uint)(buffer[i] << 8);
|
||||
dc42chk += buffer[i + 1];
|
||||
dc42chk = (dc42chk >> 1) | (dc42chk << 31);
|
||||
}
|
||||
return dc42chk;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -108,7 +108,6 @@ namespace DiscImageChef.ImagePlugins
|
||||
/// <param name="tag">Tag type to read.</param>
|
||||
public abstract byte[] ReadDiskTag(DiskTagType tag);
|
||||
|
||||
// Gets a disk tag
|
||||
/// <summary>
|
||||
/// Reads a sector's user data.
|
||||
/// </summary>
|
||||
@@ -370,7 +369,50 @@ namespace DiscImageChef.ImagePlugins
|
||||
/// </summary>
|
||||
/// <returns>The sessions.</returns>
|
||||
public abstract List<Session> GetSessions();
|
||||
// Returns disc sessions
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Verifies a sector.
|
||||
/// </summary>
|
||||
/// <returns>True if correct, false if incorrect, null if uncheckable.</returns>
|
||||
/// <param name="sectorAddress">Sector address (LBA).</param>
|
||||
public abstract bool? VerifySector(UInt64 sectorAddress);
|
||||
|
||||
/// <summary>
|
||||
/// Verifies a sector, relative to track.
|
||||
/// </summary>
|
||||
/// <returns>True if correct, false if incorrect, null if uncheckable.</returns>
|
||||
/// <param name="sectorAddress">Sector address (relative LBA).</param>
|
||||
/// <param name="track">Track.</param>
|
||||
public abstract bool? VerifySector(UInt64 sectorAddress, UInt32 track);
|
||||
|
||||
/// <summary>
|
||||
/// Verifies several sectors.
|
||||
/// </summary>
|
||||
/// <returns>True if all are correct, false if any is incorrect, null if any is uncheckable.</returns>
|
||||
/// <param name="sectorAddress">Starting sector address (LBA).</param>
|
||||
/// <param name="length">How many sectors to read.</param>
|
||||
/// <param name="FailingLBAs">List of incorrect sectors</param>
|
||||
/// <param name="UnknownLBAs">List of uncheckable sectors</param>
|
||||
public abstract bool? VerifySectors(UInt64 sectorAddress, UInt32 length, out List<UInt64> FailingLBAs, out List<UInt64> UnknownLBAs);
|
||||
|
||||
/// <summary>
|
||||
/// Verifies several sectors, relative to track.
|
||||
/// </summary>
|
||||
/// <returns>True if all are correct, false if any is incorrect, null if any is uncheckable.</returns>
|
||||
/// <param name="sectorAddress">Starting sector address (relative LBA).</param>
|
||||
/// <param name="length">How many sectors to read.</param>
|
||||
/// <param name="track">Track.</param>
|
||||
/// <param name="FailingLBAs">List of incorrect sectors</param>
|
||||
/// <param name="UnknownLBAs">List of uncheckable sectors</param>
|
||||
public abstract bool? VerifySectors(UInt64 sectorAddress, UInt32 length, UInt32 track, out List<UInt64> FailingLBAs, out List<UInt64> UnknownLBAs);
|
||||
|
||||
/// <summary>
|
||||
/// Verifies disk image internal checksum.
|
||||
/// </summary>
|
||||
/// <returns>True if correct, false if incorrect, null if there is no internal checksum available</returns>
|
||||
public abstract bool? VerifyDiskImage();
|
||||
|
||||
|
||||
// CD flags bitmask
|
||||
|
||||
@@ -719,8 +761,9 @@ namespace DiscImageChef.ImagePlugins
|
||||
FDFORMAT_35_HD,
|
||||
|
||||
// Generic hard disks
|
||||
GENERIC_HDD
|
||||
};
|
||||
GENERIC_HDD}
|
||||
|
||||
;
|
||||
|
||||
/// <summary>
|
||||
/// Track (as partitioning element) types.
|
||||
@@ -738,8 +781,9 @@ namespace DiscImageChef.ImagePlugins
|
||||
/// <summary>Data track, compact disc mode 2, form 1</summary>
|
||||
CDMode2Form1,
|
||||
/// <summary>Data track, compact disc mode 2, form 2</summary>
|
||||
CDMode2Form2
|
||||
};
|
||||
CDMode2Form2}
|
||||
|
||||
;
|
||||
|
||||
/// <summary>
|
||||
/// Track defining structure.
|
||||
@@ -811,8 +855,9 @@ namespace DiscImageChef.ImagePlugins
|
||||
/// <summary>CD track flags, 1 byte</summary>
|
||||
CDTrackFlags,
|
||||
/// <summary>DVD sector copyright information</summary>
|
||||
DVD_CMI
|
||||
};
|
||||
DVD_CMI}
|
||||
|
||||
;
|
||||
|
||||
/// <summary>
|
||||
/// Metadata present for each disk.
|
||||
@@ -834,8 +879,9 @@ namespace DiscImageChef.ImagePlugins
|
||||
/// <summary>DVD Copyright Management Information</summary>
|
||||
DVD_CMI,
|
||||
/// <summary>DVD Disc Manufacturer Information</summary>
|
||||
DVD_DMI
|
||||
};
|
||||
DVD_DMI}
|
||||
|
||||
;
|
||||
|
||||
/// <summary>
|
||||
/// Feature is supported by image but not implemented yet.
|
||||
|
||||
@@ -2291,6 +2291,85 @@ namespace DiscImageChef.ImagePlugins
|
||||
return imageSessions;
|
||||
}
|
||||
|
||||
public override bool? VerifySector(UInt64 sectorAddress)
|
||||
{
|
||||
byte[] buffer = ReadSectorLong(sectorAddress);
|
||||
return Checksums.CDChecksums.CheckCDSector(buffer);
|
||||
}
|
||||
|
||||
public override bool? VerifySector(UInt64 sectorAddress, UInt32 track)
|
||||
{
|
||||
byte[] buffer = ReadSectorLong(sectorAddress, track);
|
||||
return Checksums.CDChecksums.CheckCDSector(buffer);
|
||||
}
|
||||
|
||||
public override bool? VerifySectors(UInt64 sectorAddress, UInt32 length, out List<UInt64> FailingLBAs, out List<UInt64> UnknownLBAs)
|
||||
{
|
||||
byte[] buffer = ReadSectorsLong(sectorAddress, length);
|
||||
int bps = (int)(buffer.Length / length);
|
||||
byte[] sector = new byte[bps];
|
||||
FailingLBAs = new List<UInt64>();
|
||||
UnknownLBAs = new List<UInt64>();
|
||||
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
Array.Copy(buffer, i * bps, sector, 0, bps);
|
||||
bool? sectorStatus = Checksums.CDChecksums.CheckCDSector(sector);
|
||||
|
||||
switch (sectorStatus)
|
||||
{
|
||||
case null:
|
||||
UnknownLBAs.Add((ulong)i + sectorAddress);
|
||||
break;
|
||||
case false:
|
||||
FailingLBAs.Add((ulong)i + sectorAddress);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (UnknownLBAs.Count > 0)
|
||||
return null;
|
||||
if (FailingLBAs.Count > 0)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool? VerifySectors(UInt64 sectorAddress, UInt32 length, UInt32 track, out List<UInt64> FailingLBAs, out List<UInt64> UnknownLBAs)
|
||||
{
|
||||
byte[] buffer = ReadSectorsLong(sectorAddress, length, track);
|
||||
int bps = (int)(buffer.Length / length);
|
||||
byte[] sector = new byte[bps];
|
||||
FailingLBAs = new List<UInt64>();
|
||||
UnknownLBAs = new List<UInt64>();
|
||||
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
Array.Copy(buffer, i * bps, sector, 0, bps);
|
||||
bool? sectorStatus = Checksums.CDChecksums.CheckCDSector(sector);
|
||||
|
||||
switch (sectorStatus)
|
||||
{
|
||||
case null:
|
||||
UnknownLBAs.Add((ulong)i + sectorAddress);
|
||||
break;
|
||||
case false:
|
||||
FailingLBAs.Add((ulong)i + sectorAddress);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (UnknownLBAs.Count > 0)
|
||||
return null;
|
||||
if (FailingLBAs.Count > 0)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool? VerifyDiskImage()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private methods
|
||||
|
||||
@@ -47,6 +47,7 @@ namespace DiscImageChef.ImagePlugins
|
||||
class TeleDisk : ImagePlugin
|
||||
{
|
||||
#region Internal Structures
|
||||
|
||||
struct TD0Header
|
||||
{
|
||||
// "TD" or "td" depending on compression
|
||||
@@ -188,11 +189,16 @@ namespace DiscImageChef.ImagePlugins
|
||||
#endregion
|
||||
|
||||
#region Internal variables
|
||||
|
||||
TD0Header header;
|
||||
TDCommentBlockHeader commentHeader;
|
||||
byte[] commentBlock;
|
||||
Dictionary<UInt32, byte[]> sectorsData; // LBA, data
|
||||
Dictionary<UInt32, byte[]> sectorsData;
|
||||
// LBA, data
|
||||
UInt32 totalDiskSize;
|
||||
bool ADiskCRCHasFailed;
|
||||
List<UInt64> SectorsWhereCRCHasFailed;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Accesible variables
|
||||
@@ -231,6 +237,8 @@ namespace DiscImageChef.ImagePlugins
|
||||
_imageInfo.driveManufacturer = null;
|
||||
_imageInfo.driveModel = null;
|
||||
_imageInfo.driveSerialNumber = null;
|
||||
ADiskCRCHasFailed = false;
|
||||
SectorsWhereCRCHasFailed = new List<UInt64>();
|
||||
}
|
||||
|
||||
public override bool IdentifyImage(string imagePath)
|
||||
@@ -346,8 +354,12 @@ namespace DiscImageChef.ImagePlugins
|
||||
// This may deny legal images
|
||||
|
||||
// That would be much of a coincidence
|
||||
if (header.crc != calculatedHeaderCRC && MainClass.isDebug)
|
||||
if (header.crc != calculatedHeaderCRC)
|
||||
{
|
||||
ADiskCRCHasFailed = true;
|
||||
if (MainClass.isDebug)
|
||||
Console.WriteLine("DEBUG (TeleDisk plugin): Calculated CRC does not coincide with stored one.");
|
||||
}
|
||||
|
||||
if (header.sequence != 0x00)
|
||||
return false;
|
||||
@@ -390,7 +402,7 @@ namespace DiscImageChef.ImagePlugins
|
||||
|
||||
UInt16 cmtcrc = TeleDiskCRC(0, commentBlockForCRC);
|
||||
|
||||
if(MainClass.isDebug)
|
||||
if (MainClass.isDebug)
|
||||
{
|
||||
Console.WriteLine("DEBUG (TeleDisk plugin): Comment header");
|
||||
Console.WriteLine("DEBUG (TeleDisk plugin): \tcommentheader.crc = 0x{0:X4}", commentHeader.crc);
|
||||
@@ -404,22 +416,24 @@ namespace DiscImageChef.ImagePlugins
|
||||
Console.WriteLine("DEBUG (TeleDisk plugin): \tcommentheader.second = {0}", commentHeader.second);
|
||||
}
|
||||
|
||||
for(int i=0;i<commentBlock.Length;i++)
|
||||
ADiskCRCHasFailed |= cmtcrc != commentHeader.crc;
|
||||
|
||||
for (int i = 0; i < commentBlock.Length; i++)
|
||||
{
|
||||
// Replace NULLs, used by TeleDisk as newline markers, with UNIX newline marker
|
||||
if(commentBlock[i]==0x00)
|
||||
commentBlock[i]=0x0A;
|
||||
if (commentBlock[i] == 0x00)
|
||||
commentBlock[i] = 0x0A;
|
||||
}
|
||||
|
||||
_imageInfo.imageComments = System.Text.Encoding.ASCII.GetString(commentBlock);
|
||||
|
||||
if(MainClass.isDebug)
|
||||
if (MainClass.isDebug)
|
||||
{
|
||||
Console.WriteLine("DEBUG (TeleDisk plugin): Comment");
|
||||
Console.WriteLine("DEBUG (TeleDisk plugin): {0}", _imageInfo.imageComments);
|
||||
}
|
||||
|
||||
_imageInfo.imageCreationTime = new DateTime(commentHeader.year+1900, commentHeader.month+1, commentHeader.day,
|
||||
_imageInfo.imageCreationTime = new DateTime(commentHeader.year + 1900, commentHeader.month + 1, commentHeader.day,
|
||||
commentHeader.hour, commentHeader.minute, commentHeader.second, DateTimeKind.Unspecified);
|
||||
}
|
||||
|
||||
@@ -468,6 +482,8 @@ namespace DiscImageChef.ImagePlugins
|
||||
Console.WriteLine("DEBUG (TeleDisk plugin): \tTrack header CRC: 0x{0:X2} (calculated 0x{1:X2})\t", TDTrack.crc, TDTrackCalculatedCRC);
|
||||
}
|
||||
|
||||
ADiskCRCHasFailed |= TDTrackCalculatedCRC != TDTrack.crc;
|
||||
|
||||
if (TDTrack.sectors == 0xFF) // End of disk image
|
||||
{
|
||||
if (MainClass.isDebug)
|
||||
@@ -529,6 +545,17 @@ namespace DiscImageChef.ImagePlugins
|
||||
}
|
||||
|
||||
decodedData = DecodeTeleDiskData(TDSector.sectorSize, TDData.dataEncoding, data);
|
||||
|
||||
byte TDSectorCalculatedCRC = (byte)(TeleDiskCRC(0, decodedData) & 0xFF);
|
||||
|
||||
if (TDSectorCalculatedCRC != TDSector.crc)
|
||||
{
|
||||
if (MainClass.isDebug)
|
||||
Console.WriteLine("DEBUG (TeleDisk plugin): Sector LBA {0} calculated CRC 0x{1:X2} differs from stored CRC 0x{2:X2}", LBA, TDSectorCalculatedCRC, TDSector.crc);
|
||||
if ((TDSector.flags & FlagsSectorNoID) != FlagsSectorNoID)
|
||||
if (!sectorsData.ContainsKey(LBA) && (TDSector.flags & FlagsSectorDuplicate) != FlagsSectorDuplicate)
|
||||
SectorsWhereCRCHasFailed.Add((UInt64)LBA);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -643,7 +670,7 @@ namespace DiscImageChef.ImagePlugins
|
||||
|
||||
byte[] sector;
|
||||
|
||||
if(!sectorsData.TryGetValue((uint)i, out sector))
|
||||
if (!sectorsData.TryGetValue((uint)i, out sector))
|
||||
throw new ImageNotSupportedException(String.Format("Error reading sector {0}", i));
|
||||
|
||||
if (first)
|
||||
@@ -713,7 +740,46 @@ namespace DiscImageChef.ImagePlugins
|
||||
return _imageInfo.diskType;
|
||||
}
|
||||
|
||||
public override bool? VerifySector(UInt64 sectorAddress)
|
||||
{
|
||||
return !SectorsWhereCRCHasFailed.Contains(sectorAddress);
|
||||
}
|
||||
|
||||
public override bool? VerifySector(UInt64 sectorAddress, UInt32 track)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public override bool? VerifySectors(UInt64 sectorAddress, UInt32 length, out List<UInt64> FailingLBAs, out List<UInt64> UnknownLBAs)
|
||||
{
|
||||
FailingLBAs = new List<UInt64>();
|
||||
UnknownLBAs = new List<UInt64>();
|
||||
|
||||
for (UInt64 i = sectorAddress; i < sectorAddress + length; i++)
|
||||
if (SectorsWhereCRCHasFailed.Contains(sectorAddress))
|
||||
FailingLBAs.Add(sectorAddress);
|
||||
|
||||
return FailingLBAs.Count <= 0;
|
||||
}
|
||||
|
||||
public override bool? VerifySectors(UInt64 sectorAddress, UInt32 length, UInt32 track, out List<UInt64> FailingLBAs, out List<UInt64> UnknownLBAs)
|
||||
{
|
||||
FailingLBAs = new List<UInt64>();
|
||||
UnknownLBAs = new List<UInt64>();
|
||||
|
||||
for (UInt64 i = sectorAddress; i < sectorAddress + length; i++)
|
||||
UnknownLBAs.Add(i);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public override bool? VerifyDiskImage()
|
||||
{
|
||||
return ADiskCRCHasFailed;
|
||||
}
|
||||
|
||||
#region Private methods
|
||||
|
||||
static UInt16 TeleDiskCRC(UInt16 crc, byte[] buffer)
|
||||
{
|
||||
int counter = 0;
|
||||
@@ -782,7 +848,7 @@ namespace DiscImageChef.ImagePlugins
|
||||
|
||||
repeatNumber = BitConverter.ToUInt16(encodedData, ins);
|
||||
Array.Copy(encodedData, ins + 2, repeatValue, 0, 2);
|
||||
byte[] decodedPiece = new byte[repeatNumber*2];
|
||||
byte[] decodedPiece = new byte[repeatNumber * 2];
|
||||
ArrayHelpers.ArrayFill(decodedPiece, repeatValue);
|
||||
Array.Copy(decodedPiece, 0, decodedData, outs, decodedPiece.Length);
|
||||
ins += 4;
|
||||
@@ -845,7 +911,7 @@ namespace DiscImageChef.ImagePlugins
|
||||
return decodedData;
|
||||
}
|
||||
|
||||
private DiskType DecodeTeleDiskDiskType()
|
||||
DiskType DecodeTeleDiskDiskType()
|
||||
{
|
||||
switch (header.driveType)
|
||||
{
|
||||
@@ -858,7 +924,7 @@ namespace DiscImageChef.ImagePlugins
|
||||
case 163840:
|
||||
{
|
||||
// Acorn disk uses 256 bytes/sector
|
||||
if(_imageInfo.sectorSize == 256)
|
||||
if (_imageInfo.sectorSize == 256)
|
||||
return DiskType.ACORN_525_SS_DD_40;
|
||||
else // DOS disks use 512 bytes/sector
|
||||
return DiskType.DOS_525_SS_DD_8;
|
||||
@@ -866,7 +932,7 @@ namespace DiscImageChef.ImagePlugins
|
||||
case 184320:
|
||||
{
|
||||
// Atari disk uses 256 bytes/sector
|
||||
if(_imageInfo.sectorSize == 256)
|
||||
if (_imageInfo.sectorSize == 256)
|
||||
return DiskType.ATARI_525_DD;
|
||||
else // DOS disks use 512 bytes/sector
|
||||
return DiskType.DOS_525_SS_DD_9;
|
||||
@@ -874,7 +940,7 @@ namespace DiscImageChef.ImagePlugins
|
||||
case 327680:
|
||||
{
|
||||
// Acorn disk uses 256 bytes/sector
|
||||
if(_imageInfo.sectorSize == 256)
|
||||
if (_imageInfo.sectorSize == 256)
|
||||
return DiskType.ACORN_525_SS_DD_80;
|
||||
else // DOS disks use 512 bytes/sector
|
||||
return DiskType.DOS_525_DS_DD_8;
|
||||
@@ -994,7 +1060,7 @@ namespace DiscImageChef.ImagePlugins
|
||||
case 512512:
|
||||
{
|
||||
// DEC disk uses 256 bytes/sector
|
||||
if(_imageInfo.sectorSize == 256)
|
||||
if (_imageInfo.sectorSize == 256)
|
||||
return DiskType.RX02;
|
||||
else // ECMA disks use 128 bytes/sector
|
||||
return DiskType.ECMA_59;
|
||||
@@ -1024,6 +1090,7 @@ namespace DiscImageChef.ImagePlugins
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Unsupported features
|
||||
|
||||
@@ -46,8 +46,10 @@ namespace DiscImageChef.ImagePlugins
|
||||
class ZZZRawImage : ImagePlugin
|
||||
{
|
||||
#region Internal variables
|
||||
|
||||
string rawImagePath;
|
||||
bool differentTrackZeroSize;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Accesible variables
|
||||
@@ -356,7 +358,45 @@ namespace DiscImageChef.ImagePlugins
|
||||
return _imageInfo.diskType;
|
||||
}
|
||||
|
||||
public override bool? VerifySector(UInt64 sectorAddress)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public override bool? VerifySector(UInt64 sectorAddress, UInt32 track)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public override bool? VerifySectors(UInt64 sectorAddress, UInt32 length, out List<UInt64> FailingLBAs, out List<UInt64> UnknownLBAs)
|
||||
{
|
||||
FailingLBAs = new List<UInt64>();
|
||||
UnknownLBAs = new List<UInt64>();
|
||||
|
||||
for (UInt64 i = sectorAddress; i < sectorAddress + length; i++)
|
||||
UnknownLBAs.Add(i);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public override bool? VerifySectors(UInt64 sectorAddress, UInt32 length, UInt32 track, out List<UInt64> FailingLBAs, out List<UInt64> UnknownLBAs)
|
||||
{
|
||||
FailingLBAs = new List<UInt64>();
|
||||
UnknownLBAs = new List<UInt64>();
|
||||
|
||||
for (UInt64 i = sectorAddress; i < sectorAddress + length; i++)
|
||||
UnknownLBAs.Add(i);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public override bool? VerifyDiskImage()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
#region Private methods
|
||||
|
||||
private DiskType CalculateDiskType()
|
||||
{
|
||||
if (_imageInfo.sectorSize == 2048)
|
||||
@@ -492,6 +532,7 @@ namespace DiscImageChef.ImagePlugins
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Unsupported features
|
||||
|
||||
@@ -41,6 +41,6 @@
|
||||
</Package>
|
||||
</Packages>
|
||||
</Packages>
|
||||
<ReleaseVersion>2.0</ReleaseVersion>
|
||||
<ReleaseVersion>2.1</ReleaseVersion>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -1,4 +1,4 @@
|
||||
DiscImageChef v2.00
|
||||
DiscImageChef v2.10
|
||||
===================
|
||||
|
||||
Disc Image Chef (because "swiss-army-knife" is used too much)
|
||||
@@ -23,9 +23,9 @@ Features
|
||||
* Identifies HFS, HFS+, MFS, BeFS, ext/2/3/4, FAT12/16/32, FFS/UFS/UFS2, HPFS, ISO9660, LisaFS, MinixFS, NTFS, ODS11, Opera, PCEngine, SolarFS, System V and UnixWare boot filesystem.
|
||||
* Analyzes a disk image getting information about the disk itself and analyzes partitions and filesystems inside them
|
||||
* Can compare two disk images, even different formats, for different sectors and/or metadata
|
||||
* Can verify sectors or disk images if supported by the underlying format (well, it will be able to in version 2.1)
|
||||
* Can verify sectors or disk images if supported by the underlying format
|
||||
* Can checksum the disks (and if optical disc, separate tracks) user-data (tags and metadata coming soon)
|
||||
* Supports CRC32 and CRC64 cyclic redundance checksums as well as MD5, RMD160, SHA1, SHA256, SHA384 and SHA512 hashes.
|
||||
* Supports CRC16, CRC32 and CRC64 cyclic redundance checksums as well as MD5, RMD160, SHA1, SHA256, SHA384 and SHA512 hashes.
|
||||
|
||||
Changelog
|
||||
=========
|
||||
|
||||
Reference in New Issue
Block a user