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
|
GlobalSection(MonoDevelopProperties) = preSolution
|
||||||
StartupItem = DiscImageChef\DiscImageChef.csproj
|
StartupItem = DiscImageChef\DiscImageChef.csproj
|
||||||
description = The Disc Image Chef.
|
description = The Disc Image Chef.
|
||||||
version = 2.0
|
version = 2.1
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ using System.Reflection;
|
|||||||
// The form "{Major}.{Minor}.*" will automatically update the build and revision,
|
// The form "{Major}.{Minor}.*" will automatically update the build and revision,
|
||||||
// and "{Major}.{Minor}.{Build}.*" will update just the 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,
|
// The following attributes are used to specify the signing key for the assembly,
|
||||||
// if desired. See the Mono documentation for more information about signing.
|
// if desired. See the Mono documentation for more information about signing.
|
||||||
|
|||||||
@@ -36,6 +36,8 @@ Copyright (C) 2011-2014 Claunia.com
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
//$Id$
|
//$Id$
|
||||||
using System;
|
using System;
|
||||||
|
using DiscImageChef.ImagePlugins;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace DiscImageChef.Commands
|
namespace DiscImageChef.Commands
|
||||||
{
|
{
|
||||||
@@ -51,7 +53,211 @@ namespace DiscImageChef.Commands
|
|||||||
Console.WriteLine("--verify-disc={0}", options.VerifyDisc);
|
Console.WriteLine("--verify-disc={0}", options.VerifyDisc);
|
||||||
Console.WriteLine("--verify-sectors={0}", options.VerifySectors);
|
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>
|
<RootNamespace>DiscImageChef</RootNamespace>
|
||||||
<AssemblyName>DiscImageChef</AssemblyName>
|
<AssemblyName>DiscImageChef</AssemblyName>
|
||||||
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
|
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
|
||||||
<ReleaseVersion>2.0</ReleaseVersion>
|
<ReleaseVersion>2.1</ReleaseVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
|
||||||
<DebugSymbols>True</DebugSymbols>
|
<DebugSymbols>True</DebugSymbols>
|
||||||
|
|||||||
@@ -1251,70 +1251,68 @@ namespace DiscImageChef.ImagePlugins
|
|||||||
_imageInfo.diskBarcode = discimage.barcode;
|
_imageInfo.diskBarcode = discimage.barcode;
|
||||||
_imageInfo.diskType = discimage.disktype;
|
_imageInfo.diskType = discimage.disktype;
|
||||||
|
|
||||||
foreach(CDRWinTrack track in discimage.tracks)
|
foreach (CDRWinTrack track in discimage.tracks)
|
||||||
{
|
{
|
||||||
switch(track.tracktype)
|
switch (track.tracktype)
|
||||||
{
|
{
|
||||||
case CDRWinTrackTypeAudio:
|
case CDRWinTrackTypeAudio:
|
||||||
{
|
{
|
||||||
if(!_imageInfo.readableSectorTags.Contains(SectorTagType.CDTrackISRC))
|
if (!_imageInfo.readableSectorTags.Contains(SectorTagType.CDTrackISRC))
|
||||||
_imageInfo.readableSectorTags.Add(SectorTagType.CDTrackISRC);
|
_imageInfo.readableSectorTags.Add(SectorTagType.CDTrackISRC);
|
||||||
if(!_imageInfo.readableSectorTags.Contains(SectorTagType.CDTrackFlags))
|
if (!_imageInfo.readableSectorTags.Contains(SectorTagType.CDTrackFlags))
|
||||||
_imageInfo.readableSectorTags.Add(SectorTagType.CDTrackFlags);
|
_imageInfo.readableSectorTags.Add(SectorTagType.CDTrackFlags);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CDRWinTrackTypeCDG:
|
case CDRWinTrackTypeCDG:
|
||||||
{
|
{
|
||||||
if(!_imageInfo.readableSectorTags.Contains(SectorTagType.CDTrackISRC))
|
if (!_imageInfo.readableSectorTags.Contains(SectorTagType.CDTrackISRC))
|
||||||
_imageInfo.readableSectorTags.Add(SectorTagType.CDTrackISRC);
|
_imageInfo.readableSectorTags.Add(SectorTagType.CDTrackISRC);
|
||||||
if(!_imageInfo.readableSectorTags.Contains(SectorTagType.CDTrackFlags))
|
if (!_imageInfo.readableSectorTags.Contains(SectorTagType.CDTrackFlags))
|
||||||
_imageInfo.readableSectorTags.Add(SectorTagType.CDTrackFlags);
|
_imageInfo.readableSectorTags.Add(SectorTagType.CDTrackFlags);
|
||||||
if(!_imageInfo.readableSectorTags.Contains(SectorTagType.CDSectorSubchannel))
|
if (!_imageInfo.readableSectorTags.Contains(SectorTagType.CDSectorSubchannel))
|
||||||
_imageInfo.readableSectorTags.Add(SectorTagType.CDSectorSubchannel);
|
_imageInfo.readableSectorTags.Add(SectorTagType.CDSectorSubchannel);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CDRWinTrackTypeMode2Formless:
|
case CDRWinTrackTypeMode2Formless:
|
||||||
case CDRWinTrackTypeCDI:
|
case CDRWinTrackTypeCDI:
|
||||||
{
|
{
|
||||||
if(!_imageInfo.readableSectorTags.Contains(SectorTagType.CDSectorSubHeader))
|
if (!_imageInfo.readableSectorTags.Contains(SectorTagType.CDSectorSubHeader))
|
||||||
_imageInfo.readableSectorTags.Add(SectorTagType.CDSectorSubHeader);
|
_imageInfo.readableSectorTags.Add(SectorTagType.CDSectorSubHeader);
|
||||||
if(!_imageInfo.readableSectorTags.Contains(SectorTagType.CDSectorEDC))
|
if (!_imageInfo.readableSectorTags.Contains(SectorTagType.CDSectorEDC))
|
||||||
_imageInfo.readableSectorTags.Add(SectorTagType.CDSectorEDC);
|
_imageInfo.readableSectorTags.Add(SectorTagType.CDSectorEDC);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CDRWinTrackTypeMode2Raw:
|
case CDRWinTrackTypeMode2Raw:
|
||||||
case CDRWinTrackTypeCDIRaw:
|
case CDRWinTrackTypeCDIRaw:
|
||||||
{
|
{
|
||||||
if(!_imageInfo.readableSectorTags.Contains(SectorTagType.CDSectorSync))
|
if (!_imageInfo.readableSectorTags.Contains(SectorTagType.CDSectorSync))
|
||||||
_imageInfo.readableSectorTags.Add(SectorTagType.CDSectorSync);
|
_imageInfo.readableSectorTags.Add(SectorTagType.CDSectorSync);
|
||||||
if(!_imageInfo.readableSectorTags.Contains(SectorTagType.CDSectorHeader))
|
if (!_imageInfo.readableSectorTags.Contains(SectorTagType.CDSectorHeader))
|
||||||
_imageInfo.readableSectorTags.Add(SectorTagType.CDSectorHeader);
|
_imageInfo.readableSectorTags.Add(SectorTagType.CDSectorHeader);
|
||||||
if(!_imageInfo.readableSectorTags.Contains(SectorTagType.CDSectorSubHeader))
|
if (!_imageInfo.readableSectorTags.Contains(SectorTagType.CDSectorSubHeader))
|
||||||
_imageInfo.readableSectorTags.Add(SectorTagType.CDSectorSubHeader);
|
_imageInfo.readableSectorTags.Add(SectorTagType.CDSectorSubHeader);
|
||||||
if(!_imageInfo.readableSectorTags.Contains(SectorTagType.CDSectorEDC))
|
if (!_imageInfo.readableSectorTags.Contains(SectorTagType.CDSectorEDC))
|
||||||
_imageInfo.readableSectorTags.Add(SectorTagType.CDSectorEDC);
|
_imageInfo.readableSectorTags.Add(SectorTagType.CDSectorEDC);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CDRWinTrackTypeMode1Raw:
|
case CDRWinTrackTypeMode1Raw:
|
||||||
{
|
{
|
||||||
if(!_imageInfo.readableSectorTags.Contains(SectorTagType.CDSectorSync))
|
if (!_imageInfo.readableSectorTags.Contains(SectorTagType.CDSectorSync))
|
||||||
_imageInfo.readableSectorTags.Add(SectorTagType.CDSectorSync);
|
_imageInfo.readableSectorTags.Add(SectorTagType.CDSectorSync);
|
||||||
if(!_imageInfo.readableSectorTags.Contains(SectorTagType.CDSectorHeader))
|
if (!_imageInfo.readableSectorTags.Contains(SectorTagType.CDSectorHeader))
|
||||||
_imageInfo.readableSectorTags.Add(SectorTagType.CDSectorHeader);
|
_imageInfo.readableSectorTags.Add(SectorTagType.CDSectorHeader);
|
||||||
if(!_imageInfo.readableSectorTags.Contains(SectorTagType.CDSectorSubHeader))
|
if (!_imageInfo.readableSectorTags.Contains(SectorTagType.CDSectorSubHeader))
|
||||||
_imageInfo.readableSectorTags.Add(SectorTagType.CDSectorSubHeader);
|
_imageInfo.readableSectorTags.Add(SectorTagType.CDSectorSubHeader);
|
||||||
if(!_imageInfo.readableSectorTags.Contains(SectorTagType.CDSectorECC))
|
if (!_imageInfo.readableSectorTags.Contains(SectorTagType.CDSectorECC))
|
||||||
_imageInfo.readableSectorTags.Add(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);
|
_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);
|
_imageInfo.readableSectorTags.Add(SectorTagType.CDSectorECC_Q);
|
||||||
if(!_imageInfo.readableSectorTags.Contains(SectorTagType.CDSectorEDC))
|
if (!_imageInfo.readableSectorTags.Contains(SectorTagType.CDSectorEDC))
|
||||||
_imageInfo.readableSectorTags.Add(SectorTagType.CDSectorEDC);
|
_imageInfo.readableSectorTags.Add(SectorTagType.CDSectorEDC);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1928,6 +1926,8 @@ namespace DiscImageChef.ImagePlugins
|
|||||||
{
|
{
|
||||||
List<Track> tracks = new List<Track>();
|
List<Track> tracks = new List<Track>();
|
||||||
|
|
||||||
|
UInt64 previousStartSector = 0;
|
||||||
|
|
||||||
foreach (CDRWinTrack cdr_track in discimage.tracks)
|
foreach (CDRWinTrack cdr_track in discimage.tracks)
|
||||||
{
|
{
|
||||||
Track _track = new Track();
|
Track _track = new Track();
|
||||||
@@ -1936,6 +1936,7 @@ namespace DiscImageChef.ImagePlugins
|
|||||||
_track.TrackDescription = cdr_track.title;
|
_track.TrackDescription = cdr_track.title;
|
||||||
if (!cdr_track.indexes.TryGetValue(0, out _track.TrackStartSector))
|
if (!cdr_track.indexes.TryGetValue(0, out _track.TrackStartSector))
|
||||||
cdr_track.indexes.TryGetValue(1, out _track.TrackStartSector);
|
cdr_track.indexes.TryGetValue(1, out _track.TrackStartSector);
|
||||||
|
_track.TrackStartSector += previousStartSector;
|
||||||
_track.TrackEndSector = _track.TrackStartSector + cdr_track.sectors - 1;
|
_track.TrackEndSector = _track.TrackStartSector + cdr_track.sectors - 1;
|
||||||
_track.TrackPregap = cdr_track.pregap;
|
_track.TrackPregap = cdr_track.pregap;
|
||||||
_track.TrackSession = cdr_track.session;
|
_track.TrackSession = cdr_track.session;
|
||||||
@@ -1943,6 +1944,7 @@ namespace DiscImageChef.ImagePlugins
|
|||||||
_track.TrackType = CDRWinTrackTypeToTrackType(cdr_track.tracktype);
|
_track.TrackType = CDRWinTrackTypeToTrackType(cdr_track.tracktype);
|
||||||
|
|
||||||
tracks.Add(_track);
|
tracks.Add(_track);
|
||||||
|
previousStartSector = _track.TrackEndSector + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return tracks;
|
return tracks;
|
||||||
@@ -1989,6 +1991,85 @@ namespace DiscImageChef.ImagePlugins
|
|||||||
return discimage.sessions;
|
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
|
#endregion
|
||||||
|
|
||||||
#region Private methods
|
#region Private methods
|
||||||
@@ -2168,6 +2249,7 @@ namespace DiscImageChef.ImagePlugins
|
|||||||
{
|
{
|
||||||
return _imageInfo.imageCreator;
|
return _imageInfo.imageCreator;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -373,6 +373,83 @@ namespace DiscImageChef.ImagePlugins
|
|||||||
return true;
|
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()
|
public override bool ImageHasPartitions()
|
||||||
{
|
{
|
||||||
return _imageInfo.imageHasPartitions;
|
return _imageInfo.imageHasPartitions;
|
||||||
@@ -640,6 +717,25 @@ namespace DiscImageChef.ImagePlugins
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endregion Unsupported features
|
#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>
|
/// <param name="tag">Tag type to read.</param>
|
||||||
public abstract byte[] ReadDiskTag(DiskTagType tag);
|
public abstract byte[] ReadDiskTag(DiskTagType tag);
|
||||||
|
|
||||||
// Gets a disk tag
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Reads a sector's user data.
|
/// Reads a sector's user data.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -370,7 +369,50 @@ namespace DiscImageChef.ImagePlugins
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The sessions.</returns>
|
/// <returns>The sessions.</returns>
|
||||||
public abstract List<Session> GetSessions();
|
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
|
// CD flags bitmask
|
||||||
|
|
||||||
@@ -719,8 +761,9 @@ namespace DiscImageChef.ImagePlugins
|
|||||||
FDFORMAT_35_HD,
|
FDFORMAT_35_HD,
|
||||||
|
|
||||||
// Generic hard disks
|
// Generic hard disks
|
||||||
GENERIC_HDD
|
GENERIC_HDD}
|
||||||
};
|
|
||||||
|
;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Track (as partitioning element) types.
|
/// Track (as partitioning element) types.
|
||||||
@@ -738,8 +781,9 @@ namespace DiscImageChef.ImagePlugins
|
|||||||
/// <summary>Data track, compact disc mode 2, form 1</summary>
|
/// <summary>Data track, compact disc mode 2, form 1</summary>
|
||||||
CDMode2Form1,
|
CDMode2Form1,
|
||||||
/// <summary>Data track, compact disc mode 2, form 2</summary>
|
/// <summary>Data track, compact disc mode 2, form 2</summary>
|
||||||
CDMode2Form2
|
CDMode2Form2}
|
||||||
};
|
|
||||||
|
;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Track defining structure.
|
/// Track defining structure.
|
||||||
@@ -811,8 +855,9 @@ namespace DiscImageChef.ImagePlugins
|
|||||||
/// <summary>CD track flags, 1 byte</summary>
|
/// <summary>CD track flags, 1 byte</summary>
|
||||||
CDTrackFlags,
|
CDTrackFlags,
|
||||||
/// <summary>DVD sector copyright information</summary>
|
/// <summary>DVD sector copyright information</summary>
|
||||||
DVD_CMI
|
DVD_CMI}
|
||||||
};
|
|
||||||
|
;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Metadata present for each disk.
|
/// Metadata present for each disk.
|
||||||
@@ -834,8 +879,9 @@ namespace DiscImageChef.ImagePlugins
|
|||||||
/// <summary>DVD Copyright Management Information</summary>
|
/// <summary>DVD Copyright Management Information</summary>
|
||||||
DVD_CMI,
|
DVD_CMI,
|
||||||
/// <summary>DVD Disc Manufacturer Information</summary>
|
/// <summary>DVD Disc Manufacturer Information</summary>
|
||||||
DVD_DMI
|
DVD_DMI}
|
||||||
};
|
|
||||||
|
;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Feature is supported by image but not implemented yet.
|
/// Feature is supported by image but not implemented yet.
|
||||||
|
|||||||
@@ -2010,7 +2010,7 @@ namespace DiscImageChef.ImagePlugins
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// TODO
|
// TODO
|
||||||
case DAOMode.DataM2RawSub:
|
case DAOMode.DataM2RawSub:
|
||||||
throw new FeatureSupportedButNotImplementedImageException("Feature not yet implemented");
|
throw new FeatureSupportedButNotImplementedImageException("Feature not yet implemented");
|
||||||
case DAOMode.DataRawSub:
|
case DAOMode.DataRawSub:
|
||||||
@@ -2291,6 +2291,85 @@ namespace DiscImageChef.ImagePlugins
|
|||||||
return imageSessions;
|
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
|
#endregion
|
||||||
|
|
||||||
#region Private methods
|
#region Private methods
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ namespace DiscImageChef.ImagePlugins
|
|||||||
class TeleDisk : ImagePlugin
|
class TeleDisk : ImagePlugin
|
||||||
{
|
{
|
||||||
#region Internal Structures
|
#region Internal Structures
|
||||||
|
|
||||||
struct TD0Header
|
struct TD0Header
|
||||||
{
|
{
|
||||||
// "TD" or "td" depending on compression
|
// "TD" or "td" depending on compression
|
||||||
@@ -122,7 +123,7 @@ namespace DiscImageChef.ImagePlugins
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Internal Constants
|
#region Internal Constants
|
||||||
|
|
||||||
// "TD" as little endian uint.
|
// "TD" as little endian uint.
|
||||||
@@ -186,13 +187,18 @@ namespace DiscImageChef.ImagePlugins
|
|||||||
const byte dataBlockRLE = 0x02;
|
const byte dataBlockRLE = 0x02;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Internal variables
|
#region Internal variables
|
||||||
|
|
||||||
TD0Header header;
|
TD0Header header;
|
||||||
TDCommentBlockHeader commentHeader;
|
TDCommentBlockHeader commentHeader;
|
||||||
byte[] commentBlock;
|
byte[] commentBlock;
|
||||||
Dictionary<UInt32, byte[]> sectorsData; // LBA, data
|
Dictionary<UInt32, byte[]> sectorsData;
|
||||||
|
// LBA, data
|
||||||
UInt32 totalDiskSize;
|
UInt32 totalDiskSize;
|
||||||
|
bool ADiskCRCHasFailed;
|
||||||
|
List<UInt64> SectorsWhereCRCHasFailed;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Accesible variables
|
#region Accesible variables
|
||||||
@@ -231,6 +237,8 @@ namespace DiscImageChef.ImagePlugins
|
|||||||
_imageInfo.driveManufacturer = null;
|
_imageInfo.driveManufacturer = null;
|
||||||
_imageInfo.driveModel = null;
|
_imageInfo.driveModel = null;
|
||||||
_imageInfo.driveSerialNumber = null;
|
_imageInfo.driveSerialNumber = null;
|
||||||
|
ADiskCRCHasFailed = false;
|
||||||
|
SectorsWhereCRCHasFailed = new List<UInt64>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool IdentifyImage(string imagePath)
|
public override bool IdentifyImage(string imagePath)
|
||||||
@@ -295,7 +303,7 @@ namespace DiscImageChef.ImagePlugins
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool OpenImage(string imagePath)
|
public override bool OpenImage(string imagePath)
|
||||||
{
|
{
|
||||||
header = new TD0Header();
|
header = new TD0Header();
|
||||||
@@ -346,8 +354,12 @@ namespace DiscImageChef.ImagePlugins
|
|||||||
// This may deny legal images
|
// This may deny legal images
|
||||||
|
|
||||||
// That would be much of a coincidence
|
// That would be much of a coincidence
|
||||||
if (header.crc != calculatedHeaderCRC && MainClass.isDebug)
|
if (header.crc != calculatedHeaderCRC)
|
||||||
Console.WriteLine("DEBUG (TeleDisk plugin): Calculated CRC does not coincide with stored one.");
|
{
|
||||||
|
ADiskCRCHasFailed = true;
|
||||||
|
if (MainClass.isDebug)
|
||||||
|
Console.WriteLine("DEBUG (TeleDisk plugin): Calculated CRC does not coincide with stored one.");
|
||||||
|
}
|
||||||
|
|
||||||
if (header.sequence != 0x00)
|
if (header.sequence != 0x00)
|
||||||
return false;
|
return false;
|
||||||
@@ -390,7 +402,7 @@ namespace DiscImageChef.ImagePlugins
|
|||||||
|
|
||||||
UInt16 cmtcrc = TeleDiskCRC(0, commentBlockForCRC);
|
UInt16 cmtcrc = TeleDiskCRC(0, commentBlockForCRC);
|
||||||
|
|
||||||
if(MainClass.isDebug)
|
if (MainClass.isDebug)
|
||||||
{
|
{
|
||||||
Console.WriteLine("DEBUG (TeleDisk plugin): Comment header");
|
Console.WriteLine("DEBUG (TeleDisk plugin): Comment header");
|
||||||
Console.WriteLine("DEBUG (TeleDisk plugin): \tcommentheader.crc = 0x{0:X4}", commentHeader.crc);
|
Console.WriteLine("DEBUG (TeleDisk plugin): \tcommentheader.crc = 0x{0:X4}", commentHeader.crc);
|
||||||
@@ -404,23 +416,25 @@ namespace DiscImageChef.ImagePlugins
|
|||||||
Console.WriteLine("DEBUG (TeleDisk plugin): \tcommentheader.second = {0}", commentHeader.second);
|
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
|
// Replace NULLs, used by TeleDisk as newline markers, with UNIX newline marker
|
||||||
if(commentBlock[i]==0x00)
|
if (commentBlock[i] == 0x00)
|
||||||
commentBlock[i]=0x0A;
|
commentBlock[i] = 0x0A;
|
||||||
}
|
}
|
||||||
|
|
||||||
_imageInfo.imageComments = System.Text.Encoding.ASCII.GetString(commentBlock);
|
_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): Comment");
|
||||||
Console.WriteLine("DEBUG (TeleDisk plugin): {0}", _imageInfo.imageComments);
|
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);
|
commentHeader.hour, commentHeader.minute, commentHeader.second, DateTimeKind.Unspecified);
|
||||||
}
|
}
|
||||||
|
|
||||||
FileInfo fi = new FileInfo(imagePath);
|
FileInfo fi = new FileInfo(imagePath);
|
||||||
@@ -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);
|
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 (TDTrack.sectors == 0xFF) // End of disk image
|
||||||
{
|
{
|
||||||
if (MainClass.isDebug)
|
if (MainClass.isDebug)
|
||||||
@@ -529,6 +545,17 @@ namespace DiscImageChef.ImagePlugins
|
|||||||
}
|
}
|
||||||
|
|
||||||
decodedData = DecodeTeleDiskData(TDSector.sectorSize, TDData.dataEncoding, data);
|
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
|
else
|
||||||
{
|
{
|
||||||
@@ -598,32 +625,32 @@ namespace DiscImageChef.ImagePlugins
|
|||||||
stream.Close();
|
stream.Close();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool ImageHasPartitions()
|
public override bool ImageHasPartitions()
|
||||||
{
|
{
|
||||||
return _imageInfo.imageHasPartitions;
|
return _imageInfo.imageHasPartitions;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override UInt64 GetImageSize()
|
public override UInt64 GetImageSize()
|
||||||
{
|
{
|
||||||
return _imageInfo.imageSize;
|
return _imageInfo.imageSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override UInt64 GetSectors()
|
public override UInt64 GetSectors()
|
||||||
{
|
{
|
||||||
return _imageInfo.sectors;
|
return _imageInfo.sectors;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override UInt32 GetSectorSize()
|
public override UInt32 GetSectorSize()
|
||||||
{
|
{
|
||||||
return _imageInfo.sectorSize;
|
return _imageInfo.sectorSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override byte[] ReadSector(UInt64 sectorAddress)
|
public override byte[] ReadSector(UInt64 sectorAddress)
|
||||||
{
|
{
|
||||||
return ReadSectors(sectorAddress, 1);
|
return ReadSectors(sectorAddress, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override byte[] ReadSectors(UInt64 sectorAddress, UInt32 length)
|
public override byte[] ReadSectors(UInt64 sectorAddress, UInt32 length)
|
||||||
{
|
{
|
||||||
if (sectorAddress > (ulong)sectorsData.Count - 1)
|
if (sectorAddress > (ulong)sectorsData.Count - 1)
|
||||||
@@ -643,7 +670,7 @@ namespace DiscImageChef.ImagePlugins
|
|||||||
|
|
||||||
byte[] sector;
|
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));
|
throw new ImageNotSupportedException(String.Format("Error reading sector {0}", i));
|
||||||
|
|
||||||
if (first)
|
if (first)
|
||||||
@@ -662,58 +689,97 @@ namespace DiscImageChef.ImagePlugins
|
|||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override byte[] ReadSectorLong(UInt64 sectorAddress)
|
public override byte[] ReadSectorLong(UInt64 sectorAddress)
|
||||||
{
|
{
|
||||||
return ReadSectors(sectorAddress, 1);
|
return ReadSectors(sectorAddress, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override byte[] ReadSectorsLong(UInt64 sectorAddress, UInt32 length)
|
public override byte[] ReadSectorsLong(UInt64 sectorAddress, UInt32 length)
|
||||||
{
|
{
|
||||||
return ReadSectors(sectorAddress, length);
|
return ReadSectors(sectorAddress, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string GetImageFormat()
|
public override string GetImageFormat()
|
||||||
{
|
{
|
||||||
return "Sydex TeleDisk";
|
return "Sydex TeleDisk";
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string GetImageVersion()
|
public override string GetImageVersion()
|
||||||
{
|
{
|
||||||
return _imageInfo.imageVersion;
|
return _imageInfo.imageVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string GetImageApplication()
|
public override string GetImageApplication()
|
||||||
{
|
{
|
||||||
return _imageInfo.imageApplication;
|
return _imageInfo.imageApplication;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string GetImageApplicationVersion()
|
public override string GetImageApplicationVersion()
|
||||||
{
|
{
|
||||||
return _imageInfo.imageApplicationVersion;
|
return _imageInfo.imageApplicationVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override DateTime GetImageCreationTime()
|
public override DateTime GetImageCreationTime()
|
||||||
{
|
{
|
||||||
return _imageInfo.imageCreationTime;
|
return _imageInfo.imageCreationTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override DateTime GetImageLastModificationTime()
|
public override DateTime GetImageLastModificationTime()
|
||||||
{
|
{
|
||||||
return _imageInfo.imageLastModificationTime;
|
return _imageInfo.imageLastModificationTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string GetImageName()
|
public override string GetImageName()
|
||||||
{
|
{
|
||||||
return _imageInfo.imageName;
|
return _imageInfo.imageName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override DiskType GetDiskType()
|
public override DiskType GetDiskType()
|
||||||
{
|
{
|
||||||
return _imageInfo.diskType;
|
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
|
#region Private methods
|
||||||
|
|
||||||
static UInt16 TeleDiskCRC(UInt16 crc, byte[] buffer)
|
static UInt16 TeleDiskCRC(UInt16 crc, byte[] buffer)
|
||||||
{
|
{
|
||||||
int counter = 0;
|
int counter = 0;
|
||||||
@@ -782,7 +848,7 @@ namespace DiscImageChef.ImagePlugins
|
|||||||
|
|
||||||
repeatNumber = BitConverter.ToUInt16(encodedData, ins);
|
repeatNumber = BitConverter.ToUInt16(encodedData, ins);
|
||||||
Array.Copy(encodedData, ins + 2, repeatValue, 0, 2);
|
Array.Copy(encodedData, ins + 2, repeatValue, 0, 2);
|
||||||
byte[] decodedPiece = new byte[repeatNumber*2];
|
byte[] decodedPiece = new byte[repeatNumber * 2];
|
||||||
ArrayHelpers.ArrayFill(decodedPiece, repeatValue);
|
ArrayHelpers.ArrayFill(decodedPiece, repeatValue);
|
||||||
Array.Copy(decodedPiece, 0, decodedData, outs, decodedPiece.Length);
|
Array.Copy(decodedPiece, 0, decodedData, outs, decodedPiece.Length);
|
||||||
ins += 4;
|
ins += 4;
|
||||||
@@ -845,7 +911,7 @@ namespace DiscImageChef.ImagePlugins
|
|||||||
return decodedData;
|
return decodedData;
|
||||||
}
|
}
|
||||||
|
|
||||||
private DiskType DecodeTeleDiskDiskType()
|
DiskType DecodeTeleDiskDiskType()
|
||||||
{
|
{
|
||||||
switch (header.driveType)
|
switch (header.driveType)
|
||||||
{
|
{
|
||||||
@@ -858,7 +924,7 @@ namespace DiscImageChef.ImagePlugins
|
|||||||
case 163840:
|
case 163840:
|
||||||
{
|
{
|
||||||
// Acorn disk uses 256 bytes/sector
|
// Acorn disk uses 256 bytes/sector
|
||||||
if(_imageInfo.sectorSize == 256)
|
if (_imageInfo.sectorSize == 256)
|
||||||
return DiskType.ACORN_525_SS_DD_40;
|
return DiskType.ACORN_525_SS_DD_40;
|
||||||
else // DOS disks use 512 bytes/sector
|
else // DOS disks use 512 bytes/sector
|
||||||
return DiskType.DOS_525_SS_DD_8;
|
return DiskType.DOS_525_SS_DD_8;
|
||||||
@@ -866,7 +932,7 @@ namespace DiscImageChef.ImagePlugins
|
|||||||
case 184320:
|
case 184320:
|
||||||
{
|
{
|
||||||
// Atari disk uses 256 bytes/sector
|
// Atari disk uses 256 bytes/sector
|
||||||
if(_imageInfo.sectorSize == 256)
|
if (_imageInfo.sectorSize == 256)
|
||||||
return DiskType.ATARI_525_DD;
|
return DiskType.ATARI_525_DD;
|
||||||
else // DOS disks use 512 bytes/sector
|
else // DOS disks use 512 bytes/sector
|
||||||
return DiskType.DOS_525_SS_DD_9;
|
return DiskType.DOS_525_SS_DD_9;
|
||||||
@@ -874,7 +940,7 @@ namespace DiscImageChef.ImagePlugins
|
|||||||
case 327680:
|
case 327680:
|
||||||
{
|
{
|
||||||
// Acorn disk uses 256 bytes/sector
|
// Acorn disk uses 256 bytes/sector
|
||||||
if(_imageInfo.sectorSize == 256)
|
if (_imageInfo.sectorSize == 256)
|
||||||
return DiskType.ACORN_525_SS_DD_80;
|
return DiskType.ACORN_525_SS_DD_80;
|
||||||
else // DOS disks use 512 bytes/sector
|
else // DOS disks use 512 bytes/sector
|
||||||
return DiskType.DOS_525_DS_DD_8;
|
return DiskType.DOS_525_DS_DD_8;
|
||||||
@@ -994,7 +1060,7 @@ namespace DiscImageChef.ImagePlugins
|
|||||||
case 512512:
|
case 512512:
|
||||||
{
|
{
|
||||||
// DEC disk uses 256 bytes/sector
|
// DEC disk uses 256 bytes/sector
|
||||||
if(_imageInfo.sectorSize == 256)
|
if (_imageInfo.sectorSize == 256)
|
||||||
return DiskType.RX02;
|
return DiskType.RX02;
|
||||||
else // ECMA disks use 128 bytes/sector
|
else // ECMA disks use 128 bytes/sector
|
||||||
return DiskType.ECMA_59;
|
return DiskType.ECMA_59;
|
||||||
@@ -1024,140 +1090,141 @@ namespace DiscImageChef.ImagePlugins
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Unsupported features
|
#region Unsupported features
|
||||||
|
|
||||||
public override byte[] ReadSectorTag(UInt64 sectorAddress, SectorTagType tag)
|
public override byte[] ReadSectorTag(UInt64 sectorAddress, SectorTagType tag)
|
||||||
{
|
{
|
||||||
throw new FeatureUnsupportedImageException("Feature not supported by image format");
|
throw new FeatureUnsupportedImageException("Feature not supported by image format");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override byte[] ReadSectorsTag(UInt64 sectorAddress, UInt32 length, SectorTagType tag)
|
public override byte[] ReadSectorsTag(UInt64 sectorAddress, UInt32 length, SectorTagType tag)
|
||||||
{
|
{
|
||||||
throw new FeatureUnsupportedImageException("Feature not supported by image format");
|
throw new FeatureUnsupportedImageException("Feature not supported by image format");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override byte[] ReadDiskTag(DiskTagType tag)
|
public override byte[] ReadDiskTag(DiskTagType tag)
|
||||||
{
|
{
|
||||||
throw new FeatureUnsupportedImageException("Feature not supported by image format");
|
throw new FeatureUnsupportedImageException("Feature not supported by image format");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string GetImageCreator()
|
public override string GetImageCreator()
|
||||||
{
|
{
|
||||||
return _imageInfo.imageCreator;
|
return _imageInfo.imageCreator;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string GetImageComments()
|
public override string GetImageComments()
|
||||||
{
|
{
|
||||||
return _imageInfo.imageComments;
|
return _imageInfo.imageComments;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string GetDiskManufacturer()
|
public override string GetDiskManufacturer()
|
||||||
{
|
{
|
||||||
return _imageInfo.diskManufacturer;
|
return _imageInfo.diskManufacturer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string GetDiskModel()
|
public override string GetDiskModel()
|
||||||
{
|
{
|
||||||
return _imageInfo.diskModel;
|
return _imageInfo.diskModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string GetDiskSerialNumber()
|
public override string GetDiskSerialNumber()
|
||||||
{
|
{
|
||||||
return _imageInfo.diskSerialNumber;
|
return _imageInfo.diskSerialNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string GetDiskBarcode()
|
public override string GetDiskBarcode()
|
||||||
{
|
{
|
||||||
return _imageInfo.diskBarcode;
|
return _imageInfo.diskBarcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string GetDiskPartNumber()
|
public override string GetDiskPartNumber()
|
||||||
{
|
{
|
||||||
return _imageInfo.diskPartNumber;
|
return _imageInfo.diskPartNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int GetDiskSequence()
|
public override int GetDiskSequence()
|
||||||
{
|
{
|
||||||
return _imageInfo.diskSequence;
|
return _imageInfo.diskSequence;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int GetLastDiskSequence()
|
public override int GetLastDiskSequence()
|
||||||
{
|
{
|
||||||
return _imageInfo.lastDiskSequence;
|
return _imageInfo.lastDiskSequence;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string GetDriveManufacturer()
|
public override string GetDriveManufacturer()
|
||||||
{
|
{
|
||||||
return _imageInfo.driveManufacturer;
|
return _imageInfo.driveManufacturer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string GetDriveModel()
|
public override string GetDriveModel()
|
||||||
{
|
{
|
||||||
return _imageInfo.driveModel;
|
return _imageInfo.driveModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string GetDriveSerialNumber()
|
public override string GetDriveSerialNumber()
|
||||||
{
|
{
|
||||||
return _imageInfo.driveSerialNumber;
|
return _imageInfo.driveSerialNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override List<PartPlugins.Partition> GetPartitions()
|
public override List<PartPlugins.Partition> GetPartitions()
|
||||||
{
|
{
|
||||||
throw new FeatureUnsupportedImageException("Feature not supported by image format");
|
throw new FeatureUnsupportedImageException("Feature not supported by image format");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override List<Track> GetTracks()
|
public override List<Track> GetTracks()
|
||||||
{
|
{
|
||||||
throw new FeatureUnsupportedImageException("Feature not supported by image format");
|
throw new FeatureUnsupportedImageException("Feature not supported by image format");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override List<Track> GetSessionTracks(Session session)
|
public override List<Track> GetSessionTracks(Session session)
|
||||||
{
|
{
|
||||||
throw new FeatureUnsupportedImageException("Feature not supported by image format");
|
throw new FeatureUnsupportedImageException("Feature not supported by image format");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override List<Track> GetSessionTracks(UInt16 session)
|
public override List<Track> GetSessionTracks(UInt16 session)
|
||||||
{
|
{
|
||||||
throw new FeatureUnsupportedImageException("Feature not supported by image format");
|
throw new FeatureUnsupportedImageException("Feature not supported by image format");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override List<Session> GetSessions()
|
public override List<Session> GetSessions()
|
||||||
{
|
{
|
||||||
throw new FeatureUnsupportedImageException("Feature not supported by image format");
|
throw new FeatureUnsupportedImageException("Feature not supported by image format");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override byte[] ReadSector(UInt64 sectorAddress, UInt32 track)
|
public override byte[] ReadSector(UInt64 sectorAddress, UInt32 track)
|
||||||
{
|
{
|
||||||
throw new FeatureUnsupportedImageException("Feature not supported by image format");
|
throw new FeatureUnsupportedImageException("Feature not supported by image format");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override byte[] ReadSectorTag(UInt64 sectorAddress, UInt32 track, SectorTagType tag)
|
public override byte[] ReadSectorTag(UInt64 sectorAddress, UInt32 track, SectorTagType tag)
|
||||||
{
|
{
|
||||||
throw new FeatureUnsupportedImageException("Feature not supported by image format");
|
throw new FeatureUnsupportedImageException("Feature not supported by image format");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override byte[] ReadSectors(UInt64 sectorAddress, UInt32 length, UInt32 track)
|
public override byte[] ReadSectors(UInt64 sectorAddress, UInt32 length, UInt32 track)
|
||||||
{
|
{
|
||||||
throw new FeatureUnsupportedImageException("Feature not supported by image format");
|
throw new FeatureUnsupportedImageException("Feature not supported by image format");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override byte[] ReadSectorsTag(UInt64 sectorAddress, UInt32 length, UInt32 track, SectorTagType tag)
|
public override byte[] ReadSectorsTag(UInt64 sectorAddress, UInt32 length, UInt32 track, SectorTagType tag)
|
||||||
{
|
{
|
||||||
throw new FeatureUnsupportedImageException("Feature not supported by image format");
|
throw new FeatureUnsupportedImageException("Feature not supported by image format");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override byte[] ReadSectorLong(UInt64 sectorAddress, UInt32 track)
|
public override byte[] ReadSectorLong(UInt64 sectorAddress, UInt32 track)
|
||||||
{
|
{
|
||||||
throw new FeatureUnsupportedImageException("Feature not supported by image format");
|
throw new FeatureUnsupportedImageException("Feature not supported by image format");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override byte[] ReadSectorsLong(UInt64 sectorAddress, UInt32 length, UInt32 track)
|
public override byte[] ReadSectorsLong(UInt64 sectorAddress, UInt32 length, UInt32 track)
|
||||||
{
|
{
|
||||||
throw new FeatureUnsupportedImageException("Feature not supported by image format");
|
throw new FeatureUnsupportedImageException("Feature not supported by image format");
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion Unsupported features
|
#endregion Unsupported features
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,8 +46,10 @@ namespace DiscImageChef.ImagePlugins
|
|||||||
class ZZZRawImage : ImagePlugin
|
class ZZZRawImage : ImagePlugin
|
||||||
{
|
{
|
||||||
#region Internal variables
|
#region Internal variables
|
||||||
|
|
||||||
string rawImagePath;
|
string rawImagePath;
|
||||||
bool differentTrackZeroSize;
|
bool differentTrackZeroSize;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Accesible variables
|
#region Accesible variables
|
||||||
@@ -356,7 +358,45 @@ namespace DiscImageChef.ImagePlugins
|
|||||||
return _imageInfo.diskType;
|
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
|
#region Private methods
|
||||||
|
|
||||||
private DiskType CalculateDiskType()
|
private DiskType CalculateDiskType()
|
||||||
{
|
{
|
||||||
if (_imageInfo.sectorSize == 2048)
|
if (_imageInfo.sectorSize == 2048)
|
||||||
@@ -492,6 +532,7 @@ namespace DiscImageChef.ImagePlugins
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Unsupported features
|
#region Unsupported features
|
||||||
|
|||||||
@@ -41,6 +41,6 @@
|
|||||||
</Package>
|
</Package>
|
||||||
</Packages>
|
</Packages>
|
||||||
</Packages>
|
</Packages>
|
||||||
<ReleaseVersion>2.0</ReleaseVersion>
|
<ReleaseVersion>2.1</ReleaseVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
</Project>
|
</Project>
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
DiscImageChef v2.00
|
DiscImageChef v2.10
|
||||||
===================
|
===================
|
||||||
|
|
||||||
Disc Image Chef (because "swiss-army-knife" is used too much)
|
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.
|
* 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
|
* 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 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)
|
* 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
|
Changelog
|
||||||
=========
|
=========
|
||||||
|
|||||||
3
TODO
3
TODO
@@ -74,9 +74,6 @@ Image comparison:
|
|||||||
--- Offer the option to see differing values
|
--- Offer the option to see differing values
|
||||||
--- Optimize and multithread
|
--- Optimize and multithread
|
||||||
|
|
||||||
Image verification:
|
|
||||||
--- Implement verification on image plugins to implement this verb
|
|
||||||
|
|
||||||
Checksums:
|
Checksums:
|
||||||
--- Implement SpamSum fuzzy hashing (aka ssdeep)
|
--- Implement SpamSum fuzzy hashing (aka ssdeep)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user