22using System . Collections . Generic ;
33using System . IO ;
44using BinaryObjectScanner . Interfaces ;
5+ using SabreTools . Data . Models . ISO9660 ;
56using SabreTools . IO ;
67using SabreTools . IO . Extensions ;
78using SabreTools . IO . Matching ;
@@ -16,7 +17,7 @@ namespace BinaryObjectScanner.Protection
1617 /// Macrovision Corporation CD-ROM Unauthorized Copying Study: https://web.archive.org/web/20011005161810/http://www.macrovision.com/solutions/software/cdrom/images/Games_CD-ROM_Study.PDF
1718 /// List of trademarks associated with Marovision: https://tmsearch.uspto.gov/bin/showfield?f=toc&state=4804%3Au8wykd.5.1&p_search=searchss&p_L=50&BackReference=&p_plural=yes&p_s_PARA1=&p_tagrepl%7E%3A=PARA1%24LD&expr=PARA1+AND+PARA2&p_s_PARA2=macrovision&p_tagrepl%7E%3A=PARA2%24ALL&p_op_ALL=AND&a_default=search&a_search=Submit+Query&a_search=Submit+Query
1819 /// </summary>
19- public partial class Macrovision : IExecutableCheck < NewExecutable > , IExecutableCheck < PortableExecutable > , IPathCheck
20+ public partial class Macrovision : IExecutableCheck < NewExecutable > , IExecutableCheck < PortableExecutable > , IPathCheck , IISOCheck < ISO9660 >
2021 {
2122 /// <inheritdoc/>
2223 public string ? CheckExecutable ( string file , NewExecutable exe , bool includeDebug )
@@ -242,6 +243,48 @@ public List<string> CheckDirectoryPath(string path, List<string>? files)
242243
243244 return null ;
244245 }
246+
247+ public string ? CheckISO ( string file , ISO9660 iso , bool includeDebug )
248+ {
249+ var pvd = ( PrimaryVolumeDescriptor ) iso . VolumeDescriptorSet [ 0 ] ;
250+
251+ if ( ! FileType . ISO9660 . NoteworthyApplicationUse ( pvd ) )
252+ return null ;
253+
254+ // Early SafeDisc actually doesn't cross into reserved bytes. Regardless, SafeDisc CD is easy enough to
255+ // identify for obvious other reasons, so there's not much point in potentially running into false positives.
256+
257+ if ( ! FileType . ISO9660 . NoteworthyReserved653Bytes ( pvd ) )
258+ return null ;
259+
260+ var reserved653Bytes = pvd . Reserved653Bytes ;
261+ var applicationUse = pvd . ApplicationUse ;
262+
263+ int offset = 0 ;
264+ var appUsefirst256Bytes = applicationUse . ReadBytes ( ref offset , 256 ) ;
265+ var appUsemiddle128Bytes = applicationUse . ReadBytes ( ref offset , 128 ) ;
266+ offset += 64 ; // Some extra values get added here over time. Check is good enough, easier to skip this.
267+ var appUseFirstUint = applicationUse . ReadUInt16LittleEndian ( ref offset ) ;
268+ var appUseFollowingFirstUint = applicationUse . ReadBytes ( ref offset , 20 ) ;
269+ var appUseSecondUint = applicationUse . ReadUInt32LittleEndian ( ref offset ) ;
270+
271+ // TODO: once ST is fixed, finish this up. read to the end of the AU, then read however many bytes from the
272+ // TODO: start of the reserved, confirm everything, check if reserved ends with enough 0x00 bytes too.
273+
274+ /*if (Array.TrueForAll(first384Bytes, b => b == 0x00) && FileType.ISO9660.IsPureData(last128Bytes))
275+ return "TAGES";*/
276+
277+ // Early tages has a 4-byte value at the beginning of the AU data and nothing else.
278+ // Redump ID 35932, 21321, 8776,
279+ offset = 0 ;
280+ var initialValue = applicationUse . ReadInt32LittleEndian ( ref offset ) ;
281+ var last508Bytes = applicationUse . ReadBytes ( ref offset , 508 ) ;
282+ if ( Array . TrueForAll ( last508Bytes , b => b == 0x00 ) && initialValue != 0 )
283+ return "TAGES (Early)" ;
284+
285+ // The original releases of Moto Racer 3 (31578, 34669) are so early they have seemingly nothing identifiable.
286+ return null ;
287+ }
245288
246289 /// <inheritdoc cref="IPathCheck.CheckDirectoryPath(string, List{string})"/>
247290 internal static List < string > MacrovisionCheckDirectoryPath ( string path , List < string > ? files )
0 commit comments