From 94d59242b1dd90e8efb5e1c3adc12dc3c7bbaffe Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Fri, 6 Dec 2024 00:27:39 -0500 Subject: [PATCH] Update protection tool tests --- CHANGELIST.md | 1 + ...tectionTests.cs => ProtectionToolTests.cs} | 95 +++++++++++++++---- MPF.Frontend/Tools/ProtectionTool.cs | 85 ++++++++++------- 3 files changed, 130 insertions(+), 51 deletions(-) rename MPF.Frontend.Test/Tools/{ProtectionTests.cs => ProtectionToolTests.cs} (61%) diff --git a/CHANGELIST.md b/CHANGELIST.md index 70f632b4..36ffd4b1 100644 --- a/CHANGELIST.md +++ b/CHANGELIST.md @@ -53,6 +53,7 @@ - Ensure consistency in frontend code - Ensure Redumper support matrix is consistent - Add FrontendTool tests +- Update protection tool tests ### 3.2.4 (2024-11-24) diff --git a/MPF.Frontend.Test/Tools/ProtectionTests.cs b/MPF.Frontend.Test/Tools/ProtectionToolTests.cs similarity index 61% rename from MPF.Frontend.Test/Tools/ProtectionTests.cs rename to MPF.Frontend.Test/Tools/ProtectionToolTests.cs index c54f02ec..3f98de86 100644 --- a/MPF.Frontend.Test/Tools/ProtectionTests.cs +++ b/MPF.Frontend.Test/Tools/ProtectionToolTests.cs @@ -6,10 +6,23 @@ using Xunit; namespace MPF.Frontend.Test.Tools { - public class ProtectionTests + public class ProtectionToolTests { [Fact] - public void SanitizeFoundProtectionsActiveMARKTest() + public void SanitizeFoundProtections_Exception() + { + List protections = + [ + "Anything Else Protection", + "[Exception opening file", + ]; + + string sanitized = ProtectionTool.SanitizeFoundProtections(protections); + Assert.Equal("Anything Else Protection, Exception occurred while scanning [RESCAN NEEDED]", sanitized); + } + + [Fact] + public void SanitizeFoundProtections_ActiveMARK() { List protections = [ @@ -22,7 +35,7 @@ namespace MPF.Frontend.Test.Tools } [Fact] - public void SanitizeFoundProtectionsCactusDataShieldTest() + public void SanitizeFoundProtections_CactusDataShield() { List protections = [ @@ -35,7 +48,20 @@ namespace MPF.Frontend.Test.Tools } [Fact] - public void SanitizeFoundProtectionsCDCheckTest() + public void SanitizeFoundProtections_CactusDataShieldMacrovision() + { + List protections = + [ + "Anything Else Protection", + "Cactus Data Shield 300 (Confirm presence of other CDS-300 files)", + ]; + + string sanitized = ProtectionTool.SanitizeFoundProtections(protections); + Assert.Equal("Anything Else Protection, Cactus Data Shield 300", sanitized); + } + + [Fact] + public void SanitizeFoundProtections_CDCheck() { List protections = [ @@ -48,7 +74,7 @@ namespace MPF.Frontend.Test.Tools } [Fact] - public void SanitizeFoundProtectionsCDCopsTest() + public void SanitizeFoundProtections_CDCops() { List protections = [ @@ -61,7 +87,7 @@ namespace MPF.Frontend.Test.Tools } [Fact] - public void SanitizeFoundProtectionsCDKeyTest() + public void SanitizeFoundProtections_CDKey() { List protections = [ @@ -74,7 +100,7 @@ namespace MPF.Frontend.Test.Tools } [Fact] - public void SanitizeFoundProtectionsEACdKeyTest() + public void SanitizeFoundProtections_EACdKey() { List protections = [ @@ -87,7 +113,7 @@ namespace MPF.Frontend.Test.Tools } [Fact] - public void SanitizeFoundProtectionsEADRMTest() + public void SanitizeFoundProtections_EADRM() { List protections = [ @@ -100,7 +126,7 @@ namespace MPF.Frontend.Test.Tools } [Fact] - public void SanitizeFoundProtectionsGFWLTest() + public void SanitizeFoundProtections_GFWL() { List protections = [ @@ -113,7 +139,7 @@ namespace MPF.Frontend.Test.Tools } [Fact] - public void SanitizeFoundProtectionsGFWLZDPPTest() + public void SanitizeFoundProtections_GFWLZDPP() { List protections = [ @@ -126,7 +152,7 @@ namespace MPF.Frontend.Test.Tools } [Fact] - public void SanitizeFoundProtectionsImpulseReactorTest() + public void SanitizeFoundProtections_ImpulseReactor() { List protections = [ @@ -143,7 +169,7 @@ namespace MPF.Frontend.Test.Tools [InlineData(1)] [InlineData(2)] [InlineData(3)] - public void SanitizeFoundProtectionsJoWoodXProtTest(int skip) + public void SanitizeFoundProtections_JoWoodXProtTest(int skip) { List protections = [ @@ -166,7 +192,7 @@ namespace MPF.Frontend.Test.Tools } [Fact] - public void SanitizeFoundProtectionsOnlineRegistrationTest() + public void SanitizeFoundProtections_OnlineRegistration() { List protections = [ @@ -178,12 +204,49 @@ namespace MPF.Frontend.Test.Tools Assert.Equal("Anything Else Protection", sanitized); } + [Theory] + [InlineData(0, "Macrovision Protected Application [SafeDisc 0.00.000], SafeDisc 0.00.000, SafeDisc Lite")] + [InlineData(1, "Macrovision Protected Application [SafeDisc 0.00.000 / SRV Tool APP], SafeDisc 0.00.000, SafeDisc Lite")] + [InlineData(2, "Macrovision Security Driver, Macrovision Security Driver [SafeDisc 1.11.111], SafeDisc 0.00.000, SafeDisc 0.00.000-1.11.111, SafeDisc Lite")] + [InlineData(3, "Macrovision Security Driver, Macrovision Security Driver [SafeDisc 1.11.111], SafeDisc 0.00.000, SafeDisc Lite")] + [InlineData(4, "Macrovision Security Driver, Macrovision Security Driver [SafeDisc 1.11.111], SafeDisc Lite")] + [InlineData(5, "Macrovision Security Driver, SafeDisc Lite")] + [InlineData(6, "Macrovision Protection File, SafeDisc 2+, SafeDisc 3+ (DVD), SafeDisc Lite")] + [InlineData(7, "SafeDisc 3+ (DVD)")] + [InlineData(8, "SafeDisc 2+")] + public void SanitizeFoundProtections_SafeDisc(int skip, string expected) + { + List protections = + [ + "Macrovision Protected Application [SafeDisc 0.00.000]", + "Macrovision Protected Application [SafeDisc 0.00.000 / SRV Tool APP]", + "SafeDisc 0.00.000-1.11.111", + "SafeDisc 0.00.000", + "Macrovision Security Driver [SafeDisc 1.11.111]", + "Macrovision Security Driver", + "SafeDisc Lite", + "SafeDisc 3+ (DVD)", + "SafeDisc 2+", + "Macrovision Protection File", + ]; + + // Safeguard for the future + if (skip >= protections.Count) + throw new ArgumentException("Invalid skip value", nameof(skip)); + + // The list is in order of preference + protections = protections.Skip(skip).ToList(); + + string sanitized = ProtectionTool.SanitizeFoundProtections(protections); + Assert.Equal(expected, sanitized); + } + [Theory] [InlineData(0)] [InlineData(1)] [InlineData(2)] [InlineData(3)] - public void SanitizeFoundProtectionStarForceTest(int skip) + public void SanitizeFoundProtections_StarForce(int skip) { List protections = [ @@ -206,7 +269,7 @@ namespace MPF.Frontend.Test.Tools } [Fact] - public void SanitizeFoundProtectionsSysiphusTest() + public void SanitizeFoundProtections_Sysiphus() { List protections = [ @@ -219,7 +282,7 @@ namespace MPF.Frontend.Test.Tools } [Fact] - public void SanitizeFoundProtectionsXCPTest() + public void SanitizeFoundProtections_XCP() { List protections = [ diff --git a/MPF.Frontend/Tools/ProtectionTool.cs b/MPF.Frontend/Tools/ProtectionTool.cs index e2685d69..84ffb392 100644 --- a/MPF.Frontend/Tools/ProtectionTool.cs +++ b/MPF.Frontend/Tools/ProtectionTool.cs @@ -160,12 +160,26 @@ namespace MPF.Frontend.Tools foundProtections = foundProtections.FindAll(p => p != "Cactus Data Shield 200"); } + // Cactus Data Shield / SafeDisc + if (foundProtections.Exists(p => p == "Cactus Data Shield 300 (Confirm presence of other CDS-300 files)")) + { + foundProtections = foundProtections + .FindAll(p => p != "Cactus Data Shield 300 (Confirm presence of other CDS-300 files)"); + + if (foundProtections.Exists(p => !p.StartsWith("SafeDisc"))) + foundProtections.Add("Cactus Data Shield 300"); + } + // CD-Check foundProtections = foundProtections.FindAll(p => p != "Executable-Based CD Check"); // CD-Cops - if (foundProtections.Exists(p => p == "CD-Cops") && foundProtections.Exists(p => p.StartsWith("CD-Cops") && p.Length > "CD-Cops".Length)) + if (foundProtections.Exists(p => p == "CD-Cops") + && foundProtections.Exists(p => p.StartsWith("CD-Cops") + && p.Length > "CD-Cops".Length)) + { foundProtections = foundProtections.FindAll(p => p != "CD-Cops"); + } // CD-Key / Serial foundProtections = foundProtections.FindAll(p => p != "CD-Key / Serial"); @@ -239,73 +253,72 @@ namespace MPF.Frontend.Tools // SafeCast // TODO: Figure this one out - // Cactus Data Shield / SafeDisc - if (foundProtections.Exists(p => p == "Cactus Data Shield 300 (Confirm presence of other CDS-300 files)")) - { - foundProtections = foundProtections - .FindAll(p => p != "Cactus Data Shield 300 (Confirm presence of other CDS-300 files)"); - - if (foundProtections.Exists(p => !p.StartsWith("SafeDisc"))) - foundProtections.Add("Cactus Data Shield 300"); - } - // SafeDisc if (foundProtections.Exists(p => p.StartsWith("SafeDisc"))) { - // Confirmed this set of checks works with Redump entries 10430, 11347, 13230, 18614, 28257, 31149, 31824, 52606, 57721, 58455, 58573, 62935, 63941, 64255, 65569, 66005, 70504, 73502, 74520, 78048, 79729, 83468, 98589, and 101261. + // Confirmed this set of checks works with Redump entries 10430, 11347, 13230, 18614, 28257, 31149, 31824, 52606, 57721, 58455, + // 58573, 62935, 63941, 64255, 65569, 66005, 70504, 73502, 74520, 78048, 79729, 83468, 98589, and 101261. - // Best case scenario for SafeDisc 2+: A full SafeDisc version is found in a line starting with "Macrovision Protected Application". All other SafeDisc detections can be safely scrubbed. + // Best case scenario for SafeDisc 2+: A full SafeDisc version is found in a line starting with "Macrovision Protected Application". + // All other SafeDisc detections can be safely scrubbed. // TODO: Scrub "Macrovision Protected Application, " from before the SafeDisc version. - if (foundProtections.Exists(p => Regex.IsMatch(p, @"SafeDisc [0-9]\.[0-9]{2}\.[0-9]{3}", RegexOptions.Compiled) && p.StartsWith("Macrovision Protected Application") && !p.Contains("SRV Tool APP"))) + if (foundProtections.Exists(p => Regex.IsMatch(p, @"SafeDisc [0-9]\.[0-9]{2}\.[0-9]{3}", RegexOptions.Compiled) + && p.StartsWith("Macrovision Protected Application") + && !p.Contains("SRV Tool APP"))) { foundProtections = foundProtections.FindAll(p => !p.StartsWith("Macrovision Protection File")) .FindAll(p => !p.StartsWith("Macrovision Security Driver")) .FindAll(p => !p.Contains("SRV Tool APP")) .FindAll(p => p != "SafeDisc") .FindAll(p => !p.StartsWith("Macrovision Protected Application [Version Expunged]")) - .FindAll(p => !(Regex.IsMatch(p, @"SafeDisc [0-9]\.[0-9]{2}\.[0-9]{3}-[0-9]\.[0-9]{2}\.[0-9]{3}", RegexOptions.Compiled))) - .FindAll(p => !(Regex.IsMatch(p, @"SafeDisc [0-9]\.[0-9]{2}\.[0-9]{3}\+", RegexOptions.Compiled))) - .FindAll(p => !(Regex.IsMatch(p, @"SafeDisc [0-9]\.[0-9]{2}\.[0-9]{3}\/4\+", RegexOptions.Compiled))) + .FindAll(p => !Regex.IsMatch(p, @"SafeDisc [0-9]\.[0-9]{2}\.[0-9]{3}-[0-9]\.[0-9]{2}\.[0-9]{3}", RegexOptions.Compiled)) + .FindAll(p => !Regex.IsMatch(p, @"SafeDisc [0-9]\.[0-9]{2}\.[0-9]{3}\+", RegexOptions.Compiled)) + .FindAll(p => !Regex.IsMatch(p, @"SafeDisc [0-9]\.[0-9]{2}\.[0-9]{3}\/4\+", RegexOptions.Compiled)) .FindAll(p => p != "SafeDisc 1/Lite") .FindAll(p => p != "SafeDisc 2+") .FindAll(p => p != "SafeDisc 3+ (DVD)"); } // Next best case for SafeDisc 2+: A full SafeDisc version is found from the "SafeDisc SRV Tool APP". - else if (foundProtections.Exists(p => Regex.IsMatch(p, @"SafeDisc [0-9]\.[0-9]{2}\.[0-9]{3}", RegexOptions.Compiled) && p.StartsWith("Macrovision Protected Application") && p.Contains("SRV Tool APP"))) + else if (foundProtections.Exists(p => Regex.IsMatch(p, @"SafeDisc [0-9]\.[0-9]{2}\.[0-9]{3}", RegexOptions.Compiled) + && p.StartsWith("Macrovision Protected Application") + && p.Contains("SRV Tool APP"))) { foundProtections = foundProtections.FindAll(p => !p.StartsWith("Macrovision Protection File")) .FindAll(p => !p.StartsWith("Macrovision Security Driver")) .FindAll(p => p != "SafeDisc") .FindAll(p => !p.StartsWith("Macrovision Protected Application [Version Expunged]")) - .FindAll(p => !(Regex.IsMatch(p, @"SafeDisc [0-9]\.[0-9]{2}\.[0-9]{3}-[0-9]\.[0-9]{2}\.[0-9]{3}", RegexOptions.Compiled))) - .FindAll(p => !(Regex.IsMatch(p, @"SafeDisc [0-9]\.[0-9]{2}\.[0-9]{3}\+", RegexOptions.Compiled))) - .FindAll(p => !(Regex.IsMatch(p, @"SafeDisc [0-9]\.[0-9]{2}\.[0-9]{3}\/4\+", RegexOptions.Compiled))) + .FindAll(p => !Regex.IsMatch(p, @"SafeDisc [0-9]\.[0-9]{2}\.[0-9]{3}-[0-9]\.[0-9]{2}\.[0-9]{3}", RegexOptions.Compiled)) + .FindAll(p => !Regex.IsMatch(p, @"SafeDisc [0-9]\.[0-9]{2}\.[0-9]{3}\+", RegexOptions.Compiled)) + .FindAll(p => !Regex.IsMatch(p, @"SafeDisc [0-9]\.[0-9]{2}\.[0-9]{3}\/4\+", RegexOptions.Compiled)) .FindAll(p => p != "SafeDisc 1/Lite") .FindAll(p => p != "SafeDisc 2+") .FindAll(p => p != "SafeDisc 3+ (DVD)"); } // Covers specific edge cases where older drivers are erroneously placed in discs with a newer version of SafeDisc, and the specific SafeDisc version is expunged. - else if (foundProtections.Exists(p => Regex.IsMatch(p, @"SafeDisc [1-2]\.[0-9]{2}\.[0-9]{3}-[1-2]\.[0-9]{2}\.[0-9]{3}$", RegexOptions.Compiled) || Regex.IsMatch(p, @"SafeDisc [1-2]\.[0-9]{2}\.[0-9]{3}$", RegexOptions.Compiled)) && foundProtections.Exists(p => p == "SafeDisc 3+ (DVD)")) + else if (foundProtections.Exists(p => Regex.IsMatch(p, @"SafeDisc [1-2]\.[0-9]{2}\.[0-9]{3}-[1-2]\.[0-9]{2}\.[0-9]{3}$", RegexOptions.Compiled) + || Regex.IsMatch(p, @"SafeDisc [1-2]\.[0-9]{2}\.[0-9]{3}$", RegexOptions.Compiled)) + && foundProtections.Exists(p => p == "SafeDisc 3+ (DVD)")) { foundProtections = foundProtections.FindAll(p => !p.StartsWith("Macrovision Protection File")) .FindAll(p => !p.StartsWith("Macrovision Protected Application [Version Expunged]")) .FindAll(p => !p.StartsWith("Macrovision Security Driver")) - .FindAll(p => !(Regex.IsMatch(p, @"SafeDisc [1-2]\.[0-9]{2}\.[0-9]{3}\+", RegexOptions.Compiled))) - .FindAll(p => !(Regex.IsMatch(p, @"SafeDisc [1-2]\.[0-9]{2}\.[0-9]{3}-[1-2]\.[0-9]{2}\.[0-9]{3}", RegexOptions.Compiled))) + .FindAll(p => !Regex.IsMatch(p, @"SafeDisc [1-2]\.[0-9]{2}\.[0-9]{3}\+", RegexOptions.Compiled)) + .FindAll(p => !Regex.IsMatch(p, @"SafeDisc [1-2]\.[0-9]{2}\.[0-9]{3}-[1-2]\.[0-9]{2}\.[0-9]{3}", RegexOptions.Compiled)) .FindAll(p => p != "SafeDisc") .FindAll(p => p != "SafeDisc 1/Lite") .FindAll(p => p != "SafeDisc 2+"); } // Best case for SafeDisc 1.X: A full SafeDisc version is found that isn't part of a version range. - else if (foundProtections.Exists(p => Regex.IsMatch(p, @"SafeDisc 1\.[0-9]{2}\.[0-9]{3}$", RegexOptions.Compiled) && !(Regex.IsMatch(p, @"SafeDisc 1\.[0-9]{2}\.[0-9]{3}-[0-9]\.[0-9]{2}\.[0-9]{3}", RegexOptions.Compiled)))) + else if (foundProtections.Exists(p => Regex.IsMatch(p, @"SafeDisc 1\.[0-9]{2}\.[0-9]{3}$", RegexOptions.Compiled) + && !Regex.IsMatch(p, @"SafeDisc 1\.[0-9]{2}\.[0-9]{3}-[0-9]\.[0-9]{2}\.[0-9]{3}", RegexOptions.Compiled))) { foundProtections = foundProtections.FindAll(p => !p.StartsWith("Macrovision Protection File")) .FindAll(p => !p.StartsWith("Macrovision Security Driver")) - .FindAll(p => !(Regex.IsMatch(p, @"SafeDisc [0-9]\.[0-9]{2}\.[0-9]{3}-[0-9]\.[0-9]{2}\.[0-9]{3}", RegexOptions.Compiled))) - .FindAll(p => !(Regex.IsMatch(p, @"SafeDisc [0-9]\.[0-9]{2}\.[0-9]{3}\+", RegexOptions.Compiled))) + .FindAll(p => !Regex.IsMatch(p, @"SafeDisc [0-9]\.[0-9]{2}\.[0-9]{3}-[0-9]\.[0-9]{2}\.[0-9]{3}", RegexOptions.Compiled)) + .FindAll(p => !Regex.IsMatch(p, @"SafeDisc [0-9]\.[0-9]{2}\.[0-9]{3}\+", RegexOptions.Compiled)) .FindAll(p => p != "SafeDisc") .FindAll(p => p != "SafeDisc 1") .FindAll(p => p != "SafeDisc 1/Lite"); @@ -313,12 +326,14 @@ namespace MPF.Frontend.Tools // Next best case for SafeDisc 1: A SafeDisc version range is found from "SECDRV.SYS". // TODO: Scrub "Macrovision Security Driver {Version}" from before the SafeDisc version. - else if (foundProtections.Exists(p => p.StartsWith("Macrovision Security Driver") && Regex.IsMatch(p, @"SafeDisc 1\.[0-9]{2}\.[0-9]{3}-[1-2]\.[0-9]{2}\.[0-9]{3}", RegexOptions.Compiled) || Regex.IsMatch(p, @"SafeDisc 1\.[0-9]{2}\.[0-9]{3}$"))) + else if (foundProtections.Exists(p => p.StartsWith("Macrovision Security Driver") + && Regex.IsMatch(p, @"SafeDisc 1\.[0-9]{2}\.[0-9]{3}-[1-2]\.[0-9]{2}\.[0-9]{3}", RegexOptions.Compiled) + || Regex.IsMatch(p, @"SafeDisc 1\.[0-9]{2}\.[0-9]{3}$"))) { foundProtections = foundProtections.FindAll(p => !p.StartsWith("Macrovision Protection File")) .FindAll(p => !p.StartsWith("Macrovision Protected Application [Version Expunged]")) - .FindAll(p => !(Regex.IsMatch(p, @"SafeDisc [0-9]\.[0-9]{2}\.[0-9]{3}\+", RegexOptions.Compiled))) - .FindAll(p => !(Regex.IsMatch(p, @"SafeDisc 1\.[0-9]{2}\.[0-9]{3}-[0-9]\.[0-9]{2}\.[0-9]{3}", RegexOptions.Compiled))) + .FindAll(p => !Regex.IsMatch(p, @"SafeDisc [0-9]\.[0-9]{2}\.[0-9]{3}\+", RegexOptions.Compiled)) + .FindAll(p => !Regex.IsMatch(p, @"SafeDisc 1\.[0-9]{2}\.[0-9]{3}-[0-9]\.[0-9]{2}\.[0-9]{3}", RegexOptions.Compiled)) .FindAll(p => p != "SafeDisc") .FindAll(p => p != "SafeDisc 1") .FindAll(p => p != "SafeDisc 1/Lite"); @@ -330,8 +345,8 @@ namespace MPF.Frontend.Tools { foundProtections = foundProtections.FindAll(p => !p.StartsWith("Macrovision Protection File")) .FindAll(p => !p.StartsWith("Macrovision Protected Application [Version Expunged]")) - .FindAll(p => !(Regex.IsMatch(p, @"SafeDisc [0-9]\.[0-9]{2}\.[0-9]{3}\+", RegexOptions.Compiled))) - .FindAll(p => !(Regex.IsMatch(p, @"SafeDisc 1\.[0-9]{2}\.[0-9]{3}-[0-9]\.[0-9]{2}\.[0-9]{3}", RegexOptions.Compiled))) + .FindAll(p => !Regex.IsMatch(p, @"SafeDisc [0-9]\.[0-9]{2}\.[0-9]{3}\+", RegexOptions.Compiled)) + .FindAll(p => !Regex.IsMatch(p, @"SafeDisc 1\.[0-9]{2}\.[0-9]{3}-[0-9]\.[0-9]{2}\.[0-9]{3}", RegexOptions.Compiled)) .FindAll(p => p != "SafeDisc") .FindAll(p => p != "SafeDisc 1") .FindAll(p => p != "SafeDisc 1/Lite") @@ -343,7 +358,7 @@ namespace MPF.Frontend.Tools else if (foundProtections.Exists(p => p == "SafeDisc Lite")) { foundProtections = foundProtections.FindAll(p => p != "SafeDisc") - .FindAll(p => !(Regex.IsMatch(p, @"SafeDisc 1\.[0-9]{2}\.[0-9]{3}-1\.[0-9]{2}\.[0-9]{3}\/Lite", RegexOptions.Compiled))); + .FindAll(p => !Regex.IsMatch(p, @"SafeDisc 1\.[0-9]{2}\.[0-9]{3}-1\.[0-9]{2}\.[0-9]{3}\/Lite", RegexOptions.Compiled)); } // Only SafeDisc 3+ is found. @@ -352,7 +367,7 @@ namespace MPF.Frontend.Tools foundProtections = foundProtections.FindAll(p => p != "SafeDisc") .FindAll(p => p != "SafeDisc 2+") .FindAll(p => !p.StartsWith("Macrovision Protection File")) - .FindAll(p => !(Regex.IsMatch(p, @"SafeDisc [0-9]\.[0-9]{2}\.[0-9]{3}\+", RegexOptions.Compiled))); + .FindAll(p => !Regex.IsMatch(p, @"SafeDisc [0-9]\.[0-9]{2}\.[0-9]{3}\+", RegexOptions.Compiled)); } // Only SafeDisc 2+ is found. @@ -360,7 +375,7 @@ namespace MPF.Frontend.Tools { foundProtections = foundProtections.FindAll(p => p != "SafeDisc") .FindAll(p => !p.StartsWith("Macrovision Protection File")) - .FindAll(p => !(Regex.IsMatch(p, @"SafeDisc [0-9]\.[0-9]{2}\.[0-9]{3}\+", RegexOptions.Compiled))); + .FindAll(p => !Regex.IsMatch(p, @"SafeDisc [0-9]\.[0-9]{2}\.[0-9]{3}\+", RegexOptions.Compiled)); } }