mirror of
https://github.com/claunia/SabreTools.git
synced 2025-12-16 19:14:27 +00:00
[CHDFile, Utilities] The great CHD cleanup
This commit is contained in:
@@ -1,7 +1,4 @@
|
|||||||
using System;
|
using SabreTools.Library.Data;
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
using SabreTools.Library.Data;
|
|
||||||
using SabreTools.Library.Tools;
|
using SabreTools.Library.Tools;
|
||||||
|
|
||||||
#if MONO
|
#if MONO
|
||||||
@@ -88,7 +85,7 @@ namespace SabreTools.Library.FileTypes
|
|||||||
/// 0x68-0x7b - Parent SHA-1
|
/// 0x68-0x7b - Parent SHA-1
|
||||||
/// ----------------------------------------------
|
/// ----------------------------------------------
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public class CHDFile : BaseFile, IDisposable
|
public class CHDFile : BaseFile
|
||||||
{
|
{
|
||||||
#region Private instance variables
|
#region Private instance variables
|
||||||
|
|
||||||
@@ -110,12 +107,61 @@ namespace SabreTools.Library.FileTypes
|
|||||||
private uint m_mapentrybytes; // length of each entry in a map
|
private uint m_mapentrybytes; // length of each entry in a map
|
||||||
|
|
||||||
// additional required vars
|
// additional required vars
|
||||||
|
private uint? _headerVersion;
|
||||||
private BinaryReader m_br; // Binary reader representing the CHD stream
|
private BinaryReader m_br; // Binary reader representing the CHD stream
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region Pubically facing variables
|
||||||
|
|
||||||
|
public uint? Version
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_headerVersion == null)
|
||||||
|
{
|
||||||
|
_headerVersion = ValidateHeaderVersion();
|
||||||
|
}
|
||||||
|
|
||||||
|
return _headerVersion;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region Constructors
|
#region Constructors
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create a new, blank CHDFile
|
||||||
|
/// </summary>
|
||||||
|
public CHDFile()
|
||||||
|
{
|
||||||
|
this._fileType = FileType.CHD;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create a new CHDFile from an input file
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="filename"></param>
|
||||||
|
public CHDFile(string filename)
|
||||||
|
: base(filename)
|
||||||
|
{
|
||||||
|
_fileType = FileType.CHD;
|
||||||
|
m_br = new BinaryReader(Utilities.TryOpenRead(filename));
|
||||||
|
|
||||||
|
_headerVersion = ValidateHeaderVersion();
|
||||||
|
|
||||||
|
byte[] hash = GetHashFromHeader();
|
||||||
|
if (hash.Length == Constants.MD5Length)
|
||||||
|
{
|
||||||
|
_md5 = hash;
|
||||||
|
}
|
||||||
|
else if (hash.Length == Constants.SHA1Length)
|
||||||
|
{
|
||||||
|
_sha1 = hash;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create a new CHDFile from an input stream
|
/// Create a new CHDFile from an input stream
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -124,14 +170,18 @@ namespace SabreTools.Library.FileTypes
|
|||||||
{
|
{
|
||||||
_fileType = FileType.CHD;
|
_fileType = FileType.CHD;
|
||||||
m_br = new BinaryReader(chdstream);
|
m_br = new BinaryReader(chdstream);
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
_headerVersion = ValidateHeaderVersion();
|
||||||
/// Dispose of the CHDFile
|
|
||||||
/// </summary>
|
byte[] hash = GetHashFromHeader();
|
||||||
public void Dispose()
|
if (hash.Length == Constants.MD5Length)
|
||||||
{
|
{
|
||||||
m_br.Dispose();
|
_md5 = hash;
|
||||||
|
}
|
||||||
|
else if (hash.Length == Constants.SHA1Length)
|
||||||
|
{
|
||||||
|
_sha1 = hash;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@@ -142,7 +192,9 @@ namespace SabreTools.Library.FileTypes
|
|||||||
/// Validate the initial signature, version, and header size
|
/// Validate the initial signature, version, and header size
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>Unsigned int containing the version number, null if invalid</returns>
|
/// <returns>Unsigned int containing the version number, null if invalid</returns>
|
||||||
public uint? ValidateHeaderVersion()
|
private uint? ValidateHeaderVersion()
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
// Seek to the beginning to make sure we're reading the correct bytes
|
// Seek to the beginning to make sure we're reading the correct bytes
|
||||||
m_br.BaseStream.Seek(0, SeekOrigin.Begin);
|
m_br.BaseStream.Seek(0, SeekOrigin.Begin);
|
||||||
@@ -180,12 +232,17 @@ namespace SabreTools.Library.FileTypes
|
|||||||
|
|
||||||
return m_version;
|
return m_version;
|
||||||
}
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get the internal MD5 (v1, v2) or SHA-1 (v3, v4, v5) from the CHD
|
/// Get the internal MD5 (v1, v2) or SHA-1 (v3, v4, v5) from the CHD
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>MD5 as a byte array, null on error</returns>
|
/// <returns>MD5 as a byte array, null on error</returns>
|
||||||
public byte[] GetHashFromHeader()
|
private byte[] GetHashFromHeader()
|
||||||
{
|
{
|
||||||
// Validate the header by default just in case
|
// Validate the header by default just in case
|
||||||
uint? version = ValidateHeaderVersion();
|
uint? version = ValidateHeaderVersion();
|
||||||
@@ -194,6 +251,8 @@ namespace SabreTools.Library.FileTypes
|
|||||||
byte[] hash;
|
byte[] hash;
|
||||||
|
|
||||||
// Now parse the rest of the header according to the version
|
// Now parse the rest of the header according to the version
|
||||||
|
try
|
||||||
|
{
|
||||||
switch (version)
|
switch (version)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
@@ -216,6 +275,12 @@ namespace SabreTools.Library.FileTypes
|
|||||||
// throw CHDERR_INVALID_FILE;
|
// throw CHDERR_INVALID_FILE;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// throw CHDERR_INVALID_FILE;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1040,9 +1040,9 @@ namespace SabreTools.Library.Tools
|
|||||||
public static BaseFile GetCHDInfo(string input)
|
public static BaseFile GetCHDInfo(string input)
|
||||||
{
|
{
|
||||||
FileStream fs = TryOpenRead(input);
|
FileStream fs = TryOpenRead(input);
|
||||||
BaseFile datItem = GetCHDInfo(fs);
|
BaseFile chd = GetCHDInfo(fs);
|
||||||
fs.Dispose();
|
fs.Dispose();
|
||||||
return datItem;
|
return chd;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -1371,32 +1371,6 @@ namespace SabreTools.Library.Tools
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get if file has a known CHD header
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="input">Filename of possible CHD</param>
|
|
||||||
/// <returns>True if the file has a valid CHD header, false otherwise</returns>
|
|
||||||
public static bool HasCHDHeader(string input)
|
|
||||||
{
|
|
||||||
FileStream fs = TryOpenRead(input);
|
|
||||||
bool output = HasCHDHeader(fs);
|
|
||||||
fs.Dispose();
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get if file is a valid CHD
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="input">Filename of possible CHD</param>
|
|
||||||
/// <returns>True if the file is a valid CHD, false otherwise</returns>
|
|
||||||
public static bool IsValidCHD(string input)
|
|
||||||
{
|
|
||||||
BaseFile baseFile = GetCHDInfo(input);
|
|
||||||
return baseFile != null
|
|
||||||
&& (((CHDFile)baseFile).MD5 != null
|
|
||||||
|| ((CHDFile)baseFile).SHA1 != null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Retrieve a list of files from a directory recursively in proper order
|
/// Retrieve a list of files from a directory recursively in proper order
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -1925,7 +1899,7 @@ namespace SabreTools.Library.Tools
|
|||||||
long offset = 0, bool keepReadOpen = false, bool chdsAsFiles = true)
|
long offset = 0, bool keepReadOpen = false, bool chdsAsFiles = true)
|
||||||
{
|
{
|
||||||
// We first check to see if it's a CHD
|
// We first check to see if it's a CHD
|
||||||
if (chdsAsFiles == false && HasCHDHeader(input))
|
if (chdsAsFiles == false && GetCHDInfo(input) != null)
|
||||||
{
|
{
|
||||||
// Seek to the starting position, if one is set
|
// Seek to the starting position, if one is set
|
||||||
try
|
try
|
||||||
@@ -1952,8 +1926,8 @@ namespace SabreTools.Library.Tools
|
|||||||
Globals.Logger.Warning("Stream does not support seeking. Stream position not changed");
|
Globals.Logger.Warning("Stream does not support seeking. Stream position not changed");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the Disk from the information
|
// Get the BaseFile from the information
|
||||||
BaseFile disk = GetCHDInfo(input);
|
BaseFile chd = GetCHDInfo(input);
|
||||||
|
|
||||||
// Seek to the beginning of the stream if possible
|
// Seek to the beginning of the stream if possible
|
||||||
try
|
try
|
||||||
@@ -1974,7 +1948,7 @@ namespace SabreTools.Library.Tools
|
|||||||
input.Dispose();
|
input.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
return disk;
|
return chd;
|
||||||
}
|
}
|
||||||
|
|
||||||
BaseFile rom = new BaseFile()
|
BaseFile rom = new BaseFile()
|
||||||
@@ -2130,54 +2104,8 @@ namespace SabreTools.Library.Tools
|
|||||||
/// </remarks>
|
/// </remarks>
|
||||||
public static BaseFile GetCHDInfo(Stream input)
|
public static BaseFile GetCHDInfo(Stream input)
|
||||||
{
|
{
|
||||||
// Get a CHD object to store the data
|
|
||||||
CHDFile chd = new CHDFile(input);
|
CHDFile chd = new CHDFile(input);
|
||||||
|
return (chd.Version != null && (chd.MD5 != null || chd.SHA1 != null) ? chd : null);
|
||||||
// Ensure that the header is valid
|
|
||||||
byte[] hash = chd.GetHashFromHeader();
|
|
||||||
|
|
||||||
// Set the proper hash of the Disk to return
|
|
||||||
if (hash.Length == Constants.MD5Length)
|
|
||||||
{
|
|
||||||
chd.MD5 = hash;
|
|
||||||
return chd;
|
|
||||||
}
|
|
||||||
else if (hash.Length == Constants.SHA1Length)
|
|
||||||
{
|
|
||||||
chd.SHA1 = hash;
|
|
||||||
return chd;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get if stream has a known CHD header
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="input">Stream of possible CHD</param>
|
|
||||||
/// <returns>True if the stream has a valid CHD header, false otherwise</returns>
|
|
||||||
public static bool HasCHDHeader(Stream input)
|
|
||||||
{
|
|
||||||
// Get a CHD object to store the data
|
|
||||||
CHDFile chd = new CHDFile(input);
|
|
||||||
|
|
||||||
// Now try to get the header version
|
|
||||||
uint? version = chd.ValidateHeaderVersion();
|
|
||||||
|
|
||||||
return version != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get if stream is a valid CHD
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="input">Stream of possible CHD</param>
|
|
||||||
/// <returns>True if the stream is a valid CHD, false otherwise</returns>
|
|
||||||
public static bool IsValidCHD(Stream input)
|
|
||||||
{
|
|
||||||
BaseFile baseFile = GetCHDInfo(input);
|
|
||||||
return baseFile != null
|
|
||||||
&& (((CHDFile)baseFile).MD5 != null
|
|
||||||
|| ((CHDFile)baseFile).SHA1 != null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
Reference in New Issue
Block a user