diff --git a/Utilities.cs b/Utilities.cs
index 475cceb8..dddff8d2 100644
--- a/Utilities.cs
+++ b/Utilities.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
+using System.Text.RegularExpressions;
namespace DICUI
{
@@ -415,29 +416,27 @@ namespace DICUI
switch (type)
{
case DiscType.CD:
- return "cd";
+ return Constants.CompactDiscCommand;
case DiscType.DVD5:
- return "dvd";
case DiscType.DVD9:
- return "dvd";
+ return Constants.DVDCommand;
case DiscType.GDROM:
- return "gd"; // TODO: "swap"?
+ return Constants.GDROMCommand; // TODO: Constants.GDROMSwapCommand?
case DiscType.HDDVD:
return null;
case DiscType.BD25:
- return "bd";
case DiscType.BD50:
- return "bd";
+ return Constants.BDCommand;
// Special Formats
case DiscType.GameCubeGameDisc:
- return "dvd";
+ return Constants.DVDCommand;
case DiscType.UMD:
return null;
// Non-optical
case DiscType.Floppy:
- return "fd";
+ return Constants.FloppyCommand;
default:
return null;
@@ -464,21 +463,21 @@ namespace DICUI
switch (type)
{
case DiscType.CD:
- parameters.Add("/c2 20");
+ parameters.Add(Constants.CDC2OpcodeFlag); parameters.Add("20");
switch (sys)
{
case KnownSystem.AppleMacintosh:
case KnownSystem.IBMPCCompatible:
- parameters.Add("/ns");
- parameters.Add("/sf");
- parameters.Add("/ss");
+ parameters.Add(Constants.CDNoFixSubQSecuROMFlag);
+ parameters.Add(Constants.CDScanFileProtectFlag);
+ parameters.Add(Constants.CDScanSectorProtectFlag);
break;
case KnownSystem.NECPCEngineTurboGrafxCD:
- parameters.Add("/m");
+ parameters.Add(Constants.CDMCNFlag);
break;
case KnownSystem.SonyPlayStation:
- parameters.Add("/am");
+ parameters.Add(Constants.CDScanAnitModFlag);
break;
}
break;
@@ -489,7 +488,7 @@ namespace DICUI
// Currently no defaults set
break;
case DiscType.GDROM:
- parameters.Add("/c2 20");
+ parameters.Add(Constants.CDC2OpcodeFlag); parameters.Add("20");
break;
case DiscType.HDDVD:
break;
@@ -502,7 +501,7 @@ namespace DICUI
// Special Formats
case DiscType.GameCubeGameDisc:
- parameters.Add("/raw");
+ parameters.Add(Constants.DVDRawFlag);
break;
case DiscType.UMD:
break;
@@ -1257,5 +1256,357 @@ namespace DICUI
return true;
}
+
+ ///
+ /// Validate that at string would be valid as input to DiscImageCreator
+ ///
+ /// String representing all parameters
+ /// True if it would be valid, false otherwise
+ public static bool ValidateParameters(string parameters)
+ {
+ // 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();
+ List parts = Regex.Matches(parameters, @"[\""].+?[\""]|[^ ]+")
+ .Cast()
+ .Select(m => m.Value)
+ .ToList();
+
+ // Determine what the commandline should look like given the first item
+ switch (parts[0])
+ {
+ case Constants.CompactDiscCommand:
+ if (!Regex.IsMatch(parts[1], @"[a-Z]:?\\?"))
+ {
+ return false;
+ }
+ else if (!File.Exists(parts[2].Trim('\"')))
+ {
+ 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 Constants.DisableBeepFlag:
+ case Constants.CDD8OpcodeFlag:
+ case Constants.CDMCNFlag:
+ case Constants.CDAMSFFlag:
+ case Constants.CDReverseFlag:
+ case Constants.CDMultiSessionFlag:
+ case Constants.CDScanSectorProtectFlag:
+ case Constants.CDScanAnitModFlag:
+ case Constants.CDNoFixSubPFlag:
+ case Constants.CDNoFixSubQFlag:
+ case Constants.CDNoFixSubRtoWFlag:
+ case Constants.CDNoFixSubQLibCryptFlag:
+ case Constants.CDNoFixSubQSecuROMFlag:
+ // No-op, all of these are single flags
+ break;
+ case Constants.CDScanFileProtectFlag:
+ // TODO: Check if next is a valid number (timeout)
+ break;
+ case Constants.ForceUnitAccessFlag:
+ // TODO: Check next as valid number
+ break;
+ case Constants.CDAddOffsetFlag:
+ // TODO: Check next as valid number
+ break;
+ case Constants.CDBEOpcodeFlag:
+ // TODO: Check next as valid (raw/pack)
+ break;
+ case Constants.CDC2OpcodeFlag:
+ // TODO: Check next (0-4) are valid numbers
+ break;
+ case Constants.CDSubchannelReadLevelFlag:
+ // TODO: Check next as valid number (0-2)
+ break;
+ default:
+ return false;
+ }
+ }
+ break;
+ case Constants.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 Constants.DisableBeepFlag:
+ case Constants.CDD8OpcodeFlag:
+ case Constants.CDNoFixSubPFlag:
+ case Constants.CDNoFixSubQFlag:
+ case Constants.CDNoFixSubRtoWFlag:
+ case Constants.CDNoFixSubQSecuROMFlag:
+ // No-op, all of these are single flags
+ break;
+ case Constants.ForceUnitAccessFlag:
+ // TODO: Check next as valid number
+ break;
+ case Constants.CDBEOpcodeFlag:
+ // TODO: Check next as valid (raw/pack)
+ break;
+ case Constants.CDC2OpcodeFlag:
+ // TODO: Check next (0-4) are valid numbers
+ break;
+ case Constants.CDSubchannelReadLevelFlag:
+ // TODO: Check next as valid number (0-2)
+ break;
+ default:
+ return false;
+ }
+ }
+ break;
+ case Constants.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 Constants.DisableBeepFlag:
+ case Constants.CDD8OpcodeFlag:
+ case Constants.CDReverseFlag:
+ case Constants.CDScanSectorProtectFlag:
+ case Constants.CDNoFixSubPFlag:
+ case Constants.CDNoFixSubQFlag:
+ case Constants.CDNoFixSubRtoWFlag:
+ case Constants.CDNoFixSubQSecuROMFlag:
+ // No-op, all of these are single flags
+ break;
+ case Constants.ForceUnitAccessFlag:
+ // TODO: Check next as valid number
+ break;
+ case Constants.CDScanFileProtectFlag:
+ // TODO: Check if next is a valid number (timeout)
+ break;
+ case Constants.CDBEOpcodeFlag:
+ // TODO: Check next as valid (raw/pack)
+ break;
+ case Constants.CDC2OpcodeFlag:
+ // TODO: Check next (0-4) are valid numbers
+ break;
+ case Constants.CDSubchannelReadLevelFlag:
+ // TODO: Check next as valid number (0-2)
+ break;
+ default:
+ return false;
+ }
+ }
+ break;
+ case Constants.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 Constants.DisableBeepFlag:
+ case Constants.CDD8OpcodeFlag:
+ case Constants.CDNoFixSubPFlag:
+ case Constants.CDNoFixSubQFlag:
+ case Constants.CDNoFixSubRtoWFlag:
+ case Constants.CDNoFixSubQSecuROMFlag:
+ // No-op, all of these are single flags
+ break;
+ case Constants.ForceUnitAccessFlag:
+ // TODO: Check next as valid number
+ break;
+ case Constants.CDAddOffsetFlag:
+ // TODO: Check next as valid number
+ break;
+ case Constants.CDBEOpcodeFlag:
+ // TODO: Check next as valid (raw/pack)
+ break;
+ case Constants.CDC2OpcodeFlag:
+ // TODO: Check next (0-4) are valid numbers
+ break;
+ case Constants.CDSubchannelReadLevelFlag:
+ // TODO: Check next as valid number (0-2)
+ break;
+ default:
+ return false;
+ }
+ }
+ break;
+ case Constants.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 > 16)
+ {
+ return false;
+ }
+
+ // Loop through all auxilary flags
+ for (int i = 4; i < parts.Count; i++)
+ {
+ switch (parts[i])
+ {
+ case Constants.DisableBeepFlag:
+ case Constants.DVDCMIFlag:
+ case Constants.DVDRawFlag:
+ // No-op, all of these are single flags
+ break;
+ case Constants.ForceUnitAccessFlag:
+ // TODO: Check next as valid number
+ break;
+ default:
+ return false;
+ }
+ }
+ break;
+ case Constants.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 Constants.DisableBeepFlag:
+ // No-op, this is a single flag
+ break;
+ case Constants.ForceUnitAccessFlag:
+ // TODO: Check next as valid number
+ break;
+ default:
+ return false;
+ }
+ }
+ break;
+ case Constants.FloppyCommand:
+ if (!Regex.IsMatch(parts[1], @"[a-Z]:?\\?"))
+ {
+ return false;
+ }
+ else if (parts[2].Trim('\"').StartsWith("\\"))
+ {
+ return false;
+ }
+ else if (parts.Count > 3)
+ {
+ return false;
+ }
+ break;
+ case Constants.StopCommand:
+ case Constants.StartCommand:
+ case Constants.EjectCommand:
+ case Constants.CloseCommand:
+ case Constants.ResetCommand:
+ if (!Regex.IsMatch(parts[1], @"[a-Z]:?\\?"))
+ {
+ return false;
+ }
+ else if (parts.Count > 2)
+ {
+ return false;
+ }
+ break;
+ case Constants.SubCommand:
+ case Constants.MDSCommand:
+ if (parts[2].Trim('\"').StartsWith("\\"))
+ {
+ return false;
+ }
+ break;
+ case Constants.GDROMSwapCommand: // TODO: How to validate this?
+ default:
+ return false;
+ }
+
+ return true;
+ }
}
}