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