diff --git a/BurnOutSharp/BurnOutSharp.csproj b/BurnOutSharp/BurnOutSharp.csproj
index 59cb0b27..659fdad5 100644
--- a/BurnOutSharp/BurnOutSharp.csproj
+++ b/BurnOutSharp/BurnOutSharp.csproj
@@ -28,6 +28,7 @@
+
diff --git a/BurnOutSharp/FileType/MSI.cs b/BurnOutSharp/FileType/MSI.cs
new file mode 100644
index 00000000..7120255e
--- /dev/null
+++ b/BurnOutSharp/FileType/MSI.cs
@@ -0,0 +1,55 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using LibMSPackN;
+using Microsoft.Deployment.WindowsInstaller;
+using Microsoft.Deployment.WindowsInstaller.Package;
+
+namespace BurnOutSharp.FileType
+{
+ internal class MSI
+ {
+ public static bool ShouldScan(byte[] magic)
+ {
+ if (magic.StartsWith(new byte[] { 0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1 }))
+ return true;
+
+ return false;
+ }
+
+ // TODO: Add stream opening support
+ public static List Scan(string file, bool includePosition = false)
+ {
+ List protections = new List();
+
+ // If the MSI file itself fails
+ try
+ {
+ string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
+ Directory.CreateDirectory(tempPath);
+
+ using (Database msidb = new Database(file, DatabaseOpenMode.ReadOnly))
+ {
+ msidb.ExportAll(tempPath);
+ }
+
+ // Collect and format all found protections
+ var fileProtections = ProtectionFind.Scan(tempPath, includePosition);
+ protections = fileProtections.Select(kvp => kvp.Key.Substring(tempPath.Length) + ": " + kvp.Value.TrimEnd()).ToList();
+
+ // If temp directory cleanup fails
+ try
+ {
+ Directory.Delete(tempPath, true);
+ }
+ catch { }
+ }
+ catch { }
+
+ return protections;
+ }
+ }
+}
diff --git a/BurnOutSharp/FileType/MicrosoftCAB.cs b/BurnOutSharp/FileType/MicrosoftCAB.cs
index 2f91e93b..4f875ff4 100644
--- a/BurnOutSharp/FileType/MicrosoftCAB.cs
+++ b/BurnOutSharp/FileType/MicrosoftCAB.cs
@@ -39,18 +39,18 @@ namespace BurnOutSharp.FileType
}
catch { }
}
-
- // Collect and format all found protections
- var fileProtections = ProtectionFind.Scan(tempPath, includePosition);
- protections = fileProtections.Select(kvp => kvp.Key.Substring(tempPath.Length) + ": " + kvp.Value.TrimEnd()).ToList();
-
- // If temp directory cleanup fails
- try
- {
- Directory.Delete(tempPath, true);
- }
- catch { }
}
+
+ // Collect and format all found protections
+ var fileProtections = ProtectionFind.Scan(tempPath, includePosition);
+ protections = fileProtections.Select(kvp => kvp.Key.Substring(tempPath.Length) + ": " + kvp.Value.TrimEnd()).ToList();
+
+ // If temp directory cleanup fails
+ try
+ {
+ Directory.Delete(tempPath, true);
+ }
+ catch { }
}
catch { }
diff --git a/BurnOutSharp/ProtectionFind.cs b/BurnOutSharp/ProtectionFind.cs
index dbf966a6..3cf45921 100644
--- a/BurnOutSharp/ProtectionFind.cs
+++ b/BurnOutSharp/ProtectionFind.cs
@@ -444,6 +444,10 @@ namespace BurnOutSharp
if (file != null && MicrosoftCAB.ShouldScan(magic))
protections.AddRange(MicrosoftCAB.Scan(file, includePosition));
+ // MSI
+ if (file != null && MSI.ShouldScan(magic))
+ protections.AddRange(MSI.Scan(file, includePosition));
+
// MPQ archive
if (file != null && MPQ.ShouldScan(magic))
protections.AddRange(MPQ.Scan(file, includePosition));