Implement IRD file reading
This commit is contained in:
+34
-8
@@ -1,5 +1,7 @@
|
|||||||
using LibIRD;
|
using LibIRD;
|
||||||
using System;
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.IO.Enumeration;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace BuildIRD
|
namespace BuildIRD
|
||||||
@@ -12,15 +14,39 @@ namespace BuildIRD
|
|||||||
|
|
||||||
// Create new reproducible redump-style IRD with a key
|
// Create new reproducible redump-style IRD with a key
|
||||||
byte[] discKey = new byte[] { 0x1A, 0x2D, 0x88, 0xFC, 0x19, 0x37, 0x27, 0x44, 0x11, 0x5E, 0xE9, 0x83, 0xA0, 0x47, 0xE2, 0xD5 };
|
byte[] discKey = new byte[] { 0x1A, 0x2D, 0x88, 0xFC, 0x19, 0x37, 0x27, 0x44, 0x11, 0x5E, 0xE9, 0x83, 0xA0, 0x47, 0xE2, 0xD5 };
|
||||||
IRD ird1 = new ReIRD("./game.iso", discKey);
|
string fileName = "./game.iso";
|
||||||
ird1.Write("./test1.ird");
|
try
|
||||||
Console.WriteLine("IRD for " + ird1.Title + " created");
|
{
|
||||||
|
IRD ird1 = new ReIRD(fileName, discKey);
|
||||||
|
ird1.Write("./test1.ird");
|
||||||
|
Console.WriteLine("IRD for " + fileName + " created");
|
||||||
|
|
||||||
// Create new reproducible redump-style IRD with a GetKey log
|
// Create new reproducible redump-style IRD with a GetKey log
|
||||||
string logPath = "./log.getkey.log";
|
string logPath = "./log.getkey.log";
|
||||||
IRD ird2 = new ReIRD("./game.iso", logPath);
|
try
|
||||||
ird2.Write("./test2.ird");
|
{
|
||||||
Console.WriteLine("IRD for " + ird2.Title + " created");
|
IRD ird2 = new ReIRD(fileName, logPath);
|
||||||
|
ird2.Write("./test2.ird");
|
||||||
|
Console.WriteLine("IRD for " + fileName + " created");
|
||||||
|
}
|
||||||
|
catch (FileNotFoundException)
|
||||||
|
{
|
||||||
|
Console.WriteLine("File not found: " + logPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read IRD and print details to console
|
||||||
|
IRD ird = IRD.Read("./test1.ird");
|
||||||
|
Console.WriteLine("IRD Version: " + ird.Version);
|
||||||
|
Console.WriteLine("Title ID: " + ird.TitleID);
|
||||||
|
Console.WriteLine("Title: " + ird.Title);
|
||||||
|
Console.WriteLine("System Version: " + ird.SystemVersion);
|
||||||
|
Console.WriteLine("Game Version: " + ird.GameVersion);
|
||||||
|
Console.WriteLine("App Version: " + ird.AppVersion);
|
||||||
|
}
|
||||||
|
catch (FileNotFoundException)
|
||||||
|
{
|
||||||
|
Console.WriteLine("File not found: " + fileName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+116
-56
@@ -152,12 +152,12 @@ namespace LibIRD
|
|||||||
byte[][] regionHashes,
|
byte[][] regionHashes,
|
||||||
ulong[] fileKeys,
|
ulong[] fileKeys,
|
||||||
byte[][] fileHashes,
|
byte[][] fileHashes,
|
||||||
uint uid,
|
|
||||||
ushort extraConfig,
|
ushort extraConfig,
|
||||||
ushort attachments,
|
ushort attachments,
|
||||||
byte[] d1,
|
byte[] d1,
|
||||||
byte[] d2,
|
byte[] d2,
|
||||||
byte[] pic)
|
byte[] pic,
|
||||||
|
uint uid)
|
||||||
: base(
|
: base(
|
||||||
titleID,
|
titleID,
|
||||||
title,
|
title,
|
||||||
@@ -171,12 +171,12 @@ namespace LibIRD
|
|||||||
fileHashes)
|
fileHashes)
|
||||||
{
|
{
|
||||||
Version = version;
|
Version = version;
|
||||||
UID = uid;
|
|
||||||
ExtraConfig = extraConfig;
|
ExtraConfig = extraConfig;
|
||||||
Attachments = attachments;
|
Attachments = attachments;
|
||||||
Data1Key = d1;
|
Data1Key = d1;
|
||||||
Data2Key = d2;
|
Data2Key = d2;
|
||||||
PIC = pic;
|
PIC = pic;
|
||||||
|
UID = uid;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -357,59 +357,6 @@ namespace LibIRD
|
|||||||
Data2Key = stream.ToArray();
|
Data2Key = stream.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Read and store IRD data from an existing file
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="irdPath">Path to the IRD file</param>
|
|
||||||
/// <exception cref="ArgumentNullException"></exception>
|
|
||||||
/// <exception cref="FileNotFoundException"></exception>
|
|
||||||
public static IRD Read(string irdPath)
|
|
||||||
{
|
|
||||||
// Validate irdPath
|
|
||||||
if (irdPath == null || irdPath.Length <= 0)
|
|
||||||
throw new ArgumentNullException(nameof(irdPath));
|
|
||||||
if (!File.Exists(irdPath))
|
|
||||||
throw new FileNotFoundException(nameof(irdPath));
|
|
||||||
|
|
||||||
byte version = 1;
|
|
||||||
string titleID = "BCES01234";
|
|
||||||
string title = "R";
|
|
||||||
string sysVersion = "0.00";
|
|
||||||
string gameVersion = "00.00";
|
|
||||||
string appVersion = "00.00";
|
|
||||||
byte[] header = new byte[1];
|
|
||||||
byte[] footer = new byte[1];
|
|
||||||
byte[][] regionHashes = new byte[1][];
|
|
||||||
regionHashes[0] = new byte[1];
|
|
||||||
ulong[] fileKeys = new ulong[1];
|
|
||||||
byte[][] fileHashes = new byte[1][];
|
|
||||||
fileHashes[0] = new byte[1];
|
|
||||||
uint uid = 1;
|
|
||||||
ushort extraConfig = 1;
|
|
||||||
ushort attachments = 1;
|
|
||||||
byte[] d1 = new byte[16];
|
|
||||||
byte[] d2 = new byte[16];
|
|
||||||
byte[] pic = new byte[115];
|
|
||||||
|
|
||||||
return new IRD(version,
|
|
||||||
titleID,
|
|
||||||
title,
|
|
||||||
sysVersion,
|
|
||||||
gameVersion,
|
|
||||||
appVersion,
|
|
||||||
header,
|
|
||||||
footer,
|
|
||||||
regionHashes,
|
|
||||||
fileKeys,
|
|
||||||
fileHashes,
|
|
||||||
uid,
|
|
||||||
extraConfig,
|
|
||||||
attachments,
|
|
||||||
d1,
|
|
||||||
d2,
|
|
||||||
pic);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Write IRD data to file
|
/// Write IRD data to file
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -527,6 +474,119 @@ namespace LibIRD
|
|||||||
stream.CopyTo(gzStream);
|
stream.CopyTo(gzStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Read and store IRD data from an existing file
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="irdPath">Path to the IRD file</param>
|
||||||
|
/// <exception cref="ArgumentNullException"></exception>
|
||||||
|
/// <exception cref="FileNotFoundException"></exception>
|
||||||
|
public static IRD Read(string irdPath)
|
||||||
|
{
|
||||||
|
// Validate irdPath
|
||||||
|
if (irdPath == null || irdPath.Length <= 0)
|
||||||
|
throw new ArgumentNullException(nameof(irdPath));
|
||||||
|
if (!File.Exists(irdPath))
|
||||||
|
throw new FileNotFoundException(nameof(irdPath));
|
||||||
|
|
||||||
|
// Open IRD for reading
|
||||||
|
using FileStream fs = new(irdPath, FileMode.Open, FileAccess.Read);
|
||||||
|
using GZipStream gzs = new(fs, CompressionMode.Decompress);
|
||||||
|
using BinaryReader br = new(gzs);
|
||||||
|
|
||||||
|
// Check for IRD file signature
|
||||||
|
byte[] magic = br.ReadBytes(4);
|
||||||
|
if (!((ReadOnlySpan<byte>)Magic).SequenceEqual(magic))
|
||||||
|
throw new InvalidDataException("IRD file not recognised");
|
||||||
|
|
||||||
|
// Read file version
|
||||||
|
byte version = br.ReadByte();
|
||||||
|
if (version < 6 || version > 9)
|
||||||
|
throw new InvalidDataException("Unsupported IRD version detected");
|
||||||
|
|
||||||
|
// Read Title ID and Title
|
||||||
|
string titleID = Encoding.ASCII.GetString(br.ReadBytes(9));
|
||||||
|
string title = br.ReadString();
|
||||||
|
|
||||||
|
// Read System, Game, and App Version
|
||||||
|
string sysVersion = Encoding.ASCII.GetString(br.ReadBytes(4));
|
||||||
|
string gameVersion = Encoding.ASCII.GetString(br.ReadBytes(5));
|
||||||
|
string appVersion = Encoding.ASCII.GetString(br.ReadBytes(5));
|
||||||
|
|
||||||
|
// Read UID (for Version 7)
|
||||||
|
uint uid = 0;
|
||||||
|
if (version == 7)
|
||||||
|
uid = br.ReadUInt32();
|
||||||
|
|
||||||
|
// Read Header
|
||||||
|
uint headerLength = br.ReadUInt32();
|
||||||
|
byte[] header = new byte[headerLength];
|
||||||
|
br.Read(header, 0, header.Length);
|
||||||
|
|
||||||
|
// Read Footer
|
||||||
|
uint footerLength = br.ReadUInt32();
|
||||||
|
byte[] footer = new byte[footerLength];
|
||||||
|
br.Read(footer, 0, footer.Length);
|
||||||
|
|
||||||
|
// Read region hashes
|
||||||
|
byte regionCount = br.ReadByte();
|
||||||
|
byte[][] regionHashes = new byte[regionCount][];
|
||||||
|
for (int i = 0; i < regionCount; i++)
|
||||||
|
regionHashes[i] = br.ReadBytes(16);
|
||||||
|
|
||||||
|
// Read file hashes
|
||||||
|
uint fileCount = br.ReadUInt32();
|
||||||
|
ulong[] fileKeys = new ulong[fileCount];
|
||||||
|
byte[][] fileHashes = new byte[fileCount][];
|
||||||
|
for (int i = 0; i < fileCount; i++)
|
||||||
|
{
|
||||||
|
fileKeys[i] = br.ReadUInt64();
|
||||||
|
fileHashes[i] = br.ReadBytes(16);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read extra config and number of attachments
|
||||||
|
ushort extraConfig = br.ReadUInt16();
|
||||||
|
ushort attachments = br.ReadUInt16();
|
||||||
|
|
||||||
|
// Read PIC data (for Version 8 and prior)
|
||||||
|
byte[] pic = new byte[115];
|
||||||
|
if (version >= 9)
|
||||||
|
pic = br.ReadBytes(115);
|
||||||
|
|
||||||
|
// Read Data 1 Key, Data 2 Key
|
||||||
|
byte[] d1 = br.ReadBytes(16);
|
||||||
|
byte[] d2 = br.ReadBytes(16);
|
||||||
|
|
||||||
|
// Read PIC data (for Version 8 and prior)
|
||||||
|
if (version < 9)
|
||||||
|
pic = br.ReadBytes(115);
|
||||||
|
|
||||||
|
// Read UID (for Version 8 onwards)
|
||||||
|
if (version > 7)
|
||||||
|
uid = br.ReadUInt16();
|
||||||
|
|
||||||
|
// Read and CRC32 hash
|
||||||
|
byte[] crc = br.ReadBytes(4);
|
||||||
|
|
||||||
|
// Create new IRD object with read parameters
|
||||||
|
return new IRD(version,
|
||||||
|
titleID,
|
||||||
|
title,
|
||||||
|
sysVersion,
|
||||||
|
gameVersion,
|
||||||
|
appVersion,
|
||||||
|
header,
|
||||||
|
footer,
|
||||||
|
regionHashes,
|
||||||
|
fileKeys,
|
||||||
|
fileHashes,
|
||||||
|
extraConfig,
|
||||||
|
attachments,
|
||||||
|
d1,
|
||||||
|
d2,
|
||||||
|
pic,
|
||||||
|
uid);
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -155,7 +155,9 @@ namespace LibIRD
|
|||||||
Header = header;
|
Header = header;
|
||||||
FooterLength = (uint)footer.Length;
|
FooterLength = (uint)footer.Length;
|
||||||
Footer = footer;
|
Footer = footer;
|
||||||
|
RegionCount = (byte) regionHashes.Length;
|
||||||
RegionHashes = regionHashes;
|
RegionHashes = regionHashes;
|
||||||
|
FileCount = (uint)fileKeys.Length;
|
||||||
FileKeys = fileKeys;
|
FileKeys = fileKeys;
|
||||||
FileHashes = fileHashes;
|
FileHashes = fileHashes;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user