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; }