diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index c6dfdf7f..1eca5c30 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -1,48 +1,48 @@ name: Build and Test on: - push: - branches: [ "master" ] + push: + branches: ["master"] jobs: - build: - runs-on: ubuntu-latest + build: + runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Setup .NET - uses: actions/setup-dotnet@v4 - with: - dotnet-version: | - 6.0.x - 8.0.x - 9.0.x - - - name: Run tests - run: dotnet test - - - name: Run publish script - run: ./publish-nix.sh -d + steps: + - uses: actions/checkout@v5 + with: + fetch-depth: 0 - - name: Update rolling tag - run: | - git config user.name "github-actions[bot]" - git config user.email "github-actions[bot]@users.noreply.github.com" - git tag -f rolling - git push origin :refs/tags/rolling || true - git push origin rolling --force + - name: Setup .NET + uses: actions/setup-dotnet@v5 + with: + dotnet-version: | + 8.0.x + 9.0.x + 10.0.x - - name: Upload to rolling - uses: ncipollo/release-action@v1.14.0 - with: - allowUpdates: True - artifacts: "*.nupkg,*.snupkg,*.zip" - body: 'Last built commit: ${{ github.sha }}' - name: 'Rolling Release' - prerelease: True - replacesArtifacts: True - tag: "rolling" - updateOnlyUnreleased: True + - name: Run tests + run: dotnet test + + - name: Run publish script + run: ./publish-nix.sh -d + + - name: Update rolling tag + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git tag -f rolling + git push origin :refs/tags/rolling || true + git push origin rolling --force + + - name: Upload to rolling + uses: ncipollo/release-action@v1.20.0 + with: + allowUpdates: True + artifacts: "*.nupkg,*.snupkg,*.zip" + body: "Last built commit: ${{ github.sha }}" + name: "Rolling Release" + prerelease: True + replacesArtifacts: True + tag: "rolling" + updateOnlyUnreleased: True diff --git a/.github/workflows/check_pr.yml b/.github/workflows/check_pr.yml index c9e23ecd..5e7ba34d 100644 --- a/.github/workflows/check_pr.yml +++ b/.github/workflows/check_pr.yml @@ -3,21 +3,21 @@ name: Build PR on: [pull_request] jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Setup .NET - uses: actions/setup-dotnet@v4 - with: - dotnet-version: | - 6.0.x - 8.0.x - 9.0.x - - - name: Build - run: dotnet build + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v5 - - name: Run tests - run: dotnet test + - name: Setup .NET + uses: actions/setup-dotnet@v5 + with: + dotnet-version: | + 8.0.x + 9.0.x + 10.0.x + + - name: Build + run: dotnet build + + - name: Run tests + run: dotnet test diff --git a/.vscode/launch.json b/.vscode/launch.json index f8821671..aef77e8e 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -10,7 +10,7 @@ "request": "launch", "preLaunchTask": "build", // If you have changed target frameworks, make sure to update the program path. - "program": "${workspaceFolder}/ProtectionScan/bin/Debug/net9.0/ProtectionScan.dll", + "program": "${workspaceFolder}/ProtectionScan/bin/Debug/net10.0/ProtectionScan.dll", "args": [], "cwd": "${workspaceFolder}/ProtectionScan", // For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console diff --git a/BinaryObjectScanner.Test/BinaryObjectScanner.Test.csproj b/BinaryObjectScanner.Test/BinaryObjectScanner.Test.csproj index f8de8ec1..e9126396 100644 --- a/BinaryObjectScanner.Test/BinaryObjectScanner.Test.csproj +++ b/BinaryObjectScanner.Test/BinaryObjectScanner.Test.csproj @@ -1,7 +1,7 @@ - net8.0;net9.0 + net8.0;net9.0;net10.0 false latest enable @@ -16,8 +16,8 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - - + + runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/BinaryObjectScanner.Test/FileType/AACSMediaKeyBlockTests.cs b/BinaryObjectScanner.Test/FileType/AACSMediaKeyBlockTests.cs index 71c31640..541ade84 100644 --- a/BinaryObjectScanner.Test/FileType/AACSMediaKeyBlockTests.cs +++ b/BinaryObjectScanner.Test/FileType/AACSMediaKeyBlockTests.cs @@ -31,4 +31,3 @@ namespace BinaryObjectScanner.Test.FileType } } } - diff --git a/BinaryObjectScanner.Test/FileType/BDPlusSVMTests.cs b/BinaryObjectScanner.Test/FileType/BDPlusSVMTests.cs index 3db323d1..d66e3643 100644 --- a/BinaryObjectScanner.Test/FileType/BDPlusSVMTests.cs +++ b/BinaryObjectScanner.Test/FileType/BDPlusSVMTests.cs @@ -31,4 +31,3 @@ namespace BinaryObjectScanner.Test.FileType } } } - diff --git a/BinaryObjectScanner.Test/FileType/LDSCRYPTTests.cs b/BinaryObjectScanner.Test/FileType/LDSCRYPTTests.cs index d7731a06..f4bca804 100644 --- a/BinaryObjectScanner.Test/FileType/LDSCRYPTTests.cs +++ b/BinaryObjectScanner.Test/FileType/LDSCRYPTTests.cs @@ -31,4 +31,3 @@ namespace BinaryObjectScanner.Test.FileType } } } - diff --git a/BinaryObjectScanner.Test/FileType/PLJTests.cs b/BinaryObjectScanner.Test/FileType/PLJTests.cs index 278d7462..1ea2d5d7 100644 --- a/BinaryObjectScanner.Test/FileType/PLJTests.cs +++ b/BinaryObjectScanner.Test/FileType/PLJTests.cs @@ -31,4 +31,3 @@ namespace BinaryObjectScanner.Test.FileType } } } - diff --git a/BinaryObjectScanner.Test/FileType/RealArcadeInstallerTests.cs b/BinaryObjectScanner.Test/FileType/RealArcadeInstallerTests.cs index a9d0e74b..7ce91fc2 100644 --- a/BinaryObjectScanner.Test/FileType/RealArcadeInstallerTests.cs +++ b/BinaryObjectScanner.Test/FileType/RealArcadeInstallerTests.cs @@ -31,4 +31,3 @@ namespace BinaryObjectScanner.Test.FileType } } } - diff --git a/BinaryObjectScanner.Test/FileType/RealArcadeMezzanineTests.cs b/BinaryObjectScanner.Test/FileType/RealArcadeMezzanineTests.cs index f0c2c03e..455cc569 100644 --- a/BinaryObjectScanner.Test/FileType/RealArcadeMezzanineTests.cs +++ b/BinaryObjectScanner.Test/FileType/RealArcadeMezzanineTests.cs @@ -31,4 +31,3 @@ namespace BinaryObjectScanner.Test.FileType } } } - diff --git a/BinaryObjectScanner.Test/FileType/TextfileTests.cs b/BinaryObjectScanner.Test/FileType/TextfileTests.cs index 764d6a8f..8496157e 100644 --- a/BinaryObjectScanner.Test/FileType/TextfileTests.cs +++ b/BinaryObjectScanner.Test/FileType/TextfileTests.cs @@ -28,4 +28,3 @@ namespace BinaryObjectScanner.Test.FileType } } } - diff --git a/BinaryObjectScanner/BinaryObjectScanner.csproj b/BinaryObjectScanner/BinaryObjectScanner.csproj index 5d2a9bf6..11f133bc 100644 --- a/BinaryObjectScanner/BinaryObjectScanner.csproj +++ b/BinaryObjectScanner/BinaryObjectScanner.csproj @@ -2,7 +2,7 @@ - net20;net35;net40;net452;net462;net472;net48;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0;net9.0;netstandard2.0;netstandard2.1 + net20;net35;net40;net452;net462;net472;net48;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0;net9.0;net10.0;netstandard2.0;netstandard2.1 true false false @@ -34,11 +34,11 @@ win-x86;win-x64;win-arm64;linux-x64;linux-arm64;osx-x64 - + win-x86;win-x64;win-arm64;linux-x64;linux-arm64;osx-x64;osx-arm64 - net6.0;net7.0;net8.0;net9.0 + net6.0;net7.0;net8.0;net9.0;net10.0 @@ -46,12 +46,12 @@ - + - - - - + + + + \ No newline at end of file diff --git a/BinaryObjectScanner/Data/ProtectionDictionary.cs b/BinaryObjectScanner/Data/ProtectionDictionary.cs index adcd337a..1a238cb5 100644 --- a/BinaryObjectScanner/Data/ProtectionDictionary.cs +++ b/BinaryObjectScanner/Data/ProtectionDictionary.cs @@ -105,10 +105,11 @@ namespace BinaryObjectScanner.Data string key = keys[i]; // If the key is empty, remove it - if (this[key] == null || this[key].Count == 0) #if NET20 || NET35 + if (this[key] == null || this[key].Count == 0) Remove(key); #else + if (this[key] == null || this[key].IsEmpty) TryRemove(key, out _); #endif } @@ -167,7 +168,11 @@ namespace BinaryObjectScanner.Data continue; // Otherwise, get the new key name and transfer over +#if NETCOREAPP || NETSTANDARD2_1_OR_GREATER + string newKey = currentKey[pathToStrip!.Length..]; +#else string newKey = currentKey.Substring(pathToStrip!.Length); +#endif this[newKey] = this[currentKey]; #if NET20 || NET35 Remove(currentKey); @@ -243,7 +248,11 @@ namespace BinaryObjectScanner.Data var protections = new List(); // If we have an indicator of multiple protections +#if NETCOREAPP || NETSTANDARD2_1_OR_GREATER + if (protection!.Contains(';')) +#else if (protection!.Contains(";")) +#endif { var splitProtections = protection.Split(';'); protections.AddRange(splitProtections); diff --git a/BinaryObjectScanner/FileType/ISO9660.cs b/BinaryObjectScanner/FileType/ISO9660.cs index 244ac1c5..1920d274 100644 --- a/BinaryObjectScanner/FileType/ISO9660.cs +++ b/BinaryObjectScanner/FileType/ISO9660.cs @@ -68,7 +68,7 @@ namespace BinaryObjectScanner.FileType // Currently-found worst cases: // "Y:1BY:1BC" in Redump ID 23339 var strings = bytes.ReadStringsWithEncoding(charLimit: 7, Encoding.ASCII); - var rgx = new Regex("[^a-zA-Z0-9 -'!,.]"); + var rgx = new Regex("[^a-zA-Z0-9 -'!,.]", RegexOptions.Compiled); foreach (string str in strings) { if (rgx.Replace(str, "").Length > 7) @@ -112,7 +112,7 @@ namespace BinaryObjectScanner.FileType 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/Packer/InnoSetup.cs b/BinaryObjectScanner/Packer/InnoSetup.cs index f667e458..4527ea37 100644 --- a/BinaryObjectScanner/Packer/InnoSetup.cs +++ b/BinaryObjectScanner/Packer/InnoSetup.cs @@ -60,6 +60,7 @@ namespace BinaryObjectScanner.Packer // TODO: Don't read entire file // TODO: Only 64 bytes at the end of the file is needed +#pragma warning disable CS0618 byte[]? data = exe.ReadArbitraryRange(); if (data == null) return "Unknown 1.X"; diff --git a/BinaryObjectScanner/Packer/NSIS.cs b/BinaryObjectScanner/Packer/NSIS.cs index e3d5f9ed..882326eb 100644 --- a/BinaryObjectScanner/Packer/NSIS.cs +++ b/BinaryObjectScanner/Packer/NSIS.cs @@ -17,7 +17,11 @@ namespace BinaryObjectScanner.Packer string? name = exe.AssemblyDescription; if (name.OptionalStartsWith("Nullsoft Install System")) +#if NETCOREAPP || NETSTANDARD2_1_OR_GREATER + return $"NSIS {name!["Nullsoft Install System".Length..].Trim()}"; +#else return $"NSIS {name!.Substring("Nullsoft Install System".Length).Trim()}"; +#endif name = exe.AssemblyName; diff --git a/BinaryObjectScanner/Packer/SevenZipSFX.cs b/BinaryObjectScanner/Packer/SevenZipSFX.cs index a5e050a1..2e9b6746 100644 --- a/BinaryObjectScanner/Packer/SevenZipSFX.cs +++ b/BinaryObjectScanner/Packer/SevenZipSFX.cs @@ -12,7 +12,11 @@ namespace BinaryObjectScanner.Packer string? name = exe.AssemblyDescription; if (name.OptionalStartsWith("7-Zip Self-extracting Archive")) +#if NETCOREAPP || NETSTANDARD2_1_OR_GREATER + return $"7-Zip SFX {exe.AssemblyDescription!["7-Zip Self-extracting Archive ".Length..]}"; +#else return $"7-Zip SFX {exe.AssemblyDescription!.Substring("7-Zip Self-extracting Archive ".Length)}"; +#endif name = exe.FileDescription; diff --git a/BinaryObjectScanner/Packer/UPX.cs b/BinaryObjectScanner/Packer/UPX.cs index 967c91cd..0f381ba1 100644 --- a/BinaryObjectScanner/Packer/UPX.cs +++ b/BinaryObjectScanner/Packer/UPX.cs @@ -10,9 +10,9 @@ namespace BinaryObjectScanner.Packer // https://raw.githubusercontent.com/wolfram77web/app-peid/master/userdb.txt public class UPX : IExecutableCheck { - private static readonly Regex _oldUpxVersionMatch = new Regex(@"\$Id: UPX (.*?) Copyright \(C\)", RegexOptions.Compiled); + private static readonly Regex _oldUpxVersionMatch = new(@"\$Id: UPX (.*?) Copyright \(C\)", RegexOptions.Compiled); - private static readonly Regex _upxVersionMatch = new Regex(@"^([0-9]\.[0-9]{2})$", RegexOptions.Compiled); + private static readonly Regex _upxVersionMatch = new(@"^([0-9]\.[0-9]{2})$", RegexOptions.Compiled); /// public string? CheckExecutable(string file, PortableExecutable exe, bool includeDebug) diff --git a/BinaryObjectScanner/Protection/AlphaROM.cs b/BinaryObjectScanner/Protection/AlphaROM.cs index 810a5a50..b8f33787 100644 --- a/BinaryObjectScanner/Protection/AlphaROM.cs +++ b/BinaryObjectScanner/Protection/AlphaROM.cs @@ -65,7 +65,7 @@ namespace BinaryObjectScanner.Protection if (applicationIdentifierString == null || applicationIdentifierString.Length < 14) return null; - if (!Regex.IsMatch(applicationIdentifierString, "^[A-Z0-9]*$")) + if (!Regex.IsMatch(applicationIdentifierString, "^[A-Z0-9]*$", RegexOptions.Compiled)) return null; // While some alpharom discs have data in the publisher identifier that can be checked, not all of them do, @@ -75,7 +75,7 @@ namespace BinaryObjectScanner.Protection // #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 @@ -86,26 +86,38 @@ namespace BinaryObjectScanner.Protection { return "Alpha-ROM"; } - + // 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) +#if NETCOREAPP || NETSTANDARD2_1_OR_GREATER + if (int.TryParse(applicationIdentifierString.AsSpan(0, 4), out int year) == false + || int.TryParse(applicationIdentifierString.AsSpan(4, 2), out int month) == false + || int.TryParse(applicationIdentifierString.AsSpan(6, 2), out int day) == false + || int.TryParse(applicationIdentifierString.AsSpan(8, 6), out int extraTime) == false) +#else + if (int.TryParse(applicationIdentifierString.Substring(0, 4), out int year) == false + || int.TryParse(applicationIdentifierString.Substring(4, 2), out int month) == false + || int.TryParse(applicationIdentifierString.Substring(6, 2), out int day) == false + || int.TryParse(applicationIdentifierString.Substring(8, 6), out int extraTime) == false) +#endif { return null; } - + if (year >= 2009 || year < 2000 || month > 12 || day > 31) return null; - + int index = Array.FindIndex(applicationIdentifierStringBytes, b => b > 60); - + +#if NETCOREAPP || NETSTANDARD2_1_OR_GREATER + var startingNumbers = Encoding.ASCII.GetBytes(applicationIdentifierString[..index]); + var finalCharacters = Encoding.ASCII.GetBytes(applicationIdentifierString[index..]); +#else var startingNumbers = Encoding.ASCII.GetBytes(applicationIdentifierString.Substring(0, index)); var finalCharacters = Encoding.ASCII.GetBytes(applicationIdentifierString.Substring(index)); +#endif if (Array.TrueForAll(startingNumbers, b => b < 60) && Array.TrueForAll(finalCharacters, b => b > 60)) return "Alpha-ROM"; } diff --git a/BinaryObjectScanner/Protection/CDDVDCops.cs b/BinaryObjectScanner/Protection/CDDVDCops.cs index 46a23bce..2e710168 100644 --- a/BinaryObjectScanner/Protection/CDDVDCops.cs +++ b/BinaryObjectScanner/Protection/CDDVDCops.cs @@ -72,6 +72,7 @@ namespace BinaryObjectScanner.Protection public string? CheckExecutable(string file, NewExecutable exe, bool includeDebug) { // TODO: Don't read entire file +#pragma warning disable CS0618 byte[]? data = exe.ReadArbitraryRange(); if (data == null) return null; @@ -272,7 +273,7 @@ namespace BinaryObjectScanner.Protection // Full string ends with # (i.e. "CD-Cops, ver. 1.72, #"), use that to compensate for comma in version // number cases (don't change the comma, see earlier to-do) like "DVD-Cops, ver. 1,60, #" // TODO: improve regex via the starting "N" character? Possibly unnecessary? - var versionMatch = Regex.Match(match, @"(?<=D-Cops,\s{1,}ver. )(.*?)(?=,\s{1,}#)"); + var versionMatch = Regex.Match(match, @"(?<=D-Cops,\s{1,}ver. )(.*?)(?=,\s{1,}#)", RegexOptions.Compiled); if (versionMatch.Success) return versionMatch.Value; diff --git a/BinaryObjectScanner/Protection/CDGuard.cs b/BinaryObjectScanner/Protection/CDGuard.cs index 25dde39c..2e5ccd49 100644 --- a/BinaryObjectScanner/Protection/CDGuard.cs +++ b/BinaryObjectScanner/Protection/CDGuard.cs @@ -13,10 +13,10 @@ namespace BinaryObjectScanner.Protection /// It may have been developed by Russobit-M, though the same source also says that StarForce was created by the same company as well, which seems unlikely (https://m.linkdatasecurity.com/pnews6.htm). /// Others online have been confused by this as well (https://forum.ixbt.com/topic.cgi?id=31:009712). /// A game referred to as having CD-Guard by http://lastboss.ru/games/RUS/randevu-s-neznakomkoi-2 that was published by Russobit-M is known to have an early version of StarForce (Redump entry 97088). - /// The FAQ on the game's official website indicates that StarForce specifically is present (https://web.archive.org/web/20011220224222/http://www.aha.ru/~exe_soft/russian/exesoft.htm). + /// The FAQ on the game's official website indicates that StarForce specifically is present (https://web.archive.org/web/20011220224222/http://www.aha.ru/~exe_soft/russian/exesoft.htm). /// It's unknown for sure if there were two separate versions of this game that contained separate protections, or if the game never actually contained CD-Guard, or if CD-Guard was an early name for the StarForce line of products. /// There is a re-release of an earlier game by the same developer that seems to include both CD-Guard and StarForce drivers, with the CD-Guard driver seemingly not used during installation, nor installed onto the system (IA item "pahgeby-he3hakomkou"). - /// + /// /// Additional resources and references: /// https://gamecopyworld.com/games/pc_omikron.shtml /// https://forum.ixbt.com/topic.cgi?id=31:3985 diff --git a/BinaryObjectScanner/Protection/CopyX.cs b/BinaryObjectScanner/Protection/CopyX.cs index 337671b7..a2c33e06 100644 --- a/BinaryObjectScanner/Protection/CopyX.cs +++ b/BinaryObjectScanner/Protection/CopyX.cs @@ -110,7 +110,11 @@ namespace BinaryObjectScanner.Protection { lightFiles = fileList.FindAll(f => { +#if NETCOREAPP || NETSTANDARD2_1_OR_GREATER + f = f[path.Length..]; +#else f = f.Remove(0, path.Length); +#endif f = f.TrimStart('/', '\\'); return f.StartsWith(dir + Path.DirectorySeparatorChar, StringComparison.OrdinalIgnoreCase); }); diff --git a/BinaryObjectScanner/Protection/DVDMoviePROTECT.cs b/BinaryObjectScanner/Protection/DVDMoviePROTECT.cs index 5b5e560e..f282de94 100644 --- a/BinaryObjectScanner/Protection/DVDMoviePROTECT.cs +++ b/BinaryObjectScanner/Protection/DVDMoviePROTECT.cs @@ -23,7 +23,11 @@ namespace BinaryObjectScanner.Protection if (bupfile.DirectoryName == null) continue; +#if NETCOREAPP || NETSTANDARD2_1_OR_GREATER + string ifofile = Path.Combine(bupfile.DirectoryName, bupfile.Name[..^bupfile.Extension.Length] + ".ifo"); +#else string ifofile = Path.Combine(bupfile.DirectoryName, bupfile.Name.Substring(0, bupfile.Name.Length - bupfile.Extension.Length) + ".ifo"); +#endif if (bupfile.Length != ifofile.FileSize()) { protections.Add("DVD-Movie-PROTECT (Unconfirmed - Please report to us on Github)"); diff --git a/BinaryObjectScanner/Protection/Denuvo.cs b/BinaryObjectScanner/Protection/Denuvo.cs index 6a77d10e..af7f58ce 100644 --- a/BinaryObjectScanner/Protection/Denuvo.cs +++ b/BinaryObjectScanner/Protection/Denuvo.cs @@ -102,12 +102,11 @@ namespace BinaryObjectScanner.Protection // Mad Max, Metal Gear Solid: TPP, Rise of the Tomb Raider new( new ContentMatch( - new byte?[] - { + [ 0x51, 0x52, 0x41, 0x50, 0x41, 0x51, 0x4C, 0x8D, null, null, null, null, null, 0x4C, 0x8D, null, null, null, null, null, 0x4D, 0x29, 0xC1, - }, + ], end: 0 ), "Denuvo v1.0 (x64)"), @@ -115,11 +114,10 @@ namespace BinaryObjectScanner.Protection // Lords of the Fallen, Batman: AK, Just Cause 3, Sherlock Holmes: TdD, Tales of Berseria etc new( new ContentMatch( - new byte?[] - { + [ 0x48, 0x8D, 0x0D, null, null, null, null, 0xE9, null, null, null, null, - }, + ], end: 0 ), "Denuvo v2.0a (x64)"), @@ -127,13 +125,12 @@ namespace BinaryObjectScanner.Protection // Yesterday Origins new( new ContentMatch( - new byte?[] - { + [ 0x48, 0x89, null, null, null, null, null, 0x48, 0x89, null, null, null, null, null, 0x4C, 0x89, null, null, null, null, null, 0x4C, 0x89, null, null, null, null, null, 0x48, 0x83, 0xFA, 0x01, - }, + ], end: 0 ), "Denuvo v2.0b (x64)"), @@ -141,11 +138,10 @@ namespace BinaryObjectScanner.Protection // Sniper Ghost Warrior 3 (beta), Dead Rising 4 (SteamStub-free) new( new ContentMatch( - new byte?[] - { + [ null, null, null, null, null, null, null, null, 0x4C, 0x89, 0x1C, 0x24, 0x49, 0x89, 0xE3, - }, + ], end: 0 ), "Denuvo v3.0a (x64)"), @@ -153,13 +149,12 @@ namespace BinaryObjectScanner.Protection // Train Sim World CSX Heavy Haul new( new ContentMatch( - new byte?[] - { + [ 0x4D, 0x8D, null, null, null, null, null, null, null, null, null, 0x48, 0x89, null, null, null, null, null, 0x48, 0x8D, null, null, 0x48, 0x89, null, 0x48, 0x89, null, 0x48, 0x89, - }, + ], end: 0 ), "Denuvo v3.0b (x64)"), @@ -207,13 +202,12 @@ namespace BinaryObjectScanner.Protection // Pro Evolution Soccer 2017, Champions of Anteria new( new ContentMatch( - new byte?[] - { + [ 0x55, 0x89, 0xE5, 0x8D, null, null, null, null, null, null, 0xE8, null, null, null, null, 0xE8, null, null, null, null, 0xE8, null, null, null, null, 0xE8, null, null, null, null, - }, + ], end: 0 ), "Denuvo v1.0 (x86)"), @@ -221,11 +215,10 @@ namespace BinaryObjectScanner.Protection // Romance of 13 Kingdoms, 2Dark new( new ContentMatch( - new byte?[] - { + [ 0x8D, null, null, null, null, null, null, 0x89, 0x7C, 0x24, 0x04, 0x89, 0xE7, - }, + ], end: 0 ), "Denuvo v2.0 (x86)"), diff --git a/BinaryObjectScanner/Protection/Gefest.cs b/BinaryObjectScanner/Protection/Gefest.cs index 81b39195..b8b26274 100644 --- a/BinaryObjectScanner/Protection/Gefest.cs +++ b/BinaryObjectScanner/Protection/Gefest.cs @@ -57,7 +57,11 @@ namespace BinaryObjectScanner.Protection private static string GetVersion(string match) { match = match.Trim('*').Trim(); +#if NETCOREAPP || NETSTANDARD2_1_OR_GREATER + return match["Gefest Protection System ".Length..]; +#else return match.Substring("Gefest Protection System ".Length); +#endif } } } diff --git a/BinaryObjectScanner/Protection/InterLok.cs b/BinaryObjectScanner/Protection/InterLok.cs index 92e81b68..cacebab3 100644 --- a/BinaryObjectScanner/Protection/InterLok.cs +++ b/BinaryObjectScanner/Protection/InterLok.cs @@ -26,7 +26,7 @@ namespace BinaryObjectScanner.Protection private static string GetVersion(string match) { - var versionMatch = Regex.Match(match, @"(?<=InterLok )(.*?)(?=,)"); + var versionMatch = Regex.Match(match, @"(?<=InterLok )(.*?)(?=,)", RegexOptions.Compiled); if (versionMatch.Success) return versionMatch.Value; diff --git a/BinaryObjectScanner/Protection/Macrovision.CactusDataShield.cs b/BinaryObjectScanner/Protection/Macrovision.CactusDataShield.cs index e0d845fd..cf60cc19 100644 --- a/BinaryObjectScanner/Protection/Macrovision.CactusDataShield.cs +++ b/BinaryObjectScanner/Protection/Macrovision.CactusDataShield.cs @@ -140,7 +140,11 @@ namespace BinaryObjectScanner.Protection if (line == null) return null; +#if NETCOREAPP || NETSTANDARD2_1_OR_GREATER + return $"{line[3..]} ({sr.ReadLine()})"; +#else return $"{line.Substring(3)} ({sr.ReadLine()})"; +#endif } catch { diff --git a/BinaryObjectScanner/Protection/Macrovision.SafeCast.cs b/BinaryObjectScanner/Protection/Macrovision.SafeCast.cs index d021dea9..9bbfa823 100644 --- a/BinaryObjectScanner/Protection/Macrovision.SafeCast.cs +++ b/BinaryObjectScanner/Protection/Macrovision.SafeCast.cs @@ -52,6 +52,7 @@ namespace BinaryObjectScanner.Protection } // TODO: Don't read entire file +#pragma warning disable CS0618 byte[]? data = exe.ReadArbitraryRange(); if (data == null) return null; @@ -149,13 +150,13 @@ namespace BinaryObjectScanner.Protection var matchers = new List { // Found in IA item "britney-spears-special-edition-cd-rom". - new(new List - { + new( + [ new FilePathMatch("C2C.16"), new FilePathMatch("C2C.DLL"), new FilePathMatch("C2CDEL.16"), new FilePathMatch("C2CDEL.EXE"), - }, "SafeCast"), + ], "SafeCast"), // Found in IA item "ejay_nestle_trial". new(new FilePathMatch("cdac01aa.dll"), "SafeCast"), diff --git a/BinaryObjectScanner/Protection/Macrovision.SafeDisc.cs b/BinaryObjectScanner/Protection/Macrovision.SafeDisc.cs index b3b12388..6074ef88 100644 --- a/BinaryObjectScanner/Protection/Macrovision.SafeDisc.cs +++ b/BinaryObjectScanner/Protection/Macrovision.SafeDisc.cs @@ -1043,39 +1043,32 @@ namespace BinaryObjectScanner.Protection return string.Empty; var sha1 = HashTool.GetFileHash(firstMatchedString, HashType.SHA1); - switch (sha1?.ToUpperInvariant()) + + return sha1?.ToUpperInvariant() switch { // Found in Redump entry 63488. - case "DA39A3EE5E6B4B0D3255BFEF95601890AFD80709": - return "(Empty File)"; + "DA39A3EE5E6B4B0D3255BFEF95601890AFD80709" => "(Empty File)", // First known generic SafeDisc splash-screen. // 4-bit (16 color) version, found in Redump entries 43321, 45040, 45202, 66586, 68206, 75501, 79272, and 110603. - case "D8A8CF761DD7C04F635385E4C4589E5F26C6171E": - return "1.11.000-2.40.011"; + "D8A8CF761DD7C04F635385E4C4589E5F26C6171E" => "1.11.000-2.40.011", // 8-bit (256 color) version, found in Redump entries 43321, 45040, 45202, 66586, 68206, 75501, 79272, and 110603. - case "0C9E45BF3EBE1382A3593994328C22BCB9A55456": - return "1.11.000-2.40.011"; + "0C9E45BF3EBE1382A3593994328C22BCB9A55456" => "1.11.000-2.40.011", // Second known generic SafeDisc splash-screen. // 4-bit (16 color), found in Redump entries 46339 and 75897. - case "9B80F524D45041ED8CE1613AD5BDE94BFDBB2814": - return "2.70.030-2.80.010"; + "9B80F524D45041ED8CE1613AD5BDE94BFDBB2814" => "2.70.030-2.80.010", // 8-bit (256 color) version, found in Redump entries 46339 and 75897. - case "827AE9A32906CBE9098C9101184E0BE74CEA2744": - return "2.70.030-2.80.010"; + "827AE9A32906CBE9098C9101184E0BE74CEA2744" => "2.70.030-2.80.010", // Third known generic SafeDisc splash-screen. // 4-bit (16 color), found in Redump entries 74338, 75782, 84985, and 91552. - case "814ED63FD619655650E271D1B8B46BBE39C3655A": - return "3.15.010-3.20.022"; + "814ED63FD619655650E271D1B8B46BBE39C3655A" => "3.15.010-3.20.022", // 8-bit (256 color) version, found in Redump entries 31824, 74338, 75782, 84985, 91552, and 104053. - case "40C7ACEDB6C41AB067285090373E886EFB4F4AC4": - return "3.15.010-4.60.000"; + "40C7ACEDB6C41AB067285090373E886EFB4F4AC4" => "3.15.010-4.60.000", - default: - return null; - } + _ => null, + }; // There appear to be a few distinct generations of file names used for SafeDisc splash-screens. // The first are the files named "SPLSH16.BMP"/"SPLSH256.BMP", which were typically used in SafeDisc versions 1.00.025-1.01.044. diff --git a/BinaryObjectScanner/Protection/MediaMax.cs b/BinaryObjectScanner/Protection/MediaMax.cs index 3556e8bc..4df75d3c 100644 --- a/BinaryObjectScanner/Protection/MediaMax.cs +++ b/BinaryObjectScanner/Protection/MediaMax.cs @@ -63,22 +63,22 @@ namespace BinaryObjectScanner.Protection var matchers = new List { // Found on "All That I Am" by Santana (Barcode 8 2876-59773-2 6) - new(new List - { + new( + [ // TODO: Verify if these are OR or AND // TODO: Verify that this is directly related to MediaMax CD-3. new FilePathMatch("PlayDisc.exe"), new FilePathMatch("PlayDisc.xml"), - }, "MediaMax CD-3"), + ], "MediaMax CD-3"), // Found on "Contraband" by Velvet Revolver (Barcode 8 28766 05242 8) // "SCCD3X01.dll" should already be detected by the content checks, but not "SCCD3X02.dll". - new(new List - { + new( + [ // TODO: Verify if these are OR or AND new FilePathMatch("SCCD3X01.dll"), new FilePathMatch("SCCD3X02.dll"), - }, "MediaMax CD-3"), + ], "MediaMax CD-3"), }; return MatchUtil.GetAllMatches(files, matchers, any: false); diff --git a/BinaryObjectScanner/Protection/ProtectDISC.cs b/BinaryObjectScanner/Protection/ProtectDISC.cs index 8865fde2..7e2a3a4a 100644 --- a/BinaryObjectScanner/Protection/ProtectDISC.cs +++ b/BinaryObjectScanner/Protection/ProtectDISC.cs @@ -32,12 +32,17 @@ namespace BinaryObjectScanner.Protection if (copyrightString == null || copyrightString.Length < 19) return null; - copyrightString = copyrightString.Substring(0, 19); // Redump ID 15896 has a trailing space + // Redump ID 15896 has a trailing space +#if NETCOREAPP || NETSTANDARD2_1_OR_GREATER + copyrightString = copyrightString[..19]; +#else + copyrightString = copyrightString.Substring(0, 19); +#endif // Stores some kind of serial in the copyright string, format 0000-XXXX-XXXX-XXXX where it can be numbers or // capital letters. - if (!Regex.IsMatch(copyrightString, "[0]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}")) + if (!Regex.IsMatch(copyrightString, "[0]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}", RegexOptions.Compiled)) return null; offset = 0; diff --git a/BinaryObjectScanner/Protection/RainbowSentinel.cs b/BinaryObjectScanner/Protection/RainbowSentinel.cs index 99874b55..0d731afe 100644 --- a/BinaryObjectScanner/Protection/RainbowSentinel.cs +++ b/BinaryObjectScanner/Protection/RainbowSentinel.cs @@ -41,6 +41,7 @@ namespace BinaryObjectScanner.Protection public string? CheckExecutable(string file, NewExecutable exe, bool includeDebug) { // TODO: Don't read entire file +#pragma warning disable CS0618 byte[]? data = exe.ReadArbitraryRange(); if (data == null) return null; @@ -335,24 +336,24 @@ namespace BinaryObjectScanner.Protection new(new FilePathMatch("SNTUSB95.SYS"), "Rainbow Sentinel USB Driver"), // Found in IA item "czchip199707cd". - new(new List - { + new( + [ new FilePathMatch("DOSMON.EXE"), new FilePathMatch("FIND.EXE"), new FilePathMatch("NCEDIT.EXE"), new FilePathMatch("NETEVAL.EXE"), - }, "Rainbow NetSentinel Monitor for DOS"), + ], "Rainbow NetSentinel Monitor for DOS"), // Found in IA item "czchip199707cd". - new(new List - { + new( + [ new FilePathMatch("OS2MON.EXE"), new FilePathMatch("RHPANELP.DLL"), - }, "Rainbow NetSentinel Monitor for OS/2"), + ], "Rainbow NetSentinel Monitor for OS/2"), // Found in IA item "czchip199707cd". - new(new List - { + new( + [ new FilePathMatch("MAPFILE.TXT"), new FilePathMatch("NKWIN32.DLL"), new FilePathMatch("NSLMS32.DLL"), @@ -362,7 +363,7 @@ namespace BinaryObjectScanner.Protection new FilePathMatch("WINMON.EXE"), new FilePathMatch("WINMON.HLP"), new FilePathMatch("WMON_DOC.EXE"), - }, "Rainbow NetSentinel Monitor for Win32"), + ], "Rainbow NetSentinel Monitor for Win32"), // Found in IA item "chip-cds-2001-08". // File names for Rainbow Sentinel files sometimes found in ".cab" files. diff --git a/BinaryObjectScanner/Protection/SVKProtector.cs b/BinaryObjectScanner/Protection/SVKProtector.cs index 0691dc01..8ab4e193 100644 --- a/BinaryObjectScanner/Protection/SVKProtector.cs +++ b/BinaryObjectScanner/Protection/SVKProtector.cs @@ -55,20 +55,20 @@ namespace BinaryObjectScanner.Protection return "SVKP v1.051"; // Found in the SVKP 1.11 demo. - if (exe.EntryPointData.StartsWith(new byte?[] - { + if (exe.EntryPointData.StartsWith( + [ 0x60, 0xE8, null, null, null, null, 0x5D, 0x81, 0xED, 0x06, null, null, null, 0x64, 0xA0, 0x23 - })) + ])) return "SVKP v1.11"; // Found in the SVKP 1.32 demo and Redump entry 84122. - if (exe.EntryPointData.StartsWith(new byte?[] - { + if (exe.EntryPointData.StartsWith( + [ 0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x81, 0xED, 0x06, 0x00, 0x00, 0x00, 0xEB, 0x05, 0xB8, null, null, null, null, 0x64, 0xA0, 0x23 - })) + ])) return "SVKP v1.3+"; } diff --git a/BinaryObjectScanner/Protection/SecuROM.cs b/BinaryObjectScanner/Protection/SecuROM.cs index 2c93483f..f461754c 100644 --- a/BinaryObjectScanner/Protection/SecuROM.cs +++ b/BinaryObjectScanner/Protection/SecuROM.cs @@ -355,12 +355,12 @@ namespace BinaryObjectScanner.Protection new(new FilePathMatch("SINTFNT.DLL"), "SecuROM New"), // TODO: Find more samples of this for different versions - new(new List - { + new( + [ new FilePathMatch("securom_v7_01.bak"), new FilePathMatch("securom_v7_01.dat"), new FilePathMatch("securom_v7_01.tmp"), - }, "SecuROM 7.01"), + ], "SecuROM 7.01"), }; return MatchUtil.GetAllMatches(files, matchers, any: true); diff --git a/BinaryObjectScanner/Protection/SmartE.cs b/BinaryObjectScanner/Protection/SmartE.cs index ba4ad5d8..f5b4cb1e 100644 --- a/BinaryObjectScanner/Protection/SmartE.cs +++ b/BinaryObjectScanner/Protection/SmartE.cs @@ -50,11 +50,11 @@ namespace BinaryObjectScanner.Protection { var matchers = new List { - new(new List - { + new( + [ new FilePathMatch("00001.TMP"), new FilePathMatch("00002.TMP") - }, "SmartE"), + ], "SmartE"), }; return MatchUtil.GetAllMatches(files, matchers, any: true); diff --git a/BinaryObjectScanner/Protection/SoftLock.cs b/BinaryObjectScanner/Protection/SoftLock.cs index 8f8e5df6..c7e0001e 100644 --- a/BinaryObjectScanner/Protection/SoftLock.cs +++ b/BinaryObjectScanner/Protection/SoftLock.cs @@ -73,11 +73,11 @@ namespace BinaryObjectScanner.Protection { var matchers = new List { - new(new List - { + new( + [ new FilePathMatch("SOFTLOCKC.dat"), new FilePathMatch("SOFTLOCKI.dat"), - }, "SoftLock"), + ], "SoftLock"), }; return MatchUtil.GetAllMatches(files, matchers, any: false); diff --git a/BinaryObjectScanner/Protection/SolidShield.cs b/BinaryObjectScanner/Protection/SolidShield.cs index 7329f31f..d711f62f 100644 --- a/BinaryObjectScanner/Protection/SolidShield.cs +++ b/BinaryObjectScanner/Protection/SolidShield.cs @@ -87,7 +87,11 @@ namespace BinaryObjectScanner.Protection { var str = strs.Find(s => s.Contains("Solidshield ")); if (str != null) +#if NETCOREAPP || NETSTANDARD2_1_OR_GREATER + return $"SolidShield EXE Wrapper {str["Solidshield ".Length..]}"; +#else return $"SolidShield EXE Wrapper {str.Substring("Solidshield ".Length)}"; +#endif } } diff --git a/BinaryObjectScanner/Protection/StarForce.cs b/BinaryObjectScanner/Protection/StarForce.cs index 7ca2a7e6..30b06353 100644 --- a/BinaryObjectScanner/Protection/StarForce.cs +++ b/BinaryObjectScanner/Protection/StarForce.cs @@ -30,13 +30,13 @@ namespace BinaryObjectScanner.Protection return null; int offset = 0; - + // StarForce Keyless check: the key is stored in the Data Preparer identifier. string? dataPreparerIdentiferString = pvd.DataPreparerIdentifier.ReadNullTerminatedAnsiString(ref offset)?.Trim(); - - if (dataPreparerIdentiferString != null - && dataPreparerIdentiferString.Length != 0 - && Regex.IsMatch(dataPreparerIdentiferString, "^[A-Z0-9-]*$")) + + if (dataPreparerIdentiferString != null + && dataPreparerIdentiferString.Length != 0 + && Regex.IsMatch(dataPreparerIdentiferString, "^[A-Z0-9-]*$", RegexOptions.Compiled)) { // It is returning the key, as it tells you what set of DPM your disc corresponds to, and it would also // help show why a disc might be an alt of another disc (there are at least a decent amount of StarForce @@ -49,23 +49,23 @@ namespace BinaryObjectScanner.Protection // XXXXX-XXXXX-XXXXX-XXXXX-XXXXX (25 characters, plus 4 dashes seperating 5 groups of 5) // XXXXXXXXXXXXXXXXXXXXXXXXXXXX (28 characters) // XXXX-XXXXXX-XXXXXX-XXXXXX-XXXXXX (28 characters, with 4 dashes) - if (Regex.IsMatch(dataPreparerIdentiferString, "^[A-Z0-9]{25}$") - || Regex.IsMatch(dataPreparerIdentiferString, "^[A-Z0-9]{5}-[A-Z0-9]{5}-[A-Z0-9]{5}-[A-Z0-9]{5}-[A-Z0-9]{5}$") - || Regex.IsMatch(dataPreparerIdentiferString, "^[A-Z0-9]{28}$") - || Regex.IsMatch(dataPreparerIdentiferString, "^[A-Z0-9]{4}-[A-Z0-9]{6}-[A-Z0-9]{6}-[A-Z0-9]{6}-[A-Z0-9]{6}$")) + if (Regex.IsMatch(dataPreparerIdentiferString, "^[A-Z0-9]{25}$", RegexOptions.Compiled) + || Regex.IsMatch(dataPreparerIdentiferString, "^[A-Z0-9]{5}-[A-Z0-9]{5}-[A-Z0-9]{5}-[A-Z0-9]{5}-[A-Z0-9]{5}$", RegexOptions.Compiled) + || Regex.IsMatch(dataPreparerIdentiferString, "^[A-Z0-9]{28}$", RegexOptions.Compiled) + || Regex.IsMatch(dataPreparerIdentiferString, "^[A-Z0-9]{4}-[A-Z0-9]{6}-[A-Z0-9]{6}-[A-Z0-9]{6}-[A-Z0-9]{6}$", RegexOptions.Compiled)) { return $"StarForce Keyless - {dataPreparerIdentiferString}"; } // Redump ID 60270 is a unique case, there could possibly be more. if (UnusualStarforceKeylessKeys.ContainsKey(dataPreparerIdentiferString)) - return $"StarForce Keyless - {dataPreparerIdentiferString}"; + return $"StarForce Keyless - {dataPreparerIdentiferString}"; } - + // Starforce general check: the reserved 653 bytes start with a 32-bit LE number that's slightly less // than the length of the volume size space. The difference varies, it's usually around 10. Check 500 to be // safe. The rest of the data is all 0x00. Not many starforce discs have this, but some do, and it's - // currently the only known non-keyless check. Redump ID 60266, 72531, 87181, 91734, 106732, 105356, 74578, + // currently the only known non-keyless check. Redump ID 60266, 72531, 87181, 91734, 106732, 105356, 74578, // 78200 are some examples. if (FileType.ISO9660.NoteworthyApplicationUse(pvd)) return null; @@ -83,7 +83,7 @@ namespace BinaryObjectScanner.Protection // through here. if (initialValue > pvd.VolumeSpaceSize || initialValue + 500 < pvd.VolumeSpaceSize || !Array.TrueForAll(zeroBytes, b => b == 0x00)) return null; - + return "StarForce"; } @@ -201,31 +201,31 @@ namespace BinaryObjectScanner.Protection var matchers = new List { // This file combination is found in Redump entry 21136. - new(new List - { + new( + [ new FilePathMatch("protect.x86"), new FilePathMatch("protect.x64"), new FilePathMatch("protect.dll"), new FilePathMatch("protect.exe"), new FilePathMatch("protect.msg"), - }, "StarForce"), + ], "StarForce"), // This file combination is found in multiple games, such as Redump entries 81756, 91336, and 93657. - new(new List - { + new( + [ new FilePathMatch("protect.x86"), new FilePathMatch("protect.x64"), new FilePathMatch("protect.dll"), new FilePathMatch("protect.exe"), - }, "StarForce"), + ], "StarForce"), // This file combination is found in Redump entry 96137. - new(new List - { + new( + [ new FilePathMatch("protect.x86"), new FilePathMatch("protect.dll"), new FilePathMatch("protect.exe"), - }, "StarForce"), + ], "StarForce"), }; return MatchUtil.GetAllMatches(files, matchers, any: false); diff --git a/BinaryObjectScanner/Protection/Steam.cs b/BinaryObjectScanner/Protection/Steam.cs index 2418838e..260d4546 100644 --- a/BinaryObjectScanner/Protection/Steam.cs +++ b/BinaryObjectScanner/Protection/Steam.cs @@ -60,8 +60,8 @@ namespace BinaryObjectScanner.Protection ], "Steam (.sis/.csm/.csd)"), // These checks are grouped together due to the names being generic on their own (Redump entry 91450). - new(new List - { + new( + [ // TODO: Identify based on "Steam(TM)" being present in "Description" but not in "File Description". // Overmatches on some files, such as IA item "ASMEsMechanicalEngineeringToolkit1997December". // new FilePathMatch("steam.exe"), @@ -70,7 +70,7 @@ namespace BinaryObjectScanner.Protection // TODO: Identify file using MSI property parsing. new FilePathMatch("steam.msi"), - }, "Steam"), + ], "Steam"), new(new FilePathMatch("steam_api.dll"), "Steam"), new(new FilePathMatch("steam_api64.dll"), "Steam"), diff --git a/BinaryObjectScanner/Protection/Tages.cs b/BinaryObjectScanner/Protection/Tages.cs index dbb86998..1fb5730d 100644 --- a/BinaryObjectScanner/Protection/Tages.cs +++ b/BinaryObjectScanner/Protection/Tages.cs @@ -273,7 +273,7 @@ namespace BinaryObjectScanner.Protection return null; // TODO: Determine difference between API and BASIC - byte typeByte = fileContent[positions[0] + 6]; + _ = fileContent[positions[0] + 6]; byte versionByte = fileContent[positions[0] + 7]; return versionByte switch diff --git a/BinaryObjectScanner/ProtectionProgress.cs b/BinaryObjectScanner/ProtectionProgress.cs index bff0529b..87dd8683 100644 --- a/BinaryObjectScanner/ProtectionProgress.cs +++ b/BinaryObjectScanner/ProtectionProgress.cs @@ -6,7 +6,7 @@ #if NET20 || NET35 || NET40 public class ProtectionProgress : System.EventArgs #else - public struct ProtectionProgress + public readonly struct ProtectionProgress #endif { /// diff --git a/BinaryObjectScanner/Scanner.cs b/BinaryObjectScanner/Scanner.cs index f72738ff..5ee8f553 100644 --- a/BinaryObjectScanner/Scanner.cs +++ b/BinaryObjectScanner/Scanner.cs @@ -153,7 +153,11 @@ namespace BinaryObjectScanner // Get the reportable file name string reportableFileName = file; if (reportableFileName.StartsWith(tempFilePath)) +#if NETCOREAPP || NETSTANDARD2_1_OR_GREATER + reportableFileName = reportableFileName[tempFilePathWithGuid.Length..]; +#else reportableFileName = reportableFileName.Substring(tempFilePathWithGuid.Length); +#endif // Checkpoint _fileProgress?.Report(new ProtectionProgress(reportableFileName, depth, i / (float)files.Count, "Checking file" + (file != reportableFileName ? " from archive" : string.Empty))); @@ -173,7 +177,11 @@ namespace BinaryObjectScanner // Checkpoint protections.TryGetValue(file, out var fullProtectionList); +#if NET20 || NET35 var fullProtection = fullProtectionList != null && fullProtectionList.Count > 0 +#else + var fullProtection = fullProtectionList != null && !fullProtectionList.IsEmpty +#endif ? string.Join(", ", [.. fullProtectionList]) : null; _fileProgress?.Report(new ProtectionProgress(reportableFileName, depth, (i + 1) / (float)files.Count, fullProtection ?? string.Empty)); @@ -186,7 +194,11 @@ namespace BinaryObjectScanner // Get the reportable file name string reportableFileName = path; if (reportableFileName.StartsWith(tempFilePath)) +#if NETCOREAPP || NETSTANDARD2_1_OR_GREATER + reportableFileName = reportableFileName[tempFilePathWithGuid.Length..]; +#else reportableFileName = reportableFileName.Substring(tempFilePathWithGuid.Length); +#endif // Checkpoint _fileProgress?.Report(new ProtectionProgress(reportableFileName, depth, 0, "Checking file" + (path != reportableFileName ? " from archive" : string.Empty))); @@ -206,7 +218,11 @@ namespace BinaryObjectScanner // Checkpoint protections.TryGetValue(path, out var fullProtectionList); +#if NET20 || NET35 var fullProtection = fullProtectionList != null && fullProtectionList.Count > 0 +#else + var fullProtection = fullProtectionList != null && !fullProtectionList.IsEmpty +#endif ? string.Join(", ", [.. fullProtectionList]) : null; _fileProgress?.Report(new ProtectionProgress(reportableFileName, depth, 1, fullProtection ?? string.Empty)); @@ -473,27 +489,27 @@ namespace BinaryObjectScanner private static IDetectable? CreateDetectable(WrapperType fileType, IWrapper? wrapper) { // Use the wrapper before the type - switch (wrapper) + return wrapper switch { - case AACSMediaKeyBlock obj: return new FileType.AACSMediaKeyBlock(obj); - case BDPlusSVM obj: return new FileType.BDPlusSVM(obj); - case ISO9660 obj: return new FileType.ISO9660(obj); - case LDSCRYPT obj: return new FileType.LDSCRYPT(obj); - case LinearExecutable obj: return new FileType.LinearExecutable(obj); - case MSDOS obj: return new FileType.MSDOS(obj); - case NewExecutable obj: return new FileType.NewExecutable(obj); - case PlayJAudioFile obj: return new FileType.PLJ(obj); - case PortableExecutable obj: return new FileType.PortableExecutable(obj); - case RealArcadeInstaller obj: return new FileType.RealArcadeInstaller(obj); - case RealArcadeMezzanine obj: return new FileType.RealArcadeMezzanine(obj); - case SFFS obj: return new FileType.SFFS(obj); - } + AACSMediaKeyBlock obj => new FileType.AACSMediaKeyBlock(obj), + BDPlusSVM obj => new FileType.BDPlusSVM(obj), + ISO9660 obj => new FileType.ISO9660(obj), + LDSCRYPT obj => new FileType.LDSCRYPT(obj), + LinearExecutable obj => new FileType.LinearExecutable(obj), + MSDOS obj => new FileType.MSDOS(obj), + NewExecutable obj => new FileType.NewExecutable(obj), + PlayJAudioFile obj => new FileType.PLJ(obj), + PortableExecutable obj => new FileType.PortableExecutable(obj), + RealArcadeInstaller obj => new FileType.RealArcadeInstaller(obj), + RealArcadeMezzanine obj => new FileType.RealArcadeMezzanine(obj), + SFFS obj => new FileType.SFFS(obj), - // Fall back on the file type for types not implemented in Serialization - return fileType switch - { - WrapperType.Textfile => new FileType.Textfile(), - _ => null, + // Fall back on the file type for types not implemented in Serialization + _ => fileType switch + { + WrapperType.Textfile => new FileType.Textfile(), + _ => null, + }, }; } diff --git a/ProtectionScan/Features/MainFeature.cs b/ProtectionScan/Features/MainFeature.cs index c19680fc..bd007783 100644 --- a/ProtectionScan/Features/MainFeature.cs +++ b/ProtectionScan/Features/MainFeature.cs @@ -360,16 +360,15 @@ namespace ProtectionScan.Features var part = pathParts[i]; // Inserts new subdictionaries if one doesn't already exist - if (!current.ContainsKey(part)) + if (!current.TryGetValue(part, out object? innerObject)) { var innerDictionary = new Dictionary(); - current[part] = innerDictionary; + innerObject = innerDictionary; + current[part] = innerObject; current = innerDictionary; continue; } - // Handle instances where a protection was already assigned to the current node - var innerObject = current[part]; if (innerObject is string[] existingProtections) { modifyNodeList.Add((current, part, existingProtections)); diff --git a/ProtectionScan/ProtectionScan.csproj b/ProtectionScan/ProtectionScan.csproj index 47c8f7a9..28cde99e 100644 --- a/ProtectionScan/ProtectionScan.csproj +++ b/ProtectionScan/ProtectionScan.csproj @@ -1,7 +1,7 @@ - net20;net35;net40;net452;net462;net472;net48;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0;net9.0 + net20;net35;net40;net452;net462;net472;net48;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0;net9.0;net10.0 Exe false true @@ -20,11 +20,11 @@ win-x86;win-x64;win-arm64;linux-x64;linux-arm64;osx-x64 - + win-x86;win-x64;win-arm64;linux-x64;linux-arm64;osx-x64;osx-arm64 - net6.0;net7.0;net8.0;net9.0 + net6.0;net7.0;net8.0;net9.0;net10.0 @@ -32,8 +32,8 @@ - - + + \ No newline at end of file diff --git a/publish-nix.sh b/publish-nix.sh index ce68d837..8148036a 100755 --- a/publish-nix.sh +++ b/publish-nix.sh @@ -1,7 +1,7 @@ #!/bin/bash # This batch file assumes the following: -# - .NET 9.0 (or newer) SDK is installed and in PATH +# - .NET 10.0 (or newer) SDK is installed and in PATH # - zip is installed and in PATH # - Git is installed and in PATH # @@ -49,18 +49,18 @@ echo " No archive (-a) $NO_ARCHIVE" echo " " # Create the build matrix arrays -FRAMEWORKS=("net9.0") +FRAMEWORKS=("net10.0") RUNTIMES=("win-x86" "win-x64" "win-arm64" "linux-x64" "linux-arm64" "osx-x64" "osx-arm64") # Use expanded lists, if requested if [ $USE_ALL = true ]; then - FRAMEWORKS=("net20" "net35" "net40" "net452" "net462" "net472" "net48" "netcoreapp3.1" "net5.0" "net6.0" "net7.0" "net8.0" "net9.0") + FRAMEWORKS=("net20" "net35" "net40" "net452" "net462" "net472" "net48" "netcoreapp3.1" "net5.0" "net6.0" "net7.0" "net8.0" "net9.0" "net10.0") fi # Create the filter arrays -SINGLE_FILE_CAPABLE=("net5.0" "net6.0" "net7.0" "net8.0" "net9.0") -VALID_APPLE_FRAMEWORKS=("net6.0" "net7.0" "net8.0" "net9.0") -VALID_CROSS_PLATFORM_FRAMEWORKS=("netcoreapp3.1" "net5.0" "net6.0" "net7.0" "net8.0" "net9.0") +SINGLE_FILE_CAPABLE=("net5.0" "net6.0" "net7.0" "net8.0" "net9.0" "net10.0") +VALID_APPLE_FRAMEWORKS=("net6.0" "net7.0" "net8.0" "net9.0" "net10.0") +VALID_CROSS_PLATFORM_FRAMEWORKS=("netcoreapp3.1" "net5.0" "net6.0" "net7.0" "net8.0" "net9.0" "net10.0") VALID_CROSS_PLATFORM_RUNTIMES=("win-arm64" "linux-x64" "linux-arm64" "osx-x64" "osx-arm64") # Only build if requested diff --git a/publish-win.ps1 b/publish-win.ps1 index 332130c2..ef51c40b 100644 --- a/publish-win.ps1 +++ b/publish-win.ps1 @@ -1,5 +1,5 @@ # This batch file assumes the following: -# - .NET 9.0 (or newer) SDK is installed and in PATH +# - .NET 10.0 (or newer) SDK is installed and in PATH # - 7-zip commandline (7z.exe) is installed and in PATH # - Git for Windows is installed and in PATH # @@ -40,18 +40,18 @@ Write-Host " No archive (-NoArchive) $NO_ARCHIVE" Write-Host " " # Create the build matrix arrays -$FRAMEWORKS = @('net9.0') +$FRAMEWORKS = @('net10.0') $RUNTIMES = @('win-x86', 'win-x64', 'win-arm64', 'linux-x64', 'linux-arm64', 'osx-x64', 'osx-arm64') # Use expanded lists, if requested if ($USE_ALL.IsPresent) { - $FRAMEWORKS = @('net20', 'net35', 'net40', 'net452', 'net462', 'net472', 'net48', 'netcoreapp3.1', 'net5.0', 'net6.0', 'net7.0', 'net8.0', 'net9.0') + $FRAMEWORKS = @('net20', 'net35', 'net40', 'net452', 'net462', 'net472', 'net48', 'netcoreapp3.1', 'net5.0', 'net6.0', 'net7.0', 'net8.0', 'net9.0', 'net10.0') } # Create the filter arrays -$SINGLE_FILE_CAPABLE = @('net5.0', 'net6.0', 'net7.0', 'net8.0', 'net9.0') -$VALID_APPLE_FRAMEWORKS = @('net6.0', 'net7.0', 'net8.0', 'net9.0') -$VALID_CROSS_PLATFORM_FRAMEWORKS = @('netcoreapp3.1', 'net5.0', 'net6.0', 'net7.0', 'net8.0', 'net9.0') +$SINGLE_FILE_CAPABLE = @('net5.0', 'net6.0', 'net7.0', 'net8.0', 'net9.0', 'net10.0') +$VALID_APPLE_FRAMEWORKS = @('net6.0', 'net7.0', 'net8.0', 'net9.0', 'net10.0') +$VALID_CROSS_PLATFORM_FRAMEWORKS = @('netcoreapp3.1', 'net5.0', 'net6.0', 'net7.0', 'net8.0', 'net9.0', 'net10.0') $VALID_CROSS_PLATFORM_RUNTIMES = @('win-arm64', 'linux-x64', 'linux-arm64', 'osx-x64', 'osx-arm64') # Only build if requested