Click here to Skip to main content
15,888,984 members
Articles / Desktop Programming / MFC
Article

Telling The Difference Between CD and DVD Drives

Rate me:
Please Sign up or sign in to vote.
4.38/5 (5 votes)
27 Mar 20071 min read 56.4K   377   14   11
Provides code to determine if a drive is a CD or DVD drive.

Screenshot - CDorDV1.jpg

Introduction

The code included with this article demonstrates a way to determine whether an installed drive is a CD or DVD drive. The return from GetDriveType() only tells you that the drive is a DRIVE_CDROM, and it returns this for both CD and DVD (so far as I could tell). The additional code included here will help you determine the difference between a CD and DVD drive.

Background

I needed to know this information for a project a while back, but I couldn't find anything that encapsulated it using MFC. So, I wrote this small program to test out some ideas and ended up with the code included with this article.

Using the code

There is nothing fancy in this code. Users can simply cut and paste the code needed from this sample into their own projects.

Here is the part that does the work in question:

//
CDORDVD CCDOrDVDDriveDlg::GetMediaType(TCHAR cDrive)
{
    CString cs;
    cs.Format(_T("\\\\.\\%c:"),cDrive);
    HANDLE hDrive = CreateFile(cs, GENERIC_READ, FILE_SHARE_READ, 
                               NULL, OPEN_EXISTING, 0, NULL);

    if(hDrive == INVALID_HANDLE_VALUE || GetLastError() != NO_ERROR)
        return CDDRIVE_UNKNOWN;

    UCHAR buffer[2048]; // Must be big enough hold DEVICE_MEDIA_INFO
    ULONG returned;
    BOOL bStatus = DeviceIoControl(hDrive, 
                   IOCTL_STORAGE_GET_MEDIA_TYPES_EX,NULL, 0, 
                   &buffer, 2048, &returned, NULL);

    // Close handle. This should work, but if it can't close it something may
    // have gone wrong in the IOCTL call.
    if (!bStatus || !CloseHandle(hDrive))
        return CDDRIVE_UNKNOWN;

    PGET_MEDIA_TYPES pMediaTypes = (PGET_MEDIA_TYPES) buffer;
    if(pMediaTypes->DeviceType == FILE_DEVICE_CD_ROM)
        return CDDRIVE_CD;
    else if(pMediaTypes->DeviceType == FILE_DEVICE_DVD)
        return CDDRIVE_DVD;

    return CDDRIVE_UNKNOWN;
}

Points of interest

I tried several ideas while creating this small snippet of code. I needed it to work on any version of Windows from WinNT. I needed to know the difference because the user of my program can have either kind of media and I wanted to display the most logical drive for them to use.

History

  • Version 1.0 - March 28, 2007.
  • Version 1.1 - March 29, 2007 - fixed project file.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Software Developer (Senior)
United States United States
I have been using VC++ with MFC since it first came out circa 1993 and I saw it demonstrated at a local Software Development show. I've been working for Rimage Corporation for around 23 years developing software to make our CD and DVD publishing hardware work.

When I'm not working I enjoy hanging out with my family, playing guitar, traveling, and taking my dogs for walks. My family enjoys watching Survivor on Thursday nights and we're not even embarassed by it.

Comments and Discussions

 
Questionwhat about a CD-RW or DVD -RW Drive Pin
Vis_liner22-May-07 6:36
Vis_liner22-May-07 6:36 
QuestionPossible handle leak? Pin
Blake Miller2-Apr-07 6:40
Blake Miller2-Apr-07 6:40 
AnswerRe: Possible handle leak? Pin
Thomas Serface2-Apr-07 8:24
Thomas Serface2-Apr-07 8:24 
GeneralRe: Possible handle leak? Pin
Nathan Lewis11-Jun-07 5:31
Nathan Lewis11-Jun-07 5:31 
As long as we're on the subject, this is potentially problematic as well:
<br />
    if(hDrive == INVALID_HANDLE_VALUE || GetLastError() != NO_ERROR)<br />
        return CDDRIVE_UNKNOWN;<br />

According to the CreateFile API documentation, GetLastError() will only return a valid error code under two circumstances:

    1. If you set dwCreationDisposition to CREATE_ALWAYS or OPEN_ALWAYS, GetLastError() will return ERROR_ALREADY_EXISTS if the file exists, otherwise it returns zero. This obviously doesn't apply in this case, though, as you're using OPEN_EXISTING.

    2. If the function fails, GetLastError() will return "extended error information".

Nowhere does the documentation say that GetLastError() will return NO_ERROR - or anything else, for that matter - upon a successful call to CreateFile. The fact that it does appear to do so notwithstanding, it's never a good idea to count on undocumented behaviors, IMHO.

On the other hand, the documentation does clearly state that "[i]f the function succeeds, the return value is an open handle to a specified file." So if hDrive != INVALID_HANDLE_VALUE, we can safely assume the function succeeded.

So let's assume for the moment that CreateFile has succeeded, and yet GetLastError() returns an error code of some kind - in this case, you will return without closing the handle. It would be much better to simply do this:
<br />
    if( hDrive == INVALID_HANDLE_VALUE )<br />
        return CDDRIVE_UNKNOWN;<br />

But, of course, I am most likely just being extremeley paranoid here - I am going by a very strict interpretation of the current version of the API documentation. Chances are this problem will never occur in actual practice. But I always figure it's better to be paranoid than to potentially introduce a bug that would be very difficult to track down.... Poke tongue | ;-P

IMO, YMMV, etc.



*Real* programmers use "copy con:progname.exe"!

QuestionBlueray and HDDVD drives ? Pin
IntVestor29-Mar-07 6:35
IntVestor29-Mar-07 6:35 
AnswerRe: Blueray and HDDVD drives ? Pin
Thomas Serface29-Mar-07 6:40
Thomas Serface29-Mar-07 6:40 
GeneralTranslation to another language Pin
Anthony Slash27-Mar-07 12:07
Anthony Slash27-Mar-07 12:07 
GeneralRe: Translation to another language Pin
Thomas Serface27-Mar-07 12:19
Thomas Serface27-Mar-07 12:19 
GeneralRe: Translation to another language Pin
Thomas Serface27-Mar-07 12:36
Thomas Serface27-Mar-07 12:36 
GeneralRe: Translation to another language Pin
Anthony Slash27-Mar-07 15:50
Anthony Slash27-Mar-07 15:50 
GeneralRe: Translation to another language Pin
W Balboos, GHB5-Apr-07 4:36
W Balboos, GHB5-Apr-07 4:36 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.