5

As stated in the title, I'm trying to determine if a drive DVD drive or a CD drive. Again, I am not asking about the media, I'm asking about the actual drive itself... the object pointed to by a DriveInfo class.

I'm thinking the DriveInfo class isn't enough and I'll instead have to get the Win32_DiskDrive instance from WMI and dig around in there. The problem is all the samples I've found so far talk about the detected media, but a DVD drive can use CD media so that isn't sufficient. Plus, the code should work regardless if media is present or not.

Mark A. Donohoe
  • 28,442
  • 25
  • 137
  • 286
  • Yes, I did. I wanted to know if there was anything *more* behind that question, because a DVD drive will always be a CD-ROM itself, which makes this a bit more difficult. – Yuval Itzchakov Sep 27 '15 at 06:31
  • A DVD drive will not be a CD drive. It can *read* a CD, but it is a DVD drive. I am displaying drives in my application. I want to display DVD drives separately from CD drives. That's why I am asking if an optical drive is a DVD drive or only a CD drive. – Mark A. Donohoe Sep 27 '15 at 06:33
  • 1
    Hey... sorry if that came off snarky. Didn't mean it to. It's just I specifically said in the question what I was looking for and what I was *not* looking for, and when you asked what I had already answered, it tweaked me the wrong way. Sorry about that. – Mark A. Donohoe Sep 27 '15 at 06:40
  • No problem, just trying to help out :) – Yuval Itzchakov Sep 27 '15 at 06:41
  • BTW Ms sees it at the same type (http://i.imgur.com/2Smgs2u.png) – Royi Namir Sep 27 '15 at 06:44
  • Actually, no it doesn't. There it displays as such but in the actual Explorer window, it says DVD player. At least it does on my system. It's in that same family which is probably why you're seeing that, but I was after the specific difference, which the answer below looks like it may point out. – Mark A. Donohoe Sep 27 '15 at 08:04

1 Answers1

1

You can get it from WMI. Win32_CDROMDrive class.

ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT MediaType FROM Win32_CDROMDrive");
ManagementObjectCollection collection = searcher.Get();
foreach (ManagementBaseObject obj in collection)
{
    MessageBox.Show(obj["MediaType"].ToString());
}

It will be problem, if you need then to know about BDRom etc. I recommend to use NeroCmd tools instead of WMI.

Also you can try look here. It's about burning, but there you can find Supported Media of drive. If it's support Blu-Ray media, then it's obviously not CD-ROM :)

I was try to get only important parts. Here we are using IMAPI2 API to get device features (CD/DVD/BD/HDDVD-READ). I know, that there are COMBO drives that supports BD and HDDVD but I don't show it in code.

//
// Determine the current recording devices
//
MsftDiscMaster2 discMaster = null;
try
{
    discMaster = new MsftDiscMaster2();

    if (!discMaster.IsSupportedEnvironment)
        return;

    // Get drives
    foreach (string uniqueRecorderId in discMaster)
    {
        IDiscRecorder2 discRecorder2 = new MsftDiscRecorder2();
        discRecorder2.InitializeDiscRecorder(uniqueRecorderId);
        // Show device mount drive and determine type
        Console.WriteLine("Path: {0} Type: {1}", discRecorder2.VolumePathNames[0], CheckType(discRecorder2));
    }
}
catch (COMException ex)
{
    Console.WriteLine("Error:{0} - Please install IMAPI2", ex.ErrorCode);
}
finally
{
    if (discMaster != null)
        Marshal.ReleaseComObject(discMaster);
}

Magic ^_^

// Determine type
static string CheckType(IDiscRecorder2 disc)
{
    var features = disc.SupportedFeaturePages.Select(a => (IMAPI_FEATURE_PAGE_TYPE)a).ToArray();
    if (features.Contains(IMAPI_FEATURE_PAGE_TYPE.IMAPI_FEATURE_PAGE_TYPE_HD_DVD_READ))
        return "HD-DVD-ROM";
    if (features.Contains(IMAPI_FEATURE_PAGE_TYPE.IMAPI_FEATURE_PAGE_TYPE_BD_READ))
        return "BD-ROM";
    if (features.Contains(IMAPI_FEATURE_PAGE_TYPE.IMAPI_FEATURE_PAGE_TYPE_DVD_READ))
        return "DVD-ROM";
    if (features.Contains(IMAPI_FEATURE_PAGE_TYPE.IMAPI_FEATURE_PAGE_TYPE_CD_READ))
        return "CD-ROM";
    return "Unknown";
}

Interop...

/// <summary>
/// Microsoft IMAPIv2 Disc Master
/// </summary>
[ComImport]
[Guid("27354130-7F64-5B0F-8F00-5D77AFBE261E")]
[CoClass(typeof(MsftDiscMaster2Class))]
public interface MsftDiscMaster2 : IDiscMaster2 //, DiscMaster2_Event
{
}

[ComImport, ComSourceInterfaces("DDiscMaster2Events\0")]
[TypeLibType(TypeLibTypeFlags.FCanCreate)]
[Guid("2735412E-7F64-5B0F-8F00-5D77AFBE261E")]
[ClassInterface(ClassInterfaceType.None)]
public class MsftDiscMaster2Class
{
}

[ComImport]
[CoClass(typeof(MsftDiscRecorder2Class))]
[Guid("27354133-7F64-5B0F-8F00-5D77AFBE261E")]
public interface MsftDiscRecorder2 : IDiscRecorder2
{
}


[ComImport]
[Guid("2735412D-7F64-5B0F-8F00-5D77AFBE261E")]
[TypeLibType(TypeLibTypeFlags.FCanCreate)]
[ClassInterface(ClassInterfaceType.None)]
public class MsftDiscRecorder2Class
{
}

/// <summary>
/// IDiscMaster2 is used to get an enumerator for the set of CD/DVD (optical) devices on the system
/// </summary>
[ComImport]
[Guid("27354130-7F64-5B0F-8F00-5D77AFBE261E")]
[TypeLibType(TypeLibTypeFlags.FDual | TypeLibTypeFlags.FDispatchable | TypeLibTypeFlags.FNonExtensible)]
public interface IDiscMaster2
{
    // Enumerates the list of CD/DVD devices on the system (VT_BSTR)
    [DispId(-4), TypeLibFunc((short)0x41)]
    IEnumerator GetEnumerator();

    // Gets a single recorder's ID (ZERO BASED INDEX)
    [DispId(0)]
    string this[int index] { get; }

    // The current number of recorders in the system.
    [DispId(1)]
    int Count { get; }

    // Whether IMAPI is running in an environment with optical devices and permission to access them.
    [DispId(2)]
    bool IsSupportedEnvironment { get; }
}

/// <summary>
///  Represents a single CD/DVD type device, and enables many common operations via a simplified API.
/// </summary>
[ComImport]
[TypeLibType(TypeLibTypeFlags.FDual | TypeLibTypeFlags.FDispatchable | TypeLibTypeFlags.FNonExtensible)]
[Guid("27354133-7F64-5B0F-8F00-5D77AFBE261E")]
public interface IDiscRecorder2
{
    // Ejects the media (if any) and opens the tray
    [DispId(0x100)]
    void EjectMedia();

    // Close the media tray and load any media in the tray.
    [DispId(0x101)]
    void CloseTray();

    // Acquires exclusive access to device.  May be called multiple times.
    [DispId(0x102)]
    void AcquireExclusiveAccess(bool force, string clientName);

    // Releases exclusive access to device.  Call once per AcquireExclusiveAccess().
    [DispId(0x103)]
    void ReleaseExclusiveAccess();

    // Disables Media Change Notification (MCN).
    [DispId(260)]
    void DisableMcn();

    // Re-enables Media Change Notification after a call to DisableMcn()
    [DispId(0x105)]
    void EnableMcn();

    // Initialize the recorder, opening a handle to the specified recorder.
    [DispId(0x106)]
    void InitializeDiscRecorder(string recorderUniqueId);

    // The unique ID used to initialize the recorder.
    [DispId(0)]
    string ActiveDiscRecorder { get; }

    // The vendor ID in the device's INQUIRY data.
    [DispId(0x201)]
    string VendorId { get; }

    // The Product ID in the device's INQUIRY data.
    [DispId(0x202)]
    string ProductId { get; }

    // The Product Revision in the device's INQUIRY data.
    [DispId(0x203)]
    string ProductRevision { get; }

    // Get the unique volume name (this is not a drive letter).
    [DispId(0x204)]
    string VolumeName { get; }

    // Drive letters and NTFS mount points to access the recorder.
    [DispId(0x205)]
    object[] VolumePathNames {[DispId(0x205)] get; }

    // One of the volume names associated with the recorder.
    [DispId(0x206)]
    bool DeviceCanLoadMedia {[DispId(0x206)] get; }

    // Gets the legacy 'device number' associated with the recorder.  This number is not guaranteed to be static.
    [DispId(0x207)]
    int LegacyDeviceNumber {[DispId(0x207)] get; }

    // Gets a list of all feature pages supported by the device
    [DispId(520)]
    object[] SupportedFeaturePages {[DispId(520)] get; }

    // Gets a list of all feature pages with 'current' bit set to true
    [DispId(0x209)]
    object[] CurrentFeaturePages {[DispId(0x209)] get; }

    // Gets a list of all profiles supported by the device
    [DispId(0x20a)]
    object[] SupportedProfiles {[DispId(0x20a)] get; }

    // Gets a list of all profiles with 'currentP' bit set to true
    [DispId(0x20b)]
    object[] CurrentProfiles {[DispId(0x20b)] get; }

    // Gets a list of all MODE PAGES supported by the device
    [DispId(0x20c)]
    object[] SupportedModePages {[DispId(0x20c)] get; }

    // Queries the device to determine who, if anyone, has acquired exclusive access
    [DispId(0x20d)]
    string ExclusiveAccessOwner {[DispId(0x20d)] get; }
}

public enum IMAPI_FEATURE_PAGE_TYPE
{
    IMAPI_FEATURE_PAGE_TYPE_PROFILE_LIST = 0,
    IMAPI_FEATURE_PAGE_TYPE_CORE = 1,
    IMAPI_FEATURE_PAGE_TYPE_MORPHING = 2,
    IMAPI_FEATURE_PAGE_TYPE_REMOVABLE_MEDIUM = 3,
    IMAPI_FEATURE_PAGE_TYPE_WRITE_PROTECT = 4,
    IMAPI_FEATURE_PAGE_TYPE_RANDOMLY_READABLE = 0x10,
    IMAPI_FEATURE_PAGE_TYPE_CD_MULTIREAD = 0x1d,
    IMAPI_FEATURE_PAGE_TYPE_CD_READ = 0x1e,
    IMAPI_FEATURE_PAGE_TYPE_DVD_READ = 0x1f,
    IMAPI_FEATURE_PAGE_TYPE_RANDOMLY_WRITABLE = 0x20,
    IMAPI_FEATURE_PAGE_TYPE_INCREMENTAL_STREAMING_WRITABLE = 0x21,
    IMAPI_FEATURE_PAGE_TYPE_SECTOR_ERASABLE = 0x22,
    IMAPI_FEATURE_PAGE_TYPE_FORMATTABLE = 0x23,
    IMAPI_FEATURE_PAGE_TYPE_HARDWARE_DEFECT_MANAGEMENT = 0x24,
    IMAPI_FEATURE_PAGE_TYPE_WRITE_ONCE = 0x25,
    IMAPI_FEATURE_PAGE_TYPE_RESTRICTED_OVERWRITE = 0x26,
    IMAPI_FEATURE_PAGE_TYPE_CDRW_CAV_WRITE = 0x27,
    IMAPI_FEATURE_PAGE_TYPE_MRW = 0x28,
    IMAPI_FEATURE_PAGE_TYPE_ENHANCED_DEFECT_REPORTING = 0x29,
    IMAPI_FEATURE_PAGE_TYPE_DVD_PLUS_RW = 0x2a,
    IMAPI_FEATURE_PAGE_TYPE_DVD_PLUS_R = 0x2b,
    IMAPI_FEATURE_PAGE_TYPE_RIGID_RESTRICTED_OVERWRITE = 0x2c,
    IMAPI_FEATURE_PAGE_TYPE_CD_TRACK_AT_ONCE = 0x2d,
    IMAPI_FEATURE_PAGE_TYPE_CD_MASTERING = 0x2e,
    IMAPI_FEATURE_PAGE_TYPE_DVD_DASH_WRITE = 0x2f,
    IMAPI_FEATURE_PAGE_TYPE_DOUBLE_DENSITY_CD_READ = 0x30,
    IMAPI_FEATURE_PAGE_TYPE_DOUBLE_DENSITY_CD_R_WRITE = 0x31,
    IMAPI_FEATURE_PAGE_TYPE_DOUBLE_DENSITY_CD_RW_WRITE = 0x32,
    IMAPI_FEATURE_PAGE_TYPE_LAYER_JUMP_RECORDING = 0x33,
    IMAPI_FEATURE_PAGE_TYPE_CD_RW_MEDIA_WRITE_SUPPORT = 0x37,
    IMAPI_FEATURE_PAGE_TYPE_BD_PSEUDO_OVERWRITE = 0x38,
    IMAPI_FEATURE_PAGE_TYPE_DVD_PLUS_R_DUAL_LAYER = 0x3b,
    IMAPI_FEATURE_PAGE_TYPE_BD_READ = 0x40,
    IMAPI_FEATURE_PAGE_TYPE_BD_WRITE = 0x41,
    IMAPI_FEATURE_PAGE_TYPE_HD_DVD_READ = 0x50,
    IMAPI_FEATURE_PAGE_TYPE_HD_DVD_WRITE = 0x51,
    IMAPI_FEATURE_PAGE_TYPE_POWER_MANAGEMENT = 0x100,
    IMAPI_FEATURE_PAGE_TYPE_SMART = 0x101,
    IMAPI_FEATURE_PAGE_TYPE_EMBEDDED_CHANGER = 0x102,
    IMAPI_FEATURE_PAGE_TYPE_CD_ANALOG_PLAY = 0x103,
    IMAPI_FEATURE_PAGE_TYPE_MICROCODE_UPDATE = 0x104,
    IMAPI_FEATURE_PAGE_TYPE_TIMEOUT = 0x105,
    IMAPI_FEATURE_PAGE_TYPE_DVD_CSS = 0x106,
    IMAPI_FEATURE_PAGE_TYPE_REAL_TIME_STREAMING = 0x107,
    IMAPI_FEATURE_PAGE_TYPE_LOGICAL_UNIT_SERIAL_NUMBER = 0x108,
    IMAPI_FEATURE_PAGE_TYPE_MEDIA_SERIAL_NUMBER = 0x109,
    IMAPI_FEATURE_PAGE_TYPE_DISC_CONTROL_BLOCKS = 0x10a,
    IMAPI_FEATURE_PAGE_TYPE_DVD_CPRM = 0x10b,
    IMAPI_FEATURE_PAGE_TYPE_FIRMWARE_INFORMATION = 0x10c,
    IMAPI_FEATURE_PAGE_TYPE_AACS = 0x10d,
    IMAPI_FEATURE_PAGE_TYPE_VCPS = 0x110
}

According to MSDN, IMAPI_FEATURE_PAGE_TYPE can contain not only this values, so be carefull.

Spawn
  • 935
  • 1
  • 13
  • 32
  • Why would BD-ROM drives cause an issue? Also, this has to be something that's installed with the .NET 4.6 framework so I'm not sure about NeroCmd (I take it that has something to do with the Nero disc software, no?) – Mark A. Donohoe Sep 27 '15 at 06:38
  • @MarqueIV, there is no difference for Microsoft between BDRom and DVD-ROM, for my Blu-Ray with write support it says DVD Writer – Spawn Sep 27 '15 at 06:41
  • Ran this code and it returned 'UNKNOWN' for MediaType. Are you sure this tests the drive *without* a disc in it? Again, I'm querying the hardware, not the media. – Mark A. Donohoe Sep 27 '15 at 08:13
  • It's not for media. Do you have one optical drive? Is not it virtual? – Spawn Sep 27 '15 at 08:32
  • They could be virtual. They could also be physical hardware virtualized to a virtual machine such as Parallels on the Mac or VMWare on the PC. The point is it always has to work regardless. They all show up properly as DriveInfo objects in C#. I just can't tell the difference between CD and DVD drives, which we need to know. – Mark A. Donohoe Sep 27 '15 at 08:34
  • @MarqueIV I have updated post, it's not ideal solution, but can help out. – Spawn Sep 27 '15 at 09:23
  • That's a lot to read. I'll have to check that out in the morning. If you can extract out the info that I'm looking for however, I'll mark yours as an answer. (I don't like marking external links as an answer because they can always go dead/change making the answer useless.) – Mark A. Donohoe Sep 27 '15 at 09:26