Clean up parameters and related

This makes some former virtual methods into properties, cleans up the location of some logic, and makes the BaseParameters class a little neater
This commit is contained in:
Matt Nadareski
2021-03-12 14:59:04 -08:00
parent 3a00efc7fd
commit 512f7ae016
10 changed files with 1239 additions and 1208 deletions

View File

@@ -171,7 +171,6 @@ namespace MPF.Check
drive = new Drive(null, new DriveInfo(path));
var env = new DumpEnvironment(options, "", filepath, drive, knownSystem, mediaType, null);
env.FixOutputPaths();
// Finally, attempt to do the output dance
var result = env.VerifyAndSaveDumpOutput(resultProgress, protectionProgress).ConfigureAwait(false).GetAwaiter().GetResult();

View File

@@ -19,11 +19,35 @@ namespace MPF.Aaru
/// </summary>
public class Parameters : BaseParameters
{
#region Generic Dumping Information
/// <inheritdoc/>
public override string InputPath => InputValue;
/// <inheritdoc/>
public override string OutputPath => OutputValue;
/// <inheritdoc/>
public override int? Speed
{
get { return SpeedValue; }
set { SpeedValue = (sbyte?)value; }
}
#endregion
#region Metadata
/// <summary>
/// Base command to run
/// </summary>
public Command BaseCommand { get; set; }
/// <inheritdoc/>
public override InternalProgram InternalProgram => InternalProgram.Aaru;
#endregion
/// <summary>
/// Set of flags to pass to the executable
/// </summary>
@@ -125,134 +149,235 @@ namespace MPF.Aaru
#endregion
/// <inheritdoc/>
public Parameters(string parameters)
: base(parameters)
{
this.InternalProgram = InternalProgram.Aaru;
}
public Parameters(string parameters) : base(parameters) { }
/// <inheritdoc/>
public Parameters(KnownSystem? system, MediaType? type, char driveLetter, string filename, int? driveSpeed, Options options)
: base(system, type, driveLetter, filename, driveSpeed, options)
{
this.InternalProgram = InternalProgram.Aaru;
}
/// <inheritdoc/>
protected override void ResetValues()
{
BaseCommand = Command.NONE;
_flags = new Dictionary<Flag, bool?>();
BlockSizeValue = null;
CommentsValue = null;
CreatorValue = null;
CountValue = null;
DriveManufacturerValue = null;
DriveModelValue = null;
DriveRevisionValue = null;
DriveSerialValue = null;
EncodingValue = null;
FormatConvertValue = null;
FormatDumpValue = null;
ImgBurnLogValue = null;
InputValue = null;
Input1Value = null;
Input2Value = null;
LengthValue = null;
MediaBarcodeValue = null;
MediaLastSequenceValue = null;
MediaManufacturerValue = null;
MediaModelValue = null;
MediaPartNumberValue = null;
MediaSequenceValue = null;
MediaSerialValue = null;
MediaTitleValue = null;
MHDDLogValue = null;
NamespaceValue = null;
OptionsValue = null;
OutputValue = null;
OutputPrefixValue = null;
RemoteHostValue = null;
ResumeFileValue = null;
RetryPassesValue = null;
SkipValue = null;
SpeedValue = null;
StartValue = null;
SubchannelValue = null;
WidthValue = null;
XMLSidecarValue = null;
}
#region BaseParameters Implementations
/// <inheritdoc/>
protected override void SetDefaultParameters(char driveLetter, string filename, int? driveSpeed, Options options)
public override (bool, List<string>) CheckAllOutputFilesExist(string basePath)
{
BaseCommand = Command.MediaDump;
InputValue = $"\\\\?\\{driveLetter}:";
OutputValue = filename;
if (driveSpeed != null)
{
this[Flag.Speed] = true;
SpeedValue = (sbyte?)driveSpeed;
}
// First check to see if the combination of system and MediaType is valid
var validTypes = Validators.GetValidMediaTypes(this.System);
if (!validTypes.Contains(this.Type))
return;
// Set retry count
if (options.AaruRereadCount > 0)
{
this[Flag.RetryPasses] = true;
RetryPassesValue = (short)options.AaruRereadCount;
}
// Set user-defined options
this[Flag.Debug] = options.AaruEnableDebug;
this[Flag.Verbose] = options.AaruEnableVerbose;
this[Flag.Force] = options.AaruForceDumping;
this[Flag.Private] = options.AaruStripPersonalData;
// TODO: Look at dump-media formats and the like and see what options there are there to fill in defaults
// Now sort based on disc type
List<string> missingFiles = new List<string>();
switch (this.Type)
{
case MediaType.CDROM:
this[Flag.FirstPregap] = true;
this[Flag.FixOffset] = true;
this[Flag.Subchannel] = true;
SubchannelValue = "any";
if (!File.Exists($"{basePath}.cicm.xml"))
missingFiles.Add($"{basePath}.cicm.xml");
if (!File.Exists($"{basePath}.ibg"))
missingFiles.Add($"{basePath}.ibg");
if (!File.Exists($"{basePath}.log"))
missingFiles.Add($"{basePath}.log");
if (!File.Exists($"{basePath}.mhddlog.bin"))
missingFiles.Add($"{basePath}.mhddlog.bin");
if (!File.Exists($"{basePath}.resume.xml"))
missingFiles.Add($"{basePath}.resume.xml");
if (!File.Exists($"{basePath}.sub.log"))
missingFiles.Add($"{basePath}.sub.log");
break;
case MediaType.DVD:
// Currently no defaults set
break;
case MediaType.GDROM:
// Currently no defaults set
break;
case MediaType.HDDVD:
// Currently no defaults set
break;
case MediaType.BluRay:
// Currently no defaults set
if (!File.Exists($"{basePath}.cicm.xml"))
missingFiles.Add($"{basePath}.cicm.xml");
if (!File.Exists($"{basePath}.ibg"))
missingFiles.Add($"{basePath}.ibg");
if (!File.Exists($"{basePath}.log"))
missingFiles.Add($"{basePath}.log");
if (!File.Exists($"{basePath}.mhddlog.bin"))
missingFiles.Add($"{basePath}.mhddlog.bin");
if (!File.Exists($"{basePath}.resume.xml"))
missingFiles.Add($"{basePath}.resume.xml");
break;
// Special Formats
case MediaType.NintendoGameCubeGameDisc:
// Currently no defaults set
break;
case MediaType.NintendoWiiOpticalDisc:
// Currently no defaults set
default:
return (false, missingFiles); // TODO: Figure out more formats
}
return (!missingFiles.Any(), missingFiles);
}
/// <inheritdoc/>
public override void GenerateSubmissionInfo(SubmissionInfo info, string basePath, Drive drive)
{
// TODO: Fill in submission info specifics for Aaru
string outputDirectory = Path.GetDirectoryName(basePath);
// Deserialize the sidecar, if possible
var sidecar = GenerateSidecar(basePath + ".cicm.xml");
// Fill in the hash data
info.TracksAndWriteOffsets.ClrMameProData = GenerateDatfile(sidecar, basePath);
switch (this.Type)
{
case MediaType.CDROM:
// TODO: Can this do GD-ROM?
info.Extras.PVD = GeneratePVD(sidecar) ?? "Disc has no PVD";
long errorCount = -1;
if (File.Exists(basePath + ".resume.xml"))
errorCount = GetErrorCount(basePath + ".resume.xml");
info.CommonDiscInfo.ErrorsCount = (errorCount == -1 ? "Error retrieving error count" : errorCount.ToString());
info.TracksAndWriteOffsets.Cuesheet = GenerateCuesheet(sidecar, basePath) ?? "";
string cdWriteOffset = GetWriteOffset(sidecar) ?? "";
info.CommonDiscInfo.RingWriteOffset = cdWriteOffset;
info.TracksAndWriteOffsets.OtherWriteOffsets = cdWriteOffset;
break;
// Non-optical
case MediaType.FloppyDisk:
// Currently no defaults set
case MediaType.DVD:
case MediaType.HDDVD:
case MediaType.BluRay:
// Get the individual hash data, as per internal
if (GetISOHashValues(info.TracksAndWriteOffsets.ClrMameProData, out long size, out string crc32, out string md5, out string sha1))
{
info.SizeAndChecksums.Size = size;
info.SizeAndChecksums.CRC32 = crc32;
info.SizeAndChecksums.MD5 = md5;
info.SizeAndChecksums.SHA1 = sha1;
}
// Deal with the layerbreak
string layerbreak = null;
if (this.Type == MediaType.DVD)
layerbreak = GetLayerbreak(sidecar) ?? "";
else if (this.Type == MediaType.BluRay)
layerbreak = info.SizeAndChecksums.Size > 25_025_314_816 ? "25025314816" : null;
// If we have a single-layer disc
if (string.IsNullOrWhiteSpace(layerbreak))
{
info.Extras.PVD = GeneratePVD(sidecar) ?? "Disc has no PVD";
}
// If we have a dual-layer disc
else
{
info.Extras.PVD = GeneratePVD(sidecar) ?? "Disc has no PVD";
info.SizeAndChecksums.Layerbreak = Int64.Parse(layerbreak);
}
// TODO: Investigate XGD disc outputs
// TODO: Investigate BD specifics like PIC
break;
}
switch (this.System)
{
// TODO: Can we get SecuROM data?
// TODO: Can we get SS version/ranges?
// TODO: Can we get DMI info?
// TODO: Can we get Sega Header info?
// TODO: Can we get PS1 EDC status?
// TODO: Can we get PS1 LibCrypt status?
case KnownSystem.DVDAudio:
case KnownSystem.DVDVideo:
info.CopyProtection.Protection = GetDVDProtection(sidecar) ?? "";
break;
case KnownSystem.KonamiPython2:
if (GetPlayStationExecutableInfo(drive?.Letter, out string pythonTwoSerial, out RedumpRegion? pythonTwoRegion, out string pythonTwoDate))
{
info.CommonDiscInfo.Comments += $"Internal Disc Serial: {pythonTwoSerial}\n";
info.CommonDiscInfo.Region = info.CommonDiscInfo.Region ?? pythonTwoRegion;
info.CommonDiscInfo.EXEDateBuildDate = pythonTwoDate;
}
info.VersionAndEditions.Version = GetPlayStation2Version(drive?.Letter) ?? "";
break;
case KnownSystem.MicrosoftXBOX:
if (GetXgdAuxInfo(sidecar, out string dmihash, out string pfihash, out string sshash, out string ss, out string ssver))
{
info.CommonDiscInfo.Comments += $"{Template.XBOXDMIHash}: {dmihash ?? ""}\n" +
$"{Template.XBOXPFIHash}: {pfihash ?? ""}\n" +
$"{Template.XBOXSSHash}: {sshash ?? ""}\n" +
$"{Template.XBOXSSVersion}: {ssver ?? ""}\n";
info.Extras.SecuritySectorRanges = ss ?? "";
}
if (GetXboxDMIInfo(sidecar, out string serial, out string version, out RedumpRegion? region))
{
info.CommonDiscInfo.Serial = serial ?? "";
info.VersionAndEditions.Version = version ?? "";
info.CommonDiscInfo.Region = region;
}
break;
case KnownSystem.MicrosoftXBOX360:
if (GetXgdAuxInfo(sidecar, out string dmi360hash, out string pfi360hash, out string ss360hash, out string ss360, out string ssver360))
{
info.CommonDiscInfo.Comments += $"{Template.XBOXDMIHash}: {dmi360hash ?? ""}\n" +
$"{Template.XBOXPFIHash}: {pfi360hash ?? ""}\n" +
$"{Template.XBOXSSHash}: {ss360hash ?? ""}\n" +
$"{Template.XBOXSSVersion}: {ssver360 ?? ""}\n";
info.Extras.SecuritySectorRanges = ss360 ?? "";
}
if (GetXbox360DMIInfo(sidecar, out string serial360, out string version360, out RedumpRegion? region360))
{
info.CommonDiscInfo.Serial = serial360 ?? "";
info.VersionAndEditions.Version = version360 ?? "";
info.CommonDiscInfo.Region = region360;
}
break;
case KnownSystem.SonyPlayStation:
if (GetPlayStationExecutableInfo(drive?.Letter, out string playstationSerial, out RedumpRegion? playstationRegion, out string playstationDate))
{
info.CommonDiscInfo.Comments += $"Internal Disc Serial: {playstationSerial}\n";
info.CommonDiscInfo.Region = info.CommonDiscInfo.Region ?? playstationRegion;
info.CommonDiscInfo.EXEDateBuildDate = playstationDate;
}
info.CopyProtection.AntiModchip = GetPlayStationAntiModchipDetected(drive?.Letter) ? YesNo.Yes : YesNo.No;
break;
case KnownSystem.SonyPlayStation2:
if (GetPlayStationExecutableInfo(drive?.Letter, out string playstationTwoSerial, out RedumpRegion? playstationTwoRegion, out string playstationTwoDate))
{
info.CommonDiscInfo.Comments += $"Internal Disc Serial: {playstationTwoSerial}\n";
info.CommonDiscInfo.Region = info.CommonDiscInfo.Region ?? playstationTwoRegion;
info.CommonDiscInfo.EXEDateBuildDate = playstationTwoDate;
}
info.VersionAndEditions.Version = GetPlayStation2Version(drive?.Letter) ?? "";
break;
case KnownSystem.SonyPlayStation4:
info.VersionAndEditions.Version = GetPlayStation4Version(drive?.Letter) ?? "";
break;
case KnownSystem.SonyPlayStation5:
info.VersionAndEditions.Version = GetPlayStation5Version(drive?.Letter) ?? "";
break;
}
// Fill in any artifacts that exist, Base64-encoded
if (File.Exists(basePath + ".cicm.xml"))
info.Artifacts["cicm"] = GetBase64(GetFullFile(basePath + ".cicm.xml"));
if (File.Exists(basePath + ".ibg"))
info.Artifacts["ibg"] = Convert.ToBase64String(File.ReadAllBytes(basePath + ".ibg"));
if (File.Exists(basePath + ".log"))
info.Artifacts["log"] = GetBase64(GetFullFile(basePath + ".log"));
if (File.Exists(basePath + ".mhddlog.bin"))
info.Artifacts["mhddlog_bin"] = Convert.ToBase64String(File.ReadAllBytes(basePath + ".mhddlog.bin"));
if (File.Exists(basePath + ".resume.xml"))
info.Artifacts["resume"] = GetBase64(GetFullFile(basePath + ".resume.xml"));
if (File.Exists(basePath + ".sub.log"))
info.Artifacts["sub_log"] = GetBase64(GetFullFile(basePath + ".sub.log"));
}
/// <inheritdoc/>
@@ -903,16 +1028,7 @@ namespace MPF.Aaru
}
/// <inheritdoc/>
public override string InputPath() => InputValue;
/// <inheritdoc/>
public override string OutputPath() => OutputValue;
/// <inheritdoc/>
public override int? GetSpeed() => SpeedValue;
/// <inheritdoc/>
public override void SetSpeed(int? speed) => SpeedValue = (sbyte?)speed;
public override string GetDefaultExtension(MediaType? mediaType) => Converters.Extension(mediaType);
/// <inheritdoc/>
public override bool IsDumpingCommand()
@@ -927,6 +1043,123 @@ namespace MPF.Aaru
}
}
/// <inheritdoc/>
protected override void ResetValues()
{
BaseCommand = Command.NONE;
_flags = new Dictionary<Flag, bool?>();
BlockSizeValue = null;
CommentsValue = null;
CreatorValue = null;
CountValue = null;
DriveManufacturerValue = null;
DriveModelValue = null;
DriveRevisionValue = null;
DriveSerialValue = null;
EncodingValue = null;
FormatConvertValue = null;
FormatDumpValue = null;
ImgBurnLogValue = null;
InputValue = null;
Input1Value = null;
Input2Value = null;
LengthValue = null;
MediaBarcodeValue = null;
MediaLastSequenceValue = null;
MediaManufacturerValue = null;
MediaModelValue = null;
MediaPartNumberValue = null;
MediaSequenceValue = null;
MediaSerialValue = null;
MediaTitleValue = null;
MHDDLogValue = null;
NamespaceValue = null;
OptionsValue = null;
OutputValue = null;
OutputPrefixValue = null;
RemoteHostValue = null;
ResumeFileValue = null;
RetryPassesValue = null;
SkipValue = null;
SpeedValue = null;
StartValue = null;
SubchannelValue = null;
WidthValue = null;
XMLSidecarValue = null;
}
/// <inheritdoc/>
protected override void SetDefaultParameters(char driveLetter, string filename, int? driveSpeed, Options options)
{
BaseCommand = Command.MediaDump;
InputValue = $"\\\\?\\{driveLetter}:";
OutputValue = filename;
if (driveSpeed != null)
{
this[Flag.Speed] = true;
SpeedValue = (sbyte?)driveSpeed;
}
// First check to see if the combination of system and MediaType is valid
var validTypes = Validators.GetValidMediaTypes(this.System);
if (!validTypes.Contains(this.Type))
return;
// Set retry count
if (options.AaruRereadCount > 0)
{
this[Flag.RetryPasses] = true;
RetryPassesValue = (short)options.AaruRereadCount;
}
// Set user-defined options
this[Flag.Debug] = options.AaruEnableDebug;
this[Flag.Verbose] = options.AaruEnableVerbose;
this[Flag.Force] = options.AaruForceDumping;
this[Flag.Private] = options.AaruStripPersonalData;
// TODO: Look at dump-media formats and the like and see what options there are there to fill in defaults
// Now sort based on disc type
switch (this.Type)
{
case MediaType.CDROM:
this[Flag.FirstPregap] = true;
this[Flag.FixOffset] = true;
this[Flag.Subchannel] = true;
SubchannelValue = "any";
break;
case MediaType.DVD:
// Currently no defaults set
break;
case MediaType.GDROM:
// Currently no defaults set
break;
case MediaType.HDDVD:
// Currently no defaults set
break;
case MediaType.BluRay:
// Currently no defaults set
break;
// Special Formats
case MediaType.NintendoGameCubeGameDisc:
// Currently no defaults set
break;
case MediaType.NintendoWiiOpticalDisc:
// Currently no defaults set
break;
// Non-optical
case MediaType.FloppyDisk:
// Currently no defaults set
break;
}
}
/// <inheritdoc/>
protected override bool ValidateAndSetParameters(string parameters)
{
@@ -1410,226 +1643,9 @@ namespace MPF.Aaru
return true;
}
/// <inheritdoc/>
public override (bool, List<string>) CheckAllOutputFilesExist(string basePath)
{
List<string> missingFiles = new List<string>();
switch (this.Type)
{
case MediaType.CDROM:
if (!File.Exists($"{basePath}.cicm.xml"))
missingFiles.Add($"{basePath}.cicm.xml");
if (!File.Exists($"{basePath}.ibg"))
missingFiles.Add($"{basePath}.ibg");
if (!File.Exists($"{basePath}.log"))
missingFiles.Add($"{basePath}.log");
if (!File.Exists($"{basePath}.mhddlog.bin"))
missingFiles.Add($"{basePath}.mhddlog.bin");
if (!File.Exists($"{basePath}.resume.xml"))
missingFiles.Add($"{basePath}.resume.xml");
if (!File.Exists($"{basePath}.sub.log"))
missingFiles.Add($"{basePath}.sub.log");
#endregion
break;
case MediaType.DVD:
case MediaType.HDDVD:
case MediaType.BluRay:
if (!File.Exists($"{basePath}.cicm.xml"))
missingFiles.Add($"{basePath}.cicm.xml");
if (!File.Exists($"{basePath}.ibg"))
missingFiles.Add($"{basePath}.ibg");
if (!File.Exists($"{basePath}.log"))
missingFiles.Add($"{basePath}.log");
if (!File.Exists($"{basePath}.mhddlog.bin"))
missingFiles.Add($"{basePath}.mhddlog.bin");
if (!File.Exists($"{basePath}.resume.xml"))
missingFiles.Add($"{basePath}.resume.xml");
break;
default:
return (false, missingFiles); // TODO: Figure out more formats
}
return (!missingFiles.Any(), missingFiles);
}
/// <inheritdoc/>
public override void GenerateSubmissionInfo(SubmissionInfo info, string basePath, Drive drive)
{
// TODO: Fill in submission info specifics for Aaru
string outputDirectory = Path.GetDirectoryName(basePath);
// Deserialize the sidecar, if possible
var sidecar = GenerateSidecar(basePath + ".cicm.xml");
// Fill in the hash data
info.TracksAndWriteOffsets.ClrMameProData = GenerateDatfile(sidecar, basePath);
switch (this.Type)
{
case MediaType.CDROM:
// TODO: Can this do GD-ROM?
info.Extras.PVD = GeneratePVD(sidecar) ?? "Disc has no PVD";
long errorCount = -1;
if (File.Exists(basePath + ".resume.xml"))
errorCount = GetErrorCount(basePath + ".resume.xml");
info.CommonDiscInfo.ErrorsCount = (errorCount == -1 ? "Error retrieving error count" : errorCount.ToString());
info.TracksAndWriteOffsets.Cuesheet = GenerateCuesheet(sidecar, basePath) ?? "";
string cdWriteOffset = GetWriteOffset(sidecar) ?? "";
info.CommonDiscInfo.RingWriteOffset = cdWriteOffset;
info.TracksAndWriteOffsets.OtherWriteOffsets = cdWriteOffset;
break;
case MediaType.DVD:
case MediaType.HDDVD:
case MediaType.BluRay:
// Get the individual hash data, as per internal
if (GetISOHashValues(info.TracksAndWriteOffsets.ClrMameProData, out long size, out string crc32, out string md5, out string sha1))
{
info.SizeAndChecksums.Size = size;
info.SizeAndChecksums.CRC32 = crc32;
info.SizeAndChecksums.MD5 = md5;
info.SizeAndChecksums.SHA1 = sha1;
}
// Deal with the layerbreak
string layerbreak = null;
if (this.Type == MediaType.DVD)
layerbreak = GetLayerbreak(sidecar) ?? "";
else if (this.Type == MediaType.BluRay)
layerbreak = info.SizeAndChecksums.Size > 25_025_314_816 ? "25025314816" : null;
// If we have a single-layer disc
if (string.IsNullOrWhiteSpace(layerbreak))
{
info.Extras.PVD = GeneratePVD(sidecar) ?? "Disc has no PVD";
}
// If we have a dual-layer disc
else
{
info.Extras.PVD = GeneratePVD(sidecar) ?? "Disc has no PVD";
info.SizeAndChecksums.Layerbreak = Int64.Parse(layerbreak);
}
// TODO: Investigate XGD disc outputs
// TODO: Investigate BD specifics like PIC
break;
}
switch (this.System)
{
// TODO: Can we get SecuROM data?
// TODO: Can we get SS version/ranges?
// TODO: Can we get DMI info?
// TODO: Can we get Sega Header info?
// TODO: Can we get PS1 EDC status?
// TODO: Can we get PS1 LibCrypt status?
case KnownSystem.DVDAudio:
case KnownSystem.DVDVideo:
info.CopyProtection.Protection = GetDVDProtection(sidecar) ?? "";
break;
case KnownSystem.KonamiPython2:
if (GetPlayStationExecutableInfo(drive?.Letter, out string pythonTwoSerial, out RedumpRegion? pythonTwoRegion, out string pythonTwoDate))
{
info.CommonDiscInfo.Comments += $"Internal Disc Serial: {pythonTwoSerial}\n";
info.CommonDiscInfo.Region = info.CommonDiscInfo.Region ?? pythonTwoRegion;
info.CommonDiscInfo.EXEDateBuildDate = pythonTwoDate;
}
info.VersionAndEditions.Version = GetPlayStation2Version(drive?.Letter) ?? "";
break;
case KnownSystem.MicrosoftXBOX:
if (GetXgdAuxInfo(sidecar, out string dmihash, out string pfihash, out string sshash, out string ss, out string ssver))
{
info.CommonDiscInfo.Comments += $"{Template.XBOXDMIHash}: {dmihash ?? ""}\n" +
$"{Template.XBOXPFIHash}: {pfihash ?? ""}\n" +
$"{Template.XBOXSSHash}: {sshash ?? ""}\n" +
$"{Template.XBOXSSVersion}: {ssver ?? ""}\n";
info.Extras.SecuritySectorRanges = ss ?? "";
}
if (GetXboxDMIInfo(sidecar, out string serial, out string version, out RedumpRegion? region))
{
info.CommonDiscInfo.Serial = serial ?? "";
info.VersionAndEditions.Version = version ?? "";
info.CommonDiscInfo.Region = region;
}
break;
case KnownSystem.MicrosoftXBOX360:
if (GetXgdAuxInfo(sidecar, out string dmi360hash, out string pfi360hash, out string ss360hash, out string ss360, out string ssver360))
{
info.CommonDiscInfo.Comments += $"{Template.XBOXDMIHash}: {dmi360hash ?? ""}\n" +
$"{Template.XBOXPFIHash}: {pfi360hash ?? ""}\n" +
$"{Template.XBOXSSHash}: {ss360hash ?? ""}\n" +
$"{Template.XBOXSSVersion}: {ssver360 ?? ""}\n";
info.Extras.SecuritySectorRanges = ss360 ?? "";
}
if (GetXbox360DMIInfo(sidecar, out string serial360, out string version360, out RedumpRegion? region360))
{
info.CommonDiscInfo.Serial = serial360 ?? "";
info.VersionAndEditions.Version = version360 ?? "";
info.CommonDiscInfo.Region = region360;
}
break;
case KnownSystem.SonyPlayStation:
if (GetPlayStationExecutableInfo(drive?.Letter, out string playstationSerial, out RedumpRegion? playstationRegion, out string playstationDate))
{
info.CommonDiscInfo.Comments += $"Internal Disc Serial: {playstationSerial}\n";
info.CommonDiscInfo.Region = info.CommonDiscInfo.Region ?? playstationRegion;
info.CommonDiscInfo.EXEDateBuildDate = playstationDate;
}
info.CopyProtection.AntiModchip = GetPlayStationAntiModchipDetected(drive?.Letter) ? YesNo.Yes : YesNo.No;
break;
case KnownSystem.SonyPlayStation2:
if (GetPlayStationExecutableInfo(drive?.Letter, out string playstationTwoSerial, out RedumpRegion? playstationTwoRegion, out string playstationTwoDate))
{
info.CommonDiscInfo.Comments += $"Internal Disc Serial: {playstationTwoSerial}\n";
info.CommonDiscInfo.Region = info.CommonDiscInfo.Region ?? playstationTwoRegion;
info.CommonDiscInfo.EXEDateBuildDate = playstationTwoDate;
}
info.VersionAndEditions.Version = GetPlayStation2Version(drive?.Letter) ?? "";
break;
case KnownSystem.SonyPlayStation4:
info.VersionAndEditions.Version = GetPlayStation4Version(drive?.Letter) ?? "";
break;
case KnownSystem.SonyPlayStation5:
info.VersionAndEditions.Version = GetPlayStation5Version(drive?.Letter) ?? "";
break;
}
// Fill in any artifacts that exist, Base64-encoded
if (File.Exists(basePath + ".cicm.xml"))
info.Artifacts["cicm"] = GetBase64(GetFullFile(basePath + ".cicm.xml"));
if (File.Exists(basePath + ".ibg"))
info.Artifacts["ibg"] = Convert.ToBase64String(File.ReadAllBytes(basePath + ".ibg"));
if (File.Exists(basePath + ".log"))
info.Artifacts["log"] = GetBase64(GetFullFile(basePath + ".log"));
if (File.Exists(basePath + ".mhddlog.bin"))
info.Artifacts["mhddlog_bin"] = Convert.ToBase64String(File.ReadAllBytes(basePath + ".mhddlog.bin"));
if (File.Exists(basePath + ".resume.xml"))
info.Artifacts["resume"] = GetBase64(GetFullFile(basePath + ".resume.xml"));
if (File.Exists(basePath + ".sub.log"))
info.Artifacts["sub_log"] = GetBase64(GetFullFile(basePath + ".sub.log"));
}
#region Private Extra Methods
/// <summary>
/// Get the list of commands that use a given flag
@@ -1907,6 +1923,8 @@ namespace MPF.Aaru
return commands;
}
#endregion
#region Process Parameter Helpers
/// <summary>

View File

@@ -12,20 +12,24 @@ namespace MPF.CleanRip
/// </summary>
public class Parameters : BaseParameters
{
#region Metadata
/// <inheritdoc/>
public Parameters(string parameters)
: base(parameters)
{
this.InternalProgram = InternalProgram.CleanRip;
}
public override InternalProgram InternalProgram => InternalProgram.CleanRip;
#endregion
/// <inheritdoc/>
public Parameters(string parameters) : base(parameters) { }
/// <inheritdoc/>
public Parameters(KnownSystem? system, MediaType? type, char driveLetter, string filename, int? driveSpeed, Options options)
: base(system, type, driveLetter, filename, driveSpeed, options)
{
this.InternalProgram = InternalProgram.CleanRip;
}
#region BaseParameters Implementations
/// <inheritdoc/>
public override (bool, List<string>) CheckAllOutputFilesExist(string basePath)
{
@@ -92,6 +96,8 @@ namespace MPF.CleanRip
info.Artifacts["dumpinfo"] = GetBase64(GetFullFile(basePath + "-dumpinfo.txt"));
}
#endregion
#region Information Extraction Methods
/// <summary>

View File

@@ -13,11 +13,36 @@ namespace MPF.DD
/// </summary>
public class Parameters : BaseParameters
{
#region Generic Dumping Information
/// <inheritdoc/>
public override string InputPath => InputFileValue;
/// <inheritdoc/>
public override string OutputPath => OutputFileValue;
/// <inheritdoc/>
/// <inheritdoc/>
public override int? Speed
{
get { return 1; }
set { }
}
#endregion
#region Metadata
/// <summary>
/// Base command to run
/// </summary>
public Command BaseCommand { get; set; }
/// <inheritdoc/>
public override InternalProgram InternalProgram => InternalProgram.DD;
#endregion
/// <summary>
/// Set of flags to pass to the executable
/// </summary>
@@ -58,17 +83,77 @@ namespace MPF.DD
#endregion
/// <inheritdoc/>
public Parameters(string parameters)
: base(parameters)
{
this.InternalProgram = InternalProgram.DD;
}
public Parameters(string parameters) : base(parameters) { }
/// <inheritdoc/>
public Parameters(KnownSystem? system, MediaType? type, char driveLetter, string filename, int? driveSpeed, Options options)
: base(system, type, driveLetter, filename, driveSpeed, options)
{
this.InternalProgram = InternalProgram.DD;
}
#region BaseParameters Implementations
/// <inheritdoc/>
public override (bool, List<string>) CheckAllOutputFilesExist(string basePath)
{
// TODO: Figure out what sort of output files are expected... just `.bin`?
return (true, new List<string>());
}
/// <inheritdoc/>
public override void GenerateSubmissionInfo(SubmissionInfo info, string basePath, Drive drive)
{
// TODO: Fill in submission info specifics for DD
string outputDirectory = Path.GetDirectoryName(basePath);
switch (this.Type)
{
// Determine type-specific differences
}
switch (this.System)
{
case KnownSystem.KonamiPython2:
if (GetPlayStationExecutableInfo(drive?.Letter, out string pythonTwoSerial, out RedumpRegion? pythonTwoRegion, out string pythonTwoDate))
{
info.CommonDiscInfo.Comments += $"Internal Disc Serial: {pythonTwoSerial}\n";
info.CommonDiscInfo.Region = info.CommonDiscInfo.Region ?? pythonTwoRegion;
info.CommonDiscInfo.EXEDateBuildDate = pythonTwoDate;
}
info.VersionAndEditions.Version = GetPlayStation2Version(drive?.Letter) ?? "";
break;
case KnownSystem.SonyPlayStation:
if (GetPlayStationExecutableInfo(drive?.Letter, out string playstationSerial, out RedumpRegion? playstationRegion, out string playstationDate))
{
info.CommonDiscInfo.Comments += $"Internal Disc Serial: {playstationSerial}\n";
info.CommonDiscInfo.Region = info.CommonDiscInfo.Region ?? playstationRegion;
info.CommonDiscInfo.EXEDateBuildDate = playstationDate;
}
info.CopyProtection.AntiModchip = GetPlayStationAntiModchipDetected(drive?.Letter) ? YesNo.Yes : YesNo.No;
break;
case KnownSystem.SonyPlayStation2:
if (GetPlayStationExecutableInfo(drive?.Letter, out string playstationTwoSerial, out RedumpRegion? playstationTwoRegion, out string playstationTwoDate))
{
info.CommonDiscInfo.Comments += $"Internal Disc Serial: {playstationTwoSerial}\n";
info.CommonDiscInfo.Region = info.CommonDiscInfo.Region ?? playstationTwoRegion;
info.CommonDiscInfo.EXEDateBuildDate = playstationTwoDate;
}
info.VersionAndEditions.Version = GetPlayStation2Version(drive?.Letter) ?? "";
break;
case KnownSystem.SonyPlayStation4:
info.VersionAndEditions.Version = GetPlayStation4Version(drive?.Letter) ?? "";
break;
case KnownSystem.SonyPlayStation5:
info.VersionAndEditions.Version = GetPlayStation5Version(drive?.Letter) ?? "";
break;
}
}
/// <inheritdoc/>
@@ -162,13 +247,7 @@ namespace MPF.DD
}
/// <inheritdoc/>
public override string InputPath() => InputFileValue;
/// <inheritdoc/>
public override string OutputPath() => OutputFileValue;
/// <inheritdoc/>
public override int? GetSpeed() => 1;
public override string GetDefaultExtension(MediaType? mediaType) => Converters.Extension(mediaType);
/// <inheritdoc/>
public override bool IsDumpingCommand()
@@ -326,68 +405,9 @@ namespace MPF.DD
return true;
}
/// <inheritdoc/>
public override (bool, List<string>) CheckAllOutputFilesExist(string basePath)
{
// TODO: Figure out what sort of output files are expected... just `.bin`?
return (true, new List<string>());
}
#endregion
/// <inheritdoc/>
public override void GenerateSubmissionInfo(SubmissionInfo info, string basePath, Drive drive)
{
// TODO: Fill in submission info specifics for DD
string outputDirectory = Path.GetDirectoryName(basePath);
switch (this.Type)
{
// Determine type-specific differences
}
switch (this.System)
{
case KnownSystem.KonamiPython2:
if (GetPlayStationExecutableInfo(drive?.Letter, out string pythonTwoSerial, out RedumpRegion? pythonTwoRegion, out string pythonTwoDate))
{
info.CommonDiscInfo.Comments += $"Internal Disc Serial: {pythonTwoSerial}\n";
info.CommonDiscInfo.Region = info.CommonDiscInfo.Region ?? pythonTwoRegion;
info.CommonDiscInfo.EXEDateBuildDate = pythonTwoDate;
}
info.VersionAndEditions.Version = GetPlayStation2Version(drive?.Letter) ?? "";
break;
case KnownSystem.SonyPlayStation:
if (GetPlayStationExecutableInfo(drive?.Letter, out string playstationSerial, out RedumpRegion? playstationRegion, out string playstationDate))
{
info.CommonDiscInfo.Comments += $"Internal Disc Serial: {playstationSerial}\n";
info.CommonDiscInfo.Region = info.CommonDiscInfo.Region ?? playstationRegion;
info.CommonDiscInfo.EXEDateBuildDate = playstationDate;
}
info.CopyProtection.AntiModchip = GetPlayStationAntiModchipDetected(drive?.Letter) ? YesNo.Yes : YesNo.No;
break;
case KnownSystem.SonyPlayStation2:
if (GetPlayStationExecutableInfo(drive?.Letter, out string playstationTwoSerial, out RedumpRegion? playstationTwoRegion, out string playstationTwoDate))
{
info.CommonDiscInfo.Comments += $"Internal Disc Serial: {playstationTwoSerial}\n";
info.CommonDiscInfo.Region = info.CommonDiscInfo.Region ?? playstationTwoRegion;
info.CommonDiscInfo.EXEDateBuildDate = playstationTwoDate;
}
info.VersionAndEditions.Version = GetPlayStation2Version(drive?.Letter) ?? "";
break;
case KnownSystem.SonyPlayStation4:
info.VersionAndEditions.Version = GetPlayStation4Version(drive?.Letter) ?? "";
break;
case KnownSystem.SonyPlayStation5:
info.VersionAndEditions.Version = GetPlayStation5Version(drive?.Letter) ?? "";
break;
}
}
#region Private Extra Methods
/// <summary>
/// Get the list of commands that use a given flag
@@ -449,6 +469,10 @@ namespace MPF.DD
return commands;
}
#endregion
#region Process Parameter Helpers
/// <summary>
/// Process a boolean parameter
/// </summary>
@@ -587,5 +611,7 @@ namespace MPF.DD
return string.Empty;
}
#endregion
}
}

View File

@@ -32,11 +32,43 @@ namespace MPF.Data
#endregion
#region Generic Dumping Information
/// <summary>
/// Input path for operations
/// </summary>
public virtual string InputPath => null;
/// <summary>
/// Output path for operations
/// </summary>
/// <returns>String representing the path, null on error</returns>
public virtual string OutputPath => null;
/// <summary>
/// Get the processing speed from the implementation
/// </summary>
public virtual int? Speed { get; set; } = null;
/// <summary>
/// Process to track external program
/// </summary>
private Process process;
#endregion
#region Metadata
/// <summary>
/// Path to the executable
/// </summary>
public string ExecutablePath { get; set; }
/// <summary>
/// Program that this set of parameters represents
/// </summary>
public virtual InternalProgram InternalProgram { get; }
/// <summary>
/// Currently represented system
/// </summary>
@@ -47,15 +79,7 @@ namespace MPF.Data
/// </summary>
public MediaType? Type { get; set; }
/// <summary>
/// Program that this set of parameters represents
/// </summary>
public InternalProgram InternalProgram { get; set; }
/// <summary>
/// Process to track external program
/// </summary>
private Process process;
#endregion
/// <summary>
/// Populate a Parameters object from a param string
@@ -84,35 +108,39 @@ namespace MPF.Data
SetDefaultParameters(driveLetter, filename, driveSpeed, options);
}
#region Abstract Methods
/// <summary>
/// Validate if all required output files exist
/// </summary>
/// <param name="basePath">Base filename and path to use for checking</param>
/// <returns>Tuple of true if all required files exist, false otherwise and a list representing missing files</returns>
public abstract (bool, List<string>) CheckAllOutputFilesExist(string basePath);
/// <summary>
/// Generate a SubmissionInfo for the output files
/// </summary>
/// <param name="submissionInfo">Base submission info to fill in specifics for</param>
/// <param name="basePath">Base filename and path to use for checking</param>
/// <param name="drive">Drive representing the disc to get information from</param>
public abstract void GenerateSubmissionInfo(SubmissionInfo submissionInfo, string basePath, Drive drive);
#endregion
#region Virtual Methods
/// <summary>
/// Blindly generate a parameter string based on the inputs
/// </summary>
/// <returns>Correctly formatted parameter string, null on error</returns>
/// <returns>Parameter string for invocation, null on error</returns>
public virtual string GenerateParameters() => null;
/// <summary>
/// Get the input path from the implementation
/// Get the default extension for a given media type
/// </summary>
/// <returns>String representing the path, null on error</returns>
public virtual string InputPath() => null;
/// <summary>
/// Get the output path from the implementation
/// </summary>
/// <returns>String representing the path, null on error</returns>
public virtual string OutputPath() => null;
/// <summary>
/// Get the processing speed from the implementation
/// </summary>
/// <returns>int? representing the speed, null on error</returns>
public virtual int? GetSpeed() => null;
/// <summary>
/// Set the processing speed int the implementation
/// </summary>
/// <param name="speed">int? representing the speed</param>
public virtual void SetSpeed(int? speed) { }
/// <param name="mediaType">MediaType value to check</param>
/// <returns>String representing the media type, null on error</returns>
public virtual string GetDefaultExtension(MediaType? mediaType) => null;
/// <summary>
/// Get the MediaType from the current set of parameters
@@ -153,20 +181,9 @@ namespace MPF.Data
/// <returns>True if the parameters were set correctly, false otherwise</returns>
protected virtual bool ValidateAndSetParameters(string parameters) => true;
/// <summary>
/// Validate if all required output files exist
/// </summary>
/// <param name="basePath">Base filename and path to use for checking</param>
/// <returns>Tuple of true if all required files exist, false otherwise and a list representing missing files</returns>
public abstract (bool, List<string>) CheckAllOutputFilesExist(string basePath);
#endregion
/// <summary>
/// Generate a SubmissionInfo for the output files
/// </summary>
/// <param name="submissionInfo">Base submission info to fill in specifics for</param>
/// <param name="basePath">Base filename and path to use for checking</param>
/// <param name="drive">Drive representing the disc to get information from</param>
public abstract void GenerateSubmissionInfo(SubmissionInfo submissionInfo, string basePath, Drive drive);
#region Execution
/// <summary>
/// Run internal program
@@ -209,43 +226,6 @@ namespace MPF.Data
process.Close();
}
/// <summary>
/// Run internal program async with an input set of parameters
/// </summary>
/// <param name="parameters"></param>
/// <returns>Standard output from commandline window</returns>
public async Task<string> 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;
}
/// <summary>
/// Cancel an in-progress dumping process
/// </summary>
@@ -262,6 +242,8 @@ namespace MPF.Data
{ }
}
#endregion
#region Parameter Parsing
/// <summary>

File diff suppressed because it is too large Load Diff

View File

@@ -12,20 +12,24 @@ namespace MPF.UmdImageCreator
/// </summary>
public class Parameters : BaseParameters
{
#region Metadata
/// <inheritdoc/>
public Parameters(string parameters)
: base(parameters)
{
this.InternalProgram = InternalProgram.UmdImageCreator;
}
public override InternalProgram InternalProgram => InternalProgram.UmdImageCreator;
#endregion
/// <inheritdoc/>
public Parameters(string parameters) : base(parameters) { }
/// <inheritdoc/>
public Parameters(KnownSystem? system, MediaType? type, char driveLetter, string filename, int? driveSpeed, Options options)
: base(system, type, driveLetter, filename, driveSpeed, options)
{
this.InternalProgram = InternalProgram.UmdImageCreator;
}
#region BaseParameters Implementations
/// <inheritdoc/>
public override (bool, List<string>) CheckAllOutputFilesExist(string basePath)
{
@@ -93,6 +97,8 @@ namespace MPF.UmdImageCreator
info.Artifacts["volDesc"] = GetBase64(GetFullFile(basePath + "_volDesc.txt"));
}
#endregion
#region Information Extraction Methods
/// <summary>

View File

@@ -24,12 +24,12 @@ namespace MPF.Utilities
/// <summary>
/// Base output directory to write files to
/// </summary>
public string OutputDirectory { get; set; }
public string OutputDirectory { get; private set; }
/// <summary>
/// Base output filename for DiscImageCreator
/// Base output filename for output
/// </summary>
public string OutputFilename { get; set; }
public string OutputFilename { get; private set; }
#endregion
@@ -38,27 +38,27 @@ namespace MPF.Utilities
/// <summary>
/// Drive object representing the current drive
/// </summary>
public Drive Drive { get; set; }
public Drive Drive { get; private set; }
/// <summary>
/// Currently selected system
/// </summary>
public KnownSystem? System { get; set; }
public KnownSystem? System { get; private set; }
/// <summary>
/// Currently selected media type
/// </summary>
public MediaType? Type { get; set; }
public MediaType? Type { get; private set; }
/// <summary>
/// Options object representing user-defined options
/// </summary>
public Options Options { get; set; }
public Options Options { get; private set; }
/// <summary>
/// Parameters object representing what to send to the internal program
/// </summary>
public BaseParameters Parameters { get; set; }
public BaseParameters Parameters { get; private set; }
#endregion
@@ -102,17 +102,15 @@ namespace MPF.Utilities
this.Options = options;
// Output paths
this.OutputDirectory = outputDirectory;
this.OutputFilename = outputFilename;
(this.OutputDirectory, this.OutputFilename) = NormalizeOutputPaths(outputDirectory, outputFilename);
// UI information
this.Drive = drive;
this.System = system;
this.Type = type;
this.System = system ?? options.DefaultSystem;
this.Type = type ?? MediaType.NONE;
// Dumping program
SetParameters(parameters);
this.Parameters.System = system;
this.Parameters.Type = type;
}
#region Public Functionality
@@ -163,6 +161,10 @@ namespace MPF.Utilities
this.Parameters.ExecutablePath = Options.DiscImageCreatorPath;
break;
}
// Set system and type
this.Parameters.System = this.System;
this.Parameters.Type = this.Type;
}
/// <summary>
@@ -202,64 +204,6 @@ namespace MPF.Utilities
await ExecuteInternalProgram(parameters);
}
/// <summary>
/// Fix output paths to strip out any invalid characters
/// </summary>
public void FixOutputPaths()
{
try
{
// Cache if we had a directory separator or not
bool endedWithDirectorySeparator = OutputDirectory.EndsWith(Path.DirectorySeparatorChar.ToString())
|| OutputDirectory.EndsWith(Path.AltDirectorySeparatorChar.ToString());
bool endedWithSpace = OutputDirectory.EndsWith(" ");
// Combine the path to make things separate easier
string combinedPath = Path.Combine(OutputDirectory, OutputFilename);
// If we have have a blank path, just return
if (string.IsNullOrWhiteSpace(combinedPath))
return;
// Now get the normalized paths
OutputDirectory = Path.GetDirectoryName(combinedPath);
OutputFilename = Path.GetFileName(combinedPath);
// Take care of extra path characters
OutputDirectory = new StringBuilder(OutputDirectory)
.Replace(':', '_', 0, OutputDirectory.LastIndexOf(':') == -1 ? 0 : OutputDirectory.LastIndexOf(':')).ToString();
// Sanitize everything else
foreach (char c in Path.GetInvalidPathChars())
OutputDirectory = OutputDirectory.Replace(c, '_');
foreach (char c in Path.GetInvalidFileNameChars())
OutputFilename = OutputFilename.Replace(c, '_');
// If we had a space at the end before, add it again
if (endedWithSpace)
OutputDirectory += " ";
// If we had a directory separator at the end before, add it again
if (endedWithDirectorySeparator)
OutputDirectory += Path.DirectorySeparatorChar;
// If we have a root directory, sanitize
if (Directory.Exists(OutputDirectory))
{
var possibleRootDir = new DirectoryInfo(OutputDirectory);
if (possibleRootDir.Parent == null)
{
OutputDirectory = OutputDirectory.Replace($"{Path.DirectorySeparatorChar}{Path.DirectorySeparatorChar}", $"{Path.DirectorySeparatorChar}");
}
}
}
catch
{
// We don't care what the error was
return;
}
}
/// <summary>
/// Ensures that all required output files have been created
/// </summary>
@@ -277,30 +221,6 @@ namespace MPF.Utilities
return Parameters.CheckAllOutputFilesExist(basePath);
}
/// <summary>
/// Get the extension for a given media type and internal program
/// </summary>
/// <param name="mediaType"></param>
/// <returns></returns>
public string GetExtension(MediaType? mediaType)
{
switch (Options.InternalProgram)
{
case InternalProgram.Aaru:
return Aaru.Converters.Extension(mediaType);
case InternalProgram.DD:
return DD.Converters.Extension(mediaType);
case InternalProgram.DiscImageCreator:
return DiscImageCreator.Converters.Extension(mediaType);
// This should never happen, but it needs a fallback
default:
return DiscImageCreator.Converters.Extension(mediaType);
}
}
/// <summary>
/// Get the full parameter string for either DiscImageCreator or Aaru
/// </summary>
@@ -344,6 +264,62 @@ namespace MPF.Utilities
return null;
}
/// <summary>
/// Normalize a split set of paths
/// </summary>
/// <param name="directory">Directory name to normalize</param>
/// <param name="filename">Filename to normalize</param>
public static (string, string) NormalizeOutputPaths(string directory, string filename)
{
try
{
// Cache if we had a directory separator or not
bool endedWithDirectorySeparator = directory.EndsWith(Path.DirectorySeparatorChar.ToString())
|| directory.EndsWith(Path.AltDirectorySeparatorChar.ToString());
bool endedWithSpace = directory.EndsWith(" ");
// Combine the path to make things separate easier
string combinedPath = Path.Combine(directory, filename);
// If we have have a blank path, just return
if (string.IsNullOrWhiteSpace(combinedPath))
return (directory, filename);
// Now get the normalized paths
directory = Path.GetDirectoryName(combinedPath);
filename = Path.GetFileName(combinedPath);
// Take care of extra path characters
directory = new StringBuilder(directory)
.Replace(':', '_', 0, directory.LastIndexOf(':') == -1 ? 0 : directory.LastIndexOf(':')).ToString();
// Sanitize everything else
foreach (char c in Path.GetInvalidPathChars())
directory = directory.Replace(c, '_');
foreach (char c in Path.GetInvalidFileNameChars())
filename = filename.Replace(c, '_');
// If we had a space at the end before, add it again
if (endedWithSpace)
directory += " ";
// If we had a directory separator at the end before, add it again
if (endedWithDirectorySeparator)
directory += Path.DirectorySeparatorChar;
// If we have a root directory, sanitize
if (Directory.Exists(directory))
{
var possibleRootDir = new DirectoryInfo(directory);
if (possibleRootDir.Parent == null)
directory = directory.Replace($"{Path.DirectorySeparatorChar}{Path.DirectorySeparatorChar}", $"{Path.DirectorySeparatorChar}");
}
}
catch { }
return (directory, filename);
}
/// <summary>
/// Reset the current drive using DiscImageCreator
/// </summary>
@@ -1266,13 +1242,21 @@ namespace MPF.Utilities
return Result.Failure("Error! Current configuration is not supported!");
// Fix the output paths, just in case
FixOutputPaths();
(OutputDirectory, OutputFilename) = NormalizeOutputPaths(OutputDirectory, OutputFilename);
// Validate that the output path isn't on the dumping drive
string fullOutputPath = Path.GetFullPath(Path.Combine(OutputDirectory, OutputFilename));
if (fullOutputPath[0] == Drive.Letter)
return Result.Failure($"Error! Cannot output to same drive that is being dumped!");
// Validate that the required program exists
if (!File.Exists(Parameters.ExecutablePath))
return Result.Failure($"Error! {Parameters.ExecutablePath} does not exist!");
// TODO: Ensure output path not the same as input drive OR executable location
// Validate that the dumping drive doesn't contain the executable
string fullExecutablePath = Path.GetFullPath(Parameters.ExecutablePath);
if (fullExecutablePath[0] == Drive.Letter)
return Result.Failure("$Error! Cannot dump same drive that executable resides on!");
// Validate that the current configuration is supported
return Validators.GetSupportStatus(System, Type);

View File

@@ -38,12 +38,9 @@ namespace MPF.Test
[InlineData("superhero", "blah&foo.bin", "superhero", "blah&foo.bin")]
public void FixOutputPathsTest(string outputDirectory, string outputFilename, string expectedOutputDirectory, string expectedOutputFilename)
{
var options = new Options() { InternalProgram = InternalProgram.DiscImageCreator };
var env = new DumpEnvironment(options, outputDirectory, outputFilename, null, KnownSystem.IBMPCCompatible, MediaType.CDROM, string.Empty);
env.FixOutputPaths();
Assert.Equal(expectedOutputDirectory, env.OutputDirectory);
Assert.Equal(expectedOutputFilename, env.OutputFilename);
(string actualOutputDirectory, string actualOutputFilename) = DumpEnvironment.NormalizeOutputPaths(outputDirectory, outputFilename);
Assert.Equal(expectedOutputDirectory, actualOutputDirectory);
Assert.Equal(expectedOutputFilename, actualOutputFilename);
}
[Fact]

View File

@@ -389,12 +389,6 @@ namespace MPF.Windows
// Get the current environment information
Env = DetermineEnvironment();
// Take care of null cases
if (Env.System == null)
Env.System = UIOptions.Options.DefaultSystem;
if (Env.Type == null)
Env.Type = MediaType.NONE;
// Get the status to write out
Result result = Validators.GetSupportStatus(Env.System, Env.Type);
StatusLabel.Content = result.Message;
@@ -431,7 +425,7 @@ namespace MPF.Windows
OutputDirectoryTextBox.Text = Path.Combine(UIOptions.Options.DefaultOutputPath, drive?.VolumeLabel ?? string.Empty);
// Get the extension for the file for the next two statements
string extension = Env.GetExtension(mediaType);
string extension = Env.Parameters?.GetDefaultExtension(mediaType);
// Set the output filename, if we changed drives or it's not already
if (driveChanged || string.IsNullOrEmpty(OutputFilenameTextBox.Text))
@@ -451,19 +445,20 @@ namespace MPF.Windows
if (Env.Parameters == null)
return;
int driveIndex = Drives.Select(d => d.Letter).ToList().IndexOf(Env.Parameters.InputPath()[0]);
int driveIndex = Drives.Select(d => d.Letter).ToList().IndexOf(Env.Parameters.InputPath[0]);
if (driveIndex > -1)
DriveLetterComboBox.SelectedIndex = driveIndex;
int driveSpeed = Env.Parameters.GetSpeed() ?? -1;
int driveSpeed = Env.Parameters.Speed ?? -1;
if (driveSpeed > 0)
DriveSpeedComboBox.SelectedValue = driveSpeed;
else
Env.Parameters.SetSpeed((int?)DriveSpeedComboBox.SelectedValue);
Env.Parameters.Speed = DriveSpeedComboBox.SelectedValue as int?;
string trimmedPath = Env.Parameters.OutputPath()?.Trim('"') ?? string.Empty;
string trimmedPath = Env.Parameters.OutputPath?.Trim('"') ?? string.Empty;
string outputDirectory = Path.GetDirectoryName(trimmedPath);
string outputFilename = Path.GetFileName(trimmedPath);
(outputDirectory, outputFilename) = DumpEnvironment.NormalizeOutputPaths(outputDirectory, outputFilename);
if (!string.IsNullOrWhiteSpace(outputDirectory))
OutputDirectoryTextBox.Text = outputDirectory;
else
@@ -592,9 +587,6 @@ namespace MPF.Windows
// If "No", then we continue with the current known environment
}
// Fix the output paths
Env.FixOutputPaths();
try
{
// Validate that the user explicitly wants an inactive drive to be considered for dumping