Files
MPF/MPF.Library/DumpEnvironment.cs

575 lines
23 KiB
C#
Raw Normal View History

using System;
using System.Collections.Generic;
Merge DumpEnvironment/DumpInformation; Add Copy Protection Scan (#82) * Merge DumpEnvironment and DumpInformation * None of these need to be static * Start adding protection checks * Convert all BurnOut-related files from VB * Placeholders for SafeDisc 3 and 4 * Fix some small things * SubIntention not always output * Make copy protect scan optional * Try/catch on disc information to avoid crashes * Add placeholders for Origin, Steam, UPlay * Don't use copied method, for safety * Protection cleanup * More cleanup on SafeDisc v1/2 * Add area for cabfiles (for later); clean up more protections * Comment out cabfile path, for now * Underscores? Really? * Namespace cleanup * More Steam variations * Add an actual UPlay installer name * Skeleton for GFWL * Add one for Origin * More Steam, update note * Add note kinda like GFWL * Fix Origin installer name (IDK what I put there before...) * Remove TODOs for ones with valid checks * Add first GFWL installer name * Move online services to last Physical disc protections should ALWAYS come before an online service is mentioned. This makes sure that the physical media's information is not lost * Add another TODO * ...slightly longer comment * Fix CDCops, start adding file lists * More paths * Even more paths * Last paths for now * Dictionary is smarter... so more work ahead * Remind me why I'm doing this? * Okay, recreated in dictionary now * Reorganiation * Alphabetization is fun * Add unused call to new scan path * Add TODO * Remove TODO * Remove TODO, comment out dummy files check * Better state for no detected protection * Make copy protect scan a Task so it can be used elsehwere later * ScanEx -> Scan; cleanup * Remove unused protection scan methods These methods used to be a simple check for if a particular file existed. These are now captured in the "CreateProtectionMapping" dictionary * Remove SuffixInStr * Characters to literals, decimal to hex, start of consolidation * Add remaining string-only mappings, cleanup * Update summaries, remove unused flag * Trim out unnecessary variables These variables used to be used when a DLL or an EXE was found to have something in it but other files were needed to check against for better output. This also assumed a monolithic output in what protections were found. Now that we just list everything and all files are scanned, this should catch everything that comes through * Remove unused path-based protections * Accidentally wiped out Sysiphus * CD Check is... special * No more internal vars; static shock * Add region tags * Remove unused Dummy Files check * Add scan for copy protection without dump * Better checking of files * Better message box * Add TODO * Clearer language for SafeDisc * Fix SafeDisc scanning Thanks to eientei95 for helping find this one * Slight EVORE cleanup * Fix SolidShield Thanks to eientei95 for helping to fix this one * Add sector scan note * Add user-requested TODO * Refactor of ComboBox underlying types (#84) * Split type combobox into system combobox and disc type combobox * corrected indentation for xaml file * fixed merge with head * fixed format * fixed issues for PR, added KnownSystem.CUSTOM * removed Updater.cs which ended by error in commit * fixed GetOuptutName() for new drive/system combobox * Refactored KnownSystem combobox management - created KnownSystemComboBoxItem to manage both header and system items - totally rewrote KnownSystem category (through KnownSystemCategory enum and markers) - fixed null access in EnsureDiscInformation caused by null _drives - rewrote cmb_SystemType management to use new classes * - created Drive class to keep drive letters, volume label and is floppy flag altogether - changed all the code to use the new Drive class in combobox and in DumpEnvironment * fixed retrieval of value from cmb_KnownSystem combobox * removed OrderedDictionary, not needed anymore * Merge DumpEnvironment and DumpInformation * None of these need to be static * Start adding protection checks * Convert all BurnOut-related files from VB * Placeholders for SafeDisc 3 and 4 * Fix some small things * SubIntention not always output * Make copy protect scan optional * Try/catch on disc information to avoid crashes * Add placeholders for Origin, Steam, UPlay * Don't use copied method, for safety * Protection cleanup * More cleanup on SafeDisc v1/2 * Add area for cabfiles (for later); clean up more protections * Comment out cabfile path, for now * Underscores? Really? * Namespace cleanup * More Steam variations * Add an actual UPlay installer name * Skeleton for GFWL * Add one for Origin * More Steam, update note * Add note kinda like GFWL * Fix Origin installer name (IDK what I put there before...) * Remove TODOs for ones with valid checks * Add first GFWL installer name * Move online services to last Physical disc protections should ALWAYS come before an online service is mentioned. This makes sure that the physical media's information is not lost * Add another TODO * ...slightly longer comment * Fix CDCops, start adding file lists * More paths * Even more paths * Last paths for now * Dictionary is smarter... so more work ahead * Remind me why I'm doing this? * Okay, recreated in dictionary now * Reorganiation * Alphabetization is fun * Add unused call to new scan path * Add TODO * Remove TODO * Remove TODO, comment out dummy files check * Better state for no detected protection * Make copy protect scan a Task so it can be used elsehwere later * ScanEx -> Scan; cleanup * Remove unused protection scan methods These methods used to be a simple check for if a particular file existed. These are now captured in the "CreateProtectionMapping" dictionary * Remove SuffixInStr * Characters to literals, decimal to hex, start of consolidation * Add remaining string-only mappings, cleanup * Update summaries, remove unused flag * Trim out unnecessary variables These variables used to be used when a DLL or an EXE was found to have something in it but other files were needed to check against for better output. This also assumed a monolithic output in what protections were found. Now that we just list everything and all files are scanned, this should catch everything that comes through * Remove unused path-based protections * Accidentally wiped out Sysiphus * CD Check is... special * No more internal vars; static shock * Add region tags * Remove unused Dummy Files check * Add scan for copy protection without dump * Better checking of files * Better message box * Add TODO * Clearer language for SafeDisc * Fix SafeDisc scanning Thanks to eientei95 for helping find this one * Slight EVORE cleanup * Fix SolidShield Thanks to eientei95 for helping to fix this one * Add sector scan note * Add user-requested TODO
2018-07-05 12:58:20 -07:00
using System.Diagnostics;
using System.IO;
Merge DumpEnvironment/DumpInformation; Add Copy Protection Scan (#82) * Merge DumpEnvironment and DumpInformation * None of these need to be static * Start adding protection checks * Convert all BurnOut-related files from VB * Placeholders for SafeDisc 3 and 4 * Fix some small things * SubIntention not always output * Make copy protect scan optional * Try/catch on disc information to avoid crashes * Add placeholders for Origin, Steam, UPlay * Don't use copied method, for safety * Protection cleanup * More cleanup on SafeDisc v1/2 * Add area for cabfiles (for later); clean up more protections * Comment out cabfile path, for now * Underscores? Really? * Namespace cleanup * More Steam variations * Add an actual UPlay installer name * Skeleton for GFWL * Add one for Origin * More Steam, update note * Add note kinda like GFWL * Fix Origin installer name (IDK what I put there before...) * Remove TODOs for ones with valid checks * Add first GFWL installer name * Move online services to last Physical disc protections should ALWAYS come before an online service is mentioned. This makes sure that the physical media's information is not lost * Add another TODO * ...slightly longer comment * Fix CDCops, start adding file lists * More paths * Even more paths * Last paths for now * Dictionary is smarter... so more work ahead * Remind me why I'm doing this? * Okay, recreated in dictionary now * Reorganiation * Alphabetization is fun * Add unused call to new scan path * Add TODO * Remove TODO * Remove TODO, comment out dummy files check * Better state for no detected protection * Make copy protect scan a Task so it can be used elsehwere later * ScanEx -> Scan; cleanup * Remove unused protection scan methods These methods used to be a simple check for if a particular file existed. These are now captured in the "CreateProtectionMapping" dictionary * Remove SuffixInStr * Characters to literals, decimal to hex, start of consolidation * Add remaining string-only mappings, cleanup * Update summaries, remove unused flag * Trim out unnecessary variables These variables used to be used when a DLL or an EXE was found to have something in it but other files were needed to check against for better output. This also assumed a monolithic output in what protections were found. Now that we just list everything and all files are scanned, this should catch everything that comes through * Remove unused path-based protections * Accidentally wiped out Sysiphus * CD Check is... special * No more internal vars; static shock * Add region tags * Remove unused Dummy Files check * Add scan for copy protection without dump * Better checking of files * Better message box * Add TODO * Clearer language for SafeDisc * Fix SafeDisc scanning Thanks to eientei95 for helping find this one * Slight EVORE cleanup * Fix SolidShield Thanks to eientei95 for helping to fix this one * Add sector scan note * Add user-requested TODO * Refactor of ComboBox underlying types (#84) * Split type combobox into system combobox and disc type combobox * corrected indentation for xaml file * fixed merge with head * fixed format * fixed issues for PR, added KnownSystem.CUSTOM * removed Updater.cs which ended by error in commit * fixed GetOuptutName() for new drive/system combobox * Refactored KnownSystem combobox management - created KnownSystemComboBoxItem to manage both header and system items - totally rewrote KnownSystem category (through KnownSystemCategory enum and markers) - fixed null access in EnsureDiscInformation caused by null _drives - rewrote cmb_SystemType management to use new classes * - created Drive class to keep drive letters, volume label and is floppy flag altogether - changed all the code to use the new Drive class in combobox and in DumpEnvironment * fixed retrieval of value from cmb_KnownSystem combobox * removed OrderedDictionary, not needed anymore * Merge DumpEnvironment and DumpInformation * None of these need to be static * Start adding protection checks * Convert all BurnOut-related files from VB * Placeholders for SafeDisc 3 and 4 * Fix some small things * SubIntention not always output * Make copy protect scan optional * Try/catch on disc information to avoid crashes * Add placeholders for Origin, Steam, UPlay * Don't use copied method, for safety * Protection cleanup * More cleanup on SafeDisc v1/2 * Add area for cabfiles (for later); clean up more protections * Comment out cabfile path, for now * Underscores? Really? * Namespace cleanup * More Steam variations * Add an actual UPlay installer name * Skeleton for GFWL * Add one for Origin * More Steam, update note * Add note kinda like GFWL * Fix Origin installer name (IDK what I put there before...) * Remove TODOs for ones with valid checks * Add first GFWL installer name * Move online services to last Physical disc protections should ALWAYS come before an online service is mentioned. This makes sure that the physical media's information is not lost * Add another TODO * ...slightly longer comment * Fix CDCops, start adding file lists * More paths * Even more paths * Last paths for now * Dictionary is smarter... so more work ahead * Remind me why I'm doing this? * Okay, recreated in dictionary now * Reorganiation * Alphabetization is fun * Add unused call to new scan path * Add TODO * Remove TODO * Remove TODO, comment out dummy files check * Better state for no detected protection * Make copy protect scan a Task so it can be used elsehwere later * ScanEx -> Scan; cleanup * Remove unused protection scan methods These methods used to be a simple check for if a particular file existed. These are now captured in the "CreateProtectionMapping" dictionary * Remove SuffixInStr * Characters to literals, decimal to hex, start of consolidation * Add remaining string-only mappings, cleanup * Update summaries, remove unused flag * Trim out unnecessary variables These variables used to be used when a DLL or an EXE was found to have something in it but other files were needed to check against for better output. This also assumed a monolithic output in what protections were found. Now that we just list everything and all files are scanned, this should catch everything that comes through * Remove unused path-based protections * Accidentally wiped out Sysiphus * CD Check is... special * No more internal vars; static shock * Add region tags * Remove unused Dummy Files check * Add scan for copy protection without dump * Better checking of files * Better message box * Add TODO * Clearer language for SafeDisc * Fix SafeDisc scanning Thanks to eientei95 for helping find this one * Slight EVORE cleanup * Fix SolidShield Thanks to eientei95 for helping to fix this one * Add sector scan note * Add user-requested TODO
2018-07-05 12:58:20 -07:00
using System.Threading.Tasks;
2020-08-06 22:05:16 -07:00
using BurnOutSharp;
using MPF.Core.Data;
using MPF.Core.Utilities;
using MPF.Modules;
2023-09-05 00:08:09 -04:00
using SabreTools.RedumpLib.Data;
namespace MPF.Library
{
/// <summary>
2019-05-20 22:14:53 -07:00
/// Represents the state of all settings to be used during dumping
/// </summary>
2019-05-20 22:14:53 -07:00
public class DumpEnvironment
{
2019-05-20 22:14:53 -07:00
#region Output paths
/// <summary>
/// Base output file path to write files to
2019-05-20 22:14:53 -07:00
/// </summary>
public string OutputPath { get; private set; }
2019-05-20 22:14:53 -07:00
#endregion
#region UI information
/// <summary>
/// Drive object representing the current drive
/// </summary>
public Drive Drive { get; private set; }
2019-05-20 22:14:53 -07:00
/// <summary>
/// Currently selected system
/// </summary>
2021-08-18 22:13:38 -07:00
public RedumpSystem? System { get; private set; }
2019-05-20 22:14:53 -07:00
/// <summary>
/// Currently selected media type
/// </summary>
public MediaType? Type { get; private set; }
2019-05-20 22:14:53 -07:00
/// <summary>
/// Currently selected dumping program
/// </summary>
public InternalProgram InternalProgram { get; private set; }
2019-05-20 22:14:53 -07:00
/// <summary>
2021-03-08 14:56:26 -08:00
/// Options object representing user-defined options
2019-05-20 22:14:53 -07:00
/// </summary>
2023-07-14 12:07:44 -04:00
public Core.Data.Options Options { get; private set; }
2019-05-20 22:14:53 -07:00
/// <summary>
2021-03-08 14:56:26 -08:00
/// Parameters object representing what to send to the internal program
2019-05-20 22:14:53 -07:00
/// </summary>
public BaseParameters Parameters { get; private set; }
#endregion
#region Event Handlers
/// <summary>
2021-11-26 14:06:57 -08:00
/// Generic way of reporting a message
/// </summary>
public EventHandler<string> ReportStatus;
/// <summary>
/// Queue of items that need to be logged
/// </summary>
2021-03-29 10:50:43 -07:00
private ProcessingQueue<string> outputQueue;
/// <summary>
/// Event handler for data returned from a process
/// </summary>
2021-11-26 14:06:57 -08:00
private void OutputToLog(object proc, string args) => outputQueue.Enqueue(args);
/// <summary>
/// Process the outputs in the queue
/// </summary>
2021-11-26 14:06:57 -08:00
private void ProcessOutputs(string nextOutput) => ReportStatus.Invoke(this, nextOutput);
2019-05-20 22:14:53 -07:00
#endregion
/// <summary>
/// Constructor for a full DumpEnvironment object from user information
/// </summary>
/// <param name="options"></param>
/// <param name="outputPath"></param>
/// <param name="drive"></param>
/// <param name="system"></param>
/// <param name="type"></param>
/// <param name="internalProgram"></param>
/// <param name="parameters"></param>
2023-07-14 12:07:44 -04:00
public DumpEnvironment(Core.Data.Options options,
string outputPath,
Drive drive,
2021-08-18 22:13:38 -07:00
RedumpSystem? system,
MediaType? type,
InternalProgram? internalProgram,
string parameters)
{
2021-03-08 14:56:26 -08:00
// Set options object
this.Options = options;
// Output paths
this.OutputPath = InfoTool.NormalizeOutputPaths(outputPath);
// UI information
this.Drive = drive;
this.System = system ?? options.DefaultSystem;
this.Type = type ?? MediaType.NONE;
this.InternalProgram = internalProgram ?? options.InternalProgram;
// Dumping program
SetParameters(parameters);
}
More and more cleanup (#86) * Namespace cleanups * Make dump validation instanced * Add note to Tasks * Move stuff to DumpEnvironment Most of the stuff in Tasks.cs acted on a single input parameter, namely a DumpEnvironment. Since that's the case, it was more logical to wrap those into DumpEnvironment and make them instance methods rather than keep them static. Due to this change, quite a few methods changed access, and some had to be marked internal due to wanting them to be tested separately. * Gut Tasks * One less thing in MainWindow * Remove explicit cast * Wrong check * Create helper method * Disable scan button on dump * Remove unnecessary getters/setters * Method name/description cleanup * Address TODO * Namespace cleanups * Make dump validation instanced * Add note to Tasks * Move stuff to DumpEnvironment Most of the stuff in Tasks.cs acted on a single input parameter, namely a DumpEnvironment. Since that's the case, it was more logical to wrap those into DumpEnvironment and make them instance methods rather than keep them static. Due to this change, quite a few methods changed access, and some had to be marked internal due to wanting them to be tested separately. * Gut Tasks * One less thing in MainWindow * Remove explicit cast * Wrong check * Create helper method * Disable scan button on dump * Remove unnecessary getters/setters * Method name/description cleanup * Address TODO * Clean up OnContentRendered * Namespace cleanups * Make dump validation instanced * Add note to Tasks * Move stuff to DumpEnvironment Most of the stuff in Tasks.cs acted on a single input parameter, namely a DumpEnvironment. Since that's the case, it was more logical to wrap those into DumpEnvironment and make them instance methods rather than keep them static. Due to this change, quite a few methods changed access, and some had to be marked internal due to wanting them to be tested separately. * Gut Tasks * One less thing in MainWindow * Remove explicit cast * Wrong check * Create helper method * Disable scan button on dump * Remove unnecessary getters/setters * Method name/description cleanup * Address TODO * Clean up OnContentRendered * Update event handlers
2018-07-05 21:34:04 -07:00
#region Public Functionality
Merge DumpEnvironment/DumpInformation; Add Copy Protection Scan (#82) * Merge DumpEnvironment and DumpInformation * None of these need to be static * Start adding protection checks * Convert all BurnOut-related files from VB * Placeholders for SafeDisc 3 and 4 * Fix some small things * SubIntention not always output * Make copy protect scan optional * Try/catch on disc information to avoid crashes * Add placeholders for Origin, Steam, UPlay * Don't use copied method, for safety * Protection cleanup * More cleanup on SafeDisc v1/2 * Add area for cabfiles (for later); clean up more protections * Comment out cabfile path, for now * Underscores? Really? * Namespace cleanup * More Steam variations * Add an actual UPlay installer name * Skeleton for GFWL * Add one for Origin * More Steam, update note * Add note kinda like GFWL * Fix Origin installer name (IDK what I put there before...) * Remove TODOs for ones with valid checks * Add first GFWL installer name * Move online services to last Physical disc protections should ALWAYS come before an online service is mentioned. This makes sure that the physical media's information is not lost * Add another TODO * ...slightly longer comment * Fix CDCops, start adding file lists * More paths * Even more paths * Last paths for now * Dictionary is smarter... so more work ahead * Remind me why I'm doing this? * Okay, recreated in dictionary now * Reorganiation * Alphabetization is fun * Add unused call to new scan path * Add TODO * Remove TODO * Remove TODO, comment out dummy files check * Better state for no detected protection * Make copy protect scan a Task so it can be used elsehwere later * ScanEx -> Scan; cleanup * Remove unused protection scan methods These methods used to be a simple check for if a particular file existed. These are now captured in the "CreateProtectionMapping" dictionary * Remove SuffixInStr * Characters to literals, decimal to hex, start of consolidation * Add remaining string-only mappings, cleanup * Update summaries, remove unused flag * Trim out unnecessary variables These variables used to be used when a DLL or an EXE was found to have something in it but other files were needed to check against for better output. This also assumed a monolithic output in what protections were found. Now that we just list everything and all files are scanned, this should catch everything that comes through * Remove unused path-based protections * Accidentally wiped out Sysiphus * CD Check is... special * No more internal vars; static shock * Add region tags * Remove unused Dummy Files check * Add scan for copy protection without dump * Better checking of files * Better message box * Add TODO * Clearer language for SafeDisc * Fix SafeDisc scanning Thanks to eientei95 for helping find this one * Slight EVORE cleanup * Fix SolidShield Thanks to eientei95 for helping to fix this one * Add sector scan note * Add user-requested TODO * Refactor of ComboBox underlying types (#84) * Split type combobox into system combobox and disc type combobox * corrected indentation for xaml file * fixed merge with head * fixed format * fixed issues for PR, added KnownSystem.CUSTOM * removed Updater.cs which ended by error in commit * fixed GetOuptutName() for new drive/system combobox * Refactored KnownSystem combobox management - created KnownSystemComboBoxItem to manage both header and system items - totally rewrote KnownSystem category (through KnownSystemCategory enum and markers) - fixed null access in EnsureDiscInformation caused by null _drives - rewrote cmb_SystemType management to use new classes * - created Drive class to keep drive letters, volume label and is floppy flag altogether - changed all the code to use the new Drive class in combobox and in DumpEnvironment * fixed retrieval of value from cmb_KnownSystem combobox * removed OrderedDictionary, not needed anymore * Merge DumpEnvironment and DumpInformation * None of these need to be static * Start adding protection checks * Convert all BurnOut-related files from VB * Placeholders for SafeDisc 3 and 4 * Fix some small things * SubIntention not always output * Make copy protect scan optional * Try/catch on disc information to avoid crashes * Add placeholders for Origin, Steam, UPlay * Don't use copied method, for safety * Protection cleanup * More cleanup on SafeDisc v1/2 * Add area for cabfiles (for later); clean up more protections * Comment out cabfile path, for now * Underscores? Really? * Namespace cleanup * More Steam variations * Add an actual UPlay installer name * Skeleton for GFWL * Add one for Origin * More Steam, update note * Add note kinda like GFWL * Fix Origin installer name (IDK what I put there before...) * Remove TODOs for ones with valid checks * Add first GFWL installer name * Move online services to last Physical disc protections should ALWAYS come before an online service is mentioned. This makes sure that the physical media's information is not lost * Add another TODO * ...slightly longer comment * Fix CDCops, start adding file lists * More paths * Even more paths * Last paths for now * Dictionary is smarter... so more work ahead * Remind me why I'm doing this? * Okay, recreated in dictionary now * Reorganiation * Alphabetization is fun * Add unused call to new scan path * Add TODO * Remove TODO * Remove TODO, comment out dummy files check * Better state for no detected protection * Make copy protect scan a Task so it can be used elsehwere later * ScanEx -> Scan; cleanup * Remove unused protection scan methods These methods used to be a simple check for if a particular file existed. These are now captured in the "CreateProtectionMapping" dictionary * Remove SuffixInStr * Characters to literals, decimal to hex, start of consolidation * Add remaining string-only mappings, cleanup * Update summaries, remove unused flag * Trim out unnecessary variables These variables used to be used when a DLL or an EXE was found to have something in it but other files were needed to check against for better output. This also assumed a monolithic output in what protections were found. Now that we just list everything and all files are scanned, this should catch everything that comes through * Remove unused path-based protections * Accidentally wiped out Sysiphus * CD Check is... special * No more internal vars; static shock * Add region tags * Remove unused Dummy Files check * Add scan for copy protection without dump * Better checking of files * Better message box * Add TODO * Clearer language for SafeDisc * Fix SafeDisc scanning Thanks to eientei95 for helping find this one * Slight EVORE cleanup * Fix SolidShield Thanks to eientei95 for helping to fix this one * Add sector scan note * Add user-requested TODO
2018-07-05 12:58:20 -07:00
/// <summary>
/// Adjust output paths if we're using DiscImageCreator
/// </summary>
public void AdjustPathsForDiscImageCreator()
{
// Only DiscImageCreator has issues with paths
if (this.Parameters.InternalProgram != InternalProgram.DiscImageCreator)
return;
try
{
// Normalize the output path
string outputPath = InfoTool.NormalizeOutputPaths(this.OutputPath);
// Replace all instances in the output directory
2023-02-23 15:22:21 -05:00
string outputDirectory = Path.GetDirectoryName(outputPath);
outputDirectory = outputDirectory.Replace(".", "_");
// Replace all instances in the output filename
2023-02-23 15:22:21 -05:00
string outputFilename = Path.GetFileNameWithoutExtension(outputPath);
outputFilename = outputFilename.Replace(".", "_");
// Get the extension for recreating the path
2023-02-23 15:22:21 -05:00
string outputExtension = Path.GetExtension(outputPath).TrimStart('.');
2022-02-12 23:25:34 -08:00
// Rebuild the output path
if (!string.IsNullOrWhiteSpace(outputExtension))
this.OutputPath = Path.Combine(outputDirectory, $"{outputFilename}.{outputExtension}");
else
this.OutputPath = Path.Combine(outputDirectory, outputFilename);
// Assign the path to the filename as well for dumping
((Modules.DiscImageCreator.Parameters)this.Parameters).Filename = this.OutputPath;
}
catch { }
}
/// <summary>
/// Set the parameters object based on the internal program and parameters string
/// </summary>
/// <param name="parameters">String representation of the parameters</param>
public void SetParameters(string parameters)
{
switch (this.InternalProgram)
{
2020-05-07 14:23:49 -07:00
// Dumping support
case InternalProgram.Aaru:
this.Parameters = new Modules.Aaru.Parameters(parameters) { ExecutablePath = Options.AaruPath };
break;
2020-04-21 14:39:39 -07:00
case InternalProgram.DD:
this.Parameters = new Modules.DD.Parameters(parameters) { ExecutablePath = Options.DDPath };
2020-04-21 14:39:39 -07:00
break;
case InternalProgram.DiscImageCreator:
this.Parameters = new Modules.DiscImageCreator.Parameters(parameters) { ExecutablePath = Options.DiscImageCreatorPath };
break;
2022-09-27 23:08:12 -07:00
case InternalProgram.Redumper:
2022-12-13 20:04:20 -08:00
this.Parameters = new Modules.Redumper.Parameters(parameters) { ExecutablePath = Options.RedumperPath };
2022-09-27 23:08:12 -07:00
break;
2020-05-07 14:23:49 -07:00
// Verification support only
case InternalProgram.CleanRip:
this.Parameters = new Modules.CleanRip.Parameters(parameters) { ExecutablePath = null };
2020-05-07 14:23:49 -07:00
break;
2020-09-10 11:11:26 -07:00
case InternalProgram.DCDumper:
2021-03-08 22:19:22 -08:00
this.Parameters = null; // TODO: Create correct parameter type when supported
2020-09-10 11:11:26 -07:00
break;
2020-09-10 11:27:25 -07:00
case InternalProgram.UmdImageCreator:
this.Parameters = new Modules.UmdImageCreator.Parameters(parameters) { ExecutablePath = null };
2020-09-10 11:27:25 -07:00
break;
// This should never happen, but it needs a fallback
default:
this.Parameters = new Modules.DiscImageCreator.Parameters(parameters) { ExecutablePath = Options.DiscImageCreatorPath };
break;
}
// Set system and type
this.Parameters.System = this.System;
this.Parameters.Type = this.Type;
}
2019-05-20 22:14:53 -07:00
/// <summary>
/// Get the full parameter string for either DiscImageCreator or Aaru
2019-05-20 22:14:53 -07:00
/// </summary>
/// <param name="driveSpeed">Nullable int representing the drive speed</param>
/// <returns>String representing the params, null on error</returns>
public string GetFullParameters(int? driveSpeed)
{
// Populate with the correct params for inputs (if we're not on the default option)
2021-08-18 22:13:38 -07:00
if (System != null && Type != MediaType.NONE)
2019-05-20 22:14:53 -07:00
{
// If drive letter is invalid, skip this
if (Drive == null)
return null;
// Set the proper parameters
switch (this.InternalProgram)
{
case InternalProgram.Aaru:
Parameters = new Modules.Aaru.Parameters(System, Type, Drive.Letter, this.OutputPath, driveSpeed, Options);
break;
2020-04-21 14:39:39 -07:00
case InternalProgram.DD:
Parameters = new Modules.DD.Parameters(System, Type, Drive.Letter, this.OutputPath, driveSpeed, Options);
2020-04-21 14:39:39 -07:00
break;
case InternalProgram.DiscImageCreator:
Parameters = new Modules.DiscImageCreator.Parameters(System, Type, Drive.Letter, this.OutputPath, driveSpeed, Options);
break;
2022-09-27 23:08:12 -07:00
case InternalProgram.Redumper:
Parameters = new Modules.Redumper.Parameters(System, Type, Drive.Letter, this.OutputPath, driveSpeed, Options);
2022-09-27 23:08:12 -07:00
break;
// This should never happen, but it needs a fallback
default:
Parameters = new Modules.DiscImageCreator.Parameters(System, Type, Drive.Letter, this.OutputPath, driveSpeed, Options);
break;
}
// Generate and return the param string
return Parameters.GenerateParameters();
2019-05-20 22:14:53 -07:00
}
return null;
}
2021-03-12 15:14:40 -08:00
#endregion
#region Dumping
/// <summary>
/// Cancel an in-progress dumping process
/// </summary>
2021-11-26 14:06:57 -08:00
public void CancelDumping() => Parameters.KillInternalProgram();
2021-03-12 15:14:40 -08:00
/// <summary>
/// Eject the disc using DiscImageCreator
/// </summary>
2021-11-26 14:06:57 -08:00
public async Task<string> EjectDisc() =>
await RunStandaloneDiscImageCreatorCommand(Modules.DiscImageCreator.CommandStrings.Eject);
2021-03-12 15:14:40 -08:00
/// <summary>
2020-05-06 16:06:30 -07:00
/// Reset the current drive using DiscImageCreator
/// </summary>
2021-11-26 14:06:57 -08:00
public async Task<string> ResetDrive() =>
await RunStandaloneDiscImageCreatorCommand(Modules.DiscImageCreator.CommandStrings.Reset);
2019-05-20 22:14:53 -07:00
/// <summary>
/// Execute the initial invocation of the dumping programs
2019-05-20 22:14:53 -07:00
/// </summary>
2020-08-06 22:52:25 -07:00
/// <param name="progress">Optional result progress callback</param>
public async Task<Result> Run(IProgress<Result> progress = null)
2019-05-20 22:14:53 -07:00
{
// Check that we have the basics for dumping
2019-05-20 22:14:53 -07:00
Result result = IsValidForDump();
if (!result)
return result;
2019-05-20 22:14:53 -07:00
// Invoke output processing, if needed
if (!Options.ToolsInSeparateWindow)
{
2021-03-29 10:50:43 -07:00
outputQueue = new ProcessingQueue<string>(ProcessOutputs);
Parameters.ReportStatus += OutputToLog;
}
// Execute internal tool
progress?.Report(Result.Success($"Executing {this.InternalProgram}... {(Options.ToolsInSeparateWindow ? "please wait!" : "see log for output!")}"));
Directory.CreateDirectory(Path.GetDirectoryName(this.OutputPath));
await Task.Run(() => Parameters.ExecuteInternalProgram(Options.ToolsInSeparateWindow));
progress?.Report(Result.Success($"{this.InternalProgram} has finished!"));
// Execute additional tools
progress?.Report(Result.Success("Running any additional tools... see log for output!"));
result = await Task.Run(() => ExecuteAdditionalTools());
progress?.Report(result);
2019-05-20 22:14:53 -07:00
2021-03-29 10:50:43 -07:00
// Remove event handler if needed
if (!Options.ToolsInSeparateWindow)
2021-03-29 10:50:43 -07:00
{
outputQueue.Dispose();
Parameters.ReportStatus -= OutputToLog;
2021-03-29 10:50:43 -07:00
}
2019-05-20 22:14:53 -07:00
return result;
}
/// <summary>
/// Verify that the current environment has a complete dump and create submission info is possible
/// </summary>
2020-08-06 22:05:16 -07:00
/// <param name="resultProgress">Optional result progress callback</param>
/// <param name="protectionProgress">Optional protection progress callback</param>
2021-11-26 14:06:57 -08:00
/// <param name="processUserInfo">Optional user prompt to deal with submission information</param>
2019-05-20 22:14:53 -07:00
/// <returns>Result instance with the outcome</returns>
2020-08-06 22:05:16 -07:00
public async Task<Result> VerifyAndSaveDumpOutput(
IProgress<Result> resultProgress = null,
2021-01-22 12:03:12 -08:00
IProgress<ProtectionProgress> protectionProgress = null,
Func<SubmissionInfo, (bool?, SubmissionInfo)> processUserInfo = null)
2019-05-20 22:14:53 -07:00
{
2020-08-06 22:05:16 -07:00
resultProgress?.Report(Result.Success("Gathering submission information... please wait!"));
// Get the output directory and filename separately
string outputDirectory = Path.GetDirectoryName(this.OutputPath);
string outputFilename = Path.GetFileName(this.OutputPath);
2019-05-20 22:14:53 -07:00
// Check to make sure that the output had all the correct files
(bool foundFiles, List<string> missingFiles) = InfoTool.FoundAllFiles(outputDirectory, outputFilename, this.Parameters, false);
if (!foundFiles)
{
2021-11-24 22:05:10 -08:00
resultProgress?.Report(Result.Failure($"There were files missing from the output:\n{string.Join("\n", missingFiles)}"));
2019-05-20 22:14:53 -07:00
return Result.Failure("Error! Please check output directory as dump may be incomplete!");
}
2019-05-20 22:14:53 -07:00
// Extract the information from the output files
2020-08-06 22:05:16 -07:00
resultProgress?.Report(Result.Success("Extracting output information from output files..."));
2021-09-29 16:16:54 -07:00
SubmissionInfo submissionInfo = await InfoTool.ExtractOutputInformation(
this.OutputPath,
2021-09-29 16:16:54 -07:00
this.Drive,
this.System,
this.Type,
this.Options,
this.Parameters,
resultProgress,
protectionProgress);
2020-08-06 22:05:16 -07:00
resultProgress?.Report(Result.Success("Extracting information complete!"));
2019-05-20 22:14:53 -07:00
2021-11-26 14:06:57 -08:00
// Eject the disc automatically if configured to
2021-03-08 15:06:40 -08:00
if (Options.EjectAfterDump == true)
2020-01-27 00:03:03 -08:00
{
2020-08-06 22:05:16 -07:00
resultProgress?.Report(Result.Success($"Ejecting disc in drive {Drive.Letter}"));
2021-11-26 14:06:57 -08:00
await EjectDisc();
2020-01-27 00:03:03 -08:00
}
2021-11-26 14:06:57 -08:00
// Reset the drive automatically if configured to
if (this.InternalProgram == InternalProgram.DiscImageCreator && Options.DICResetDriveAfterDump)
{
2020-08-06 22:05:16 -07:00
resultProgress?.Report(Result.Success($"Resetting drive {Drive.Letter}"));
2021-11-26 14:06:57 -08:00
await ResetDrive();
}
2021-11-26 14:06:57 -08:00
// Get user-modifiable information if confugured to
if (Options.PromptForDiscInformation && processUserInfo != null)
{
2020-08-06 22:05:16 -07:00
resultProgress?.Report(Result.Success("Waiting for additional disc information..."));
bool? filledInfo;
(filledInfo, submissionInfo) = processUserInfo(submissionInfo);
if (filledInfo == true)
resultProgress?.Report(Result.Success("Additional disc information added!"));
else
resultProgress?.Report(Result.Success("Disc information skipped!"));
}
2019-05-20 22:14:53 -07:00
// Process special fields for site codes
resultProgress?.Report(Result.Success("Processing site codes..."));
InfoTool.ProcessSpecialFields(submissionInfo);
resultProgress?.Report(Result.Success("Processing complete!"));
// Format the information for the text output
resultProgress?.Report(Result.Success("Formatting information..."));
(List<string> formattedValues, string formatResult) = InfoTool.FormatOutputData(submissionInfo, this.Options);
if (formattedValues == null)
resultProgress?.Report(Result.Success(formatResult));
else
resultProgress?.Report(Result.Failure(formatResult));
2019-05-20 22:14:53 -07:00
// Write the text output
2020-08-06 22:05:16 -07:00
resultProgress?.Report(Result.Success("Writing information to !submissionInfo.txt..."));
(bool txtSuccess, string txtResult) = InfoTool.WriteOutputData(outputDirectory, formattedValues);
if (txtSuccess)
resultProgress?.Report(Result.Success(txtResult));
2019-05-20 22:14:53 -07:00
else
resultProgress?.Report(Result.Failure(txtResult));
2019-05-20 22:14:53 -07:00
// Write the copy protection output
if (Options.ScanForProtection && Options.OutputSeparateProtectionFile)
{
resultProgress?.Report(Result.Success("Writing protection to !protectionInfo.txt..."));
bool scanSuccess = InfoTool.WriteProtectionData(outputDirectory, submissionInfo);
if (scanSuccess)
resultProgress?.Report(Result.Success("Writing complete!"));
else
resultProgress?.Report(Result.Failure("Writing could not complete!"));
}
2021-04-02 18:57:25 -07:00
// Write the JSON output, if required
if (Options.OutputSubmissionJSON)
{
resultProgress?.Report(Result.Success($"Writing information to !submissionInfo.json{(Options.IncludeArtifacts ? ".gz" : string.Empty)}..."));
bool jsonSuccess = InfoTool.WriteOutputData(outputDirectory, submissionInfo, Options.IncludeArtifacts);
if (jsonSuccess)
2021-04-02 18:57:25 -07:00
resultProgress?.Report(Result.Success("Writing complete!"));
else
resultProgress?.Report(Result.Failure("Writing could not complete!"));
}
// Compress the logs, if required
2021-04-02 21:21:50 -07:00
if (Options.CompressLogFiles)
{
resultProgress?.Report(Result.Success("Compressing log files..."));
(bool compressSuccess, string compressResult) = InfoTool.CompressLogFiles(outputDirectory, outputFilename, this.Parameters);
2022-10-17 15:41:00 -07:00
if (compressSuccess)
resultProgress?.Report(Result.Success(compressResult));
else
resultProgress?.Report(Result.Failure(compressResult));
}
2021-04-02 21:21:50 -07:00
resultProgress?.Report(Result.Success("Submission information process complete!"));
2019-05-20 22:14:53 -07:00
return Result.Success();
}
/// <summary>
/// Checks if the parameters are valid
/// </summary>
/// <returns>True if the configuration is valid, false otherwise</returns>
internal bool ParametersValid()
{
bool parametersValid = Parameters.IsValid();
bool floppyValid = !(Drive.InternalDriveType == InternalDriveType.Floppy ^ Type == MediaType.FloppyDisk);
// TODO: HardDisk being in the Removable category is a hack, fix this later
bool removableDiskValid = !((Drive.InternalDriveType == InternalDriveType.Removable || Drive.InternalDriveType == InternalDriveType.HardDisk)
^ (Type == MediaType.CompactFlash || Type == MediaType.SDCard || Type == MediaType.FlashDrive || Type == MediaType.HardDisk));
return parametersValid && floppyValid && removableDiskValid;
2019-05-20 22:14:53 -07:00
}
More and more cleanup (#86) * Namespace cleanups * Make dump validation instanced * Add note to Tasks * Move stuff to DumpEnvironment Most of the stuff in Tasks.cs acted on a single input parameter, namely a DumpEnvironment. Since that's the case, it was more logical to wrap those into DumpEnvironment and make them instance methods rather than keep them static. Due to this change, quite a few methods changed access, and some had to be marked internal due to wanting them to be tested separately. * Gut Tasks * One less thing in MainWindow * Remove explicit cast * Wrong check * Create helper method * Disable scan button on dump * Remove unnecessary getters/setters * Method name/description cleanup * Address TODO * Namespace cleanups * Make dump validation instanced * Add note to Tasks * Move stuff to DumpEnvironment Most of the stuff in Tasks.cs acted on a single input parameter, namely a DumpEnvironment. Since that's the case, it was more logical to wrap those into DumpEnvironment and make them instance methods rather than keep them static. Due to this change, quite a few methods changed access, and some had to be marked internal due to wanting them to be tested separately. * Gut Tasks * One less thing in MainWindow * Remove explicit cast * Wrong check * Create helper method * Disable scan button on dump * Remove unnecessary getters/setters * Method name/description cleanup * Address TODO * Clean up OnContentRendered * Namespace cleanups * Make dump validation instanced * Add note to Tasks * Move stuff to DumpEnvironment Most of the stuff in Tasks.cs acted on a single input parameter, namely a DumpEnvironment. Since that's the case, it was more logical to wrap those into DumpEnvironment and make them instance methods rather than keep them static. Due to this change, quite a few methods changed access, and some had to be marked internal due to wanting them to be tested separately. * Gut Tasks * One less thing in MainWindow * Remove explicit cast * Wrong check * Create helper method * Disable scan button on dump * Remove unnecessary getters/setters * Method name/description cleanup * Address TODO * Clean up OnContentRendered * Update event handlers
2018-07-05 21:34:04 -07:00
/// <summary>
/// Run any additional tools given a DumpEnvironment
/// </summary>
/// <returns>Result instance with the outcome</returns>
2021-11-26 14:06:57 -08:00
private Result ExecuteAdditionalTools() => Result.Success("No external tools needed!");
/// <summary>
/// Run internal program async with an input set of parameters
/// </summary>
/// <param name="parameters"></param>
/// <returns>Standard output from commandline window</returns>
private async Task<string> ExecuteInternalProgram(BaseParameters parameters)
{
Process childProcess;
string output = await Task.Run(() =>
{
childProcess = new Process()
{
StartInfo = new ProcessStartInfo()
{
FileName = parameters.ExecutablePath,
Arguments = parameters.GenerateParameters(),
CreateNoWindow = true,
UseShellExecute = false,
RedirectStandardInput = true,
RedirectStandardOutput = true,
},
};
childProcess.Start();
childProcess.WaitForExit(1000);
// Just in case, we want to push a button 5 times to clear any errors
for (int i = 0; i < 5; i++)
childProcess.StandardInput.WriteLine("Y");
string stdout = childProcess.StandardOutput.ReadToEnd();
childProcess.Dispose();
return stdout;
});
return output;
}
2019-05-20 00:12:06 -07:00
/// <summary>
/// Validate the current environment is ready for a dump
/// </summary>
/// <returns>Result instance with the outcome</returns>
private Result IsValidForDump()
{
// Validate that everything is good
if (!ParametersValid())
return Result.Failure("Error! Current configuration is not supported!");
// Fix the output paths, just in case
this.OutputPath = InfoTool.NormalizeOutputPaths(this.OutputPath);
// Validate that the output path isn't on the dumping drive
if (this.OutputPath[0] == Drive.Letter)
return Result.Failure("Error! Cannot output to same drive that is being dumped!");
2019-05-20 00:12:06 -07:00
// Validate that the required program exists
if (!File.Exists(Parameters.ExecutablePath))
return Result.Failure($"Error! {Parameters.ExecutablePath} does not exist!");
2019-05-20 00:12:06 -07:00
// 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 Tools.GetSupportStatus(System, Type);
2019-05-20 00:12:06 -07:00
}
2021-11-26 14:06:57 -08:00
/// <summary>
/// Validate that DIscImageCreator is able to be found
/// </summary>
/// <returns>True if DiscImageCreator is found properly, false otherwise</returns>
private bool RequiredProgramsExist()
{
// Validate that the path is configured
if (string.IsNullOrWhiteSpace(Options.DiscImageCreatorPath))
return false;
// Validate that the required program exists
if (!File.Exists(Options.DiscImageCreatorPath))
return false;
return true;
}
/// <summary>
/// Run a standalone DiscImageCreator command
/// </summary>
/// <param name="command">Command string to run</param>
/// <returns>The output of the command on success, null on error</returns>
private async Task<string> RunStandaloneDiscImageCreatorCommand(string command)
{
// Validate that DiscImageCreator is all set
if (!RequiredProgramsExist())
return null;
// Validate we're not trying to eject a non-optical
if (Drive.InternalDriveType != InternalDriveType.Optical)
return null;
CancelDumping();
var parameters = new Modules.DiscImageCreator.Parameters(string.Empty)
{
BaseCommand = command,
DriveLetter = Drive.Letter.ToString(),
ExecutablePath = Options.DiscImageCreatorPath,
};
return await ExecuteInternalProgram(parameters);
}
#endregion
}
}