From d7af44a858fd24f098c8697b165dbcfd1db9388d Mon Sep 17 00:00:00 2001
From: Deterous <138427222+Deterous@users.noreply.github.com>
Date: Sun, 29 Oct 2023 11:36:41 +1300
Subject: [PATCH] Calculate Size and CRC32
---
BuildIRD/BuildIRD.cs | 4 +--
LibIRD/ReIRD.cs | 86 ++++++++++++++++++++++++++++----------------
2 files changed, 56 insertions(+), 34 deletions(-)
diff --git a/BuildIRD/BuildIRD.cs b/BuildIRD/BuildIRD.cs
index 839dc5f..ccb4d6d 100644
--- a/BuildIRD/BuildIRD.cs
+++ b/BuildIRD/BuildIRD.cs
@@ -8,9 +8,7 @@ namespace BuildIRD
static void Main()
{
byte[] discKey = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
- byte[] discID = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
- byte[] discPIC = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
- IRD ird = new IRD("Z:", discKey, discID, discPIC);
+ IRD ird = new ReIRD("./game.iso", discKey);
ird.Write("./test.ird");
Console.WriteLine(ird.HeaderLength);
}
diff --git a/LibIRD/ReIRD.cs b/LibIRD/ReIRD.cs
index 9a18621..334f834 100644
--- a/LibIRD/ReIRD.cs
+++ b/LibIRD/ReIRD.cs
@@ -1,4 +1,6 @@
using System;
+using System.IO;
+using System.IO.Hashing;
namespace LibIRD
{
@@ -91,7 +93,7 @@ namespace LibIRD
if (size == 0 || (size % 2048) != 0)
throw new ArgumentException("ISO Size in bytes must be a positive integer multiple of 2048", nameof(size));
// Validate layerbreak
- if (layerbreak == 0 || layerbreak >= size)
+ if (layerbreak == 0 || (layerbreak != BDLayerSize && layerbreak >= size))
throw new ArgumentException("Layerbreak in bytes must be a positive integer less than the ISO Size", nameof(size));
// TODO: Generate correct PICs for Hybrid PS3 discs (BD-50 with layerbreak value other than 12219392)
@@ -159,20 +161,30 @@ namespace LibIRD
}
///
- /// Generates the UID field
+ /// Generates the UID field by computing the CRC32 hash of the ISO
///
- /// Redump ISO CRC32 hash
+ /// Full path to the ISO
///
///
- private void GenerateUID(byte[] crc32)
+ private void GenerateUID(string isoPath)
{
+ // Compute CRC32 hash
+ byte[] crc32;
+ using (FileStream fs = File.OpenRead(isoPath))
+ {
+ Crc32 hasher = new Crc32();
+ hasher.Append(fs);
+ crc32 = hasher.GetCurrentHash();
+ Array.Reverse(crc32);
+ }
+
// Validate CRC32
if (crc32 == null)
throw new ArgumentNullException(nameof(crc32));
- if (crc32.Length != 8)
- throw new ArgumentException("CRC32 hash must be an byte array of length 8", nameof(crc32));
+ if (crc32.Length != 4)
+ throw new ArgumentException("CRC32 hash must be an byte array of length 4", nameof(crc32));
- // Redump ISO CRC32 hash is used as the Unique ID in the IRD
+ // Redump ISO CRC32 hash is used as the Unique ID in the reproducible IRD
UID = BitConverter.ToUInt32(crc32, 0);
}
@@ -183,13 +195,26 @@ namespace LibIRD
///
/// Constructor with required redump-style IRD fields
///
- /// ISO Size in bytes, a multiple of 2048
- /// CRC32 hash of the redump ISO
+ /// Full path to the ISO
/// Disc Key, redump-style (AES encrypted Data 1)
- public ReIRD(long size, byte[] crc32, byte[] key)
+ ///
+ ///
+ public ReIRD(string isoPath, byte[] key)
{
+ // Validate ISO path
+ if (isoPath == null || isoPath.Length <= 0)
+ throw new ArgumentNullException(nameof(isoPath));
+
+ // Check file exists
+ var iso = new FileInfo(isoPath);
+ if (!iso.Exists)
+ throw new FileNotFoundException(isoPath);
+
+ // Calculate size of ISO
+ long size = iso.Length;
+
// Generate Unique Identifier using ISO CRC32
- GenerateUID(crc32);
+ GenerateUID(isoPath);
// Generate Data 1 using Disc Key
GenerateD1(key);
@@ -199,19 +224,33 @@ namespace LibIRD
// Generate Disc PIC
GeneratePIC(size);
+
+ // Generate the IRD hashes
+ Generate(isoPath);
}
///
/// Constructor with additional region to generate a specific Disc ID
///
- /// ISO Size in bytes, a multiple of 2048
- /// CRC32 hash of the redump ISO
+ /// Full path to the ISO
/// Disc Key, redump-style (AES encrypted Data 1)
/// Disc Region
- public ReIRD(long size, byte[] crc32, byte[] key, Region region)
+ public ReIRD(string isoPath, byte[] key, Region region)
{
+ // Check path exists
+ if (isoPath == null || isoPath.Length <= 0)
+ throw new ArgumentNullException(nameof(isoPath));
+
+ // Check file exists
+ var iso = new FileInfo(isoPath);
+ if (!iso.Exists)
+ throw new FileNotFoundException(isoPath);
+
+ // Calculate size of ISO
+ long size = iso.Length;
+
// Generate Unique Identifier using ISO CRC32
- GenerateUID(crc32);
+ GenerateUID(isoPath);
// Generate Data 1 using Disc Key
GenerateD1(key);
@@ -221,24 +260,9 @@ namespace LibIRD
// Generate Disc PIC
GeneratePIC(size);
- }
- #endregion
-
- #region Methods
-
- ///
- /// Generate and write the redump-style IRD file, after any optional IRD fields have been set
- ///
- /// Full path to the disc drive / mounted ISO
- /// Full path to IRD file to be written to
- public void Create(string discPath, string irdPath)
- {
// Generate the IRD hashes
- Generate(discPath);
-
- // Write to IRD file
- Write(irdPath);
+ Generate(isoPath);
}
#endregion