diff --git a/DICUI.Library/Utilities/Validators.cs b/DICUI.Library/Utilities/Validators.cs index bb23360e..6ebd04af 100644 --- a/DICUI.Library/Utilities/Validators.cs +++ b/DICUI.Library/Utilities/Validators.cs @@ -734,14 +734,14 @@ namespace DICUI.Utilities } /// - /// Get the current disc type from drive letter + /// Get the current media type from drive letter /// /// /// /// /// https://stackoverflow.com/questions/11420365/detecting-if-disc-is-in-dvd-drive /// - public static MediaType? GetDiscType(char? driveLetter) + public static MediaType? GetMediaType(char? driveLetter) { // Get the DeviceID from the current drive letter string deviceId = null; @@ -798,6 +798,74 @@ namespace DICUI.Utilities return null; } + /// + /// Get the current system from drive letter + /// + /// + /// + public static KnownSystem? GetKnownSystem(char? driveLetter) + { + // If no letter is provided, then we can't do anything + if (driveLetter == null) + return null; + + string drivePath = $"{driveLetter}:\\"; + + // If we can't read the media in that drive, we can't do anything + if (!Directory.Exists(drivePath)) + return null; + + // Sega Dreamcast + if (File.Exists(Path.Combine(drivePath, "IP.BIN"))) + { + return KnownSystem.SegaDreamcast; + } + + // Sega Mega-CD / Sega-CD + if (File.Exists(Path.Combine(drivePath, "_BOOT", "IP.BIN")) + || File.Exists(Path.Combine(drivePath, "_BOOT", "SP.BIN")) + || File.Exists(Path.Combine(drivePath, "_BOOT", "SP_AS.BIN")) + || File.Exists(Path.Combine(drivePath, "FILESYSTEM.BIN"))) + { + return KnownSystem.SegaCDMegaCD; + } + + // Sony PlayStation and Sony PlayStation 2 + if (File.Exists(Path.Combine(drivePath, "SYSTEM.CNF"))) + { + // Check for either BOOT or BOOT2 + using (StreamReader reader = File.OpenText(Path.Combine(drivePath, "SYSTEM.CNF"))) + { + while (!reader.EndOfStream) + { + string line = reader.ReadLine(); + if (line.Contains("BOOT2")) + return KnownSystem.SonyPlayStation2; + else if (line.Contains("BOOT")) + return KnownSystem.SonyPlayStation; + } + } + + // If we have a weird disc, just assume PS1 + return KnownSystem.SonyPlayStation; + } + + // Sony PlayStation 4 + if (File.Exists(Path.Combine(drivePath, "PSLogo.ico"))) + { + return KnownSystem.SonyPlayStation4; + } + + // V.Tech V.Flash / V.Smile Pro + if (File.Exists(Path.Combine(drivePath, "0SYSTEM"))) + { + return KnownSystem.VTechVFlashVSmilePro; + } + + // Default return + return KnownSystem.NONE; + } + /// /// Verify that, given a system and a media type, they are correct /// diff --git a/DICUI/App.config b/DICUI/App.config index 2e8b6f96..98b342fd 100644 --- a/DICUI/App.config +++ b/DICUI/App.config @@ -11,6 +11,7 @@ + diff --git a/DICUI/Options.cs b/DICUI/Options.cs index 374a3ce6..303254f2 100644 --- a/DICUI/Options.cs +++ b/DICUI/Options.cs @@ -23,6 +23,7 @@ namespace DICUI public bool AddPlaceholders { get; set; } public bool SkipMediaTypeDetection { get; set; } + public bool SkipSystemDetection { get; set; } public bool VerboseLogging { get; set; } public bool OpenLogWindowAtStartup { get; set; } @@ -64,6 +65,7 @@ namespace DICUI 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); diff --git a/DICUI/ViewModels.cs b/DICUI/ViewModels.cs index 1c7938d0..0256b64a 100644 --- a/DICUI/ViewModels.cs +++ b/DICUI/ViewModels.cs @@ -37,6 +37,12 @@ namespace DICUI set { _options.SkipMediaTypeDetection = value; } } + public bool SkipSystemDetection + { + get { return _options.SkipSystemDetection; } + set { _options.SkipSystemDetection = value; } + } + public string RereadAmountForC2 { get { return Convert.ToString(_options.RereadAmountForC2); } diff --git a/DICUI/Windows/MainWindow.xaml.cs b/DICUI/Windows/MainWindow.xaml.cs index f1ea05d9..fa8561e5 100644 --- a/DICUI/Windows/MainWindow.xaml.cs +++ b/DICUI/Windows/MainWindow.xaml.cs @@ -16,7 +16,7 @@ namespace DICUI.Windows // Private UI-related variables private List _drives; private MediaType? _currentMediaType; - private List _systems; + private List _systems; private List _mediaTypes; private bool _alreadyShown; @@ -282,11 +282,11 @@ namespace DICUI.Windows /// private void PopulateSystems() { - _systems = Validators.CreateListOfSystems(); + var knownSystems = Validators.CreateListOfSystems(); - ViewModels.LoggerViewModel.VerboseLogLn("Populating systems, {0} systems found.", _systems.Count); + ViewModels.LoggerViewModel.VerboseLogLn("Populating systems, {0} systems found.", knownSystems.Count); - Dictionary> mapping = _systems + Dictionary> mapping = knownSystems .GroupBy(s => s.Category()) .ToDictionary( k => k.Key, @@ -295,17 +295,16 @@ namespace DICUI.Windows .ToList() ); - List comboBoxItems = new List(); - - comboBoxItems.Add(new KnownSystemComboBoxItem(KnownSystem.NONE)); + _systems = new List(); + _systems.Add(new KnownSystemComboBoxItem(KnownSystem.NONE)); foreach (var group in mapping) { - comboBoxItems.Add(new KnownSystemComboBoxItem(group.Key)); - group.Value.ForEach(system => comboBoxItems.Add(new KnownSystemComboBoxItem(system))); + _systems.Add(new KnownSystemComboBoxItem(group.Key)); + group.Value.ForEach(system => _systems.Add(new KnownSystemComboBoxItem(system))); } - SystemTypeComboBox.ItemsSource = comboBoxItems; + SystemTypeComboBox.ItemsSource = _systems; SystemTypeComboBox.SelectedIndex = 0; StartStopButton.IsEnabled = false; @@ -331,8 +330,24 @@ namespace DICUI.Windows int index = _drives.FindIndex(d => d.MarkedActive); DriveLetterComboBox.SelectedIndex = (index != -1 ? index : 0); StatusLabel.Content = "Valid drive found! Choose your Media Type"; - StartStopButton.IsEnabled = true; - CopyProtectScanButton.IsEnabled = true; + CopyProtectScanButton.IsEnabled = true; + + // Get the current optical disc type + if (!_options.SkipSystemDetection && index != -1) + { + ViewModels.LoggerViewModel.VerboseLog("Trying to detect system for drive {0}.. ", _drives[index].Letter); + var currentSystem = Validators.GetKnownSystem(_drives[index].Letter); + ViewModels.LoggerViewModel.VerboseLogLn(currentSystem == null || currentSystem == KnownSystem.NONE ? "unable to detect." : ("detected " + currentSystem.LongName() + ".")); + + if (currentSystem != null && currentSystem != KnownSystem.NONE) + { + int sysIndex = _systems.FindIndex(s => s == currentSystem); + SystemTypeComboBox.SelectedIndex = sysIndex; + } + } + + // Only enable the start/stop if we don't have the default selected + StartStopButton.IsEnabled = (SystemTypeComboBox.SelectedItem as KnownSystemComboBoxItem) != KnownSystem.NONE; ViewModels.LoggerViewModel.VerboseLogLn("Found {0} drives: {1}", _drives.Count, String.Join(", ", _drives.Select(d => d.Letter))); } @@ -631,7 +646,7 @@ namespace DICUI.Windows if (!_options.SkipMediaTypeDetection) { ViewModels.LoggerViewModel.VerboseLog("Trying to detect media type for drive {0}.. ", drive.Letter); - _currentMediaType = Validators.GetDiscType(drive.Letter); + _currentMediaType = Validators.GetMediaType(drive.Letter); ViewModels.LoggerViewModel.VerboseLogLn(_currentMediaType == null ? "unable to detect." : ("detected " + _currentMediaType.LongName() + ".")); } }