diff --git a/BinaryObjectScanner/FileType/ISO9660.cs b/BinaryObjectScanner/FileType/ISO9660.cs index 9e16bbf9..244ac1c5 100644 --- a/BinaryObjectScanner/FileType/ISO9660.cs +++ b/BinaryObjectScanner/FileType/ISO9660.cs @@ -107,6 +107,12 @@ public static bool NoteworthyApplicationUse(PrimaryVolumeDescriptor pvd) // character. If these are found to be causing issues they can be added. } + // Seems to come from "FERGUS_MCNEILL - ISOCD 1.00 by Pantaray, Inc. USA -" + offset = 1; + potentialAppUseString = applicationUse.ReadNullTerminatedAnsiString(ref offset); + if (potentialAppUseString == "FS") + return false; + offset = 141; potentialAppUseString = applicationUse.ReadNullTerminatedAnsiString(ref offset); if (potentialAppUseString == "CD-XA001") diff --git a/BinaryObjectScanner/Protection/AlphaROM.cs b/BinaryObjectScanner/Protection/AlphaROM.cs index 43c44047..fd7161af 100644 --- a/BinaryObjectScanner/Protection/AlphaROM.cs +++ b/BinaryObjectScanner/Protection/AlphaROM.cs @@ -1,4 +1,5 @@ using System; +using System.Text; using System.Text.RegularExpressions; using BinaryObjectScanner.Interfaces; using SabreTools.Data.Models.ISO9660; @@ -56,8 +57,8 @@ public class AlphaROM : IDiskImageCheck, IExecutableCheck, IExecutableCheck b == 0x20); - if (firstSpace <= 10 || firstSpace >= 120) - return null; - - var publisherData = new byte[firstSpace]; - var publisherSpaces = new byte[publisherData.Length - firstSpace]; - Array.Copy(publisherIdentifier, 0, publisherData, 0, firstSpace); - Array.Copy(publisherIdentifier, firstSpace, publisherSpaces, 0, publisherData.Length - firstSpace); - - if (!Array.TrueForAll(publisherSpaces, b => b == 0x20)) - return null; - - if (!FileType.ISO9660.IsPureData(publisherData)) - return null; + // While some alpharom discs have data in the publisher identifier that can be checked, not all of them do, + // so that can't reliably be used. There are two formats currently observed regarding the application + // identifier strings. + // #1 examples: DCOBG11C1B094961XN, DCXA9083CA554846GP, RCXA1107UD2510461A + // #2 examples: 2003120514103077LAHD, 20040326195254AVKC, 20051019163346WXUDCD + + var applicationIdentifierStringBytes = Encoding.ASCII.GetBytes(applicationIdentifierString); + + // Type #1: 18 characters long, mix of letters and numbers. Since the string has already been confirmed + // to only consist of capital letters and numbers, a basic byte value check can be performed to ensure + // at least 5 bytes are numbers and 5 bytes are letters. Unfortunately, there doesn't seem to be quite + // enough of a pattern to have a better check than this, but it works well enough. + if (applicationIdentifierString.Length == 18 + && Array.FindAll(applicationIdentifierStringBytes, b => b < 60).Length >= 5 + && Array.FindAll(applicationIdentifierStringBytes, b => b > 60).Length >= 5) + { + return "AlphaROM"; + } + + // Type #2: Usually 20 characters long, but Redump ID 124334 is 18 characters long. Validate that it + // starts with YYYYMMDD, followed by 6-8 more numbers, followed by letters. + if (applicationIdentifierString.Length >= 18 && applicationIdentifierString.Length <= 20) + { + if (Int32.TryParse(applicationIdentifierString.Substring(0, 4), out int year) == false + || Int32.TryParse(applicationIdentifierString.Substring(4, 2), out int month) == false + || Int32.TryParse(applicationIdentifierString.Substring(6, 2), out int day) == false + || Int32.TryParse(applicationIdentifierString.Substring(8, 6), out int extraTime) == false) + { + return null; + } + + if (year >= 2009 || year < 2000 || month > 12 || day > 31) + return null; + + int index = Array.FindIndex(applicationIdentifierStringBytes, b => b > 60); + + var startingNumbers = Encoding.ASCII.GetBytes(applicationIdentifierString.Substring(0, index)); + var finalCharacters = Encoding.ASCII.GetBytes(applicationIdentifierString.Substring(index)); + if (Array.TrueForAll(startingNumbers, b => b < 60) && Array.TrueForAll(finalCharacters, b => b > 60)) + return "AlphaROM"; + } - return "AlphaROM"; + return null; } /// diff --git a/BinaryObjectScanner/Protection/Tages.cs b/BinaryObjectScanner/Protection/Tages.cs index b6d1081e..dbb86998 100644 --- a/BinaryObjectScanner/Protection/Tages.cs +++ b/BinaryObjectScanner/Protection/Tages.cs @@ -43,9 +43,12 @@ public class TAGES : IDiskImageCheck, IExecutableCheck b == 0x00) && earlyTagesBytes != 0) + + // Check on earlyTagesBytes needed because Redump ID 56899 begins with "FUN" and is then all 0x00. + // 0x70 value is probably just by chance of where early TAGES checks, but it seems to be consistent. + if (Array.TrueForAll(zeroBytes, b => b == 0x00) && (earlyTagesBytes & 0x70000000) == 0x70000000) return "TAGES (Early)"; // The original releases of Moto Racer 3 (31578, 34669) are so early they have seemingly nothing identifiable.