SlunkCrypt/gui/Process/SlunkCryptRunner.cs

136 lines
5.5 KiB
C#
Raw Permalink Normal View History

/******************************************************************************/
/* 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.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 }
public struct SlunkOptions
{
public SlunkOptions(bool keepIncompleteFiles, int threadCount, bool enableLegacyCompat)
{
this.keepIncompleteFiles = keepIncompleteFiles;
this.threadCount = threadCount;
this.enableLegacyCompat = enableLegacyCompat;
}
public readonly bool keepIncompleteFiles, enableLegacyCompat;
public readonly int threadCount;
}
private const string COMMAND_ENCRYPT = "-e";
private const string COMMAND_DECRYPT = "-d";
#if DEBUG
private const bool ENABLE_DEBUG_LOGGING = true;
#else
private const bool ENABLE_DEBUG_LOGGING = false;
#endif
private static readonly Regex RX_PROGRESS = new Regex(@"(\d+)\.(\d)%", RegexOptions.Compiled);
private readonly FileStream m_executableFile;
// =============================================================================
// Constructor
// =============================================================================
public SlunkCryptRunner(Dispatcher dispatcher, ProcessPriorityClass? priorityClass = null) : base(dispatcher, priorityClass)
{
m_executableFile = ExecutableHelper.GetExecutableFile();
}
// =============================================================================
// Public methods
// =============================================================================
public async Task<int> ExecuteAsync(Mode mode, string inputFile, string outputFile, string password, SlunkOptions? options = null)
{
if ((!EnumHelper.IsDefined(mode)) || string.IsNullOrWhiteSpace(inputFile) || string.IsNullOrWhiteSpace(outputFile) || string.IsNullOrWhiteSpace(password))
{
throw new ArgumentException("Invalid SlunkCrypt parameters!");
}
Dictionary<string, string> environmentVariables = new Dictionary<string, string>();
environmentVariables.Add("SLUNK_PASSPHRASE", password);
environmentVariables.Add("SLUNK_KEEP_INCOMPLETE", Convert.ToString(Convert.ToInt32(options.HasValue ? options.Value.keepIncompleteFiles : false)));
environmentVariables.Add("SLUNK_THREADS", Convert.ToString(Math.Max(0, Math.Min(32, options.HasValue ? options.Value.threadCount : 0))));
environmentVariables.Add("SLUNK_LEGACY_COMPAT", Convert.ToString(Convert.ToInt32(options.HasValue ? options.Value.enableLegacyCompat : false)));
environmentVariables.Add("SLUNK_DEBUG_LOGGING", Convert.ToString(Convert.ToInt32(ENABLE_DEBUG_LOGGING)));
return await ExecAsnyc(m_executableFile.Name, new string[] { GetCommandString(mode), inputFile, outputFile }, Path.GetDirectoryName(outputFile), environmentVariables);
}
public override void Dispose()
{
base.Dispose();
try
{
m_executableFile.Dispose();
}
catch { }
}
// =============================================================================
// Internal methods
// =============================================================================
protected override double ParseProgressString(ref string currentLine, bool stream)
{
double temp, result = double.NaN;
int index = int.MaxValue;
Match match = RX_PROGRESS.Match(currentLine);
while (match.Success)
{
if (TryParseProgressValue(match, out temp))
{
result = temp;
}
index = Math.Min(index, match.Index);
match = RX_PROGRESS.Match(currentLine, match.Index + match.Length);
}
if (index != int.MaxValue)
{
currentLine = (index > 0) ? currentLine.Substring(0, index - 1).TrimEnd() : string.Empty;
}
return result;
}
private static bool TryParseProgressValue(Match match, out double progress)
{
uint intPart, fractPart;
if (uint.TryParse(match.Groups[1].Value, out intPart) && uint.TryParse(match.Groups[2].Value, out fractPart))
{
progress = ((intPart * 10) + fractPart) / 1000.0;
return true;
}
progress = double.NaN;
return false;
}
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!");
}
}
}
}