diff --git a/MainWindow.xaml b/MainWindow.xaml
index 5188c895..9f8e491d 100644
--- a/MainWindow.xaml
+++ b/MainWindow.xaml
@@ -58,8 +58,8 @@
-
-
+
+
diff --git a/MainWindow.xaml.cs b/MainWindow.xaml.cs
index 5939fecf..1563e470 100644
--- a/MainWindow.xaml.cs
+++ b/MainWindow.xaml.cs
@@ -195,25 +195,44 @@ namespace DICUI
///
private async void StartDumping()
{
- // Local variables
- var driveLetter = cmb_DriveLetter.SelectedItem as Tuple;
- string outputDirectory = txt_OutputDirectory.Text;
- string outputFilename = txt_OutputFilename.Text;
btn_StartStop.Content = UIElements.StopDumping;
- // Get the currently selected item
+ // Get the currently selected options
+ var driveLetterTuple = cmb_DriveLetter.SelectedItem as Tuple;
+ char driveLetter = driveLetterTuple.Item1;
+ bool isFloppy = driveLetterTuple.Item3;
+
+ string outputDirectory = txt_OutputDirectory.Text;
+ string outputFilename = txt_OutputFilename.Text;
+
var selected = cmb_DiscType.SelectedValue as Tuple;
+ string systemName = selected.Item1;
+ KnownSystem? system = selected.Item2;
+ DiscType? type = selected.Item3;
+
+ string customParameters = txt_Parameters.Text;
// Validate that everything is good
- if (string.IsNullOrWhiteSpace(txt_CustomParameters.Text)
- || !Utilities.ValidateParameters(txt_CustomParameters.Text)
- || (driveLetter.Item3 ^ selected.Item3 == DiscType.Floppy))
+ if (string.IsNullOrWhiteSpace(customParameters)
+ || !Utilities.ValidateParameters(customParameters)
+ || (isFloppy ^ type == DiscType.Floppy))
{
lbl_Status.Content = "Error! Current configuration is not supported!";
btn_StartStop.Content = UIElements.StartDumping;
return;
}
+ // If we have a known custom configuration, we need to extract the relevant information from it
+ if (systemName == "Custom Input" && system == KnownSystem.NONE && type == DiscType.NONE)
+ {
+ Utilities.DetermineFlags(customParameters, out string command, out string letter, out string path);
+ type = Utilities.GetDiscType(command);
+ system = Utilities.GetKnownSystem(type);
+ driveLetter = letter[0];
+ outputDirectory = Path.GetDirectoryName(path);
+ outputFilename = Path.GetFileName(path);
+ }
+
// Validate that the required program exits
if (!File.Exists(dicPath))
{
@@ -223,7 +242,7 @@ namespace DICUI
}
// If a complete dump already exists
- if (DumpInformation.FoundAllFiles(outputDirectory, outputFilename, selected.Item3))
+ if (DumpInformation.FoundAllFiles(outputDirectory, outputFilename, type))
{
MessageBoxResult result = MessageBox.Show("A complete dump already exists! Are you sure you want to overwrite?", "Overwrite?", MessageBoxButton.YesNo, MessageBoxImage.Exclamation);
if (result == MessageBoxResult.No || result == MessageBoxResult.Cancel || result == MessageBoxResult.None)
@@ -235,7 +254,7 @@ namespace DICUI
}
lbl_Status.Content = "Beginning dumping process";
- string parameters = txt_CustomParameters.Text;
+ string parameters = txt_Parameters.Text;
await Task.Run(() =>
{
@@ -257,7 +276,7 @@ namespace DICUI
}
// Special cases
- switch (selected.Item2)
+ switch (system)
{
case KnownSystem.MicrosoftXBOXOne:
case KnownSystem.SonyPlayStation4:
@@ -274,7 +293,7 @@ namespace DICUI
StartInfo = new ProcessStartInfo()
{
FileName = sgRawPath,
- Arguments = "-v -r 4100 -R " + driveLetter.Item1 + ": " + "ad 01 00 00 00 00 00 00 10 04 00 00 -o \"PIC.bin\""
+ Arguments = "-v -r 4100 -R " + driveLetter + ": " + "ad 01 00 00 00 00 00 00 10 04 00 00 -o \"PIC.bin\""
},
};
childProcess.Start();
@@ -295,7 +314,7 @@ namespace DICUI
StartInfo = new ProcessStartInfo()
{
FileName = subdumpPath,
- Arguments = "-i " + driveLetter.Item1 + ": -f " + Path.Combine(outputDirectory, Path.GetFileNameWithoutExtension(outputFilename) + "_subdump.sub") + "-mode 6 -rereadnum 25 -fix 2",
+ Arguments = "-i " + driveLetter + ": -f " + Path.Combine(outputDirectory, Path.GetFileNameWithoutExtension(outputFilename) + "_subdump.sub") + "-mode 6 -rereadnum 25 -fix 2",
},
};
childProcess.Start();
@@ -340,7 +359,7 @@ namespace DICUI
StartInfo = new ProcessStartInfo()
{
FileName = psxtPath,
- Arguments = "--libcryptdrvfast " + driveLetter.Item1 + " > " + "\"" + Path.Combine(outputDirectory, "libcryptdrv.log"),
+ Arguments = "--libcryptdrvfast " + driveLetter + " > " + "\"" + Path.Combine(outputDirectory, "libcryptdrv.log"),
},
};
childProcess.Start();
@@ -350,19 +369,25 @@ namespace DICUI
}
// Check to make sure that the output had all the correct files
- if (!DumpInformation.FoundAllFiles(outputDirectory, outputFilename, selected.Item3))
+ if (!DumpInformation.FoundAllFiles(outputDirectory, outputFilename, type))
{
lbl_Status.Content = "Error! Please check output directory as dump may be incomplete!";
btn_StartStop.Content = UIElements.StartDumping;
- EjectDisc();
+ if (chk_EjectWhenDone.IsChecked == true)
+ {
+ EjectDisc();
+ }
return;
}
lbl_Status.Content = "Dumping complete!";
- EjectDisc();
+ if (chk_EjectWhenDone.IsChecked == true)
+ {
+ EjectDisc();
+ }
- Dictionary templateValues = DumpInformation.ExtractOutputInformation(outputDirectory, outputFilename, selected.Item2, selected.Item3);
- List formattedValues = DumpInformation.FormatOutputData(templateValues, selected.Item2, selected.Item3);
+ Dictionary templateValues = DumpInformation.ExtractOutputInformation(outputDirectory, outputFilename, system, type);
+ List formattedValues = DumpInformation.FormatOutputData(templateValues, system, type);
bool success = DumpInformation.WriteOutputData(outputDirectory, outputFilename, formattedValues);
btn_StartStop.Content = UIElements.StartDumping;
@@ -472,7 +497,7 @@ namespace DICUI
// Special case for Custom input
if (tuple.Item1 == "Custom Input" && tuple.Item2 == KnownSystem.NONE && tuple.Item3 == DiscType.NONE)
{
- txt_CustomParameters.IsEnabled = true;
+ txt_Parameters.IsEnabled = true;
txt_OutputFilename.IsEnabled = false;
txt_OutputDirectory.IsEnabled = false;
btn_OutputDirectoryBrowse.IsEnabled = false;
@@ -483,7 +508,7 @@ namespace DICUI
}
else
{
- txt_CustomParameters.IsEnabled = false;
+ txt_Parameters.IsEnabled = false;
txt_OutputFilename.IsEnabled = true;
txt_OutputDirectory.IsEnabled = true;
btn_OutputDirectoryBrowse.IsEnabled = true;
@@ -497,7 +522,7 @@ namespace DICUI
var driveletter = cmb_DriveLetter.SelectedValue as Tuple;
string discType = Utilities.GetBaseCommand(selected.Item3);
List defaultParams = Utilities.GetDefaultParameters(selected.Item2, selected.Item3);
- txt_CustomParameters.Text = discType
+ txt_Parameters.Text = discType
+ " " + driveletter.Item1
+ " \"" + Path.Combine(txt_OutputDirectory.Text, txt_OutputFilename.Text) + "\" "
+ (selected.Item3 != DiscType.Floppy && selected.Item3 != DiscType.BD25 && selected.Item3 != DiscType.BD50 ? (int)cmb_DriveSpeed.SelectedItem + " " : "")
diff --git a/Utilities.cs b/Utilities.cs
index 576ec2f6..bd15af9e 100644
--- a/Utilities.cs
+++ b/Utilities.cs
@@ -464,6 +464,71 @@ namespace DICUI
}
}
+ ///
+ /// Get the DiscType associated with a given base command
+ ///
+ /// String value to check
+ /// DiscType if possible, null on error
+ /// This takes the "safe" route by assuming the larger of any given format
+ public static DiscType? GetDiscType(string baseCommand)
+ {
+ switch (baseCommand)
+ {
+ case DICCommands.CompactDiscCommand:
+ return DiscType.CD;
+ case DICCommands.GDROMCommand:
+ case DICCommands.GDROMSwapCommand:
+ return DiscType.GDROM;
+ case DICCommands.DVDCommand:
+ return DiscType.DVD9;
+ case DICCommands.BDCommand:
+ return DiscType.BD50;
+
+ // Non-optical
+ case DICCommands.FloppyCommand:
+ return DiscType.Floppy;
+ default:
+ return null;
+ }
+ }
+
+ ///
+ /// Get the most common known system for a given DiscType
+ ///
+ /// DiscType value to check
+ /// KnownSystem if possible, null on error
+ public static KnownSystem? GetKnownSystem(DiscType? type)
+ {
+ switch (type)
+ {
+ case DiscType.CD:
+ case DiscType.DVD5:
+ case DiscType.DVD9:
+ case DiscType.Floppy:
+ return KnownSystem.IBMPCCompatible;
+ case DiscType.GDROM:
+ return KnownSystem.SegaDreamcast;
+ case DiscType.HDDVD:
+ return KnownSystem.MicrosoftXBOX360;
+ case DiscType.BD25:
+ case DiscType.BD50:
+ return KnownSystem.SonyPlayStation3;
+
+ // Special Formats
+ case DiscType.GameCubeGameDisc:
+ return KnownSystem.NintendoGameCube;
+ case DiscType.WiiOpticalDisc:
+ return KnownSystem.NintendoWii;
+ case DiscType.WiiUOpticalDisc:
+ return KnownSystem.NintendoWiiU;
+ case DiscType.UMD:
+ return KnownSystem.SonyPlayStationPortable;
+
+ default:
+ return null;
+ }
+ }
+
///
/// Get list of default parameters for a given system and disc type
///
@@ -691,7 +756,6 @@ namespace DICUI
///
/// String representing all parameters
/// True if it would be valid, false otherwise
- /// TODO: Refactor this to make it cleaner
public static bool ValidateParameters(string parameters)
{
// The string has to be valid by itself first
@@ -700,6 +764,540 @@ namespace DICUI
return false;
}
+ // Now split the string into parts for easier validation
+ // https://stackoverflow.com/questions/14655023/split-a-string-that-has-white-spaces-unless-they-are-enclosed-within-quotes
+ parameters = parameters.Trim();
+ List parts = Regex.Matches(parameters, @"[\""].+?[\""]|[^ ]+")
+ .Cast()
+ .Select(m => m.Value)
+ .ToList();
+
+ // Determine what the commandline should look like given the first item
+ int index = -1;
+ switch (parts[0])
+ {
+ case DICCommands.CompactDiscCommand:
+ case DICCommands.GDROMCommand:
+ case DICCommands.GDROMSwapCommand:
+ case DICCommands.DataCommand:
+ if (!IsValidDriveLetter(parts[1]))
+ {
+ return false;
+ }
+ else if (IsFlag(parts[2]))
+ {
+ return false;
+ }
+ else if (!IsValidNumber(parts[3], lowerBound: 0, upperBound: 72))
+ {
+ return false;
+ }
+
+ if (parts[0] == DICCommands.GDROMSwapCommand)
+ {
+ if (parts.Count > 4)
+ {
+ return false;
+ }
+ }
+ else if (parts[0] == DICCommands.DataCommand || parts[0] == DICCommands.AudioCommand)
+ {
+ if (!IsValidNumber(parts[4]) || !IsValidNumber(parts[5]))
+ {
+ return false;
+ }
+
+ index = 6;
+ }
+ else
+ {
+ index = 4;
+ }
+
+ break;
+ case DICCommands.DVDCommand:
+ if (!IsValidDriveLetter(parts[1]))
+ {
+ return false;
+ }
+ else if (IsFlag(parts[2]))
+ {
+ return false;
+ }
+ else if (!IsValidNumber(parts[3], lowerBound: 0, upperBound: 72)) // Officially 0-16
+ {
+ return false;
+ }
+
+ // Loop through all auxilary flags
+ for (int i = 4; i < parts.Count; i++)
+ {
+ switch (parts[i])
+ {
+ case DICCommands.DisableBeepFlag:
+ case DICCommands.DVDCMIFlag:
+ case DICCommands.DVDRawFlag:
+ // No-op, all of these are single flags
+ break;
+ case DICCommands.ForceUnitAccessFlag:
+ // If the next item doesn't exist, it's good
+ if (!DoesNextExist(parts, i))
+ {
+ break;
+ }
+ // If the next item is a flag, it's good
+ if (IsFlag(parts[i + 1]))
+ {
+ break;
+ }
+ // If the next item isn't a valid number
+ else if (!IsValidNumber(parts[i + 1], lowerBound: 0))
+ {
+ return false;
+ }
+ i++;
+ break;
+ default:
+ return false;
+ }
+ }
+ break;
+ case DICCommands.BDCommand:
+ if (!IsValidDriveLetter(parts[1]))
+ {
+ return false;
+ }
+ else if (IsFlag(parts[2]))
+ {
+ return false;
+ }
+
+ // Loop through all auxilary flags
+ for (int i = 3; i < parts.Count; i++)
+ {
+ switch (parts[i])
+ {
+ case DICCommands.DisableBeepFlag:
+ // No-op, this is a single flag
+ break;
+ case DICCommands.ForceUnitAccessFlag:
+ // If the next item doesn't exist, it's good
+ if (!DoesNextExist(parts, i))
+ {
+ break;
+ }
+ // If the next item is a flag, it's good
+ if (IsFlag(parts[i + 1]))
+ {
+ break;
+ }
+ // If the next item isn't a valid number
+ else if (!IsValidNumber(parts[i + 1], lowerBound: 0))
+ {
+ return false;
+ }
+ i++;
+ break;
+ default:
+ return false;
+ }
+ }
+ break;
+ case DICCommands.FloppyCommand:
+ if (!IsValidDriveLetter(parts[1]))
+ {
+ return false;
+ }
+ else if (IsFlag(parts[2]))
+ {
+ return false;
+ }
+ else if (parts.Count > 3)
+ {
+ return false;
+ }
+ break;
+ case DICCommands.StopCommand:
+ case DICCommands.StartCommand:
+ case DICCommands.EjectCommand:
+ case DICCommands.CloseCommand:
+ case DICCommands.ResetCommand:
+ case DICCommands.DriveSpeedCommand:
+ if (!IsValidDriveLetter(parts[1]))
+ {
+ return false;
+ }
+ else if (parts.Count > 2)
+ {
+ return false;
+ }
+ break;
+ case DICCommands.SubCommand:
+ case DICCommands.MDSCommand:
+ if (IsFlag(parts[1]))
+ {
+ return false;
+ }
+ else if (parts.Count > 2)
+ {
+ return false;
+ }
+ break;
+ default:
+ return false;
+ }
+
+ // Loop through all auxilary flags, if necessary
+ if (index > 0)
+ {
+ for (int i = index; i < parts.Count; i++)
+ {
+ switch(parts[i])
+ {
+ case DICCommands.DisableBeepFlag:
+ if (parts[0] != DICCommands.CompactDiscCommand
+ && parts[0] != DICCommands.GDROMCommand
+ && parts[0] != DICCommands.DataCommand
+ && parts[0] != DICCommands.AudioCommand)
+ {
+ return false;
+ }
+ break;
+ case DICCommands.CDD8OpcodeFlag:
+ if (parts[0] != DICCommands.CompactDiscCommand
+ && parts[0] != DICCommands.GDROMCommand
+ && parts[0] != DICCommands.DataCommand
+ && parts[0] != DICCommands.AudioCommand)
+ {
+ return false;
+ }
+ break;
+ case DICCommands.CDMCNFlag:
+ if (parts[0] != DICCommands.CompactDiscCommand)
+ {
+ return false;
+ }
+ break;
+ case DICCommands.CDAMSFFlag:
+ if (parts[0] != DICCommands.CompactDiscCommand)
+ {
+ return false;
+ }
+ break;
+ case DICCommands.CDReverseFlag:
+ if (parts[0] != DICCommands.CompactDiscCommand
+ && parts[0] != DICCommands.DataCommand)
+ {
+ return false;
+ }
+ break;
+ case DICCommands.CDMultiSessionFlag:
+ if (parts[0] != DICCommands.CompactDiscCommand)
+ {
+ return false;
+ }
+ break;
+ case DICCommands.CDScanSectorProtectFlag:
+ if (parts[0] != DICCommands.CompactDiscCommand
+ && parts[0] != DICCommands.DataCommand)
+ {
+ return false;
+ }
+ break;
+ case DICCommands.CDScanAnitModFlag:
+ if (parts[0] != DICCommands.CompactDiscCommand)
+ {
+ return false;
+ }
+ break;
+ case DICCommands.CDNoFixSubPFlag:
+ if (parts[0] != DICCommands.CompactDiscCommand
+ && parts[0] != DICCommands.GDROMCommand
+ && parts[0] != DICCommands.DataCommand
+ && parts[0] != DICCommands.AudioCommand)
+ {
+ return false;
+ }
+ break;
+ case DICCommands.CDNoFixSubQFlag:
+ if (parts[0] != DICCommands.CompactDiscCommand
+ && parts[0] != DICCommands.GDROMCommand
+ && parts[0] != DICCommands.DataCommand
+ && parts[0] != DICCommands.AudioCommand)
+ {
+ return false;
+ }
+ break;
+ case DICCommands.CDNoFixSubRtoWFlag:
+ if (parts[0] != DICCommands.CompactDiscCommand
+ && parts[0] != DICCommands.GDROMCommand
+ && parts[0] != DICCommands.DataCommand
+ && parts[0] != DICCommands.AudioCommand)
+ {
+ return false;
+ }
+ break;
+ case DICCommands.CDNoFixSubQLibCryptFlag:
+ if (parts[0] != DICCommands.CompactDiscCommand)
+ {
+ return false;
+ }
+ break;
+ case DICCommands.CDNoFixSubQSecuROMFlag:
+ if (parts[0] != DICCommands.CompactDiscCommand
+ && parts[0] != DICCommands.GDROMCommand
+ && parts[0] != DICCommands.DataCommand
+ && parts[0] != DICCommands.AudioCommand)
+ {
+ return false;
+ }
+ break;
+ case DICCommands.CDScanFileProtectFlag:
+ if (parts[0] != DICCommands.CompactDiscCommand
+ && parts[0] != DICCommands.DataCommand)
+ {
+ return false;
+ }
+
+ // If the next item doesn't exist, it's good
+ if (!DoesNextExist(parts, i))
+ {
+ break;
+ }
+ // If the next item is a flag, it's good
+ if (IsFlag(parts[i + 1]))
+ {
+ break;
+ }
+ // If the next item isn't a valid number
+ else if (!IsValidNumber(parts[i + 1], lowerBound: 0))
+ {
+ return false;
+ }
+ i++;
+ break;
+ case DICCommands.ForceUnitAccessFlag: // CD, GDROM, Data, Audio
+ if (parts[0] != DICCommands.CompactDiscCommand
+ && parts[0] != DICCommands.GDROMCommand
+ && parts[0] != DICCommands.DataCommand
+ && parts[0] != DICCommands.AudioCommand)
+ {
+ return false;
+ }
+
+ // If the next item doesn't exist, it's good
+ if (!DoesNextExist(parts, i))
+ {
+ break;
+ }
+ // If the next item is a flag, it's good
+ if (IsFlag(parts[i + 1]))
+ {
+ break;
+ }
+ // If the next item isn't a valid number
+ else if (!IsValidNumber(parts[i + 1], lowerBound: 0))
+ {
+ return false;
+ }
+ i++;
+ break;
+ case DICCommands.CDAddOffsetFlag:
+ if (parts[0] != DICCommands.CompactDiscCommand
+ && parts[0] != DICCommands.AudioCommand)
+ {
+ return false;
+ }
+
+ // If the next item doesn't exist, it's not good
+ if (parts.Count == i + 1)
+ {
+ return false;
+ }
+ // If the next item isn't a valid number
+ else if (IsValidNumber(parts[i + 1]))
+ {
+ return false;
+ }
+ break;
+ case DICCommands.CDBEOpcodeFlag:
+ if (parts[0] != DICCommands.CompactDiscCommand
+ && parts[0] != DICCommands.GDROMCommand
+ && parts[0] != DICCommands.DataCommand
+ && parts[0] != DICCommands.AudioCommand)
+ {
+ return false;
+ }
+
+ // If the next item doesn't exist, it's good
+ if (!DoesNextExist(parts, i))
+ {
+ break;
+ }
+ // If the next item is a flag, it's good
+ if (IsFlag(parts[i + 1]))
+ {
+ break;
+ }
+ else if (parts[i + 1] != "raw"
+ && (parts[i + 1] != "pack"))
+ {
+ return false;
+ }
+ i++;
+ break;
+ case DICCommands.CDC2OpcodeFlag:
+ if (parts[0] != DICCommands.CompactDiscCommand
+ && parts[0] != DICCommands.GDROMCommand
+ && parts[0] != DICCommands.DataCommand
+ && parts[0] != DICCommands.AudioCommand)
+ {
+ return false;
+ }
+
+ for (int j = 1; j < 4; j++)
+ {
+ // If the next item doesn't exist, it's good
+ if (!DoesNextExist(parts, i + j - 1))
+ {
+ break;
+ }
+ // If the next item is a flag, it's good
+ if (IsFlag(parts[i + j]))
+ {
+ i += (j - 1);
+ break;
+ }
+ // If the next item isn't a valid number
+ else if (!IsValidNumber(parts[i + j], lowerBound: 0))
+ {
+ return false;
+ }
+ }
+ break;
+ case DICCommands.CDSubchannelReadLevelFlag:
+ if (parts[0] != DICCommands.CompactDiscCommand
+ && parts[0] != DICCommands.GDROMCommand
+ && parts[0] != DICCommands.DataCommand
+ && parts[0] != DICCommands.AudioCommand)
+ {
+ return false;
+ }
+
+ // If the next item doesn't exist, it's good
+ if (!DoesNextExist(parts, i))
+ {
+ break;
+ }
+ // If the next item is a flag, it's good
+ if (IsFlag(parts[i + 1]))
+ {
+ break;
+ }
+ // If the next item isn't a valid number
+ else if (!IsValidNumber(parts[3], lowerBound: 0, upperBound: 2))
+ {
+ return false;
+ }
+ break;
+ default:
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
+
+ ///
+ /// Returns whether a string is a valid drive letter
+ ///
+ /// String value to check
+ /// True if it's a valid drive letter, false otherwise
+ private static bool IsValidDriveLetter(string parameter)
+ {
+ if (!Regex.IsMatch(parameter, @"^[A-Z]:?\\?$"))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ ///
+ /// Returns whether a string is a flag (starts with '/')
+ ///
+ /// String value to check
+ /// True if it's a flag, false otherwise
+ private static bool IsFlag(string parameter)
+ {
+ if (parameter.Trim('\"').StartsWith("/"))
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ ///
+ /// Returns whether or not the next item exists
+ ///
+ /// List of parameters to check against
+ /// Current index
+ /// True if the next item exists, false otherwise
+ private static bool DoesNextExist(List parameters, int index)
+ {
+ if (index >= parameters.Count - 1)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ ///
+ /// Returns whether a string is a valid number
+ ///
+ /// String value to check
+ /// Lower bound (>=)
+ /// Upper bound (<=)
+ /// True if it's a valid number, false otherwise
+ private static bool IsValidNumber(string parameter, int lowerBound = -1, int upperBound = -1)
+ {
+ if (!Int32.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;
+ }
+
+ ///
+ /// Determine the base flags to use for checking a commandline
+ ///
+ /// Parameters as a string to check
+ /// Output string containing the found command
+ /// Output string containing the found drive letter
+ /// Output string containing the found path
+ /// False on error (and all outputs set to null), true otherwise
+ public static bool DetermineFlags(string parameters, out string command, out string letter, out string path)
+ {
+ command = null; letter = null; path = null;
+
+ // The string has to be valid by itself first
+ if (String.IsNullOrWhiteSpace(parameters))
+ {
+ return false;
+ }
+
// Now split the string into parts for easier validation
// https://stackoverflow.com/questions/14655023/split-a-string-that-has-white-spaces-unless-they-are-enclosed-within-quotes
parameters = parameters.Trim();
@@ -712,608 +1310,27 @@ namespace DICUI
switch (parts[0])
{
case DICCommands.CompactDiscCommand:
- if (!Regex.IsMatch(parts[1], @"[A-Z]:?\\?"))
- {
- return false;
- }
- else if (parts[2].Trim('\"').StartsWith("/"))
- {
- return false;
- }
- else if (!Int32.TryParse(parts[3], out int cdspeed))
- {
- return false;
- }
- else if (cdspeed < 0 || cdspeed > 72)
- {
- return false;
- }
-
- // Loop through all auxilary flags
- for (int i = 4; i < parts.Count; i++)
- {
- switch (parts[i])
- {
- case DICCommands.DisableBeepFlag:
- case DICCommands.CDD8OpcodeFlag:
- case DICCommands.CDMCNFlag:
- case DICCommands.CDAMSFFlag:
- case DICCommands.CDReverseFlag:
- case DICCommands.CDMultiSessionFlag:
- case DICCommands.CDScanSectorProtectFlag:
- case DICCommands.CDScanAnitModFlag:
- case DICCommands.CDNoFixSubPFlag:
- case DICCommands.CDNoFixSubQFlag:
- case DICCommands.CDNoFixSubRtoWFlag:
- case DICCommands.CDNoFixSubQLibCryptFlag:
- case DICCommands.CDNoFixSubQSecuROMFlag:
- // No-op, all of these are single flags
- break;
- case DICCommands.CDScanFileProtectFlag:
- // If the next item is a flag, it's good
- if (parts[i + 1].StartsWith("/"))
- {
- break;
- }
- // If the next item isn't a valid number
- else if (!Int32.TryParse(parts[i + 1], out int sfp1))
- {
- return false;
- }
- else if (sfp1 < 0)
- {
- return false;
- }
- i++;
- break;
- case DICCommands.ForceUnitAccessFlag:
- // If the next item is a flag, it's good
- if (parts[i + 1].StartsWith("/"))
- {
- break;
- }
- // If the next item isn't a valid number
- else if (!Int32.TryParse(parts[i + 1], out int fua1))
- {
- return false;
- }
- else if (fua1 < 0)
- {
- return false;
- }
- i++;
- break;
- case DICCommands.CDAddOffsetFlag:
- // If the next item isn't a valid number
- if (!Int32.TryParse(parts[i + 1], out int af1))
- {
- return false;
- }
- break;
- case DICCommands.CDBEOpcodeFlag:
- // If the next item is a flag, it's good
- if (parts[i + 1].StartsWith("/"))
- {
- break;
- }
- else if (parts[i + 1] != "raw"
- && (parts[i + 1] != "pack"))
- {
- return false;
- }
- i++;
- break;
- case DICCommands.CDC2OpcodeFlag:
- for (int j = 1; j < 4; j++)
- {
- // If the next item is a flag, it's good
- if (parts[i + j].StartsWith("/"))
- {
- i += (j - 1);
- break;
- }
- // If the next item isn't a valid number
- else if (!Int32.TryParse(parts[i + j], out int c2))
- {
- return false;
- }
- else if (c2 < 0)
- {
- return false;
- }
- }
- break;
- case DICCommands.CDSubchannelReadLevelFlag:
- // If the next item is a flag, it's good
- if (parts[i + 1].StartsWith("/"))
- {
- break;
- }
- // If the next item isn't a valid number
- else if (!Int32.TryParse(parts[i + 1], out int sub))
- {
- return false;
- }
- else if (sub < 0 || sub > 2)
- {
- return false;
- }
- break;
- default:
- return false;
- }
- }
- break;
case DICCommands.GDROMCommand:
- if (!Regex.IsMatch(parts[1], @"[A-Z]:?\\?"))
- {
- return false;
- }
- else if (parts[2].Trim('\"').StartsWith("/"))
- {
- return false;
- }
- else if (!Int32.TryParse(parts[3], out int cdspeed))
- {
- return false;
- }
- else if (cdspeed < 0 || cdspeed > 72)
- {
- return false;
- }
-
- // Loop through all auxilary flags
- for (int i = 4; i < parts.Count; i++)
- {
- switch (parts[i])
- {
- case DICCommands.DisableBeepFlag:
- case DICCommands.CDD8OpcodeFlag:
- case DICCommands.CDNoFixSubPFlag:
- case DICCommands.CDNoFixSubQFlag:
- case DICCommands.CDNoFixSubRtoWFlag:
- case DICCommands.CDNoFixSubQSecuROMFlag:
- // No-op, all of these are single flags
- break;
- case DICCommands.ForceUnitAccessFlag:
- // If the next item is a flag, it's good
- if (parts[i + 1].StartsWith("/"))
- {
- break;
- }
- // If the next item isn't a valid number
- else if (!Int32.TryParse(parts[i + 1], out int fua1))
- {
- return false;
- }
- else if (fua1 < 0)
- {
- return false;
- }
- i++;
- break;
- case DICCommands.CDBEOpcodeFlag:
- // If the next item is a flag, it's good
- if (parts[i + 1].StartsWith("/"))
- {
- break;
- }
- else if (parts[i + 1] != "raw"
- && (parts[i + 1] != "pack"))
- {
- return false;
- }
- i++;
- break;
- case DICCommands.CDC2OpcodeFlag:
- for (int j = 1; j < 4; j++)
- {
- // If the next item is a flag, it's good
- if (parts[i + j].StartsWith("/"))
- {
- i += (j - 1);
- break;
- }
- // If the next item isn't a valid number
- else if (!Int32.TryParse(parts[i + j], out int c2))
- {
- return false;
- }
- else if (c2 < 0)
- {
- return false;
- }
- }
- break;
- case DICCommands.CDSubchannelReadLevelFlag:
- // If the next item is a flag, it's good
- if (parts[i + 1].StartsWith("/"))
- {
- break;
- }
- // If the next item isn't a valid number
- else if (!Int32.TryParse(parts[i + 1], out int sub))
- {
- return false;
- }
- else if (sub < 0 || sub > 2)
- {
- return false;
- }
- i++;
- break;
- default:
- return false;
- }
- }
- break;
case DICCommands.GDROMSwapCommand:
- if (!Regex.IsMatch(parts[1], @"[A-Z]:?\\?"))
- {
- return false;
- }
- else if (parts[2].Trim('\"').StartsWith("/"))
- {
- return false;
- }
- else if (!Int32.TryParse(parts[3], out int cdspeed))
- {
- return false;
- }
- else if (cdspeed < 0 || cdspeed > 72)
- {
- return false;
- }
- else if (parts.Count > 4)
- {
- return false;
- }
- break;
case DICCommands.DataCommand:
- if (!Regex.IsMatch(parts[1], @"[A-Z]:?\\?"))
- {
- return false;
- }
- else if (parts[2].Trim('\"').StartsWith("/"))
- {
- return false;
- }
- else if (!Int32.TryParse(parts[3], out int cdspeed))
- {
- return false;
- }
- else if (cdspeed < 0 || cdspeed > 72)
- {
- return false;
- }
- else if (!Int32.TryParse(parts[4], out int startlba)
- || !Int32.TryParse(parts[5], out int endlba))
- {
- return false;
- }
-
- // Loop through all auxilary flags
- for (int i = 6; i < parts.Count; i++)
- {
- switch (parts[i])
- {
- case DICCommands.DisableBeepFlag:
- case DICCommands.CDD8OpcodeFlag:
- case DICCommands.CDReverseFlag:
- case DICCommands.CDScanSectorProtectFlag:
- case DICCommands.CDNoFixSubPFlag:
- case DICCommands.CDNoFixSubQFlag:
- case DICCommands.CDNoFixSubRtoWFlag:
- case DICCommands.CDNoFixSubQSecuROMFlag:
- // No-op, all of these are single flags
- break;
- case DICCommands.ForceUnitAccessFlag:
- // If the next item is a flag, it's good
- if (parts[i + 1].StartsWith("/"))
- {
- break;
- }
- // If the next item isn't a valid number
- else if (!Int32.TryParse(parts[i + 1], out int fua1))
- {
- return false;
- }
- else if (fua1 < 0)
- {
- return false;
- }
- i++;
- break;
- case DICCommands.CDScanFileProtectFlag:
- // If the next item is a flag, it's good
- if (parts[i + 1].StartsWith("/"))
- {
- break;
- }
- // If the next item isn't a valid number
- else if (!Int32.TryParse(parts[i + 1], out int sfp1))
- {
- return false;
- }
- else if (sfp1 < 0)
- {
- return false;
- }
- i++;
- break;
- case DICCommands.CDBEOpcodeFlag:
- // If the next item is a flag, it's good
- if (parts[i + 1].StartsWith("/"))
- {
- break;
- }
- else if (parts[i + 1] != "raw"
- && (parts[i + 1] != "pack"))
- {
- return false;
- }
- i++;
- break;
- case DICCommands.CDC2OpcodeFlag:
- for (int j = 1; j < 4; j++)
- {
- // If the next item is a flag, it's good
- if (parts[i + j].StartsWith("/"))
- {
- i += (j - 1);
- break;
- }
- // If the next item isn't a valid number
- else if (!Int32.TryParse(parts[i + j], out int c2))
- {
- return false;
- }
- else if (c2 < 0)
- {
- return false;
- }
- }
- break;
- case DICCommands.CDSubchannelReadLevelFlag:
- // If the next item is a flag, it's good
- if (parts[i + 1].StartsWith("/"))
- {
- break;
- }
- // If the next item isn't a valid number
- else if (!Int32.TryParse(parts[i + 1], out int sub))
- {
- return false;
- }
- else if (sub < 0 || sub > 2)
- {
- return false;
- }
- i++;
- break;
- default:
- return false;
- }
- }
- break;
case DICCommands.AudioCommand:
- if (!Regex.IsMatch(parts[1], @"[A-Z]:?\\?"))
- {
- return false;
- }
- else if (parts[2].Trim('\"').StartsWith("/"))
- {
- return false;
- }
- else if (!Int32.TryParse(parts[3], out int cdspeed))
- {
- return false;
- }
- else if (cdspeed < 0 || cdspeed > 72)
- {
- return false;
- }
- else if (!Int32.TryParse(parts[4], out int startlba)
- || !Int32.TryParse(parts[5], out int endlba))
- {
- return false;
- }
-
- // Loop through all auxilary flags
- for (int i = 6; i < parts.Count; i++)
- {
- switch (parts[i])
- {
- case DICCommands.DisableBeepFlag:
- case DICCommands.CDD8OpcodeFlag:
- case DICCommands.CDNoFixSubPFlag:
- case DICCommands.CDNoFixSubQFlag:
- case DICCommands.CDNoFixSubRtoWFlag:
- case DICCommands.CDNoFixSubQSecuROMFlag:
- // No-op, all of these are single flags
- break;
- case DICCommands.ForceUnitAccessFlag:
- // If the next item is a flag, it's good
- if (parts[i + 1].StartsWith("/"))
- {
- break;
- }
- // If the next item isn't a valid number
- else if (!Int32.TryParse(parts[i + 1], out int fua1))
- {
- return false;
- }
- else if (fua1 < 0)
- {
- return false;
- }
- i++;
- break;
- case DICCommands.CDAddOffsetFlag:
- // If the next item isn't a valid number
- if (!Int32.TryParse(parts[i + 1], out int af1))
- {
- return false;
- }
- break;
- case DICCommands.CDBEOpcodeFlag:
- // If the next item is a flag, it's good
- if (parts[i + 1].StartsWith("/"))
- {
- break;
- }
- else if (parts[i + 1] != "raw"
- && (parts[i + 1] != "pack"))
- {
- return false;
- }
- i++;
- break;
- case DICCommands.CDC2OpcodeFlag:
- for (int j = 1; j < 4; j++)
- {
- // If the next item is a flag, it's good
- if (parts[i + j].StartsWith("/"))
- {
- i += (j - 1);
- break;
- }
- // If the next item isn't a valid number
- else if (!Int32.TryParse(parts[i + j], out int c2))
- {
- return false;
- }
- else if (c2 < 0)
- {
- return false;
- }
- }
- break;
- case DICCommands.CDSubchannelReadLevelFlag:
- // If the next item is a flag, it's good
- if (parts[i + 1].StartsWith("/"))
- {
- break;
- }
- // If the next item isn't a valid number
- else if (!Int32.TryParse(parts[i + 1], out int sub))
- {
- return false;
- }
- else if (sub < 0 || sub > 2)
- {
- return false;
- }
- i++;
- break;
- default:
- return false;
- }
- }
- break;
case DICCommands.DVDCommand:
- if (!Regex.IsMatch(parts[1], @"[A-Z]:?\\?"))
- {
- return false;
- }
- else if (parts[2].Trim('\"').StartsWith("/"))
- {
- return false;
- }
- else if (!Int32.TryParse(parts[3], out int dvdspeed))
- {
- return false;
- }
- else if (dvdspeed < 0 || dvdspeed > 72) // Officialy, 0-16
- {
- return false;
- }
-
- // Loop through all auxilary flags
- for (int i = 4; i < parts.Count; i++)
- {
- switch (parts[i])
- {
- case DICCommands.DisableBeepFlag:
- case DICCommands.DVDCMIFlag:
- case DICCommands.DVDRawFlag:
- // No-op, all of these are single flags
- break;
- case DICCommands.ForceUnitAccessFlag:
- // If the next item is a flag, it's good
- if (parts[i + 1].StartsWith("/"))
- {
- break;
- }
- // If the next item isn't a valid number
- else if (!Int32.TryParse(parts[i + 1], out int fua1))
- {
- return false;
- }
- else if (fua1 < 0)
- {
- return false;
- }
- i++;
- break;
- default:
- return false;
- }
- }
- break;
case DICCommands.BDCommand:
- if (!Regex.IsMatch(parts[1], @"[A-Z]:?\\?"))
- {
- return false;
- }
- else if (parts[2].Trim('\"').StartsWith("/"))
- {
- return false;
- }
-
- // Loop through all auxilary flags
- for (int i = 3; i < parts.Count; i++)
- {
- switch (parts[i])
- {
- case DICCommands.DisableBeepFlag:
- // No-op, this is a single flag
- break;
- case DICCommands.ForceUnitAccessFlag:
- // If the next item is a flag, it's good
- if (parts[i + 1].StartsWith("/"))
- {
- break;
- }
- // If the next item isn't a valid number
- else if (!Int32.TryParse(parts[i + 1], out int fua1))
- {
- return false;
- }
- else if (fua1 < 0)
- {
- return false;
- }
- i++;
- break;
- default:
- return false;
- }
- }
- break;
case DICCommands.FloppyCommand:
- if (!Regex.IsMatch(parts[1], @"[A-Z]:?\\?"))
+ command = parts[0];
+
+ if (!IsValidDriveLetter(parts[1]))
{
return false;
}
- else if (parts[2].Trim('\"').StartsWith("/"))
- {
- return false;
- }
- else if (parts.Count > 3)
+ letter = parts[1];
+
+ if (IsFlag(parts[2]))
{
return false;
}
+ path = parts[2].Trim('\"');
+
break;
case DICCommands.StopCommand:
case DICCommands.StartCommand:
@@ -1321,21 +1338,25 @@ namespace DICUI
case DICCommands.CloseCommand:
case DICCommands.ResetCommand:
case DICCommands.DriveSpeedCommand:
- if (!Regex.IsMatch(parts[1], @"[A-Z]:?\\?"))
- {
- return false;
- }
- else if (parts.Count > 2)
+ command = parts[0];
+
+ if (!IsValidDriveLetter(parts[1]))
{
return false;
}
+ letter = parts[1];
+
break;
case DICCommands.SubCommand:
case DICCommands.MDSCommand:
- if (parts[2].Trim('\"').StartsWith("/"))
+ command = parts[0];
+
+ if (IsFlag(parts[1]))
{
return false;
}
+ path = parts[1].Trim('\"');
+
break;
default:
return false;