Added image checksum support for SuperCardPro.

This commit is contained in:
2017-12-06 01:31:37 +00:00
parent c50b49ddd1
commit af91c7ceab

View File

@@ -173,6 +173,7 @@ namespace DiscImageChef.ImagePlugins
// TODO: These variables have been made public so create-sidecar can access to this information until I define an API >4.0 // TODO: These variables have been made public so create-sidecar can access to this information until I define an API >4.0
public ScpHeader header; public ScpHeader header;
public Dictionary<byte, TrackHeader> tracks; public Dictionary<byte, TrackHeader> tracks;
Stream scpStream;
#endregion Internal variables #endregion Internal variables
public SuperCardPro() public SuperCardPro()
@@ -227,13 +228,13 @@ namespace DiscImageChef.ImagePlugins
public override bool OpenImage(Filter imageFilter) public override bool OpenImage(Filter imageFilter)
{ {
header = new ScpHeader(); header = new ScpHeader();
Stream stream = imageFilter.GetDataForkStream(); scpStream = imageFilter.GetDataForkStream();
stream.Seek(0, SeekOrigin.Begin); scpStream.Seek(0, SeekOrigin.Begin);
if(stream.Length < Marshal.SizeOf(header)) if(scpStream.Length < Marshal.SizeOf(header))
return false; return false;
byte[] hdr = new byte[Marshal.SizeOf(header)]; byte[] hdr = new byte[Marshal.SizeOf(header)];
stream.Read(hdr, 0, Marshal.SizeOf(header)); scpStream.Read(hdr, 0, Marshal.SizeOf(header));
IntPtr hdrPtr = Marshal.AllocHGlobal(Marshal.SizeOf(header)); IntPtr hdrPtr = Marshal.AllocHGlobal(Marshal.SizeOf(header));
Marshal.Copy(hdr, 0, hdrPtr, Marshal.SizeOf(header)); Marshal.Copy(hdr, 0, hdrPtr, Marshal.SizeOf(header));
@@ -262,12 +263,12 @@ namespace DiscImageChef.ImagePlugins
if(t >= header.offsets.Length) if(t >= header.offsets.Length)
break; break;
stream.Position = header.offsets[t]; scpStream.Position = header.offsets[t];
TrackHeader trk = new TrackHeader(); TrackHeader trk = new TrackHeader();
trk.signature = new byte[3]; trk.signature = new byte[3];
trk.entries = new TrackEntry[header.revolutions]; trk.entries = new TrackEntry[header.revolutions];
stream.Read(trk.signature, 0, trk.signature.Length); scpStream.Read(trk.signature, 0, trk.signature.Length);
trk.trackNumber = (byte)stream.ReadByte(); trk.trackNumber = (byte)scpStream.ReadByte();
if(!trk.signature.SequenceEqual(TrkSignature)) if(!trk.signature.SequenceEqual(TrkSignature))
{ {
@@ -286,7 +287,7 @@ namespace DiscImageChef.ImagePlugins
for(byte r = 0; r < header.revolutions; r++) for(byte r = 0; r < header.revolutions; r++)
{ {
byte[] rev = new byte[Marshal.SizeOf(typeof(TrackEntry))]; byte[] rev = new byte[Marshal.SizeOf(typeof(TrackEntry))];
stream.Read(rev, 0, Marshal.SizeOf(typeof(TrackEntry))); scpStream.Read(rev, 0, Marshal.SizeOf(typeof(TrackEntry)));
IntPtr revPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(TrackEntry))); IntPtr revPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(TrackEntry)));
Marshal.Copy(rev, 0, revPtr, Marshal.SizeOf(typeof(TrackEntry))); Marshal.Copy(rev, 0, revPtr, Marshal.SizeOf(typeof(TrackEntry)));
@@ -301,23 +302,23 @@ namespace DiscImageChef.ImagePlugins
if(header.flags.HasFlag(ScpFlags.HasFooter)) if(header.flags.HasFlag(ScpFlags.HasFooter))
{ {
long position = stream.Position; long position = scpStream.Position;
stream.Seek(-4, SeekOrigin.End); scpStream.Seek(-4, SeekOrigin.End);
while(stream.Position >= position) while(scpStream.Position >= position)
{ {
byte[] footerSig = new byte[4]; byte[] footerSig = new byte[4];
stream.Read(footerSig, 0, 4); scpStream.Read(footerSig, 0, 4);
uint footerMagic = BitConverter.ToUInt32(footerSig, 0); uint footerMagic = BitConverter.ToUInt32(footerSig, 0);
if(footerMagic == FooterSignature) if(footerMagic == FooterSignature)
{ {
stream.Seek(-Marshal.SizeOf(typeof(ScpFooter)), SeekOrigin.Current); scpStream.Seek(-Marshal.SizeOf(typeof(ScpFooter)), SeekOrigin.Current);
DicConsole.DebugWriteLine("SuperCardPro plugin", "Found footer at {0}", stream.Position); DicConsole.DebugWriteLine("SuperCardPro plugin", "Found footer at {0}", scpStream.Position);
byte[] ftr = new byte[Marshal.SizeOf(typeof(ScpFooter))]; byte[] ftr = new byte[Marshal.SizeOf(typeof(ScpFooter))];
stream.Read(ftr, 0, Marshal.SizeOf(typeof(ScpFooter))); scpStream.Read(ftr, 0, Marshal.SizeOf(typeof(ScpFooter)));
IntPtr ftrPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(ScpFooter))); IntPtr ftrPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(ScpFooter)));
Marshal.Copy(ftr, 0, ftrPtr, Marshal.SizeOf(typeof(ScpFooter))); Marshal.Copy(ftr, 0, ftrPtr, Marshal.SizeOf(typeof(ScpFooter)));
@@ -338,12 +339,12 @@ namespace DiscImageChef.ImagePlugins
DicConsole.DebugWriteLine("SuperCardPro plugin", "footer.imageVersion = {0}.{1}", (footer.imageVersion & 0xF0) >> 4, footer.imageVersion & 0xF); DicConsole.DebugWriteLine("SuperCardPro plugin", "footer.imageVersion = {0}.{1}", (footer.imageVersion & 0xF0) >> 4, footer.imageVersion & 0xF);
DicConsole.DebugWriteLine("SuperCardPro plugin", "footer.signature = \"{0}\"", StringHandlers.CToString(BitConverter.GetBytes(footer.signature))); DicConsole.DebugWriteLine("SuperCardPro plugin", "footer.signature = \"{0}\"", StringHandlers.CToString(BitConverter.GetBytes(footer.signature)));
ImageInfo.driveManufacturer = ReadPStringUTF8(stream, footer.manufacturerOffset); ImageInfo.driveManufacturer = ReadPStringUTF8(scpStream, footer.manufacturerOffset);
ImageInfo.driveModel = ReadPStringUTF8(stream, footer.modelOffset); ImageInfo.driveModel = ReadPStringUTF8(scpStream, footer.modelOffset);
ImageInfo.driveSerialNumber = ReadPStringUTF8(stream, footer.serialOffset); ImageInfo.driveSerialNumber = ReadPStringUTF8(scpStream, footer.serialOffset);
ImageInfo.imageCreator = ReadPStringUTF8(stream, footer.creatorOffset); ImageInfo.imageCreator = ReadPStringUTF8(scpStream, footer.creatorOffset);
ImageInfo.imageApplication = ReadPStringUTF8(stream, footer.applicationOffset); ImageInfo.imageApplication = ReadPStringUTF8(scpStream, footer.applicationOffset);
ImageInfo.imageComments = ReadPStringUTF8(stream, footer.commentsOffset); ImageInfo.imageComments = ReadPStringUTF8(scpStream, footer.commentsOffset);
DicConsole.DebugWriteLine("SuperCardPro plugin", "ImageInfo.driveManufacturer = \"{0}\"", ImageInfo.driveManufacturer); DicConsole.DebugWriteLine("SuperCardPro plugin", "ImageInfo.driveManufacturer = \"{0}\"", ImageInfo.driveManufacturer);
DicConsole.DebugWriteLine("SuperCardPro plugin", "ImageInfo.driveModel = \"{0}\"", ImageInfo.driveModel); DicConsole.DebugWriteLine("SuperCardPro plugin", "ImageInfo.driveModel = \"{0}\"", ImageInfo.driveModel);
@@ -375,7 +376,7 @@ namespace DiscImageChef.ImagePlugins
break; break;
} }
stream.Seek(-8, SeekOrigin.Current); scpStream.Seek(-8, SeekOrigin.Current);
} }
} }
else else
@@ -583,7 +584,19 @@ namespace DiscImageChef.ImagePlugins
public override bool? VerifyMediaImage() public override bool? VerifyMediaImage()
{ {
throw new NotImplementedException(); if(header.flags.HasFlag(ScpFlags.Writable))
return null;
byte[] wholeFile = new byte[scpStream.Length];
uint sum = 0;
scpStream.Position = 0;
scpStream.Read(wholeFile, 0, wholeFile.Length);
for(int i = 0x10; i < wholeFile.Length; i++)
sum += wholeFile[i];
return header.checksum == sum;
} }
#endregion Public methods #endregion Public methods