diff --git a/MPF.Check/Program.cs b/MPF.Check/Program.cs
index 7362db44..e6106f01 100644
--- a/MPF.Check/Program.cs
+++ b/MPF.Check/Program.cs
@@ -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();
diff --git a/MPF.Library/Aaru/Parameters.cs b/MPF.Library/Aaru/Parameters.cs
index 32490742..d94c4128 100644
--- a/MPF.Library/Aaru/Parameters.cs
+++ b/MPF.Library/Aaru/Parameters.cs
@@ -19,11 +19,35 @@ namespace MPF.Aaru
///
public class Parameters : BaseParameters
{
+ #region Generic Dumping Information
+
+ ///
+ public override string InputPath => InputValue;
+
+ ///
+ public override string OutputPath => OutputValue;
+
+ ///
+ public override int? Speed
+ {
+ get { return SpeedValue; }
+ set { SpeedValue = (sbyte?)value; }
+ }
+
+ #endregion
+
+ #region Metadata
+
///
/// Base command to run
///
public Command BaseCommand { get; set; }
+ ///
+ public override InternalProgram InternalProgram => InternalProgram.Aaru;
+
+ #endregion
+
///
/// Set of flags to pass to the executable
///
@@ -125,134 +149,235 @@ namespace MPF.Aaru
#endregion
///
- public Parameters(string parameters)
- : base(parameters)
- {
- this.InternalProgram = InternalProgram.Aaru;
- }
+ public Parameters(string parameters) : base(parameters) { }
///
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;
}
- ///
- protected override void ResetValues()
- {
- BaseCommand = Command.NONE;
-
- _flags = new Dictionary();
-
- 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
///
- protected override void SetDefaultParameters(char driveLetter, string filename, int? driveSpeed, Options options)
+ public override (bool, List) 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 missingFiles = new List();
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);
+ }
+
+ ///
+ 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"));
}
///
@@ -903,16 +1028,7 @@ namespace MPF.Aaru
}
///
- public override string InputPath() => InputValue;
-
- ///
- public override string OutputPath() => OutputValue;
-
- ///
- public override int? GetSpeed() => SpeedValue;
-
- ///
- public override void SetSpeed(int? speed) => SpeedValue = (sbyte?)speed;
+ public override string GetDefaultExtension(MediaType? mediaType) => Converters.Extension(mediaType);
///
public override bool IsDumpingCommand()
@@ -927,6 +1043,123 @@ namespace MPF.Aaru
}
}
+ ///
+ protected override void ResetValues()
+ {
+ BaseCommand = Command.NONE;
+
+ _flags = new Dictionary();
+
+ 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;
+ }
+
+ ///
+ 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;
+ }
+ }
+
///
protected override bool ValidateAndSetParameters(string parameters)
{
@@ -1410,226 +1643,9 @@ namespace MPF.Aaru
return true;
}
- ///
- public override (bool, List) CheckAllOutputFilesExist(string basePath)
- {
- List missingFiles = new List();
- 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);
- }
-
- ///
- 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
///
/// Get the list of commands that use a given flag
@@ -1907,6 +1923,8 @@ namespace MPF.Aaru
return commands;
}
+ #endregion
+
#region Process Parameter Helpers
///
diff --git a/MPF.Library/CleanRIp/Parameters.cs b/MPF.Library/CleanRIp/Parameters.cs
index 7b484693..3a57a5f5 100644
--- a/MPF.Library/CleanRIp/Parameters.cs
+++ b/MPF.Library/CleanRIp/Parameters.cs
@@ -12,20 +12,24 @@ namespace MPF.CleanRip
///
public class Parameters : BaseParameters
{
+ #region Metadata
+
///
- public Parameters(string parameters)
- : base(parameters)
- {
- this.InternalProgram = InternalProgram.CleanRip;
- }
+ public override InternalProgram InternalProgram => InternalProgram.CleanRip;
+
+ #endregion
+
+ ///
+ public Parameters(string parameters) : base(parameters) { }
///
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
+
///
public override (bool, List) CheckAllOutputFilesExist(string basePath)
{
@@ -92,6 +96,8 @@ namespace MPF.CleanRip
info.Artifacts["dumpinfo"] = GetBase64(GetFullFile(basePath + "-dumpinfo.txt"));
}
+ #endregion
+
#region Information Extraction Methods
///
diff --git a/MPF.Library/DD/Parameters.cs b/MPF.Library/DD/Parameters.cs
index de5a1ce8..5eff05b0 100644
--- a/MPF.Library/DD/Parameters.cs
+++ b/MPF.Library/DD/Parameters.cs
@@ -13,11 +13,36 @@ namespace MPF.DD
///
public class Parameters : BaseParameters
{
+ #region Generic Dumping Information
+
+ ///
+ public override string InputPath => InputFileValue;
+
+ ///
+ public override string OutputPath => OutputFileValue;
+
+ ///
+ ///
+ public override int? Speed
+ {
+ get { return 1; }
+ set { }
+ }
+
+ #endregion
+
+ #region Metadata
+
///
/// Base command to run
///
public Command BaseCommand { get; set; }
+ ///
+ public override InternalProgram InternalProgram => InternalProgram.DD;
+
+ #endregion
+
///
/// Set of flags to pass to the executable
///
@@ -58,17 +83,77 @@ namespace MPF.DD
#endregion
///
- public Parameters(string parameters)
- : base(parameters)
- {
- this.InternalProgram = InternalProgram.DD;
- }
+ public Parameters(string parameters) : base(parameters) { }
///
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
+
+ ///
+ public override (bool, List) CheckAllOutputFilesExist(string basePath)
+ {
+ // TODO: Figure out what sort of output files are expected... just `.bin`?
+ return (true, new List());
+ }
+
+ ///
+ 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;
+ }
}
///
@@ -162,13 +247,7 @@ namespace MPF.DD
}
///
- public override string InputPath() => InputFileValue;
-
- ///
- public override string OutputPath() => OutputFileValue;
-
- ///
- public override int? GetSpeed() => 1;
+ public override string GetDefaultExtension(MediaType? mediaType) => Converters.Extension(mediaType);
///
public override bool IsDumpingCommand()
@@ -326,68 +405,9 @@ namespace MPF.DD
return true;
}
- ///
- public override (bool, List) CheckAllOutputFilesExist(string basePath)
- {
- // TODO: Figure out what sort of output files are expected... just `.bin`?
- return (true, new List());
- }
+ #endregion
- ///
- 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
///
/// Get the list of commands that use a given flag
@@ -449,6 +469,10 @@ namespace MPF.DD
return commands;
}
+ #endregion
+
+ #region Process Parameter Helpers
+
///
/// Process a boolean parameter
///
@@ -587,5 +611,7 @@ namespace MPF.DD
return string.Empty;
}
+
+ #endregion
}
}
diff --git a/MPF.Library/Data/BaseParameters.cs b/MPF.Library/Data/BaseParameters.cs
index 581be892..7c5e6096 100644
--- a/MPF.Library/Data/BaseParameters.cs
+++ b/MPF.Library/Data/BaseParameters.cs
@@ -32,11 +32,43 @@ namespace MPF.Data
#endregion
+ #region Generic Dumping Information
+
+ ///
+ /// Input path for operations
+ ///
+ public virtual string InputPath => null;
+
+ ///
+ /// Output path for operations
+ ///
+ /// String representing the path, null on error
+ public virtual string OutputPath => null;
+
+ ///
+ /// Get the processing speed from the implementation
+ ///
+ public virtual int? Speed { get; set; } = null;
+
+ ///
+ /// Process to track external program
+ ///
+ private Process process;
+
+ #endregion
+
+ #region Metadata
+
///
/// Path to the executable
///
public string ExecutablePath { get; set; }
+ ///
+ /// Program that this set of parameters represents
+ ///
+ public virtual InternalProgram InternalProgram { get; }
+
///
/// Currently represented system
///
@@ -47,15 +79,7 @@ namespace MPF.Data
///
public MediaType? Type { get; set; }
- ///
- /// Program that this set of parameters represents
- ///
- public InternalProgram InternalProgram { get; set; }
-
- ///
- /// Process to track external program
- ///
- private Process process;
+ #endregion
///
/// Populate a Parameters object from a param string
@@ -84,35 +108,39 @@ namespace MPF.Data
SetDefaultParameters(driveLetter, filename, driveSpeed, options);
}
+ #region Abstract Methods
+
+ ///
+ /// Validate if all required output files exist
+ ///
+ /// Base filename and path to use for checking
+ /// Tuple of true if all required files exist, false otherwise and a list representing missing files
+ public abstract (bool, List) CheckAllOutputFilesExist(string basePath);
+
+ ///
+ /// Generate a SubmissionInfo for the output files
+ ///
+ /// Base submission info to fill in specifics for
+ /// Base filename and path to use for checking
+ /// Drive representing the disc to get information from
+ public abstract void GenerateSubmissionInfo(SubmissionInfo submissionInfo, string basePath, Drive drive);
+
+ #endregion
+
+ #region Virtual Methods
+
///
/// Blindly generate a parameter string based on the inputs
///
- /// Correctly formatted parameter string, null on error
+ /// Parameter string for invocation, null on error
public virtual string GenerateParameters() => null;
///
- /// Get the input path from the implementation
+ /// Get the default extension for a given media type
///
- /// String representing the path, null on error
- public virtual string InputPath() => null;
-
- ///
- /// Get the output path from the implementation
- ///
- /// String representing the path, null on error
- public virtual string OutputPath() => null;
-
- ///
- /// Get the processing speed from the implementation
- ///
- /// int? representing the speed, null on error
- public virtual int? GetSpeed() => null;
-
- ///
- /// Set the processing speed int the implementation
- ///
- /// int? representing the speed
- public virtual void SetSpeed(int? speed) { }
+ /// MediaType value to check
+ /// String representing the media type, null on error
+ public virtual string GetDefaultExtension(MediaType? mediaType) => null;
///
/// Get the MediaType from the current set of parameters
@@ -153,20 +181,9 @@ namespace MPF.Data
/// True if the parameters were set correctly, false otherwise
protected virtual bool ValidateAndSetParameters(string parameters) => true;
- ///
- /// Validate if all required output files exist
- ///
- /// Base filename and path to use for checking
- /// Tuple of true if all required files exist, false otherwise and a list representing missing files
- public abstract (bool, List) CheckAllOutputFilesExist(string basePath);
+ #endregion
- ///
- /// Generate a SubmissionInfo for the output files
- ///
- /// Base submission info to fill in specifics for
- /// Base filename and path to use for checking
- /// Drive representing the disc to get information from
- public abstract void GenerateSubmissionInfo(SubmissionInfo submissionInfo, string basePath, Drive drive);
+ #region Execution
///
/// Run internal program
@@ -209,43 +226,6 @@ namespace MPF.Data
process.Close();
}
- ///
- /// Run internal program async with an input set of parameters
- ///
- ///
- /// Standard output from commandline window
- public async Task ExecuteInternalProgram(BaseParameters parameters)
- {
- Process childProcess;
- string output = await Task.Run(() =>
- {
- childProcess = new Process()
- {
- StartInfo = new ProcessStartInfo()
- {
- FileName = parameters.ExecutablePath,
- Arguments = parameters.GenerateParameters(),
- CreateNoWindow = true,
- UseShellExecute = false,
- RedirectStandardInput = true,
- RedirectStandardOutput = true,
- },
- };
- childProcess.Start();
- childProcess.WaitForExit(1000);
-
- // Just in case, we want to push a button 5 times to clear any errors
- for (int i = 0; i < 5; i++)
- childProcess.StandardInput.WriteLine("Y");
-
- string stdout = childProcess.StandardOutput.ReadToEnd();
- childProcess.Dispose();
- return stdout;
- });
-
- return output;
- }
-
///
/// Cancel an in-progress dumping process
///
@@ -262,6 +242,8 @@ namespace MPF.Data
{ }
}
+ #endregion
+
#region Parameter Parsing
///
diff --git a/MPF.Library/DiscImageCreator/Parameters.cs b/MPF.Library/DiscImageCreator/Parameters.cs
index 034f9204..ffdd3ccd 100644
--- a/MPF.Library/DiscImageCreator/Parameters.cs
+++ b/MPF.Library/DiscImageCreator/Parameters.cs
@@ -15,11 +15,36 @@ namespace MPF.DiscImageCreator
///
public class Parameters : BaseParameters
{
+ #region Generic Dumping Information
+
+ ///
+ public override string InputPath => DriveLetter;
+
+ ///
+ public override string OutputPath => Filename;
+
+ ///
+ ///
+ public override int? Speed
+ {
+ get { return DriveSpeed; }
+ set { DriveSpeed = (sbyte?)value; }
+ }
+
+ #endregion
+
+ #region Metadata
+
///
/// Base command to run
///
public Command BaseCommand { get; set; }
+ ///
+ public override InternalProgram InternalProgram => InternalProgram.DiscImageCreator;
+
+ #endregion
+
///
/// Set of flags to pass to the executable
///
@@ -151,19 +176,585 @@ namespace MPF.DiscImageCreator
#endregion
///
- public Parameters(string parameters)
- : base(parameters)
- {
- this.InternalProgram = InternalProgram.DiscImageCreator;
- }
+ public Parameters(string parameters) : base(parameters) { }
///
public Parameters(KnownSystem? system, MediaType? type, char driveLetter, string filename, int? driveSpeed, Options options)
: base(system, type, driveLetter, filename, driveSpeed, options)
{
- this.InternalProgram = InternalProgram.DiscImageCreator;
- if (options.DICQuietMode)
- this[Flag.DisableBeep] = true;
+ }
+
+ #region BaseParameters Implementations
+
+ ///
+ public override (bool, List) CheckAllOutputFilesExist(string basePath)
+ {
+ /*
+ If there are no external programs, such as error checking, etc., DIC outputs
+ a slightly different set of files. This reduced set needs to be documented in
+ order for special use cases, such as self-built versions of DIC or removed
+ helper programs, can be detected to the best of our ability. Below is the list
+ of files that are generated in that case:
+
+ .bin
+ .c2
+ .ccd
+ .cue
+ .img/.imgtmp
+ .scm/.scmtmp
+ .sub/.subtmp
+ _cmd.txt (formerly)
+ _img.cue
+
+ This list needs to be translated into the minimum viable set of information
+ such that things like error checking can be passed back as a flag, or some
+ similar method.
+
+ Here are some notes about the various output files and what they represent:
+ - bin - Final split output disc image (CD/GD only)
+ - c2 - Represents each byte per sector as one bit; 0 means no error, 1 means error
+ - c2Error - Human-readable version of `c2`; only errors are printed
+ - ccd - CloneCD control file referencing the `img` file
+ - cmd - Represents the commandline that was run
+ - cue - CDRWIN cuesheet referencing the `bin` file(s)
+ - dat - Logiqx datfile referencing the `bin` file(s)
+ - disc - Disc metadata and information
+ - drive - Drive metadata and information
+ - img - CloneCD output disc image (CD/GD only)
+ - img.cue - CDRWIN cuesheet referencing the `img` file
+ - img_EdcEcc - ECC check output as run on the `img` file
+ - iso - Final output disc image (DVD/BD only)
+ - mainError - Read, drive, or system errors
+ - mainInfo - ISOBuster-formatted sector information
+ - scm - Scrambled disc image
+ - sub - Binary subchannel data as read from the disc
+ - subError - Subchannel read errors
+ - subInfo - Subchannel informational messages
+ - subIntention - Subchannel intentional error information
+ - subReadable - Human-readable version of `sub`
+ - volDesc - Volume descriptor information
+ */
+
+ List missingFiles = new List();
+ switch (this.Type)
+ {
+ case MediaType.CDROM:
+ case MediaType.GDROM: // TODO: Verify GD-ROM outputs this
+ if (!File.Exists($"{basePath}.ccd"))
+ missingFiles.Add($"{basePath}.ccd");
+ if (!File.Exists($"{basePath}.cue"))
+ missingFiles.Add($"{basePath}.cue");
+ if (!File.Exists($"{basePath}.dat"))
+ missingFiles.Add($"{basePath}.dat");
+ if (!File.Exists($"{basePath}.img") && !File.Exists($"{basePath}.imgtmp"))
+ missingFiles.Add($"{basePath}.img");
+ if (!File.Exists($"{basePath}.sub") && !File.Exists($"{basePath}.subtmp"))
+ missingFiles.Add($"{basePath}.sub");
+ if (!File.Exists($"{basePath}_disc.txt"))
+ missingFiles.Add($"{basePath}_disc.txt");
+ if (!File.Exists($"{basePath}_drive.txt"))
+ missingFiles.Add($"{basePath}_drive.txt");
+ if (!File.Exists($"{basePath}_img.cue"))
+ missingFiles.Add($"{basePath}_img.cue");
+ if (!File.Exists($"{basePath}_mainError.txt"))
+ missingFiles.Add($"{basePath}_mainError.txt");
+ if (!File.Exists($"{basePath}_mainInfo.txt"))
+ missingFiles.Add($"{basePath}_mainInfo.txt");
+ if (!File.Exists($"{basePath}_subError.txt"))
+ missingFiles.Add($"{basePath}_subError.txt");
+ if (!File.Exists($"{basePath}_subInfo.txt"))
+ missingFiles.Add($"{basePath}_subInfo.txt");
+ if (!File.Exists($"{basePath}_subReadable.txt") && !File.Exists($"{basePath}_sub.txt"))
+ missingFiles.Add($"{basePath}_subReadable.txt");
+ if (!File.Exists($"{basePath}_volDesc.txt"))
+ missingFiles.Add($"{basePath}_volDesc.txt");
+
+ // Audio-only discs don't output these files
+ if (!this.System.IsAudio())
+ {
+ if (!File.Exists($"{basePath}.img_EdcEcc.txt") && !File.Exists($"{basePath}.img_EccEdc.txt"))
+ missingFiles.Add($"{basePath}.img_EdcEcc.txt");
+ if (!File.Exists($"{basePath}.scm") && !File.Exists($"{basePath}.scmtmp"))
+ missingFiles.Add($"{basePath}.scm");
+ }
+
+ // Removed or inconsistent files
+ if (false)
+ {
+ // Doesn't output on Linux
+ if (!File.Exists($"{basePath}.c2"))
+ missingFiles.Add($"{basePath}.c2");
+
+ // Doesn't output on Linux
+ if (!File.Exists($"{basePath}_c2Error.txt"))
+ missingFiles.Add($"{basePath}_c2Error.txt");
+
+ // Replaced by timestamp-named file
+ if (!File.Exists($"{basePath}_cmd.txt"))
+ missingFiles.Add($"{basePath}_cmd.txt");
+
+ // Not guaranteed output
+ if (!File.Exists($"{basePath}_subIntention.txt"))
+ missingFiles.Add($"{basePath}_subIntention.txt");
+ }
+
+ break;
+
+ case MediaType.DVD:
+ case MediaType.HDDVD:
+ case MediaType.BluRay:
+ case MediaType.NintendoGameCubeGameDisc:
+ case MediaType.NintendoWiiOpticalDisc:
+ if (!File.Exists($"{basePath}.dat"))
+ missingFiles.Add($"{basePath}.dat");
+ if (!File.Exists($"{basePath}_disc.txt"))
+ missingFiles.Add($"{basePath}_disc.txt");
+ if (!File.Exists($"{basePath}_drive.txt"))
+ missingFiles.Add($"{basePath}_drive.txt");
+ if (!File.Exists($"{basePath}_mainError.txt"))
+ missingFiles.Add($"{basePath}_mainError.txt");
+ if (!File.Exists($"{basePath}_mainInfo.txt"))
+ missingFiles.Add($"{basePath}_mainInfo.txt");
+ if (!File.Exists($"{basePath}_volDesc.txt"))
+ missingFiles.Add($"{basePath}_volDesc.txt");
+
+ // Removed or inconsistent files
+ if (false)
+ {
+ // Replaced by timestamp-named file
+ if (!File.Exists($"{basePath}_cmd.txt"))
+ missingFiles.Add($"{basePath}_cmd.txt");
+ }
+
+ break;
+
+ case MediaType.FloppyDisk:
+ case MediaType.HardDisk:
+ // TODO: Determine what outputs come out from a HDD, SD, etc.
+ if (!File.Exists($"{basePath}.dat"))
+ missingFiles.Add($"{basePath}.dat");
+ if (!File.Exists($"{basePath}_disc.txt"))
+ missingFiles.Add($"{basePath}_disc.txt");
+
+ // Removed or inconsistent files
+ if (false)
+ {
+ // Replaced by timestamp-named file
+ if (!File.Exists($"{basePath}_cmd.txt"))
+ missingFiles.Add($"{basePath}_cmd.txt");
+ }
+
+ break;
+
+ default:
+ return (false, missingFiles);
+ }
+
+ return (!missingFiles.Any(), missingFiles);
+ }
+
+ ///
+ public override void GenerateSubmissionInfo(SubmissionInfo info, string basePath, Drive drive)
+ {
+ string outputDirectory = Path.GetDirectoryName(basePath);
+
+ // Fill in the hash data
+ info.TracksAndWriteOffsets.ClrMameProData = GetDatfile(basePath + ".dat");
+
+ // Extract info based generically on MediaType
+ switch (this.Type)
+ {
+ case MediaType.CDROM:
+ case MediaType.GDROM: // TODO: Verify GD-ROM outputs this
+ info.Extras.PVD = GetPVD(basePath + "_mainInfo.txt") ?? "Disc has no PVD"; ;
+
+ // Audio-only discs will fail if there are any C2 errors, so they would never get here
+ if (this.System.IsAudio())
+ {
+ info.CommonDiscInfo.ErrorsCount = "0";
+ }
+ else
+ {
+ long errorCount = -1;
+ if (File.Exists(basePath + ".img_EdcEcc.txt"))
+ errorCount = GetErrorCount(basePath + ".img_EdcEcc.txt");
+ else if (File.Exists(basePath + ".img_EccEdc.txt"))
+ errorCount = GetErrorCount(basePath + ".img_EccEdc.txt");
+
+ info.CommonDiscInfo.ErrorsCount = (errorCount == -1 ? "Error retrieving error count" : errorCount.ToString());
+ }
+
+ info.TracksAndWriteOffsets.Cuesheet = GetFullFile(basePath + ".cue") ?? "";
+ var cueSheet = new CueSheet(basePath + ".cue"); // TODO: Do something with this
+
+ string cdWriteOffset = GetWriteOffset(basePath + "_disc.txt") ?? "";
+ 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 layerbreaks
+ if (this.Type == MediaType.DVD)
+ {
+ string layerbreak = GetLayerbreak(basePath + "_disc.txt", System.IsXGD()) ?? "";
+ info.SizeAndChecksums.Layerbreak = !string.IsNullOrEmpty(layerbreak) ? Int64.Parse(layerbreak) : default;
+ }
+ else if (this.Type == MediaType.BluRay)
+ {
+ if (GetLayerbreak(Path.Combine(outputDirectory, "PIC.bin"), out long? layerbreak1, out long? layerbreak2, out long? layerbreak3))
+ {
+ if (layerbreak1 != null && layerbreak1 * 2048 < info.SizeAndChecksums.Size)
+ info.SizeAndChecksums.Layerbreak = layerbreak1.Value;
+
+ if (layerbreak2 != null && layerbreak2 * 2048 < info.SizeAndChecksums.Size)
+ info.SizeAndChecksums.Layerbreak2 = layerbreak2.Value;
+
+ if (layerbreak3 != null && layerbreak3 * 2048 < info.SizeAndChecksums.Size)
+ info.SizeAndChecksums.Layerbreak3 = layerbreak3.Value;
+ }
+ }
+
+ // Read the PVD
+ info.Extras.PVD = GetPVD(basePath + "_mainInfo.txt") ?? "";
+
+ // Bluray-specific options
+ if (this.Type == MediaType.BluRay)
+ info.Extras.PIC = GetPIC(Path.Combine(outputDirectory, "PIC.bin")) ?? "";
+
+ break;
+ }
+
+ // Extract info based specifically on KnownSystem
+ switch (this.System)
+ {
+ case KnownSystem.AppleMacintosh:
+ case KnownSystem.EnhancedCD:
+ case KnownSystem.IBMPCCompatible:
+ case KnownSystem.RainbowDisc:
+ if (File.Exists(basePath + "_subIntention.txt"))
+ {
+ FileInfo fi = new FileInfo(basePath + "_subIntention.txt");
+ if (fi.Length > 0)
+ info.CopyProtection.SecuROMData = GetFullFile(basePath + "_subIntention.txt") ?? "";
+ }
+
+ break;
+
+ case KnownSystem.DVDAudio:
+ case KnownSystem.DVDVideo:
+ info.CopyProtection.Protection = GetDVDProtection(basePath + "_CSSKey.txt", basePath + "_disc.txt") ?? "";
+ 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(basePath + "_disc.txt", 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(Path.Combine(outputDirectory, "DMI.bin"), 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(basePath + "_disc.txt", 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(Path.Combine(outputDirectory, "DMI.bin"), out string serial360, out string version360, out RedumpRegion? region360))
+ {
+ info.CommonDiscInfo.Serial = serial360 ?? "";
+ info.VersionAndEditions.Version = version360 ?? "";
+ info.CommonDiscInfo.Region = region360;
+ }
+ break;
+
+ case KnownSystem.NamcoSegaNintendoTriforce:
+ if (this.Type == MediaType.CDROM)
+ {
+ info.Extras.Header = GetSegaHeader(basePath + "_mainInfo.txt") ?? "";
+
+ // Take only the first 16 lines for GD-ROM
+ if (!string.IsNullOrEmpty(info.Extras.Header))
+ info.Extras.Header = string.Join("\n", info.Extras.Header.Split('\n').Take(16));
+
+ if (GetGDROMBuildInfo(info.Extras.Header, out string gdSerial, out string gdVersion, out string gdDate))
+ {
+ info.CommonDiscInfo.Comments += $"Internal Serial: {gdSerial ?? ""}";
+ info.VersionAndEditions.Version = gdVersion ?? "";
+ info.CommonDiscInfo.EXEDateBuildDate = gdDate ?? "";
+ }
+ }
+
+ break;
+
+ case KnownSystem.SegaCDMegaCD:
+ info.Extras.Header = GetSegaHeader(basePath + "_mainInfo.txt") ?? "";
+
+ // Take only the last 16 lines for Sega CD
+ if (!string.IsNullOrEmpty(info.Extras.Header))
+ info.Extras.Header = string.Join("\n", info.Extras.Header.Split('\n').Skip(16));
+
+ if (GetSegaCDBuildInfo(info.Extras.Header, out string scdSerial, out string fixedDate))
+ {
+ info.CommonDiscInfo.Comments += $"Internal Serial: {scdSerial ?? ""}";
+ info.CommonDiscInfo.EXEDateBuildDate = fixedDate ?? "";
+ }
+
+ break;
+
+ case KnownSystem.SegaChihiro:
+ if (this.Type == MediaType.CDROM)
+ {
+ info.Extras.Header = GetSegaHeader(basePath + "_mainInfo.txt") ?? "";
+
+ // Take only the first 16 lines for GD-ROM
+ if (!string.IsNullOrEmpty(info.Extras.Header))
+ info.Extras.Header = string.Join("\n", info.Extras.Header.Split('\n').Take(16));
+
+ if (GetGDROMBuildInfo(info.Extras.Header, out string gdSerial, out string gdVersion, out string gdDate))
+ {
+ info.CommonDiscInfo.Comments += $"Internal Serial: {gdSerial ?? ""}";
+ info.VersionAndEditions.Version = gdVersion ?? "";
+ info.CommonDiscInfo.EXEDateBuildDate = gdDate ?? "";
+ }
+ }
+
+ break;
+
+ case KnownSystem.SegaDreamcast:
+ if (this.Type == MediaType.CDROM)
+ {
+ info.Extras.Header = GetSegaHeader(basePath + "_mainInfo.txt") ?? "";
+
+ // Take only the first 16 lines for GD-ROM
+ if (!string.IsNullOrEmpty(info.Extras.Header))
+ info.Extras.Header = string.Join("\n", info.Extras.Header.Split('\n').Take(16));
+
+ if (GetGDROMBuildInfo(info.Extras.Header, out string gdSerial, out string gdVersion, out string gdDate))
+ {
+ info.CommonDiscInfo.Comments += $"Internal Serial: {gdSerial ?? ""}";
+ info.VersionAndEditions.Version = gdVersion ?? "";
+ info.CommonDiscInfo.EXEDateBuildDate = gdDate ?? "";
+ }
+ }
+
+ break;
+
+ case KnownSystem.SegaNaomi:
+ if (this.Type == MediaType.CDROM)
+ {
+ info.Extras.Header = GetSegaHeader(basePath + "_mainInfo.txt") ?? "";
+
+ // Take only the first 16 lines for GD-ROM
+ if (!string.IsNullOrEmpty(info.Extras.Header))
+ info.Extras.Header = string.Join("\n", info.Extras.Header.Split('\n').Take(16));
+
+ if (GetGDROMBuildInfo(info.Extras.Header, out string gdSerial, out string gdVersion, out string gdDate))
+ {
+ info.CommonDiscInfo.Comments += $"Internal Serial: {gdSerial ?? ""}";
+ info.VersionAndEditions.Version = gdVersion ?? "";
+ info.CommonDiscInfo.EXEDateBuildDate = gdDate ?? "";
+ }
+ }
+
+ break;
+
+ case KnownSystem.SegaNaomi2:
+ if (this.Type == MediaType.CDROM)
+ {
+ info.Extras.Header = GetSegaHeader(basePath + "_mainInfo.txt") ?? "";
+
+ // Take only the first 16 lines for GD-ROM
+ if (!string.IsNullOrEmpty(info.Extras.Header))
+ info.Extras.Header = string.Join("\n", info.Extras.Header.Split('\n').Take(16));
+
+ if (GetGDROMBuildInfo(info.Extras.Header, out string gdSerial, out string gdVersion, out string gdDate))
+ {
+ info.CommonDiscInfo.Comments += $"Internal Serial: {gdSerial ?? ""}";
+ info.VersionAndEditions.Version = gdVersion ?? "";
+ info.CommonDiscInfo.EXEDateBuildDate = gdDate ?? "";
+ }
+ }
+
+ break;
+
+ case KnownSystem.SegaSaturn:
+ info.Extras.Header = GetSegaHeader(basePath + "_mainInfo.txt") ?? "";
+
+ // Take only the first 16 lines for Saturn
+ if (!string.IsNullOrEmpty(info.Extras.Header))
+ info.Extras.Header = string.Join("\n", info.Extras.Header.Split('\n').Take(16));
+
+ if (GetSaturnBuildInfo(info.Extras.Header, out string saturnSerial, out string saturnVersion, out string buildDate))
+ {
+ info.CommonDiscInfo.Comments += $"Internal Serial: {saturnSerial ?? ""}";
+ info.VersionAndEditions.Version = saturnVersion ?? "";
+ info.CommonDiscInfo.EXEDateBuildDate = buildDate ?? "";
+ }
+
+ break;
+
+ case KnownSystem.SonyPlayStation:
+ if (GetPlayStationExecutableInfo(drive?.Letter, out string playstationSerial, out RedumpRegion? playstationRegion, out string playstationDate))
+ {
+ info.CommonDiscInfo.Comments += $"Internal Serial: {playstationSerial ?? ""}\n";
+ info.CommonDiscInfo.Region = info.CommonDiscInfo.Region ?? playstationRegion;
+ info.CommonDiscInfo.EXEDateBuildDate = playstationDate;
+ }
+
+ bool? psEdcStatus = null;
+ if (File.Exists(basePath + ".img_EdcEcc.txt"))
+ psEdcStatus = GetPlayStationEDCStatus(basePath + ".img_EdcEcc.txt");
+ else if (File.Exists(basePath + ".img_EccEdc.txt"))
+ psEdcStatus = GetPlayStationEDCStatus(basePath + ".img_EccEdc.txt");
+
+ if (psEdcStatus == true)
+ info.EDC.EDC = YesNo.Yes;
+ else if (psEdcStatus == false)
+ info.EDC.EDC = YesNo.No;
+ else
+ info.EDC.EDC = YesNo.NULL;
+
+ info.CopyProtection.AntiModchip = GetPlayStationAntiModchipDetected(basePath + "_disc.txt") ? YesNo.Yes : YesNo.No;
+
+ bool? psLibCryptStatus = GetLibCryptDetected(basePath + ".sub");
+ if (psLibCryptStatus == true)
+ {
+ // Guard against false positives
+ if (File.Exists(basePath + "_subIntention.txt"))
+ {
+ string libCryptData = GetFullFile(basePath + "_subIntention.txt") ?? "";
+ if (string.IsNullOrEmpty(libCryptData))
+ {
+ info.CopyProtection.LibCrypt = YesNo.No;
+ }
+ else
+ {
+ info.CopyProtection.LibCrypt = YesNo.Yes;
+ info.CopyProtection.LibCryptData = libCryptData;
+ }
+ }
+ else
+ {
+ info.CopyProtection.LibCrypt = YesNo.No;
+ }
+ }
+ else if (psLibCryptStatus == false)
+ {
+ info.CopyProtection.LibCrypt = YesNo.No;
+ }
+ else
+ {
+ info.CopyProtection.LibCrypt = YesNo.NULL;
+ info.CopyProtection.LibCryptData = "LibCrypt could not be detected because subchannel file is missing";
+ }
+
+ 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 + ".c2"))
+ // info.Artifacts["c2"] = Convert.ToBase64String(File.ReadAllBytes(basePath + ".c2"));
+ if (File.Exists(basePath + "_c2Error.txt"))
+ info.Artifacts["c2Error"] = GetBase64(GetFullFile(basePath + "_c2Error.txt"));
+ if (File.Exists(basePath + ".ccd"))
+ info.Artifacts["ccd"] = GetBase64(GetFullFile(basePath + ".ccd"));
+ if (File.Exists(basePath + "_cmd.txt")) // TODO: Figure out how to read in the timestamp-named file
+ info.Artifacts["cmd"] = GetBase64(GetFullFile(basePath + "_cmd.txt"));
+ if (File.Exists(basePath + ".cue"))
+ info.Artifacts["cue"] = GetBase64(GetFullFile(basePath + ".cue"));
+ if (File.Exists(basePath + ".dat"))
+ info.Artifacts["dat"] = GetBase64(GetFullFile(basePath + ".dat"));
+ if (File.Exists(basePath + "_disc.txt"))
+ info.Artifacts["disc"] = GetBase64(GetFullFile(basePath + "_disc.txt"));
+ //if (File.Exists(Path.Combine(outputDirectory, "DMI.bin")))
+ // info.Artifacts["dmi"] = Convert.ToBase64String(File.ReadAllBytes(Path.Combine(outputDirectory, "DMI.bin")));
+ if (File.Exists(basePath + "_drive.txt"))
+ info.Artifacts["drive"] = GetBase64(GetFullFile(basePath + "_drive.txt"));
+ if (File.Exists(basePath + "_img.cue"))
+ info.Artifacts["img_cue"] = GetBase64(GetFullFile(basePath + "_img.cue"));
+ if (File.Exists(basePath + ".img_EdcEcc.txt"))
+ info.Artifacts["img_EdcEcc"] = GetBase64(GetFullFile(basePath + ".img_EdcEcc.txt"));
+ if (File.Exists(basePath + ".img_EccEdc.txt"))
+ info.Artifacts["img_EdcEcc"] = GetBase64(GetFullFile(basePath + ".img_EccEdc.txt"));
+ if (File.Exists(basePath + "_mainError.txt"))
+ info.Artifacts["mainError"] = GetBase64(GetFullFile(basePath + "_mainError.txt"));
+ if (File.Exists(basePath + "_mainInfo.txt"))
+ info.Artifacts["mainInfo"] = GetBase64(GetFullFile(basePath + "_mainInfo.txt"));
+ //if (File.Exists(Path.Combine(outputDirectory, "PFI.bin")))
+ // info.Artifacts["pfi"] = Convert.ToBase64String(File.ReadAllBytes(Path.Combine(outputDirectory, "PFI.bin")));
+ //if (File.Exists(Path.Combine(outputDirectory, "SS.bin")))
+ // info.Artifacts["ss"] = Convert.ToBase64String(File.ReadAllBytes(Path.Combine(outputDirectory, "SS.bin")));
+ if (File.Exists(basePath + ".sub"))
+ info.Artifacts["sub"] = Convert.ToBase64String(File.ReadAllBytes(basePath + ".sub"));
+ if (File.Exists(basePath + "_subError.txt"))
+ info.Artifacts["subError"] = GetBase64(GetFullFile(basePath + "_subError.txt"));
+ if (File.Exists(basePath + "_subInfo.txt"))
+ info.Artifacts["subInfo"] = GetBase64(GetFullFile(basePath + "_subInfo.txt"));
+ if (File.Exists(basePath + "_subIntention.txt"))
+ info.Artifacts["subIntention"] = GetBase64(GetFullFile(basePath + "_subIntention.txt"));
+ //if (File.Exists(basePath + "_sub.txt"))
+ // info.Artifacts["subReadable"] = GetBase64(GetFullFile(basePath + "_sub.txt"));
+ //if (File.Exists(basePath + "_subReadable.txt"))
+ // info.Artifacts["subReadable"] = GetBase64(GetFullFile(basePath + "_subReadable.txt"));
+ if (File.Exists(basePath + "_volDesc.txt"))
+ info.Artifacts["volDesc"] = GetBase64(GetFullFile(basePath + "_volDesc.txt"));
}
///
@@ -623,16 +1214,7 @@ namespace MPF.DiscImageCreator
}
///
- public override string InputPath() => DriveLetter;
-
- ///
- public override string OutputPath() => Filename;
-
- ///
- public override int? GetSpeed() => DriveSpeed;
-
- ///
- public override void SetSpeed(int? speed) => DriveSpeed = speed;
+ public override string GetDefaultExtension(MediaType? mediaType) => Converters.Extension(mediaType);
///
public override MediaType? GetMediaType() => Converters.ToMediaType(BaseCommand);
@@ -704,6 +1286,10 @@ namespace MPF.DiscImageCreator
if (!validTypes.Contains(this.Type))
return;
+ // Set disable beep flag, if needed
+ if (options.DICQuietMode)
+ this[Flag.DisableBeep] = true;
+
// Set the C2 reread count
switch (options.DICRereadCount)
{
@@ -1629,576 +2215,9 @@ namespace MPF.DiscImageCreator
return true;
}
- ///
- public override (bool, List) CheckAllOutputFilesExist(string basePath)
- {
- /*
- If there are no external programs, such as error checking, etc., DIC outputs
- a slightly different set of files. This reduced set needs to be documented in
- order for special use cases, such as self-built versions of DIC or removed
- helper programs, can be detected to the best of our ability. Below is the list
- of files that are generated in that case:
+ #endregion
- .bin
- .c2
- .ccd
- .cue
- .img/.imgtmp
- .scm/.scmtmp
- .sub/.subtmp
- _cmd.txt (formerly)
- _img.cue
-
- This list needs to be translated into the minimum viable set of information
- such that things like error checking can be passed back as a flag, or some
- similar method.
-
- Here are some notes about the various output files and what they represent:
- - bin - Final split output disc image (CD/GD only)
- - c2 - Represents each byte per sector as one bit; 0 means no error, 1 means error
- - c2Error - Human-readable version of `c2`; only errors are printed
- - ccd - CloneCD control file referencing the `img` file
- - cmd - Represents the commandline that was run
- - cue - CDRWIN cuesheet referencing the `bin` file(s)
- - dat - Logiqx datfile referencing the `bin` file(s)
- - disc - Disc metadata and information
- - drive - Drive metadata and information
- - img - CloneCD output disc image (CD/GD only)
- - img.cue - CDRWIN cuesheet referencing the `img` file
- - img_EdcEcc - ECC check output as run on the `img` file
- - iso - Final output disc image (DVD/BD only)
- - mainError - Read, drive, or system errors
- - mainInfo - ISOBuster-formatted sector information
- - scm - Scrambled disc image
- - sub - Binary subchannel data as read from the disc
- - subError - Subchannel read errors
- - subInfo - Subchannel informational messages
- - subIntention - Subchannel intentional error information
- - subReadable - Human-readable version of `sub`
- - volDesc - Volume descriptor information
- */
-
- List missingFiles = new List();
- switch (this.Type)
- {
- case MediaType.CDROM:
- case MediaType.GDROM: // TODO: Verify GD-ROM outputs this
- if (!File.Exists($"{basePath}.ccd"))
- missingFiles.Add($"{basePath}.ccd");
- if (!File.Exists($"{basePath}.cue"))
- missingFiles.Add($"{basePath}.cue");
- if (!File.Exists($"{basePath}.dat"))
- missingFiles.Add($"{basePath}.dat");
- if (!File.Exists($"{basePath}.img") && !File.Exists($"{basePath}.imgtmp"))
- missingFiles.Add($"{basePath}.img");
- if (!File.Exists($"{basePath}.sub") && !File.Exists($"{basePath}.subtmp"))
- missingFiles.Add($"{basePath}.sub");
- if (!File.Exists($"{basePath}_disc.txt"))
- missingFiles.Add($"{basePath}_disc.txt");
- if (!File.Exists($"{basePath}_drive.txt"))
- missingFiles.Add($"{basePath}_drive.txt");
- if (!File.Exists($"{basePath}_img.cue"))
- missingFiles.Add($"{basePath}_img.cue");
- if (!File.Exists($"{basePath}_mainError.txt"))
- missingFiles.Add($"{basePath}_mainError.txt");
- if (!File.Exists($"{basePath}_mainInfo.txt"))
- missingFiles.Add($"{basePath}_mainInfo.txt");
- if (!File.Exists($"{basePath}_subError.txt"))
- missingFiles.Add($"{basePath}_subError.txt");
- if (!File.Exists($"{basePath}_subInfo.txt"))
- missingFiles.Add($"{basePath}_subInfo.txt");
- if (!File.Exists($"{basePath}_subReadable.txt") && !File.Exists($"{basePath}_sub.txt"))
- missingFiles.Add($"{basePath}_subReadable.txt");
- if (!File.Exists($"{basePath}_volDesc.txt"))
- missingFiles.Add($"{basePath}_volDesc.txt");
-
- // Audio-only discs don't output these files
- if (!this.System.IsAudio())
- {
- if (!File.Exists($"{basePath}.img_EdcEcc.txt") && !File.Exists($"{basePath}.img_EccEdc.txt"))
- missingFiles.Add($"{basePath}.img_EdcEcc.txt");
- if (!File.Exists($"{basePath}.scm") && !File.Exists($"{basePath}.scmtmp"))
- missingFiles.Add($"{basePath}.scm");
- }
-
- // Removed or inconsistent files
- if (false)
- {
- // Doesn't output on Linux
- if (!File.Exists($"{basePath}.c2"))
- missingFiles.Add($"{basePath}.c2");
-
- // Doesn't output on Linux
- if (!File.Exists($"{basePath}_c2Error.txt"))
- missingFiles.Add($"{basePath}_c2Error.txt");
-
- // Replaced by timestamp-named file
- if (!File.Exists($"{basePath}_cmd.txt"))
- missingFiles.Add($"{basePath}_cmd.txt");
-
- // Not guaranteed output
- if (!File.Exists($"{basePath}_subIntention.txt"))
- missingFiles.Add($"{basePath}_subIntention.txt");
- }
-
- break;
-
- case MediaType.DVD:
- case MediaType.HDDVD:
- case MediaType.BluRay:
- case MediaType.NintendoGameCubeGameDisc:
- case MediaType.NintendoWiiOpticalDisc:
- if (!File.Exists($"{basePath}.dat"))
- missingFiles.Add($"{basePath}.dat");
- if (!File.Exists($"{basePath}_disc.txt"))
- missingFiles.Add($"{basePath}_disc.txt");
- if (!File.Exists($"{basePath}_drive.txt"))
- missingFiles.Add($"{basePath}_drive.txt");
- if (!File.Exists($"{basePath}_mainError.txt"))
- missingFiles.Add($"{basePath}_mainError.txt");
- if (!File.Exists($"{basePath}_mainInfo.txt"))
- missingFiles.Add($"{basePath}_mainInfo.txt");
- if (!File.Exists($"{basePath}_volDesc.txt"))
- missingFiles.Add($"{basePath}_volDesc.txt");
-
- // Removed or inconsistent files
- if (false)
- {
- // Replaced by timestamp-named file
- if (!File.Exists($"{basePath}_cmd.txt"))
- missingFiles.Add($"{basePath}_cmd.txt");
- }
-
- break;
-
- case MediaType.FloppyDisk:
- case MediaType.HardDisk:
- // TODO: Determine what outputs come out from a HDD, SD, etc.
- if (!File.Exists($"{basePath}.dat"))
- missingFiles.Add($"{basePath}.dat");
- if (!File.Exists($"{basePath}_disc.txt"))
- missingFiles.Add($"{basePath}_disc.txt");
-
- // Removed or inconsistent files
- if (false)
- {
- // Replaced by timestamp-named file
- if (!File.Exists($"{basePath}_cmd.txt"))
- missingFiles.Add($"{basePath}_cmd.txt");
- }
-
- break;
-
- default:
- return (false, missingFiles);
- }
-
- return (!missingFiles.Any(), missingFiles);
- }
-
- ///
- public override void GenerateSubmissionInfo(SubmissionInfo info, string basePath, Drive drive)
- {
- string outputDirectory = Path.GetDirectoryName(basePath);
-
- // Fill in the hash data
- info.TracksAndWriteOffsets.ClrMameProData = GetDatfile(basePath + ".dat");
-
- // Extract info based generically on MediaType
- switch (this.Type)
- {
- case MediaType.CDROM:
- case MediaType.GDROM: // TODO: Verify GD-ROM outputs this
- info.Extras.PVD = GetPVD(basePath + "_mainInfo.txt") ?? "Disc has no PVD"; ;
-
- // Audio-only discs will fail if there are any C2 errors, so they would never get here
- if (this.System.IsAudio())
- {
- info.CommonDiscInfo.ErrorsCount = "0";
- }
- else
- {
- long errorCount = -1;
- if (File.Exists(basePath + ".img_EdcEcc.txt"))
- errorCount = GetErrorCount(basePath + ".img_EdcEcc.txt");
- else if (File.Exists(basePath + ".img_EccEdc.txt"))
- errorCount = GetErrorCount(basePath + ".img_EccEdc.txt");
-
- info.CommonDiscInfo.ErrorsCount = (errorCount == -1 ? "Error retrieving error count" : errorCount.ToString());
- }
-
- info.TracksAndWriteOffsets.Cuesheet = GetFullFile(basePath + ".cue") ?? "";
- var cueSheet = new CueSheet(basePath + ".cue"); // TODO: Do something with this
-
- string cdWriteOffset = GetWriteOffset(basePath + "_disc.txt") ?? "";
- 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 layerbreaks
- if (this.Type == MediaType.DVD)
- {
- string layerbreak = GetLayerbreak(basePath + "_disc.txt", System.IsXGD()) ?? "";
- info.SizeAndChecksums.Layerbreak = !string.IsNullOrEmpty(layerbreak) ? Int64.Parse(layerbreak) : default;
- }
- else if (this.Type == MediaType.BluRay)
- {
- if (GetLayerbreak(Path.Combine(outputDirectory, "PIC.bin"), out long? layerbreak1, out long? layerbreak2, out long? layerbreak3))
- {
- if (layerbreak1 != null && layerbreak1 * 2048 < info.SizeAndChecksums.Size)
- info.SizeAndChecksums.Layerbreak = layerbreak1.Value;
-
- if (layerbreak2 != null && layerbreak2 * 2048 < info.SizeAndChecksums.Size)
- info.SizeAndChecksums.Layerbreak2 = layerbreak2.Value;
-
- if (layerbreak3 != null && layerbreak3 * 2048 < info.SizeAndChecksums.Size)
- info.SizeAndChecksums.Layerbreak3 = layerbreak3.Value;
- }
- }
-
- // Read the PVD
- info.Extras.PVD = GetPVD(basePath + "_mainInfo.txt") ?? "";
-
- // Bluray-specific options
- if (this.Type == MediaType.BluRay)
- info.Extras.PIC = GetPIC(Path.Combine(outputDirectory, "PIC.bin")) ?? "";
-
- break;
- }
-
- // Extract info based specifically on KnownSystem
- switch (this.System)
- {
- case KnownSystem.AppleMacintosh:
- case KnownSystem.EnhancedCD:
- case KnownSystem.IBMPCCompatible:
- case KnownSystem.RainbowDisc:
- if (File.Exists(basePath + "_subIntention.txt"))
- {
- FileInfo fi = new FileInfo(basePath + "_subIntention.txt");
- if (fi.Length > 0)
- info.CopyProtection.SecuROMData = GetFullFile(basePath + "_subIntention.txt") ?? "";
- }
-
- break;
-
- case KnownSystem.DVDAudio:
- case KnownSystem.DVDVideo:
- info.CopyProtection.Protection = GetDVDProtection(basePath + "_CSSKey.txt", basePath + "_disc.txt") ?? "";
- 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(basePath + "_disc.txt", 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(Path.Combine(outputDirectory, "DMI.bin"), 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(basePath + "_disc.txt", 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(Path.Combine(outputDirectory, "DMI.bin"), out string serial360, out string version360, out RedumpRegion? region360))
- {
- info.CommonDiscInfo.Serial = serial360 ?? "";
- info.VersionAndEditions.Version = version360 ?? "";
- info.CommonDiscInfo.Region = region360;
- }
- break;
-
- case KnownSystem.NamcoSegaNintendoTriforce:
- if (this.Type == MediaType.CDROM)
- {
- info.Extras.Header = GetSegaHeader(basePath + "_mainInfo.txt") ?? "";
-
- // Take only the first 16 lines for GD-ROM
- if (!string.IsNullOrEmpty(info.Extras.Header))
- info.Extras.Header = string.Join("\n", info.Extras.Header.Split('\n').Take(16));
-
- if (GetGDROMBuildInfo(info.Extras.Header, out string gdSerial, out string gdVersion, out string gdDate))
- {
- info.CommonDiscInfo.Comments += $"Internal Serial: {gdSerial ?? ""}";
- info.VersionAndEditions.Version = gdVersion ?? "";
- info.CommonDiscInfo.EXEDateBuildDate = gdDate ?? "";
- }
- }
-
- break;
-
- case KnownSystem.SegaCDMegaCD:
- info.Extras.Header = GetSegaHeader(basePath + "_mainInfo.txt") ?? "";
-
- // Take only the last 16 lines for Sega CD
- if (!string.IsNullOrEmpty(info.Extras.Header))
- info.Extras.Header = string.Join("\n", info.Extras.Header.Split('\n').Skip(16));
-
- if (GetSegaCDBuildInfo(info.Extras.Header, out string scdSerial, out string fixedDate))
- {
- info.CommonDiscInfo.Comments += $"Internal Serial: {scdSerial ?? ""}";
- info.CommonDiscInfo.EXEDateBuildDate = fixedDate ?? "";
- }
-
- break;
-
- case KnownSystem.SegaChihiro:
- if (this.Type == MediaType.CDROM)
- {
- info.Extras.Header = GetSegaHeader(basePath + "_mainInfo.txt") ?? "";
-
- // Take only the first 16 lines for GD-ROM
- if (!string.IsNullOrEmpty(info.Extras.Header))
- info.Extras.Header = string.Join("\n", info.Extras.Header.Split('\n').Take(16));
-
- if (GetGDROMBuildInfo(info.Extras.Header, out string gdSerial, out string gdVersion, out string gdDate))
- {
- info.CommonDiscInfo.Comments += $"Internal Serial: {gdSerial ?? ""}";
- info.VersionAndEditions.Version = gdVersion ?? "";
- info.CommonDiscInfo.EXEDateBuildDate = gdDate ?? "";
- }
- }
-
- break;
-
- case KnownSystem.SegaDreamcast:
- if (this.Type == MediaType.CDROM)
- {
- info.Extras.Header = GetSegaHeader(basePath + "_mainInfo.txt") ?? "";
-
- // Take only the first 16 lines for GD-ROM
- if (!string.IsNullOrEmpty(info.Extras.Header))
- info.Extras.Header = string.Join("\n", info.Extras.Header.Split('\n').Take(16));
-
- if (GetGDROMBuildInfo(info.Extras.Header, out string gdSerial, out string gdVersion, out string gdDate))
- {
- info.CommonDiscInfo.Comments += $"Internal Serial: {gdSerial ?? ""}";
- info.VersionAndEditions.Version = gdVersion ?? "";
- info.CommonDiscInfo.EXEDateBuildDate = gdDate ?? "";
- }
- }
-
- break;
-
- case KnownSystem.SegaNaomi:
- if (this.Type == MediaType.CDROM)
- {
- info.Extras.Header = GetSegaHeader(basePath + "_mainInfo.txt") ?? "";
-
- // Take only the first 16 lines for GD-ROM
- if (!string.IsNullOrEmpty(info.Extras.Header))
- info.Extras.Header = string.Join("\n", info.Extras.Header.Split('\n').Take(16));
-
- if (GetGDROMBuildInfo(info.Extras.Header, out string gdSerial, out string gdVersion, out string gdDate))
- {
- info.CommonDiscInfo.Comments += $"Internal Serial: {gdSerial ?? ""}";
- info.VersionAndEditions.Version = gdVersion ?? "";
- info.CommonDiscInfo.EXEDateBuildDate = gdDate ?? "";
- }
- }
-
- break;
-
- case KnownSystem.SegaNaomi2:
- if (this.Type == MediaType.CDROM)
- {
- info.Extras.Header = GetSegaHeader(basePath + "_mainInfo.txt") ?? "";
-
- // Take only the first 16 lines for GD-ROM
- if (!string.IsNullOrEmpty(info.Extras.Header))
- info.Extras.Header = string.Join("\n", info.Extras.Header.Split('\n').Take(16));
-
- if (GetGDROMBuildInfo(info.Extras.Header, out string gdSerial, out string gdVersion, out string gdDate))
- {
- info.CommonDiscInfo.Comments += $"Internal Serial: {gdSerial ?? ""}";
- info.VersionAndEditions.Version = gdVersion ?? "";
- info.CommonDiscInfo.EXEDateBuildDate = gdDate ?? "";
- }
- }
-
- break;
-
- case KnownSystem.SegaSaturn:
- info.Extras.Header = GetSegaHeader(basePath + "_mainInfo.txt") ?? "";
-
- // Take only the first 16 lines for Saturn
- if (!string.IsNullOrEmpty(info.Extras.Header))
- info.Extras.Header = string.Join("\n", info.Extras.Header.Split('\n').Take(16));
-
- if (GetSaturnBuildInfo(info.Extras.Header, out string saturnSerial, out string saturnVersion, out string buildDate))
- {
- info.CommonDiscInfo.Comments += $"Internal Serial: {saturnSerial ?? ""}";
- info.VersionAndEditions.Version = saturnVersion ?? "";
- info.CommonDiscInfo.EXEDateBuildDate = buildDate ?? "";
- }
-
- break;
-
- case KnownSystem.SonyPlayStation:
- if (GetPlayStationExecutableInfo(drive?.Letter, out string playstationSerial, out RedumpRegion? playstationRegion, out string playstationDate))
- {
- info.CommonDiscInfo.Comments += $"Internal Serial: {playstationSerial ?? ""}\n";
- info.CommonDiscInfo.Region = info.CommonDiscInfo.Region ?? playstationRegion;
- info.CommonDiscInfo.EXEDateBuildDate = playstationDate;
- }
-
- bool? psEdcStatus = null;
- if (File.Exists(basePath + ".img_EdcEcc.txt"))
- psEdcStatus = GetPlayStationEDCStatus(basePath + ".img_EdcEcc.txt");
- else if (File.Exists(basePath + ".img_EccEdc.txt"))
- psEdcStatus = GetPlayStationEDCStatus(basePath + ".img_EccEdc.txt");
-
- if (psEdcStatus == true)
- info.EDC.EDC = YesNo.Yes;
- else if (psEdcStatus == false)
- info.EDC.EDC = YesNo.No;
- else
- info.EDC.EDC = YesNo.NULL;
-
- info.CopyProtection.AntiModchip = GetPlayStationAntiModchipDetected(basePath + "_disc.txt") ? YesNo.Yes : YesNo.No;
-
- bool? psLibCryptStatus = GetLibCryptDetected(basePath + ".sub");
- if (psLibCryptStatus == true)
- {
- // Guard against false positives
- if (File.Exists(basePath + "_subIntention.txt"))
- {
- string libCryptData = GetFullFile(basePath + "_subIntention.txt") ?? "";
- if (string.IsNullOrEmpty(libCryptData))
- {
- info.CopyProtection.LibCrypt = YesNo.No;
- }
- else
- {
- info.CopyProtection.LibCrypt = YesNo.Yes;
- info.CopyProtection.LibCryptData = libCryptData;
- }
- }
- else
- {
- info.CopyProtection.LibCrypt = YesNo.No;
- }
- }
- else if (psLibCryptStatus == false)
- {
- info.CopyProtection.LibCrypt = YesNo.No;
- }
- else
- {
- info.CopyProtection.LibCrypt = YesNo.NULL;
- info.CopyProtection.LibCryptData = "LibCrypt could not be detected because subchannel file is missing";
- }
-
- 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 + ".c2"))
- // info.Artifacts["c2"] = Convert.ToBase64String(File.ReadAllBytes(basePath + ".c2"));
- if (File.Exists(basePath + "_c2Error.txt"))
- info.Artifacts["c2Error"] = GetBase64(GetFullFile(basePath + "_c2Error.txt"));
- if (File.Exists(basePath + ".ccd"))
- info.Artifacts["ccd"] = GetBase64(GetFullFile(basePath + ".ccd"));
- if (File.Exists(basePath + "_cmd.txt")) // TODO: Figure out how to read in the timestamp-named file
- info.Artifacts["cmd"] = GetBase64(GetFullFile(basePath + "_cmd.txt"));
- if (File.Exists(basePath + ".cue"))
- info.Artifacts["cue"] = GetBase64(GetFullFile(basePath + ".cue"));
- if (File.Exists(basePath + ".dat"))
- info.Artifacts["dat"] = GetBase64(GetFullFile(basePath + ".dat"));
- if (File.Exists(basePath + "_disc.txt"))
- info.Artifacts["disc"] = GetBase64(GetFullFile(basePath + "_disc.txt"));
- //if (File.Exists(Path.Combine(outputDirectory, "DMI.bin")))
- // info.Artifacts["dmi"] = Convert.ToBase64String(File.ReadAllBytes(Path.Combine(outputDirectory, "DMI.bin")));
- if (File.Exists(basePath + "_drive.txt"))
- info.Artifacts["drive"] = GetBase64(GetFullFile(basePath + "_drive.txt"));
- if (File.Exists(basePath + "_img.cue"))
- info.Artifacts["img_cue"] = GetBase64(GetFullFile(basePath + "_img.cue"));
- if (File.Exists(basePath + ".img_EdcEcc.txt"))
- info.Artifacts["img_EdcEcc"] = GetBase64(GetFullFile(basePath + ".img_EdcEcc.txt"));
- if (File.Exists(basePath + ".img_EccEdc.txt"))
- info.Artifacts["img_EdcEcc"] = GetBase64(GetFullFile(basePath + ".img_EccEdc.txt"));
- if (File.Exists(basePath + "_mainError.txt"))
- info.Artifacts["mainError"] = GetBase64(GetFullFile(basePath + "_mainError.txt"));
- if (File.Exists(basePath + "_mainInfo.txt"))
- info.Artifacts["mainInfo"] = GetBase64(GetFullFile(basePath + "_mainInfo.txt"));
- //if (File.Exists(Path.Combine(outputDirectory, "PFI.bin")))
- // info.Artifacts["pfi"] = Convert.ToBase64String(File.ReadAllBytes(Path.Combine(outputDirectory, "PFI.bin")));
- //if (File.Exists(Path.Combine(outputDirectory, "SS.bin")))
- // info.Artifacts["ss"] = Convert.ToBase64String(File.ReadAllBytes(Path.Combine(outputDirectory, "SS.bin")));
- if (File.Exists(basePath + ".sub"))
- info.Artifacts["sub"] = Convert.ToBase64String(File.ReadAllBytes(basePath + ".sub"));
- if (File.Exists(basePath + "_subError.txt"))
- info.Artifacts["subError"] = GetBase64(GetFullFile(basePath + "_subError.txt"));
- if (File.Exists(basePath + "_subInfo.txt"))
- info.Artifacts["subInfo"] = GetBase64(GetFullFile(basePath + "_subInfo.txt"));
- if (File.Exists(basePath + "_subIntention.txt"))
- info.Artifacts["subIntention"] = GetBase64(GetFullFile(basePath + "_subIntention.txt"));
- //if (File.Exists(basePath + "_sub.txt"))
- // info.Artifacts["subReadable"] = GetBase64(GetFullFile(basePath + "_sub.txt"));
- //if (File.Exists(basePath + "_subReadable.txt"))
- // info.Artifacts["subReadable"] = GetBase64(GetFullFile(basePath + "_subReadable.txt"));
- if (File.Exists(basePath + "_volDesc.txt"))
- info.Artifacts["volDesc"] = GetBase64(GetFullFile(basePath + "_volDesc.txt"));
- }
+ #region Private Extra Methods
///
/// Get the list of commands that use a given flag
@@ -2455,6 +2474,8 @@ namespace MPF.DiscImageCreator
}
}
+ #endregion
+
#region Information Extraction Methods
///
diff --git a/MPF.Library/UmdImageCreator/Parameters.cs b/MPF.Library/UmdImageCreator/Parameters.cs
index fba33394..bfc15154 100644
--- a/MPF.Library/UmdImageCreator/Parameters.cs
+++ b/MPF.Library/UmdImageCreator/Parameters.cs
@@ -12,20 +12,24 @@ namespace MPF.UmdImageCreator
///
public class Parameters : BaseParameters
{
+ #region Metadata
+
///
- public Parameters(string parameters)
- : base(parameters)
- {
- this.InternalProgram = InternalProgram.UmdImageCreator;
- }
+ public override InternalProgram InternalProgram => InternalProgram.UmdImageCreator;
+
+ #endregion
+
+ ///
+ public Parameters(string parameters) : base(parameters) { }
///
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
+
///
public override (bool, List) CheckAllOutputFilesExist(string basePath)
{
@@ -93,6 +97,8 @@ namespace MPF.UmdImageCreator
info.Artifacts["volDesc"] = GetBase64(GetFullFile(basePath + "_volDesc.txt"));
}
+ #endregion
+
#region Information Extraction Methods
///
diff --git a/MPF.Library/Utilities/DumpEnvironment.cs b/MPF.Library/Utilities/DumpEnvironment.cs
index dad3bf1a..49e85949 100644
--- a/MPF.Library/Utilities/DumpEnvironment.cs
+++ b/MPF.Library/Utilities/DumpEnvironment.cs
@@ -24,12 +24,12 @@ namespace MPF.Utilities
///
/// Base output directory to write files to
///
- public string OutputDirectory { get; set; }
+ public string OutputDirectory { get; private set; }
///
- /// Base output filename for DiscImageCreator
+ /// Base output filename for output
///
- public string OutputFilename { get; set; }
+ public string OutputFilename { get; private set; }
#endregion
@@ -38,27 +38,27 @@ namespace MPF.Utilities
///
/// Drive object representing the current drive
///
- public Drive Drive { get; set; }
+ public Drive Drive { get; private set; }
///
/// Currently selected system
///
- public KnownSystem? System { get; set; }
+ public KnownSystem? System { get; private set; }
///
/// Currently selected media type
///
- public MediaType? Type { get; set; }
+ public MediaType? Type { get; private set; }
///
/// Options object representing user-defined options
///
- public Options Options { get; set; }
+ public Options Options { get; private set; }
///
/// Parameters object representing what to send to the internal program
///
- 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;
}
///
@@ -202,64 +204,6 @@ namespace MPF.Utilities
await ExecuteInternalProgram(parameters);
}
- ///
- /// Fix output paths to strip out any invalid characters
- ///
- 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;
- }
- }
-
///
/// Ensures that all required output files have been created
///
@@ -277,30 +221,6 @@ namespace MPF.Utilities
return Parameters.CheckAllOutputFilesExist(basePath);
}
- ///
- /// Get the extension for a given media type and internal program
- ///
- ///
- ///
- 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);
- }
- }
-
///
/// Get the full parameter string for either DiscImageCreator or Aaru
///
@@ -344,6 +264,62 @@ namespace MPF.Utilities
return null;
}
+ ///
+ /// Normalize a split set of paths
+ ///
+ /// Directory name to normalize
+ /// Filename to normalize
+ 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);
+ }
+
///
/// Reset the current drive using DiscImageCreator
///
@@ -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);
diff --git a/MPF.Test/Utilities/DumpEnvironmentTest.cs b/MPF.Test/Utilities/DumpEnvironmentTest.cs
index 5c2e54b3..b1a59b70 100644
--- a/MPF.Test/Utilities/DumpEnvironmentTest.cs
+++ b/MPF.Test/Utilities/DumpEnvironmentTest.cs
@@ -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]
diff --git a/MPF/Windows/MainWindow.xaml.cs b/MPF/Windows/MainWindow.xaml.cs
index 7150062f..06c6d818 100644
--- a/MPF/Windows/MainWindow.xaml.cs
+++ b/MPF/Windows/MainWindow.xaml.cs
@@ -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