From c1bd30e008e91d84a47ea14d6fb0639719f1faec Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Wed, 27 Jun 2018 23:21:52 -0700 Subject: [PATCH] Streamline Callbacks and Ensure MediaType (#78) * Separate drive speeds; better ensuring of media type This is the first attempt at separating out the drive speeds into separate categories. At the moment, it seems to be working just fine for CD and DVD. This also includes some updated code to better ensure that the detected (or selected if the user has changed it) media type is kept between all of the regular changes * Multiple medium * Add more drive speed prototyping * Strip out redundant calls * Separate drive speeds; better ensuring of media type This is the first attempt at separating out the drive speeds into separate categories. At the moment, it seems to be working just fine for CD and DVD. This also includes some updated code to better ensure that the detected (or selected if the user has changed it) media type is kept between all of the regular changes * Multiple medium * Add more drive speed prototyping * Strip out redundant calls * Streamline merge * Comment patrol; keep BluRay a first-class citizen * HD-DVD is supported?! --- Data/Constants.cs | 18 +++++--- MainWindow.xaml.cs | 94 +++++++++++++++++++---------------------- Utilities/Converters.cs | 3 +- Utilities/Validators.cs | 60 +++++++++++++++++--------- 4 files changed, 99 insertions(+), 76 deletions(-) diff --git a/Data/Constants.cs b/Data/Constants.cs index cc884395..4edd9961 100644 --- a/Data/Constants.cs +++ b/Data/Constants.cs @@ -14,11 +14,17 @@ namespace DICUI.Data public const string StopDumping = "Stop Dumping"; public const string FloppyDriveString = "<>"; + // Private lists of known drive speed ranges private static IReadOnlyList AllowedDriveSpeedsForCD { get; } = new List { 1, 2, 3, 4, 6, 8, 12, 16, 20, 24, 32, 40, 44, 48, 52, 56, 72 }; private static IReadOnlyList AllowedDriveSpeedsForDVD { get; } = AllowedDriveSpeedsForCD.Where(s => s <= 24).ToList(); private static IReadOnlyList AllowedDriveSpeedsForBD { get; } = AllowedDriveSpeedsForCD.Where(s => s <= 16).ToList(); - private static IReadOnlyList AllowedDriveSpeedsForUnknownType { get; } = AllowedDriveSpeedsForCD; /*TODO: all or maybe just 1? eg new List { 1 };*/ + private static IReadOnlyList AllowedDriveSpeedsForUnknownType { get; } = AllowedDriveSpeedsForCD; // TODO: All or {1}? Maybe null? + /// + /// Get list of all drive speeds for a given MediaType + /// + /// MediaType? that represents the current item + /// Read-only list of drive speeds public static IReadOnlyList GetAllowedDriveSpeedsForMediaType(MediaType? type) { switch (type) @@ -32,19 +38,19 @@ namespace DICUI.Data case MediaType.WiiOpticalDisc: case MediaType.WiiUOpticalDisc: return AllowedDriveSpeedsForDVD; - //TODO: we should return them all since DIC doens't support them in any case case MediaType.BluRay: return AllowedDriveSpeedsForBD; default: - return AllowedDriveSpeedsForUnknownType; + return AllowedDriveSpeedsForUnknownType; } } - public static DoubleCollection GetDoubleCollectionFromIntList(IReadOnlyList list) - => new DoubleCollection(list.Select(i => Convert.ToDouble(i)).ToList()); - + // Create collections for UI based on known drive speeds public static DoubleCollection AllowedDriveSpeedsForCDAsCollection { get; } = GetDoubleCollectionFromIntList(AllowedDriveSpeedsForCD); public static DoubleCollection AllowedDriveSpeedsForDVDAsCollection { get; } = GetDoubleCollectionFromIntList(AllowedDriveSpeedsForDVD); + public static DoubleCollection AllowedDriveSpeedsForBDAsCollection { get; } = GetDoubleCollectionFromIntList(AllowedDriveSpeedsForBD); + private static DoubleCollection GetDoubleCollectionFromIntList(IReadOnlyList list) + => new DoubleCollection(list.Select(i => Convert.ToDouble(i)).ToList()); } /// diff --git a/MainWindow.xaml.cs b/MainWindow.xaml.cs index d0381047..a22bf157 100644 --- a/MainWindow.xaml.cs +++ b/MainWindow.xaml.cs @@ -39,10 +39,6 @@ namespace DICUI // Populate the list of drives PopulateDrives(); - - // Populate the list of drive speeds - PopulateDriveSpeeds(); - SetSupportedDriveSpeed(); } #region Events @@ -74,32 +70,31 @@ namespace DICUI private void btn_Search_Click(object sender, RoutedEventArgs e) { PopulateDrives(); - SetCurrentDiscType(); - SetSupportedDriveSpeed(); - EnsureDiscInformation(); } private void cmb_SystemType_SelectionChanged(object sender, SelectionChangedEventArgs e) { PopulateMediaTypeAccordingToChosenSystem(); - GetOutputNames(); - EnsureDiscInformation(); } - private void cmb_MediaType_SelectionChanged(object sencder, SelectionChangedEventArgs e) + private void cmb_MediaType_SelectionChanged(object sender, SelectionChangedEventArgs e) { + // Only change the media type if the selection and not the list has changed + if (e.RemovedItems.Count == 1 && e.AddedItems.Count == 1) + { + _currentMediaType = cmb_MediaType.SelectedItem as MediaType?; + } + // TODO: This is giving people the benefit of the doubt that their change is valid - _currentMediaType = cmb_MediaType.SelectedItem as MediaType?; + SetSupportedDriveSpeed(); GetOutputNames(); - EnsureDiscInformation(); } private void cmb_DriveLetter_SelectionChanged(object sender, SelectionChangedEventArgs e) { SetCurrentDiscType(); - SetSupportedDriveSpeed(); GetOutputNames(); - EnsureDiscInformation(); + SetSupportedDriveSpeed(); } private void cmb_DriveSpeed_SelectionChanged(object sender, SelectionChangedEventArgs e) @@ -158,7 +153,7 @@ namespace DICUI cmb_MediaType.ItemsSource = _mediaTypes; cmb_MediaType.IsEnabled = _mediaTypes.Count > 1; - cmb_MediaType.SelectedIndex = 0; + cmb_MediaType.SelectedIndex = (_mediaTypes.IndexOf(_currentMediaType) >= 0 ? _mediaTypes.IndexOf(_currentMediaType) : 0); } else { @@ -199,27 +194,17 @@ namespace DICUI if (cmb_DriveLetter.Items.Count > 0) { cmb_DriveLetter.SelectedIndex = 0; - lbl_Status.Content = "Valid optical disc found! Choose your Disc Type"; + lbl_Status.Content = "Valid media found! Choose your Media Type"; btn_StartStop.IsEnabled = true; } else { cmb_DriveLetter.SelectedIndex = -1; - lbl_Status.Content = "No valid optical disc found!"; + lbl_Status.Content = "No valid media found!"; btn_StartStop.IsEnabled = false; } } - /// - /// Get a complete list of (possible) disc drive speeds, and fill the combo box - /// - private void PopulateDriveSpeeds() - { - var values = UIElements.GetAllowedDriveSpeedsForMediaType(_currentMediaType); - cmb_DriveSpeed.ItemsSource = values; - cmb_DriveSpeed.SelectedIndex = values.Count / 2; - } - /// /// Browse for an output folder /// @@ -349,7 +334,7 @@ namespace DICUI && selectedSystem != KnownSystem.MicrosoftXBOX && selectedSystem != KnownSystem.MicrosoftXBOX360XDG2 && selectedSystem != KnownSystem.MicrosoftXBOX360XDG3 - ? (int)cmb_DriveSpeed.SelectedItem + " " : "") + ? (int?)cmb_DriveSpeed.SelectedItem + " " : "") + string.Join(" ", defaultParams); } } @@ -370,21 +355,11 @@ namespace DICUI // If we're on an unsupported type, update the status accordingly switch (type) { - case MediaType.NONE: - return Result.Failure("Please select a valid disc type"); - case MediaType.GameCubeGameDisc: - case MediaType.GDROM: - return Result.Success("{0} discs are partially supported by DIC", type.Name()); + // Fully supported types + case MediaType.CD: + case MediaType.DVD: case MediaType.HDDVD: - case MediaType.LaserDisc: - case MediaType.CED: - case MediaType.UMD: - case MediaType.WiiOpticalDisc: - case MediaType.WiiUOpticalDisc: - case MediaType.Cartridge: - case MediaType.Cassette: - return Result.Failure("{0} discs are not currently supported by DIC", type.Name()); - default: + case MediaType.BluRay: if (system == KnownSystem.MicrosoftXBOX360XDG3) { return Result.Failure("{0} discs are not currently supported by DIC", type.Name()); @@ -405,15 +380,32 @@ namespace DICUI } else { - return Result.Success("Disc of type {0} found, but the current system does not support it!", type.Name()); + return Result.Success("Disc of type {0} found, but the current system does not support it!", _currentMediaType.Name()); } } - } - break; - } + return Result.Success("{0} ready to dump", type.Name()); - return Result.Success("{0} ready to dump", type.Name()); + // Partially supported types + case MediaType.GDROM: + case MediaType.GameCubeGameDisc: + case MediaType.WiiOpticalDisc: + case MediaType.WiiUOpticalDisc: + return Result.Success("{0} discs are partially supported by DIC", type.Name()); + + // Undumpable but recognized types + case MediaType.LaserDisc: + case MediaType.CED: + case MediaType.UMD: + case MediaType.Cartridge: + case MediaType.Cassette: + return Result.Failure("{0} discs are not currently supported by DIC", type.Name()); + + // Invalid or unknown types + case MediaType.NONE: + default: + return Result.Failure("Please select a valid disc type"); + } } /// @@ -446,8 +438,10 @@ namespace DICUI /// private void SetSupportedDriveSpeed() { - // Set generic drive speed just in case - cmb_DriveSpeed.SelectedItem = 8; + // Set the drive speed list that's appropriate + var values = UIElements.GetAllowedDriveSpeedsForMediaType(_currentMediaType); + cmb_DriveSpeed.ItemsSource = values; + cmb_DriveSpeed.SelectedIndex = values.Count / 2; // Get the drive letter from the selected item var selected = cmb_DriveLetter.SelectedItem as KeyValuePair?; @@ -457,7 +451,7 @@ namespace DICUI } //Validators.GetDriveSpeed((char)selected?.Key); - //Validators.GetDriveSpeedEx((char)selected?.Key, MediaType.CD); + //Validators.GetDriveSpeedEx((char)selected?.Key, _currentMediaType); // Validate that the required program exists and it's not DICUI itself if (!File.Exists(_options.dicPath) || diff --git a/Utilities/Converters.cs b/Utilities/Converters.cs index 260f5745..940c7332 100644 --- a/Utilities/Converters.cs +++ b/Utilities/Converters.cs @@ -262,7 +262,7 @@ namespace DICUI.Utilities case MediaType.GDROM: return DICCommands.GDROM; case MediaType.HDDVD: - return null; + return DICCommands.DigitalVideoDisc; case MediaType.BluRay: return DICCommands.BluRay; @@ -331,6 +331,7 @@ namespace DICUI.Utilities parameters.Add(DICFlags.C2Opcode); parameters.Add("20"); break; case MediaType.HDDVD: + // Currently no defaults set break; case MediaType.BluRay: // Currently no defaults set diff --git a/Utilities/Validators.cs b/Utilities/Validators.cs index 158fa165..51765e17 100644 --- a/Utilities/Validators.cs +++ b/Utilities/Validators.cs @@ -52,7 +52,6 @@ namespace DICUI.Utilities case KnownSystem.MicrosoftXBOX360XDG3: types.Add(MediaType.CD); types.Add(MediaType.DVD); - types.Add(MediaType.HDDVD); break; case KnownSystem.MicrosoftXBOXOne: types.Add(MediaType.BluRay); @@ -546,6 +545,7 @@ namespace DICUI.Utilities /// See if SCSI_MODE_SENSE can be used here /// Currently, the calculations get something that is technically accurate, but is different than the advertisised /// capabilities of the drives (according to QPXTool) + /// TransferRate appears to be the CURRENT transfer rate, not the maximum... basically making that flag useless /// public static int GetDriveSpeed(char driveLetter) { @@ -561,19 +561,17 @@ namespace DICUI.Utilities transferRate = (double?)queryObj["TransferRate"]; } - // Transfer Rates (bps) - double cdTransfer = 150 * 1024; - double dvdTransfer = 1353 * 1024; + // Transfer Rates (kBps) + double cdTransfer = 153.6; + double dvdTransfer = 1385; - double cdTransferTest = ((transferRate ?? -1) * 1024) / cdTransfer; - double cdTransferTestKilo = ((transferRate ?? -1) * 1000) / cdTransfer; - double dvdTransferTest = ((transferRate ?? -1) * 1024) / dvdTransfer; - double dvdTransferTestKilo = ((transferRate ?? -1) * 1000) / dvdTransfer; + double cdTransferTest = ((transferRate ?? -1)) / cdTransfer; + double dvdTransferTest = ((transferRate ?? -1)) / dvdTransfer; return 0; } - public static int GetDriveSpeedEx(char driveLetter, MediaType? mediaType) + public unsafe static int GetDriveSpeedEx(char driveLetter, MediaType? mediaType) { // Get the DeviceID from the current drive letter string deviceId = null; @@ -646,25 +644,49 @@ namespace DICUI.Utilities return -1; } + // Ones that haven't worked: + // recorderEx.GetAdapterDescriptor + // recorderEx.GetDeviceDescriptor + // recorderEx.GetDiscInformation + // recorderEx.GetTrackInformation + + // Now we get the requested feature page + // TODO: Figure out structure of returned data + IntPtr featureData = Marshal.AllocHGlobal(32 * sizeof(byte)); + recorderEx.GetFeaturePage( + ifpt, + (sbyte)0, + featureData, + out uint byteSize); + byte[] outFeatureArray = new byte[byteSize]; + Marshal.Copy(featureData, outFeatureArray, 0, (int)byteSize); + // Now we get the requested mode data + // TODO: Figure out structure of returned data IntPtr modeData = Marshal.AllocHGlobal(256 * sizeof(byte)); recorderEx.GetModePage( - IMAPI_MODE_PAGE_TYPE.IMAPI_MODE_PAGE_TYPE_LEGACY_CAPABILITIES, + (IMAPI_MODE_PAGE_TYPE)0x2A, IMAPI_MODE_PAGE_REQUEST_TYPE.IMAPI_MODE_PAGE_REQUEST_TYPE_CURRENT_VALUES, modeData, out uint modeDataSize); byte[] outModeArray = new byte[modeDataSize]; Marshal.Copy(modeData, outModeArray, 0, (int)modeDataSize); - // Now we get the requested feature page - IntPtr featureData = Marshal.AllocHGlobal(32 * sizeof(byte)); - recorderEx.GetFeaturePage( - ifpt, - (sbyte)1, - featureData, - out uint byteSize); - byte[] outArray = new byte[byteSize]; - Marshal.Copy(featureData, outArray, 0, (int)byteSize); + // Now we send the command to get sense data from the device + // TODO: This seems like the best option, but how is this data structured properly? + byte[] cdbArray = new byte[] { 0x5a, 0x0, 0x2a, 0x00, 0xff, 0x0 }; + byte[] senseBuffer = new byte[256]; + byte[] buffer = new byte[256]; + uint bufferSize = 256; + + recorderEx.SendCommandGetDataFromDevice( + ref cdbArray[0], + (uint)6, + senseBuffer, + (uint)60, + out buffer[0], + bufferSize, + out uint BufferFetched); return -1; }