From 3667a5b57aed1d0bda91e06e25af0a49b9222ff1 Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Sun, 18 Jul 2021 09:44:23 -0700 Subject: [PATCH] Concurrent protection scans per file (#52) * Move to ConcurrentDictionary * Convert to ConcurrentQueue --- BurnOutSharp/FileType/BFPK.cs | 6 +-- BurnOutSharp/FileType/BZip2.cs | 5 +- BurnOutSharp/FileType/Executable.cs | 12 +++-- BurnOutSharp/FileType/GZIP.cs | 5 +- BurnOutSharp/FileType/InstallShieldCAB.cs | 5 +- BurnOutSharp/FileType/MPQ.cs | 5 +- BurnOutSharp/FileType/MSI.cs | 5 +- BurnOutSharp/FileType/MicrosoftCAB.cs | 5 +- BurnOutSharp/FileType/PKZIP.cs | 5 +- BurnOutSharp/FileType/RAR.cs | 5 +- BurnOutSharp/FileType/SevenZip.cs | 5 +- BurnOutSharp/FileType/TapeArchive.cs | 5 +- BurnOutSharp/FileType/Textfile.cs | 7 +-- BurnOutSharp/FileType/Valve.cs | 5 +- BurnOutSharp/FileType/XZ.cs | 5 +- BurnOutSharp/IPathCheck.cs | 5 +- BurnOutSharp/IScannable.cs | 6 +-- BurnOutSharp/Matching/MatchUtil.cs | 27 +++++----- BurnOutSharp/PackerType/CExe.cs | 5 +- BurnOutSharp/PackerType/InnoSetup.cs | 5 +- BurnOutSharp/PackerType/InstallerVISE.cs | 5 +- BurnOutSharp/PackerType/SetupFactory.cs | 7 +-- BurnOutSharp/PackerType/WinRARSFX.cs | 5 +- BurnOutSharp/PackerType/WinZipSFX.cs | 5 +- BurnOutSharp/PackerType/WiseInstaller.cs | 5 +- BurnOutSharp/ProtectionType/AACS.cs | 5 +- BurnOutSharp/ProtectionType/AlphaDVD.cs | 5 +- BurnOutSharp/ProtectionType/BDPlus.cs | 3 +- BurnOutSharp/ProtectionType/Bitpool.cs | 5 +- BurnOutSharp/ProtectionType/ByteShield.cs | 5 +- BurnOutSharp/ProtectionType/CDCops.cs | 3 +- BurnOutSharp/ProtectionType/CDLock.cs | 5 +- BurnOutSharp/ProtectionType/CDProtector.cs | 5 +- BurnOutSharp/ProtectionType/CDX.cs | 5 +- .../ProtectionType/CactusDataShield.cs | 3 +- BurnOutSharp/ProtectionType/CopyKiller.cs | 5 +- BurnOutSharp/ProtectionType/DVDCrypt.cs | 5 +- .../ProtectionType/DVDMoviePROTECT.cs | 14 +++-- BurnOutSharp/ProtectionType/DiscGuard.cs | 5 +- BurnOutSharp/ProtectionType/FreeLock.cs | 5 +- BurnOutSharp/ProtectionType/GFWL.cs | 5 +- .../ProtectionType/HexalockAutoLock.cs | 5 +- BurnOutSharp/ProtectionType/ImpulseReactor.cs | 5 +- BurnOutSharp/ProtectionType/IndyVCD.cs | 5 +- BurnOutSharp/ProtectionType/Key2AudioXS.cs | 5 +- BurnOutSharp/ProtectionType/LaserLock.cs | 3 +- BurnOutSharp/ProtectionType/MediaCloQ.cs | 5 +- BurnOutSharp/ProtectionType/MediaMaxCD3.cs | 5 +- BurnOutSharp/ProtectionType/Origin.cs | 3 +- .../ProtectionType/ProtectDVDVideo.cs | 14 +++-- BurnOutSharp/ProtectionType/SafeCast.cs | 5 +- BurnOutSharp/ProtectionType/SafeDisc.cs | 3 +- BurnOutSharp/ProtectionType/SafeDiscLite.cs | 5 +- BurnOutSharp/ProtectionType/SafeLock.cs | 5 +- BurnOutSharp/ProtectionType/SecuROM.cs | 3 +- BurnOutSharp/ProtectionType/SmartE.cs | 5 +- BurnOutSharp/ProtectionType/SoftLock.cs | 5 +- BurnOutSharp/ProtectionType/SolidShield.cs | 3 +- BurnOutSharp/ProtectionType/StarForce.cs | 5 +- BurnOutSharp/ProtectionType/Steam.cs | 5 +- .../ProtectionType/TZCopyProtector.cs | 5 +- BurnOutSharp/ProtectionType/Tages.cs | 13 ++--- .../ProtectionType/TivolaRingProtection.cs | 5 +- BurnOutSharp/ProtectionType/Uplay.cs | 5 +- .../ProtectionType/VOBProtectCDDVD.cs | 3 +- BurnOutSharp/ProtectionType/WTMCDProtect.cs | 5 +- BurnOutSharp/ProtectionType/Winlock.cs | 5 +- BurnOutSharp/ProtectionType/XCP.cs | 15 ++++-- BurnOutSharp/ProtectionType/Zzxzz.cs | 3 +- BurnOutSharp/Scanner.cs | 48 ++++++++--------- BurnOutSharp/Utilities.cs | 51 +++++++++++++------ Test/Program.cs | 7 +-- 72 files changed, 303 insertions(+), 199 deletions(-) diff --git a/BurnOutSharp/FileType/BFPK.cs b/BurnOutSharp/FileType/BFPK.cs index 8aa67b20..bbed1cc9 100644 --- a/BurnOutSharp/FileType/BFPK.cs +++ b/BurnOutSharp/FileType/BFPK.cs @@ -1,5 +1,5 @@ using System; -using System.Collections.Generic; +using System.Collections.Concurrent; using System.IO; using System.Text; using SharpCompress.Compressors; @@ -19,7 +19,7 @@ namespace BurnOutSharp.FileType } /// - public Dictionary> Scan(Scanner scanner, string file) + public ConcurrentDictionary> Scan(Scanner scanner, string file) { if (!File.Exists(file)) return null; @@ -31,7 +31,7 @@ namespace BurnOutSharp.FileType } /// - public Dictionary> Scan(Scanner scanner, Stream stream, string file) + public ConcurrentDictionary> Scan(Scanner scanner, Stream stream, string file) { // If the BFPK file itself fails try diff --git a/BurnOutSharp/FileType/BZip2.cs b/BurnOutSharp/FileType/BZip2.cs index 55228d2d..43981372 100644 --- a/BurnOutSharp/FileType/BZip2.cs +++ b/BurnOutSharp/FileType/BZip2.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using SharpCompress.Compressors; @@ -18,7 +19,7 @@ namespace BurnOutSharp.FileType } /// - public Dictionary> Scan(Scanner scanner, string file) + public ConcurrentDictionary> Scan(Scanner scanner, string file) { if (!File.Exists(file)) return null; @@ -30,7 +31,7 @@ namespace BurnOutSharp.FileType } /// - public Dictionary> Scan(Scanner scanner, Stream stream, string file) + public ConcurrentDictionary> Scan(Scanner scanner, Stream stream, string file) { // If the BZip2 file itself fails try diff --git a/BurnOutSharp/FileType/Executable.cs b/BurnOutSharp/FileType/Executable.cs index 55e13da5..2fe4f145 100644 --- a/BurnOutSharp/FileType/Executable.cs +++ b/BurnOutSharp/FileType/Executable.cs @@ -1,9 +1,11 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.Text; +using System.Threading.Tasks; namespace BurnOutSharp.FileType { @@ -49,7 +51,7 @@ namespace BurnOutSharp.FileType } /// - public Dictionary> Scan(Scanner scanner, string file) + public ConcurrentDictionary> Scan(Scanner scanner, string file) { if (!File.Exists(file)) return null; @@ -61,10 +63,10 @@ namespace BurnOutSharp.FileType } /// - public Dictionary> Scan(Scanner scanner, Stream stream, string file) + public ConcurrentDictionary> Scan(Scanner scanner, Stream stream, string file) { // Files can be protected in multiple ways - var protections = new Dictionary>(); + var protections = new ConcurrentDictionary>(); // Load the current file content byte[] fileContent = null; @@ -86,7 +88,7 @@ namespace BurnOutSharp.FileType stream.Seek(0, SeekOrigin.Begin); // Iterate through all content checks - foreach (var contentCheckClass in contentCheckClasses) + Parallel.ForEach(contentCheckClasses, contentCheckClass => { string protection = contentCheckClass.CheckContents(file, fileContent, scanner.IncludePosition); @@ -108,7 +110,7 @@ namespace BurnOutSharp.FileType Utilities.AppendToDictionary(protections, subProtections); } } - } + }); return protections; } diff --git a/BurnOutSharp/FileType/GZIP.cs b/BurnOutSharp/FileType/GZIP.cs index 6bc4b766..a65a4ca6 100644 --- a/BurnOutSharp/FileType/GZIP.cs +++ b/BurnOutSharp/FileType/GZIP.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using SharpCompress.Archives; @@ -18,7 +19,7 @@ namespace BurnOutSharp.FileType } /// - public Dictionary> Scan(Scanner scanner, string file) + public ConcurrentDictionary> Scan(Scanner scanner, string file) { if (!File.Exists(file)) return null; @@ -30,7 +31,7 @@ namespace BurnOutSharp.FileType } /// - public Dictionary> Scan(Scanner scanner, Stream stream, string file) + public ConcurrentDictionary> Scan(Scanner scanner, Stream stream, string file) { // If the gzip file itself fails try diff --git a/BurnOutSharp/FileType/InstallShieldCAB.cs b/BurnOutSharp/FileType/InstallShieldCAB.cs index d0954846..70d464b5 100644 --- a/BurnOutSharp/FileType/InstallShieldCAB.cs +++ b/BurnOutSharp/FileType/InstallShieldCAB.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Text.RegularExpressions; @@ -18,7 +19,7 @@ namespace BurnOutSharp.FileType } /// - public Dictionary> Scan(Scanner scanner, string file) + public ConcurrentDictionary> Scan(Scanner scanner, string file) { if (!File.Exists(file)) return null; @@ -31,7 +32,7 @@ namespace BurnOutSharp.FileType // TODO: Add stream opening support /// - public Dictionary> Scan(Scanner scanner, Stream stream, string file) + public ConcurrentDictionary> Scan(Scanner scanner, Stream stream, string file) { // Get the name of the first cabinet file or header string directory = Path.GetDirectoryName(file); diff --git a/BurnOutSharp/FileType/MPQ.cs b/BurnOutSharp/FileType/MPQ.cs index 8d0b297c..8529d8b0 100644 --- a/BurnOutSharp/FileType/MPQ.cs +++ b/BurnOutSharp/FileType/MPQ.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using StormLibSharp; @@ -17,7 +18,7 @@ namespace BurnOutSharp.FileType } /// - public Dictionary> Scan(Scanner scanner, string file) + public ConcurrentDictionary> Scan(Scanner scanner, string file) { if (!File.Exists(file)) return null; @@ -30,7 +31,7 @@ namespace BurnOutSharp.FileType // TODO: Add stream opening support /// - public Dictionary> Scan(Scanner scanner, Stream stream, string file) + public ConcurrentDictionary> Scan(Scanner scanner, Stream stream, string file) { // If the mpq file itself fails try diff --git a/BurnOutSharp/FileType/MSI.cs b/BurnOutSharp/FileType/MSI.cs index 1d41b3b1..44d8ea30 100644 --- a/BurnOutSharp/FileType/MSI.cs +++ b/BurnOutSharp/FileType/MSI.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using WixToolset.Dtf.WindowsInstaller; @@ -17,7 +18,7 @@ namespace BurnOutSharp.FileType } /// - public Dictionary> Scan(Scanner scanner, string file) + public ConcurrentDictionary> Scan(Scanner scanner, string file) { if (!File.Exists(file)) return null; @@ -30,7 +31,7 @@ namespace BurnOutSharp.FileType // TODO: Add stream opening support /// - public Dictionary> Scan(Scanner scanner, Stream stream, string file) + public ConcurrentDictionary> Scan(Scanner scanner, Stream stream, string file) { // If the MSI file itself fails try diff --git a/BurnOutSharp/FileType/MicrosoftCAB.cs b/BurnOutSharp/FileType/MicrosoftCAB.cs index dc870976..310a9cd6 100644 --- a/BurnOutSharp/FileType/MicrosoftCAB.cs +++ b/BurnOutSharp/FileType/MicrosoftCAB.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using LibMSPackN; @@ -18,7 +19,7 @@ namespace BurnOutSharp.FileType } /// - public Dictionary> Scan(Scanner scanner, string file) + public ConcurrentDictionary> Scan(Scanner scanner, string file) { if (!File.Exists(file)) return null; @@ -31,7 +32,7 @@ namespace BurnOutSharp.FileType // TODO: Add stream opening support /// - public Dictionary> Scan(Scanner scanner, Stream stream, string file) + public ConcurrentDictionary> Scan(Scanner scanner, Stream stream, string file) { // If the cab file itself fails try diff --git a/BurnOutSharp/FileType/PKZIP.cs b/BurnOutSharp/FileType/PKZIP.cs index 6fba6ab2..04f4d891 100644 --- a/BurnOutSharp/FileType/PKZIP.cs +++ b/BurnOutSharp/FileType/PKZIP.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using SharpCompress.Archives; @@ -27,7 +28,7 @@ namespace BurnOutSharp.FileType } /// - public Dictionary> Scan(Scanner scanner, string file) + public ConcurrentDictionary> Scan(Scanner scanner, string file) { if (!File.Exists(file)) return null; @@ -39,7 +40,7 @@ namespace BurnOutSharp.FileType } /// - public Dictionary> Scan(Scanner scanner, Stream stream, string file) + public ConcurrentDictionary> Scan(Scanner scanner, Stream stream, string file) { // If the zip file itself fails try diff --git a/BurnOutSharp/FileType/RAR.cs b/BurnOutSharp/FileType/RAR.cs index f69e7c2c..5bb5dd60 100644 --- a/BurnOutSharp/FileType/RAR.cs +++ b/BurnOutSharp/FileType/RAR.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using SharpCompress.Archives; @@ -23,7 +24,7 @@ namespace BurnOutSharp.FileType } /// - public Dictionary> Scan(Scanner scanner, string file) + public ConcurrentDictionary> Scan(Scanner scanner, string file) { if (!File.Exists(file)) return null; @@ -35,7 +36,7 @@ namespace BurnOutSharp.FileType } /// - public Dictionary> Scan(Scanner scanner, Stream stream, string file) + public ConcurrentDictionary> Scan(Scanner scanner, Stream stream, string file) { // If the rar file itself fails try diff --git a/BurnOutSharp/FileType/SevenZip.cs b/BurnOutSharp/FileType/SevenZip.cs index 432bc6dd..fb750174 100644 --- a/BurnOutSharp/FileType/SevenZip.cs +++ b/BurnOutSharp/FileType/SevenZip.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using SharpCompress.Archives; @@ -18,7 +19,7 @@ namespace BurnOutSharp.FileType } /// - public Dictionary> Scan(Scanner scanner, string file) + public ConcurrentDictionary> Scan(Scanner scanner, string file) { if (!File.Exists(file)) return null; @@ -30,7 +31,7 @@ namespace BurnOutSharp.FileType } /// - public Dictionary> Scan(Scanner scanner, Stream stream, string file) + public ConcurrentDictionary> Scan(Scanner scanner, Stream stream, string file) { // If the 7-zip file itself fails try diff --git a/BurnOutSharp/FileType/TapeArchive.cs b/BurnOutSharp/FileType/TapeArchive.cs index 33fa41c2..853a1b4f 100644 --- a/BurnOutSharp/FileType/TapeArchive.cs +++ b/BurnOutSharp/FileType/TapeArchive.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using SharpCompress.Archives; @@ -21,7 +22,7 @@ namespace BurnOutSharp.FileType } /// - public Dictionary> Scan(Scanner scanner, string file) + public ConcurrentDictionary> Scan(Scanner scanner, string file) { if (!File.Exists(file)) return null; @@ -33,7 +34,7 @@ namespace BurnOutSharp.FileType } /// - public Dictionary> Scan(Scanner scanner, Stream stream, string file) + public ConcurrentDictionary> Scan(Scanner scanner, Stream stream, string file) { // If the tar file itself fails try diff --git a/BurnOutSharp/FileType/Textfile.cs b/BurnOutSharp/FileType/Textfile.cs index 806402b9..63fd1023 100644 --- a/BurnOutSharp/FileType/Textfile.cs +++ b/BurnOutSharp/FileType/Textfile.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Text; @@ -45,7 +46,7 @@ namespace BurnOutSharp.FileType } /// - public Dictionary> Scan(Scanner scanner, string file) + public ConcurrentDictionary> Scan(Scanner scanner, string file) { if (!File.Exists(file)) return null; @@ -57,10 +58,10 @@ namespace BurnOutSharp.FileType } /// - public Dictionary> Scan(Scanner scanner, Stream stream, string file) + public ConcurrentDictionary> Scan(Scanner scanner, Stream stream, string file) { // Files can be protected in multiple ways - var protections = new Dictionary>(); + var protections = new ConcurrentDictionary>(); try { diff --git a/BurnOutSharp/FileType/Valve.cs b/BurnOutSharp/FileType/Valve.cs index 3f3ea846..f3e96882 100644 --- a/BurnOutSharp/FileType/Valve.cs +++ b/BurnOutSharp/FileType/Valve.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Runtime.InteropServices; @@ -34,7 +35,7 @@ namespace BurnOutSharp.FileType } /// - public Dictionary> Scan(Scanner scanner, string file) + public ConcurrentDictionary> Scan(Scanner scanner, string file) { if (!File.Exists(file)) return null; @@ -47,7 +48,7 @@ namespace BurnOutSharp.FileType // TODO: Add stream opening support /// - public Dictionary> Scan(Scanner scanner, Stream stream, string file) + public ConcurrentDictionary> Scan(Scanner scanner, Stream stream, string file) { string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); Directory.CreateDirectory(tempPath); diff --git a/BurnOutSharp/FileType/XZ.cs b/BurnOutSharp/FileType/XZ.cs index c9aaa33c..05365f14 100644 --- a/BurnOutSharp/FileType/XZ.cs +++ b/BurnOutSharp/FileType/XZ.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using SharpCompress.Compressors.Xz; @@ -17,7 +18,7 @@ namespace BurnOutSharp.FileType } /// - public Dictionary> Scan(Scanner scanner, string file) + public ConcurrentDictionary> Scan(Scanner scanner, string file) { if (!File.Exists(file)) return null; @@ -29,7 +30,7 @@ namespace BurnOutSharp.FileType } /// - public Dictionary> Scan(Scanner scanner, Stream stream, string file) + public ConcurrentDictionary> Scan(Scanner scanner, Stream stream, string file) { // If the xz file itself fails try diff --git a/BurnOutSharp/IPathCheck.cs b/BurnOutSharp/IPathCheck.cs index 94e50d62..e296612e 100644 --- a/BurnOutSharp/IPathCheck.cs +++ b/BurnOutSharp/IPathCheck.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Collections.Generic; namespace BurnOutSharp { @@ -10,7 +11,7 @@ namespace BurnOutSharp /// Path to check for protection indicators /// Enumerable of strings representing files in a directory /// This can do some limited content checking as well, but it's suggested to use IContentCheck instead, if possible - List CheckDirectoryPath(string path, IEnumerable files); + ConcurrentQueue CheckDirectoryPath(string path, IEnumerable files); /// /// Check a file path for protections based on path name diff --git a/BurnOutSharp/IScannable.cs b/BurnOutSharp/IScannable.cs index f30d9fa0..5501ff9a 100644 --- a/BurnOutSharp/IScannable.cs +++ b/BurnOutSharp/IScannable.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Concurrent; using System.IO; namespace BurnOutSharp @@ -19,7 +19,7 @@ namespace BurnOutSharp /// Path to the input file /// Dictionary mapping paths to protection lists /// Ideally, this should just point to the other scan implementation - Dictionary> Scan(Scanner scanner, string file); + ConcurrentDictionary> Scan(Scanner scanner, string file); /// /// Scan a stream for all internal protections @@ -28,6 +28,6 @@ namespace BurnOutSharp /// Stream representing the input file /// Path to the input file /// Dictionary mapping paths to protection lists - Dictionary> Scan(Scanner scanner, Stream stream, string filename); + ConcurrentDictionary> Scan(Scanner scanner, Stream stream, string filename); } } diff --git a/BurnOutSharp/Matching/MatchUtil.cs b/BurnOutSharp/Matching/MatchUtil.cs index 3fec7fdd..0b3e78d0 100644 --- a/BurnOutSharp/Matching/MatchUtil.cs +++ b/BurnOutSharp/Matching/MatchUtil.cs @@ -1,3 +1,4 @@ +using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; @@ -18,7 +19,7 @@ namespace BurnOutSharp.Matching /// Enumerable of ContentMatchSets to be run on the file /// True to include positional data, false otherwise /// List of strings representing the matched protections, null or empty otherwise - public static List GetAllMatches( + public static ConcurrentQueue GetAllMatches( string file, byte[] fileContent, IEnumerable matchers, @@ -57,7 +58,7 @@ namespace BurnOutSharp.Matching /// True to include positional data, false otherwise /// True to stop after the first match, false otherwise /// List of strings representing the matched protections, null or empty otherwise - private static List FindAllMatches( + private static ConcurrentQueue FindAllMatches( string file, byte[] fileContent, IEnumerable matchers, @@ -68,8 +69,8 @@ namespace BurnOutSharp.Matching if (matchers == null || !matchers.Any()) return null; - // Initialize the list of matched protections - List matchedProtections = new List(); + // Initialize the queue of matched protections + var matchedProtections = new ConcurrentQueue(); // Loop through and try everything otherwise foreach (var matcher in matchers) @@ -85,7 +86,7 @@ namespace BurnOutSharp.Matching // If we there is no version method, just return the protection name if (matcher.GetVersion == null) { - matchedProtections.Add((matcher.ProtectionName ?? "Unknown Protection") + (includePosition ? $" (Index {positionsString})" : string.Empty)); + matchedProtections.Enqueue((matcher.ProtectionName ?? "Unknown Protection") + (includePosition ? $" (Index {positionsString})" : string.Empty)); } // Otherwise, invoke the version method @@ -96,7 +97,7 @@ namespace BurnOutSharp.Matching if (version == null) continue; - matchedProtections.Add($"{matcher.ProtectionName ?? "Unknown Protection"} {version}".TrimEnd() + (includePosition ? $" (Index {positionsString})" : string.Empty)); + matchedProtections.Enqueue($"{matcher.ProtectionName ?? "Unknown Protection"} {version}".TrimEnd() + (includePosition ? $" (Index {positionsString})" : string.Empty)); } // If we're stopping after the first protection, bail out here @@ -118,7 +119,7 @@ namespace BurnOutSharp.Matching /// Enumerable of PathMatchSets to be run on the file /// True if any path match is a success, false if all have to match /// List of strings representing the matched protections, null or empty otherwise - public static List GetAllMatches(string file, IEnumerable matchers, bool any = false) + public static ConcurrentQueue GetAllMatches(string file, IEnumerable matchers, bool any = false) { return FindAllMatches(new List { file }, matchers, any, false); } @@ -130,7 +131,7 @@ namespace BurnOutSharp.Matching /// Enumerable of PathMatchSets to be run on the file /// True if any path match is a success, false if all have to match /// List of strings representing the matched protections, null or empty otherwise - public static List GetAllMatches(IEnumerable files, IEnumerable matchers, bool any = false) + public static ConcurrentQueue GetAllMatches(IEnumerable files, IEnumerable matchers, bool any = false) { return FindAllMatches(files, matchers, any, false); } @@ -175,14 +176,14 @@ namespace BurnOutSharp.Matching /// True if any path match is a success, false if all have to match /// True to stop after the first match, false otherwise /// List of strings representing the matched protections, null or empty otherwise - private static List FindAllMatches(IEnumerable files, IEnumerable matchers, bool any, bool stopAfterFirst) + private static ConcurrentQueue FindAllMatches(IEnumerable files, IEnumerable matchers, bool any, bool stopAfterFirst) { // If there's no mappings, we can't match if (matchers == null || !matchers.Any()) - return new List(); + return new ConcurrentQueue(); // Initialize the list of matched protections - List matchedProtections = new List(); + var matchedProtections = new ConcurrentQueue(); // Loop through and try everything otherwise foreach (var matcher in matchers) @@ -210,7 +211,7 @@ namespace BurnOutSharp.Matching // If we there is no version method, just return the protection name if (matcher.GetVersion == null) { - matchedProtections.Add(matcher.ProtectionName ?? "Unknown Protection"); + matchedProtections.Enqueue(matcher.ProtectionName ?? "Unknown Protection"); } // Otherwise, invoke the version method @@ -221,7 +222,7 @@ namespace BurnOutSharp.Matching if (version == null) continue; - matchedProtections.Add($"{matcher.ProtectionName ?? "Unknown Protection"} {version}".TrimEnd()); + matchedProtections.Enqueue($"{matcher.ProtectionName ?? "Unknown Protection"} {version}".TrimEnd()); } // If we're stopping after the first protection, bail out here diff --git a/BurnOutSharp/PackerType/CExe.cs b/BurnOutSharp/PackerType/CExe.cs index b81fee90..baf4ec7b 100644 --- a/BurnOutSharp/PackerType/CExe.cs +++ b/BurnOutSharp/PackerType/CExe.cs @@ -1,3 +1,4 @@ +using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using BurnOutSharp.Matching; @@ -33,7 +34,7 @@ namespace BurnOutSharp.PackerType } /// - public Dictionary> Scan(Scanner scanner, string file) + public ConcurrentDictionary> Scan(Scanner scanner, string file) { if (!File.Exists(file)) return null; @@ -46,7 +47,7 @@ namespace BurnOutSharp.PackerType /// // TODO: Add extraction if viable - public Dictionary> Scan(Scanner scanner, Stream stream, string file) + public ConcurrentDictionary> Scan(Scanner scanner, Stream stream, string file) { return null; } diff --git a/BurnOutSharp/PackerType/InnoSetup.cs b/BurnOutSharp/PackerType/InnoSetup.cs index e833d41c..9b55378d 100644 --- a/BurnOutSharp/PackerType/InnoSetup.cs +++ b/BurnOutSharp/PackerType/InnoSetup.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Linq; @@ -36,7 +37,7 @@ namespace BurnOutSharp.PackerType } /// - public Dictionary> Scan(Scanner scanner, string file) + public ConcurrentDictionary> Scan(Scanner scanner, string file) { if (!File.Exists(file)) return null; @@ -50,7 +51,7 @@ namespace BurnOutSharp.PackerType // TOOO: Add Inno Setup extraction // https://github.com/dscharrer/InnoExtract /// - public Dictionary> Scan(Scanner scanner, Stream stream, string file) + public ConcurrentDictionary> Scan(Scanner scanner, Stream stream, string file) { return null; } diff --git a/BurnOutSharp/PackerType/InstallerVISE.cs b/BurnOutSharp/PackerType/InstallerVISE.cs index 15957b36..11debac7 100644 --- a/BurnOutSharp/PackerType/InstallerVISE.cs +++ b/BurnOutSharp/PackerType/InstallerVISE.cs @@ -1,3 +1,4 @@ +using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using BurnOutSharp.Matching; @@ -28,7 +29,7 @@ namespace BurnOutSharp.PackerType // TODO: Add Installer VISE extraction // https://github.com/Bioruebe/UniExtract2 /// - public Dictionary> Scan(Scanner scanner, string file) + public ConcurrentDictionary> Scan(Scanner scanner, string file) { if (!File.Exists(file)) return null; @@ -40,7 +41,7 @@ namespace BurnOutSharp.PackerType } /// - public Dictionary> Scan(Scanner scanner, Stream stream, string file) + public ConcurrentDictionary> Scan(Scanner scanner, Stream stream, string file) { return null; } diff --git a/BurnOutSharp/PackerType/SetupFactory.cs b/BurnOutSharp/PackerType/SetupFactory.cs index 9331bb34..7bd54a12 100644 --- a/BurnOutSharp/PackerType/SetupFactory.cs +++ b/BurnOutSharp/PackerType/SetupFactory.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Collections.Generic; using System.IO; using BurnOutSharp.Matching; @@ -48,7 +49,7 @@ namespace BurnOutSharp.PackerType } /// - public Dictionary> Scan(Scanner scanner, string file) + public ConcurrentDictionary> Scan(Scanner scanner, string file) { if (!File.Exists(file)) return null; @@ -62,7 +63,7 @@ namespace BurnOutSharp.PackerType /// // TODO: Add extraction, which is possible but the only tools available that can // do this seem to be Universal Extractor 2 and InstallExplorer (https://totalcmd.net/plugring/InstallExplorer.html) - public Dictionary> Scan(Scanner scanner, Stream stream, string file) + public ConcurrentDictionary> Scan(Scanner scanner, Stream stream, string file) { return null; } diff --git a/BurnOutSharp/PackerType/WinRARSFX.cs b/BurnOutSharp/PackerType/WinRARSFX.cs index 3c3db7dc..2190712f 100644 --- a/BurnOutSharp/PackerType/WinRARSFX.cs +++ b/BurnOutSharp/PackerType/WinRARSFX.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using BurnOutSharp.Matching; @@ -29,7 +30,7 @@ namespace BurnOutSharp.PackerType return MatchUtil.GetFirstMatch(file, fileContent, matchers, includePosition); } - public Dictionary> Scan(Scanner scanner, string file) + public ConcurrentDictionary> Scan(Scanner scanner, string file) { if (!File.Exists(file)) return null; @@ -41,7 +42,7 @@ namespace BurnOutSharp.PackerType } /// - public Dictionary> Scan(Scanner scanner, Stream stream, string file) + public ConcurrentDictionary> Scan(Scanner scanner, Stream stream, string file) { // If the rar file itself fails try diff --git a/BurnOutSharp/PackerType/WinZipSFX.cs b/BurnOutSharp/PackerType/WinZipSFX.cs index 6c43a998..dc0c6a0b 100644 --- a/BurnOutSharp/PackerType/WinZipSFX.cs +++ b/BurnOutSharp/PackerType/WinZipSFX.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using BurnOutSharp.Matching; @@ -35,7 +36,7 @@ namespace BurnOutSharp.PackerType // TODO: Find a way to generically detect 2.X versions and improve exact version detection for SFX PE versions bundled with WinZip 11+ /// - public Dictionary> Scan(Scanner scanner, string file) + public ConcurrentDictionary> Scan(Scanner scanner, string file) { if (!File.Exists(file)) return null; @@ -47,7 +48,7 @@ namespace BurnOutSharp.PackerType } /// - public Dictionary> Scan(Scanner scanner, Stream stream, string file) + public ConcurrentDictionary> Scan(Scanner scanner, Stream stream, string file) { // If the zip file itself fails try diff --git a/BurnOutSharp/PackerType/WiseInstaller.cs b/BurnOutSharp/PackerType/WiseInstaller.cs index 9ffa58d8..09d09724 100644 --- a/BurnOutSharp/PackerType/WiseInstaller.cs +++ b/BurnOutSharp/PackerType/WiseInstaller.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using BurnOutSharp.Matching; @@ -24,7 +25,7 @@ namespace BurnOutSharp.PackerType } /// - public Dictionary> Scan(Scanner scanner, string file) + public ConcurrentDictionary> Scan(Scanner scanner, string file) { if (!File.Exists(file)) return null; @@ -36,7 +37,7 @@ namespace BurnOutSharp.PackerType } /// - public Dictionary> Scan(Scanner scanner, Stream stream, string file) + public ConcurrentDictionary> Scan(Scanner scanner, Stream stream, string file) { // If the installer file itself fails try diff --git a/BurnOutSharp/ProtectionType/AACS.cs b/BurnOutSharp/ProtectionType/AACS.cs index 5a265428..13edf034 100644 --- a/BurnOutSharp/ProtectionType/AACS.cs +++ b/BurnOutSharp/ProtectionType/AACS.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Collections.Generic; using System.IO; using BurnOutSharp.Matching; @@ -7,7 +8,7 @@ namespace BurnOutSharp.ProtectionType public class AACS : IPathCheck { /// - public List CheckDirectoryPath(string path, IEnumerable files) + public ConcurrentQueue CheckDirectoryPath(string path, IEnumerable files) { var matchers = new List { diff --git a/BurnOutSharp/ProtectionType/AlphaDVD.cs b/BurnOutSharp/ProtectionType/AlphaDVD.cs index fa4485b6..7e6e4c56 100644 --- a/BurnOutSharp/ProtectionType/AlphaDVD.cs +++ b/BurnOutSharp/ProtectionType/AlphaDVD.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Collections.Generic; using BurnOutSharp.Matching; namespace BurnOutSharp.ProtectionType @@ -6,7 +7,7 @@ namespace BurnOutSharp.ProtectionType public class AlphaDVD : IPathCheck { /// - public List CheckDirectoryPath(string path, IEnumerable files) + public ConcurrentQueue CheckDirectoryPath(string path, IEnumerable files) { var matchers = new List { diff --git a/BurnOutSharp/ProtectionType/BDPlus.cs b/BurnOutSharp/ProtectionType/BDPlus.cs index e69ce8d5..69337e39 100644 --- a/BurnOutSharp/ProtectionType/BDPlus.cs +++ b/BurnOutSharp/ProtectionType/BDPlus.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Linq; @@ -9,7 +10,7 @@ namespace BurnOutSharp.ProtectionType public class BDPlus : IPathCheck { /// - public List CheckDirectoryPath(string path, IEnumerable files) + public ConcurrentQueue CheckDirectoryPath(string path, IEnumerable files) { var matchers = new List { diff --git a/BurnOutSharp/ProtectionType/Bitpool.cs b/BurnOutSharp/ProtectionType/Bitpool.cs index 62c220d9..b467c2b7 100644 --- a/BurnOutSharp/ProtectionType/Bitpool.cs +++ b/BurnOutSharp/ProtectionType/Bitpool.cs @@ -1,5 +1,6 @@ -using BurnOutSharp.Matching; +using System.Collections.Concurrent; using System.Collections.Generic; +using BurnOutSharp.Matching; namespace BurnOutSharp.ProtectionType { @@ -29,7 +30,7 @@ namespace BurnOutSharp.ProtectionType } /// - public List CheckDirectoryPath(string path, IEnumerable files) + public ConcurrentQueue CheckDirectoryPath(string path, IEnumerable files) { var matchers = new List { diff --git a/BurnOutSharp/ProtectionType/ByteShield.cs b/BurnOutSharp/ProtectionType/ByteShield.cs index f2810ffb..74b6d717 100644 --- a/BurnOutSharp/ProtectionType/ByteShield.cs +++ b/BurnOutSharp/ProtectionType/ByteShield.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Collections.Generic; using BurnOutSharp.Matching; namespace BurnOutSharp.ProtectionType @@ -6,7 +7,7 @@ namespace BurnOutSharp.ProtectionType public class ByteShield : IPathCheck { /// - public List CheckDirectoryPath(string path, IEnumerable files) + public ConcurrentQueue CheckDirectoryPath(string path, IEnumerable files) { var matchers = new List { diff --git a/BurnOutSharp/ProtectionType/CDCops.cs b/BurnOutSharp/ProtectionType/CDCops.cs index acb2ae08..a777e904 100644 --- a/BurnOutSharp/ProtectionType/CDCops.cs +++ b/BurnOutSharp/ProtectionType/CDCops.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using BurnOutSharp.Matching; @@ -27,7 +28,7 @@ namespace BurnOutSharp.ProtectionType } /// - public List CheckDirectoryPath(string path, IEnumerable files) + public ConcurrentQueue CheckDirectoryPath(string path, IEnumerable files) { // TODO: Original had "CDCOPS.DLL" required and all the rest in a combined OR var matchers = new List diff --git a/BurnOutSharp/ProtectionType/CDLock.cs b/BurnOutSharp/ProtectionType/CDLock.cs index e1aef99c..348c7c30 100644 --- a/BurnOutSharp/ProtectionType/CDLock.cs +++ b/BurnOutSharp/ProtectionType/CDLock.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Collections.Generic; using BurnOutSharp.Matching; namespace BurnOutSharp.ProtectionType @@ -24,7 +25,7 @@ namespace BurnOutSharp.ProtectionType } /// - public List CheckDirectoryPath(string path, IEnumerable files) + public ConcurrentQueue CheckDirectoryPath(string path, IEnumerable files) { var matchers = new List { diff --git a/BurnOutSharp/ProtectionType/CDProtector.cs b/BurnOutSharp/ProtectionType/CDProtector.cs index 57a3a9d4..4bcf1639 100644 --- a/BurnOutSharp/ProtectionType/CDProtector.cs +++ b/BurnOutSharp/ProtectionType/CDProtector.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Collections.Generic; using BurnOutSharp.Matching; namespace BurnOutSharp.ProtectionType @@ -6,7 +7,7 @@ namespace BurnOutSharp.ProtectionType public class CDProtector : IPathCheck { /// - public List CheckDirectoryPath(string path, IEnumerable files) + public ConcurrentQueue CheckDirectoryPath(string path, IEnumerable files) { // TODO: Verify if these are OR or AND var matchers = new List diff --git a/BurnOutSharp/ProtectionType/CDX.cs b/BurnOutSharp/ProtectionType/CDX.cs index 76a9b70c..7ed6fba4 100644 --- a/BurnOutSharp/ProtectionType/CDX.cs +++ b/BurnOutSharp/ProtectionType/CDX.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Collections.Generic; using BurnOutSharp.Matching; namespace BurnOutSharp.ProtectionType @@ -6,7 +7,7 @@ namespace BurnOutSharp.ProtectionType public class CDX : IPathCheck { /// - public List CheckDirectoryPath(string path, IEnumerable files) + public ConcurrentQueue CheckDirectoryPath(string path, IEnumerable files) { // TODO: Verify if these are OR or AND var matchers = new List diff --git a/BurnOutSharp/ProtectionType/CactusDataShield.cs b/BurnOutSharp/ProtectionType/CactusDataShield.cs index ac13e5ae..3bd08851 100644 --- a/BurnOutSharp/ProtectionType/CactusDataShield.cs +++ b/BurnOutSharp/ProtectionType/CactusDataShield.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Linq; @@ -28,7 +29,7 @@ namespace BurnOutSharp.ProtectionType } /// - public List CheckDirectoryPath(string path, IEnumerable files) + public ConcurrentQueue CheckDirectoryPath(string path, IEnumerable files) { // TODO: Verify if these are OR or AND var matchers = new List diff --git a/BurnOutSharp/ProtectionType/CopyKiller.cs b/BurnOutSharp/ProtectionType/CopyKiller.cs index e4ebdb64..8f6c0d04 100644 --- a/BurnOutSharp/ProtectionType/CopyKiller.cs +++ b/BurnOutSharp/ProtectionType/CopyKiller.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Collections.Generic; using BurnOutSharp.Matching; namespace BurnOutSharp.ProtectionType @@ -22,7 +23,7 @@ namespace BurnOutSharp.ProtectionType } /// - public List CheckDirectoryPath(string path, IEnumerable files) + public ConcurrentQueue CheckDirectoryPath(string path, IEnumerable files) { // TODO: The following checks are overly broad and should be refined var matchers = new List diff --git a/BurnOutSharp/ProtectionType/DVDCrypt.cs b/BurnOutSharp/ProtectionType/DVDCrypt.cs index 776ff8bc..c77b4993 100644 --- a/BurnOutSharp/ProtectionType/DVDCrypt.cs +++ b/BurnOutSharp/ProtectionType/DVDCrypt.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Collections.Generic; using BurnOutSharp.Matching; namespace BurnOutSharp.ProtectionType @@ -6,7 +7,7 @@ namespace BurnOutSharp.ProtectionType public class DVDCrypt : IPathCheck { /// - public List CheckDirectoryPath(string path, IEnumerable files) + public ConcurrentQueue CheckDirectoryPath(string path, IEnumerable files) { var matchers = new List { diff --git a/BurnOutSharp/ProtectionType/DVDMoviePROTECT.cs b/BurnOutSharp/ProtectionType/DVDMoviePROTECT.cs index 554fca9a..a686e3e9 100644 --- a/BurnOutSharp/ProtectionType/DVDMoviePROTECT.cs +++ b/BurnOutSharp/ProtectionType/DVDMoviePROTECT.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Collections.Generic; using System.IO; using System.Linq; @@ -8,8 +9,10 @@ namespace BurnOutSharp.ProtectionType public class DVDMoviePROTECT : IPathCheck { /// - public List CheckDirectoryPath(string path, IEnumerable files) + public ConcurrentQueue CheckDirectoryPath(string path, IEnumerable files) { + var protections = new ConcurrentQueue(); + if (Directory.Exists(Path.Combine(path, "VIDEO_TS"))) { string[] bupfiles = files.Where(s => s.EndsWith(".bup")).ToArray(); @@ -18,11 +21,14 @@ namespace BurnOutSharp.ProtectionType FileInfo bupfile = new FileInfo(bupfiles[i]); FileInfo ifofile = new FileInfo(Path.Combine(bupfile.DirectoryName, bupfile.Name.Substring(0, bupfile.Name.Length - bupfile.Extension.Length) + ".ifo")); if (bupfile.Length != ifofile.Length) - return new List() { "DVD-Movie-PROTECT" }; + { + protections.Enqueue("DVD-Movie-PROTECT"); + break; + } } } - return null; + return protections; } /// diff --git a/BurnOutSharp/ProtectionType/DiscGuard.cs b/BurnOutSharp/ProtectionType/DiscGuard.cs index 076491dd..70643bc3 100644 --- a/BurnOutSharp/ProtectionType/DiscGuard.cs +++ b/BurnOutSharp/ProtectionType/DiscGuard.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Collections.Generic; using BurnOutSharp.Matching; namespace BurnOutSharp.ProtectionType @@ -6,7 +7,7 @@ namespace BurnOutSharp.ProtectionType public class DiscGuard : IPathCheck { /// - public List CheckDirectoryPath(string path, IEnumerable files) + public ConcurrentQueue CheckDirectoryPath(string path, IEnumerable files) { var matchers = new List { diff --git a/BurnOutSharp/ProtectionType/FreeLock.cs b/BurnOutSharp/ProtectionType/FreeLock.cs index 2f44e46d..28a4a4e5 100644 --- a/BurnOutSharp/ProtectionType/FreeLock.cs +++ b/BurnOutSharp/ProtectionType/FreeLock.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Collections.Generic; using BurnOutSharp.Matching; namespace BurnOutSharp.ProtectionType @@ -6,7 +7,7 @@ namespace BurnOutSharp.ProtectionType public class FreeLock : IPathCheck { /// - public List CheckDirectoryPath(string path, IEnumerable files) + public ConcurrentQueue CheckDirectoryPath(string path, IEnumerable files) { var matchers = new List { diff --git a/BurnOutSharp/ProtectionType/GFWL.cs b/BurnOutSharp/ProtectionType/GFWL.cs index 0a3b4d84..53386738 100644 --- a/BurnOutSharp/ProtectionType/GFWL.cs +++ b/BurnOutSharp/ProtectionType/GFWL.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Collections.Generic; using BurnOutSharp.Matching; namespace BurnOutSharp.ProtectionType @@ -18,7 +19,7 @@ namespace BurnOutSharp.ProtectionType } /// - public List CheckDirectoryPath(string path, IEnumerable files) + public ConcurrentQueue CheckDirectoryPath(string path, IEnumerable files) { var matchers = new List { diff --git a/BurnOutSharp/ProtectionType/HexalockAutoLock.cs b/BurnOutSharp/ProtectionType/HexalockAutoLock.cs index 88bad64b..2ab30ba9 100644 --- a/BurnOutSharp/ProtectionType/HexalockAutoLock.cs +++ b/BurnOutSharp/ProtectionType/HexalockAutoLock.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Collections.Generic; using BurnOutSharp.Matching; namespace BurnOutSharp.ProtectionType @@ -6,7 +7,7 @@ namespace BurnOutSharp.ProtectionType public class HexalockAutoLock : IPathCheck { /// - public List CheckDirectoryPath(string path, IEnumerable files) + public ConcurrentQueue CheckDirectoryPath(string path, IEnumerable files) { // TODO: Verify if these are OR or AND var matchers = new List diff --git a/BurnOutSharp/ProtectionType/ImpulseReactor.cs b/BurnOutSharp/ProtectionType/ImpulseReactor.cs index 400e0897..c566e370 100644 --- a/BurnOutSharp/ProtectionType/ImpulseReactor.cs +++ b/BurnOutSharp/ProtectionType/ImpulseReactor.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Collections.Generic; using BurnOutSharp.Matching; namespace BurnOutSharp.ProtectionType @@ -45,7 +46,7 @@ namespace BurnOutSharp.ProtectionType } /// - public List CheckDirectoryPath(string path, IEnumerable files) + public ConcurrentQueue CheckDirectoryPath(string path, IEnumerable files) { var matchers = new List { diff --git a/BurnOutSharp/ProtectionType/IndyVCD.cs b/BurnOutSharp/ProtectionType/IndyVCD.cs index 3fc6f2ca..4ed993df 100644 --- a/BurnOutSharp/ProtectionType/IndyVCD.cs +++ b/BurnOutSharp/ProtectionType/IndyVCD.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Collections.Generic; using BurnOutSharp.Matching; namespace BurnOutSharp.ProtectionType @@ -6,7 +7,7 @@ namespace BurnOutSharp.ProtectionType public class IndyVCD : IPathCheck { /// - public List CheckDirectoryPath(string path, IEnumerable files) + public ConcurrentQueue CheckDirectoryPath(string path, IEnumerable files) { // TODO: Verify if these are OR or AND var matchers = new List diff --git a/BurnOutSharp/ProtectionType/Key2AudioXS.cs b/BurnOutSharp/ProtectionType/Key2AudioXS.cs index 639e371d..36298365 100644 --- a/BurnOutSharp/ProtectionType/Key2AudioXS.cs +++ b/BurnOutSharp/ProtectionType/Key2AudioXS.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Collections.Generic; using BurnOutSharp.Matching; namespace BurnOutSharp.ProtectionType @@ -6,7 +7,7 @@ namespace BurnOutSharp.ProtectionType public class Key2AudioXS : IPathCheck { /// - public List CheckDirectoryPath(string path, IEnumerable files) + public ConcurrentQueue CheckDirectoryPath(string path, IEnumerable files) { // TODO: Verify if these are OR or AND var matchers = new List diff --git a/BurnOutSharp/ProtectionType/LaserLock.cs b/BurnOutSharp/ProtectionType/LaserLock.cs index 120240a1..9d0d5bc7 100644 --- a/BurnOutSharp/ProtectionType/LaserLock.cs +++ b/BurnOutSharp/ProtectionType/LaserLock.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Linq; @@ -62,7 +63,7 @@ namespace BurnOutSharp.ProtectionType } /// - public List CheckDirectoryPath(string path, IEnumerable files) + public ConcurrentQueue CheckDirectoryPath(string path, IEnumerable files) { var matchers = new List { diff --git a/BurnOutSharp/ProtectionType/MediaCloQ.cs b/BurnOutSharp/ProtectionType/MediaCloQ.cs index 21a425d2..08cc0643 100644 --- a/BurnOutSharp/ProtectionType/MediaCloQ.cs +++ b/BurnOutSharp/ProtectionType/MediaCloQ.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Collections.Generic; using BurnOutSharp.Matching; namespace BurnOutSharp.ProtectionType @@ -6,7 +7,7 @@ namespace BurnOutSharp.ProtectionType public class MediaCloQ : IPathCheck { /// - public List CheckDirectoryPath(string path, IEnumerable files) + public ConcurrentQueue CheckDirectoryPath(string path, IEnumerable files) { var matchers = new List { diff --git a/BurnOutSharp/ProtectionType/MediaMaxCD3.cs b/BurnOutSharp/ProtectionType/MediaMaxCD3.cs index 8994278c..614ef7c5 100644 --- a/BurnOutSharp/ProtectionType/MediaMaxCD3.cs +++ b/BurnOutSharp/ProtectionType/MediaMaxCD3.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Collections.Generic; using BurnOutSharp.Matching; namespace BurnOutSharp.ProtectionType @@ -25,7 +26,7 @@ namespace BurnOutSharp.ProtectionType } /// - public List CheckDirectoryPath(string path, IEnumerable files) + public ConcurrentQueue CheckDirectoryPath(string path, IEnumerable files) { var matchers = new List { diff --git a/BurnOutSharp/ProtectionType/Origin.cs b/BurnOutSharp/ProtectionType/Origin.cs index 37a7b37c..acfd0025 100644 --- a/BurnOutSharp/ProtectionType/Origin.cs +++ b/BurnOutSharp/ProtectionType/Origin.cs @@ -1,3 +1,4 @@ +using System.Collections.Concurrent; using System.Collections.Generic; using BurnOutSharp.Matching; @@ -18,7 +19,7 @@ namespace BurnOutSharp.ProtectionType } /// - public List CheckDirectoryPath(string path, IEnumerable files) + public ConcurrentQueue CheckDirectoryPath(string path, IEnumerable files) { var matchers = new List { diff --git a/BurnOutSharp/ProtectionType/ProtectDVDVideo.cs b/BurnOutSharp/ProtectionType/ProtectDVDVideo.cs index fb2a9267..6b08ac10 100644 --- a/BurnOutSharp/ProtectionType/ProtectDVDVideo.cs +++ b/BurnOutSharp/ProtectionType/ProtectDVDVideo.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Collections.Generic; using System.IO; using System.Linq; @@ -8,8 +9,10 @@ namespace BurnOutSharp.ProtectionType public class ProtectDVDVideo : IPathCheck { /// - public List CheckDirectoryPath(string path, IEnumerable files) + public ConcurrentQueue CheckDirectoryPath(string path, IEnumerable files) { + var protections = new ConcurrentQueue(); + if (Directory.Exists(Path.Combine(path, "VIDEO_TS"))) { string[] ifofiles = files.Where(s => s.EndsWith(".ifo")).ToArray(); @@ -17,11 +20,14 @@ namespace BurnOutSharp.ProtectionType { FileInfo ifofile = new FileInfo(ifofiles[i]); if (ifofile.Length == 0) - return new List() { "Protect DVD-Video" }; + { + protections.Enqueue("Protect DVD-Video"); + break; + } } } - return null; + return protections; } /// diff --git a/BurnOutSharp/ProtectionType/SafeCast.cs b/BurnOutSharp/ProtectionType/SafeCast.cs index ca609f2a..96d39b30 100644 --- a/BurnOutSharp/ProtectionType/SafeCast.cs +++ b/BurnOutSharp/ProtectionType/SafeCast.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Collections.Generic; using BurnOutSharp.Matching; namespace BurnOutSharp.ProtectionType @@ -6,7 +7,7 @@ namespace BurnOutSharp.ProtectionType public class SafeCast : IPathCheck { /// - public List CheckDirectoryPath(string path, IEnumerable files) + public ConcurrentQueue CheckDirectoryPath(string path, IEnumerable files) { var matchers = new List { diff --git a/BurnOutSharp/ProtectionType/SafeDisc.cs b/BurnOutSharp/ProtectionType/SafeDisc.cs index 4bb3eb29..35c38238 100644 --- a/BurnOutSharp/ProtectionType/SafeDisc.cs +++ b/BurnOutSharp/ProtectionType/SafeDisc.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.IO; @@ -84,7 +85,7 @@ namespace BurnOutSharp.ProtectionType } /// - public List CheckDirectoryPath(string path, IEnumerable files) + public ConcurrentQueue CheckDirectoryPath(string path, IEnumerable files) { return MatchUtil.GetAllMatches(files, pathMatchers, any: false); } diff --git a/BurnOutSharp/ProtectionType/SafeDiscLite.cs b/BurnOutSharp/ProtectionType/SafeDiscLite.cs index 7a6c96b0..2a599434 100644 --- a/BurnOutSharp/ProtectionType/SafeDiscLite.cs +++ b/BurnOutSharp/ProtectionType/SafeDiscLite.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Collections.Generic; using BurnOutSharp.Matching; namespace BurnOutSharp.ProtectionType @@ -6,7 +7,7 @@ namespace BurnOutSharp.ProtectionType public class SafeDiscLite : IPathCheck { /// - public List CheckDirectoryPath(string path, IEnumerable files) + public ConcurrentQueue CheckDirectoryPath(string path, IEnumerable files) { var matchers = new List { diff --git a/BurnOutSharp/ProtectionType/SafeLock.cs b/BurnOutSharp/ProtectionType/SafeLock.cs index 08732593..0d5a1c03 100644 --- a/BurnOutSharp/ProtectionType/SafeLock.cs +++ b/BurnOutSharp/ProtectionType/SafeLock.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Collections.Generic; using BurnOutSharp.Matching; namespace BurnOutSharp.ProtectionType @@ -18,7 +19,7 @@ namespace BurnOutSharp.ProtectionType } /// - public List CheckDirectoryPath(string path, IEnumerable files) + public ConcurrentQueue CheckDirectoryPath(string path, IEnumerable files) { // TODO: Verify if these are OR or AND var matchers = new List diff --git a/BurnOutSharp/ProtectionType/SecuROM.cs b/BurnOutSharp/ProtectionType/SecuROM.cs index 186a42e0..12a3c7e1 100644 --- a/BurnOutSharp/ProtectionType/SecuROM.cs +++ b/BurnOutSharp/ProtectionType/SecuROM.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Text; using BurnOutSharp.Matching; @@ -56,7 +57,7 @@ namespace BurnOutSharp.ProtectionType } /// - public List CheckDirectoryPath(string path, IEnumerable files) + public ConcurrentQueue CheckDirectoryPath(string path, IEnumerable files) { var matchers = new List { diff --git a/BurnOutSharp/ProtectionType/SmartE.cs b/BurnOutSharp/ProtectionType/SmartE.cs index 3d5bfce7..26e72963 100644 --- a/BurnOutSharp/ProtectionType/SmartE.cs +++ b/BurnOutSharp/ProtectionType/SmartE.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Collections.Generic; using System.IO; using BurnOutSharp.Matching; @@ -19,7 +20,7 @@ namespace BurnOutSharp.ProtectionType } /// - public List CheckDirectoryPath(string path, IEnumerable files) + public ConcurrentQueue CheckDirectoryPath(string path, IEnumerable files) { // TODO: Verify if these are OR or AND var matchers = new List diff --git a/BurnOutSharp/ProtectionType/SoftLock.cs b/BurnOutSharp/ProtectionType/SoftLock.cs index 1dd5dcde..6a945a86 100644 --- a/BurnOutSharp/ProtectionType/SoftLock.cs +++ b/BurnOutSharp/ProtectionType/SoftLock.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Collections.Generic; using BurnOutSharp.Matching; namespace BurnOutSharp.ProtectionType @@ -6,7 +7,7 @@ namespace BurnOutSharp.ProtectionType public class SoftLock : IPathCheck { /// - public List CheckDirectoryPath(string path, IEnumerable files) + public ConcurrentQueue CheckDirectoryPath(string path, IEnumerable files) { // TODO: Verify if these are OR or AND var matchers = new List diff --git a/BurnOutSharp/ProtectionType/SolidShield.cs b/BurnOutSharp/ProtectionType/SolidShield.cs index 4be20abc..530faf45 100644 --- a/BurnOutSharp/ProtectionType/SolidShield.cs +++ b/BurnOutSharp/ProtectionType/SolidShield.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Linq; @@ -94,7 +95,7 @@ namespace BurnOutSharp.ProtectionType } /// - public List CheckDirectoryPath(string path, IEnumerable files) + public ConcurrentQueue CheckDirectoryPath(string path, IEnumerable files) { // TODO: Verify if these are OR or AND return MatchUtil.GetAllMatches(files, pathMatchers, any: true); diff --git a/BurnOutSharp/ProtectionType/StarForce.cs b/BurnOutSharp/ProtectionType/StarForce.cs index 205c9d33..e591ed8c 100644 --- a/BurnOutSharp/ProtectionType/StarForce.cs +++ b/BurnOutSharp/ProtectionType/StarForce.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Collections.Generic; using System.Linq; using BurnOutSharp.Matching; @@ -117,7 +118,7 @@ namespace BurnOutSharp.ProtectionType } /// - public List CheckDirectoryPath(string path, IEnumerable files) + public ConcurrentQueue CheckDirectoryPath(string path, IEnumerable files) { var matchers = new List { diff --git a/BurnOutSharp/ProtectionType/Steam.cs b/BurnOutSharp/ProtectionType/Steam.cs index 0659ae9c..901a1722 100644 --- a/BurnOutSharp/ProtectionType/Steam.cs +++ b/BurnOutSharp/ProtectionType/Steam.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Collections.Generic; using BurnOutSharp.Matching; namespace BurnOutSharp.ProtectionType @@ -6,7 +7,7 @@ namespace BurnOutSharp.ProtectionType public class Steam : IPathCheck { /// - public List CheckDirectoryPath(string path, IEnumerable files) + public ConcurrentQueue CheckDirectoryPath(string path, IEnumerable files) { var matchers = new List { diff --git a/BurnOutSharp/ProtectionType/TZCopyProtector.cs b/BurnOutSharp/ProtectionType/TZCopyProtector.cs index 7226d523..4cdddf24 100644 --- a/BurnOutSharp/ProtectionType/TZCopyProtector.cs +++ b/BurnOutSharp/ProtectionType/TZCopyProtector.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Collections.Generic; using BurnOutSharp.Matching; namespace BurnOutSharp.ProtectionType @@ -6,7 +7,7 @@ namespace BurnOutSharp.ProtectionType public class TZCopyProtector : IPathCheck { /// - public List CheckDirectoryPath(string path, IEnumerable files) + public ConcurrentQueue CheckDirectoryPath(string path, IEnumerable files) { var matchers = new List { diff --git a/BurnOutSharp/ProtectionType/Tages.cs b/BurnOutSharp/ProtectionType/Tages.cs index 877e5705..e69480c4 100644 --- a/BurnOutSharp/ProtectionType/Tages.cs +++ b/BurnOutSharp/ProtectionType/Tages.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Linq; @@ -39,30 +40,30 @@ namespace BurnOutSharp.ProtectionType } /// - public List CheckDirectoryPath(string path, IEnumerable files) + public ConcurrentQueue CheckDirectoryPath(string path, IEnumerable files) { - List protections = new List(); + var protections = new ConcurrentQueue(); // TODO: Verify if these are OR or AND if (files.Any(f => Path.GetFileName(f).Equals("Tages.dll", StringComparison.OrdinalIgnoreCase)) || files.Any(f => Path.GetFileName(f).Equals("Wave.aif", StringComparison.OrdinalIgnoreCase))) { - protections.Add("TAGES"); + protections.Enqueue("TAGES"); } if (files.Any(f => Path.GetFileName(f).Equals("tagesclient.exe", StringComparison.OrdinalIgnoreCase))) { string file = files.First(f => Path.GetFileName(f).Equals("tagesclient.exe", StringComparison.OrdinalIgnoreCase)); - protections.Add("TAGES Activation Client " + Utilities.GetFileVersion(file)); + protections.Enqueue("TAGES Activation Client " + Utilities.GetFileVersion(file)); } if (files.Any(f => Path.GetFileName(f).Equals("TagesSetup.exe", StringComparison.OrdinalIgnoreCase))) { string file = files.First(f => Path.GetFileName(f).Equals("TagesSetup.exe", StringComparison.OrdinalIgnoreCase)); - protections.Add("TAGES Setup " + Utilities.GetFileVersion(file)); + protections.Enqueue("TAGES Setup " + Utilities.GetFileVersion(file)); } if (files.Any(f => Path.GetFileName(f).Equals("TagesSetup_x64.exe", StringComparison.OrdinalIgnoreCase))) { string file = files.First(f => Path.GetFileName(f).Equals("TagesSetup_x64.exe", StringComparison.OrdinalIgnoreCase)); - protections.Add("TAGES Setup " + Utilities.GetFileVersion(file)); + protections.Enqueue("TAGES Setup " + Utilities.GetFileVersion(file)); } if (protections.Count == 0) diff --git a/BurnOutSharp/ProtectionType/TivolaRingProtection.cs b/BurnOutSharp/ProtectionType/TivolaRingProtection.cs index d6c352b9..9c8750e5 100644 --- a/BurnOutSharp/ProtectionType/TivolaRingProtection.cs +++ b/BurnOutSharp/ProtectionType/TivolaRingProtection.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Collections.Generic; using System.IO; using BurnOutSharp.Matching; @@ -10,7 +11,7 @@ namespace BurnOutSharp.ProtectionType public class TivolaRingProtection : IPathCheck { /// - public List CheckDirectoryPath(string path, IEnumerable files) + public ConcurrentQueue CheckDirectoryPath(string path, IEnumerable files) { var matchers = new List { diff --git a/BurnOutSharp/ProtectionType/Uplay.cs b/BurnOutSharp/ProtectionType/Uplay.cs index 5dc01d32..8bafff35 100644 --- a/BurnOutSharp/ProtectionType/Uplay.cs +++ b/BurnOutSharp/ProtectionType/Uplay.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Collections.Generic; using BurnOutSharp.Matching; namespace BurnOutSharp.ProtectionType @@ -6,7 +7,7 @@ namespace BurnOutSharp.ProtectionType public class Uplay : IPathCheck { /// - public List CheckDirectoryPath(string path, IEnumerable files) + public ConcurrentQueue CheckDirectoryPath(string path, IEnumerable files) { var matchers = new List { diff --git a/BurnOutSharp/ProtectionType/VOBProtectCDDVD.cs b/BurnOutSharp/ProtectionType/VOBProtectCDDVD.cs index f730f208..b1a863bd 100644 --- a/BurnOutSharp/ProtectionType/VOBProtectCDDVD.cs +++ b/BurnOutSharp/ProtectionType/VOBProtectCDDVD.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.IO; @@ -33,7 +34,7 @@ namespace BurnOutSharp.ProtectionType } /// - public List CheckDirectoryPath(string path, IEnumerable files) + public ConcurrentQueue CheckDirectoryPath(string path, IEnumerable files) { var matchers = new List { diff --git a/BurnOutSharp/ProtectionType/WTMCDProtect.cs b/BurnOutSharp/ProtectionType/WTMCDProtect.cs index ca704fa4..475a8059 100644 --- a/BurnOutSharp/ProtectionType/WTMCDProtect.cs +++ b/BurnOutSharp/ProtectionType/WTMCDProtect.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Collections.Generic; using BurnOutSharp.Matching; namespace BurnOutSharp.ProtectionType @@ -38,7 +39,7 @@ namespace BurnOutSharp.ProtectionType } /// - public List CheckDirectoryPath(string path, IEnumerable files) + public ConcurrentQueue CheckDirectoryPath(string path, IEnumerable files) { var matchers = new List { diff --git a/BurnOutSharp/ProtectionType/Winlock.cs b/BurnOutSharp/ProtectionType/Winlock.cs index 4f9bfaf0..124911d1 100644 --- a/BurnOutSharp/ProtectionType/Winlock.cs +++ b/BurnOutSharp/ProtectionType/Winlock.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Collections.Generic; using BurnOutSharp.Matching; namespace BurnOutSharp.ProtectionType @@ -6,7 +7,7 @@ namespace BurnOutSharp.ProtectionType public class Winlock : IPathCheck { /// - public List CheckDirectoryPath(string path, IEnumerable files) + public ConcurrentQueue CheckDirectoryPath(string path, IEnumerable files) { var matchers = new List { diff --git a/BurnOutSharp/ProtectionType/XCP.cs b/BurnOutSharp/ProtectionType/XCP.cs index e9924066..8edf6414 100644 --- a/BurnOutSharp/ProtectionType/XCP.cs +++ b/BurnOutSharp/ProtectionType/XCP.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Linq; @@ -46,8 +47,10 @@ namespace BurnOutSharp.ProtectionType } /// - public List CheckDirectoryPath(string path, IEnumerable files) + public ConcurrentQueue CheckDirectoryPath(string path, IEnumerable files) { + var protections = new ConcurrentQueue(); + // TODO: Verify if these are OR or AND if (files.Any(f => Path.GetFileName(f).Equals("XCP.DAT", StringComparison.OrdinalIgnoreCase)) || files.Any(f => Path.GetFileName(f).Equals("ECDPlayerControl.ocx", StringComparison.OrdinalIgnoreCase))) @@ -57,13 +60,15 @@ namespace BurnOutSharp.ProtectionType { string xcpVersion = GetDatVersion(versionDatPath); if (!string.IsNullOrWhiteSpace(xcpVersion)) - return new List() { xcpVersion }; + protections.Enqueue(xcpVersion); + } + else + { + protections.Enqueue("XCP"); } - - return new List() { "XCP" }; } - return null; + return protections; } /// diff --git a/BurnOutSharp/ProtectionType/Zzxzz.cs b/BurnOutSharp/ProtectionType/Zzxzz.cs index d85cb32b..b3e59571 100644 --- a/BurnOutSharp/ProtectionType/Zzxzz.cs +++ b/BurnOutSharp/ProtectionType/Zzxzz.cs @@ -1,3 +1,4 @@ +using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using BurnOutSharp.Matching; @@ -7,7 +8,7 @@ namespace BurnOutSharp.ProtectionType public class Zzxzz : IPathCheck { /// - public List CheckDirectoryPath(string path, IEnumerable files) + public ConcurrentQueue CheckDirectoryPath(string path, IEnumerable files) { var matchers = new List { diff --git a/BurnOutSharp/Scanner.cs b/BurnOutSharp/Scanner.cs index bf77fff8..d2681e70 100644 --- a/BurnOutSharp/Scanner.cs +++ b/BurnOutSharp/Scanner.cs @@ -1,8 +1,10 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; +using System.Threading.Tasks; using BurnOutSharp.FileType; namespace BurnOutSharp @@ -54,7 +56,7 @@ namespace BurnOutSharp /// /// Path to scan /// Dictionary of list of strings representing the found protections - public Dictionary> GetProtections(string path) + public ConcurrentDictionary> GetProtections(string path) { return GetProtections(new List { path }); } @@ -63,7 +65,7 @@ namespace BurnOutSharp /// Scan the list of paths and get all found protections /// /// Dictionary of list of strings representing the found protections - public Dictionary> GetProtections(List paths) + public ConcurrentDictionary> GetProtections(List paths) { // If we have no paths, we can't scan if (paths == null || !paths.Any()) @@ -77,7 +79,7 @@ namespace BurnOutSharp string tempFilePathWithGuid = Path.Combine(tempFilePath, Guid.NewGuid().ToString()); // Loop through each path and get the returned values - var protections = new Dictionary>(); + var protections = new ConcurrentDictionary>(); foreach (string path in paths) { // Directories scan each internal file individually @@ -115,14 +117,14 @@ namespace BurnOutSharp foreach (string key in fileProtections.Keys) { if (!protections.ContainsKey(key)) - protections[key] = new List(); + protections[key] = new ConcurrentQueue(); protections[key].AddRange(fileProtections[key]); } } // Checkpoint - protections.TryGetValue(file, out List fullProtectionList); + protections.TryGetValue(file, out ConcurrentQueue fullProtectionList); string fullProtection = (fullProtectionList != null && fullProtectionList.Any() ? string.Join(", ", fullProtectionList) : null); FileProgress?.Report(new ProtectionProgress(reportableFileName, (i + 1) / (float)files.Count, fullProtection ?? string.Empty)); } @@ -150,14 +152,14 @@ namespace BurnOutSharp foreach (string key in fileProtections.Keys) { if (!protections.ContainsKey(key)) - protections[key] = new List(); + protections[key] = new ConcurrentQueue(); protections[key].AddRange(fileProtections[key]); } } // Checkpoint - protections.TryGetValue(path, out List fullProtectionList); + protections.TryGetValue(path, out ConcurrentQueue fullProtectionList); string fullProtection = (fullProtectionList != null && fullProtectionList.Any() ? string.Join(", ", fullProtectionList) : null); FileProgress?.Report(new ProtectionProgress(reportableFileName, 1, fullProtection ?? string.Empty)); } @@ -182,24 +184,24 @@ namespace BurnOutSharp /// Path of the directory to scan /// Files contained within /// Dictionary of list of strings representing the found protections - private Dictionary> GetDirectoryPathProtections(string path, List files) + private ConcurrentDictionary> GetDirectoryPathProtections(string path, List files) { - // Create an empty list for protections - List protections = new List(); + // Create an empty queue for protections + var protections = new ConcurrentQueue(); // Preprocess the list of files files = files.Select(f => f.Replace('\\', '/')).ToList(); // Iterate through all path checks - foreach (var pathCheckClass in pathCheckClasses) + Parallel.ForEach(pathCheckClasses, pathCheckClass => { - List protection = pathCheckClass.CheckDirectoryPath(path, files); + ConcurrentQueue protection = pathCheckClass.CheckDirectoryPath(path, files); if (protection != null) protections.AddRange(protection); - } + }); // Create and return the dictionary - return new Dictionary> + return new ConcurrentDictionary> { [path] = protections }; @@ -210,21 +212,21 @@ namespace BurnOutSharp /// /// Path of the file to scan /// Dictionary of list of strings representing the found protections - private Dictionary> GetFilePathProtections(string path) + private ConcurrentDictionary> GetFilePathProtections(string path) { - // Create an empty list for protections - List protections = new List(); + // Create an empty queue for protections + var protections = new ConcurrentQueue(); // Iterate through all path checks - foreach (var pathCheckClass in pathCheckClasses) + Parallel.ForEach(pathCheckClasses, pathCheckClass => { string protection = pathCheckClass.CheckFilePath(path.Replace("\\", "/")); if (!string.IsNullOrWhiteSpace(protection)) - protections.Add(protection); - } + protections.Enqueue(protection); + }); // Create and return the dictionary - return new Dictionary> + return new ConcurrentDictionary> { [path] = protections }; @@ -235,14 +237,14 @@ namespace BurnOutSharp /// /// Path to the file to scan /// Dictionary of list of strings representing the found protections - private Dictionary> GetInternalProtections(string file) + private ConcurrentDictionary> GetInternalProtections(string file) { // Quick sanity check before continuing if (!File.Exists(file)) return null; // Initialze the protections found - var protections = new Dictionary>(); + var protections = new ConcurrentDictionary>(); // Get the extension for certain checks string extension = Path.GetExtension(file).ToLower().TrimStart('.'); diff --git a/BurnOutSharp/Utilities.cs b/BurnOutSharp/Utilities.cs index a3c189f3..2bb57cfb 100644 --- a/BurnOutSharp/Utilities.cs +++ b/BurnOutSharp/Utilities.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.IO; @@ -19,9 +20,11 @@ namespace BurnOutSharp /// Dictionary to append to /// Key to add information to /// String value to add - public static void AppendToDictionary(Dictionary> original, string key, string value) + public static void AppendToDictionary(ConcurrentDictionary> original, string key, string value) { - AppendToDictionary(original, key, new List { value }); + var values = new ConcurrentQueue(); + values.Enqueue(value); + AppendToDictionary(original, key, values); } /// @@ -30,7 +33,7 @@ namespace BurnOutSharp /// Dictionary to append to /// Key to add information to /// String value to add - public static void AppendToDictionary(Dictionary> original, string key, List values) + public static void AppendToDictionary(ConcurrentDictionary> original, string key, ConcurrentQueue values) { // If the dictionary is null, just return if (original == null) @@ -40,9 +43,7 @@ namespace BurnOutSharp key = key ?? "NO FILENAME"; // Add the key if needed and then append the lists - if (!original.ContainsKey(key)) - original[key] = new List(); - + original.TryAdd(key, new ConcurrentQueue()); original[key].AddRange(values); } @@ -51,7 +52,7 @@ namespace BurnOutSharp /// /// Dictionary to append to /// Dictionary to pull from - public static void AppendToDictionary(Dictionary> original, Dictionary> addition) + public static void AppendToDictionary(ConcurrentDictionary> original, ConcurrentDictionary> addition) { // If either dictionary is missing, just return if (original == null || addition == null) @@ -60,9 +61,7 @@ namespace BurnOutSharp // Loop through each of the addition keys and add accordingly foreach (string key in addition.Keys) { - if (!original.ContainsKey(key)) - original[key] = new List(); - + original.TryAdd(key, new ConcurrentQueue()); original[key].AddRange(addition[key]); } } @@ -71,7 +70,7 @@ namespace BurnOutSharp /// Remove empty or null keys from a results dictionary /// /// Dictionary to clean - public static void ClearEmptyKeys(Dictionary> original) + public static void ClearEmptyKeys(ConcurrentDictionary> original) { // If the dictionary is missing, we can't do anything if (original == null) @@ -88,7 +87,7 @@ namespace BurnOutSharp // If the key is empty, remove it if (original[key] == null || !original[key].Any()) - original.Remove(key); + original.TryRemove(key, out _); } } @@ -97,7 +96,7 @@ namespace BurnOutSharp /// /// Dictionary to strip values from /// Path to strip from the keys - public static void PrependToKeys(Dictionary> original, string pathToPrepend) + public static void PrependToKeys(ConcurrentDictionary> original, string pathToPrepend) { // If the dictionary is missing, we can't do anything if (original == null) @@ -118,7 +117,7 @@ namespace BurnOutSharp // Otherwise, get the new key name and transfer over string newKey = $"{pathToPrepend}{Path.DirectorySeparatorChar}{currentKey.Trim(Path.DirectorySeparatorChar)}"; original[newKey] = original[currentKey]; - original.Remove(currentKey); + original.TryRemove(currentKey, out _); } } @@ -127,7 +126,7 @@ namespace BurnOutSharp /// /// Dictionary to strip values from /// Path to strip from the keys - public static void StripFromKeys(Dictionary> original, string pathToStrip) + public static void StripFromKeys(ConcurrentDictionary> original, string pathToStrip) { // If either is missing, we can't do anything if (original == null || string.IsNullOrEmpty(pathToStrip)) @@ -149,7 +148,27 @@ namespace BurnOutSharp // Otherwise, get the new key name and transfer over string newKey = currentKey.Substring(pathToStrip.Length); original[newKey] = original[currentKey]; - original.Remove(currentKey); + original.TryRemove(currentKey, out _); + } + } + + #endregion + + #region Concurrent Manipulation + + /// + /// Add a range of values from one queue to another + /// + /// Queue to add data to + /// Queue to get data from + public static void AddRange(this ConcurrentQueue original, ConcurrentQueue values) + { + while (!values.IsEmpty) + { + if (!values.TryDequeue(out string value)) + return; + + original.Enqueue(value); } } diff --git a/Test/Program.cs b/Test/Program.cs index 7ec4713a..76d41a8a 100644 --- a/Test/Program.cs +++ b/Test/Program.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Linq; @@ -66,7 +67,7 @@ namespace Test /// /// File or directory path /// Dictionary of protections found, if any - private static void WriteProtectionResultFile(string path, Dictionary> protections) + private static void WriteProtectionResultFile(string path, ConcurrentDictionary> protections) { if (protections == null) { @@ -76,13 +77,13 @@ namespace Test using (var sw = new StreamWriter(File.OpenWrite($"{DateTime.Now:yyyy-MM-dd_HHmmss}.txt"))) { - foreach (string key in protections.Keys) + foreach (string key in protections.Keys.OrderBy(k => k)) { // Skip over files with no protection if (protections[key] == null || !protections[key].Any()) continue; - string line = $"{key}: {string.Join(", ", protections[key])}"; + string line = $"{key}: {string.Join(", ", protections[key].OrderBy(p => p))}"; Console.WriteLine(line); sw.WriteLine(line); }