Compare commits

..

67 Commits
1.15 ... 1.16.1

Author SHA1 Message Date
Matt Nadareski
8f3d325e7d Update to version 1.16.1 2020-05-07 15:40:29 -07:00
Matt Nadareski
a63472c6e6 Options (#201)
* Start reorganizing options and internals

* Make entire options flow more robust

* Few more TODOs, slightly cleaner code

* Simplify Options constructor

* Fix eject and reset

* Some other abstractions

* Enforce readonly

* Fix tests, like the TODO said

* Move specific output file parsing to specific parameters

* Add some future enums, add notes around .NET Core build path

* Wrap last incompatible .NET Core stuff

* Extract out CleanRip, fix a bunch of other spaghetti
2020-05-07 14:36:06 -07:00
Matt Nadareski
8c98005605 Fix CleanRip support 2020-05-07 14:23:49 -07:00
Matt Nadareski
8062d6cf17 Extract out CleanRip, fix a bunch of other spaghetti 2020-05-07 13:56:21 -07:00
Matt Nadareski
78bf6e63ed Wrap last incompatible .NET Core stuff 2020-05-07 13:03:24 -07:00
Matt Nadareski
68e0d759f7 Add some future enums, add notes around .NET Core build path 2020-05-07 12:58:37 -07:00
Matt Nadareski
26e72284af Move specific output file parsing to specific parameters 2020-05-06 20:24:33 -07:00
Matt Nadareski
0efecd6601 Fix tests, like the TODO said 2020-05-06 17:00:34 -07:00
Matt Nadareski
9a3c2eb626 Enforce readonly 2020-05-06 16:46:26 -07:00
Matt Nadareski
ca753b4526 Some other abstractions 2020-05-06 16:37:33 -07:00
Matt Nadareski
230b6ca721 Fix eject and reset 2020-05-06 16:06:30 -07:00
Matt Nadareski
dc90f9af3f Simplify Options constructor 2020-05-06 15:56:08 -07:00
Matt Nadareski
b5898c7ea3 Few more TODOs, slightly cleaner code 2020-05-06 15:44:46 -07:00
Matt Nadareski
36f1aea509 Make entire options flow more robust 2020-05-06 15:33:28 -07:00
Matt Nadareski
6742444182 Start reorganizing options and internals 2020-05-06 14:24:37 -07:00
Matt Nadareski
e01fd37e6b Typo 2020-05-05 14:37:34 -07:00
Matt Nadareski
ca7071f82a Update Aaru version for WIP builds 2020-05-05 14:23:23 -07:00
Matt Nadareski
3cb67e3e65 Add Python2 CNF parsing, forgot DumpEnv fixes 2020-05-01 15:02:58 -07:00
Matt Nadareski
e67dd589b5 Fix options, add fallbacks, consolidate code 2020-05-01 14:59:29 -07:00
Matt Nadareski
74f491eaaa Forgot the flag 2020-04-21 17:03:45 -07:00
Matt Nadareski
9ebd28ef5a More dd stuff, including AppVeyor. Why? Because. 2020-04-21 16:09:37 -07:00
Matt Nadareski
2a58052bfd So, I added DD support 2020-04-21 15:52:57 -07:00
Matt Nadareski
5ed73aff2b Mock out the basics needed for DD 2020-04-21 14:39:39 -07:00
Matt Nadareski
5a6ad09004 No DIC firmware check temporarily (fixes https://github.com/SabreTools/DICUI/issues/199) 2020-04-21 11:24:22 -07:00
Matt Nadareski
6a43b74043 Fix file location in AppVeyor builds 2020-04-13 12:17:17 -07:00
Matt Nadareski
69dc91aa1a Update to 1.16 2020-04-13 12:03:58 -07:00
Matt Nadareski
f840db5143 Cleanup and Upgrades (#197)
* First part of cleanup

* Second part of cleanup

* Second part of cleanup, part two

* Second part of cleanup, part three

* Second part of cleanup, part four

* Third part of cleanup

* Fourth part of cleanup (nw)

* Rebranding

* Aaru-fication

* Try to fix .NET Core builds

* Strip out CD Check for false positives

* Update DIC to 20200403

* Add .NET 4.8 to automated builds

* Address a couple of TODOs

* Typo

* Aaru is up to date

* Fix AppVeyor

* Add new systems (fixes #196)

* Fix build

Co-authored-by: Matt Nadareski <mnadareski@mparticle.com>
2020-04-13 11:55:21 -07:00
Matt Nadareski
f33cd41ebb Update BurnOutSharp (fixes #191) 2020-02-18 14:27:44 -08:00
Matt Nadareski
da7896e62a Make it super apparent they're disabled 2020-02-18 11:43:49 -08:00
Matt Nadareski
08b5b4a1aa Condiitionally disable L1 for single-layer discs 2020-02-18 11:34:57 -08:00
Matt Nadareski
c397701818 Better check for submission info write (fixes #190 2020-02-18 11:25:34 -08:00
Matt Nadareski
617eb00f21 Fix PS regex matching (fixes #192) 2020-02-18 11:15:26 -08:00
Matt Nadareski
751fd0cf1e Check PSX.EXE date second (fixes #193) 2020-02-18 11:05:15 -08:00
Matt Nadareski
84c64e6073 Add Chef as Check flag 2020-02-06 23:54:49 -08:00
Matt Nadareski
ff5bc464ab Non-dumping commands shouldn't cause issues 2020-02-04 13:25:50 -08:00
Matt Nadareski
b09a87c7e4 Partial datfile and cuesheet support for Chef 2020-02-04 00:44:12 -08:00
Matt Nadareski
4032b48e63 Calculate start better 2020-02-04 00:41:52 -08:00
Matt Nadareski
12fad35065 Fix Chef flag handling for debug, verbose, and version 2020-02-04 00:20:13 -08:00
Matt Nadareski
c28be2da72 Update Creator version... again 2020-02-04 00:16:19 -08:00
Matt Nadareski
122cc0d20b Support similarly named parameters for DiscImageChef 2020-02-03 14:17:42 -08:00
Matt Nadareski
89db32dd53 Preliminary Support for DiscImageChef (#188)
* Professional cook

* Accuracy improvements

* Better yet

* Spicy

* Simplify and reduce

* You eye note

* More info for validation

* Read you

* Verbose

* Typo

* Custom fix

* Of note

* Clearly the same

* Creator update

* Creator MCN flag gone

* Missed a spot

* Fix issues after code walkthrough
2020-02-03 14:02:24 -08:00
Matt Nadareski
59040ae0f0 Update naming schemes 2020-01-30 14:47:23 -08:00
Matt Nadareski
d8035745a9 Add button to save console output 2020-01-29 13:28:27 -08:00
Matt Nadareski
c73e13c1f0 Update packages, better LibCrypt handling (fixes #134) 2020-01-29 12:21:41 -08:00
Matt Nadareski
af75c7c949 Add .NET Core 3.0 note to README 2020-01-29 10:18:43 -08:00
Matt Nadareski
896eb28308 Upgrade EDC check for PS1 (fixes #148) 2020-01-29 10:17:56 -08:00
Matt Nadareski
6ca3d39e5f Manual protect scan can handle SmartE weirdness 2020-01-28 21:25:26 -08:00
Matt Nadareski
a7af0d0d7b Add P* serials for PlayStation (fixes #187) 2020-01-27 22:38:07 -08:00
Matt Nadareski
04f5a7ea8d Add remote version check (fixes #45) 2020-01-27 22:27:40 -08:00
Matt Nadareski
5d82cc5622 Add option to reset drive after dump (fixes #143) 2020-01-27 13:33:30 -08:00
Matt Nadareski
2f37f51c0c Simplify serial matching for PS1/PS2 (fixes #186) 2020-01-27 11:58:08 -08:00
Matt Nadareski
4690db61e1 Add CleanRip formatting support (fixes #185) 2020-01-27 03:06:11 -08:00
Matt Nadareski
672ec42903 Don't overwrite region if it already exists 2020-01-27 01:38:52 -08:00
Matt Nadareski
cb39599a46 Get region from PS1/2 executable name (fixes #175) 2020-01-27 01:34:39 -08:00
Matt Nadareski
80b5ff3920 Fix options UI, add ignore fixed drives setting (fixes #182) 2020-01-27 00:42:58 -08:00
Matt Nadareski
f27d3a91d3 Fix Check build 2020-01-27 00:04:17 -08:00
Matt Nadareski
b18357bff5 Better eject location 2020-01-27 00:03:03 -08:00
Matt Nadareski
e3cd5b7082 Move eject to before user input (fixes #173) 2020-01-26 23:59:05 -08:00
Matt Nadareski
16d7a6224b Fix drive speed selection (fixes #177) 2020-01-26 23:18:20 -08:00
Matt Nadareski
f8e32ec06c Multi-select language dropdown in submission info (fixes #170) 2020-01-26 23:06:52 -08:00
Matt Nadareski
7073d4e298 Allow testing of credentials from UI (fixes #171) 2020-01-26 22:59:03 -08:00
Matt Nadareski
f7f464920b Fix ampersand tests 2020-01-26 22:45:59 -08:00
Matt Nadareski
e677dc20e9 Add missing default setting 2020-01-26 22:45:46 -08:00
Matt Nadareski
9871eb9928 Save path fixing until the very end (fixes #176) 2020-01-26 22:24:10 -08:00
Matt Nadareski
12b43cf688 Remove ampersand filtering (fixes #180) 2020-01-26 22:06:38 -08:00
Matt Nadareski
7dd6db66ee GD-ROM LD area header extraction 2019-12-23 13:07:23 -08:00
Matt Nadareski
d7726a070e Update to DIC 20191223 2019-12-23 10:28:42 -08:00
51 changed files with 9984 additions and 3976 deletions

View File

@@ -1,3 +1,22 @@
### 1.16.1 (2020-05-07)
- Add preliminary support for DD for Windows (end to end still NW)
- Add CNF parsing for Konami Python 2 discs (PS2-based)
- Updated included Aaru version
- Massive cleanup effort to detangle large chunks of code
- Miscellaneous bugfixes that came from the above
### 1.16 (2020-04-13)
- Updated to DIC version 20200403
- UI updates based on user feedback
- Added support for Aaru (formerly DiscImageChef)
- Added more support for different output file formats (such as CleanRip)
- Add PS1/PS2 serial extraction and matching
- Fix PS1 date support when both PSX.EXE and normal executable are both present
- Update BurnOutSharp
- Many MANY bits of internal cleanup
### 1.15 (2019-11-16)
- Updated to DIC version 20191116

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net462;net472;netcoreapp3.0</TargetFrameworks>
<TargetFrameworks>net462;net472;net48;netcoreapp3.1</TargetFrameworks>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<OutputType>Exe</OutputType>
<Prefer32Bit>true</Prefer32Bit>

View File

@@ -10,24 +10,26 @@ namespace DICUI.Check
public static void Main(string[] args)
{
// Help options
if (args.Length == 0
|| args[0] == "/h" || args[0] == "/?"
|| args[0] == "-h" || args[0] == "-?")
if (args.Length == 0 || args[0] == "-h" || args[0] == "-?")
{
DisplayHelp();
return;
}
// List options
if (args[0] == "/lm" || args[0] == "/listmedia"
|| args[0] == "-lm" || args[0] == "--listmedia")
if (args[0] == "-lm" || args[0] == "--listmedia")
{
ListMediaTypes();
Console.ReadLine();
return;
}
else if (args[0] == "/ls" || args[0] == "/listsystems"
|| args[0] == "-ls" || args[0] == "--listsystems")
else if (args[0] == "-lp" || args[0] == "--listprograms")
{
ListPrograms();
Console.ReadLine();
return;
}
else if (args[0] == "-ls" || args[0] == "--listsystems")
{
ListKnownSystems();
Console.ReadLine();
@@ -39,10 +41,10 @@ namespace DICUI.Check
{
DisplayHelp("Invalid number of arguments");
return;
}
}
// Check the MediaType
var mediaType = Converters.StringToMediaType(args[0].Trim('"'));
var mediaType = Converters.ToMediaType(args[0].Trim('"'));
if (mediaType == MediaType.NONE)
{
DisplayHelp($"{args[0]} is not a recognized media type");
@@ -50,21 +52,49 @@ namespace DICUI.Check
}
// Check the KnownSystem
var knownSystem = Converters.StringToKnownSystem(args[1].Trim('"'));
var knownSystem = Converters.ToKnownSystem(args[1].Trim('"'));
if (knownSystem == KnownSystem.NONE)
{
DisplayHelp($"{args[1]} is not a recognized system");
return;
}
// Check for Redump login credentials
// Check for additional flags
string username = null, password = null;
string internalProgram = "DiscImageCreator";
int startIndex = 2;
if (args[2] == "-c" || args[2] == "--credentials")
for (; startIndex < args.Length; startIndex++)
{
username = args[3];
password = args[4];
startIndex = 5;
// Redump login
if (args[startIndex].StartsWith("-c=") || args[startIndex].StartsWith("--credentials="))
{
string[] credentials = args[startIndex].Split('=')[1].Split(';');
username = credentials[0];
password = credentials[1];
}
else if (args[startIndex] == "-c" || args[startIndex] == "--credentials")
{
username = args[startIndex + 1];
password = args[startIndex + 2];
startIndex += 2;
}
// Use specific program
else if (args[startIndex].StartsWith("-u=") || args[startIndex].StartsWith("--use="))
{
internalProgram = args[startIndex].Split('=')[1];
}
else if (args[startIndex] == "-u" || args[startIndex] == "--use")
{
internalProgram = args[startIndex + 1];
startIndex++;
}
// Default, we fall out
else
{
break;
}
}
// Make a new Progress object
@@ -85,18 +115,18 @@ namespace DICUI.Check
string filepath = Path.GetFullPath(args[i]);
// Now populate an environment
var env = new DumpEnvironment
// TODO: Replace this with Dictionary constructor
var options = new Options
{
OutputDirectory = "",
OutputFilename = filepath,
System = knownSystem,
Type = mediaType,
InternalProgram = internalProgram,
ScanForProtection = false,
PromptForDiscInformation = false,
Username = username,
Password = password,
};
var env = new DumpEnvironment(options, "", filepath, null, knownSystem, mediaType, null);
env.FixOutputPaths();
// Finally, attempt to do the output dance
@@ -115,9 +145,9 @@ namespace DICUI.Check
Console.WriteLine(error);
Console.WriteLine("Usage:");
Console.WriteLine("DICUI.Check.exe <mediatype> <system> [-c username password] </path/to/output.bin> ...");
Console.WriteLine("DICUI.Check.exe <mediatype> <system> [options] </path/to/output.bin> ...");
Console.WriteLine();
Console.WriteLine(@"Common Media Types:\r\n
Console.WriteLine(@"Common Media Types:
bd / bluray - BD-ROM
cd / cdrom - CD-ROM
dvd - DVD-ROM
@@ -126,7 +156,7 @@ gd / gdrom - GD-ROM
umd - UMD");
Console.WriteLine("Run 'DICUI.Check.exe [-lm|--listmedia' for more options");
Console.WriteLine();
Console.WriteLine(@"Common Systems:\r\n
Console.WriteLine(@"Common Systems:
apple / mac - Apple Macintosh
cdi - Philips CD-i
ibm / ibmpc - IBM PC Compatible
@@ -137,6 +167,16 @@ saturn - Sega Saturn
xbox - Microsoft XBOX
x360 - Microsoft XBOX 360");
Console.WriteLine("Run 'DICUI.Check.exe [-ls|--listsystems' for more options");
Console.WriteLine();
Console.WriteLine(@"Common Options:
-c username password - Redump credentials
-u - Set dumping program");
Console.WriteLine();
Console.WriteLine(@"Common Dumping Programs:
cr / cleanrip - CleanRip
dic - DiscImageCreator");
Console.WriteLine("Run 'DICUI.Check.exe [-lp|--listprograms' for more options");
Console.WriteLine();
}
/// <summary>
@@ -154,6 +194,21 @@ x360 - Microsoft XBOX 360");
}
}
/// <summary>
/// List all programs with their short usable names
/// </summary>
private static void ListPrograms()
{
Console.WriteLine("Supported Programs:");
foreach (var val in Enum.GetValues(typeof(InternalProgram)))
{
if (((InternalProgram)val) == InternalProgram.NONE)
continue;
Console.WriteLine($"{((InternalProgram?)val).LongName()}");
}
}
/// <summary>
/// List all known systems with their short usable names
/// </summary>

View File

@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyVersion("1.16.1")]
[assembly: AssemblyFileVersion("1.16.1.0")]

View File

@@ -0,0 +1,455 @@
namespace DICUI.Aaru
{
/// <summary>
/// Top-level commands for Aaru
/// </summary>
public static class CommandStrings
{
// Database Family
public const string DatabasePrefixShort = "db";
public const string DatabasePrefixLong = "database";
public const string DatabaseStats = "stats";
public const string DatabaseUpdate = "update";
// Device Family
public const string DevicePrefixShort = "dev";
public const string DevicePrefixLong = "device";
public const string DeviceInfo = "info";
public const string DeviceList = "list";
public const string DeviceReport = "report";
// Filesystem Family
public const string FilesystemPrefixShort = "fi";
public const string FilesystemPrefixShortAlt = "fs";
public const string FilesystemPrefixLong = "filesystem";
public const string FilesystemExtract = "extract";
public const string FilesystemListShort = "ls";
public const string FilesystemListLong = "list";
public const string FilesystemOptions = "options";
// Image Family
public const string ImagePrefixShort = "i";
public const string ImagePrefixLong = "image";
public const string ImageAnalyze = "analyze";
public const string ImageChecksumShort = "chk";
public const string ImageChecksumLong = "checksum";
public const string ImageCompareShort = "cmp";
public const string ImageCompareLong = "compare";
public const string ImageConvert = "convert";
public const string ImageCreateSidecar = "create-sidecar";
public const string ImageDecode = "decode";
public const string ImageEntropy = "entropy";
public const string ImageInfo = "info";
public const string ImageOptions = "options";
public const string ImagePrint = "print";
public const string ImageVerify = "verify";
// Media Family
public const string MediaPrefixShort = "m";
public const string MediaPrefixLong = "media";
public const string MediaDump = "dump";
public const string MediaInfo = "info";
public const string MediaScan = "scan";
// Standalone Commands
public const string Configure = "configure";
public const string Formats = "formats";
public const string ListEncodings = "list-encodings";
public const string ListNamespaces = "list-namespaces";
public const string Remote = "remote";
}
/// <summary>
/// Supported encodings for Aaru
/// </summary>
public static class EncodingStrings
{
public static string ArabicMac = "x-mac-arabic";
public static string AtariASCII = "atascii";
public static string CentralEuropeanMac = "x-mac-ce";
public static string CommodorePETSCII = "petscii";
public static string CroatianMac = "x-mac-croatian";
public static string CyrillicMac = "x-mac-cryillic";
public static string FarsiMac = "x-mac-farsi";
public static string GreekMac = "x-mac-greek";
public static string HebrewMac = "x-mac-hebrew";
public static string RomanianMac = "x-mac-romanian";
public static string SinclairZXSpectrum = "spectrum";
public static string SinclairZX80 = "zx80";
public static string SinclairZX81 = "zx81";
public static string TurkishMac = "x-mac-turkish";
public static string UkrainianMac = "x-mac-ukrainian";
public static string Unicode = "utf-16";
public static string UnicodeBigEndian = "utf-16BE";
public static string UnicodeUTF32BigEndian = "utf-32BE";
public static string UnicodeUTF32 = "utf-32";
public static string UnicodeUTF7 = "utf-7";
public static string UnicodeUTF8 = "utf-8";
public static string USASCII = "us-ascii";
public static string WesternEuropeanAppleII = "apple2";
public static string WesternEuropeanAppleIIc = "apple2c";
public static string WesternEuropeanAppleIIe = "apple2e";
public static string WesternEuropeanAppleIIgs = "apple2gs";
public static string WesternEuropeanAppleLisa = "lisa";
public static string WesternEuropeanAtariST = "atarist";
public static string WesternEuropeanGEM = "gem";
public static string WesternEuropeanGEOS = "geos";
public static string WesternEuropeanISO = "iso-8859-1";
public static string WesternEuropeanMac = "macintosh";
public static string WesternEuropeanRadix50 = "radix50";
}
/// <summary>
/// Dumping flags for Aaru
/// </summary>
public static class FlagStrings
{
// Boolean flags
public const string Adler32Short = "-a";
public const string Adler32Long = "--adler32";
public const string ClearLong = "--clear";
public const string ClearAllLong = "--clear-all";
public const string CRC16Long = "--crc16";
public const string CRC32Short = "-c";
public const string CRC32Long = "--crc32";
public const string CRC64Long = "--crc64";
public const string DebugShort = "-d";
public const string DebugLong = "--debug";
public const string DiskTagsShort = "-f";
public const string DiskTagsLong = "--disk-tags";
public const string DuplicatedSectorsShort = "-p";
public const string DuplicatedSectorsLong = "--duplicated-sectors";
public const string ExtendedAttributesShort = "-x";
public const string ExtendedAttributesLong = "--xattrs";
public const string FilesystemsShort = "-f";
public const string FilesystemsLong = "--filesystems";
public const string FirstPregapLong = "--first-pregap";
public const string FixOffsetLong = "--fix-offset";
public const string Fletcher16Long = "--fletcher16";
public const string Fletcher32Long = "--fletcher32";
public const string ForceShort = "-f";
public const string ForceLong = "--force";
public const string LongFormatShort = "-l";
public const string LongFormatLong = "--long-format";
public const string LongSectorsShort = "-r";
public const string LongSectorsLong = "--long-sectors";
public const string MD5Short = "-m";
public const string MD5Long = "--md5";
public const string MetadataLong = "--metadata";
public const string PartitionsShort = "-p";
public const string PartitionsLong = "--partitions";
public const string PersistentLong = "--persistent";
public const string ResumeShort = "-r";
public const string ResumeLong = "--resume";
public const string SectorTagsShort = "-p";
public const string SectorTagsLong = "--sector-tags";
public const string SeparatedTracksShort = "-t";
public const string SeparatedTracksLong = "--separated-tracks";
public const string SHA1Short = "-s";
public const string SHA1Long = "--sha1";
public const string SHA256Long = "--sha256";
public const string SHA384Long = "--sha384";
public const string SHA512Long = "--sha512";
public const string SpamSumShort = "-f";
public const string SpamSumLong = "--spamsum";
public const string StopOnErrorShort = "-s";
public const string StopOnErrorLong = "--stop-on-error";
public const string TapeShort = "-t";
public const string TapeLong = "--tape";
public const string TrimLong = "--trim";
public const string VerboseShort = "-v";
public const string VerboseLong = "--verbose";
public const string VerifyDiscShort = "-w";
public const string VerifyDiscLong = "--verify-disc";
public const string VerifySectorsShort = "-s";
public const string VerifySectorsLong = "--verify-sectors";
public const string VersionLong = "--version";
public const string WholeDiscShort = "-w";
public const string WholeDiscLong = "--whole-disc";
// Int8 flags
public const string SpeedLong = "--speed";
// Int16 flags
public const string RetryPassesShort = "-p";
public const string RetryPassesLong = "--retry-passes";
public const string WidthShort = "-w";
public const string WidthLong = "--width";
// Int32 flags
public const string BlockSizeShort = "-b";
public const string BlockSizeLong = "--block-size";
public const string CountShort = "-c";
public const string CountLong = "--count";
public const string MediaLastSequenceLong = "--media-lastsequence";
public const string MediaSequenceLong = "--media-sequence";
public const string SkipShort = "-k";
public const string SkipLong = "--skip";
// Int64 flags
public const string LengthShort = "-l"; // or "all"
public const string LengthLong = "--length"; // or "all"
public const string StartShort = "-s";
public const string StartLong = "--start";
// String flags
public const string CommentsLong = "--comments";
public const string CreatorLong = "--creator";
public const string DriveManufacturerLong = "--drive-manufacturer";
public const string DriveModelLong = "--drive-model";
public const string DriveRevisionLong = "--drive-revision";
public const string DriveSerialLong = "--drive-serial";
public const string EncodingShort = "-e";
public const string EncodingLong = "--encoding";
public const string FormatConvertShort = "-p";
public const string FormatConvertLong = "--format";
public const string FormatDumpShort = "-t";
public const string FormatDumpLong = "--format";
public const string ImgBurnLogShort = "-b";
public const string ImgBurnLogLong = "--ibg-log";
public const string MediaBarcodeLong = "--media-barcode";
public const string MediaManufacturerLong = "--media-manufacturer";
public const string MediaModelLong = "--media-model";
public const string MediaPartNumberLong = "--media-partnumber";
public const string MediaSerialLong = "--media-serial";
public const string MediaTitleLong = "--media-title";
public const string MHDDLogShort = "-m";
public const string MHDDLogLong = "--mhdd-log";
public const string NamespaceShort = "-n";
public const string NamespaceLong = "--namespace";
public const string OptionsShort = "-O";
public const string OptionsLong = "--options";
public const string OutputPrefixShort = "-w";
public const string OutputPrefixLong = "--output-prefix";
public const string ResumeFileShort = "-r";
public const string ResumeFileLong = "--resume-file";
public const string SubchannelLong = "--subchannel";
public const string XMLSidecarShort = "-x";
public const string XMLSidecarLong = "--cicm-xml";
}
/// <summary>
/// Supported formats for Aaru
/// </summary>
public static class FormatStrings
{
// Supported filters
public static string AppleDouble = "AppleDouble";
public static string AppleSingle = "AppleSingle";
public static string BZip2 = "BZip2";
public static string GZip = "GZip";
public static string LZip = "LZip";
public static string MacBinary = "MacBinary";
public static string NoFilter = "No filter";
public static string PCExchange = "PCExchange";
public static string XZ = "XZ";
// Read-only media image formats
public static string AppleDiskArchivalRetrievalTool = "Apple Disk Archival/Retrieval Tool";
public static string AppleNewDiskImageFormat = "Apple New Disk Image Format";
public static string AppleNIB = "Apple NIB";
public static string BlindWrite4 = "BlindWrite 4";
public static string BlindWrite5 = "BlindWrite 5";
public static string CPCEMUDiskFileAndExtendedCPCDiskFile = "CPCEMU Disk-File and Extended CPC Disk-File";
public static string D2FDiskImage = "d2f disk image";
public static string D88DiskImage = "D88 Disk Image";
public static string DIMDiskImage = "DIM Disk Image";
public static string DiscFerret = "DiscFerret";
public static string DiscJuggler = "DiscJuggler";
public static string DreamcastGDIImage = "Dreamcast GDI image";
public static string DunfieldsIMD = "Dunfield's IMD";
public static string HDCopyDiskImage = "HD-Copy disk image";
public static string KryoFluxSTREAM = "KryoFlux STREAM";
public static string MAMECompressedHunksOfData = "MAME Compressed Hunks of Data";
public static string MicrosoftVHDX = "Microsoft VHDX";
public static string NeroBurningROMImage = "Nero Burning ROM image";
public static string PartCloneDiskImage = "PartClone disk image";
public static string PartimageDiskImage = "Partimage disk image";
public static string SpectrumFloppyDiskImage = "Spectrum Floppy Disk Image";
public static string SuperCardPro = "SuperCardPro";
public static string SydexCopyQM = "Sydex CopyQM";
public static string SydexTeleDisk = "Sydex TeleDisk";
// Read/write media image formats
public static string ACTApricotDiskImage = "ACT Apricot Disk Image";
public static string Alcohol120MediaDescriptorStructure = "Alcohol 120% Media Descriptor Structure";
public static string Anex86DiskImage = "Anex86 Disk Image";
public static string Apple2InterleavedDiskImage = "Apple ][Interleaved Disk Image";
public static string Apple2IMG = "Apple 2IMG";
public static string AppleDiskCopy42 = "Apple DiskCopy 4.2";
public static string AppleUniversalDiskImageFormat = "Apple Universal Disk Image Format";
public static string BasicLisaUtility = "Basic Lisa Utility";
public static string CDRDAOTocfile = "CDRDAO tocfile";
public static string CDRWinCuesheet = "CDRWin cuesheet";
public static string CisCopyDiskImageDCFile = "CisCopy Disk Image(DC-File)";
public static string CloneCD = "CloneCD";
public static string CopyTape = "CopyTape";
public static string DigitalResearchDiskCopy = "Digital Research DiskCopy";
public static string AaruFormat = "Aaru format";
public static string IBMSaveDskF = "IBM SaveDskF";
public static string MAXIDiskImage = "MAXI Disk image";
public static string ParallelsDiskImage = "Parallels disk image";
public static string QEMUCopyOnWriteDiskImage = "QEMU Copy-On-Write disk image";
public static string QEMUCopyOnWriteDiskImageV2 = "QEMU Copy-On-Write disk image v2";
public static string QEMUEnhancedDiskImage = "QEMU Enhanced Disk image";
public static string RawDiskImage = "Raw Disk Image";
public static string RayAracheliansDiskIMage = "Ray Arachelian's Disk IMage";
public static string RSIDEHardDiskImage = "RS-IDE Hard Disk Image";
public static string T98HardDiskImage = "T98 Hard Disk Image";
public static string T98NextNHDr0DiskImage = "T98-Next NHD r0 Disk Image";
public static string Virtual98DiskImage = "Virtual98 Disk Image";
public static string VirtualBoxDiskImage = "VirtualBox Disk Image";
public static string VirtualPC = "VirtualPC";
public static string VMwareDiskImage = "VMware disk image";
// Supported filesystems for identification and information only
public static string AcornAdvancedDiscFilingSystem = "Acorn Advanced Disc Filing System";
public static string AlexanderOsipovDOSFileSystem = "Alexander Osipov DOS file system";
public static string AmigaDOSFilesystem = "Amiga DOS filesystem";
public static string AppleFileSystem = "Apple File System";
public static string AppleHFSPlusFilesystem = "Apple HFS+ filesystem";
public static string AppleHierarchicalFileSystem = "Apple Hierarchical File System";
public static string AppleProDOSFilesystem = "Apple ProDOS filesystem";
public static string AtheOSFilesystem = "AtheOS Filesystem";
public static string BeFilesystem = "Be Filesystem";
public static string BSDFastFileSystem = "BSD Fast File System(aka UNIX File System, UFS)";
public static string BTreeFileSystem = "B-tree file system";
public static string CommodoreFileSystem = "Commodore file system";
public static string CramFilesystem = "Cram filesystem";
public static string DumpEightPlugin = "dump(8) Plugin";
public static string ECMA67 = "ECMA-67";
public static string ExtentFileSystemPlugin = "Extent File System Plugin";
public static string F2FSPlugin = "F2FS Plugin";
public static string Files11OnDiskStructure = "Files-11 On-Disk Structure";
public static string FossilFilesystemPlugin = "Fossil Filesystem Plugin";
public static string HAMMERFilesystem = "HAMMER Filesystem";
public static string HighPerformanceOpticalFileSystem = "High Performance Optical File System";
public static string HPLogicalInterchangeFormatPlugin = "HP Logical Interchange Format Plugin";
public static string JFSPlugin = "JFS Plugin";
public static string LinuxExtendedFilesystem = "Linux extended Filesystem";
public static string LinuxExtendedFilesystem234 = "Linux extended Filesystem 2, 3 and 4";
public static string LocusFilesystemPlugin = "Locus Filesystem Plugin";
public static string MicroDOSFileSystem = "MicroDOS file system";
public static string MicrosoftExtendedFileAllocationTable = "Microsoft Extended File Allocation Table";
public static string MinixFilesystem = "Minix Filesystem";
public static string NewTechnologyFileSystem = "New Technology File System(NTFS)";
public static string NILFS2Plugin = "NILFS2 Plugin";
public static string NintendoOpticalFilesystems = "Nintendo optical filesystems";
public static string OS2HighPerformanceFileSystem = "OS/2 High Performance File System";
public static string OS9RandomBlockFilePlugin = "OS-9 Random Block File Plugin";
public static string PCEngineCDPlugin = "PC Engine CD Plugin";
public static string PCFXPlugin = "PC-FX Plugin";
public static string ProfessionalFileSystem = "Professional File System";
public static string QNX4Plugin = "QNX4 Plugin";
public static string QNX6Plugin = "QNX6 Plugin";
public static string ReiserFilesystemPlugin = "Reiser Filesystem Plugin";
public static string Reiser4FilesystemPlugin = "Reiser4 Filesystem Plugin";
public static string ResilientFileSystemPlugin = "Resilient File System plugin";
public static string RT11FileSystem = "RT-11 file system";
public static string SmartFileSystem = "SmartFileSystem";
public static string SolarOSFilesystem = "Solar_OS filesystem";
public static string SquashFilesystem = "Squash filesystem";
public static string UNICOSFilesystemPlugin = "UNICOS Filesystem Plugin";
public static string UniversalDiskFormat = "Universal Disk Format";
public static string UNIXBootFilesystem = "UNIX Boot filesystem";
public static string UNIXSystemVFilesystem = "UNIX System V filesystem";
public static string VeritasFilesystem = "Veritas filesystem";
public static string VMwareFilesystem = "VMware filesystem";
public static string XFSFilesystemPlugin = "XFS Filesystem Plugin";
public static string XiaFilesystem = "Xia filesystem";
public static string ZFSFilesystemPlugin = "ZFS Filesystem Plugin";
// Supported filesystems that can read their contents
public static string AppleDOSFileSystem = "Apple DOS File System";
public static string AppleLisaFileSystem = "Apple Lisa File System";
public static string AppleMacintoshFileSystem = "Apple Macintosh File System";
public static string CPMFileSystem = "CP/M File System";
public static string FATXFilesystemPlugin = "FATX Filesystem Plugin";
public static string ISO9660Filesystem = "ISO9660 Filesystem";
public static string MicrosoftFileAllocationTable = "Microsoft File Allocation Table";
public static string OperaFilesystemPlugin = "Opera Filesystem Plugin";
public static string UCSDPascalFilesystem = "U.C.S.D.Pascal filesystem";
// Supported partitioning schemes
public static string AcornFileCorePartitions = "Acorn FileCore partitions";
public static string ACTApricotPartitions = "ACT Apricot partitions";
public static string AmigaRigidDiskBlock = "Amiga Rigid Disk Block";
public static string ApplePartitionMap = "Apple Partition Map";
public static string AtariPartitions = "Atari partitions";
public static string BSDDisklabel = "BSD disklabel";
public static string DECDisklabel = "DEC disklabel";
public static string DragonFlyBSD64bitDisklabel = "DragonFly BSD 64-bit disklabel";
public static string GUIDPartitionTable = "GUID Partition Table";
public static string Human68kPartitions = "Human 68k partitions";
public static string MasterBootRecord = "Master Boot Record";
public static string NECPC9800PartitionTable = "NEC PC-9800 partition table";
public static string NeXTDisklabel = "NeXT Disklabel";
public static string Plan9PartitionTable = "Plan9 partition table";
public static string RioKarmaPartitioning = "Rio Karma partitioning";
public static string SGIDiskVolumeHeader = "SGI Disk Volume Header";
public static string SunDisklabel = "Sun Disklabel";
public static string UNIXHardwired = "UNIX hardwired";
public static string UNIXVTOC = "UNIX VTOC";
public static string XboxPartitioning = "Xbox partitioning";
public static string XENIX = "XENIX";
}
/// <summary>
/// Supported namespaces for Aaru
/// </summary>
public static class NamespaceStrings
{
// Namespaces for Apple Lisa File System
public static string LisaOfficeSystem = "office";
public static string LisaPascalWorkshop = "workshop";
// Namespaces for ISO9660 Filesystem
public static string JolietVolumeDescriptor = "joliet";
public static string PrimaryVolumeDescriptor = "normal";
public static string PrimaryVolumeDescriptorwithEncoding = "romeo";
public static string RockRidge = "rrip";
public static string PrimaryVolumeDescriptorVersionSuffix = "vms";
// Namespaces for Microsoft File Allocation Table
public static string DOS = "dos";
public static string LFNWhenAvailable = "ecs";
public static string LongFileNames = "lfn";
public static string WindowsNT = "nt";
public static string OS2Extended = "os2";
}
/// <summary>
/// Supported options for Aaru
/// </summary>
public static class OptionStrings
{
// ACT Apricot Disk Image
public static string ACTApricotDiskImageCompress = "compress"; // boolean, default false
// Apple DiskCopy 4.2
public static string AppleDiskCopyMacOSX = "macosx"; // boolean, default false
// CDRDAO tocfile
public static string CDRDAOTocfileSeparate = "separate"; // boolean, default false
// CDRWin cuesheet
public static string CDRWinCuesheetSeparate = "separate"; // boolean, default false
// Aaru format
public static string AaruDeduplicate = "deduplicate"; // boolean, default true
public static string AaruDictionary = "dictionary"; // number, default 33554432
public static string AaruMaxDDTSize = "max_ddt_size"; // number, default 256
public static string AaruMD5 = "md5"; // boolean, default false
public static string AaruNoCompress = "nocompress"; // boolean, default false
public static string AaruSectorsPerBlock = "sectors_per_block"; // number, default 4096
public static string AaruSHA1 = "sha1"; // boolean, default false
public static string AaruSHA256 = "sha256"; // boolean, default false
public static string AaruSpamSum = "spamsum"; // boolean, default false
// VMware disk image
public static string VMwareDiskImageAdapterType = "adapter_type"; // string, default ide
public static string VMwareDiskImageHWVersion = "hwversion"; // number, default 4
public static string VMwareDiskImageSparse = "sparse"; // boolean, default false
public static string VMwareDiskImageSplit = "split"; // boolean, default false
}
}

View File

@@ -0,0 +1,406 @@
using DICUI.Data;
namespace DICUI.Aaru
{
public static class Converters
{
#region Cross-enumeration conversions
/// <summary>
/// Get the default extension for a given disc type
/// </summary>
/// <param name="type">MediaType value to check</param>
/// <returns>Valid extension (with leading '.'), null on error</returns>
public static string Extension(MediaType? type)
{
// Aaru has a single, unified output format by default
return ".aif";
}
#endregion
#region Convert to Long Name
/// <summary>
/// Get the string representation of the Command enum values
/// </summary>
/// <param name="command">Command value to convert</param>
/// <returns>String representing the value, if possible</returns>
public static string LongName(Command command)
{
switch (command)
{
// Database Family
case Command.DatabaseStats:
return $"{CommandStrings.DatabasePrefixLong} {CommandStrings.DatabaseStats}";
case Command.DatabaseUpdate:
return $"{CommandStrings.DatabasePrefixLong} {CommandStrings.DatabaseUpdate}";
// Device Family
case Command.DeviceInfo:
return $"{CommandStrings.DevicePrefixLong} {CommandStrings.DeviceInfo}";
case Command.DeviceList:
return $"{CommandStrings.DevicePrefixLong} {CommandStrings.DeviceList}";
case Command.DeviceReport:
return $"{CommandStrings.DevicePrefixLong} {CommandStrings.DeviceReport}";
// Filesystem Family
case Command.FilesystemExtract:
return $"{CommandStrings.FilesystemPrefixLong} {CommandStrings.FilesystemExtract}";
case Command.FilesystemList:
return $"{CommandStrings.FilesystemPrefixLong} {CommandStrings.FilesystemListLong}";
case Command.FilesystemOptions:
return $"{CommandStrings.FilesystemPrefixLong} {CommandStrings.FilesystemOptions}";
// Image Family
case Command.ImageAnalyze:
return $"{CommandStrings.ImagePrefixLong} {CommandStrings.ImageAnalyze}";
case Command.ImageChecksum:
return $"{CommandStrings.ImagePrefixLong} {CommandStrings.ImageChecksumLong}";
case Command.ImageCompare:
return $"{CommandStrings.ImagePrefixLong} {CommandStrings.ImageCompareLong}";
case Command.ImageConvert:
return $"{CommandStrings.ImagePrefixLong} {CommandStrings.ImageConvert}";
case Command.ImageCreateSidecar:
return $"{CommandStrings.ImagePrefixLong} {CommandStrings.ImageCreateSidecar}";
case Command.ImageDecode:
return $"{CommandStrings.ImagePrefixLong} {CommandStrings.ImageDecode}";
case Command.ImageEntropy:
return $"{CommandStrings.ImagePrefixLong} {CommandStrings.ImageEntropy}";
case Command.ImageInfo:
return $"{CommandStrings.ImagePrefixLong} {CommandStrings.ImageInfo}";
case Command.ImageOptions:
return $"{CommandStrings.ImagePrefixLong} {CommandStrings.ImageOptions}";
case Command.ImagePrint:
return $"{CommandStrings.ImagePrefixLong} {CommandStrings.ImagePrint}";
case Command.ImageVerify:
return $"{CommandStrings.ImagePrefixLong} {CommandStrings.ImageVerify}";
// Media Family
case Command.MediaDump:
return $"{CommandStrings.MediaPrefixLong} {CommandStrings.MediaDump}";
case Command.MediaInfo:
return $"{CommandStrings.MediaPrefixLong} {CommandStrings.MediaInfo}";
case Command.MediaScan:
return $"{CommandStrings.MediaPrefixLong} {CommandStrings.MediaScan}";
// Standalone Commands
case Command.Configure:
return CommandStrings.Configure;
case Command.Formats:
return CommandStrings.Formats;
case Command.ListEncodings:
return CommandStrings.ListEncodings;
case Command.ListNamespaces:
return CommandStrings.ListNamespaces;
case Command.Remote:
return CommandStrings.Remote;
case Command.NONE:
default:
return "";
}
}
/// <summary>
/// Get the string representation of the Flag enum values
/// </summary>
/// <param name="command">Flag value to convert</param>
/// <returns>String representing the value, if possible</returns>
public static string LongName(Flag flag)
{
switch (flag)
{
// Boolean flags
case Flag.Adler32:
return FlagStrings.Adler32Long;
case Flag.Clear:
return FlagStrings.ClearLong;
case Flag.ClearAll:
return FlagStrings.ClearAllLong;
case Flag.CRC16:
return FlagStrings.CRC16Long;
case Flag.CRC32:
return FlagStrings.CRC32Long;
case Flag.CRC64:
return FlagStrings.CRC64Long;
case Flag.Debug:
return FlagStrings.DebugLong;
case Flag.DiskTags:
return FlagStrings.DiskTagsLong;
case Flag.DuplicatedSectors:
return FlagStrings.DuplicatedSectorsLong;
case Flag.ExtendedAttributes:
return FlagStrings.ExtendedAttributesLong;
case Flag.Filesystems:
return FlagStrings.FilesystemsLong;
case Flag.FirstPregap:
return FlagStrings.FirstPregapLong;
case Flag.FixOffset:
return FlagStrings.FixOffsetLong;
case Flag.Fletcher16:
return FlagStrings.Fletcher16Long;
case Flag.Fletcher32:
return FlagStrings.Fletcher32Long;
case Flag.Force:
return FlagStrings.ForceLong;
case Flag.LongFormat:
return FlagStrings.LongFormatLong;
case Flag.LongSectors:
return FlagStrings.LongSectorsLong;
case Flag.MD5:
return FlagStrings.MD5Long;
case Flag.Metadata:
return FlagStrings.MetadataLong;
case Flag.Partitions:
return FlagStrings.PartitionsLong;
case Flag.Persistent:
return FlagStrings.PersistentLong;
case Flag.Resume:
return FlagStrings.ResumeLong;
case Flag.SectorTags:
return FlagStrings.SectorTagsLong;
case Flag.SeparatedTracks:
return FlagStrings.SeparatedTracksLong;
case Flag.SHA1:
return FlagStrings.SHA1Long;
case Flag.SHA256:
return FlagStrings.SHA256Long;
case Flag.SHA384:
return FlagStrings.SHA384Long;
case Flag.SHA512:
return FlagStrings.SHA512Long;
case Flag.SpamSum:
return FlagStrings.SpamSumLong;
case Flag.StopOnError:
return FlagStrings.StopOnErrorLong;
case Flag.Tape:
return FlagStrings.TapeLong;
case Flag.Trim:
return FlagStrings.TrimLong;
case Flag.Verbose:
return FlagStrings.VerboseLong;
case Flag.VerifyDisc:
return FlagStrings.VerifyDiscLong;
case Flag.VerifySectors:
return FlagStrings.VerifySectorsLong;
case Flag.Version:
return FlagStrings.VersionLong;
case Flag.WholeDisc:
return FlagStrings.WholeDiscLong;
// Int8 flags
case Flag.Speed:
return FlagStrings.SpeedLong;
// Int16 flags
case Flag.RetryPasses:
return FlagStrings.RetryPassesLong;
case Flag.Width:
return FlagStrings.WidthLong;
// Int32 flags
case Flag.BlockSize:
return FlagStrings.BlockSizeLong;
case Flag.Count:
return FlagStrings.CountLong;
case Flag.MediaLastSequence:
return FlagStrings.MediaLastSequenceLong;
case Flag.MediaSequence:
return FlagStrings.MediaSequenceLong;
case Flag.Skip:
return FlagStrings.SkipLong;
// Int64 flags
case Flag.Length:
return FlagStrings.LengthLong;
case Flag.Start:
return FlagStrings.StartLong;
// String flags
case Flag.Comments:
return FlagStrings.CommentsLong;
case Flag.Creator:
return FlagStrings.CreatorLong;
case Flag.DriveManufacturer:
return FlagStrings.DriveManufacturerLong;
case Flag.DriveModel:
return FlagStrings.DriveModelLong;
case Flag.DriveRevision:
return FlagStrings.DriveRevisionLong;
case Flag.DriveSerial:
return FlagStrings.DriveSerialLong;
case Flag.Encoding:
return FlagStrings.EncodingLong;
case Flag.FormatConvert:
return FlagStrings.FormatConvertLong;
case Flag.FormatDump:
return FlagStrings.FormatDumpLong;
case Flag.ImgBurnLog:
return FlagStrings.ImgBurnLogLong;
case Flag.MediaBarcode:
return FlagStrings.MediaBarcodeLong;
case Flag.MediaManufacturer:
return FlagStrings.MediaManufacturerLong;
case Flag.MediaModel:
return FlagStrings.MediaModelLong;
case Flag.MediaPartNumber:
return FlagStrings.MediaPartNumberLong;
case Flag.MediaSerial:
return FlagStrings.MediaSerialLong;
case Flag.MediaTitle:
return FlagStrings.MediaTitleLong;
case Flag.MHDDLog:
return FlagStrings.MHDDLogLong;
case Flag.Namespace:
return FlagStrings.NamespaceLong;
case Flag.Options:
return FlagStrings.OptionsLong;
case Flag.OutputPrefix:
return FlagStrings.OutputPrefixLong;
case Flag.ResumeFile:
return FlagStrings.ResumeFileLong;
case Flag.Subchannel:
return FlagStrings.SubchannelLong;
case Flag.XMLSidecar:
return FlagStrings.XMLSidecarLong;
case Flag.NONE:
default:
return "";
}
}
#endregion
#region Convert From String
/// <summary>
/// Get the Command enum value for a given string
/// </summary>
/// <param name="commandOne">First part of String value to convert</param>
/// <param name="commandTwo">Second part of String value to convert</param>
/// <param name="useSecond">Output bool if the second command was used</param>
/// <returns>Command represented by the string(s), if possible</returns>
public static Command StringToCommand(string commandOne, string commandTwo, out bool useSecond)
{
useSecond = false;
switch (commandOne)
{
// Database Family
case CommandStrings.DatabasePrefixShort:
case CommandStrings.DatabasePrefixLong:
useSecond = true;
switch (commandTwo)
{
case CommandStrings.DatabaseStats:
return Command.DatabaseStats;
case CommandStrings.DatabaseUpdate:
return Command.DatabaseUpdate;
}
break;
// Device Family
case CommandStrings.DevicePrefixShort:
case CommandStrings.DevicePrefixLong:
useSecond = true;
switch (commandTwo)
{
case CommandStrings.DeviceInfo:
return Command.DeviceInfo;
case CommandStrings.DeviceList:
return Command.DeviceList;
case CommandStrings.DeviceReport:
return Command.DeviceReport;
}
break;
// Filesystem Family
case CommandStrings.FilesystemPrefixShort:
case CommandStrings.FilesystemPrefixShortAlt:
case CommandStrings.FilesystemPrefixLong:
useSecond = true;
switch (commandTwo)
{
case CommandStrings.FilesystemExtract:
return Command.FilesystemExtract;
case CommandStrings.FilesystemListShort:
case CommandStrings.FilesystemListLong:
return Command.FilesystemList;
case CommandStrings.DatabaseStats:
return Command.FilesystemOptions;
}
break;
// Image Family
case CommandStrings.ImagePrefixShort:
case CommandStrings.ImagePrefixLong:
useSecond = true;
switch (commandTwo)
{
case CommandStrings.ImageAnalyze:
return Command.ImageAnalyze;
case CommandStrings.ImageChecksumShort:
case CommandStrings.ImageChecksumLong:
return Command.ImageChecksum;
case CommandStrings.ImageCompareShort:
case CommandStrings.ImageCompareLong:
return Command.ImageCompare;
case CommandStrings.ImageConvert:
return Command.ImageConvert;
case CommandStrings.ImageCreateSidecar:
return Command.ImageCreateSidecar;
case CommandStrings.ImageDecode:
return Command.ImageDecode;
case CommandStrings.ImageEntropy:
return Command.ImageEntropy;
case CommandStrings.ImageInfo:
return Command.ImageInfo;
case CommandStrings.ImageOptions:
return Command.ImageOptions;
case CommandStrings.ImagePrint:
return Command.ImagePrint;
case CommandStrings.ImageVerify:
return Command.ImageVerify;
}
break;
// Media Family
case CommandStrings.MediaPrefixShort:
case CommandStrings.MediaPrefixLong:
useSecond = true;
switch (commandTwo)
{
case CommandStrings.MediaDump:
return Command.MediaDump;
case CommandStrings.MediaInfo:
return Command.MediaInfo;
case CommandStrings.MediaScan:
return Command.MediaScan;
}
break;
// Standalone Commands
case CommandStrings.Configure:
return Command.Configure;
case CommandStrings.Formats:
return Command.Formats;
case CommandStrings.ListEncodings:
return Command.ListEncodings;
case CommandStrings.ListNamespaces:
return Command.ListNamespaces;
case CommandStrings.Remote:
return Command.Remote;
}
return Command.NONE;
}
#endregion
}
}

View File

@@ -0,0 +1,140 @@
namespace DICUI.Aaru
{
/// <summary>
/// Supported Aaru commands
/// </summary>
public enum Command : int
{
NONE = 0,
// Database Family
DatabaseStats,
DatabaseUpdate,
// Device Family
DeviceInfo,
DeviceList,
DeviceReport,
// Filesystem Family
FilesystemExtract,
FilesystemList,
FilesystemOptions,
// Image Family
ImageAnalyze,
ImageChecksum,
ImageCompare,
ImageConvert,
ImageCreateSidecar,
ImageDecode,
ImageEntropy,
ImageInfo,
ImageOptions,
ImagePrint,
ImageVerify,
// Media Family
MediaDump,
MediaInfo,
MediaScan,
// Standalone Commands
Configure,
Formats,
ListEncodings,
ListNamespaces,
Remote,
}
/// <summary>
/// Supported Aaru flags
/// </summary>
public enum Flag : int
{
NONE = 0,
// Boolean flags
Adler32,
Clear,
ClearAll,
CRC16,
CRC32,
CRC64,
Debug,
DiskTags,
DuplicatedSectors,
ExtendedAttributes,
Filesystems,
FirstPregap,
FixOffset,
Fletcher16,
Fletcher32,
Force,
LongFormat,
LongSectors,
MD5,
Metadata,
Partitions,
Persistent,
Resume,
SectorTags,
SeparatedTracks,
SHA1,
SHA256,
SHA384,
SHA512,
SpamSum,
StopOnError,
Tape,
Trim,
Verbose,
VerifyDisc,
VerifySectors,
Version,
WholeDisc,
// Int8 flags
Speed,
// Int16 flags
RetryPasses,
Width,
// Int32 flags
BlockSize,
Count,
MediaLastSequence,
MediaSequence,
Skip,
// Int64 flags
Length,
Start,
// String flags
Comments,
Creator,
DriveManufacturer,
DriveModel,
DriveRevision,
DriveSerial,
Encoding,
FormatConvert,
FormatDump,
ImgBurnLog,
MediaBarcode,
MediaManufacturer,
MediaModel,
MediaPartNumber,
MediaSerial,
MediaTitle,
MHDDLog,
Namespace,
Options,
OutputPrefix,
ResumeFile,
Subchannel,
XMLSidecar,
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,319 @@
using System.IO;
using DICUI.Data;
using DICUI.Utilities;
namespace DICUI.CleanRip
{
/// <summary>
/// Represents a generic set of CleanRip parameters
/// </summary>
public class Parameters : BaseParameters
{
/// <summary>
/// Populate a Parameters object from a param string
/// </summary>
/// <param name="parameters">String possibly representing a set of parameters</param>
public Parameters(string parameters)
: base(parameters)
{
this.InternalProgram = InternalProgram.CleanRip;
}
/// <summary>
/// Generate parameters based on a set of known inputs
/// </summary>
/// <param name="system">KnownSystem value to use</param>
/// <param name="type">MediaType value to use</param>
/// <param name="driveLetter">Drive letter to use</param>
/// <param name="filename">Filename to use</param>
/// <param name="driveSpeed">Drive speed to use</param>
/// <param name="paranoid">Enable paranoid mode (safer dumping)</param>
/// <param name="quietMode">Enable quiet mode (no beeps)</param>
/// <param name="retryCount">User-defined reread count</param>
public Parameters(KnownSystem? system, MediaType? type, char driveLetter, string filename, int? driveSpeed, bool paranoid, bool quietMode, int retryCount)
: base(system, type, driveLetter, filename, driveSpeed, paranoid, quietMode, retryCount)
{
}
/// <summary>
/// Blindly generate a parameter string based on the inputs
/// </summary>
/// <returns>Correctly formatted parameter string, null on error</returns>
public override string GenerateParameters() => null;
/// <summary>
/// Get the input path from the implementation
/// </summary>
/// <returns>String representing the path, null on error</returns>
public override string InputPath() => null;
/// <summary>
/// Get the output path from the implementation
/// </summary>
/// <returns>String representing the path, null on error</returns>
public override string OutputPath() => null;
/// <summary>
/// Get the processing speed from the implementation
/// </summary>
/// <returns>int? representing the speed, null on error</returns>
public override int? GetSpeed() => null;
/// <summary>
/// Set the processing speed int the implementation
/// </summary>
/// <param name="speed">int? representing the speed</param>
public override void SetSpeed(int? speed) { }
/// <summary>
/// Get the MediaType from the current set of parameters
/// </summary>
/// <returns>MediaType value if successful, null on error</returns>
public override MediaType? GetMediaType() => null;
/// <summary>
/// Gets if the current command is considered a dumping command or not
/// </summary>
/// <returns>True if it's a dumping command, false otherwise</returns>
public override bool IsDumpingCommand() => true;
/// <summary>
/// Reset all special variables to have default values
/// </summary>
protected override void ResetValues() { }
/// <summary>
/// Set default parameters for a given system and media type
/// </summary>
/// <param name="system">KnownSystem value to use</param>
/// <param name="type">MediaType value to use</param>
/// <param name="driveLetter">Drive letter to use</param>
/// <param name="filename">Filename to use</param>
/// <param name="driveSpeed">Drive speed to use</param>
/// <param name="paranoid">Enable paranoid mode (safer dumping)</param>
/// <param name="retryCount">User-defined reread count</param>
protected override void SetDefaultParameters(
KnownSystem? system,
MediaType? type,
char driveLetter,
string filename,
int? driveSpeed,
bool paranoid,
int retryCount)
{
}
/// <summary>
/// Scan a possible parameter string and populate whatever possible
/// </summary>
/// <param name="parameters">String possibly representing parameters</param>
/// <returns></returns>
protected override bool ValidateAndSetParameters(string parameters) => true;
/// <summary>
/// Validate if all required output files exist
/// </summary>
/// <param name="basePath">Base filename and path to use for checking</param>
/// <param name="system">KnownSystem type representing the media</param>
/// <param name="type">MediaType type representing the media</param>
/// <returns></returns>
public override bool CheckAllOutputFilesExist(string basePath, KnownSystem? system, MediaType? type)
{
switch (type)
{
case MediaType.NintendoGameCubeGameDisc:
case MediaType.NintendoWiiOpticalDisc:
return File.Exists(basePath + "-dumpinfo.txt")
&& File.Exists(basePath + ".bca");
default:
return false;
}
}
/// <summary>
/// Generate a SubmissionInfo for the output files
/// </summary>
/// <param name="info">Base submission info to fill in specifics for</param>
/// <param name="basePath">Base filename and path to use for checking</param>
/// <param name="system">KnownSystem type representing the media</param>
/// <param name="type">MediaType type representing the media</param>
/// <param name="drive">Drive representing the disc to get information from</param>
/// <returns></returns>
public override void GenerateSubmissionInfo(SubmissionInfo info, string basePath, KnownSystem? system, MediaType? type, Drive drive)
{
info.TracksAndWriteOffsets.ClrMameProData = GetCleanripDatfile(basePath + ".iso", basePath + "-dumpinfo.txt");
// Extract info based generically on MediaType
switch (type)
{
case MediaType.NintendoGameCubeGameDisc:
case MediaType.NintendoWiiOpticalDisc:
if (File.Exists(basePath + ".bca"))
info.Extras.BCA = GetFullFile(basePath + ".bca", true);
if (GetGameCubeWiiInformation(basePath + "-dumpinfo.txt", out Region? gcRegion, out string gcVersion))
{
info.CommonDiscInfo.Region = info.CommonDiscInfo.Region ?? gcRegion;
info.VersionAndEditions.Version = string.IsNullOrEmpty(info.VersionAndEditions.Version) ? gcVersion : info.VersionAndEditions.Version;
}
break;
}
}
#region Information Extraction Methods
/// <summary>
/// Get a formatted datfile from the cleanrip output, if possible
/// </summary>
/// <param name="iso">Path to ISO file</param>
/// <param name="dumpinfo">Path to discinfo file</param>
/// <returns></returns>
private string GetCleanripDatfile(string iso, string dumpinfo)
{
// If the file doesn't exist, we can't get info from it
if (!File.Exists(dumpinfo))
return null;
using (StreamReader sr = File.OpenText(dumpinfo))
{
long size = new FileInfo(iso).Length;
string crc = string.Empty;
string md5 = string.Empty;
string sha1 = string.Empty;
try
{
// Make sure this file is a dumpinfo
if (!sr.ReadLine().Contains("--File Generated by CleanRip"))
return null;
// Read all lines and gather dat information
while (!sr.EndOfStream)
{
string line = sr.ReadLine().Trim();
if (line.StartsWith("CRC32"))
crc = line.Substring(7).ToLowerInvariant();
else if (line.StartsWith("MD5"))
md5 = line.Substring(5);
else if (line.StartsWith("SHA-1"))
sha1 = line.Substring(7);
}
return $"<rom name=\"{Path.GetFileName(iso)}\" size=\"{size}\" crc=\"{crc}\" md5=\"{md5}\" sha1=\"{sha1}\" />";
}
catch
{
// We don't care what the exception is right now
return null;
}
}
}
/// <summary>
/// Get the extracted GC and Wii version
/// </summary>
/// <param name="dumpinfo">Path to discinfo file</param>
/// <param name="region">Output region, if possible</param>
/// <param name="version">Output internal version of the game</param>
/// <returns></returns>
private bool GetGameCubeWiiInformation(string dumpinfo, out Region? region, out string version)
{
region = null; version = null;
// If the file doesn't exist, we can't get info from it
if (!File.Exists(dumpinfo))
return false;
using (StreamReader sr = File.OpenText(dumpinfo))
{
try
{
// Make sure this file is a dumpinfo
if (!sr.ReadLine().Contains("--File Generated by CleanRip"))
return false;
// Read all lines and gather dat information
while (!sr.EndOfStream)
{
string line = sr.ReadLine().Trim();
if (line.StartsWith("Version"))
{
version = line.Substring(9);
}
else if (line.StartsWith("Filename"))
{
string serial = line.Substring(10);
// char gameType = serial[0];
// string gameid = serial[1] + serial[2];
// string version = serial[4] + serial[5]
switch (serial[3])
{
case 'A':
region = Region.World;
break;
case 'D':
region = Region.Germany;
break;
case 'E':
region = Region.USA;
break;
case 'F':
region = Region.France;
break;
case 'I':
region = Region.Italy;
break;
case 'J':
region = Region.Japan;
break;
case 'K':
region = Region.Korea;
break;
case 'L':
region = Region.Europe; // Japanese import to Europe
break;
case 'M':
region = Region.Europe; // American import to Europe
break;
case 'N':
region = Region.USA; // Japanese import to USA
break;
case 'P':
region = Region.Europe;
break;
case 'R':
region = Region.Russia;
break;
case 'S':
region = Region.Spain;
break;
case 'Q':
region = Region.Korea; // Korea with Japanese language
break;
case 'T':
region = Region.Korea; // Korea with English language
break;
case 'X':
region = null; // Not a real region code
break;
}
}
}
return true;
}
catch
{
// We don't care what the exception is right now
return false;
}
}
}
#endregion
}
}

View File

@@ -0,0 +1,31 @@
namespace DICUI.DD
{
/// <summary>
/// Top-level commands for DD
/// </summary>
public static class CommandStrings
{
public const string List = "--list";
}
/// <summary>
/// Dumping flags for DD
/// </summary>
public static class FlagStrings
{
// Boolean flags
public const string Progress = "--progress";
public const string Size = "--size";
// Int64 flags
public const string BlockSize = "bs";
public const string Count = "count";
public const string Seek = "seek";
public const string Skip = "skip";
// String flags
public const string Filter = "--filter";
public const string InputFile = "if";
public const string OutputFile = "of";
}
}

View File

@@ -0,0 +1,104 @@
using DICUI.Data;
namespace DICUI.DD
{
public static class Converters
{
#region Cross-enumeration conversions
/// <summary>
/// Get the default extension for a given disc type
/// </summary>
/// <param name="type">MediaType value to check</param>
/// <returns>Valid extension (with leading '.'), null on error</returns>
public static string Extension(MediaType? type)
{
// DD has a single, unified output format by default
return ".bin";
}
#endregion
#region Convert to Long Name
/// <summary>
/// Get the string representation of the Command enum values
/// </summary>
/// <param name="command">Command value to convert</param>
/// <returns>String representing the value, if possible</returns>
public static string LongName(Command command)
{
switch (command)
{
case Command.List:
return CommandStrings.List;
case Command.NONE:
default:
return "";
}
}
/// <summary>
/// Get the string representation of the Flag enum values
/// </summary>
/// <param name="command">Flag value to convert</param>
/// <returns>String representing the value, if possible</returns>
public static string LongName(Flag flag)
{
switch (flag)
{
// Boolean flags
case Flag.Progress:
return FlagStrings.Progress;
case Flag.Size:
return FlagStrings.Size;
// Int64 flags
case Flag.BlockSize:
return FlagStrings.BlockSize;
case Flag.Count:
return FlagStrings.Count;
case Flag.Seek:
return FlagStrings.Seek;
case Flag.Skip:
return FlagStrings.Skip;
// String flags
case Flag.Filter:
return FlagStrings.Filter;
case Flag.InputFile:
return FlagStrings.InputFile;
case Flag.OutputFile:
return FlagStrings.OutputFile;
case Flag.NONE:
default:
return "";
}
}
#endregion
#region Convert From String
/// <summary>
/// Get the Command enum value for a given string
/// </summary>
/// <param name="command">String value to convert</param>
/// <returns>Command represented by the string(s), if possible</returns>
public static Command StringToCommand(string command)
{
switch (command)
{
case CommandStrings.List:
return Command.List;
default:
return Command.NONE;
}
}
#endregion
}
}

View File

@@ -0,0 +1,34 @@
namespace DICUI.DD
{
/// <summary>
/// Supported DD commands
/// </summary>
public enum Command: int
{
NONE = 0, // For DD, this represents a normal dump
List,
}
/// <summary>
/// Supported DD flags
/// </summary>
public enum Flag : int
{
NONE = 0,
// Boolean flags
Progress,
Size,
// Int64 flags
BlockSize,
Count,
Seek,
Skip,
// String flags
Filter,
InputFile,
OutputFile,
}
}

View File

@@ -0,0 +1,620 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using DICUI.Data;
using DICUI.Utilities;
namespace DICUI.DD
{
/// <summary>
/// Represents a generic set of DD parameters
/// </summary>
public class Parameters : BaseParameters
{
/// <summary>
/// Base command to run
/// </summary>
public Command BaseCommand { get; set; }
/// <summary>
/// Set of flags to pass to the executable
/// </summary>
protected Dictionary<Flag, bool?> _flags = new Dictionary<Flag, bool?>();
public bool? this[Flag key]
{
get
{
if (_flags.ContainsKey(key))
return _flags[key];
return null;
}
set
{
_flags[key] = value;
}
}
protected internal IEnumerable<Flag> Keys => _flags.Keys;
#region Flag Values
public long? BlockSizeValue { get; set; }
public long? CountValue { get; set; }
// fixed, removable, disk, partition
public string FilterValue { get; set; }
public string InputFileValue { get; set; }
public string OutputFileValue { get; set; }
public long? SeekValue { get; set; }
public long? SkipValue { get; set; }
#endregion
/// <summary>
/// Populate a Parameters object from a param string
/// </summary>
/// <param name="parameters">String possibly representing a set of parameters</param>
public Parameters(string parameters)
: base(parameters)
{
this.InternalProgram = InternalProgram.DD;
}
/// <summary>
/// Generate parameters based on a set of known inputs
/// </summary>
/// <param name="system">KnownSystem value to use</param>
/// <param name="type">MediaType value to use</param>
/// <param name="driveLetter">Drive letter to use</param>
/// <param name="filename">Filename to use</param>
/// <param name="driveSpeed">Drive speed to use</param>
/// <param name="paranoid">Enable paranoid mode (safer dumping)</param>
/// <param name="quietMode">Enable quiet mode (no beeps)</param>
/// <param name="retryCount">User-defined reread count</param>
public Parameters(KnownSystem? system, MediaType? type, char driveLetter, string filename, int? driveSpeed, bool paranoid, bool quietMode, int retryCount)
: base(system, type, driveLetter, filename, driveSpeed, paranoid, quietMode, retryCount)
{
}
/// <summary>
/// Blindly generate a parameter string based on the inputs
/// </summary>
/// <returns>Correctly formatted parameter string, null on error</returns>
public override string GenerateParameters()
{
List<string> parameters = new List<string>();
if (BaseCommand != Command.NONE)
parameters.Add(Converters.LongName(BaseCommand));
#region Boolean flags
// Progress
if (GetSupportedCommands(Flag.Progress).Contains(BaseCommand))
{
if (this[Flag.Progress] == true)
parameters.Add($"{this[Flag.Progress]}");
}
// Size
if (GetSupportedCommands(Flag.Size).Contains(BaseCommand))
{
if (this[Flag.Size] == true)
parameters.Add($"{this[Flag.Size]}");
}
#endregion
#region Int64 flags
// Block Size
if (GetSupportedCommands(Flag.BlockSize).Contains(BaseCommand))
{
if (this[Flag.BlockSize] == true && BlockSizeValue != null)
parameters.Add($"{Converters.LongName(Flag.BlockSize)}={BlockSizeValue}");
}
// Count
if (GetSupportedCommands(Flag.Count).Contains(BaseCommand))
{
if (this[Flag.Count] == true && CountValue != null)
parameters.Add($"{Converters.LongName(Flag.Count)}={CountValue}");
}
// Seek
if (GetSupportedCommands(Flag.Seek).Contains(BaseCommand))
{
if (this[Flag.Seek] == true && SeekValue != null)
parameters.Add($"{Converters.LongName(Flag.Seek)}={SeekValue}");
}
// Skip
if (GetSupportedCommands(Flag.Skip).Contains(BaseCommand))
{
if (this[Flag.Skip] == true && SkipValue != null)
parameters.Add($"{Converters.LongName(Flag.Skip)}={SkipValue}");
}
#endregion
#region String flags
// Filter
if (GetSupportedCommands(Flag.Filter).Contains(BaseCommand))
{
if (this[Flag.Filter] == true && FilterValue != null)
parameters.Add($"{Converters.LongName(Flag.Filter)}={FilterValue}");
}
// Input File
if (GetSupportedCommands(Flag.InputFile).Contains(BaseCommand))
{
if (this[Flag.InputFile] == true && InputFileValue != null)
parameters.Add($"{Converters.LongName(Flag.InputFile)}={InputFileValue}");
else
return null;
}
// Output File
if (GetSupportedCommands(Flag.OutputFile).Contains(BaseCommand))
{
if (this[Flag.OutputFile] == true && OutputFileValue != null)
parameters.Add($"{Converters.LongName(Flag.OutputFile)}={OutputFileValue}");
else
return null;
}
#endregion
return string.Empty;
}
/// <summary>
/// Get the input path from the implementation
/// </summary>
/// <returns>String representing the path, null on error</returns>
public override string InputPath() => InputFileValue;
/// <summary>
/// Get the output path from the implementation
/// </summary>
/// <returns>String representing the path, null on error</returns>
public override string OutputPath() => OutputFileValue;
/// <summary>
/// Get the processing speed from the implementation
/// </summary>
/// <returns>int? representing the speed, null on error</returns>
/// <remarks>DD does not support drive speeds</remarks>
public override int? GetSpeed() => 1;
/// <summary>
/// Set the processing speed int the implementation
/// </summary>
/// <param name="speed">int? representing the speed</param>
/// <remarks>DD does not support drive speeds</remarks>
public override void SetSpeed(int? speed)
{
}
/// <summary>
/// Get the MediaType from the current set of parameters
/// </summary>
/// <returns>MediaType value if successful, null on error</returns>
/// <remarks>DD does not know the difference between media types</remarks>
public override MediaType? GetMediaType() => null;
/// <summary>
/// Gets if the current command is considered a dumping command or not
/// </summary>
/// <returns>True if it's a dumping command, false otherwise</returns>
public override bool IsDumpingCommand()
{
switch (this.BaseCommand)
{
case Command.List:
return false;
default:
return true;
}
}
/// <summary>
/// Reset all special variables to have default values
/// </summary>
protected override void ResetValues()
{
BaseCommand = Command.NONE;
_flags = new Dictionary<Flag, bool?>();
BlockSizeValue = null;
CountValue = null;
InputFileValue = null;
OutputFileValue = null;
SeekValue = null;
SkipValue = null;
}
/// <summary>
/// Set default parameters for a given system and media type
/// </summary>
/// <param name="system">KnownSystem value to use</param>
/// <param name="type">MediaType value to use</param>
/// <param name="driveLetter">Drive letter to use</param>
/// <param name="filename">Filename to use</param>
/// <param name="driveSpeed">Drive speed to use</param>
/// <param name="paranoid">Enable paranoid mode (safer dumping)</param>
/// <param name="retryCount">User-defined reread count</param>
protected override void SetDefaultParameters(
KnownSystem? system,
MediaType? type,
char driveLetter,
string filename,
int? driveSpeed,
bool paranoid,
int retryCount)
{
BaseCommand = Command.NONE;
this[Flag.InputFile] = true;
InputFileValue = $"\\\\?\\{driveLetter}:";
this[Flag.OutputFile] = true;
OutputFileValue = filename;
// TODO: Add more common block sizes
this[Flag.BlockSize] = true;
switch (type)
{
case MediaType.FloppyDisk:
BlockSizeValue = 1440 * 1024;
break;
default:
BlockSizeValue = 1024 * 1024 * 1024;
break;
}
this[Flag.Progress] = true;
this[Flag.Size] = true;
}
/// <summary>
/// Scan a possible parameter string and populate whatever possible
/// </summary>
/// <param name="parameters">String possibly representing parameters</param>
/// <returns></returns>
protected override bool ValidateAndSetParameters(string parameters)
{
// The string has to be valid by itself first
if (string.IsNullOrWhiteSpace(parameters))
return false;
// Now split the string into parts for easier validation
// https://stackoverflow.com/questions/14655023/split-a-string-that-has-white-spaces-unless-they-are-enclosed-within-quotes
parameters = parameters.Trim();
List<string> parts = Regex.Matches(parameters, @"[\""].+?[\""]|[^ ]+")
.Cast<Match>()
.Select(m => m.Value)
.ToList();
// Determine what the commandline should look like given the first item
int start = 0;
BaseCommand = Converters.StringToCommand(parts[0]);
if (BaseCommand != Command.NONE)
start = 1;
// Loop through all auxilary flags, if necessary
int i = 0;
for (i = start; i < parts.Count; i++)
{
// Flag read-out values
long? longValue = null;
string stringValue = null;
// Keep a count of keys to determine if we should break out to filename handling or not
int keyCount = Keys.Count();
#region Boolean flags
// Progress
ProcessBooleanParameter(parts, FlagStrings.Progress, Flag.Progress, ref i);
// Size
ProcessBooleanParameter(parts, FlagStrings.Size, Flag.Size, ref i);
#endregion
#region Int64 flags
// Block Size
longValue = ProcessInt64Parameter(parts, FlagStrings.BlockSize, Flag.BlockSize, ref i);
if (longValue == Int64.MinValue)
return false;
else if (longValue != null)
BlockSizeValue = longValue;
// Count
longValue = ProcessInt64Parameter(parts, FlagStrings.Count, Flag.Count, ref i);
if (longValue == Int64.MinValue)
return false;
else if (longValue != null)
CountValue = longValue;
// Seek
longValue = ProcessInt64Parameter(parts, FlagStrings.Seek, Flag.Seek, ref i);
if (longValue == Int64.MinValue)
return false;
else if (longValue != null)
SeekValue = longValue;
// Skip
longValue = ProcessInt64Parameter(parts, FlagStrings.Skip, Flag.Skip, ref i);
if (longValue == Int64.MinValue)
return false;
else if (longValue != null)
SkipValue = longValue;
#endregion
#region String flags
// Filter (fixed, removable, disk, partition)
stringValue = ProcessStringParameter(parts, FlagStrings.Filter, Flag.Filter, ref i);
if (!string.IsNullOrEmpty(stringValue))
FilterValue = stringValue;
// Input File
stringValue = ProcessStringParameter(parts, FlagStrings.InputFile, Flag.InputFile, ref i);
if (string.Equals(stringValue, string.Empty))
return false;
else if (stringValue != null)
InputFileValue = stringValue;
// Output File
stringValue = ProcessStringParameter(parts, FlagStrings.OutputFile, Flag.OutputFile, ref i);
if (string.Equals(stringValue, string.Empty))
return false;
else if (stringValue != null)
OutputFileValue = stringValue;
#endregion
}
return true;
}
/// <summary>
/// Validate if all required output files exist
/// </summary>
/// <param name="basePath">Base filename and path to use for checking</param>
/// <param name="system">KnownSystem type representing the media</param>
/// <param name="type">MediaType type representing the media</param>
/// <returns></returns>
public override bool CheckAllOutputFilesExist(string basePath, KnownSystem? system, MediaType? type)
{
// TODO: Figure out what sort of output files are expected... just `.bin`?
return true;
}
/// <summary>
/// Generate a SubmissionInfo for the output files
/// </summary>
/// <param name="info">Base submission info to fill in specifics for</param>
/// <param name="basePath">Base filename and path to use for checking</param>
/// <param name="system">KnownSystem type representing the media</param>
/// <param name="type">MediaType type representing the media</param>
/// <param name="drive">Drive representing the disc to get information from</param>
/// <returns></returns>
public override void GenerateSubmissionInfo(SubmissionInfo info, string basePath, KnownSystem? system, MediaType? type, Drive drive)
{
// TODO: Implement getting submission info, if possible
}
/// <summary>
/// Get the list of commands that use a given flag
/// </summary>
/// <param name="flag">Flag value to get commands for</param>
/// <returns>List of Commands, if possible</returns>
private List<Command> GetSupportedCommands(Flag flag)
{
var commands = new List<Command>();
switch (flag)
{
#region Boolean flags
case Flag.Progress:
commands.Add(Command.NONE);
break;
case Flag.Size:
commands.Add(Command.NONE);
break;
#endregion
#region Int64 flags
case Flag.BlockSize:
commands.Add(Command.NONE);
break;
case Flag.Count:
commands.Add(Command.NONE);
break;
case Flag.Seek:
commands.Add(Command.NONE);
break;
case Flag.Skip:
commands.Add(Command.NONE);
break;
#endregion
#region String flags
case Flag.Filter:
commands.Add(Command.NONE);
break;
case Flag.InputFile:
commands.Add(Command.NONE);
break;
case Flag.OutputFile:
commands.Add(Command.NONE);
break;
#endregion
case Flag.NONE:
default:
return commands;
}
return commands;
}
/// <summary>
/// Process a boolean parameter
/// </summary>
/// <param name="parts">List of parts to be referenced</param>
/// <param name="flagString">Flag string to check</param>
/// <param name="flag">Flag value corresponding to the flag</param>
/// <param name="i">Reference to the position in the parts</param>
/// <returns>True if the parameter was processed successfully or skipped, false otherwise</returns>
private bool ProcessBooleanParameter(List<string> parts, string flagString, Flag flag, ref int i)
{
if (parts == null)
return false;
if (parts[i] == flagString)
{
if (!GetSupportedCommands(flag).Contains(BaseCommand))
return false;
this[flag] = true;
}
return true;
}
/// <summary>
/// Process an Int64 parameter
/// </summary>
/// <param name="parts">List of parts to be referenced</param>
/// <param name="flagString">Flag string to check</param>
/// <param name="flag">Flag value corresponding to the flag</param>
/// <param name="i">Reference to the position in the parts</param>
/// <returns>Int64 value if success, Int64.MinValue if skipped, null on error/returns>
private long? ProcessInt64Parameter(List<string> parts, string flagString, Flag flag, ref int i)
{
if (parts == null)
return null;
if (parts[i].StartsWith(flagString))
{
if (!GetSupportedCommands(flag).Contains(BaseCommand))
return null;
string[] commandParts = parts[i].Split('=');
if (commandParts.Length != 2)
return null;
string valuePart = commandParts[1];
long factor = 1;
// Characters
if (valuePart.EndsWith("c", StringComparison.Ordinal))
{
factor = 1;
valuePart.TrimEnd('c');
}
// Words
else if (valuePart.EndsWith("w", StringComparison.Ordinal))
{
factor = 2;
valuePart.TrimEnd('w');
}
// Double Words
else if (valuePart.EndsWith("d", StringComparison.Ordinal))
{
factor = 4;
valuePart.TrimEnd('d');
}
// Quad Words
else if (valuePart.EndsWith("q", StringComparison.Ordinal))
{
factor = 8;
valuePart.TrimEnd('q');
}
// Kilobytes
else if (valuePart.EndsWith("k", StringComparison.Ordinal))
{
factor = 1024;
valuePart.TrimEnd('k');
}
// Megabytes
else if (valuePart.EndsWith("M", StringComparison.Ordinal))
{
factor = 1024 * 1024;
valuePart.TrimEnd('M');
}
// Gigabytes
else if (valuePart.EndsWith("G", StringComparison.Ordinal))
{
factor = 1024 * 1024 * 1024;
valuePart.TrimEnd('G');
}
if (!IsValidInt64(valuePart))
return null;
this[flag] = true;
return long.Parse(valuePart) * factor;
}
return Int64.MinValue;
}
/// <summary>
/// Process a string parameter
/// </summary>
/// <param name="parts">List of parts to be referenced</param>
/// <param name="flagString">Flag string to check</param>
/// <param name="flag">Flag value corresponding to the flag</param>
/// <param name="i">Reference to the position in the parts</param>
/// <returns>String value if possible, string.Empty on missing, null on error</returns>
private string ProcessStringParameter(List<string> parts, string flagString, Flag flag, ref int i)
{
if (parts == null)
return null;
if (parts[i] == flagString)
{
if (!GetSupportedCommands(flag).Contains(BaseCommand))
return null;
string[] commandParts = parts[i].Split('=');
if (commandParts.Length != 2)
return null;
string valuePart = commandParts[1];
this[flag] = true;
return valuePart.Trim('"');
}
return string.Empty;
}
}
}

View File

@@ -1,12 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net462;net472;netcoreapp3.0</TargetFrameworks>
<TargetFrameworks>net462;net472;net48;netcoreapp3.1</TargetFrameworks>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<PropertyGroup Condition="'$(TargetFramework)'!='netcoreapp3.1'">
<DefineConstants>NET_FRAMEWORK</DefineConstants>
</PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)'!='netcoreapp3.1'">
<COMReference Include="IMAPI2">
<Guid>{2735412F-7F64-5B0F-8F00-5D77AFBE261E}</Guid>
<VersionMajor>1</VersionMajor>
@@ -28,9 +32,9 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="BurnOutSharp" Version="1.3.8.2" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
<PackageReference Include="System.Management" Version="4.6.0" />
<PackageReference Include="BurnOutSharp" Version="1.3.9.1" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="System.Management" Version="4.7.0" />
</ItemGroup>
<ItemGroup>

View File

@@ -0,0 +1,382 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using DICUI.Utilities;
namespace DICUI.Data
{
public abstract class BaseParameters
{
/// <summary>
/// Path to the executable
/// </summary>
public string ExecutablePath { get; set; }
/// <summary>
/// Program that this set of parameters represents
/// </summary>
public InternalProgram InternalProgram { get; set; }
/// <summary>
/// Process to track external program
/// </summary>
private Process process;
/// <summary>
/// Populate a Parameters object from a param string
/// </summary>
/// <param name="parameters">String possibly representing a set of parameters</param>
public BaseParameters(string parameters)
{
// If any parameters are not valid, wipe out everything
if (!ValidateAndSetParameters(parameters))
{
ResetValues();
}
}
/// <summary>
/// Generate parameters based on a set of known inputs
/// </summary>
/// <param name="system">KnownSystem value to use</param>
/// <param name="type">MediaType value to use</param>
/// <param name="driveLetter">Drive letter to use</param>
/// <param name="filename">Filename to use</param>
/// <param name="driveSpeed">Drive speed to use</param>
/// <param name="paranoid">Enable paranoid mode (safer dumping)</param>
/// <param name="quietMode">Enable quiet mode (no beeps)</param>
/// <param name="retryCount">User-defined reread count</param>
public BaseParameters(KnownSystem? system, MediaType? type, char driveLetter, string filename, int? driveSpeed, bool paranoid, bool quietMode, int retryCount)
{
SetDefaultParameters(system, type, driveLetter, filename, driveSpeed, paranoid, retryCount);
}
/// <summary>
/// Blindly generate a parameter string based on the inputs
/// </summary>
/// <returns>Correctly formatted parameter string, null on error</returns>
public abstract string GenerateParameters();
/// <summary>
/// Get the input path from the implementation
/// </summary>
/// <returns>String representing the path, null on error</returns>
public abstract string InputPath();
/// <summary>
/// Get the output path from the implementation
/// </summary>
/// <returns>String representing the path, null on error</returns>
public abstract string OutputPath();
/// <summary>
/// Get the processing speed from the implementation
/// </summary>
/// <returns>int? representing the speed, null on error</returns>
public abstract int? GetSpeed();
/// <summary>
/// Set the processing speed int the implementation
/// </summary>
/// <param name="speed">int? representing the speed</param>
public abstract void SetSpeed(int? speed);
/// <summary>
/// Get the MediaType from the current set of parameters
/// </summary>
/// <returns>MediaType value if successful, null on error</returns>
public abstract MediaType? GetMediaType();
/// <summary>
/// Gets if the current command is considered a dumping command or not
/// </summary>
/// <returns>True if it's a dumping command, false otherwise</returns>
public abstract bool IsDumpingCommand();
/// <summary>
/// Returns if the current Parameter object is valid
/// </summary>
/// <returns></returns>
public bool IsValid()
{
return GenerateParameters() != null;
}
/// <summary>
/// Reset all special variables to have default values
/// </summary>
protected abstract void ResetValues();
/// <summary>
/// Set default parameters for a given system and media type
/// </summary>
/// <param name="system">KnownSystem value to use</param>
/// <param name="type">MediaType value to use</param>
/// <param name="driveLetter">Drive letter to use</param>
/// <param name="filename">Filename to use</param>
/// <param name="driveSpeed">Drive speed to use</param>
/// <param name="paranoid">Enable paranoid mode (safer dumping)</param>
/// <param name="retryCount">User-defined reread count</param>
protected abstract void SetDefaultParameters(
KnownSystem? system,
MediaType? type,
char driveLetter,
string filename,
int? driveSpeed,
bool paranoid,
int retryCount);
/// <summary>
/// Scan a possible parameter string and populate whatever possible
/// </summary>
/// <param name="parameters">String possibly representing parameters</param>
/// <returns></returns>
protected abstract bool ValidateAndSetParameters(string parameters);
/// <summary>
/// Validate if all required output files exist
/// </summary>
/// <param name="basePath">Base filename and path to use for checking</param>
/// <param name="system">KnownSystem type representing the media</param>
/// <param name="type">MediaType type representing the media</param>
/// <returns></returns>
public abstract bool CheckAllOutputFilesExist(string basePath, KnownSystem? system, MediaType? type);
/// <summary>
/// Generate a SubmissionInfo for the output files
/// </summary>
/// <param name="submissionInfo">Base submission info to fill in specifics for</param>
/// <param name="basePath">Base filename and path to use for checking</param>
/// <param name="system">KnownSystem type representing the media</param>
/// <param name="type">MediaType type representing the media</param>
/// <param name="drive">Drive representing the disc to get information from</param>
public abstract void GenerateSubmissionInfo(SubmissionInfo submissionInfo, string basePath, KnownSystem? system, MediaType? type, Drive drive);
/// <summary>
/// Run internal program
/// </summary>
public void ExecuteInternalProgram()
{
process = new Process()
{
StartInfo = new ProcessStartInfo()
{
FileName = ExecutablePath,
Arguments = GenerateParameters() ?? "",
},
};
process.Start();
process.WaitForExit();
}
/// <summary>
/// Run internal program async with an input set of parameters
/// </summary>
/// <param name="parameters"></param>
/// <returns>Standard output from commandline window</returns>
public async Task<string> ExecuteInternalProgram(BaseParameters parameters)
{
Process childProcess;
string output = await Task.Run(() =>
{
childProcess = new Process()
{
StartInfo = new ProcessStartInfo()
{
FileName = parameters.ExecutablePath,
Arguments = parameters.GenerateParameters(),
CreateNoWindow = true,
UseShellExecute = false,
RedirectStandardInput = true,
RedirectStandardOutput = true,
},
};
childProcess.Start();
childProcess.WaitForExit(1000);
// Just in case, we want to push a button 5 times to clear any errors
for (int i = 0; i < 5; i++)
childProcess.StandardInput.WriteLine("Y");
string stdout = childProcess.StandardOutput.ReadToEnd();
childProcess.Dispose();
return stdout;
});
return output;
}
/// <summary>
/// Cancel an in-progress dumping process
/// </summary>
public void KillInternalProgram()
{
try
{
if (process != null && !process.HasExited)
process.Kill();
}
catch
{ }
}
/// <summary>
/// Returns whether or not the selected item exists
/// </summary>
/// <param name="parameters">List of parameters to check against</param>
/// <param name="index">Current index</param>
/// <returns>True if the next item exists, false otherwise</returns>
protected bool DoesExist(List<string> parameters, int index)
{
if (index >= parameters.Count)
return false;
return true;
}
/// <summary>
/// Get the full lines from the input file, if possible
/// </summary>
/// <param name="filename">file location</param>
/// <param name="binary">True if should read as binary, false otherwise (default)</param>
/// <returns>Full text of the file, null on error</returns>
protected string GetFullFile(string filename, bool binary = false)
{
// If the file doesn't exist, we can't get info from it
if (!File.Exists(filename))
return null;
// If we're reading as binary
if (binary)
{
string hex = string.Empty;
using (BinaryReader br = new BinaryReader(File.OpenRead(filename)))
{
while (br.BaseStream.Position < br.BaseStream.Length)
{
hex += Convert.ToString(br.ReadByte(), 16);
}
}
return hex;
}
return string.Join("\n", File.ReadAllLines(filename));
}
/// <summary>
/// Returns whether a string is a flag (starts with '/')
/// </summary>
/// <param name="parameter">String value to check</param>
/// <returns>True if it's a flag, false otherwise</returns>
protected bool IsFlag(string parameter)
{
if (parameter.Trim('\"').StartsWith("/"))
return true;
return false;
}
/// <summary>
/// Returns whether a string is a valid drive letter
/// </summary>
/// <param name="parameter">String value to check</param>
/// <returns>True if it's a valid drive letter, false otherwise</returns>
protected bool IsValidDriveLetter(string parameter)
{
if (!Regex.IsMatch(parameter, @"^[A-Z]:?\\?$"))
return false;
return true;
}
/// <summary>
/// Returns whether a string is a valid bool
/// </summary>
/// <param name="parameter">String value to check</param>
/// <returns>True if it's a valid bool, false otherwise</returns>
protected bool IsValidBool(string parameter)
{
return bool.TryParse(parameter, out bool temp);
}
/// <summary>
/// Returns whether a string is a valid byte
/// </summary>
/// <param name="parameter">String value to check</param>
/// <param name="lowerBound">Lower bound (>=)</param>
/// <param name="upperBound">Upper bound (<=)</param>
/// <returns>True if it's a valid byte, false otherwise</returns>
protected bool IsValidInt8(string parameter, sbyte lowerBound = -1, sbyte upperBound = -1)
{
if (!sbyte.TryParse(parameter, out sbyte temp))
return false;
else if (lowerBound != -1 && temp < lowerBound)
return false;
else if (upperBound != -1 && temp > upperBound)
return false;
return true;
}
/// <summary>
/// Returns whether a string is a valid Int16
/// </summary>
/// <param name="parameter">String value to check</param>
/// <param name="lowerBound">Lower bound (>=)</param>
/// <param name="upperBound">Upper bound (<=)</param>
/// <returns>True if it's a valid Int16, false otherwise</returns>
protected bool IsValidInt16(string parameter, short lowerBound = -1, short upperBound = -1)
{
if (!short.TryParse(parameter, out short temp))
return false;
else if (lowerBound != -1 && temp < lowerBound)
return false;
else if (upperBound != -1 && temp > upperBound)
return false;
return true;
}
/// <summary>
/// Returns whether a string is a valid Int32
/// </summary>
/// <param name="parameter">String value to check</param>
/// <param name="lowerBound">Lower bound (>=)</param>
/// <param name="upperBound">Upper bound (<=)</param>
/// <returns>True if it's a valid Int32, false otherwise</returns>
protected bool IsValidInt32(string parameter, int lowerBound = -1, int upperBound = -1)
{
if (!int.TryParse(parameter, out int temp))
return false;
else if (lowerBound != -1 && temp < lowerBound)
return false;
else if (upperBound != -1 && temp > upperBound)
return false;
return true;
}
/// <summary>
/// Returns whether a string is a valid Int64
/// </summary>
/// <param name="parameter">String value to check</param>
/// <param name="lowerBound">Lower bound (>=)</param>
/// <param name="upperBound">Upper bound (<=)</param>
/// <returns>True if it's a valid Int64, false otherwise</returns>
protected bool IsValidInt64(string parameter, long lowerBound = -1, long upperBound = -1)
{
if (!long.TryParse(parameter, out long temp))
return false;
else if (lowerBound != -1 && temp < lowerBound)
return false;
else if (upperBound != -1 && temp > upperBound)
return false;
return true;
}
}
}

View File

@@ -1,69 +1,5 @@
namespace DICUI.Data
{
/// <summary>
/// Top-level commands for DiscImageCreator
/// </summary>
public static class DICCommandStrings
{
public const string Audio = "audio";
public const string BluRay = "bd";
public const string Close = "close";
public const string CompactDisc = "cd";
public const string Data = "data";
public const string DigitalVideoDisc = "dvd";
public const string Disk = "disk";
public const string DriveSpeed = "ls";
public const string Eject = "eject";
public const string Floppy = "fd";
public const string GDROM = "gd";
public const string MDS = "mds";
public const string Merge = "merge";
public const string Reset = "reset";
public const string SACD = "sacd";
public const string Start = "start";
public const string Stop = "stop";
public const string Sub = "sub";
public const string Swap = "swap";
public const string XBOX = "xbox";
public const string XBOXSwap = "xboxswap";
public const string XGD2Swap = "xgd2swap";
public const string XGD3Swap = "xgd3swap";
}
/// <summary>
/// Dumping flags for DiscImageCreator
/// </summary>
public static class DICFlagStrings
{
public const string AddOffset = "/a";
public const string AMSF = "/p";
public const string AtariJaguar = "/aj";
public const string BEOpcode = "/be";
public const string C2Opcode = "/c2";
public const string CopyrightManagementInformation = "/c";
public const string D8Opcode = "/d8";
public const string DisableBeep = "/q";
public const string ForceUnitAccess = "/f";
public const string MCN = "/m";
public const string MultiSession = "/ms";
public const string NoFixSubP = "/np";
public const string NoFixSubQ = "/nq";
public const string NoFixSubQLibCrypt = "/nl";
public const string NoFixSubRtoW = "/nr";
public const string NoFixSubQSecuROM = "/ns";
public const string NoSkipSS = "/nss";
public const string Raw = "/raw";
public const string Reverse = "/r";
public const string ScanAntiMod = "/am";
public const string ScanFileProtect = "/sf";
public const string ScanSectorProtect = "/ss";
public const string SeventyFour = "/74";
public const string SkipSector = "/sk";
public const string SubchannelReadLevel = "/s";
public const string VideoNow = "/vn";
public const string VideoNowColor = "/vnc";
}
/// <summary>
/// Template field values for submission info
/// </summary>

View File

@@ -1,4 +1,6 @@
namespace DICUI.Data
using System;
namespace DICUI.Data
{
/// <summary>
/// Category for Redump
@@ -19,69 +21,14 @@
}
/// <summary>
/// Supported DIC commands
/// Dump status for Redump
/// </summary>
public enum DICCommand
public enum DumpStatus
{
NONE = 0,
Audio,
BluRay,
Close,
CompactDisc,
Data,
DigitalVideoDisc,
Disk,
DriveSpeed,
Eject,
Floppy,
GDROM,
MDS,
Merge,
Reset,
SACD,
Start,
Stop,
Sub,
Swap,
XBOX,
XBOXSwap,
XGD2Swap,
XGD3Swap,
}
/// <summary>
/// Supported DIC flags
/// </summary>
public enum DICFlag
{
NONE = 0,
AddOffset,
AMSF,
AtariJaguar,
BEOpcode,
C2Opcode,
CopyrightManagementInformation,
D8Opcode,
DisableBeep,
ForceUnitAccess,
MCN,
MultiSession,
NoFixSubP,
NoFixSubQ,
NoFixSubQLibCrypt,
NoFixSubRtoW,
NoFixSubQSecuROM,
NoSkipSS,
Raw,
Reverse,
ScanAntiMod,
ScanFileProtect,
ScanSectorProtect,
SeventyFour,
SkipSector,
SubchannelReadLevel,
VideoNow,
VideoNowColor,
BadDumpRed = 2,
PossibleBadDumpYellow = 3,
OriginalMediaBlue = 4,
TwoOrMoreDumpsGreen = 5,
}
/// <summary>
@@ -96,14 +43,19 @@
}
/// <summary>
/// Dump status for Redump
/// Program that is being used to dump media
/// </summary>
public enum DumpStatus
public enum InternalProgram
{
BadDumpRed = 2,
PossibleBadDumpYellow = 3,
OriginalMediaBlue = 4,
TwoOrMoreDumpsGreen = 5,
NONE = 0,
// Dumping support
Aaru,
DD,
DiscImageCreator, // Includes UmdImageCreator
// Verification support only
CleanRip,
}
/// <summary>
@@ -238,6 +190,7 @@
AUSCOMSystem1,
BallyGameMagic,
CapcomCPSystemIII,
funworldPhotoPlay,
GlobalVRVarious,
GlobalVRVortek,
GlobalVRVortekV3,
@@ -302,6 +255,7 @@
PhotoCD,
PlayStationGameSharkUpdates,
RainbowDisc,
SegaPrologue21,
SuperAudioCD,
TaoiKTV,
TomyKissSite,
@@ -436,6 +390,81 @@
FlashDrive,
}
/// <summary>
/// Physical media types
/// </summary>
/// <see cref="https://docs.microsoft.com/en-us/previous-versions/windows/desktop/cimwin32a/win32-physicalmedia"/>
public enum PhysicalMediaType : ushort
{
Unknown = 0,
Other = 1,
TapeCartridge = 2,
QICCartridge = 3,
AITCartridge = 4,
DTFCartridge = 5,
DATCartridge = 6,
EightMillimeterTapeCartridge = 7,
NineteenMillimeterTapeCartridge = 8,
DLTCartridge = 9,
HalfInchMagneticTapeCartridge = 10,
CartridgeDisk = 11,
JAZDisk = 12,
ZIPDisk = 13,
SyQuestDisk = 14,
WinchesterRemovableDisk = 15,
CDROM = 16,
CDROMXA = 17,
CDI = 18,
CDRecordable = 19,
WORM = 20,
MagnetoOptical = 21,
DVD = 22,
DVDPlusRW = 23,
DVDRAM = 24,
DVDROM = 25,
DVDVideo = 26,
Divx = 27,
FloppyDiskette = 28,
HardDisk = 29,
MemoryCard = 30,
HardCopy = 31,
ClikDisk = 32,
CDRW = 33,
CDDA = 34,
CDPlus = 35,
DVDRecordable = 36,
DVDMinusRW = 37,
DVDAudio = 38,
DVD5 = 39,
DVD9 = 40,
DVD10 = 41,
DVD18 = 42,
MagnetoOpticalRewriteable = 43,
MagnetoOpticalWriteOnce = 44,
MagnetoOpticalRewriteableLIMDOW = 45,
PhaseChangeWriteOnce = 46,
PhaseChangeRewriteable = 47,
PhaseChangeDualRewriteable = 48,
AblativeWriteOnce = 49,
NearFieldRecording = 50,
MiniQic = 51,
Travan = 52,
EightMillimeterMetalParticle = 53,
EightMillimeterAdvancedMetalEvaporate = 54,
NCTP = 55,
LTOUltrium = 56,
LTOAccelis = 57,
NineTrackTape = 58,
EighteenTrackTape = 59,
ThirtySixTrackTape = 60,
Magstar3590 = 61,
MagstarMP = 62,
D2Tape = 63,
TapeDSTSmall = 64,
TapeDSTMedium = 65,
TapeDSTLarge = 66,
}
/// <summary>
/// List of all known Redump systems
/// </summary>
@@ -598,4 +627,97 @@
No = 1,
Yes = 2,
}
#region Win32_CDROMDrive
// https://docs.microsoft.com/en-us/windows/win32/cimwin32prov/win32-cdromdrive
/// <summary>
/// Availability and status of the device
/// </summary>
public enum Availability : ushort
{
Other = 1,
Unknown = 2,
RunningFullPower = 3,
Warning = 4,
InTest = 5,
NotApplicable = 6,
PowerOff = 7,
OffLine = 8,
OffDuty = 9,
Degraded = 10,
NotInstalled = 11,
InstallError = 12,
PowerSaveUnknown = 13,
PowerSaveLowPowerMode = 14,
PowerSaveStandby = 15,
PowerCycle = 16,
PowerSaveWarning = 17,
Paused = 18,
NotReady = 19,
NotConfigured = 20,
Quiesced = 21,
}
/// <summary>
/// Optical drive capabilities
/// </summary>
public enum Capabilities : ushort
{
Unknown = 0,
Other = 1,
SequentialAccess = 2,
RandomAccess = 3,
SupportsWriting = 4,
Encryption = 5,
Compression = 6,
SupportsRemoveableMedia = 7,
ManualCleaning = 8,
AutomaticCleaning = 9,
SMARTNotification = 10,
SupportsDualSidedMedia = 11,
PredismountEjectNotRequired = 12,
}
/// <summary>
/// File system flags
/// </summary>
[Flags]
public enum FileSystemFlags : uint
{
None = 0,
CaseSensitiveSearch = 1,
CasePreservedNames = 2,
UnicodeOnDisk = 4,
PersistentACLs = 8,
FileCompression = 16,
VolumeQuotas = 32,
SupportsSparseFiles = 64,
SupportsReparsePoints = 128,
SupportsRemoteStorage = 256,
SupportsLongNames = 16384,
VolumeIsCompressed = 32768,
ReadOnlyVolume = 524289, // TODO: Invesitgate, as this value seems wrong
SupportsObjectIDS = 65536,
SupportsEncryption = 131072,
SupportsNamedStreams = 262144,
}
/// <summary>
/// Specific power-related capabilities of a logical device
/// </summary>
public enum PowerManagementCapabilities : ushort
{
Unknown = 0,
NotSupported = 1,
Disabled = 2,
Enabled = 3,
PowerSavingModesEnteredAutomatically = 4,
PowerStateSettable = 5,
PowerCyclingSupported = 6,
TimedPowerOnSupported = 7,
}
#endregion
}

View File

@@ -0,0 +1,286 @@
using System;
using System.Collections;
using System.Collections.Generic;
namespace DICUI.Data
{
public class Options : IDictionary<string, string>
{
private Dictionary<string, string> _settings;
#region Internal Program
public string AaruPath
{
get { return GetStringSetting(_settings, "AaruPath", "Programs\\Aaru\\Aaru.exe"); }
set { _settings["AaruPath"] = value; }
}
public string CreatorPath
{
get { return GetStringSetting(_settings, "CreatorPath", "Programs\\Creator\\DiscImageCreator.exe"); }
set { _settings["CreatorPath"] = value; }
}
public string DDPath
{
get { return GetStringSetting(_settings, "DDPath", "Programs\\DD\\dd.exe"); }
set { _settings["DDPath"] = value; }
}
public string InternalProgram
{
get { return GetStringSetting(_settings, "InternalProgram", Data.InternalProgram.DiscImageCreator.ToString()); }
set { _settings["InternalProgram"] = value; }
}
#endregion
#region Extra Paths
public string DefaultOutputPath
{
get { return GetStringSetting(_settings, "DefaultOutputPath", "ISO"); }
set { _settings["DefaultOutputPath"] = value; }
}
public string SubDumpPath
{
get { return GetStringSetting(_settings, "SubDumpPath", "Programs\\Subdump\\subdump.exe"); }
set { _settings["SubDumpPath"] = value; }
}
#endregion
#region Dumping Speeds
public int PreferredDumpSpeedCD
{
get { return GetInt32Setting(_settings, "PreferredDumpSpeedCD", 72); }
set { _settings["PreferredDumpSpeedCD"] = value.ToString(); }
}
public int PreferredDumpSpeedDVD
{
get { return GetInt32Setting(_settings, "PreferredDumpSpeedDVD", 24); }
set { _settings["PreferredDumpSpeedDVD"] = value.ToString(); }
}
public int PreferredDumpSpeedBD
{
get { return GetInt32Setting(_settings, "PreferredDumpSpeedBD", 16); }
set { _settings["PreferredDumpSpeedBD"] = value.ToString(); }
}
#endregion
#region Extra Dumping Options
public bool QuietMode
{
get { return GetBooleanSetting(_settings, "QuietMode", false); }
set { _settings["QuietMode"] = value.ToString(); }
}
public bool ParanoidMode
{
get { return GetBooleanSetting(_settings, "ParanoidMode", false); }
set { _settings["ParanoidMode"] = value.ToString(); }
}
public bool ScanForProtection
{
get { return GetBooleanSetting(_settings, "ScanForProtection", true); }
set { _settings["ScanForProtection"] = value.ToString(); }
}
public int RereadAmountForC2
{
get { return GetInt32Setting(_settings, "RereadAmountForC2", 20); }
set { _settings["RereadAmountForC2"] = value.ToString(); }
}
public bool AddPlaceholders
{
get { return GetBooleanSetting(_settings, "AddPlaceholders", true); }
set { _settings["AddPlaceholders"] = value.ToString(); }
}
public bool PromptForDiscInformation
{
get { return GetBooleanSetting(_settings, "PromptForDiscInformation", true); }
set { _settings["PromptForDiscInformation"] = value.ToString(); }
}
public bool IgnoreFixedDrives
{
get { return GetBooleanSetting(_settings, "IgnoreFixedDrives", false); }
set { _settings["IgnoreFixedDrives"] = value.ToString(); }
}
public bool ResetDriveAfterDump
{
get { return GetBooleanSetting(_settings, "ResetDriveAfterDump", false); }
set { _settings["ResetDriveAfterDump"] = value.ToString(); }
}
#endregion
#region Skip Options
public bool SkipMediaTypeDetection
{
get { return GetBooleanSetting(_settings, "SkipMediaTypeDetection", false); }
set { _settings["SkipMediaTypeDetection"] = value.ToString(); }
}
public bool SkipSystemDetection
{
get { return GetBooleanSetting(_settings, "SkipSystemDetection", false); }
set { _settings["SkipSystemDetection"] = value.ToString(); }
}
#endregion
#region Logging Options
public bool VerboseLogging
{
get { return GetBooleanSetting(_settings, "VerboseLogging", true); }
set { _settings["VerboseLogging"] = value.ToString(); }
}
public bool OpenLogWindowAtStartup
{
get { return GetBooleanSetting(_settings, "OpenLogWindowAtStartup", true); }
set { _settings["OpenLogWindowAtStartup"] = value.ToString(); }
}
#endregion
#region Redump Login Information
public string Username
{
get { return GetStringSetting(_settings, "Username", ""); }
set { _settings["Username"] = value; }
}
// TODO: Figure out a way to keep this encrypted in some way, BASE64 to start?
public string Password
{
get { return GetStringSetting(_settings, "Password", ""); }
set { _settings["Password"] = value; }
}
#endregion
/// <summary>
/// Constructor taking a dictionary for settings
/// </summary>
/// <param name="settings"></param>
public Options(Dictionary<string, string> settings = null)
{
this._settings = settings ?? new Dictionary<string, string>();
}
/// <summary>
/// Get a Boolean setting from a settings, dictionary
/// </summary>
/// <param name="settings">Dictionary representing the settings</param>
/// <param name="key">Setting key to get a value for</param>
/// <param name="defaultValue">Default value to return if no value is found</param>
/// <returns>Setting value if possible, default value otherwise</returns>
private bool GetBooleanSetting(Dictionary<string, string> settings, string key, bool defaultValue)
{
if (settings.ContainsKey(key))
{
if (Boolean.TryParse(settings[key], out bool value))
return value;
else
return defaultValue;
}
else
{
return defaultValue;
}
}
/// <summary>
/// Get an Int32 setting from a settings, dictionary
/// </summary>
/// <param name="settings">Dictionary representing the settings</param>
/// <param name="key">Setting key to get a value for</param>
/// <param name="defaultValue">Default value to return if no value is found</param>
/// <returns>Setting value if possible, default value otherwise</returns>
private int GetInt32Setting(Dictionary<string, string> settings, string key, int defaultValue)
{
if (settings.ContainsKey(key))
{
if (Int32.TryParse(settings[key], out int value))
return value;
else
return defaultValue;
}
else
{
return defaultValue;
}
}
/// <summary>
/// Get a String setting from a settings, dictionary
/// </summary>
/// <param name="settings">Dictionary representing the settings</param>
/// <param name="key">Setting key to get a value for</param>
/// <param name="defaultValue">Default value to return if no value is found</param>
/// <returns>Setting value if possible, default value otherwise</returns>
private string GetStringSetting(Dictionary<string, string> settings, string key, string defaultValue)
{
if (settings.ContainsKey(key))
return settings[key];
else
return defaultValue;
}
#region IDictionary implementations
public ICollection<string> Keys => _settings.Keys;
public ICollection<string> Values => _settings.Values;
public int Count => _settings.Count;
public bool IsReadOnly => ((IDictionary<string, string>)_settings).IsReadOnly;
public string this[string key]
{
get { return (_settings.ContainsKey(key) ? _settings[key] : null); }
set { _settings[key] = value; }
}
public bool ContainsKey(string key) => _settings.ContainsKey(key);
public void Add(string key, string value) => _settings.Add(key, value);
public bool Remove(string key) => _settings.Remove(key);
public bool TryGetValue(string key, out string value) => _settings.TryGetValue(key, out value);
public void Add(KeyValuePair<string, string> item) => _settings.Add(item.Key, item.Value);
public void Clear() => _settings.Clear();
public bool Contains(KeyValuePair<string, string> item) => ((IDictionary<string, string>)_settings).Contains(item);
public void CopyTo(KeyValuePair<string, string>[] array, int arrayIndex) => ((IDictionary<string, string>)_settings).CopyTo(array, arrayIndex);
public bool Remove(KeyValuePair<string, string> item) => ((IDictionary<string, string>)_settings).Remove(item);
public IEnumerator<KeyValuePair<string, string>> GetEnumerator() => _settings.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => _settings.GetEnumerator();
#endregion
}
}

View File

@@ -146,14 +146,14 @@ namespace DICUI.Data
// Category
match = categoryRegex.Match(discData);
if (match.Success)
this.CommonDiscInfo.Category = Converters.StringToCategory(match.Groups[1].Value);
this.CommonDiscInfo.Category = Converters.ToCategory(match.Groups[1].Value);
else
this.CommonDiscInfo.Category = Data.Category.Games;
// Region
match = regionRegex.Match(discData);
if (match.Success)
this.CommonDiscInfo.Region = Converters.StringToRegion(match.Groups[1].Value);
this.CommonDiscInfo.Region = Converters.ToRegion(match.Groups[1].Value);
// Languages
var matches = languagesRegex.Matches(discData);
@@ -161,7 +161,7 @@ namespace DICUI.Data
{
List<Language?> tempLanguages = new List<Language?>();
foreach (Match submatch in matches)
tempLanguages.Add(Converters.StringToLanguage(submatch.Groups[1].Value));
tempLanguages.Add(Converters.ToLanguage(submatch.Groups[1].Value));
this.CommonDiscInfo.Languages = tempLanguages.ToArray();
}
@@ -249,12 +249,12 @@ namespace DICUI.Data
/// </summary>
public class CommonDiscInfoSection
{
// TODO: Name not defined
// Name not defined by Redump
[JsonProperty(PropertyName = "d_system", Required = Required.AllowNull)]
[JsonConverter(typeof(KnownSystemConverter))]
public KnownSystem? System { get; set; }
// TODO: Name not defined
// Name not defined by Redump
// TODO: Have this convert to a new `RedumpMedia?` if possible, for submission
[JsonProperty(PropertyName = "d_media", Required = Required.AllowNull)]
[JsonConverter(typeof(MediaTypeConverter))]

View File

@@ -0,0 +1,66 @@
namespace DICUI.DiscImageCreator
{
/// <summary>
/// Top-level commands for DiscImageCreator
/// </summary>
public static class CommandStrings
{
public const string Audio = "audio";
public const string BluRay = "bd";
public const string Close = "close";
public const string CompactDisc = "cd";
public const string Data = "data";
public const string DigitalVideoDisc = "dvd";
public const string Disk = "disk";
public const string DriveSpeed = "ls";
public const string Eject = "eject";
public const string Floppy = "fd";
public const string GDROM = "gd";
public const string MDS = "mds";
public const string Merge = "merge";
public const string Reset = "reset";
public const string SACD = "sacd";
public const string Start = "start";
public const string Stop = "stop";
public const string Sub = "sub";
public const string Swap = "swap";
public const string XBOX = "xbox";
public const string XBOXSwap = "xboxswap";
public const string XGD2Swap = "xgd2swap";
public const string XGD3Swap = "xgd3swap";
}
/// <summary>
/// Dumping flags for DiscImageCreator
/// </summary>
public static class FlagStrings
{
public const string AddOffset = "/a";
public const string AMSF = "/p";
public const string AtariJaguar = "/aj";
public const string BEOpcode = "/be";
public const string C2Opcode = "/c2";
public const string CopyrightManagementInformation = "/c";
public const string D8Opcode = "/d8";
public const string DisableBeep = "/q";
public const string ForceUnitAccess = "/f";
public const string MultiSession = "/ms";
public const string NoFixSubP = "/np";
public const string NoFixSubQ = "/nq";
public const string NoFixSubQLibCrypt = "/nl";
public const string NoFixSubRtoW = "/nr";
public const string NoFixSubQSecuROM = "/ns";
public const string NoSkipSS = "/nss";
public const string Raw = "/raw";
public const string Reverse = "/r";
public const string ScanAntiMod = "/am";
public const string ScanFileProtect = "/sf";
public const string ScanSectorProtect = "/ss";
public const string SeventyFour = "/74";
public const string SkipSector = "/sk";
public const string SubchannelReadLevel = "/s";
public const string VideoNow = "/vn";
public const string VideoNowColor = "/vnc";
public const string VideoNowXP = "/vnx";
}
}

View File

@@ -0,0 +1,323 @@
using DICUI.Data;
namespace DICUI.DiscImageCreator
{
public static class Converters
{
#region Cross-enumeration conversions
/// <summary>
/// Get the most common known system for a given MediaType
/// </summary>
/// <param name="baseCommand">Command value to check</param>
/// <returns>KnownSystem if possible, null on error</returns>
public static KnownSystem? ToKnownSystem(Command baseCommand)
{
switch (baseCommand)
{
case Command.Audio:
return KnownSystem.AudioCD;
case Command.CompactDisc:
case Command.Data:
case Command.DigitalVideoDisc:
case Command.Disk:
case Command.Floppy:
return KnownSystem.IBMPCCompatible;
case Command.GDROM:
case Command.Swap:
return KnownSystem.SegaDreamcast;
case Command.BluRay:
return KnownSystem.SonyPlayStation3;
case Command.SACD:
return KnownSystem.SuperAudioCD;
case Command.XBOX:
case Command.XBOXSwap:
return KnownSystem.MicrosoftXBOX;
case Command.XGD2Swap:
case Command.XGD3Swap:
return KnownSystem.MicrosoftXBOX360;
default:
return null;
}
}
/// <summary>
/// Get the MediaType associated with a given base command
/// </summary>
/// <param name="baseCommand">Command value to check</param>
/// <returns>MediaType if possible, null on error</returns>
/// <remarks>This takes the "safe" route by assuming the larger of any given format</remarks>
public static MediaType? ToMediaType(Command baseCommand)
{
switch (baseCommand)
{
case Command.Audio:
case Command.CompactDisc:
case Command.Data:
case Command.SACD:
return MediaType.CDROM;
case Command.GDROM:
case Command.Swap:
return MediaType.GDROM;
case Command.DigitalVideoDisc:
case Command.XBOX:
case Command.XBOXSwap:
case Command.XGD2Swap:
case Command.XGD3Swap:
return MediaType.DVD;
case Command.BluRay:
return MediaType.BluRay;
// Non-optical
case Command.Floppy:
return MediaType.FloppyDisk;
case Command.Disk:
return MediaType.HardDisk;
default:
return null;
}
}
/// <summary>
/// Get the default extension for a given disc type
/// </summary>
/// <param name="type">MediaType value to check</param>
/// <returns>Valid extension (with leading '.'), null on error</returns>
public static string Extension(MediaType? type)
{
switch (type)
{
case MediaType.CDROM:
case MediaType.GDROM:
case MediaType.Cartridge:
case MediaType.HardDisk:
case MediaType.CompactFlash:
case MediaType.MMC:
case MediaType.SDCard:
case MediaType.FlashDrive:
return ".bin";
case MediaType.DVD:
case MediaType.HDDVD:
case MediaType.BluRay:
case MediaType.NintendoWiiOpticalDisc:
case MediaType.UMD:
return ".iso";
case MediaType.LaserDisc:
case MediaType.NintendoGameCubeGameDisc:
return ".raw";
case MediaType.NintendoWiiUOpticalDisc:
return ".wud";
case MediaType.FloppyDisk:
return ".img";
case MediaType.Cassette:
return ".wav";
case MediaType.NONE:
default:
return null;
}
}
#endregion
#region Convert to Long Name
/// <summary>
/// Get the string representation of the Command enum values
/// </summary>
/// <param name="command">Command value to convert</param>
/// <returns>String representing the value, if possible</returns>
public static string LongName(Command command)
{
switch (command)
{
case Command.Audio:
return CommandStrings.Audio;
case Command.BluRay:
return CommandStrings.BluRay;
case Command.Close:
return CommandStrings.Close;
case Command.CompactDisc:
return CommandStrings.CompactDisc;
case Command.Data:
return CommandStrings.Data;
case Command.DigitalVideoDisc:
return CommandStrings.DigitalVideoDisc;
case Command.Disk:
return CommandStrings.Disk;
case Command.DriveSpeed:
return CommandStrings.DriveSpeed;
case Command.Eject:
return CommandStrings.Eject;
case Command.Floppy:
return CommandStrings.Floppy;
case Command.GDROM:
return CommandStrings.GDROM;
case Command.MDS:
return CommandStrings.MDS;
case Command.Merge:
return CommandStrings.Merge;
case Command.Reset:
return CommandStrings.Reset;
case Command.SACD:
return CommandStrings.SACD;
case Command.Start:
return CommandStrings.Start;
case Command.Stop:
return CommandStrings.Stop;
case Command.Sub:
return CommandStrings.Sub;
case Command.Swap:
return CommandStrings.Swap;
case Command.XBOX:
return CommandStrings.XBOX;
case Command.XBOXSwap:
return CommandStrings.XBOXSwap;
case Command.XGD2Swap:
return CommandStrings.XGD2Swap;
case Command.XGD3Swap:
return CommandStrings.XGD3Swap;
case Command.NONE:
default:
return "";
}
}
/// <summary>
/// Get the string representation of the Flag enum values
/// </summary>
/// <param name="command">Flag value to convert</param>
/// <returns>String representing the value, if possible</returns>
public static string LongName(Flag flag)
{
switch (flag)
{
case Flag.AddOffset:
return FlagStrings.AddOffset;
case Flag.AMSF:
return FlagStrings.AMSF;
case Flag.AtariJaguar:
return FlagStrings.AtariJaguar;
case Flag.BEOpcode:
return FlagStrings.BEOpcode;
case Flag.C2Opcode:
return FlagStrings.C2Opcode;
case Flag.CopyrightManagementInformation:
return FlagStrings.CopyrightManagementInformation;
case Flag.D8Opcode:
return FlagStrings.D8Opcode;
case Flag.DisableBeep:
return FlagStrings.DisableBeep;
case Flag.ForceUnitAccess:
return FlagStrings.ForceUnitAccess;
case Flag.MultiSession:
return FlagStrings.MultiSession;
case Flag.NoFixSubP:
return FlagStrings.NoFixSubP;
case Flag.NoFixSubQ:
return FlagStrings.NoFixSubQ;
case Flag.NoFixSubQLibCrypt:
return FlagStrings.NoFixSubQLibCrypt;
case Flag.NoFixSubRtoW:
return FlagStrings.NoFixSubRtoW;
case Flag.NoFixSubQSecuROM:
return FlagStrings.NoFixSubQSecuROM;
case Flag.NoSkipSS:
return FlagStrings.NoSkipSS;
case Flag.Raw:
return FlagStrings.Raw;
case Flag.Reverse:
return FlagStrings.Reverse;
case Flag.ScanAntiMod:
return FlagStrings.ScanAntiMod;
case Flag.ScanFileProtect:
return FlagStrings.ScanFileProtect;
case Flag.ScanSectorProtect:
return FlagStrings.ScanSectorProtect;
case Flag.SeventyFour:
return FlagStrings.SeventyFour;
case Flag.SkipSector:
return FlagStrings.SkipSector;
case Flag.SubchannelReadLevel:
return FlagStrings.SubchannelReadLevel;
case Flag.VideoNow:
return FlagStrings.VideoNow;
case Flag.VideoNowColor:
return FlagStrings.VideoNowColor;
case Flag.VideoNowXP:
return FlagStrings.VideoNowXP;
case Flag.NONE:
default:
return "";
}
}
#endregion
#region Convert From String
/// <summary>
/// Get the Command enum value for a given string
/// </summary>
/// <param name="command">String value to convert</param>
/// <returns>Command represented by the string(s), if possible</returns>
public static Command StringToCommand(string command)
{
switch (command)
{
case CommandStrings.Audio:
return Command.Audio;
case CommandStrings.BluRay:
return Command.BluRay;
case CommandStrings.Close:
return Command.Close;
case CommandStrings.CompactDisc:
return Command.CompactDisc;
case CommandStrings.Data:
return Command.Data;
case CommandStrings.DigitalVideoDisc:
return Command.DigitalVideoDisc;
case CommandStrings.Disk:
return Command.Disk;
case CommandStrings.DriveSpeed:
return Command.DriveSpeed;
case CommandStrings.Eject:
return Command.Eject;
case CommandStrings.Floppy:
return Command.Floppy;
case CommandStrings.GDROM:
return Command.GDROM;
case CommandStrings.MDS:
return Command.MDS;
case CommandStrings.Merge:
return Command.Merge;
case CommandStrings.Reset:
return Command.Reset;
case CommandStrings.SACD:
return Command.SACD;
case CommandStrings.Start:
return Command.Start;
case CommandStrings.Stop:
return Command.Stop;
case CommandStrings.Sub:
return Command.Sub;
case CommandStrings.Swap:
return Command.Swap;
case CommandStrings.XBOX:
return Command.XBOX;
case CommandStrings.XBOXSwap:
return Command.XBOXSwap;
case CommandStrings.XGD2Swap:
return Command.XGD2Swap;
case CommandStrings.XGD3Swap:
return Command.XGD3Swap;
default:
return Command.NONE;
}
}
#endregion
}
}

View File

@@ -0,0 +1,68 @@
namespace DICUI.DiscImageCreator
{
/// <summary>
/// Supported DiscImageCreator commands
/// </summary>
public enum Command : int
{
NONE = 0,
Audio,
BluRay,
Close,
CompactDisc,
Data,
DigitalVideoDisc,
Disk,
DriveSpeed,
Eject,
Floppy,
GDROM,
MDS,
Merge,
Reset,
SACD,
Start,
Stop,
Sub,
Swap,
XBOX,
XBOXSwap,
XGD2Swap,
XGD3Swap,
}
/// <summary>
/// Supported DiscImageCreator flags
/// </summary>
public enum Flag : int
{
NONE = 0,
AddOffset,
AMSF,
AtariJaguar,
BEOpcode,
C2Opcode,
CopyrightManagementInformation,
D8Opcode,
DisableBeep,
ForceUnitAccess,
MultiSession,
NoFixSubP,
NoFixSubQ,
NoFixSubQLibCrypt,
NoFixSubRtoW,
NoFixSubQSecuROM,
NoSkipSS,
Raw,
Reverse,
ScanAntiMod,
ScanFileProtect,
ScanSectorProtect,
SeventyFour,
SkipSector,
SubchannelReadLevel,
VideoNow,
VideoNowColor,
VideoNowXP,
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -32,6 +32,6 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.13")]
[assembly: AssemblyFileVersion("1.13.0.0")]
[assembly: AssemblyVersion("1.16.1")]
[assembly: AssemblyFileVersion("1.16.1.0")]
[assembly: InternalsVisibleTo("DICUI.Test")]

View File

@@ -1,7 +1,9 @@
using System;
using System.IO;
using IMAPI2;
using DICUI.Data;
#if NET_FRAMEWORK
using IMAPI2;
#endif
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
@@ -31,41 +33,6 @@ namespace DICUI.Utilities
}
}
/// <summary>
/// Get the most common known system for a given MediaType
/// </summary>
/// <param name="baseCommand">DICCommand value to check</param>
/// <returns>KnownSystem if possible, null on error</returns>
public static KnownSystem? ToKnownSystem(this DICCommand baseCommand)
{
switch (baseCommand)
{
case DICCommand.Audio:
return KnownSystem.AudioCD;
case DICCommand.CompactDisc:
case DICCommand.Data:
case DICCommand.DigitalVideoDisc:
case DICCommand.Disk:
case DICCommand.Floppy:
return KnownSystem.IBMPCCompatible;
case DICCommand.GDROM:
case DICCommand.Swap:
return KnownSystem.SegaDreamcast;
case DICCommand.BluRay:
return KnownSystem.SonyPlayStation3;
case DICCommand.SACD:
return KnownSystem.SuperAudioCD;
case DICCommand.XBOX:
case DICCommand.XBOXSwap:
return KnownSystem.MicrosoftXBOX;
case DICCommand.XGD2Swap:
case DICCommand.XGD3Swap:
return KnownSystem.MicrosoftXBOX360;
default:
return null;
}
}
/// <summary>
/// Convert currently known Redump systems to the master list of systems
/// </summary>
@@ -231,77 +198,84 @@ namespace DICUI.Utilities
}
}
/// <summary>
/// Get the MediaType associated with a given base command
/// </summary>
/// <param name="baseCommand">DICCommand value to check</param>
/// <returns>MediaType if possible, null on error</returns>
/// <remarks>This takes the "safe" route by assuming the larger of any given format</remarks>
public static MediaType? ToMediaType(this DICCommand baseCommand)
{
switch (baseCommand)
{
case DICCommand.Audio:
case DICCommand.CompactDisc:
case DICCommand.Data:
case DICCommand.SACD:
return MediaType.CDROM;
case DICCommand.GDROM:
case DICCommand.Swap:
return MediaType.GDROM;
case DICCommand.DigitalVideoDisc:
case DICCommand.XBOX:
case DICCommand.XBOXSwap:
case DICCommand.XGD2Swap:
case DICCommand.XGD3Swap:
return MediaType.DVD;
case DICCommand.BluRay:
return MediaType.BluRay;
// Non-optical
case DICCommand.Floppy:
return MediaType.FloppyDisk;
case DICCommand.Disk:
return MediaType.HardDisk;
default:
return null;
}
}
#if NET_FRAMEWORK
/// <summary>
/// Convert IMAPI physical media type to a MediaType
/// </summary>
/// <param name="type">IMAPI_MEDIA_PHYSICAL_TYPE value to check</param>
/// <returns>MediaType if possible, null on error</returns>
public static MediaType? ToMediaType(IMAPI_MEDIA_PHYSICAL_TYPE type)
public static MediaType? IMAPIToMediaType(this IMAPI_MEDIA_PHYSICAL_TYPE type)
{
switch (type)
{
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_UNKNOWN:
return MediaType.NONE;
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_CDROM:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_CDR:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_CDRW:
return MediaType.CDROM;
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDROM:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDRAM:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDPLUSR:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDPLUSRW:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDPLUSR_DUALLAYER:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDDASHR:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDDASHRW:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDDASHR_DUALLAYER:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DISK:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDPLUSRW_DUALLAYER:
return MediaType.DVD;
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_HDDVDROM:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_HDDVDR:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_HDDVDRAM:
return MediaType.HDDVD;
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_BDROM:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_BDR:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_BDRE:
return MediaType.BluRay;
default:
return null;
}
}
#endif
/// <summary>
/// Convert physical media type to a MediaType
/// </summary>
/// <param name="type">PhsyicalMediaType value to check</param>
/// <returns>MediaType if possible, null on error</returns>
public static MediaType? ToMediaType(this PhysicalMediaType type)
{
switch (type)
{
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_UNKNOWN:
case PhysicalMediaType.Unknown:
return MediaType.NONE;
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_CDROM:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_CDR:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_CDRW:
// CD-based media
case PhysicalMediaType.CDROM:
case PhysicalMediaType.CDROMXA:
case PhysicalMediaType.CDI: // TODO: Make this separate at some point (CD-I/CD-I Ready?)
case PhysicalMediaType.CDRecordable:
case PhysicalMediaType.CDRW:
case PhysicalMediaType.CDDA:
case PhysicalMediaType.CDPlus: // TODO: Make this separate at some point (Enhanced CD?)
return MediaType.CDROM;
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDROM:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDRAM:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDPLUSR:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDPLUSRW:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDPLUSR_DUALLAYER:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDDASHR:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDDASHRW:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDDASHR_DUALLAYER:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DISK:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDPLUSRW_DUALLAYER:
// DVD-based media
case PhysicalMediaType.DVD:
case PhysicalMediaType.DVDPlusRW:
case PhysicalMediaType.DVDRAM:
case PhysicalMediaType.DVDROM:
case PhysicalMediaType.DVDVideo: // TODO: Make this separate at some point (DVD-Video?)
case PhysicalMediaType.DVDRecordable:
case PhysicalMediaType.DVDMinusRW:
case PhysicalMediaType.DVDAudio: // TODO: Make this separate at some point (DVD-Audio?)
case PhysicalMediaType.DVD5: // TODO: Make this separate at some point (DVD-5?)
case PhysicalMediaType.DVD9: // TODO: Make this separate at some point (DVD-9?)
case PhysicalMediaType.DVD10: // TODO: Make this separate at some point (DVD-10?)
case PhysicalMediaType.DVD18: // TODO: Make this separate at some point (DVD-18?)
return MediaType.DVD;
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_HDDVDROM:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_HDDVDR:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_HDDVDRAM:
return MediaType.HDDVD;
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_BDROM:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_BDR:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_BDRE:
return MediaType.BluRay;
default:
return null;
}
@@ -461,45 +435,6 @@ namespace DICUI.Utilities
}
}
/// <summary>
/// Get the default extension for a given disc type
/// </summary>
/// <param name="type">MediaType value to check</param>
/// <returns>Valid extension (with leading '.'), null on error</returns>
public static string Extension(this MediaType? type)
{
switch (type)
{
case MediaType.CDROM:
case MediaType.GDROM:
case MediaType.Cartridge:
case MediaType.HardDisk:
case MediaType.CompactFlash:
case MediaType.MMC:
case MediaType.SDCard:
case MediaType.FlashDrive:
return ".bin";
case MediaType.DVD:
case MediaType.HDDVD:
case MediaType.BluRay:
case MediaType.NintendoWiiOpticalDisc:
case MediaType.UMD:
return ".iso";
case MediaType.LaserDisc:
case MediaType.NintendoGameCubeGameDisc:
return ".raw";
case MediaType.NintendoWiiUOpticalDisc:
return ".wud";
case MediaType.FloppyDisk:
return ".img";
case MediaType.Cassette:
return ".wav";
case MediaType.NONE:
default:
return null;
}
}
#endregion
#region Convert to Long Name
@@ -541,134 +476,35 @@ namespace DICUI.Utilities
}
/// <summary>
/// Get the string representation of the DICCommand enum values
/// Get the string representation of the InternalProgram enum values
/// </summary>
/// <param name="command">DICCommand value to convert</param>
/// <param name="prog">InternalProgram value to convert</param>
/// <returns>String representing the value, if possible</returns>
public static string LongName(this DICCommand command)
public static string LongName(this InternalProgram? prog)
{
switch (command)
switch (prog)
{
case DICCommand.Audio:
return DICCommandStrings.Audio;
case DICCommand.BluRay:
return DICCommandStrings.BluRay;
case DICCommand.Close:
return DICCommandStrings.Close;
case DICCommand.CompactDisc:
return DICCommandStrings.CompactDisc;
case DICCommand.Data:
return DICCommandStrings.Data;
case DICCommand.DigitalVideoDisc:
return DICCommandStrings.DigitalVideoDisc;
case DICCommand.Disk:
return DICCommandStrings.Disk;
case DICCommand.DriveSpeed:
return DICCommandStrings.DriveSpeed;
case DICCommand.Eject:
return DICCommandStrings.Eject;
case DICCommand.Floppy:
return DICCommandStrings.Floppy;
case DICCommand.GDROM:
return DICCommandStrings.GDROM;
case DICCommand.MDS:
return DICCommandStrings.MDS;
case DICCommand.Merge:
return DICCommandStrings.Merge;
case DICCommand.Reset:
return DICCommandStrings.Reset;
case DICCommand.SACD:
return DICCommandStrings.SACD;
case DICCommand.Start:
return DICCommandStrings.Start;
case DICCommand.Stop:
return DICCommandStrings.Stop;
case DICCommand.Sub:
return DICCommandStrings.Sub;
case DICCommand.Swap:
return DICCommandStrings.Swap;
case DICCommand.XBOX:
return DICCommandStrings.XBOX;
case DICCommand.XBOXSwap:
return DICCommandStrings.XBOXSwap;
case DICCommand.XGD2Swap:
return DICCommandStrings.XGD2Swap;
case DICCommand.XGD3Swap:
return DICCommandStrings.XGD3Swap;
#region Dumping support
case DICCommand.NONE:
case InternalProgram.Aaru:
return "Aaru";
case InternalProgram.DD:
return "dd";
case InternalProgram.DiscImageCreator:
return "DiscImageCreator";
#endregion
#region Verification support only
case InternalProgram.CleanRip:
return "CleanRip";
#endregion
case InternalProgram.NONE:
default:
return "";
}
}
/// <summary>
/// Get the string representation of the DICFlag enum values
/// </summary>
/// <param name="command">DICFlag value to convert</param>
/// <returns>String representing the value, if possible</returns>
public static string LongName(this DICFlag flag)
{
switch (flag)
{
case DICFlag.AddOffset:
return DICFlagStrings.AddOffset;
case DICFlag.AMSF:
return DICFlagStrings.AMSF;
case DICFlag.AtariJaguar:
return DICFlagStrings.AtariJaguar;
case DICFlag.BEOpcode:
return DICFlagStrings.BEOpcode;
case DICFlag.C2Opcode:
return DICFlagStrings.C2Opcode;
case DICFlag.CopyrightManagementInformation:
return DICFlagStrings.CopyrightManagementInformation;
case DICFlag.D8Opcode:
return DICFlagStrings.D8Opcode;
case DICFlag.DisableBeep:
return DICFlagStrings.DisableBeep;
case DICFlag.ForceUnitAccess:
return DICFlagStrings.ForceUnitAccess;
case DICFlag.MCN:
return DICFlagStrings.MCN;
case DICFlag.MultiSession:
return DICFlagStrings.MultiSession;
case DICFlag.NoFixSubP:
return DICFlagStrings.NoFixSubP;
case DICFlag.NoFixSubQ:
return DICFlagStrings.NoFixSubQ;
case DICFlag.NoFixSubQLibCrypt:
return DICFlagStrings.NoFixSubQLibCrypt;
case DICFlag.NoFixSubRtoW:
return DICFlagStrings.NoFixSubRtoW;
case DICFlag.NoFixSubQSecuROM:
return DICFlagStrings.NoFixSubQSecuROM;
case DICFlag.NoSkipSS:
return DICFlagStrings.NoSkipSS;
case DICFlag.Raw:
return DICFlagStrings.Raw;
case DICFlag.Reverse:
return DICFlagStrings.Reverse;
case DICFlag.ScanAntiMod:
return DICFlagStrings.ScanAntiMod;
case DICFlag.ScanFileProtect:
return DICFlagStrings.ScanFileProtect;
case DICFlag.ScanSectorProtect:
return DICFlagStrings.ScanSectorProtect;
case DICFlag.SeventyFour:
return DICFlagStrings.SeventyFour;
case DICFlag.SkipSector:
return DICFlagStrings.SkipSector;
case DICFlag.SubchannelReadLevel:
return DICFlagStrings.SubchannelReadLevel;
case DICFlag.VideoNow:
return DICFlagStrings.VideoNow;
case DICFlag.VideoNowColor:
return DICFlagStrings.VideoNowColor;
case DICFlag.NONE:
default:
return "";
return "Unknown";
}
}
@@ -797,6 +633,8 @@ namespace DICUI.Utilities
return "Bally Game Magic";
case KnownSystem.CapcomCPSystemIII:
return "Capcom CP System III";
case KnownSystem.funworldPhotoPlay:
return "funworld Photo Play";
case KnownSystem.GlobalVRVarious:
return "Global VR PC-based Systems";
case KnownSystem.GlobalVRVortek:
@@ -916,6 +754,8 @@ namespace DICUI.Utilities
return "PlayStation GameShark Updates";
case KnownSystem.RainbowDisc:
return "Rainbow Disc";
case KnownSystem.SegaPrologue21:
return "Sega Prologue 21";
case KnownSystem.SuperAudioCD:
return "Super Audio CD";
case KnownSystem.TaoiKTV:
@@ -1606,6 +1446,8 @@ namespace DICUI.Utilities
return "game magic";
case KnownSystem.CapcomCPSystemIII:
return "cps3";
case KnownSystem.funworldPhotoPlay:
return "fpp";
case KnownSystem.GlobalVRVarious:
return "globalvr";
case KnownSystem.GlobalVRVortek:
@@ -1725,6 +1567,8 @@ namespace DICUI.Utilities
return "gameshark";
case KnownSystem.RainbowDisc:
return "rainbow";
case KnownSystem.SegaPrologue21:
return "pl21";
case KnownSystem.SuperAudioCD:
return "sacd";
case KnownSystem.TaoiKTV:
@@ -2228,9 +2072,9 @@ namespace DICUI.Utilities
/// <summary>
/// Get the Category enum value for a given string
/// </summary>
/// <param name="sys">String value to convert</param>
/// <param name="category">String value to convert</param>
/// <returns>Category represented by the string, if possible</returns>
public static Category StringToCategory(string category)
public static Category ToCategory(string category)
{
switch (category.ToLowerInvariant())
{
@@ -2263,12 +2107,48 @@ namespace DICUI.Utilities
}
}
/// <summary>
/// Get the InternalProgram enum value for a given string
/// </summary>
/// <param name="internalProgram">String value to convert</param>
/// <returns>InternalProgram represented by the string, if possible</returns>
public static InternalProgram ToInternalProgram(string internalProgram)
{
switch (internalProgram.ToLowerInvariant())
{
// Dumping support
case "aaru":
case "chef":
case "dichef":
case "discimagechef":
return InternalProgram.Aaru;
case "creator":
case "dic":
case "dicreator":
case "discimagecreator":
case "umd":
case "umdcreator":
case "umdimagecreator":
return InternalProgram.DiscImageCreator;
case "dd":
return InternalProgram.DD;
// Verification support only
case "cleanrip":
case "cr":
return InternalProgram.CleanRip;
default:
return InternalProgram.NONE;
}
}
/// <summary>
/// Get the KnownSystem enum value for a given string
/// </summary>
/// <param name="sys">String value to convert</param>
/// <returns>KnownSystem represented by the string, if possible</returns>
public static KnownSystem StringToKnownSystem(string sys)
public static KnownSystem? ToKnownSystem(string sys)
{
switch (sys)
{
@@ -2654,6 +2534,11 @@ namespace DICUI.Utilities
case "capcom cp system 3":
case "capcom cp system iii":
return KnownSystem.CapcomCPSystemIII;
case "fpp":
case "funworldphotoplay":
case "funworld photoplay":
case "funworld photo play":
return KnownSystem.funworldPhotoPlay;
case "globalvr":
case "global vr":
case "global vr pc-based systems":
@@ -2951,6 +2836,13 @@ namespace DICUI.Utilities
case "rainbowdisc":
case "rainbow disc":
return KnownSystem.RainbowDisc;
case "pl21":
case "prologue21":
case "prologue 21":
case "segaprologue21":
case "sega prologue21":
case "sega prologue 21":
return KnownSystem.SegaPrologue21;
case "sacd":
case "superaudiocd":
case "super audio cd":
@@ -2980,9 +2872,9 @@ namespace DICUI.Utilities
/// <summary>
/// Get the Language enum value for a given string
/// </summary>
/// <param name="sys">String value to convert</param>
/// <param name="lang">String value to convert</param>
/// <returns>Language represented by the string, if possible</returns>
public static Language? StringToLanguage(string lang)
public static Language? ToLanguage(string lang)
{
switch (lang)
{
@@ -3068,7 +2960,7 @@ namespace DICUI.Utilities
/// </summary>
/// <param name="type">String value to convert</param>
/// <returns>MediaType represented by the string, if possible</returns>
public static MediaType StringToMediaType(string type)
public static MediaType ToMediaType(string type)
{
switch (type.ToLowerInvariant())
{
@@ -3239,9 +3131,9 @@ namespace DICUI.Utilities
/// <summary>
/// Get the Region enum value for a given string
/// </summary>
/// <param name="type">String value to convert</param>
/// <param name="region">String value to convert</param>
/// <returns>Region represented by the string, if possible</returns>
public static Region? StringToRegion(string region)
public static Region? ToRegion(string region)
{
switch (region)
{
@@ -3483,4 +3375,4 @@ namespace DICUI.Utilities
t.WriteTo(writer);
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -188,6 +188,15 @@ namespace DICUI.Utilities
RedumpSystem.SonyPlayStation3,
};
/// <summary>
/// List of systems that has an LSD pack
/// </summary>
public static readonly RedumpSystem[] HasLsd = new RedumpSystem[]
{
RedumpSystem.IBMPCcompatible,
RedumpSystem.SonyPlayStation,
};
/// <summary>
/// List of systems that has an SBI pack
/// </summary>

File diff suppressed because it is too large Load Diff

View File

@@ -5,8 +5,10 @@ using System.Linq;
using System.Management;
using System.Threading.Tasks;
using BurnOutSharp;
using IMAPI2;
using DICUI.Data;
#if NET_FRAMEWORK
using IMAPI2;
#endif
namespace DICUI.Utilities
{
@@ -318,6 +320,11 @@ namespace DICUI.Utilities
types.Add(MediaType.CDROM);
break;
// UNKNOWN
case KnownSystem.funworldPhotoPlay:
types.Add(MediaType.CDROM);
break;
// UNKNOWN
case KnownSystem.GlobalVRVarious:
types.Add(MediaType.CDROM);
@@ -649,6 +656,11 @@ namespace DICUI.Utilities
types.Add(MediaType.CDROM);
break;
// https://segaretro.org/Prologue_21
case KnownSystem.SegaPrologue21:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/Super_Audio_CD
case KnownSystem.SuperAudioCD:
types.Add(MediaType.CDROM);
@@ -695,16 +707,24 @@ namespace DICUI.Utilities
/// <summary>
/// Create a list of active drives matched to their volume labels
/// </summary>
/// <param name="ignoreFixedDrives">Ture to ignore fixed drives from population, false otherwise</param>
/// <returns>Active drives, matched to labels, if possible</returns>
/// <remarks>
/// https://stackoverflow.com/questions/3060796/how-to-distinguish-between-usb-and-floppy-devices?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa
/// https://msdn.microsoft.com/en-us/library/aa394173(v=vs.85).aspx
/// </remarks>
public static List<Drive> CreateListOfDrives()
public static List<Drive> CreateListOfDrives(bool ignoreFixedDrives)
{
var desiredDriveTypes = new List<DriveType>() { DriveType.CDRom };
if (!ignoreFixedDrives)
{
desiredDriveTypes.Add(DriveType.Fixed);
desiredDriveTypes.Add(DriveType.Removable);
}
// Get all supported drive types
var drives = DriveInfo.GetDrives()
.Where(d => d.DriveType == DriveType.CDRom || d.DriveType == DriveType.Fixed || d.DriveType == DriveType.Removable)
.Where(d => desiredDriveTypes.Contains(d.DriveType))
.Select(d => new Drive(Converters.ToInternalDriveType(d.DriveType), d))
.ToList();
@@ -756,31 +776,56 @@ namespace DICUI.Utilities
else if (drive.InternalDriveType == InternalDriveType.Removable)
return MediaType.FlashDrive;
// Get the DeviceID from the current drive letter
// Get the DeviceID and MediaType from the current drive letter
string deviceId = null;
int mediaType = 0;
try
{
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("root\\CIMV2",
"SELECT * FROM Win32_CDROMDrive WHERE Id = '" + drive.Letter + ":\'");
// Get the device ID first
var searcher = new ManagementObjectSearcher(
"root\\CIMV2",
$"SELECT * FROM Win32_CDROMDrive WHERE Id = '{drive.Letter}:\'");
var collection = searcher.Get();
foreach (ManagementObject queryObj in collection)
foreach (ManagementObject queryObj in searcher.Get())
{
deviceId = (string)queryObj["DeviceID"];
}
catch
{
// We don't care what the error was
return null;
}
// If we got no valid device, we don't care and just return
if (deviceId == null)
return null;
#region Possibly useful fields
// Get all relevant disc information
try
{
foreach (var property in queryObj.Properties)
{
Console.WriteLine(property);
}
// Capabilities list
ushort[] capabilities = (ushort[])queryObj["Capabilities"];
// Internal name of the device
string caption = (string)queryObj["Caption"];
// Flags for the file system, see FileSystemFlags
uint fileSystemFlagsEx = (uint)queryObj["FileSystemFlagsEx"];
// "CD Writer" doesn't fit https://docs.microsoft.com/en-us/windows/win32/cimwin32prov/win32-cdromdrive
string mediaTypeString = (string)queryObj["MediaType"];
// Internal name of the device (Seems like a duplicate of Caption)
string name = (string)queryObj["Name"];
// Full device ID for the drive (Seems like duplicate of DeviceID)
string pnpDeviceId = (string)queryObj["PNPDeviceId"];
// Size of the loaded media (extrapolate disc type from this?)
ulong size = (ulong)queryObj["Size"];
#endregion
}
// If we got no valid device, we don't care and just return
if (deviceId == null)
return null;
#if NET_FRAMEWORK
MsftDiscMaster2 discMaster = new MsftDiscMaster2();
deviceId = deviceId.ToLower().Replace('\\', '#');
string id = null;
@@ -801,14 +846,38 @@ namespace DICUI.Utilities
dataWriter.Recorder = recorder;
var media = dataWriter.CurrentPhysicalMediaType;
if (media != IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_UNKNOWN)
return Converters.ToMediaType(media);
return media.IMAPIToMediaType();
return null;
#else
// TODO: This entire .NET Core path still doesn't work
// This may honestly require an entire import of IMAPI2 stuff and then try
// as best as possible to get it working.
// Now try to get the physical media associated
searcher = new ManagementObjectSearcher(
"root\\CIMV2",
$"SELECT * FROM Win32_PhysicalMedia");
foreach (ManagementObject queryObj in searcher.Get())
{
foreach (var property in queryObj.Properties)
{
Console.WriteLine(property);
}
mediaType = (int)(queryObj["MediaType"] ?? 0);
}
return ((PhysicalMediaType)mediaType).ToMediaType();
#endif
}
catch
{
// We don't care what the error is
// We don't care what the error was
return null;
}
return null;
}
/// <summary>
@@ -867,7 +936,7 @@ namespace DICUI.Utilities
// If we have a weird disc, just assume PS1
return KnownSystem.SonyPlayStation;
}
// Sony PlayStation 4
if (drive.VolumeLabel.Equals("PS4VOLUME", StringComparison.OrdinalIgnoreCase))
{
@@ -935,6 +1004,7 @@ namespace DICUI.Utilities
/// <returns>Copy protection detected in the envirionment, if any</returns>
public static async Task<string> RunProtectionScanOnPath(string path)
{
#if NET_FRAMEWORK
try
{
var found = await Task.Run(() =>
@@ -945,12 +1015,16 @@ namespace DICUI.Utilities
if (found == null || found.Count == 0)
return "None found";
return string.Join("\n", found.Select(kvp => kvp.Key + ": " + kvp.Value).ToArray());
// Strip out "CD Check" instances due to false positives
return string.Join("\n", found.Where(kvp => !kvp.Value.Equals("CD Check", StringComparison.OrdinalIgnoreCase)).Select(kvp => kvp.Key + ": " + kvp.Value).ToArray());
}
catch (Exception ex)
{
return $"Path could not be scanned! {ex}";
}
#else
return "Copy protection scanning is not available on .NET Core builds";
#endif
}
}
}

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net462;net472;netcoreapp3.0</TargetFrameworks>
<TargetFrameworks>net462;net472;net48;netcoreapp3.1</TargetFrameworks>
<IsPackable>false</IsPackable>
</PropertyGroup>

View File

@@ -8,50 +8,50 @@ namespace DICUI.Test.Utilities
public class ConvertersTest
{
[Theory]
[InlineData(DICCommand.Audio, MediaType.CDROM)]
[InlineData(DICCommand.BluRay, MediaType.BluRay)]
[InlineData(DICCommand.Close, null)]
[InlineData(DICCommand.CompactDisc, MediaType.CDROM)]
[InlineData(DICCommand.Data, MediaType.CDROM)]
[InlineData(DICCommand.DigitalVideoDisc, MediaType.DVD)]
[InlineData(DICCommand.Eject, null)]
[InlineData(DICCommand.Floppy, MediaType.FloppyDisk)]
[InlineData(DICCommand.GDROM, MediaType.GDROM)]
[InlineData(DICCommand.MDS, null)]
[InlineData(DICCommand.Reset, null)]
[InlineData(DICCommand.SACD, MediaType.CDROM)]
[InlineData(DICCommand.Start, null)]
[InlineData(DICCommand.Stop, null)]
[InlineData(DICCommand.Sub, null)]
[InlineData(DICCommand.Swap, MediaType.GDROM)]
[InlineData(DICCommand.XBOX, MediaType.DVD)]
public void BaseCommandToMediaTypeTest(DICCommand command, MediaType? expected)
[InlineData(DiscImageCreator.Command.Audio, MediaType.CDROM)]
[InlineData(DiscImageCreator.Command.BluRay, MediaType.BluRay)]
[InlineData(DiscImageCreator.Command.Close, null)]
[InlineData(DiscImageCreator.Command.CompactDisc, MediaType.CDROM)]
[InlineData(DiscImageCreator.Command.Data, MediaType.CDROM)]
[InlineData(DiscImageCreator.Command.DigitalVideoDisc, MediaType.DVD)]
[InlineData(DiscImageCreator.Command.Eject, null)]
[InlineData(DiscImageCreator.Command.Floppy, MediaType.FloppyDisk)]
[InlineData(DiscImageCreator.Command.GDROM, MediaType.GDROM)]
[InlineData(DiscImageCreator.Command.MDS, null)]
[InlineData(DiscImageCreator.Command.Reset, null)]
[InlineData(DiscImageCreator.Command.SACD, MediaType.CDROM)]
[InlineData(DiscImageCreator.Command.Start, null)]
[InlineData(DiscImageCreator.Command.Stop, null)]
[InlineData(DiscImageCreator.Command.Sub, null)]
[InlineData(DiscImageCreator.Command.Swap, MediaType.GDROM)]
[InlineData(DiscImageCreator.Command.XBOX, MediaType.DVD)]
public void BaseCommandToMediaTypeTest(DiscImageCreator.Command command, MediaType? expected)
{
MediaType? actual = command.ToMediaType();
MediaType? actual = DiscImageCreator.Converters.ToMediaType(command);
Assert.Equal(expected, actual);
}
[Theory]
[InlineData(DICCommand.Audio, KnownSystem.AudioCD)]
[InlineData(DICCommand.BluRay, KnownSystem.SonyPlayStation3)]
[InlineData(DICCommand.Close, null)]
[InlineData(DICCommand.CompactDisc, KnownSystem.IBMPCCompatible)]
[InlineData(DICCommand.Data, KnownSystem.IBMPCCompatible)]
[InlineData(DICCommand.DigitalVideoDisc, KnownSystem.IBMPCCompatible)]
[InlineData(DICCommand.Eject, null)]
[InlineData(DICCommand.Floppy, KnownSystem.IBMPCCompatible)]
[InlineData(DICCommand.GDROM, KnownSystem.SegaDreamcast)]
[InlineData(DICCommand.MDS, null)]
[InlineData(DICCommand.Reset, null)]
[InlineData(DICCommand.SACD, KnownSystem.SuperAudioCD)]
[InlineData(DICCommand.Start, null)]
[InlineData(DICCommand.Stop, null)]
[InlineData(DICCommand.Sub, null)]
[InlineData(DICCommand.Swap, KnownSystem.SegaDreamcast)]
[InlineData(DICCommand.XBOX, KnownSystem.MicrosoftXBOX)]
public void BaseCommandToKnownSystemTest(DICCommand command, KnownSystem? expected)
[InlineData(DiscImageCreator.Command.Audio, KnownSystem.AudioCD)]
[InlineData(DiscImageCreator.Command.BluRay, KnownSystem.SonyPlayStation3)]
[InlineData(DiscImageCreator.Command.Close, null)]
[InlineData(DiscImageCreator.Command.CompactDisc, KnownSystem.IBMPCCompatible)]
[InlineData(DiscImageCreator.Command.Data, KnownSystem.IBMPCCompatible)]
[InlineData(DiscImageCreator.Command.DigitalVideoDisc, KnownSystem.IBMPCCompatible)]
[InlineData(DiscImageCreator.Command.Eject, null)]
[InlineData(DiscImageCreator.Command.Floppy, KnownSystem.IBMPCCompatible)]
[InlineData(DiscImageCreator.Command.GDROM, KnownSystem.SegaDreamcast)]
[InlineData(DiscImageCreator.Command.MDS, null)]
[InlineData(DiscImageCreator.Command.Reset, null)]
[InlineData(DiscImageCreator.Command.SACD, KnownSystem.SuperAudioCD)]
[InlineData(DiscImageCreator.Command.Start, null)]
[InlineData(DiscImageCreator.Command.Stop, null)]
[InlineData(DiscImageCreator.Command.Sub, null)]
[InlineData(DiscImageCreator.Command.Swap, KnownSystem.SegaDreamcast)]
[InlineData(DiscImageCreator.Command.XBOX, KnownSystem.MicrosoftXBOX)]
public void BaseCommandToKnownSystemTest(DiscImageCreator.Command command, KnownSystem? expected)
{
KnownSystem? actual = Converters.ToKnownSystem(command);
KnownSystem? actual = DiscImageCreator.Converters.ToKnownSystem(command);
Assert.Equal(expected, actual);
}
@@ -65,7 +65,7 @@ namespace DICUI.Test.Utilities
[InlineData(MediaType.NONE, null)]
public void MediaTypeToExtensionTest(MediaType? mediaType, string expected)
{
string actual = Converters.Extension(mediaType);
string actual = DiscImageCreator.Converters.Extension(mediaType);
Assert.Equal(expected, actual);
}

View File

@@ -16,14 +16,12 @@ namespace DICUI.Test
[InlineData("stop D", 'D', false, MediaType.DVD, true)]
public void ParametersValidTest(string parameters, char letter, bool isFloppy, MediaType? mediaType, bool expected)
{
var env = new DumpEnvironment
{
DICParameters = new Parameters(parameters),
Drive = isFloppy
? new Drive(InternalDriveType.Floppy, new DriveInfo(letter.ToString()))
: new Drive(InternalDriveType.Optical, new DriveInfo(letter.ToString())),
Type = mediaType,
};
var options = new Options() { InternalProgram = "dic" };
var drive = isFloppy
? new Drive(InternalDriveType.Floppy, new DriveInfo(letter.ToString()))
: new Drive(InternalDriveType.Optical, new DriveInfo(letter.ToString()));
var env = new DumpEnvironment(options, string.Empty, string.Empty, drive, KnownSystem.IBMPCCompatible, mediaType, parameters);
bool actual = env.ParametersValid();
Assert.Equal(expected, actual);
@@ -36,15 +34,12 @@ namespace DICUI.Test
[InlineData("super\\hero", "blah.bin", "super\\hero", "blah.bin")]
[InlineData("super.hero", "blah.bin", "super.hero", "blah.bin")]
[InlineData("superhero", "blah.rev.bin", "superhero", "blah.rev.bin")]
[InlineData("super&hero", "blah.bin", "super_hero", "blah.bin")]
[InlineData("superhero", "blah&foo.bin", "superhero", "blah_foo.bin")]
[InlineData("super&hero", "blah.bin", "super&hero", "blah.bin")]
[InlineData("superhero", "blah&foo.bin", "superhero", "blah&foo.bin")]
public void FixOutputPathsTest(string outputDirectory, string outputFilename, string expectedOutputDirectory, string expectedOutputFilename)
{
var env = new DumpEnvironment
{
OutputDirectory = outputDirectory,
OutputFilename = outputFilename,
};
var options = new Options() { InternalProgram = "dic" };
var env = new DumpEnvironment(options, outputDirectory, outputFilename, null, KnownSystem.IBMPCCompatible, MediaType.CDROM, string.Empty);
env.FixOutputPaths();
Assert.Equal(expectedOutputDirectory, env.OutputDirectory);

View File

@@ -26,7 +26,7 @@ namespace DICUI.Test.Utilities
[InlineData(MediaType.NONE, null)]
public void ExtensionTest(MediaType? mediaType, string expected)
{
string actual = mediaType.Extension();
string actual = DiscImageCreator.Converters.Extension(mediaType);
Assert.Equal(expected, actual);
}

View File

@@ -1,6 +1,7 @@
using System.Collections.Generic;
using System.Linq;
using DICUI.Data;
using DICUI.DiscImageCreator;
using DICUI.Utilities;
using Xunit;
@@ -9,39 +10,39 @@ namespace DICUI.Test.Utilities
public class ParametersTest
{
[Theory]
[InlineData(KnownSystem.MicrosoftXBOX, MediaType.CDROM, DICCommand.CompactDisc)]
[InlineData(KnownSystem.MicrosoftXBOX, MediaType.DVD, DICCommand.XBOX)]
[InlineData(KnownSystem.MicrosoftXBOX, MediaType.LaserDisc, DICCommand.NONE)]
[InlineData(KnownSystem.SegaNu, MediaType.BluRay, DICCommand.BluRay)]
[InlineData(KnownSystem.AppleMacintosh, MediaType.FloppyDisk, DICCommand.Floppy)]
[InlineData(KnownSystem.RawThrillsVarious, MediaType.GDROM, DICCommand.NONE)]
public void ParametersFromSystemAndTypeTest(KnownSystem? knownSystem, MediaType? mediaType, DICCommand expected)
[InlineData(KnownSystem.MicrosoftXBOX, MediaType.CDROM, Command.CompactDisc)]
[InlineData(KnownSystem.MicrosoftXBOX, MediaType.DVD, Command.XBOX)]
[InlineData(KnownSystem.MicrosoftXBOX, MediaType.LaserDisc, Command.NONE)]
[InlineData(KnownSystem.SegaNu, MediaType.BluRay, Command.BluRay)]
[InlineData(KnownSystem.AppleMacintosh, MediaType.FloppyDisk, Command.Floppy)]
[InlineData(KnownSystem.RawThrillsVarious, MediaType.GDROM, Command.NONE)]
public void ParametersFromSystemAndTypeTest(KnownSystem? knownSystem, MediaType? mediaType, Command expected)
{
Parameters actual = new Parameters(knownSystem, mediaType, 'D', "disc.bin", 16, true, -1);
Assert.Equal(expected, actual.Command);
var actual = new Parameters(knownSystem, mediaType, 'D', "disc.bin", 16, true, false, -1);
Assert.Equal(expected, actual.BaseCommand);
}
[Theory]
[InlineData(KnownSystem.AppleMacintosh, MediaType.LaserDisc, true, 20, null, null)]
[InlineData(KnownSystem.NintendoGameCube, MediaType.NintendoGameCubeGameDisc, false, 20, null, new DICFlag[] { DICFlag.Raw })]
[InlineData(KnownSystem.IBMPCCompatible, MediaType.DVD, false, 20, null, new DICFlag[] { })]
[InlineData(KnownSystem.NintendoGameCube, MediaType.NintendoGameCubeGameDisc, false, 20, null, new Flag[] { Flag.Raw })]
[InlineData(KnownSystem.IBMPCCompatible, MediaType.DVD, false, 20, null, new Flag[] { })]
/* paranoid mode tests */
[InlineData(KnownSystem.IBMPCCompatible, MediaType.CDROM, true, 1000, 2, new DICFlag[] { DICFlag.C2Opcode, DICFlag.NoFixSubQSecuROM, DICFlag.ScanFileProtect, DICFlag.ScanSectorProtect, DICFlag.SubchannelReadLevel })]
[InlineData(KnownSystem.AppleMacintosh, MediaType.CDROM, false, 20, null, new DICFlag[] { DICFlag.C2Opcode, DICFlag.NoFixSubQSecuROM, DICFlag.ScanFileProtect })]
[InlineData(KnownSystem.IBMPCCompatible, MediaType.DVD, true, 500, null, new DICFlag[] { DICFlag.CopyrightManagementInformation, DICFlag.ScanFileProtect })]
[InlineData(KnownSystem.HDDVDVideo, MediaType.HDDVD, true, 500, null, new DICFlag[] { DICFlag.CopyrightManagementInformation })]
[InlineData(KnownSystem.IBMPCCompatible, MediaType.DVD, false, 500, null, new DICFlag[] { })]
[InlineData(KnownSystem.HDDVDVideo, MediaType.HDDVD, false, 500, null, new DICFlag[] { })]
[InlineData(KnownSystem.IBMPCCompatible, MediaType.CDROM, true, 1000, 2, new Flag[] { Flag.C2Opcode, Flag.NoFixSubQSecuROM, Flag.ScanFileProtect, Flag.ScanSectorProtect, Flag.SubchannelReadLevel })]
[InlineData(KnownSystem.AppleMacintosh, MediaType.CDROM, false, 20, null, new Flag[] { Flag.C2Opcode, Flag.NoFixSubQSecuROM, Flag.ScanFileProtect })]
[InlineData(KnownSystem.IBMPCCompatible, MediaType.DVD, true, 500, null, new Flag[] { Flag.CopyrightManagementInformation, Flag.ScanFileProtect })]
[InlineData(KnownSystem.HDDVDVideo, MediaType.HDDVD, true, 500, null, new Flag[] { Flag.CopyrightManagementInformation })]
[InlineData(KnownSystem.IBMPCCompatible, MediaType.DVD, false, 500, null, new Flag[] { })]
[InlineData(KnownSystem.HDDVDVideo, MediaType.HDDVD, false, 500, null, new Flag[] { })]
/* reread c2 */
[InlineData(KnownSystem.SegaDreamcast, MediaType.GDROM, false, 1000, null, new DICFlag[] { DICFlag.C2Opcode })]
[InlineData(KnownSystem.SegaDreamcast, MediaType.GDROM, false, -1, null, new DICFlag[] { DICFlag.C2Opcode })]
[InlineData(KnownSystem.SegaDreamcast, MediaType.GDROM, false, 1000, null, new Flag[] { Flag.C2Opcode })]
[InlineData(KnownSystem.SegaDreamcast, MediaType.GDROM, false, -1, null, new Flag[] { Flag.C2Opcode })]
public void ParametersFromOptionsTest(KnownSystem? knownSystem, MediaType? mediaType, bool paranoid, int rereadC2, int? subchannelLevel, DICFlag[] expected)
public void ParametersFromOptionsTest(KnownSystem? knownSystem, MediaType? mediaType, bool paranoid, int rereadC2, int? subchannelLevel, Flag[] expected)
{
Parameters actual = new Parameters(knownSystem, mediaType, 'D', "disc.bin", 16, paranoid, rereadC2);
var actual = new Parameters(knownSystem, mediaType, 'D', "disc.bin", 16, paranoid, false, rereadC2);
HashSet<DICFlag> expectedSet = new HashSet<DICFlag>(expected ?? new DICFlag[0]);
HashSet<DICFlag> actualSet = new HashSet<DICFlag>(actual.Keys ?? new DICFlag[0]);
HashSet<Flag> expectedSet = new HashSet<Flag>(expected ?? new Flag[0]);
HashSet<Flag> actualSet = new HashSet<Flag>(actual.Keys.Cast<Flag>() ?? new Flag[0]);
Assert.Equal(expectedSet, actualSet);
if (rereadC2 == -1 || !Validators.GetValidMediaTypes(knownSystem).Contains(mediaType))
Assert.Null(actual.C2OpcodeValue[0]);
@@ -50,23 +51,6 @@ namespace DICUI.Test.Utilities
Assert.Equal(subchannelLevel, actual.SubchannelReadLevelValue);
}
[Theory]
[InlineData(null, null, null, null, null)]
[InlineData("", null, null, null, null)]
[InlineData("cd F test.bin 8 /c2 20", MediaType.CDROM, KnownSystem.IBMPCCompatible, "F", "test.bin")]
[InlineData("fd A blah\\test.img", MediaType.FloppyDisk, KnownSystem.IBMPCCompatible, "A", "blah\\test.img")]
[InlineData("dvd X super\\blah\\test.iso 8 /raw", MediaType.NintendoGameCubeGameDisc, KnownSystem.NintendoGameCube, "X", "super\\blah\\test.iso")]
[InlineData("stop D", null, null, "D", null)]
public void DetermineFlagsTest(string parameters, MediaType? expectedMediaType, KnownSystem? expectedKnownSystem, string expectedDriveLetter, string expectedPath)
{
Parameters actualParams = new Parameters(parameters);
bool actual = actualParams.DetermineFlags(out MediaType? actualMediaType, out KnownSystem? actualKnownSystem, out string actualDriveLetter, out string actualPath);
Assert.Equal(expectedMediaType, actualMediaType);
Assert.Equal(expectedKnownSystem, actualKnownSystem);
Assert.Equal(expectedDriveLetter, actualDriveLetter);
Assert.Equal(expectedPath, actualPath);
}
[Theory]
[InlineData(null, false)]
[InlineData("", false)]
@@ -78,7 +62,7 @@ namespace DICUI.Test.Utilities
[InlineData("ls", false)]
public void ValidateParametersTest(string parameters, bool expected)
{
Parameters actual = new Parameters(parameters);
var actual = new Parameters(parameters);
Assert.Equal(expected, actual.IsValid());
}
}

View File

@@ -1,12 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="DICPath" value="Programs\DiscImageCreator.exe"/>
<add key="SubDumpPath" value="subdump.exe"/>
<add key="AaruPath" value="Programs\Aaru\Aaru.exe"/>
<add key="CreatorPath" value="Programs\Creator\DiscImageCreator.exe"/>
<add key="DDPath" value="Programs\DD\dd.exe"/>
<add key="SubDumpPath" value="Programs\Subdump\subdump.exe"/>
<add key="DefaultOutputPath" value="ISO"/>
<add key="PreferredDumpSpeedCD" value="72"/>
<add key="InternalProgram" value="DiscImageCreator"/>
<add key="PreferredDumpSpeedCD" value="48"/>
<add key="PreferredDumpSpeedDVD" value="24"/>
<add key="PreferredDumpSpeedBD" value="16"/>
<add key="QuietMode" value="false"/>
<add key="ParanoidMode" value="false"/>
<add key="ScanForProtection" value="true"/>
@@ -15,7 +20,11 @@
<add key="RereadAmountForC2" value="20"/>
<add key="VerboseLogging" value="true"/>
<add key="OpenLogWindowAtStartup" value="true"/>
<add key="AddPlaceholders" value="true"/>
<add key="AddPlaceholders" value="true"/>
<add key="PromptForDiscInformation" value="true"/>
<add key="IgnoreFixedDrives" value="false"/>
<add key="ResetDriveAfterDump" value="false"/>
<add key="Username" value=""/>
<add key="Password" value=""/>
</appSettings>

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<PropertyGroup>
<TargetFrameworks>net462;net472;netcoreapp3.0</TargetFrameworks>
<TargetFrameworks>net462;net472;net48;netcoreapp3.1</TargetFrameworks>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<OutputType>WinExe</OutputType>
<UseWindowsForms>true</UseWindowsForms>

View File

@@ -13,14 +13,13 @@ namespace DICUI
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is DICCommand)
return ((DICCommand)value).LongName();
else if (value is DICFlag)
return ((DICFlag)value).LongName();
else if (value is MediaType?)
// Common
if (value is MediaType?)
return ((MediaType?)value).LongName();
else if (value is KnownSystem?)
return ((KnownSystem?)value).LongName();
// Default
else
return "";
}

View File

@@ -1,199 +0,0 @@
using System;
using System.Configuration;
using System.Linq;
using System.Reflection;
using DICUI.Data;
namespace DICUI
{
public class Options
{
public string DefaultOutputPath { get; private set; }
public string DICPath { get; private set; }
public string SubDumpPath { get; private set; }
public int PreferredDumpSpeedCD { get; set; }
public int PreferredDumpSpeedDVD { get; set; }
public int PreferredDumpSpeedBD { get; set; }
public bool QuietMode { get; set; }
public bool ParanoidMode { get; set; }
public bool ScanForProtection { get; set; }
public int RereadAmountForC2 { get; set; }
public bool AddPlaceholders { get; set; }
public bool PromptForDiscInformation { get; set; }
public bool SkipMediaTypeDetection { get; set; }
public bool SkipSystemDetection { get; set; }
public bool VerboseLogging { get; set; }
public bool OpenLogWindowAtStartup { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public void Save()
{
Configuration configFile = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
//TODO: reflection is used
//TODO: is remove needed, doesn't the value get directly overridden
Array.ForEach(
GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance),
p => {
configFile.AppSettings.Settings.Remove(p.Name);
configFile.AppSettings.Settings.Add(p.Name, Convert.ToString(p.GetValue(this)));
}
);
configFile.Save(ConfigurationSaveMode.Modified);
}
public void Load()
{
Configuration configFile = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
//TODO: hardcoded, we should find a better way
this.DICPath = GetStringSetting(configFile, "DICPath", "Programs\\DiscImageCreator.exe");
this.SubDumpPath = GetStringSetting(configFile, "SubDumpPath", "subdump.exe");
this.DefaultOutputPath = GetStringSetting(configFile, "DefaultOutputPath", "ISO");
this.PreferredDumpSpeedCD = GetInt32Setting(configFile, "PreferredDumpSpeedCD", 72);
this.PreferredDumpSpeedDVD = GetInt32Setting(configFile, "PreferredDumpSpeedDVD", 24);
this.PreferredDumpSpeedBD = GetInt32Setting(configFile, "PreferredDumpSpeedBD", 16);
this.QuietMode = GetBooleanSetting(configFile, "QuietMode", false);
this.ParanoidMode = GetBooleanSetting(configFile, "ParanoidMode", false);
this.ScanForProtection = GetBooleanSetting(configFile, "ScanForProtection", true);
this.SkipMediaTypeDetection = GetBooleanSetting(configFile, "SkipMediaTypeDetection", false);
this.SkipSystemDetection = GetBooleanSetting(configFile, "SkipSystemDetection", false);
this.RereadAmountForC2 = GetInt32Setting(configFile, "RereadAmountForC2", 20);
this.VerboseLogging = GetBooleanSetting(configFile, "VerboseLogging", true);
this.OpenLogWindowAtStartup = GetBooleanSetting(configFile, "OpenLogWindowAtStartup", true);
this.AddPlaceholders = GetBooleanSetting(configFile, "AddPlaceholders", true);
this.PromptForDiscInformation = GetBooleanSetting(configFile, "PromptForDiscInformation", true);
this.Username = GetStringSetting(configFile, "Username", "");
this.Password = GetStringSetting(configFile, "Password", "");
}
/// <summary>
/// Get a boolean setting from a configuration
/// </summary>
/// <param name="configFile">Current configuration file</param>
/// <param name="key">Setting key to get a value for</param>
/// <param name="defaultValue">Default value to return if no value is found</param>
/// <returns>Setting value if possible, default value otherwise</returns>
public bool GetBooleanSetting(Configuration configFile, string key, bool defaultValue)
{
var settings = configFile.AppSettings.Settings;
if (settings.AllKeys.Contains(key))
{
if (Boolean.TryParse(settings[key].Value, out bool value))
return value;
else
return defaultValue;
}
else
{
return defaultValue;
}
}
/// <summary>
/// Get a boolean setting from a configuration
/// </summary>
/// <param name="configFile">Current configuration file</param>
/// <param name="key">Setting key to get a value for</param>
/// <param name="defaultValue">Default value to return if no value is found</param>
/// <returns>Setting value if possible, default value otherwise</returns>
public int GetInt32Setting(Configuration configFile, string key, int defaultValue)
{
var settings = configFile.AppSettings.Settings;
if (settings.AllKeys.Contains(key))
{
if (Int32.TryParse(settings[key].Value, out int value))
return value;
else
return defaultValue;
}
else
{
return defaultValue;
}
}
/// <summary>
/// Get a boolean setting from a configuration
/// </summary>
/// <param name="configFile">Current configuration file</param>
/// <param name="key">Setting key to get a value for</param>
/// <param name="defaultValue">Default value to return if no value is found</param>
/// <returns>Setting value if possible, default value otherwise</returns>
public long GetInt64Setting(Configuration configFile, string key, long defaultValue)
{
var settings = configFile.AppSettings.Settings;
if (settings.AllKeys.Contains(key))
{
if (Int64.TryParse(settings[key].Value, out long value))
return value;
else
return defaultValue;
}
else
{
return defaultValue;
}
}
/// <summary>
/// Get a boolean setting from a configuration
/// </summary>
/// <param name="configFile">Current configuration file</param>
/// <param name="key">Setting key to get a value for</param>
/// <param name="defaultValue">Default value to return if no value is found</param>
/// <returns>Setting value if possible, default value otherwise</returns>
public string GetStringSetting(Configuration configFile, string key, string defaultValue)
{
var settings = configFile.AppSettings.Settings;
if (settings.AllKeys.Contains(key))
return settings[key].Value;
else
return defaultValue;
}
//TODO: probably should be generic for non-string options
//TODO: using reflection for Set and Get is orthodox but it works, should be changed to a key,value map probably
public void Set(string key, string value)
{
GetType().GetProperty(key, BindingFlags.Public | BindingFlags.Instance).SetValue(this, value);
}
public string Get(string key)
{
return GetType().GetProperty(key, BindingFlags.Public | BindingFlags.Instance).GetValue(this) as string;
}
public int GetPreferredDumpSpeedForMediaType(MediaType? type)
{
switch (type)
{
case MediaType.CDROM:
case MediaType.GDROM:
return PreferredDumpSpeedCD;
case MediaType.DVD:
case MediaType.HDDVD:
case MediaType.NintendoGameCubeGameDisc:
case MediaType.NintendoWiiOpticalDisc:
return PreferredDumpSpeedDVD;
case MediaType.BluRay:
return PreferredDumpSpeedBD;
default:
return 8;
}
}
}
}

View File

@@ -12,7 +12,7 @@ using System.Windows;
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("DICUI")]
[assembly: AssemblyCopyright("Copyright © 2019")]
[assembly: AssemblyCopyright("Copyright © 2020")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
@@ -51,8 +51,8 @@ using System.Windows;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.15")]
[assembly: AssemblyFileVersion("1.15.0.0")]
[assembly: AssemblyVersion("1.16.1")]
[assembly: AssemblyFileVersion("1.16.1.0")]
// Anything marked as internal can be used by the test methods
[assembly: InternalsVisibleTo("DICUI.Test")]

122
DICUI/UIOptions.cs Normal file
View File

@@ -0,0 +1,122 @@
using System.Collections.Generic;
using System.Configuration;
using DICUI.Data;
namespace DICUI
{
public class UIOptions
{
// TODO: Is there any way that this can be made private?
public Options Options { get; set; }
#region Passthrough readonly values
// TODO: Can any of these be removed?
public string DefaultOutputPath { get { return Options.DefaultOutputPath; } }
public bool IgnoreFixedDrives { get { return Options.IgnoreFixedDrives; } }
public bool ResetDriveAfterDump { get { return Options.ResetDriveAfterDump; } }
public bool SkipMediaTypeDetection { get { return Options.SkipMediaTypeDetection; } }
public bool SkipSystemDetection { get { return Options.SkipSystemDetection; } }
public bool OpenLogWindowAtStartup { get { return Options.OpenLogWindowAtStartup; } }
#endregion
/// <summary>
/// Default constructor
/// </summary>
public UIOptions()
{
Load();
}
/// <summary>
/// Save a configuration from internal Options
/// </summary>
public void Save()
{
Configuration configFile = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
// Loop through all settings in Options and save them, overwriting existing settings
foreach (var kvp in Options)
{
configFile.AppSettings.Settings.Remove(kvp.Key);
configFile.AppSettings.Settings.Add(kvp.Key, kvp.Value);
}
configFile.Save(ConfigurationSaveMode.Modified);
}
/// <summary>
/// Load a configuration into internal Options
/// </summary>
private void Load()
{
Configuration configFile = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
var settings = ConvertToDictionary(configFile);
Options = new Options(settings);
}
/// <summary>
/// Get a setting value from the base Options
/// </summary>
/// <param name="key">Key to retrieve the value for</param>
/// <returns>String value if possible, null otherwise</returns>
public string Get(string key)
{
return Options[key];
}
/// <summary>
/// Set a setting value in the base Options
/// </summary>
/// <param name="key">Key to set the value for</param>
/// <param name="value">Value to set</param>
public void Set(string key, string value)
{
Options[key] = value;
}
/// <summary>
/// Get the preferred dumping speed given a media type
/// </summary>
/// <param name="type">MediaType representing the current selection</param>
/// <returns>Int value representing the dump speed</returns>
public int GetPreferredDumpSpeedForMediaType(MediaType? type)
{
switch (type)
{
case MediaType.CDROM:
case MediaType.GDROM:
return this.Options.PreferredDumpSpeedCD;
case MediaType.DVD:
case MediaType.HDDVD:
case MediaType.NintendoGameCubeGameDisc:
case MediaType.NintendoWiiOpticalDisc:
return this.Options.PreferredDumpSpeedDVD;
case MediaType.BluRay:
return this.Options.PreferredDumpSpeedBD;
default:
return this.Options.PreferredDumpSpeedCD;
}
}
/// <summary>
/// Convert the configuration app settings to a dictionary
/// </summary>
/// <param name="configFile">Configuration to load from</param>
/// <returns>Dictionary with all values from app settings</returns>
private Dictionary<string, string> ConvertToDictionary(Configuration configFile)
{
var settings = configFile.AppSettings.Settings;
var dict = new Dictionary<string, string>();
foreach (string key in settings.AllKeys)
{
dict[key] = settings[key]?.Value ?? string.Empty;
}
return dict;
}
}
}

View File

@@ -6,72 +6,190 @@ namespace DICUI
{
public class OptionsViewModel
{
private Options _options;
private UIOptions _uiOptions;
public OptionsViewModel(Options options)
#region Internal Program
public string AaruPath
{
this._options = options;
get { return _uiOptions.Options.AaruPath; }
set { _uiOptions.Options.AaruPath = value; }
}
public string CreatorPath
{
get { return _uiOptions.Options.CreatorPath; }
set { _uiOptions.Options.CreatorPath = value; }
}
public string DDPath
{
get { return _uiOptions.Options.DDPath; }
set { _uiOptions.Options.DDPath = value; }
}
public string InternalProgram
{
get { return _uiOptions.Options.InternalProgram; }
set { _uiOptions.Options.InternalProgram = value; }
}
#endregion
#region Extra Paths
public string DefaultOutputPath
{
get { return _uiOptions.Options.DefaultOutputPath; }
set { _uiOptions.Options.DefaultOutputPath = value; }
}
public string SubDumpPath
{
get { return _uiOptions.Options.SubDumpPath; }
set { _uiOptions.Options.SubDumpPath = value; }
}
#endregion
#region Dumping Speeds
public int PreferredDumpSpeedCD
{
get { return _uiOptions.Options.PreferredDumpSpeedCD; }
set { _uiOptions.Options.PreferredDumpSpeedCD = value; }
}
public int PreferredDumpSpeedDVD
{
get { return _uiOptions.Options.PreferredDumpSpeedDVD; }
set { _uiOptions.Options.PreferredDumpSpeedDVD = value; }
}
public int PreferredDumpSpeedBD
{
get { return _uiOptions.Options.PreferredDumpSpeedBD; }
set { _uiOptions.Options.PreferredDumpSpeedBD = value; }
}
#endregion
#region Extra Dumping Options
public bool QuietMode
{
get { return _options.QuietMode; }
set { _options.QuietMode = value; }
get { return _uiOptions.Options.QuietMode; }
set { _uiOptions.Options.QuietMode = value; }
}
public bool ParanoidMode
{
get { return _options.ParanoidMode; }
set { _options.ParanoidMode = value; }
get { return _uiOptions.Options.ParanoidMode; }
set { _uiOptions.Options.ParanoidMode = value; }
}
public bool ScanForProtection
{
get { return _options.ScanForProtection; }
set { _options.ScanForProtection = value; }
}
public bool SkipMediaTypeDetection
{
get { return _options.SkipMediaTypeDetection; }
set { _options.SkipMediaTypeDetection = value; }
}
public bool SkipSystemDetection
{
get { return _options.SkipSystemDetection; }
set { _options.SkipSystemDetection = value; }
get { return _uiOptions.Options.ScanForProtection; }
set { _uiOptions.Options.ScanForProtection = value; }
}
public string RereadAmountForC2
{
get { return Convert.ToString(_options.RereadAmountForC2); }
get { return Convert.ToString(_uiOptions.Options.RereadAmountForC2); }
set
{
if (Int32.TryParse(value, out int result))
_options.RereadAmountForC2 = result;
_uiOptions.Options.RereadAmountForC2 = result;
}
}
public bool AddPlaceholders
{
get { return _uiOptions.Options.AddPlaceholders; }
set { _uiOptions.Options.AddPlaceholders = value; }
}
public bool PromptForDiscInformation
{
get { return _uiOptions.Options.PromptForDiscInformation; }
set { _uiOptions.Options.PromptForDiscInformation = value; }
}
public bool IgnoreFixedDrives
{
get { return _uiOptions.Options.IgnoreFixedDrives; }
set { _uiOptions.Options.IgnoreFixedDrives = value; }
}
public bool ResetDriveAfterDump
{
get { return _uiOptions.Options.ResetDriveAfterDump; }
set { _uiOptions.Options.ResetDriveAfterDump = value; }
}
#endregion
#region Skip Options
public bool SkipMediaTypeDetection
{
get { return _uiOptions.Options.SkipMediaTypeDetection; }
set { _uiOptions.Options.SkipMediaTypeDetection = value; }
}
public bool SkipSystemDetection
{
get { return _uiOptions.Options.SkipSystemDetection; }
set { _uiOptions.Options.SkipSystemDetection = value; }
}
#endregion
#region Logging Options
public bool VerboseLogging
{
get { return _options.VerboseLogging; }
get { return _uiOptions.Options.VerboseLogging; }
set
{
_options.VerboseLogging = value;
_options.Save();
_uiOptions.Options.VerboseLogging = value;
_uiOptions.Save(); // TODO: Why does this save here?
}
}
public bool OpenLogWindowAtStartup
{
get { return _options.OpenLogWindowAtStartup; }
get { return _uiOptions.Options.OpenLogWindowAtStartup; }
set
{
_options.OpenLogWindowAtStartup = value;
_options.Save();
_uiOptions.Options.OpenLogWindowAtStartup = value;
_uiOptions.Save(); // TODO: Why does this save here?
}
}
#endregion
#region Redump Login Information
public string Username
{
get { return _uiOptions.Options.Username; }
set { _uiOptions.Options.Username = value; }
}
public string Password
{
get { return _uiOptions.Options.Password; }
set { _uiOptions.Options.Password = value; }
}
#endregion
public OptionsViewModel(UIOptions uiOptions)
{
this._uiOptions = uiOptions;
}
}
public class LoggerViewModel

View File

@@ -77,13 +77,13 @@
</ComboBox>
<Label Grid.Row="6" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Languages" />
<ListBox x:Name="LanguagesComboBox" Grid.Row="6" Grid.Column="1" Height="24" HorizontalAlignment="Stretch" SelectionMode="Multiple">
<ListBox.ItemTemplate>
<ComboBox x:Name="LanguagesComboBox" Grid.Row="6" Grid.Column="1" Height="24" HorizontalAlignment="Stretch" >
<ComboBox.ItemTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding IsChecked}" Content="{Binding Path=Name}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</ComboBox.ItemTemplate>
</ComboBox>
<Label Grid.Row="7" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Serial" />
<TextBox x:Name="SerialTextBox" Grid.Row="7" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" />

View File

@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Media;
using DICUI.Data;
namespace DICUI.Windows
@@ -27,6 +28,7 @@ namespace DICUI.Windows
PopulateCategories();
PopulateRegions();
PopulateLanguages();
DisableFieldsIfNeeded();
}
public void Refresh()
@@ -118,6 +120,31 @@ namespace DICUI.Windows
LanguagesComboBox.SelectedIndex = 0;
}
/// <summary>
/// Disable fields that aren't applicable to the current disc
/// </summary>
private void DisableFieldsIfNeeded()
{
// Only disable for single-layer discs
if (_submissionInfo.SizeAndChecksums.Layerbreak == default(long))
{
L1MasteringRingTextBox.IsEnabled = false;
L1MasteringRingTextBox.Background = Brushes.Gray;
L1MasteringSIDTextBox.IsEnabled = false;
L1MasteringSIDTextBox.Background = Brushes.Gray;
L1ToolstampTextBox.IsEnabled = false;
L1ToolstampTextBox.Background = Brushes.Gray;
L1MouldSIDTextBox.IsEnabled = false;
L1MouldSIDTextBox.Background = Brushes.Gray;
L1AdditionalMouldTextBox.IsEnabled = false;
L1AdditionalMouldTextBox.Background = Brushes.Gray;
}
}
#region Event Handlers
private void OnClosed(object sender, EventArgs e)

View File

@@ -28,7 +28,8 @@
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition Width="4*"/>
<ColumnDefinition Width="3*"/>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
@@ -45,6 +46,7 @@
/>
<Button Margin="0 0 10 10" Grid.Column="3" Height="22" Width="60" Content="Clear" HorizontalAlignment="Right" Click="OnClearButton" />
<Button Margin="0 0 10 10" Grid.Column="4" Height="22" Width="60" Content="Hide" HorizontalAlignment="Right" Click="OnHideButton" />
<Button Margin="0 0 10 10" Grid.Column="5" Height="22" Width="60" Content="Save" HorizontalAlignment="Right" Click="OnSaveButton" />
<Button Visibility="Hidden" Name="AbortButton" Margin="0 0 10 10" Grid.Column="2" Height="22" Width="80" Content="Abort" HorizontalAlignment="Right" Click="OnAbortButton" />
</Grid>

View File

@@ -363,6 +363,20 @@ namespace DICUI.Windows
{
output.Document.Blocks.Clear();
}
private void OnSaveButton(object sender, EventArgs e)
{
using (StreamWriter tw = new StreamWriter(File.OpenWrite("console.log")))
{
foreach (var inline in _paragraph.Inlines)
{
if (inline is Run)
{
tw.Write(((Run)(inline)).Text);
}
}
}
}
private void OnAbortButton(object sender, EventArgs args)
{

View File

@@ -5,7 +5,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:DICUI"
mc:Ignorable="d"
Title="Disc Image Creator GUI" Height="450" Width="600" WindowStartupLocation="CenterScreen" ResizeMode="CanMinimize"
Title="DICUI" Height="450" Width="600" WindowStartupLocation="CenterScreen" ResizeMode="CanMinimize"
LocationChanged="MainWindowLocationChanged" Activated="MainWindowActivated" Closing="MainWindowClosing">
<Window.Resources>
@@ -27,17 +27,18 @@
<StackPanel VerticalAlignment="Top" Grid.ColumnSpan="4">
<Menu Width="Auto" Height="20" >
<MenuItem Header="_File">
<MenuItem x:Name="AppExit" Header="E_xit" HorizontalAlignment="Left" Width="140" Click="AppExitClick" />
<MenuItem x:Name="AppExit" Header="E_xit" HorizontalAlignment="Left" Width="185" Click="AppExitClick" />
</MenuItem>
<MenuItem Header="_Tools">
<MenuItem x:Name="OptionsMenuItem" Header="_Options" HorizontalAlignment="Left" Width="140" Click="OptionsClick"/>
<MenuItem x:Name="ShowLogMenuItem" Header="Show _Log Window" IsCheckable="true" HorizontalAlignment="Left"
<MenuItem x:Name="OptionsMenuItem" Header="_Options" HorizontalAlignment="Left" Width="185" Click="OptionsClick" />
<MenuItem x:Name="ShowLogMenuItem" Header="Show _Log Window" IsCheckable="true" Width="185" HorizontalAlignment="Left"
DataContext="{Binding Source={x:Static local:ViewModels.LoggerViewModel}}"
IsChecked="{Binding Path=WindowVisible}"
/>
</MenuItem>
<MenuItem Header="_Help">
<MenuItem x:Name="About" Header="_About" HorizontalAlignment="Left" Width="140" Click="AboutClick"/>
<MenuItem x:Name="About" Header="_About" HorizontalAlignment="Left" Width="185" Click="AboutClick" />
<MenuItem x:Name="CheckForUpdatesMenuItem" Header="_Check for Updates" HorizontalAlignment="Left" Width="185" Click="CheckForUpdatesClick" />
</MenuItem>
</Menu>
</StackPanel>

View File

@@ -3,12 +3,14 @@ using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;
using WinForms = System.Windows.Forms;
using DICUI.Data;
using DICUI.Utilities;
using DICUI.Web;
using Newtonsoft.Json.Linq;
namespace DICUI.Windows
{
@@ -24,7 +26,7 @@ namespace DICUI.Windows
private DumpEnvironment _env;
// Option related
private Options _options;
private UIOptions _uiOptions;
private OptionsWindow _optionsWindow;
// User input related
@@ -37,9 +39,8 @@ namespace DICUI.Windows
InitializeComponent();
// Initializes and load Options object
_options = new Options();
_options.Load();
ViewModels.OptionsViewModel = new OptionsViewModel(_options);
_uiOptions = new UIOptions();
ViewModels.OptionsViewModel = new OptionsViewModel(_uiOptions);
_logWindow = new LogWindow(this);
ViewModels.LoggerViewModel.SetWindow(_logWindow);
@@ -49,7 +50,7 @@ namespace DICUI.Windows
DiskScanButton.IsEnabled = false;
CopyProtectScanButton.IsEnabled = false;
if (_options.OpenLogWindowAtStartup)
if (_uiOptions.OpenLogWindowAtStartup)
{
this.WindowStartupLocation = WindowStartupLocation.Manual;
double combinedHeight = this.Height + _logWindow.Height + Constants.LogWindowMarginFromMainWindow;
@@ -71,7 +72,7 @@ namespace DICUI.Windows
_alreadyShown = true;
if (_options.OpenLogWindowAtStartup)
if (_uiOptions.OpenLogWindowAtStartup)
{
//TODO: this should be bound directly to WindowVisible property in two way fashion
// we need to study how to properly do it in XAML
@@ -106,6 +107,12 @@ namespace DICUI.Windows
ViewModels.LoggerViewModel.VerboseLogLn($"Ejecting disc in drive {_env.Drive.Letter}");
_env.EjectDisc();
}
if (_uiOptions.ResetDriveAfterDump)
{
ViewModels.LoggerViewModel.VerboseLogLn($"Resetting drive {_env.Drive.Letter}");
_env.ResetDrive();
}
}
}
@@ -223,11 +230,10 @@ namespace DICUI.Windows
private void AboutClick(object sender, RoutedEventArgs e)
{
MessageBox.Show($"ReignStumble - Project Lead / UI Design{Environment.NewLine}" +
$"darksabre76 - Project Co-Lead / Backend Design{Environment.NewLine}" +
$"Jakz - Feature Contributor{Environment.NewLine}" +
$"NHellFire - Feature Contributor{Environment.NewLine}" +
$"Dizzzy - Concept/Ideas/Beta tester{Environment.NewLine}", "About", MessageBoxButton.OK, MessageBoxImage.Information);
MessageBox.Show($"darksabre76 - Project Lead / Backend Design"
+ $"{Environment.NewLine}ReignStumble - Former Project Lead / UI Design"
+ $"{Environment.NewLine}Jakz - Primary Feature Contributor"
+ $"{Environment.NewLine}NHellFire - Feature Contributor", "About", MessageBoxButton.OK, MessageBoxImage.Information);
}
private void OptionsClick(object sender, RoutedEventArgs e)
@@ -235,7 +241,7 @@ namespace DICUI.Windows
// lazy initialization
if (_optionsWindow == null)
{
_optionsWindow = new OptionsWindow(this, _options);
_optionsWindow = new OptionsWindow(this, _uiOptions);
_optionsWindow.Closed += delegate
{
_optionsWindow = null;
@@ -248,8 +254,43 @@ namespace DICUI.Windows
_optionsWindow.Show();
}
private void CheckForUpdatesClick(object sender, RoutedEventArgs e)
{
// Get the current internal version
var assemblyVersion = Assembly.GetEntryAssembly().GetName().Version;
string version = $"{assemblyVersion.Major}.{assemblyVersion.Minor}" + (assemblyVersion.MajorRevision != 0 ? $".{assemblyVersion.MajorRevision}" : string.Empty);
// Get the latest tag from GitHub
using (var client = new CookieAwareWebClient())
{
client.Headers["User-Agent"] = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:64.0) Gecko/20100101 Firefox/64.0";
// TODO: Figure out a better way than having this hardcoded...
string url = "https://api.github.com/repos/SabreTools/DICUI/releases/latest";
string latestReleaseJsonString = client.DownloadString(url);
var latestReleaseJson = JObject.Parse(latestReleaseJsonString);
string latestTag = latestReleaseJson["tag_name"].ToString();
string releaseUrl = latestReleaseJson["html_url"].ToString();
bool different = version != latestTag;
string message = $"Local version: {version}"
+ $"{Environment.NewLine}Remote version: {latestTag}"
+ (different
? $"{Environment.NewLine}The update URL has been added copied to your clipboard"
: $"{Environment.NewLine}You have the newest version!");
// If we have a new version, put it in the clipboard
if (different)
Clipboard.SetText(releaseUrl);
MessageBox.Show(message, "Version Update Check", MessageBoxButton.OK, different ? MessageBoxImage.Exclamation : MessageBoxImage.Information);
}
}
public void OnOptionsUpdated()
{
PopulateDrives();
GetOutputNames(false);
SetSupportedDriveSpeed();
EnsureDiscInformation();
@@ -327,7 +368,7 @@ namespace DICUI.Windows
DiskScanButton.IsEnabled = true;
// Populate the list of drives and add it to the combo box
_drives = Validators.CreateListOfDrives();
_drives = Validators.CreateListOfDrives(_uiOptions.IgnoreFixedDrives);
DriveLetterComboBox.ItemsSource = _drives;
if (DriveLetterComboBox.Items.Count > 0)
@@ -349,7 +390,7 @@ namespace DICUI.Windows
CopyProtectScanButton.IsEnabled = true;
// Get the current media type
if (!_options.SkipSystemDetection && index != -1)
if (!_uiOptions.SkipSystemDetection && index != -1)
{
ViewModels.LoggerViewModel.VerboseLog("Trying to detect system for drive {0}.. ", _drives[index].Letter);
var currentSystem = Validators.GetKnownSystem(_drives[index]);
@@ -399,36 +440,13 @@ namespace DICUI.Windows
private DumpEnvironment DetermineEnvironment()
{
// Populate the new environment
var env = new DumpEnvironment()
{
// Paths to tools
SubdumpPath = _options.SubDumpPath,
DICPath = _options.DICPath,
OutputDirectory = OutputDirectoryTextBox.Text,
OutputFilename = OutputFilenameTextBox.Text,
// Get the currently selected options
Drive = DriveLetterComboBox.SelectedItem as Drive,
DICParameters = new Parameters(ParametersTextBox.Text),
QuietMode = _options.QuietMode,
ParanoidMode = _options.ParanoidMode,
ScanForProtection = _options.ScanForProtection,
RereadAmountC2 = _options.RereadAmountForC2,
AddPlaceholders = _options.AddPlaceholders,
PromptForDiscInformation = _options.PromptForDiscInformation,
Username = _options.Username,
Password = _options.Password,
System = SystemTypeComboBox.SelectedItem as KnownSystemComboBoxItem,
Type = MediaTypeComboBox.SelectedItem as MediaType?,
};
// Fix the output paths
env.FixOutputPaths();
var env = new DumpEnvironment(_uiOptions.Options,
OutputDirectoryTextBox.Text,
OutputFilenameTextBox.Text,
DriveLetterComboBox.SelectedItem as Drive,
SystemTypeComboBox.SelectedItem as KnownSystemComboBoxItem,
MediaTypeComboBox.SelectedItem as MediaType?,
ParametersTextBox.Text);
// Disable automatic reprocessing of the textboxes until we're done
OutputDirectoryTextBox.TextChanged -= OutputDirectoryTextBoxTextChanged;
@@ -448,8 +466,8 @@ namespace DICUI.Windows
/// </summary>
private async void StartDumping()
{
if (_env == null)
_env = DetermineEnvironment();
// One last check to determine environment, just in case
_env = DetermineEnvironment();
// If still in custom parameter mode, check that users meant to continue or not
if (EnableParametersCheckBox.IsChecked == true)
@@ -466,16 +484,11 @@ namespace DICUI.Windows
// If "No", then we continue with the current known environment
}
// Fix the output paths
_env.FixOutputPaths();
try
{
// Check for the firmware first
// TODO: Remove this (and method) once DIC end-to-end logging becomes a thing
if (!await _env.DriveHasLatestFimrware())
{
MessageBox.Show($"DiscImageCreator has reported that drive {_env.Drive.Letter} is not updated to the most recent firmware. Please update the firmware for your drive and try again.", "Outdated Firmware", MessageBoxButton.OK, MessageBoxImage.Error);
return;
}
// Validate that the user explicitly wants an inactive drive to be considered for dumping
if (!_env.Drive.MarkedActive)
{
@@ -505,12 +518,24 @@ namespace DICUI.Windows
var progress = new Progress<Result>();
progress.ProgressChanged += ProgressUpdated;
Result result = await _env.StartDumping(progress);
Result result = await _env.Run(progress);
// If we didn't execute a dumping command we cannot get submission output
if (!_env.Parameters.IsDumpingCommand())
{
ViewModels.LoggerViewModel.VerboseLogLn("No dumping command was run, submission information will not be gathered.");
StatusLabel.Content = "Execution complete!";
StartStopButton.Content = Constants.StartDumping;
CopyProtectScanButton.IsEnabled = true;
return;
}
if (result)
{
// Verify dump output and save it
result = _env.VerifyAndSaveDumpOutput(progress,
EjectWhenDoneCheckBox.IsChecked,
_uiOptions.ResetDriveAfterDump,
(si) =>
{
// lazy initialization
@@ -543,12 +568,6 @@ namespace DICUI.Windows
StartStopButton.Content = Constants.StartDumping;
CopyProtectScanButton.IsEnabled = true;
}
if (EjectWhenDoneCheckBox.IsChecked == true)
{
ViewModels.LoggerViewModel.VerboseLogLn($"Ejecting disc in drive {_env.Drive.Letter}");
_env.EjectDisc();
}
}
/// <summary>
@@ -598,15 +617,18 @@ namespace DICUI.Windows
// Set the output directory, if we changed drives or it's not already
if (driveChanged || string.IsNullOrEmpty(OutputDirectoryTextBox.Text))
OutputDirectoryTextBox.Text = Path.Combine(_options.DefaultOutputPath, drive?.VolumeLabel ?? string.Empty);
OutputDirectoryTextBox.Text = Path.Combine(_uiOptions.DefaultOutputPath, drive?.VolumeLabel ?? string.Empty);
// Get the extension for the file for the next two statements
string extension = _env.GetExtension(mediaType);
// Set the output filename, if we changed drives or it's not already
if (driveChanged || string.IsNullOrEmpty(OutputFilenameTextBox.Text))
OutputFilenameTextBox.Text = (drive?.VolumeLabel ?? systemType.LongName()) + (mediaType.Extension() ?? ".bin");
OutputFilenameTextBox.Text = (drive?.VolumeLabel ?? systemType.LongName()) + (extension ?? ".bin");
// If the extension for the file changed, update that automatically
else if (Path.GetExtension(OutputFilenameTextBox.Text) != mediaType.Extension())
OutputFilenameTextBox.Text = Path.GetFileNameWithoutExtension(OutputFilenameTextBox.Text) + (mediaType.Extension() ?? ".bin");
else if (Path.GetExtension(OutputFilenameTextBox.Text) != extension)
OutputFilenameTextBox.Text = Path.GetFileNameWithoutExtension(OutputFilenameTextBox.Text) + (extension ?? ".bin");
}
/// <summary>
@@ -628,6 +650,14 @@ namespace DICUI.Windows
CopyProtectScanButton.IsEnabled = false;
string protections = await Validators.RunProtectionScanOnPath(_env.Drive.Letter + ":\\");
// If SmartE is detected on the current disc, remove `/sf` from the flags for DIC only
if (_env.InternalProgram == InternalProgram.DiscImageCreator && protections.Contains("SmartE"))
{
((DiscImageCreator.Parameters)_env.Parameters)[DiscImageCreator.Flag.ScanFileProtect] = false;
ViewModels.LoggerViewModel.VerboseLogLn($"SmartE detected, removing {DiscImageCreator.FlagStrings.ScanFileProtect} from parameters");
}
if (!ViewModels.LoggerViewModel.WindowVisible)
MessageBox.Show(protections, "Detected Protection", MessageBoxButton.OK, MessageBoxImage.Information);
ViewModels.LoggerViewModel.VerboseLog("Detected the following protections in {0}:\r\n\r\n{1}", _env.Drive.Letter, protections);
@@ -649,38 +679,10 @@ namespace DICUI.Windows
DriveSpeedComboBox.ItemsSource = values;
ViewModels.LoggerViewModel.VerboseLogLn("Supported media speeds: {0}", string.Join(",", values));
// Find the minimum set to compare against
int preferred = 100;
switch (_currentMediaType)
{
case MediaType.CDROM:
case MediaType.GDROM:
preferred = _options.PreferredDumpSpeedCD;
break;
case MediaType.DVD:
case MediaType.HDDVD:
case MediaType.NintendoGameCubeGameDisc:
case MediaType.NintendoWiiOpticalDisc:
preferred = _options.PreferredDumpSpeedDVD;
break;
case MediaType.BluRay:
preferred = _options.PreferredDumpSpeedBD;
break;
default:
preferred = _options.PreferredDumpSpeedCD;
break;
}
// Choose the lower of the two speeds between the allowed speeds and the user-defined one
// TODO: Inform more users about setting preferences in the settings so this comparison doesn't need to happen
int chosenSpeed = Math.Min(
values.Where(s => s <= values[values.Count / 2]).Last(),
preferred
);
// Set the selected speed
ViewModels.LoggerViewModel.VerboseLogLn("Setting drive speed to: {0}", chosenSpeed);
DriveSpeedComboBox.SelectedValue = chosenSpeed;
int speed = _uiOptions.GetPreferredDumpSpeedForMediaType(_currentMediaType);
ViewModels.LoggerViewModel.VerboseLogLn("Setting drive speed to: {0}", speed);
DriveSpeedComboBox.SelectedValue = speed;
}
/// <summary>
@@ -689,12 +691,12 @@ namespace DICUI.Windows
private void CacheCurrentDiscType()
{
// Get the drive letter from the selected item
Drive drive = DriveLetterComboBox.SelectedItem as Drive;
var drive = DriveLetterComboBox.SelectedItem as Drive;
if (drive == null)
return;
// Get the current media type
if (!_options.SkipMediaTypeDetection)
if (!_uiOptions.SkipMediaTypeDetection)
{
ViewModels.LoggerViewModel.VerboseLog("Trying to detect media type for drive {0}.. ", drive.Letter);
_currentMediaType = Validators.GetMediaType(drive);
@@ -724,19 +726,21 @@ namespace DICUI.Windows
/// </summary>
private void ProcessCustomParameters()
{
_env.DICParameters = new Parameters(ParametersTextBox.Text);
_env.SetParameters(ParametersTextBox.Text);
if (_env.Parameters == null)
return;
int driveIndex = _drives.Select(d => d.Letter).ToList().IndexOf(_env.DICParameters.DriveLetter[0]);
int driveIndex = _drives.Select(d => d.Letter).ToList().IndexOf(_env.Parameters.InputPath()[0]);
if (driveIndex > -1)
DriveLetterComboBox.SelectedIndex = driveIndex;
int driveSpeed = _env.DICParameters.DriveSpeed ?? -1;
int driveSpeed = _env.Parameters.GetSpeed() ?? -1;
if (driveSpeed > 0)
DriveSpeedComboBox.SelectedValue = driveSpeed;
else
_env.DICParameters.DriveSpeed = (int?)DriveSpeedComboBox.SelectedValue;
_env.Parameters.SetSpeed((int?)DriveSpeedComboBox.SelectedValue);
string trimmedPath = _env.DICParameters.Filename?.Trim('"') ?? string.Empty;
string trimmedPath = _env.Parameters.OutputPath()?.Trim('"') ?? string.Empty;
string outputDirectory = Path.GetDirectoryName(trimmedPath);
string outputFilename = Path.GetFileName(trimmedPath);
if (!string.IsNullOrWhiteSpace(outputDirectory))
@@ -748,7 +752,7 @@ namespace DICUI.Windows
else
outputFilename = OutputFilenameTextBox.Text;
MediaType? mediaType = _env.DICParameters.Command.ToMediaType();
MediaType? mediaType = _env.Parameters.GetMediaType();
int mediaTypeIndex = _mediaTypes.IndexOf(mediaType);
if (mediaTypeIndex > -1)
MediaTypeComboBox.SelectedIndex = mediaTypeIndex;

View File

@@ -5,13 +5,13 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:DICUI"
mc:Ignorable="d"
Title="Options" Height="580" Width="515.132">
Title="Options" Width="515.132" Height="605">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="150"/>
<RowDefinition Height="100"/>
<RowDefinition Height="150"/>
<RowDefinition Height="150"/>
<RowDefinition Height="80"/>
<RowDefinition Height="40"/>
</Grid.RowDefinitions>
@@ -29,19 +29,40 @@
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Label Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="DiscImageCreator Path" />
<TextBox x:Name="DICPathTextBox" Grid.Row="0" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" />
<Button x:Name="DICPathButton" Grid.Row="0" Grid.Column="2" Height="22" Width="22" Content="..." Click="BrowseForPathClick" />
<Label Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Aaru Path" />
<TextBox x:Name="AaruPathTextBox" Grid.Row="0" Grid.Column="1" Height="22" HorizontalAlignment="Stretch"
DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
Text="{Binding Path=AaruPath}" />
<Button x:Name="AaruPathButton" Grid.Row="0" Grid.Column="2" Height="22" Width="22" Content="..." Click="BrowseForPathClick" />
<Label Grid.Row="1" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="subdump Path" />
<TextBox x:Name="SubDumpPathTextBox" Grid.Row="1" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" />
<Button x:Name="SubDumpPathButton" Grid.Row="1" Grid.Column="2" Height="22" Width="22" Content="..." Click="BrowseForPathClick"/>
<Label Grid.Row="1" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="DiscImageCreator Path" />
<TextBox x:Name="CreatorPathTextBox" Grid.Row="1" Grid.Column="1" Height="22" HorizontalAlignment="Stretch"
DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
Text="{Binding Path=CreatorPath}" />
<Button x:Name="CreatorPathButton" Grid.Row="1" Grid.Column="2" Height="22" Width="22" Content="..." Click="BrowseForPathClick" />
<Label Grid.Row="2" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Default Output Path" />
<TextBox x:Name="DefaultOutputPathTextBox" Grid.Row="2" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" />
<Button x:Name="DefaultOutputPathButton" Grid.Row="2" Grid.Column="2" Height="22" Width="22" Content="..." Click="BrowseForPathClick" />
<!--
<Label Grid.Row="1" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="DD Path" />
<TextBox x:Name="DDPathTextBox" Grid.Row="1" Grid.Column="1" Height="22" HorizontalAlignment="Stretch"
DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
Text="{Binding Path=DDPath}" />
<Button x:Name="DDPathButton" Grid.Row="1" Grid.Column="2" Height="22" Width="22" Content="..." Click="BrowseForPathClick" />
-->
<Label Grid.Row="2" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="subdump Path" />
<TextBox x:Name="SubDumpPathTextBox" Grid.Row="2" Grid.Column="1" Height="22" HorizontalAlignment="Stretch"
DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
Text="{Binding Path=SubDumpPath}" />
<Button x:Name="SubDumpPathButton" Grid.Row="2" Grid.Column="2" Height="22" Width="22" Content="..." Click="BrowseForPathClick"/>
<Label Grid.Row="3" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Default Output Path" />
<TextBox x:Name="DefaultOutputPathTextBox" Grid.Row="3" Grid.Column="1" Height="22" HorizontalAlignment="Stretch"
DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
Text="{Binding Path=DefaultOutputPath}" />
<Button x:Name="DefaultOutputPathButton" Grid.Row="3" Grid.Column="2" Height="22" Width="22" Content="..." Click="BrowseForPathClick" />
</Grid>
<GroupBox Grid.Row="1" Margin="5,5,5,5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Header="Preferred Dump Speed">
@@ -59,16 +80,28 @@
</Grid.RowDefinitions>
<Label Grid.Row="0" Grid.Column="0" Content="CD-ROM" />
<Slider x:Name="DumpSpeedCDSlider" Grid.Row="0" Grid.Column="1" Minimum="1" Maximum="72" IsSnapToTickEnabled="True" TickPlacement="BottomRight" Ticks="{Binding Source={x:Static local:Constants.SpeedsForCDAsCollection}}" />
<TextBox x:Name="DumpSpeedCDTextBox" Grid.Row="0" Grid.Column="2" Width="22" Height="22" TextAlignment="Center" IsReadOnly="True" IsReadOnlyCaretVisible="False" VerticalAlignment="Center" Text="{Binding ElementName=DumpSpeedCDSlider, Path=Value, UpdateSourceTrigger=PropertyChanged}" Background="LightGray" Foreground="Gray"/>
<Slider x:Name="DumpSpeedCDSlider" Grid.Row="0" Grid.Column="1" Minimum="1" Maximum="72" IsSnapToTickEnabled="True" TickPlacement="BottomRight"
Ticks="{Binding Source={x:Static local:Constants.SpeedsForCDAsCollection}}"
DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
Value="{Binding Path=PreferredDumpSpeedCD}" />
<TextBox x:Name="DumpSpeedCDTextBox" Grid.Row="0" Grid.Column="2" Width="22" Height="22" TextAlignment="Center" IsReadOnly="True" IsReadOnlyCaretVisible="False" VerticalAlignment="Center"
Text="{Binding ElementName=DumpSpeedCDSlider, Path=Value, UpdateSourceTrigger=PropertyChanged}" Background="LightGray" Foreground="Gray"/>
<Label Grid.Row="1" Grid.Column="0" Content="DVD-ROM" />
<Slider x:Name="DumpSpeedDVDSlider" Grid.Row="1" Grid.Column="1" Minimum="1" Maximum="24" IsSnapToTickEnabled="True" TickPlacement="BottomRight" Ticks="{Binding Source={x:Static local:Constants.SpeedsForDVDAsCollection}}" />
<TextBox x:Name="DumpSpeedDVDTextBox" Grid.Row="1" Grid.Column="2" Width="22" Height="22" TextAlignment="Center" IsReadOnly="True" IsReadOnlyCaretVisible="False" VerticalAlignment="Center" Text="{Binding ElementName=DumpSpeedDVDSlider, Path=Value, UpdateSourceTrigger=PropertyChanged}" Background="LightGray" Foreground="Gray"/>
<Slider x:Name="DumpSpeedDVDSlider" Grid.Row="1" Grid.Column="1" Minimum="1" Maximum="24" IsSnapToTickEnabled="True" TickPlacement="BottomRight"
Ticks="{Binding Source={x:Static local:Constants.SpeedsForDVDAsCollection}}"
DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
Value="{Binding Path=PreferredDumpSpeedDVD}" />
<TextBox x:Name="DumpSpeedDVDTextBox" Grid.Row="1" Grid.Column="2" Width="22" Height="22" TextAlignment="Center" IsReadOnly="True" IsReadOnlyCaretVisible="False" VerticalAlignment="Center"
Text="{Binding ElementName=DumpSpeedDVDSlider, Path=Value, UpdateSourceTrigger=PropertyChanged}" Background="LightGray" Foreground="Gray"/>
<Label Grid.Row="2" Grid.Column="0" Content="BD-ROM" />
<Slider x:Name="DumpSpeedBDSlider" Grid.Row="2" Grid.Column="1" Minimum="1" Maximum="16" IsSnapToTickEnabled="True" TickPlacement="BottomRight" Ticks="{Binding Source={x:Static local:Constants.SpeedsForBDAsCollection}}" />
<TextBox x:Name="DumpSpeedBDTextBox" Grid.Row="2" Grid.Column="2" Width="22" Height="22" TextAlignment="Center" IsReadOnly="True" IsReadOnlyCaretVisible="False" VerticalAlignment="Center" Text="{Binding ElementName=DumpSpeedBDSlider, Path=Value, UpdateSourceTrigger=PropertyChanged}" Background="LightGray" Foreground="Gray"/>
<Slider x:Name="DumpSpeedBDSlider" Grid.Row="2" Grid.Column="1" Minimum="1" Maximum="16" IsSnapToTickEnabled="True" TickPlacement="BottomRight"
Ticks="{Binding Source={x:Static local:Constants.SpeedsForBDAsCollection}}"
DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
Value="{Binding Path=PreferredDumpSpeedBD}" />
<TextBox x:Name="DumpSpeedBDTextBox" Grid.Row="2" Grid.Column="2" Width="22" Height="22" TextAlignment="Center" IsReadOnly="True" IsReadOnlyCaretVisible="False" VerticalAlignment="Center"
Text="{Binding ElementName=DumpSpeedBDSlider, Path=Value, UpdateSourceTrigger=PropertyChanged}" Background="LightGray" Foreground="Gray"/>
</Grid>
@@ -84,58 +117,64 @@
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="24*" />
<RowDefinition Height="13*" />
<RowDefinition Height="11*"/>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<CheckBox Grid.Column="0" VerticalAlignment="Center" Content="Quiet Mode"
DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
IsChecked="{Binding Path=QuietMode}"
ToolTip="Disable DiscImageCreator sounds" Margin="0,4"
<CheckBox Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" Content="Quiet Mode"
DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
IsChecked="{Binding Path=QuietMode}"
ToolTip="Disable DiscImageCreator sounds" Margin="0,4"
/>
<CheckBox Grid.Column="1" VerticalAlignment="Center" Content="Paranoid Mode"
DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
<CheckBox Grid.Row="0" Grid.Column="1" VerticalAlignment="Center" Content="Paranoid Mode"
DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
IsChecked="{Binding Path=ParanoidMode}"
ToolTip="Enable pedantic and super-safe flags" Margin="0,4"
ToolTip="Enable pedantic and super-safe flags" Margin="0,4"
/>
<Grid Grid.Column="2" Grid.ColumnSpan="2" Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Content="C2 Reread Tries:" />
<TextBox Grid.Column="1" VerticalAlignment="Center"
<Label Grid.Row="0" Grid.Column="2" Content="Reread Tries:" VerticalAlignment="Center" HorizontalAlignment="Right"/>
<TextBox Grid.Row="0" Grid.Column="3" VerticalAlignment="Center"
DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
Text="{Binding Path=RereadAmountForC2}"
ToolTip="Specifies how many rereads are attempted on C2 error"
/>
</Grid>
<CheckBox Grid.Column="0" Grid.Row="1" Grid.ColumnSpan="2" VerticalAlignment="Top" Content="Protection Scan"
DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
<CheckBox Grid.Column="0" Grid.Row="1" VerticalAlignment="Center" Content="Protection Scan"
DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
IsChecked="{Binding Path=ScanForProtection}"
ToolTip="Enable automatic checking for copy protection on dumped media" Margin="0,4,0,0" Grid.RowSpan="2"
ToolTip="Enable automatic checking for copy protection on dumped media" Margin="0,4,0,0"
/>
<CheckBox Grid.Column="1" Grid.Row="1" VerticalAlignment="Center" Content="Skip Type Detect"
DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
<CheckBox Grid.Column="1" Grid.Row="1" VerticalAlignment="Center" Content="Skip Type Detect"
DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
IsChecked="{Binding Path=SkipMediaTypeDetection}"
ToolTip="Disable trying to guess media type inserted (may improve performance at startup)" Margin="0,4" Grid.RowSpan="2"
ToolTip="Disable trying to guess media type inserted (may improve performance at startup)" Margin="0,4"
/>
<CheckBox Grid.Column="2" Grid.Row="1" VerticalAlignment="Center" Content="Add Placeholders"
DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
<CheckBox Grid.Row="1" Grid.Column="2" VerticalAlignment="Center" Content="Add Placeholders"
DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
IsChecked="{Binding Path=AddPlaceholders}"
ToolTip="Enable adding placeholder text in the submissioninfo output for required and optional fields" Margin="0,4" Grid.RowSpan="2"
ToolTip="Enable adding placeholder text in the submissioninfo output for required and optional fields" Margin="0,4"
/>
<CheckBox Grid.Column="3" Grid.Row="1" VerticalAlignment="Center" Content="Show Disc Info"
DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
<CheckBox Grid.Row="2" Grid.Column="0" VerticalAlignment="Center" Content="Show Disc Info"
DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
IsChecked="{Binding Path=PromptForDiscInformation}"
ToolTip="Enable showing the disc information output after dumping" Margin="0,4" Grid.RowSpan="2"
ToolTip="Enable showing the disc information output after dumping" Margin="0,4"
/>
<CheckBox Grid.Row="2" Grid.Column="1" VerticalAlignment="Center" Content="No Fixed Drives"
DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
IsChecked="{Binding Path=IgnoreFixedDrives}"
ToolTip="Ignore hard drives and other fixed drives" Margin="0,4"
/>
<CheckBox Grid.Row="2" Grid.Column="2" VerticalAlignment="Center" Content="Reset After Dump"
DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
IsChecked="{Binding Path=ResetDriveAfterDump}"
ToolTip="Reset disc drives after dumping; useful for some older machines" Margin="0,4"
/>
</Grid>
@@ -148,6 +187,7 @@
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1.2*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
@@ -155,10 +195,14 @@
</Grid.RowDefinitions>
<Label Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Username" />
<TextBox x:Name="RedumpUsernameTextBox" Grid.Row="0" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" />
<TextBox x:Name="RedumpUsernameTextBox" Grid.Row="0" Grid.Column="1" Height="22" HorizontalAlignment="Stretch"
DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
Text="{Binding Path=Username}" />
<Label Grid.Row="0" Grid.Column="2" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Password" />
<TextBox x:Name="RedumpPasswordTextBox" Grid.Row="0" Grid.Column="3" Height="22" HorizontalAlignment="Stretch" />
<PasswordBox x:Name="RedumpPasswordBox" Grid.Row="0" Grid.Column="3" Height="22" HorizontalAlignment="Stretch" PasswordChar="*" />
<Button x:Name="RedumpLoginTestButton" Grid.Row="0" Grid.Column="5" Height="22" Width="80" Content="Test Login" Click="OnRedumpTestClick" />
</Grid>
</GroupBox>

View File

@@ -2,6 +2,7 @@
using System.IO;
using System.Windows;
using System.Windows.Forms;
using DICUI.Web;
using Button = System.Windows.Controls.Button;
using TextBox = System.Windows.Controls.TextBox;
@@ -13,13 +14,13 @@ namespace DICUI.Windows
public partial class OptionsWindow : Window
{
private readonly MainWindow _mainWindow;
private readonly Options _options;
private readonly UIOptions _uiOptions;
public OptionsWindow(MainWindow mainWindow, Options options)
public OptionsWindow(MainWindow mainWindow, UIOptions options)
{
InitializeComponent();
_mainWindow = mainWindow;
_options = options;
_uiOptions = options;
}
private OpenFileDialog CreateOpenFileDialog()
@@ -40,12 +41,6 @@ namespace DICUI.Windows
return dialog;
}
private string[] PathSettings()
{
string[] pathSettings = { "DefaultOutputPath", "DICPath", "SubDumpPath" };
return pathSettings;
}
private TextBox TextBoxForPathSetting(string name)
{
return FindName(name + "TextBox") as TextBox;
@@ -82,7 +77,9 @@ namespace DICUI.Windows
}
if (exists)
{
TextBoxForPathSetting(pathSettingName).Text = path;
}
else
{
System.Windows.MessageBox.Show(
@@ -98,30 +95,18 @@ namespace DICUI.Windows
public void Refresh()
{
Array.ForEach(PathSettings(), setting => TextBoxForPathSetting(setting).Text = _options.Get(setting));
DumpSpeedCDSlider.Value = _options.PreferredDumpSpeedCD;
DumpSpeedDVDSlider.Value = _options.PreferredDumpSpeedDVD;
DumpSpeedBDSlider.Value = _options.PreferredDumpSpeedBD;
RedumpUsernameTextBox.Text = _options.Username;
RedumpPasswordTextBox.Text = _options.Password;
// Handle non-bindable fields
RedumpPasswordBox.Password = _uiOptions.Options.Password;
}
#region Event Handlers
private void OnAcceptClick(object sender, EventArgs e)
{
Array.ForEach(PathSettings(), setting => _options.Set(setting, TextBoxForPathSetting(setting).Text));
// Handle non-bindable fields
_uiOptions.Options.Password = RedumpPasswordBox.Password;
_options.PreferredDumpSpeedCD = Convert.ToInt32(DumpSpeedCDSlider.Value);
_options.PreferredDumpSpeedDVD = Convert.ToInt32(DumpSpeedDVDSlider.Value);
_options.PreferredDumpSpeedBD = Convert.ToInt32(DumpSpeedBDSlider.Value);
_options.Username = RedumpUsernameTextBox.Text;
_options.Password = RedumpPasswordTextBox.Text;
_options.Save();
_uiOptions.Save();
Hide();
_mainWindow.OnOptionsUpdated();
@@ -133,6 +118,21 @@ namespace DICUI.Windows
Hide();
}
/// <summary>
/// Test Redump credentials for validity
/// </summary>
private void OnRedumpTestClick(object sender, EventArgs e)
{
using (CookieAwareWebClient wc = new CookieAwareWebClient())
{
RedumpAccess access = new RedumpAccess();
if (access.RedumpLogin(wc, RedumpUsernameTextBox.Text, RedumpPasswordBox.Password))
System.Windows.MessageBox.Show("Redump login credentials accepted!", "Success", MessageBoxButton.OK, MessageBoxImage.Information);
else
System.Windows.MessageBox.Show("Redump login credentials denied!", "Failure", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
#endregion
}
}

View File

@@ -1,21 +1,27 @@
# DICUI
DiscImageCreator UI in C#
DiscImageCreator/Aaru UI in C#
[![Build status](https://ci.appveyor.com/api/projects/status/3ldav3v0c373jeqa?svg=true)](https://ci.appveyor.com/project/mnadareski/dicui/build/artifacts)
This is a community project, so if you have some time and knowledge to give, we'll be glad to add you to the contributor of this project :)
We are using DiscImageCreator (DIC), created by Sarami, and we would like to thanks him for his great software. The latest release of DIC can be found on [the GitHub page](https://github.com/saramibreak/DiscImageCreator)
DICUI relies on the following projects:
- **Aaru** by Claunia - Dumping - [GitHub](https://github.com/aaru-dps/Aaru)
- **CleanRip** by emu_kidid - Offline dumping - [GitHub](https://github.com/emukidid/cleanrip)
- **DD for Windows* - Dumping - [Homepage](http://www.chrysocome.net/dd);
- **DiscImageCreator** by Sarami - Dumping - [GitHub](https://github.com/saramibreak/DiscImageCreator)
- **BurnOutSharp** - Protection scanning - [GitHub](https://github.com/mnadareski/BurnOutSharp)
- **UnshieldSharp** - Protection scanning - [GitHub](https://github.com/mnadareski/UnshieldSharp)
This project relies on two open-source code ports to help perform copy protection scanning: [BurnOutSharp](https://github.com/mnadareski/BurnOutSharp) and [UnshieldSharp](https://github.com/mnadareski/UnshieldSharp)
**Note:** Both Aaru DiscImageCreator have WIP builds. In general, WIP builds are not supported with new flags or features until they make it into the stable release.
## System Requirements
Even though this is written in C#, this program can only be used on Windows systems due to the base program, DiscImageCreator, being Windows-only. There is some preliminary support for Linux underway, and we will try to integrate with that when the time comes.
Even though this is written in C#, this program can only be used on Windows systems due to one of the base programs, DiscImageCreator, being Windows-only. There is some preliminary support for Linux underway, and we will try to integrate with that when the time comes.
- Windows 7 (newest version of Windows recommended)
- .NET Framework 4.6.2, .NET Framework 4.7.2, or .NET Core 3.0 Runtimes
- .NET Framework 4.6.2, .NET Framework 4.7.2, or .NET Core 3.0 Runtimes (.NET Core 3.0 is not currently functional due to a dependency, please do not use it)
- 128 MB of free RAM
- As much hard drive space as amount of discs you will be dumping (20+ GB recommended)
@@ -49,3 +55,4 @@ These are the tireless individuals who have dedicated countless hours to help te
- **Kludge** - Primary stress tester
- **ajshell1** - Tester
- **eientei95** - Tester
- **VGPC Discord** - Testing and feedback

View File

@@ -1,5 +1,5 @@
# version format
version: 1.15-{build}
version: 1.16-{build}
# pull request template
pull_requests:
@@ -32,17 +32,34 @@ build:
# post-build step
after_build:
- ps: appveyor DownloadFile https://github.com/saramibreak/DiscImageCreator/files/3854216/DiscImageCreator_20191116.zip
- ps: appveyor DownloadFile https://github.com/aaru-dps/Aaru/releases/download/v5.0.1.2884/aaru-5.0.1.2884-1_windows_x64.zip
- ps: appveyor DownloadFile http://www.chrysocome.net/downloads/8ab730cd2a29e76ddd89be1f99357942/dd-0.6beta3.zip
- ps: appveyor DownloadFile https://github.com/saramibreak/DiscImageCreator/files/4426240/DiscImageCreator_20200403.zip
- ps: appveyor DownloadFile https://archive.org/download/subdump_fua_0x28/subdump_fua_0x28.zip
- 7z e DiscImageCreator_20191116.zip -oDICUI\bin\Debug\net462\Programs Release_ANSI\*
- 7z e DiscImageCreator_20191116.zip -oDICUI\bin\Debug\net472\Programs Release_ANSI\*
- 7z e DiscImageCreator_20191116.zip -oDICUI\bin\Debug\netcoreapp3.0\Programs Release_ANSI\*
- 7z e aaru-5.0.1.2884-1_windows_x64.zip -oDICUI\bin\Debug\net462\Programs\Aaru *
- 7z e aaru-5.0.1.2884-1_windows_x64.zip -oDICUI\bin\Debug\net472\Programs\Aaru *
- 7z e aaru-5.0.1.2884-1_windows_x64.zip -oDICUI\bin\Debug\net48\Programs\Aaru *
- 7z e aaru-5.0.1.2884-1_windows_x64.zip -oDICUI\bin\Debug\netcoreapp3.1\Programs\Aaru *
- 7z e dd-0.6beta3.zip -oDICUI\bin\Debug\net462\Programs\DD *
- 7z e dd-0.6beta3.zip -oDICUI\bin\Debug\net472\Programs\DD *
- 7z e dd-0.6beta3.zip -oDICUI\bin\Debug\net48\Programs\DD *
- 7z e dd-0.6beta3.zip -oDICUI\bin\Debug\netcoreapp3.1\Programs\DD *
- 7z e DiscImageCreator_20200403.zip -oDICUI\bin\Debug\net462\Programs\Creator Release_ANSI\*
- 7z e DiscImageCreator_20200403.zip -oDICUI\bin\Debug\net472\Programs\Creator Release_ANSI\*
- 7z e DiscImageCreator_20200403.zip -oDICUI\bin\Debug\net48\Programs\Creator Release_ANSI\*
- 7z e DiscImageCreator_20200403.zip -oDICUI\bin\Debug\netcoreapp3.1\Programs\Creator Release_ANSI\*
- 7z e subdump_fua_0x28.zip -oDICUI\bin\Debug\net462 *
- mv DICUI\bin\Debug\net462\subdump_fua_0x28.exe DICUI\bin\Debug\net462\subdump.exe
- mkdir DICUI\bin\Debug\net462\Programs\Subdump
- mv DICUI\bin\Debug\net462\subdump_fua_0x28.exe DICUI\bin\Debug\net462\Programs\Subdump\subdump.exe
- 7z e subdump_fua_0x28.zip -oDICUI\bin\Debug\net472 *
- mv DICUI\bin\Debug\net472\subdump_fua_0x28.exe DICUI\bin\Debug\net472\subdump.exe
- 7z e subdump_fua_0x28.zip -oDICUI\bin\Debug\netcoreapp3.0 *
- mv DICUI\bin\Debug\netcoreapp3.0\subdump_fua_0x28.exe DICUI\bin\Debug\netcoreapp3.0\subdump.exe
- mkdir DICUI\bin\Debug\net472\Programs\Subdump
- mv DICUI\bin\Debug\net472\subdump_fua_0x28.exe DICUI\bin\Debug\net472\Programs\Subdump\subdump.exe
- 7z e subdump_fua_0x28.zip -oDICUI\bin\Debug\net48 *
- mkdir DICUI\bin\Debug\net48\Programs\Subdump
- mv DICUI\bin\Debug\net48\subdump_fua_0x28.exe DICUI\bin\Debug\net462\Programs\Subdump\subdump.exe
- 7z e subdump_fua_0x28.zip -oDICUI\bin\Debug\netcoreapp3.1 *
- mkdir DICUI\bin\Debug\netcoreapp3.1\Programs\Subdump
- mv DICUI\bin\Debug\netcoreapp3.1\subdump_fua_0x28.exe DICUI\bin\Debug\netcoreapp3.1\Programs\Subdump\subdump.exe
- 7z a DICUI.zip DICUI\bin\Debug\*
- 7z a DICUI-Check.zip DICUI.Check\bin\Debug\*
@@ -51,4 +68,4 @@ artifacts:
- path: DICUI.zip
name: DICUI
- path: DICUI-Check.zip
name: DICUI Check
name: DICUI Check