diff --git a/BurnOutSharp/FileType/Textfile.cs b/BinaryObjectScanner.FileType/Textfile.cs
similarity index 61%
rename from BurnOutSharp/FileType/Textfile.cs
rename to BinaryObjectScanner.FileType/Textfile.cs
index c288b24d..514ebe4a 100644
--- a/BurnOutSharp/FileType/Textfile.cs
+++ b/BinaryObjectScanner.FileType/Textfile.cs
@@ -1,34 +1,33 @@
using System;
-using System.Collections.Concurrent;
+using System.Collections.Generic;
using System.IO;
using System.Text;
-using BurnOutSharp.Interfaces;
-using static BinaryObjectScanner.Utilities.Dictionary;
+using BinaryObjectScanner.Interfaces;
-namespace BurnOutSharp.FileType
+namespace BinaryObjectScanner.FileType
{
///
/// Various generic textfile formats
///
- public class Textfile : IScannable
+ public class Textfile : IDetectable
{
///
- public ConcurrentDictionary> Scan(Scanner scanner, string file)
+ public string Detect(string file, bool includeDebug)
{
if (!File.Exists(file))
return null;
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
{
- return Scan(scanner, fs, file);
+ return Detect(fs, file, includeDebug);
}
}
///
- public ConcurrentDictionary> Scan(Scanner scanner, Stream stream, string file)
+ public string Detect(Stream stream, string file, bool includeDebug)
{
// Files can be protected in multiple ways
- var protections = new ConcurrentDictionary>();
+ var protections = new List();
try
{
@@ -42,60 +41,60 @@ namespace BurnOutSharp.FileType
// AegiSoft License Manager
// Found in "setup.ins" (Redump entry 73521/IA item "Nova_HoyleCasino99USA").
if (fileContent.Contains("Failed to load the AegiSoft License Manager install program."))
- AppendToDictionary(protections, file, "AegiSoft License Manager");
+ protections.Add("AegiSoft License Manager");
// CD-Key
if (fileContent.Contains("a valid serial number is required"))
- AppendToDictionary(protections, file, "CD-Key / Serial");
+ protections.Add("CD-Key / Serial");
else if (fileContent.Contains("serial number is located"))
- AppendToDictionary(protections, file, "CD-Key / Serial");
+ protections.Add("CD-Key / Serial");
// Found in "Setup.Ins" ("Word Point 2002" in IA item "advantage-language-french-beginner-langmaster-2005").
else if (fileContent.Contains("Please enter a valid registration number"))
- AppendToDictionary(protections, file, "CD-Key / Serial");
+ protections.Add("CD-Key / Serial");
// Freelock
// Found in "FILE_ID.DIZ" distributed with Freelock.
if (fileContent.Contains("FREELOCK 1.0"))
- AppendToDictionary(protections, file, "Freelock 1.0");
+ protections.Add("Freelock 1.0");
else if (fileContent.Contains("FREELOCK 1.2"))
- AppendToDictionary(protections, file, "Freelock 1.2");
+ protections.Add("Freelock 1.2");
else if (fileContent.Contains("FREELOCK 1.2a"))
- AppendToDictionary(protections, file, "Freelock 1.2a");
+ protections.Add("Freelock 1.2a");
else if (fileContent.Contains("FREELOCK 1.3"))
- AppendToDictionary(protections, file, "Freelock 1.3");
+ protections.Add("Freelock 1.3");
else if (fileContent.Contains("FREELOCK"))
- AppendToDictionary(protections, file, "Freelock");
+ protections.Add("Freelock");
// MediaCloQ
if (fileContent.Contains("SunnComm MediaCloQ"))
- AppendToDictionary(protections, file, "MediaCloQ");
+ protections.Add("MediaCloQ");
else if (fileContent.Contains("http://download.mediacloq.com/"))
- AppendToDictionary(protections, file, "MediaCloQ");
+ protections.Add("MediaCloQ");
else if (fileContent.Contains("http://www.sunncomm.com/mediacloq/"))
- AppendToDictionary(protections, file, "MediaCloQ");
+ protections.Add("MediaCloQ");
// MediaMax
if (fileContent.Contains("MediaMax technology"))
- AppendToDictionary(protections, file, "MediaMax CD-3");
+ protections.Add("MediaMax CD-3");
else if (fileContent.Contains("exclusive Cd3 technology"))
- AppendToDictionary(protections, file, "MediaMax CD-3");
+ protections.Add("MediaMax CD-3");
else if (fileContent.Contains("MediaMAX"))
- AppendToDictionary(protections, file, "MediaMax CD-3");
+ protections.Add("MediaMax CD-3");
else if (fileContent.Contains("MediaMax(tm)"))
- AppendToDictionary(protections, file, "MediaMax CD-3");
+ protections.Add("MediaMax CD-3");
// phenoProtect
if (fileContent.Contains("phenoProtect"))
- AppendToDictionary(protections, file, "phenoProtect");
+ protections.Add("phenoProtect");
// Rainbow Sentinel
// Found in "SENTW95.HLP" and "SENTINEL.HLP" in BA entry "Autodesk AutoCAD LT 98 (1998) (CD) [English] [Dutch]".
if (fileContent.Contains("Rainbow Sentinel Driver Help"))
- AppendToDictionary(protections, file, "Rainbow Sentinel");
+ protections.Add("Rainbow Sentinel");
// Found in "OEMSETUP.INF" in BA entry "Autodesk AutoCAD LT 98 (1998) (CD) [English] [Dutch]".
if (fileContent.Contains("Sentinel Driver Disk"))
- AppendToDictionary(protections, file, "Rainbow Sentinel");
+ protections.Add("Rainbow Sentinel");
// The full line from a sample is as follows:
//
@@ -105,22 +104,22 @@ namespace BurnOutSharp.FileType
// SecuROM
if (fileContent.Contains("SecuROM protected application"))
- AppendToDictionary(protections, file, "SecuROM");
+ protections.Add("SecuROM");
// Steam
if (fileContent.Contains("All use of the Program is governed by the terms of the Steam Agreement as described below."))
- AppendToDictionary(protections, file, "Steam");
+ protections.Add("Steam");
// XCP
if (fileContent.Contains("http://cp.sonybmg.com/xcp/"))
- AppendToDictionary(protections, file, "XCP");
+ protections.Add("XCP");
}
catch (Exception ex)
{
- if (scanner.IncludeDebug) Console.WriteLine(ex);
+ if (includeDebug) Console.WriteLine(ex);
}
- return protections;
+ return string.Join(";", protections);
}
}
}
diff --git a/BinaryObjectScanner.Utilities/Dictionary.cs b/BinaryObjectScanner.Utilities/Dictionary.cs
index a9133d28..82ccea2c 100644
--- a/BinaryObjectScanner.Utilities/Dictionary.cs
+++ b/BinaryObjectScanner.Utilities/Dictionary.cs
@@ -28,7 +28,27 @@ namespace BinaryObjectScanner.Utilities
}
///
- /// Append one result to a results dictionary
+ /// Append one set of results to a results dictionary
+ ///
+ /// Dictionary to append to
+ /// Key to add information to
+ /// String value to add
+ public static void AppendToDictionary(ConcurrentDictionary> original, string key, string[] values)
+ {
+ // If the dictionary is null, just return
+ if (original == null)
+ return;
+
+ // Use a placeholder value if the key is null
+ key = key ?? "NO FILENAME";
+
+ // Add the key if needed and then append the lists
+ original.TryAdd(key, new ConcurrentQueue());
+ original[key].AddRange(values);
+ }
+
+ ///
+ /// Append one set of results to a results dictionary
///
/// Dictionary to append to
/// Key to add information to
diff --git a/BinaryObjectScanner.Utilities/Extensions.cs b/BinaryObjectScanner.Utilities/Extensions.cs
index 70f47a66..57f95dfd 100644
--- a/BinaryObjectScanner.Utilities/Extensions.cs
+++ b/BinaryObjectScanner.Utilities/Extensions.cs
@@ -12,6 +12,22 @@ namespace BinaryObjectScanner.Utilities
{
#region ConcurrentQueue
+ ///
+ /// Add a range of values from one queue to another
+ ///
+ /// Queue to add data to
+ /// Array to get data from
+ public static void AddRange(this ConcurrentQueue original, string[] values)
+ {
+ if (values == null || values.Length == 0)
+ return;
+
+ for (int i = 0; i < values.Length; i++)
+ {
+ original.Enqueue(values[i]);
+ }
+ }
+
///
/// Add a range of values from one queue to another
///
diff --git a/BurnOutSharp/Scanner.cs b/BurnOutSharp/Scanner.cs
index 52d96fc7..d1819b61 100644
--- a/BurnOutSharp/Scanner.cs
+++ b/BurnOutSharp/Scanner.cs
@@ -352,7 +352,18 @@ namespace BurnOutSharp
{
string subProtection = detectable.Detect(stream, fileName, IncludeDebug);
if (!string.IsNullOrWhiteSpace(subProtection))
- AppendToDictionary(protections, fileName, subProtection);
+ {
+ // If we have an indicator of multiple protections
+ if (subProtection.Contains(';'))
+ {
+ var splitProtections = subProtection.Split(';');
+ AppendToDictionary(protections, fileName, splitProtections);
+ }
+ else
+ {
+ AppendToDictionary(protections, fileName, subProtection);
+ }
+ }
}
// Create a scannable for the given file type
@@ -443,6 +454,7 @@ namespace BurnOutSharp
//case SupportedFileType.Nitro: return new BinaryObjectScanner.FileType.Nitro();
case SupportedFileType.PLJ: return new BinaryObjectScanner.FileType.PLJ();
case SupportedFileType.SFFS: return new BinaryObjectScanner.FileType.SFFS();
+ case SupportedFileType.Textfile: return new BinaryObjectScanner.FileType.Textfile();
default: return null;
}
}
@@ -497,7 +509,6 @@ namespace BurnOutSharp
switch (fileType)
{
case SupportedFileType.Executable: return new FileType.Executable();
- case SupportedFileType.Textfile: return new FileType.Textfile();
default: return null;
}
}