Implement IRD file reading
This commit is contained in:
+34
-8
@@ -1,5 +1,7 @@
|
||||
using LibIRD;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.IO.Enumeration;
|
||||
using System.Text;
|
||||
|
||||
namespace BuildIRD
|
||||
@@ -12,15 +14,39 @@ namespace BuildIRD
|
||||
|
||||
// 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 };
|
||||
IRD ird1 = new ReIRD("./game.iso", discKey);
|
||||
ird1.Write("./test1.ird");
|
||||
Console.WriteLine("IRD for " + ird1.Title + " created");
|
||||
string fileName = "./game.iso";
|
||||
try
|
||||
{
|
||||
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
|
||||
string logPath = "./log.getkey.log";
|
||||
IRD ird2 = new ReIRD("./game.iso", logPath);
|
||||
ird2.Write("./test2.ird");
|
||||
Console.WriteLine("IRD for " + ird2.Title + " created");
|
||||
// Create new reproducible redump-style IRD with a GetKey log
|
||||
string logPath = "./log.getkey.log";
|
||||
try
|
||||
{
|
||||
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,
|
||||
ulong[] fileKeys,
|
||||
byte[][] fileHashes,
|
||||
uint uid,
|
||||
ushort extraConfig,
|
||||
ushort attachments,
|
||||
byte[] d1,
|
||||
byte[] d2,
|
||||
byte[] pic)
|
||||
byte[] pic,
|
||||
uint uid)
|
||||
: base(
|
||||
titleID,
|
||||
title,
|
||||
@@ -171,12 +171,12 @@ namespace LibIRD
|
||||
fileHashes)
|
||||
{
|
||||
Version = version;
|
||||
UID = uid;
|
||||
ExtraConfig = extraConfig;
|
||||
Attachments = attachments;
|
||||
Data1Key = d1;
|
||||
Data2Key = d2;
|
||||
PIC = pic;
|
||||
UID = uid;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -357,59 +357,6 @@ namespace LibIRD
|
||||
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>
|
||||
/// Write IRD data to file
|
||||
/// </summary>
|
||||
@@ -527,6 +474,119 @@ namespace LibIRD
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,7 +155,9 @@ namespace LibIRD
|
||||
Header = header;
|
||||
FooterLength = (uint)footer.Length;
|
||||
Footer = footer;
|
||||
RegionCount = (byte) regionHashes.Length;
|
||||
RegionHashes = regionHashes;
|
||||
FileCount = (uint)fileKeys.Length;
|
||||
FileKeys = fileKeys;
|
||||
FileHashes = fileHashes;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user