SlunkCrypt/gui/Process/SlunkCryptRunner.cs

163 lines
6.3 KiB
C#

/******************************************************************************/
/* SlunkCrypt, by LoRd_MuldeR <MuldeR2@GMX.de> */
/* This work has been released under the CC0 1.0 Universal license! */
/******************************************************************************/
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Threading;
using com.muldersoft.slunkcrypt.gui.utils;
namespace com.muldersoft.slunkcrypt.gui.process
{
internal class SlunkCryptRunner : ProcessRunner
{
public enum Mode { Encrypt, Decrypt }
private const string FILENAME_FORMAT = "slunkcrypt-cli-{0}.exe";
private const string COMMAND_ENCRYPT = "-e";
private const string COMMAND_DECRYPT = "-d";
private static readonly Regex RX_PROGRESS = new Regex(@"(\d+)\.(\d)%", RegexOptions.Compiled);
private readonly FileStream m_executableFile;
// =============================================================================
// Exception classes
// =============================================================================
public class ExecutableNotFoundException : FileNotFoundException
{
public ExecutableNotFoundException(string message, string fileName) : base(message, fileName)
{
}
}
// =============================================================================
// Constructor
// =============================================================================
public SlunkCryptRunner(Dispatcher dispatcher, ProcessPriorityClass? priorityClass = null) : base(dispatcher, priorityClass)
{
m_executableFile = GetExecutableFile();
}
// =============================================================================
// Public methods
// =============================================================================
public async Task<int> ExecuteAsync(Mode mode, string inputFile, string outputFile, string password)
{
Dictionary<string, string> environmentVariables = new Dictionary<string, string>();
environmentVariables.Add("SLUNK_PASSPHRASE", password);
string[] arguments = new string[] { GetCommandString(mode), inputFile, outputFile };
return await ExecAsnyc(m_executableFile.Name, arguments, environmentVariables);
}
public override void Dispose()
{
base.Dispose();
try
{
m_executableFile.Dispose();
}
catch { }
}
// =============================================================================
// Internal methods
// =============================================================================
private static FileStream GetExecutableFile()
{
FileStream executableFile = null;
string appBaseDirectory = AppDomain.CurrentDomain.BaseDirectory;
CPUFeatures cpuFeatures = CPUFeatures.Features;
if (cpuFeatures.x64 && CheckExecutableFile(ref executableFile, appBaseDirectory, "x64"))
{
Trace.Assert(executableFile != null);
return executableFile;
}
if (cpuFeatures.sse2 && CheckExecutableFile(ref executableFile, appBaseDirectory, "sse2"))
{
Trace.Assert(executableFile != null);
return executableFile;
}
if (CheckExecutableFile(ref executableFile, appBaseDirectory, "i686"))
{
Trace.Assert(executableFile != null);
return executableFile;
}
throw new ExecutableNotFoundException("SlunkCrypt executable file not found!", FILENAME_FORMAT);
}
private static bool CheckExecutableFile(ref FileStream executableFile, string appBaseDirectory, string suffix)
{
try
{
executableFile = new FileStream(Path.Combine(appBaseDirectory, String.Format(FILENAME_FORMAT, suffix)), FileMode.Open, FileAccess.Read, FileShare.Read);
Version appVersion = VersionInfo.Version;
FileVersionInfo fileVersion = FileVersionInfo.GetVersionInfo(executableFile.Name);
if (string.Equals(fileVersion.FileDescription, "SlunkCrypt", StringComparison.OrdinalIgnoreCase) &&
string.Equals(fileVersion.CompanyName, "Muldersoft", StringComparison.OrdinalIgnoreCase) &&
(fileVersion.FileMajorPart == appVersion.Major) && (fileVersion.FileMinorPart == appVersion.Minor))
{
return true;
}
executableFile.Dispose(); /*clean-up*/
}
catch { }
return false;
}
protected override double ParseProgressString(StringBuilder currentLine)
{
Match match;
double progress, result = double.NaN;
do
{
match = RX_PROGRESS.Match(currentLine.ToString());
if (match.Success)
{
if (!double.IsNaN(progress = ParseProgressValue(match)))
{
result = progress;
}
currentLine.Remove(match.Index, match.Length);
}
}
while (match.Success);
return result;
}
private static double ParseProgressValue(Match match)
{
uint intPart, fractPart;
if (uint.TryParse(match.Groups[1].Value, out intPart) && uint.TryParse(match.Groups[2].Value, out fractPart))
{
return ((intPart * 10) + fractPart) / 1000.0;
}
return double.NaN;
}
private static string GetCommandString(Mode mode)
{
switch(mode)
{
case Mode.Encrypt:
return COMMAND_ENCRYPT;
case Mode.Decrypt:
return COMMAND_DECRYPT;
default:
throw new ArgumentException("Invalid mode!");
}
}
}
}