diff --git a/BinaryObjectScanner/Handler.cs b/BinaryObjectScanner/Handler.cs
index ba76668d..a4d8fc38 100644
--- a/BinaryObjectScanner/Handler.cs
+++ b/BinaryObjectScanner/Handler.cs
@@ -10,7 +10,6 @@ using System.Threading.Tasks;
using BinaryObjectScanner.Interfaces;
using BinaryObjectScanner.Utilities;
using SabreTools.Serialization.Wrappers;
-using static BinaryObjectScanner.Utilities.Dictionary;
namespace BinaryObjectScanner
{
@@ -49,18 +48,10 @@ namespace BinaryObjectScanner
/// Path of the file or directory to check
/// Scanner object to use for options and scanning
/// Set of protections in file, null on error
-#if NET20 || NET35
- public static Dictionary> HandlePathChecks(string path, IEnumerable? files)
-#else
- public static ConcurrentDictionary> HandlePathChecks(string path, IEnumerable? files)
-#endif
+ public static ProtectionDictionary HandlePathChecks(string path, IEnumerable? files)
{
// Create the output dictionary
-#if NET20 || NET35
- var protections = new Dictionary>();
-#else
- var protections = new ConcurrentDictionary>();
-#endif
+ var protections = new ProtectionDictionary();
// Preprocess the list of files
files = files?.Select(f => f.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar))?.ToList();
@@ -74,7 +65,7 @@ namespace BinaryObjectScanner
{
var subProtections = checkClass?.PerformCheck(path, files);
if (subProtections != null)
- AppendToDictionary(protections, path, subProtections);
+ protections.Append(path, subProtections);
#if NET20 || NET35
}
#else
@@ -114,11 +105,7 @@ namespace BinaryObjectScanner
/// Stream to scan the contents of
/// Scanner object to use on extractable contents
/// Set of protections in file, null on error
-#if NET20 || NET35
- public static Dictionary>? HandleExtractable(IExtractable impl, string fileName, Stream? stream, Scanner scanner)
-#else
- public static ConcurrentDictionary>? HandleExtractable(IExtractable impl, string fileName, Stream? stream, Scanner scanner)
-#endif
+ public static ProtectionDictionary? HandleExtractable(IExtractable impl, string fileName, Stream? stream, Scanner scanner)
{
// If the extractable file itself fails
try
@@ -142,8 +129,8 @@ namespace BinaryObjectScanner
}
// Prepare the returned protections
- StripFromKeys(subProtections, tempPath);
- PrependToKeys(subProtections, fileName);
+ subProtections.StripFromKeys(tempPath);
+ subProtections.PrependToKeys(fileName);
return subProtections;
}
catch (Exception ex)
@@ -162,11 +149,7 @@ namespace BinaryObjectScanner
/// MSDOS to scan the contents of
/// Scanner object to use on extractable contents
/// Set of protections in file, null on error
-#if NET20 || NET35
- public static Dictionary>? HandleExtractable(IExtractableMSDOSExecutable impl, string fileName, MSDOS mz, Scanner scanner)
-#else
- public static ConcurrentDictionary>? HandleExtractable(IExtractableMSDOSExecutable impl, string fileName, MSDOS mz, Scanner scanner)
-#endif
+ public static ProtectionDictionary? HandleExtractable(IExtractableMSDOSExecutable impl, string fileName, MSDOS mz, Scanner scanner)
{
// If the extractable file itself fails
try
@@ -190,8 +173,8 @@ namespace BinaryObjectScanner
}
// Prepare the returned protections
- StripFromKeys(subProtections, tempPath);
- PrependToKeys(subProtections, fileName);
+ subProtections.StripFromKeys(tempPath);
+ subProtections.PrependToKeys(fileName);
return subProtections;
}
catch (Exception ex)
@@ -210,11 +193,7 @@ namespace BinaryObjectScanner
/// LinearExecutable to scan the contents of
/// Scanner object to use on extractable contents
/// Set of protections in file, null on error
-#if NET20 || NET35
- public static Dictionary>? HandleExtractable(IExtractableLinearExecutable impl, string fileName, LinearExecutable lex, Scanner scanner)
-#else
- public static ConcurrentDictionary>? HandleExtractable(IExtractableLinearExecutable impl, string fileName, LinearExecutable lex, Scanner scanner)
-#endif
+ public static ProtectionDictionary? HandleExtractable(IExtractableLinearExecutable impl, string fileName, LinearExecutable lex, Scanner scanner)
{
// If the extractable file itself fails
try
@@ -238,8 +217,8 @@ namespace BinaryObjectScanner
}
// Prepare the returned protections
- StripFromKeys(subProtections, tempPath);
- PrependToKeys(subProtections, fileName);
+ subProtections.StripFromKeys(tempPath);
+ subProtections.PrependToKeys(fileName);
return subProtections;
}
catch (Exception ex)
@@ -258,11 +237,7 @@ namespace BinaryObjectScanner
/// NewExecutable to scan the contents of
/// Scanner object to use on extractable contents
/// Set of protections in file, null on error
-#if NET20 || NET35
- public static Dictionary>? HandleExtractable(IExtractableNewExecutable impl, string fileName, NewExecutable nex, Scanner scanner)
-#else
- public static ConcurrentDictionary>? HandleExtractable(IExtractableNewExecutable impl, string fileName, NewExecutable nex, Scanner scanner)
-#endif
+ public static ProtectionDictionary? HandleExtractable(IExtractableNewExecutable impl, string fileName, NewExecutable nex, Scanner scanner)
{
// If the extractable file itself fails
try
@@ -286,8 +261,8 @@ namespace BinaryObjectScanner
}
// Prepare the returned protections
- StripFromKeys(subProtections, tempPath);
- PrependToKeys(subProtections, fileName);
+ subProtections.StripFromKeys(tempPath);
+ subProtections.PrependToKeys(fileName);
return subProtections;
}
catch (Exception ex)
@@ -306,11 +281,7 @@ namespace BinaryObjectScanner
/// PortableExecutable to scan the contents of
/// Scanner object to use on extractable contents
/// Set of protections in file, null on error
-#if NET20 || NET35
- public static Dictionary>? HandleExtractable(IExtractablePortableExecutable impl, string fileName, PortableExecutable pex, Scanner scanner)
-#else
- public static ConcurrentDictionary>? HandleExtractable(IExtractablePortableExecutable impl, string fileName, PortableExecutable pex, Scanner scanner)
-#endif
+ public static ProtectionDictionary? HandleExtractable(IExtractablePortableExecutable impl, string fileName, PortableExecutable pex, Scanner scanner)
{
// If the extractable file itself fails
try
@@ -334,8 +305,8 @@ namespace BinaryObjectScanner
}
// Prepare the returned protections
- StripFromKeys(subProtections, tempPath);
- PrependToKeys(subProtections, fileName);
+ subProtections.StripFromKeys(tempPath);
+ subProtections.PrependToKeys(fileName);
return subProtections;
}
catch (Exception ex)
diff --git a/BinaryObjectScanner/Interfaces/IPathCheck.cs b/BinaryObjectScanner/Interfaces/IPathCheck.cs
index 4d081966..dbda4de7 100644
--- a/BinaryObjectScanner/Interfaces/IPathCheck.cs
+++ b/BinaryObjectScanner/Interfaces/IPathCheck.cs
@@ -20,7 +20,7 @@ namespace BinaryObjectScanner.Interfaces
/// Enumerable of strings representing files in a directory
/// This can do some limited content checking as well, but it's suggested to use a content check instead, if possible
#if NET20 || NET35
- Queue CheckDirectoryPath(string path, IEnumerable? files);
+ List CheckDirectoryPath(string path, IEnumerable? files);
#else
ConcurrentQueue CheckDirectoryPath(string path, IEnumerable? files);
#endif
diff --git a/BinaryObjectScanner/ProtectionDictionary.cs b/BinaryObjectScanner/ProtectionDictionary.cs
index e9f11fbf..550a6f87 100644
--- a/BinaryObjectScanner/ProtectionDictionary.cs
+++ b/BinaryObjectScanner/ProtectionDictionary.cs
@@ -48,8 +48,8 @@ namespace BinaryObjectScanner
// Add the key if needed and then append the lists
#if NET20 || NET35
- if (!original.ContainsKey(key))
- original[key] = new Queue();
+ if (!ContainsKey(key))
+ this[key] = new Queue();
#else
TryAdd(key, new ConcurrentQueue());
#endif
@@ -72,8 +72,8 @@ namespace BinaryObjectScanner
// Add the key if needed and then append the lists
#if NET20 || NET35
- if (!original.ContainsKey(key))
- original[key] = new Queue();
+ if (!ContainsKey(key))
+ this[key] = new Queue();
#else
TryAdd(key, new ConcurrentQueue());
#endif
@@ -94,8 +94,8 @@ namespace BinaryObjectScanner
foreach (string key in addition.Keys)
{
#if NET20 || NET35
- if (!original.ContainsKey(key))
- original[key] = new Queue();
+ if (!ContainsKey(key))
+ this[key] = new Queue();
#else
TryAdd(key, new ConcurrentQueue());
#endif
diff --git a/BinaryObjectScanner/Scanner.cs b/BinaryObjectScanner/Scanner.cs
index b4019541..e35af71d 100644
--- a/BinaryObjectScanner/Scanner.cs
+++ b/BinaryObjectScanner/Scanner.cs
@@ -17,7 +17,6 @@ using BinaryObjectScanner.Utilities;
using SabreTools.IO.Extensions;
using SabreTools.Serialization.Interfaces;
using SabreTools.Serialization.Wrappers;
-using static BinaryObjectScanner.Utilities.Dictionary;
namespace BinaryObjectScanner
{
@@ -92,24 +91,14 @@ namespace BinaryObjectScanner
///
/// Path to scan
/// Dictionary of list of strings representing the found protections
-#if NET20 || NET35
- public Dictionary>? GetProtections(string path)
-#else
- public ConcurrentDictionary>? GetProtections(string path)
-#endif
- {
- return GetProtections([path]);
- }
+ public ProtectionDictionary? GetProtections(string path)
+ => GetProtections([path]);
///
/// Scan the list of paths and get all found protections
///
/// Dictionary of list of strings representing the found protections
-#if NET20 || NET35
- public Dictionary>? GetProtections(List? paths)
-#else
- public ConcurrentDictionary>? GetProtections(List? paths)
-#endif
+ public ProtectionDictionary? GetProtections(List? paths)
{
// If we have no paths, we can't scan
if (paths == null || !paths.Any())
@@ -126,11 +115,7 @@ namespace BinaryObjectScanner
string tempFilePathWithGuid = Path.Combine(tempFilePath, Guid.NewGuid().ToString());
// Loop through each path and get the returned values
-#if NET20 || NET35
- var protections = new Dictionary>();
-#else
- var protections = new ConcurrentDictionary>();
-#endif
+ var protections = new ProtectionDictionary();
foreach (string path in paths)
{
// Directories scan each internal file individually
@@ -143,7 +128,7 @@ namespace BinaryObjectScanner
if (ScanPaths)
{
var directoryPathProtections = Handler.HandlePathChecks(path, files);
- AppendToDictionary(protections, directoryPathProtections);
+ protections.Append(directoryPathProtections);
}
// Scan each file in directory separately
@@ -164,25 +149,14 @@ namespace BinaryObjectScanner
if (ScanPaths)
{
var filePathProtections = Handler.HandlePathChecks(file, files: null);
- AppendToDictionary(protections, filePathProtections);
+ if (filePathProtections != null && filePathProtections.Any())
+ protections.Append(filePathProtections);
}
// Scan for content-detectable protections
var fileProtections = GetInternalProtections(file);
if (fileProtections != null && fileProtections.Any())
- {
- foreach (string key in fileProtections.Keys)
- {
- if (!protections.ContainsKey(key))
-#if NET20 || NET35
- protections[key] = new Queue();
-#else
- protections[key] = new ConcurrentQueue();
-#endif
-
- protections[key].AddRange(fileProtections[key]);
- }
- }
+ protections.Append(fileProtections);
// Checkpoint
protections.TryGetValue(file, out var fullProtectionList);
@@ -206,25 +180,14 @@ namespace BinaryObjectScanner
if (ScanPaths)
{
var filePathProtections = Handler.HandlePathChecks(path, files: null);
- AppendToDictionary(protections, filePathProtections);
+ if (filePathProtections != null && filePathProtections.Any())
+ protections.Append(filePathProtections);
}
// Scan for content-detectable protections
var fileProtections = GetInternalProtections(path);
if (fileProtections != null && fileProtections.Any())
- {
- foreach (string key in fileProtections.Keys)
- {
- if (!protections.ContainsKey(key))
-#if NET20 || NET35
- protections[key] = new Queue();
-#else
- protections[key] = new ConcurrentQueue();
-#endif
-
- protections[key].AddRange(fileProtections[key]);
- }
- }
+ protections.Append(fileProtections);
// Checkpoint
protections.TryGetValue(path, out var fullProtectionList);
@@ -241,7 +204,7 @@ namespace BinaryObjectScanner
}
// Clear out any empty keys
- ClearEmptyKeys(protections);
+ protections.ClearEmptyKeys();
// If we're in debug, output the elasped time to console
if (IncludeDebug)
@@ -255,11 +218,7 @@ namespace BinaryObjectScanner
///
/// Path to the file to scan
/// Dictionary of list of strings representing the found protections
-#if NET20 || NET35
- private Dictionary>? GetInternalProtections(string file)
-#else
- private ConcurrentDictionary>? GetInternalProtections(string file)
-#endif
+ private ProtectionDictionary? GetInternalProtections(string file)
{
// Quick sanity check before continuing
if (!File.Exists(file))
@@ -275,13 +234,9 @@ namespace BinaryObjectScanner
{
if (IncludeDebug) Console.WriteLine(ex);
-#if NET20 || NET35
- var protections = new Dictionary>();
-#else
- var protections = new ConcurrentDictionary>();
-#endif
- AppendToDictionary(protections, file, IncludeDebug ? ex.ToString() : "[Exception opening file, please try again]");
- ClearEmptyKeys(protections);
+ var protections = new ProtectionDictionary();
+ protections.Append(file, IncludeDebug ? ex.ToString() : "[Exception opening file, please try again]");
+ protections.ClearEmptyKeys();
return protections;
}
}
@@ -292,22 +247,14 @@ namespace BinaryObjectScanner
/// Name of the source file of the stream, for tracking
/// Stream to scan the contents of
/// Dictionary of list of strings representing the found protections
-#if NET20 || NET35
- private Dictionary>? GetInternalProtections(string fileName, Stream stream)
-#else
- private ConcurrentDictionary>? GetInternalProtections(string fileName, Stream stream)
-#endif
+ private ProtectionDictionary? GetInternalProtections(string fileName, Stream stream)
{
// Quick sanity check before continuing
if (stream == null || !stream.CanRead || !stream.CanSeek)
return null;
// Initialize the protections found
-#if NET20 || NET35
- var protections = new Dictionary>();
-#else
- var protections = new ConcurrentDictionary>();
-#endif
+ var protections = new ProtectionDictionary();
// Get the extension for certain checks
string extension = Path.GetExtension(fileName).ToLower().TrimStart('.');
@@ -349,7 +296,7 @@ namespace BinaryObjectScanner
executable.IncludePackers = ScanPackers;
var subProtections = ProcessExecutable(executable, fileName, stream);
if (subProtections != null)
- AppendToDictionary(protections, subProtections);
+ protections.Append(subProtections);
}
// Otherwise, use the default implementation
@@ -357,7 +304,7 @@ namespace BinaryObjectScanner
{
var subProtections = Handler.HandleDetectable(detectable, fileName, stream, IncludeDebug);
if (subProtections != null)
- AppendToDictionary(protections, fileName, subProtections);
+ protections.Append(fileName, subProtections);
}
var subProtection = detectable.Detect(stream, fileName, IncludeDebug);
@@ -367,11 +314,11 @@ namespace BinaryObjectScanner
if (subProtection.Contains(';'))
{
var splitProtections = subProtection!.Split(';');
- AppendToDictionary(protections, fileName, splitProtections);
+ protections.Append(fileName, splitProtections);
}
else
{
- AppendToDictionary(protections, fileName, subProtection!);
+ protections.Append(fileName, subProtection!);
}
}
}
@@ -388,7 +335,7 @@ namespace BinaryObjectScanner
{
var subProtections = Handler.HandleExtractable(extractable, fileName, stream, this);
if (subProtections != null)
- AppendToDictionary(protections, subProtections);
+ protections.Append(subProtections);
}
#endregion
@@ -396,11 +343,11 @@ namespace BinaryObjectScanner
catch (Exception ex)
{
if (IncludeDebug) Console.WriteLine(ex);
- AppendToDictionary(protections, fileName, IncludeDebug ? ex.ToString() : "[Exception opening file, please try again]");
+ protections.Append(fileName, IncludeDebug ? ex.ToString() : "[Exception opening file, please try again]");
}
// Clear out any empty keys
- ClearEmptyKeys(protections);
+ protections.ClearEmptyKeys();
return protections;
}
@@ -419,11 +366,7 @@ namespace BinaryObjectScanner
/// Ideally, we wouldn't need to circumvent the proper handling of file types just for Executable,
/// but due to the complexity of scanning, this is not currently possible.
///
-#if NET20 || NET35
- private Dictionary>? ProcessExecutable(Executable executable, string fileName, Stream stream)
-#else
- private ConcurrentDictionary>? ProcessExecutable(Executable executable, string fileName, Stream stream)
-#endif
+ private ProtectionDictionary? ProcessExecutable(Executable executable, string fileName, Stream stream)
{
// Try to create a wrapper for the proper executable type
IWrapper? wrapper;
@@ -440,18 +383,14 @@ namespace BinaryObjectScanner
}
// Create the output dictionary
-#if NET20 || NET35
- var protections = new Dictionary>();
-#else
- var protections = new ConcurrentDictionary>();
-#endif
+ var protections = new ProtectionDictionary();
// Only use generic content checks if we're in debug mode
if (IncludeDebug)
{
var subProtections = executable.RunContentChecks(fileName, stream, IncludeDebug);
if (subProtections != null)
- AppendToDictionary(protections, fileName, subProtections.Values.ToArray());
+ protections.Append(fileName, subProtections.Values.ToArray());
}
if (wrapper is MSDOS mz)
@@ -461,12 +400,12 @@ namespace BinaryObjectScanner
return protections;
// Append the returned values
- AppendToDictionary(protections, fileName, subProtections.Values.ToArray());
+ protections.Append(fileName, subProtections.Values.ToArray());
// If we have any extractable packers
var extractedProtections = HandleExtractableProtections(subProtections.Keys, fileName, mz);
if (extractedProtections != null)
- AppendToDictionary(protections, extractedProtections);
+ protections.Append(extractedProtections);
}
else if (wrapper is LinearExecutable lex)
{
@@ -475,12 +414,12 @@ namespace BinaryObjectScanner
return protections;
// Append the returned values
- AppendToDictionary(protections, fileName, subProtections.Values.ToArray());
+ protections.Append(fileName, subProtections.Values.ToArray());
// If we have any extractable packers
var extractedProtections = HandleExtractableProtections(subProtections.Keys, fileName, lex);
if (extractedProtections != null)
- AppendToDictionary(protections, extractedProtections);
+ protections.Append(extractedProtections);
}
else if (wrapper is NewExecutable nex)
{
@@ -489,12 +428,12 @@ namespace BinaryObjectScanner
return protections;
// Append the returned values
- AppendToDictionary(protections, fileName, subProtections.Values.ToArray());
+ protections.Append(fileName, subProtections.Values.ToArray());
// If we have any extractable packers
var extractedProtections = HandleExtractableProtections(subProtections.Keys, fileName, nex);
if (extractedProtections != null)
- AppendToDictionary(protections, extractedProtections);
+ protections.Append(extractedProtections);
}
else if (wrapper is PortableExecutable pex)
{
@@ -503,12 +442,12 @@ namespace BinaryObjectScanner
return protections;
// Append the returned values
- AppendToDictionary(protections, fileName, subProtections.Values.ToArray());
+ protections.Append(fileName, subProtections.Values.ToArray());
// If we have any extractable packers
var extractedProtections = HandleExtractableProtections(subProtections.Keys, fileName, pex);
if (extractedProtections != null)
- AppendToDictionary(protections, extractedProtections);
+ protections.Append(extractedProtections);
}
return protections;
@@ -522,9 +461,9 @@ namespace BinaryObjectScanner
/// MSDOS to scan the contents of
/// Set of protections found from extraction, null on error
#if NET20 || NET35
- private Dictionary>? HandleExtractableProtections(Dictionary.KeyCollection? classes, string fileName, MSDOS mz)
+ private ProtectionDictionary? HandleExtractableProtections(Dictionary.KeyCollection? classes, string fileName, MSDOS mz)
#else
- private ConcurrentDictionary>? HandleExtractableProtections(IEnumerable