using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Text.RegularExpressions; using System.Threading.Tasks; using DICUI.Utilities; namespace DICUI.Data { public abstract class BaseParameters { /// /// Path to the executable /// public string ExecutablePath { get; set; } /// /// Program that this set of parameters represents /// public InternalProgram InternalProgram { get; set; } /// /// Process to track external program /// private Process process; /// /// Populate a Parameters object from a param string /// /// String possibly representing a set of parameters public BaseParameters(string parameters) { // If any parameters are not valid, wipe out everything if (!ValidateAndSetParameters(parameters)) { ResetValues(); } } /// /// Generate parameters based on a set of known inputs /// /// KnownSystem value to use /// MediaType value to use /// Drive letter to use /// Filename to use /// Drive speed to use /// Enable paranoid mode (safer dumping) /// Enable quiet mode (no beeps) /// User-defined reread count public BaseParameters(KnownSystem? system, MediaType? type, char driveLetter, string filename, int? driveSpeed, bool paranoid, bool quietMode, int retryCount) { SetDefaultParameters(system, type, driveLetter, filename, driveSpeed, paranoid, retryCount); } /// /// Blindly generate a parameter string based on the inputs /// /// Correctly formatted parameter string, null on error public abstract string GenerateParameters(); /// /// Get the input path from the implementation /// /// String representing the path, null on error public abstract string InputPath(); /// /// Get the output path from the implementation /// /// String representing the path, null on error public abstract string OutputPath(); /// /// Get the processing speed from the implementation /// /// int? representing the speed, null on error public abstract int? GetSpeed(); /// /// Set the processing speed int the implementation /// /// int? representing the speed public abstract void SetSpeed(int? speed); /// /// Get the MediaType from the current set of parameters /// /// MediaType value if successful, null on error public abstract MediaType? GetMediaType(); /// /// Gets if the current command is considered a dumping command or not /// /// True if it's a dumping command, false otherwise public abstract bool IsDumpingCommand(); /// /// Returns if the current Parameter object is valid /// /// public bool IsValid() { return GenerateParameters() != null; } /// /// Reset all special variables to have default values /// protected abstract void ResetValues(); /// /// Set default parameters for a given system and media type /// /// KnownSystem value to use /// MediaType value to use /// Drive letter to use /// Filename to use /// Drive speed to use /// Enable paranoid mode (safer dumping) /// User-defined reread count protected abstract void SetDefaultParameters( KnownSystem? system, MediaType? type, char driveLetter, string filename, int? driveSpeed, bool paranoid, int retryCount); /// /// Scan a possible parameter string and populate whatever possible /// /// String possibly representing parameters /// protected abstract bool ValidateAndSetParameters(string parameters); /// /// Validate if all required output files exist /// /// Base filename and path to use for checking /// KnownSystem type representing the media /// MediaType type representing the media /// public abstract bool CheckAllOutputFilesExist(string basePath, KnownSystem? system, MediaType? type); /// /// Generate a SubmissionInfo for the output files /// /// Base submission info to fill in specifics for /// Base filename and path to use for checking /// KnownSystem type representing the media /// MediaType type representing the media /// Drive representing the disc to get information from public abstract void GenerateSubmissionInfo(SubmissionInfo submissionInfo, string basePath, KnownSystem? system, MediaType? type, Drive drive); /// /// Run internal program /// public void ExecuteInternalProgram() { process = new Process() { StartInfo = new ProcessStartInfo() { FileName = ExecutablePath, Arguments = GenerateParameters() ?? "", }, }; process.Start(); process.WaitForExit(); } /// /// Run internal program async with an input set of parameters /// /// /// Standard output from commandline window public async Task ExecuteInternalProgram(BaseParameters parameters) { Process childProcess; string output = await Task.Run(() => { childProcess = new Process() { StartInfo = new ProcessStartInfo() { FileName = parameters.ExecutablePath, Arguments = parameters.GenerateParameters(), CreateNoWindow = true, UseShellExecute = false, RedirectStandardInput = true, RedirectStandardOutput = true, }, }; childProcess.Start(); childProcess.WaitForExit(1000); // Just in case, we want to push a button 5 times to clear any errors for (int i = 0; i < 5; i++) childProcess.StandardInput.WriteLine("Y"); string stdout = childProcess.StandardOutput.ReadToEnd(); childProcess.Dispose(); return stdout; }); return output; } /// /// Cancel an in-progress dumping process /// public void KillInternalProgram() { try { if (process != null && !process.HasExited) process.Kill(); } catch { } } /// /// Returns whether or not the selected item exists /// /// List of parameters to check against /// Current index /// True if the next item exists, false otherwise protected bool DoesExist(List parameters, int index) { if (index >= parameters.Count) return false; return true; } /// /// Get the full lines from the input file, if possible /// /// file location /// True if should read as binary, false otherwise (default) /// Full text of the file, null on error protected string GetFullFile(string filename, bool binary = false) { // If the file doesn't exist, we can't get info from it if (!File.Exists(filename)) return null; // If we're reading as binary if (binary) { string hex = string.Empty; using (BinaryReader br = new BinaryReader(File.OpenRead(filename))) { while (br.BaseStream.Position < br.BaseStream.Length) { hex += Convert.ToString(br.ReadByte(), 16); } } return hex; } return string.Join("\n", File.ReadAllLines(filename)); } /// /// Returns whether a string is a flag (starts with '/') /// /// String value to check /// True if it's a flag, false otherwise protected bool IsFlag(string parameter) { if (parameter.Trim('\"').StartsWith("/")) return true; return false; } /// /// Returns whether a string is a valid drive letter /// /// String value to check /// True if it's a valid drive letter, false otherwise protected bool IsValidDriveLetter(string parameter) { if (!Regex.IsMatch(parameter, @"^[A-Z]:?\\?$")) return false; return true; } /// /// Returns whether a string is a valid bool /// /// String value to check /// True if it's a valid bool, false otherwise protected bool IsValidBool(string parameter) { return bool.TryParse(parameter, out bool temp); } /// /// Returns whether a string is a valid byte /// /// String value to check /// Lower bound (>=) /// Upper bound (<=) /// True if it's a valid byte, false otherwise protected bool IsValidInt8(string parameter, sbyte lowerBound = -1, sbyte upperBound = -1) { if (!sbyte.TryParse(parameter, out sbyte temp)) return false; else if (lowerBound != -1 && temp < lowerBound) return false; else if (upperBound != -1 && temp > upperBound) return false; return true; } /// /// Returns whether a string is a valid Int16 /// /// String value to check /// Lower bound (>=) /// Upper bound (<=) /// True if it's a valid Int16, false otherwise protected bool IsValidInt16(string parameter, short lowerBound = -1, short upperBound = -1) { if (!short.TryParse(parameter, out short temp)) return false; else if (lowerBound != -1 && temp < lowerBound) return false; else if (upperBound != -1 && temp > upperBound) return false; return true; } /// /// Returns whether a string is a valid Int32 /// /// String value to check /// Lower bound (>=) /// Upper bound (<=) /// True if it's a valid Int32, false otherwise protected bool IsValidInt32(string parameter, int lowerBound = -1, int upperBound = -1) { if (!int.TryParse(parameter, out int temp)) return false; else if (lowerBound != -1 && temp < lowerBound) return false; else if (upperBound != -1 && temp > upperBound) return false; return true; } /// /// Returns whether a string is a valid Int64 /// /// String value to check /// Lower bound (>=) /// Upper bound (<=) /// True if it's a valid Int64, false otherwise protected bool IsValidInt64(string parameter, long lowerBound = -1, long upperBound = -1) { if (!long.TryParse(parameter, out long temp)) return false; else if (lowerBound != -1 && temp < lowerBound) return false; else if (upperBound != -1 && temp > upperBound) return false; return true; } } }