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