diff --git a/CHANGELIST.md b/CHANGELIST.md index 23124f4f..69437d93 100644 --- a/CHANGELIST.md +++ b/CHANGELIST.md @@ -85,6 +85,7 @@ - Better get drive list (.NET 6) - Add optical media support method (.NET 6) - Simplify IsOptical (.NET 6) +- Reorganize GetMediaType ### 2.3 (2022-02-05) - Start overhauling Redump information pulling, again diff --git a/MPF.Core/Data/Drive.cs b/MPF.Core/Data/Drive.cs index 3eb69eb7..ec15843c 100644 --- a/MPF.Core/Data/Drive.cs +++ b/MPF.Core/Data/Drive.cs @@ -12,7 +12,6 @@ using IMAPI2; using Aaru.CommonTypes.Enums; using Aaru.Core.Media.Info; using Aaru.Decoders.SCSI.MMC; -using Aaru.Decoders.SCSI.SSC; using Aaru.Devices; #endif @@ -114,95 +113,16 @@ namespace MPF.Core.Data public static List CreateListOfDrives(bool ignoreFixedDrives) { var drives = GetDriveList(ignoreFixedDrives); - drives = drives.OrderBy(i => i.Letter).ToList(); + drives = drives?.OrderBy(i => i.Letter)?.ToList(); return drives; } /// /// Get the current media type from drive letter /// - /// /// public (MediaType?, string) GetMediaType() - { - // Take care of the non-optical stuff first - // TODO: See if any of these can be more granular, like Optical is - if (this.InternalDriveType == Data.InternalDriveType.Floppy) - return (MediaType.FloppyDisk, null); - else if (this.InternalDriveType == Data.InternalDriveType.HardDisk) - return (MediaType.HardDisk, null); - else if (this.InternalDriveType == Data.InternalDriveType.Removable) - return (MediaType.FlashDrive, null); - -#if NETFRAMEWORK - // Get the current drive information - string deviceId = null; - bool loaded = false; - try - { - // Get the device ID first - var searcher = new ManagementObjectSearcher( - "root\\CIMV2", - $"SELECT * FROM Win32_CDROMDrive WHERE Id = '{this.Letter}:\'"); - - foreach (ManagementObject queryObj in searcher.Get()) - { - deviceId = (string)queryObj["DeviceID"]; - loaded = (bool)queryObj["MediaLoaded"]; - } - - // If we got no valid device, we don't care and just return - if (deviceId == null) - return (null, "Device could not be found"); - else if (!loaded) - return (null, "Device is not reporting media loaded"); - - MsftDiscMaster2 discMaster = new MsftDiscMaster2(); - deviceId = deviceId.ToLower().Replace('\\', '#').Replace('/', '#'); - string id = null; - foreach (var disc in discMaster) - { - if (disc.ToString().Contains(deviceId)) - id = disc.ToString(); - } - - // If we couldn't find the drive, we don't care and return - if (id == null) - return (null, "Device ID could not be found"); - - // Create the required objects for reading from the drive - MsftDiscRecorder2 recorder = new MsftDiscRecorder2(); - recorder.InitializeDiscRecorder(id); - MsftDiscFormat2Data dataWriter = new MsftDiscFormat2Data(); - - // If the recorder is not supported, just return - if (!dataWriter.IsRecorderSupported(recorder)) - return (null, "IMAPI2 recorder not supported"); - - // Otherwise, set the recorder to get information from - dataWriter.Recorder = recorder; - - var media = dataWriter.CurrentPhysicalMediaType; - return (media.IMAPIToMediaType(), null); - } - catch (Exception ex) - { - return (null, ex.Message); - } -#else - try - { - // TODO: Get the device type for devices with set media types - // TODO: Follow same pattern as GetDriveList and call the same named helper - var aaruMediaType = GetMediaType(this.Name); - return (EnumConverter.MediaTypeToMediaType(aaruMediaType), null); - } - catch (Exception ex) - { - return (null, ex.Message); - } -#endif - } + => GetMediaType(this.Name, this.InternalDriveType); /// /// Get the current system from drive @@ -509,6 +429,81 @@ namespace MPF.Core.Data return drives; } + /// + /// Get the media type for a device path using the Aaru libraries + /// + /// Path to the device + /// Current internal drive type + /// MediaType, null on error + private static (MediaType?, string) GetMediaType(string devicePath, InternalDriveType? internalDriveType) + { + char driveLetter = devicePath == null || !devicePath.Any() ? '\0' : devicePath[0]; + + // Take care of the non-optical stuff first + // TODO: See if any of these can be more granular, like Optical is + if (internalDriveType == Data.InternalDriveType.Floppy) + return (MediaType.FloppyDisk, null); + else if (internalDriveType == Data.InternalDriveType.HardDisk) + return (MediaType.HardDisk, null); + else if (internalDriveType == Data.InternalDriveType.Removable) + return (MediaType.FlashDrive, null); + + // Get the current drive information + string deviceId = null; + bool loaded = false; + try + { + // Get the device ID first + var searcher = new ManagementObjectSearcher( + "root\\CIMV2", + $"SELECT * FROM Win32_CDROMDrive WHERE Id = '{driveLetter}:\'"); + + foreach (ManagementObject queryObj in searcher.Get()) + { + deviceId = (string)queryObj["DeviceID"]; + loaded = (bool)queryObj["MediaLoaded"]; + } + + // If we got no valid device, we don't care and just return + if (deviceId == null) + return (null, "Device could not be found"); + else if (!loaded) + return (null, "Device is not reporting media loaded"); + + MsftDiscMaster2 discMaster = new MsftDiscMaster2(); + deviceId = deviceId.ToLower().Replace('\\', '#').Replace('/', '#'); + string id = null; + foreach (var disc in discMaster) + { + if (disc.ToString().Contains(deviceId)) + id = disc.ToString(); + } + + // If we couldn't find the drive, we don't care and return + if (id == null) + return (null, "Device ID could not be found"); + + // Create the required objects for reading from the drive + MsftDiscRecorder2 recorder = new MsftDiscRecorder2(); + recorder.InitializeDiscRecorder(id); + MsftDiscFormat2Data dataWriter = new MsftDiscFormat2Data(); + + // If the recorder is not supported, just return + if (!dataWriter.IsRecorderSupported(recorder)) + return (null, "IMAPI2 recorder not supported"); + + // Otherwise, set the recorder to get information from + dataWriter.Recorder = recorder; + + var media = dataWriter.CurrentPhysicalMediaType; + return (media.IMAPIToMediaType(), null); + } + catch (Exception ex) + { + return (null, ex.Message); + } + } + #else /// @@ -607,8 +602,12 @@ namespace MPF.Core.Data /// Get the media type for a device path using the Aaru libraries /// /// Path to the device - /// Aaru MediaType, null on error - private static Aaru.CommonTypes.MediaType? GetMediaType(string devicePath) + /// Current internal drive type + /// MediaType, null on error + /// + /// TODO: Get the device type for devices with set media types + /// + private static (MediaType?, string) GetMediaType(string devicePath, InternalDriveType? internalDriveType) { if (devicePath.Length == 2 && devicePath[1] == ':' && @@ -618,17 +617,21 @@ namespace MPF.Core.Data var dev = Device.Create(devicePath, out _); if (dev == null || dev.Error) - return null; + return (null, "Device could not be accessed"); switch (dev.Type) { case DeviceType.ATAPI: case DeviceType.SCSI: ScsiInfo scsiInfo = new ScsiInfo(dev); - return scsiInfo?.MediaType; + var mediaType = EnumConverter.MediaTypeToMediaType(scsiInfo?.MediaType); + if (mediaType == null) + return (mediaType, "Could not determine media type"); + else + return (mediaType, null); } - return null; + return (null, "Device does not support media type finding"); } ///