diff --git a/CHANGELIST.md b/CHANGELIST.md
index 61f1c594..e0a794fb 100644
--- a/CHANGELIST.md
+++ b/CHANGELIST.md
@@ -82,6 +82,7 @@
- Multisession is multi-line
- Use Aaru for media type retrival (.NET 6)
- Fix CD-R multisession info
+- Better get drive list (.NET 6)
### 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 4740d337..2da1cd5b 100644
--- a/MPF.Core/Data/Drive.cs
+++ b/MPF.Core/Data/Drive.cs
@@ -11,6 +11,7 @@ using IMAPI2;
#else
using Aaru.CommonTypes.Enums;
using Aaru.Core.Media.Info;
+using Aaru.Decoders.SCSI.MMC;
using Aaru.Decoders.SCSI.SSC;
using Aaru.Devices;
#endif
@@ -110,56 +111,10 @@ namespace MPF.Core.Data
///
/// True to ignore fixed drives from population, false otherwise
/// Active drives, matched to labels, if possible
- ///
- /// 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
- ///
public static List CreateListOfDrives(bool ignoreFixedDrives)
{
- var desiredDriveTypes = new List() { DriveType.CDRom };
- if (!ignoreFixedDrives)
- {
- desiredDriveTypes.Add(DriveType.Fixed);
- desiredDriveTypes.Add(DriveType.Removable);
- }
-
- // Get all supported drive types
- var drives = DriveInfo.GetDrives()
- .Where(d => desiredDriveTypes.Contains(d.DriveType))
- .Select(d => new Drive(EnumConverter.ToInternalDriveType(d.DriveType), d))
- .ToList();
-
-#if NETFRAMEWORK
- // Get the floppy drives and set the flag from removable
- try
- {
- ManagementObjectSearcher searcher =
- new ManagementObjectSearcher("root\\CIMV2",
- "SELECT * FROM Win32_LogicalDisk");
-
- var collection = searcher.Get();
- foreach (ManagementObject queryObj in collection)
- {
- uint? mediaType = (uint?)queryObj["MediaType"];
- if (mediaType != null && ((mediaType > 0 && mediaType < 11) || (mediaType > 12 && mediaType < 22)))
- {
- char devId = queryObj["DeviceID"].ToString()[0];
- drives.ForEach(d => { if (d.Letter == devId) { d.InternalDriveType = Data.InternalDriveType.Floppy; } });
- }
- }
- }
- catch
- {
- // No-op
- }
-#else
- // TODO: Use this returned drive list once fixed
- var driveList = GetDriveList(ignoreFixedDrives);
-#endif
-
- // Order the drives by drive letter
+ var drives = GetDriveList(ignoreFixedDrives);
drives = drives.OrderBy(i => i.Letter).ToList();
-
return drives;
}
@@ -238,6 +193,7 @@ namespace MPF.Core.Data
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);
}
@@ -501,7 +457,59 @@ namespace MPF.Core.Data
public void RefreshDrive()
=> this.driveInfo = DriveInfo.GetDrives().FirstOrDefault(d => d?.Name == this.Name);
-#if NET6_0_OR_GREATER
+#if NETFRAMEWORK
+
+ ///
+ /// Get all current attached Drives
+ ///
+ /// True to ignore fixed drives from population, false otherwise
+ /// List of drives, null on error
+ ///
+ /// 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
+ ///
+ private static List GetDriveList(bool ignoreFixedDrives)
+ {
+ var desiredDriveTypes = new List() { DriveType.CDRom };
+ if (!ignoreFixedDrives)
+ {
+ desiredDriveTypes.Add(DriveType.Fixed);
+ desiredDriveTypes.Add(DriveType.Removable);
+ }
+
+ // Get all supported drive types
+ var drives = DriveInfo.GetDrives()
+ .Where(d => desiredDriveTypes.Contains(d.DriveType))
+ .Select(d => new Drive(EnumConverter.ToInternalDriveType(d.DriveType), d))
+ .ToList();
+
+ // Get the floppy drives and set the flag from removable
+ try
+ {
+ ManagementObjectSearcher searcher =
+ new ManagementObjectSearcher("root\\CIMV2",
+ "SELECT * FROM Win32_LogicalDisk");
+
+ var collection = searcher.Get();
+ foreach (ManagementObject queryObj in collection)
+ {
+ uint? mediaType = (uint?)queryObj["MediaType"];
+ if (mediaType != null && ((mediaType > 0 && mediaType < 11) || (mediaType > 12 && mediaType < 22)))
+ {
+ char devId = queryObj["DeviceID"].ToString()[0];
+ drives.ForEach(d => { if (d.Letter == devId) { d.InternalDriveType = Data.InternalDriveType.Floppy; } });
+ }
+ }
+ }
+ catch
+ {
+ // No-op
+ }
+
+ return drives;
+ }
+
+#else
///
/// Get all devices attached converted to Drive objects
@@ -549,14 +557,19 @@ namespace MPF.Core.Data
return null;
// TODO: Narrow down devices to "readable" ones
- // TODO: Look at Prettify_0000 for optical disc drive support
var devInfo = new Aaru.Core.Devices.Info.DeviceInfo(dev);
- if (devInfo.MediumDensitySupport != null && devInfo.MediaTypeSupportHeader.HasValue)
+ if (devInfo.MmcConfiguration != null)
{
- foreach (DensitySupport.MediaTypeSupportDescriptor descriptor in devInfo.MediaTypeSupportHeader.Value.descriptors)
+ Features.SeparatedFeatures ftr = Features.Separate(devInfo.MmcConfiguration);
+ if (ftr.Descriptors != null && ftr.Descriptors.Any(d => d.Code == 0x0000))
{
- string mediumType = descriptor.name;
+ var desc = ftr.Descriptors.First(d => d.Code == 0x0000);
+ bool isOptical = IsOptical(desc.Data);
+ if (isOptical)
+ return new Drive(Data.InternalDriveType.Optical, new DriveInfo(devicePath));
+ else if (!ignoreFixedDrives)
+ return new Drive(Data.InternalDriveType.Removable, new DriveInfo(devicePath));
}
}
@@ -613,6 +626,75 @@ namespace MPF.Core.Data
return null;
}
+ ///
+ /// Determine if a drive is optical or not
+ ///
+ /// Bytes representing the field to check
+ /// True if the drive is optical, false otherwise
+ ///
+ /// TODO: This should be more granular about getting supported media types instead of true/false
+ ///
+ private static bool IsOptical(byte[] featureBytes)
+ {
+ Feature_0000? feature = Features.Decode_0000(featureBytes);
+
+ if (!feature.HasValue)
+ return false;
+
+ foreach (Profile prof in feature.Value.Profiles)
+ {
+ switch (prof.Number)
+ {
+ // Values we don't care about for Optical
+ case ProfileNumber.Reserved:
+ case ProfileNumber.NonRemovable:
+ case ProfileNumber.Removable:
+ case ProfileNumber.MOErasable:
+ case ProfileNumber.OpticalWORM:
+ case ProfileNumber.ASMO:
+ case ProfileNumber.Unconforming:
+ break;
+
+ // Every supported optical profile
+ case ProfileNumber.CDROM:
+ case ProfileNumber.CDR:
+ case ProfileNumber.CDRW:
+ case ProfileNumber.DVDROM:
+ case ProfileNumber.DVDRSeq:
+ case ProfileNumber.DVDRAM:
+ case ProfileNumber.DVDRWRes:
+ case ProfileNumber.DVDRWSeq:
+ case ProfileNumber.DVDRDLSeq:
+ case ProfileNumber.DVDRDLJump:
+ case ProfileNumber.DVDRWDL:
+ case ProfileNumber.DVDDownload:
+ case ProfileNumber.DVDRWPlus:
+ case ProfileNumber.DVDRPlus:
+ case ProfileNumber.DDCDROM:
+ case ProfileNumber.DDCDR:
+ case ProfileNumber.DDCDRW:
+ case ProfileNumber.DVDRWDLPlus:
+ case ProfileNumber.DVDRDLPlus:
+ case ProfileNumber.BDROM:
+ case ProfileNumber.BDRSeq:
+ case ProfileNumber.BDRRdm:
+ case ProfileNumber.BDRE:
+ case ProfileNumber.HDDVDROM:
+ case ProfileNumber.HDDVDR:
+ case ProfileNumber.HDDVDRAM:
+ case ProfileNumber.HDDVDRW:
+ case ProfileNumber.HDDVDRDL:
+ case ProfileNumber.HDDVDRWDL:
+ case ProfileNumber.HDBURNROM:
+ case ProfileNumber.HDBURNR:
+ case ProfileNumber.HDBURNRW:
+ return true;
+ }
+ }
+
+ return false;
+ }
+
#endif
}
}