GUI: Hide the options for "legacy" compatibility mode by default + some improvements on error handling.
This commit is contained in:
parent
cc3f9da1d2
commit
aaecd43e2d
@ -63,6 +63,9 @@ The following settings can be adjusted in the `slunkcrypt-gui.exe.config` config
|
|||||||
- **`KeepIncompleteFiles`:**
|
- **`KeepIncompleteFiles`:**
|
||||||
If set to `true`, incomplete or corrupted output files will *not* be deleted — default value: `false`.
|
If set to `true`, incomplete or corrupted output files will *not* be deleted — default value: `false`.
|
||||||
|
|
||||||
|
- **`LegacyCompat`:**
|
||||||
|
If set to `1`, show options to enable “legacy” compatibility-mode in the GUI; if set to `2`, select “legacy” compatibility-mode by default — default value: `0`.
|
||||||
|
|
||||||
Command-line Usage
|
Command-line Usage
|
||||||
==================
|
==================
|
||||||
|
|
||||||
@ -132,7 +135,7 @@ The following environment variables may be used:
|
|||||||
Specifies the number of worker threads to use. By default, SlunkCrypt detects the number of available processors and creates one thread for each processor.
|
Specifies the number of worker threads to use. By default, SlunkCrypt detects the number of available processors and creates one thread for each processor.
|
||||||
|
|
||||||
- **`SLUNK_LEGACY_COMPAT`**:
|
- **`SLUNK_LEGACY_COMPAT`**:
|
||||||
If set to a *non-zero* value, enables "legacy" compatibility-mode, required to decrypt files encrypted with SlunkCrypt version 1.2.x or older.
|
If set to a *non-zero* value, enables “legacy” compatibility-mode, required to decrypt files encrypted with SlunkCrypt version 1.2.x or older.
|
||||||
|
|
||||||
- **`SLUNK_DEBUG_LOGGING`**:
|
- **`SLUNK_DEBUG_LOGGING`**:
|
||||||
If set to a *non-zero* value, enables additional logging output to the syslog (Unix-like) or to the debugger (Windows). This is intended for debugging purposes only!
|
If set to a *non-zero* value, enables additional logging output to the syslog (Unix-like) or to the debugger (Windows). This is intended for debugging purposes only!
|
||||||
|
@ -7,6 +7,6 @@
|
|||||||
<add key="DisableBusyIndicator" value="false"/>
|
<add key="DisableBusyIndicator" value="false"/>
|
||||||
<add key="ThreadCount" value="0"/>
|
<add key="ThreadCount" value="0"/>
|
||||||
<add key="KeepIncompleteFiles" value="false"/>
|
<add key="KeepIncompleteFiles" value="false"/>
|
||||||
<add key="LegacyCompat" value="false"/>
|
<add key="LegacyCompat" value="0"/>
|
||||||
</appSettings>
|
</appSettings>
|
||||||
</configuration>
|
</configuration>
|
||||||
|
@ -19,6 +19,8 @@ namespace com.muldersoft.slunkcrypt.gui.process
|
|||||||
{
|
{
|
||||||
public enum Mode { Encrypt, Decrypt }
|
public enum Mode { Encrypt, Decrypt }
|
||||||
|
|
||||||
|
public enum Error { Checksum, Password }
|
||||||
|
|
||||||
public struct SlunkOptions
|
public struct SlunkOptions
|
||||||
{
|
{
|
||||||
public SlunkOptions(bool keepIncompleteFiles, int threadCount, bool enableLegacyCompat)
|
public SlunkOptions(bool keepIncompleteFiles, int threadCount, bool enableLegacyCompat)
|
||||||
@ -40,7 +42,14 @@ namespace com.muldersoft.slunkcrypt.gui.process
|
|||||||
private const bool ENABLE_DEBUG_LOGGING = false;
|
private const bool ENABLE_DEBUG_LOGGING = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
private static readonly Regex RX_PROGRESS = new Regex(@"(\d+)\.(\d)%", RegexOptions.Compiled);
|
private static readonly Regex RX_PROGRESS = new Regex(@"(\d+)\.(\d)%", RegexOptions.Compiled | RegexOptions.CultureInvariant);
|
||||||
|
|
||||||
|
private static readonly IReadOnlyDictionary<Error, Regex> RX_ERROR = new Dictionary<Error, Regex>
|
||||||
|
{
|
||||||
|
{ Error.Checksum, new Regex(@"\bChecksum\s+mismatch\s+detected\b", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.CultureInvariant) },
|
||||||
|
{ Error.Password, new Regex(@"\bThe\s+given\s+passphrase\s+is\s+forbidden\s+as\s+a\s+precautionary\s+measure\b", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.CultureInvariant) }
|
||||||
|
}
|
||||||
|
.ToReadOnlyDictionary();
|
||||||
|
|
||||||
private readonly FileStream m_executableFile;
|
private readonly FileStream m_executableFile;
|
||||||
|
|
||||||
@ -63,12 +72,15 @@ namespace com.muldersoft.slunkcrypt.gui.process
|
|||||||
{
|
{
|
||||||
throw new ArgumentException("Invalid SlunkCrypt parameters!");
|
throw new ArgumentException("Invalid SlunkCrypt parameters!");
|
||||||
}
|
}
|
||||||
Dictionary<string, string> environmentVariables = new Dictionary<string, string>();
|
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)));
|
{ "SLUNK_PASSPHRASE", password },
|
||||||
environmentVariables.Add("SLUNK_THREADS", Convert.ToString(Math.Max(0, Math.Min(32, options.HasValue ? options.Value.threadCount : 0))));
|
{ "SLUNK_KEEP_INCOMPLETE", Convert.ToString(Convert.ToInt32(options.HasValue ? options.Value.keepIncompleteFiles : false)) },
|
||||||
environmentVariables.Add("SLUNK_LEGACY_COMPAT", Convert.ToString(Convert.ToInt32(options.HasValue ? options.Value.enableLegacyCompat : false)));
|
{ "SLUNK_THREADS", Convert.ToString(Math.Max(0, Math.Min(32, options.HasValue ? options.Value.threadCount : 0))) },
|
||||||
environmentVariables.Add("SLUNK_DEBUG_LOGGING", Convert.ToString(Convert.ToInt32(ENABLE_DEBUG_LOGGING)));
|
{ "SLUNK_LEGACY_COMPAT", Convert.ToString(Convert.ToInt32(options.HasValue ? options.Value.enableLegacyCompat : false)) },
|
||||||
|
{ "SLUNK_DEBUG_LOGGING", Convert.ToString(Convert.ToInt32(ENABLE_DEBUG_LOGGING)) }
|
||||||
|
};
|
||||||
|
ErrorState = null;
|
||||||
return await ExecAsnyc(m_executableFile.Name, new string[] { GetCommandString(mode), inputFile, outputFile }, Path.GetDirectoryName(outputFile), environmentVariables);
|
return await ExecAsnyc(m_executableFile.Name, new string[] { GetCommandString(mode), inputFile, outputFile }, Path.GetDirectoryName(outputFile), environmentVariables);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,23 +94,34 @@ namespace com.muldersoft.slunkcrypt.gui.process
|
|||||||
catch { }
|
catch { }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Error? ErrorState { get; private set; } = null;
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// Internal methods
|
// Internal methods
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
|
|
||||||
protected override double ParseProgressString(ref string currentLine, bool stream)
|
protected override double ParseProgressString(ref string currentLine, bool stream)
|
||||||
{
|
{
|
||||||
double temp, result = double.NaN;
|
|
||||||
int index = int.MaxValue;
|
int index = int.MaxValue;
|
||||||
Match match = RX_PROGRESS.Match(currentLine);
|
double temp = double.NaN, result = double.NaN;
|
||||||
while (match.Success)
|
if (!ErrorState.HasValue)
|
||||||
|
{
|
||||||
|
foreach (KeyValuePair<Error, Regex> errorRegex in RX_ERROR)
|
||||||
|
{
|
||||||
|
if (errorRegex.Value.IsMatch(currentLine))
|
||||||
|
{
|
||||||
|
ErrorState = errorRegex.Key;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (Match match = RX_PROGRESS.Match(currentLine); match.Success; match = match.NextMatch())
|
||||||
{
|
{
|
||||||
if (TryParseProgressValue(match, out temp))
|
if (TryParseProgressValue(match, out temp))
|
||||||
{
|
{
|
||||||
result = temp;
|
result = double.IsNaN(result) ? temp : Math.Max(result, temp);
|
||||||
}
|
}
|
||||||
index = Math.Min(index, match.Index);
|
index = Math.Min(index, match.Index);
|
||||||
match = RX_PROGRESS.Match(currentLine, match.Index + match.Length);
|
|
||||||
}
|
}
|
||||||
if (index != int.MaxValue)
|
if (index != int.MaxValue)
|
||||||
{
|
{
|
||||||
|
@ -82,6 +82,7 @@
|
|||||||
<DependentUpon>PasswordToggleBox.xaml</DependentUpon>
|
<DependentUpon>PasswordToggleBox.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Properties\_Version.cs" />
|
<Compile Include="Properties\_Version.cs" />
|
||||||
|
<Compile Include="Utilities\DictionaryHelper.cs" />
|
||||||
<Compile Include="Utilities\EnumHelper.cs" />
|
<Compile Include="Utilities\EnumHelper.cs" />
|
||||||
<Compile Include="Process\ExecutableHelper.cs" />
|
<Compile Include="Process\ExecutableHelper.cs" />
|
||||||
<Compile Include="Utilities\ApplicationConfig.cs" />
|
<Compile Include="Utilities\ApplicationConfig.cs" />
|
||||||
|
@ -49,7 +49,7 @@ namespace com.muldersoft.slunkcrypt.gui
|
|||||||
|
|
||||||
private volatile int m_isInitialized = 0;
|
private volatile int m_isInitialized = 0;
|
||||||
private volatile ModeOfOperation m_modeOfOperation = (ModeOfOperation)(-1);
|
private volatile ModeOfOperation m_modeOfOperation = (ModeOfOperation)(-1);
|
||||||
private volatile bool m_busyFlag = false, m_checksumError = false, m_processReceived = false, m_disableAnimation = false;
|
private volatile bool m_busyFlag = false, m_processReceived = false, m_disableAnimation = false;
|
||||||
private volatile SlunkCryptRunner m_processRunner = null;
|
private volatile SlunkCryptRunner m_processRunner = null;
|
||||||
private uint? m_menuId_disableAnimation = null, m_menuId_enableExpertMode = null;
|
private uint? m_menuId_disableAnimation = null, m_menuId_enableExpertMode = null;
|
||||||
|
|
||||||
@ -68,6 +68,10 @@ namespace com.muldersoft.slunkcrypt.gui
|
|||||||
m_dispatcherTimer.Interval = TimeSpan.FromMilliseconds(331);
|
m_dispatcherTimer.Interval = TimeSpan.FromMilliseconds(331);
|
||||||
m_logFileReadOnly = new ReadOnlyObservableCollection<string>(m_logFile);
|
m_logFileReadOnly = new ReadOnlyObservableCollection<string>(m_logFile);
|
||||||
m_disableAnimation = m_config.DisableBusyIndicator;
|
m_disableAnimation = m_config.DisableBusyIndicator;
|
||||||
|
if (m_config.LegacyCompat < 1)
|
||||||
|
{
|
||||||
|
Checkbox_Encrypt_LegacyCompat.Visibility = Checkbox_Decrypt_LegacyCompat.Visibility = Visibility.Collapsed;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
@ -125,7 +129,7 @@ namespace com.muldersoft.slunkcrypt.gui
|
|||||||
{
|
{
|
||||||
Hint_SoftwareRendering.Visibility = Visibility.Visible;
|
Hint_SoftwareRendering.Visibility = Visibility.Visible;
|
||||||
}
|
}
|
||||||
if (m_config.LegacyCompat)
|
if (m_config.LegacyCompat > 1)
|
||||||
{
|
{
|
||||||
Checkbox_Encrypt_LegacyCompat.IsChecked = Checkbox_Decrypt_LegacyCompat.IsChecked = true;
|
Checkbox_Encrypt_LegacyCompat.IsChecked = Checkbox_Decrypt_LegacyCompat.IsChecked = true;
|
||||||
}
|
}
|
||||||
@ -273,10 +277,6 @@ namespace com.muldersoft.slunkcrypt.gui
|
|||||||
private void Process_OutputAvailable(string line, bool stderr)
|
private void Process_OutputAvailable(string line, bool stderr)
|
||||||
{
|
{
|
||||||
AppendLogFile(line);
|
AppendLogFile(line);
|
||||||
if (line.IndexOf("Checksum mismatch detected!", StringComparison.OrdinalIgnoreCase) >= 0)
|
|
||||||
{
|
|
||||||
m_checksumError = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Porcess_ProgressChanged(double progress)
|
private void Porcess_ProgressChanged(double progress)
|
||||||
@ -522,7 +522,7 @@ namespace com.muldersoft.slunkcrypt.gui
|
|||||||
|
|
||||||
private async Task ValidatePassword(string inputFilePath, string outputFilePath, PasswordToggleBox passwordEdit, CheckBox legacyCheckBox, SlunkProcessor processor, bool checkStrongPasswd)
|
private async Task ValidatePassword(string inputFilePath, string outputFilePath, PasswordToggleBox passwordEdit, CheckBox legacyCheckBox, SlunkProcessor processor, bool checkStrongPasswd)
|
||||||
{
|
{
|
||||||
bool enableLegacyCompat = legacyCheckBox.IsChecked.GetValueOrDefault();
|
bool enableLegacyCompat = (m_config.LegacyCompat > 0) && legacyCheckBox.IsChecked.GetValueOrDefault(m_config.LegacyCompat > 1);
|
||||||
string passwordStr;
|
string passwordStr;
|
||||||
if (string.IsNullOrEmpty(passwordStr = passwordEdit.Password) || (passwordStr.Length < MIN_PASSWD_LENGTH))
|
if (string.IsNullOrEmpty(passwordStr = passwordEdit.Password) || (passwordStr.Length < MIN_PASSWD_LENGTH))
|
||||||
{
|
{
|
||||||
@ -548,7 +548,7 @@ namespace com.muldersoft.slunkcrypt.gui
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (enableLegacyCompat && (!m_config.LegacyCompat))
|
if (enableLegacyCompat && (m_config.LegacyCompat < 2))
|
||||||
{
|
{
|
||||||
if (MessageBox.Show(this, "Legacy compat-mode should not be used to encrypt new files!", "Legacy Compatibility", MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel) != MessageBoxResult.OK)
|
if (MessageBox.Show(this, "Legacy compat-mode should not be used to encrypt new files!", "Legacy Compatibility", MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel) != MessageBoxResult.OK)
|
||||||
{
|
{
|
||||||
@ -567,7 +567,7 @@ namespace com.muldersoft.slunkcrypt.gui
|
|||||||
ResetKeyboardFocus(this);
|
ResetKeyboardFocus(this);
|
||||||
SetProgress(double.PositiveInfinity);
|
SetProgress(double.PositiveInfinity);
|
||||||
ClearLogFile();
|
ClearLogFile();
|
||||||
Button_Decrypt_Toggle.IsChecked = Button_Encrypt_Toggle.IsChecked = m_checksumError = m_processReceived = false;
|
Button_Decrypt_Toggle.IsChecked = Button_Encrypt_Toggle.IsChecked = m_processReceived = false;
|
||||||
if (!await processor(inputFile, outputFile, password, enableLegacyCompat))
|
if (!await processor(inputFile, outputFile, password, enableLegacyCompat))
|
||||||
{
|
{
|
||||||
if (!m_config.KeepIncompleteFiles)
|
if (!m_config.KeepIncompleteFiles)
|
||||||
@ -583,10 +583,10 @@ namespace com.muldersoft.slunkcrypt.gui
|
|||||||
private async Task<bool> Encrypt(string inputFile, string outputFile, string password, bool enableLegacyCompat)
|
private async Task<bool> Encrypt(string inputFile, string outputFile, string password, bool enableLegacyCompat)
|
||||||
{
|
{
|
||||||
SetStatus("Please wait while the encryption process is initializing...");
|
SetStatus("Please wait while the encryption process is initializing...");
|
||||||
int? exitCode = await RunProcess(SlunkCryptRunner.Mode.Encrypt, inputFile, outputFile, password, enableLegacyCompat);
|
Tuple<int, SlunkCryptRunner.Error?> result = await RunProcess(SlunkCryptRunner.Mode.Encrypt, inputFile, outputFile, password, enableLegacyCompat);
|
||||||
if (exitCode.HasValue)
|
if (!ReferenceEquals(result, null))
|
||||||
{
|
{
|
||||||
if (exitCode.Value == 0)
|
if (result.Item1 == 0)
|
||||||
{
|
{
|
||||||
SetProgress(1);
|
SetProgress(1);
|
||||||
SetStatus("Completed: The file has been encrypted successfully.", Status.Success);
|
SetStatus("Completed: The file has been encrypted successfully.", Status.Success);
|
||||||
@ -594,8 +594,16 @@ namespace com.muldersoft.slunkcrypt.gui
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SetProgress(1, true);
|
switch (result.Item2)
|
||||||
|
{
|
||||||
|
case SlunkCryptRunner.Error.Password:
|
||||||
|
SetStatus("Error: The specified passphrase is forbidden! (contained in OWASP database)", Status.Failure);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
SetStatus("Error: Failed to enecrypt the file. Please see the log file for details!", Status.Failure);
|
SetStatus("Error: Failed to enecrypt the file. Please see the log file for details!", Status.Failure);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
SetProgress(1, true);
|
||||||
SystemSounds.Hand.Play();
|
SystemSounds.Hand.Play();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -606,10 +614,10 @@ namespace com.muldersoft.slunkcrypt.gui
|
|||||||
private async Task<bool> Decrypt(string inputFile, string outputFile, string password, bool enableLegacyCompat)
|
private async Task<bool> Decrypt(string inputFile, string outputFile, string password, bool enableLegacyCompat)
|
||||||
{
|
{
|
||||||
SetStatus("Please wait while the decryption process is initializing...");
|
SetStatus("Please wait while the decryption process is initializing...");
|
||||||
int? exitCode = await RunProcess(SlunkCryptRunner.Mode.Decrypt, inputFile, outputFile, password, enableLegacyCompat);
|
Tuple<int, SlunkCryptRunner.Error?> result = await RunProcess(SlunkCryptRunner.Mode.Decrypt, inputFile, outputFile, password, enableLegacyCompat);
|
||||||
if (exitCode.HasValue)
|
if (!ReferenceEquals(result, null))
|
||||||
{
|
{
|
||||||
if (exitCode.Value == 0)
|
if (result.Item1 == 0)
|
||||||
{
|
{
|
||||||
SetStatus("Completed: The file has been decrypted successfully (checksum is correct).", Status.Success);
|
SetStatus("Completed: The file has been decrypted successfully (checksum is correct).", Status.Success);
|
||||||
SetProgress(1);
|
SetProgress(1);
|
||||||
@ -617,13 +625,14 @@ namespace com.muldersoft.slunkcrypt.gui
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (m_checksumError)
|
switch (result.Item2)
|
||||||
{
|
{
|
||||||
|
case SlunkCryptRunner.Error.Checksum:
|
||||||
SetStatus("Error: Checksum mismatch detected! Wrong passphrase or corrupted file?", Status.Failure);
|
SetStatus("Error: Checksum mismatch detected! Wrong passphrase or corrupted file?", Status.Failure);
|
||||||
}
|
break;
|
||||||
else
|
default:
|
||||||
{
|
|
||||||
SetStatus("Error: Failed to decrypt the file. Please see the log file for details!", Status.Failure);
|
SetStatus("Error: Failed to decrypt the file. Please see the log file for details!", Status.Failure);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
SetProgress(1, true);
|
SetProgress(1, true);
|
||||||
SystemSounds.Hand.Play();
|
SystemSounds.Hand.Play();
|
||||||
@ -633,7 +642,7 @@ namespace com.muldersoft.slunkcrypt.gui
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<int?> RunProcess(SlunkCryptRunner.Mode mode, string inputFile, string outputFile, string password, bool enableLegacyCompat)
|
private async Task<Tuple<int, SlunkCryptRunner.Error?>> RunProcess(SlunkCryptRunner.Mode mode, string inputFile, string outputFile, string password, bool enableLegacyCompat)
|
||||||
{
|
{
|
||||||
if (!ReferenceEquals(m_processRunner, null))
|
if (!ReferenceEquals(m_processRunner, null))
|
||||||
{
|
{
|
||||||
@ -647,7 +656,8 @@ namespace com.muldersoft.slunkcrypt.gui
|
|||||||
m_processRunner.OutputAvailable += Process_OutputAvailable;
|
m_processRunner.OutputAvailable += Process_OutputAvailable;
|
||||||
m_processRunner.ProgressChanged += Porcess_ProgressChanged;
|
m_processRunner.ProgressChanged += Porcess_ProgressChanged;
|
||||||
SetProcessPriority(ProcessPriorityClass.AboveNormal);
|
SetProcessPriority(ProcessPriorityClass.AboveNormal);
|
||||||
return await m_processRunner.ExecuteAsync(mode, inputFile, outputFile, password, options);
|
int exitCode = await m_processRunner.ExecuteAsync(mode, inputFile, outputFile, password, options);
|
||||||
|
return Tuple.Create(exitCode, m_processRunner.ErrorState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (ProcessRunner.ProcessStartException err)
|
catch (ProcessRunner.ProcessStartException err)
|
||||||
|
@ -34,15 +34,15 @@ namespace com.muldersoft.slunkcrypt.gui.utils
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return ComputeIfAbsent("ThreadCount", (key) => AppConfHelper.GetConfigValueAsInt32(key).GetValueOrDefault(0));
|
return ComputeIfAbsent("ThreadCount", (key) => Clamp(0, AppConfHelper.GetConfigValueAsInt32(key).GetValueOrDefault(0), 32));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool LegacyCompat
|
public int LegacyCompat
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return ComputeIfAbsent("LegacyCompat", (key) => AppConfHelper.GetConfigValueAsBool(key).GetValueOrDefault(false));
|
return ComputeIfAbsent("LegacyCompat", (key) => Clamp(0, AppConfHelper.GetConfigValueAsInt32(key).GetValueOrDefault(0), 2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,6 +60,11 @@ namespace com.muldersoft.slunkcrypt.gui.utils
|
|||||||
return Convert.ToBoolean(m_cache.GetOrAdd(name, (key) => Convert.ToInt32(valueFactory(key))));
|
return Convert.ToBoolean(m_cache.GetOrAdd(name, (key) => Convert.ToInt32(valueFactory(key))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected static int Clamp(int min, int value, int max)
|
||||||
|
{
|
||||||
|
return (value < min) ? min : ((value > max) ? max : value);
|
||||||
|
}
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// Helper class
|
// Helper class
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
@ -116,6 +121,14 @@ namespace com.muldersoft.slunkcrypt.gui.utils
|
|||||||
{
|
{
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bool boolean;
|
||||||
|
if (bool.TryParse(value.Trim(), out boolean))
|
||||||
|
{
|
||||||
|
return Convert.ToInt32(boolean);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
18
gui/Utilities/DictionaryHelper.cs
Normal file
18
gui/Utilities/DictionaryHelper.cs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
/******************************************************************************/
|
||||||
|
/* SlunkCrypt, by LoRd_MuldeR <MuldeR2@GMX.de> */
|
||||||
|
/* This work has been released under the CC0 1.0 Universal license! */
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
|
||||||
|
namespace com.muldersoft.slunkcrypt.gui.utils
|
||||||
|
{
|
||||||
|
public static class DictionaryHelper
|
||||||
|
{
|
||||||
|
public static IReadOnlyDictionary<K, V> ToReadOnlyDictionary<K, V>(this IDictionary<K, V> dict)
|
||||||
|
{
|
||||||
|
return (dict is ReadOnlyDictionary<K, V>) ? ((ReadOnlyDictionary<K, V>)dict) : new ReadOnlyDictionary<K, V>(dict);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user