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;