Geekpedia Programming Tutorials






CD Drive Control

Enumerates all CD-ROM drives and allows them to be opened and closed at the touch of a button.

On Wednesday, April 7th 2004 at 10:45 PM
By Sean Eshbaugh (View Profile)
*****   (Rated 4.8 with 15 votes)
Contextual Ads
More C++ Resources
Advertisement

I got bored the other day and was looking through the Platform SDK Documentation and came across the DeviceIoControl API function. I came upon the IOCTL_STORAGE_EJECT_MEDIA control code and it got my interest. I decided to make a small application that made use of DeviceIoControl and the IOCTL_STORAGE_EJECT_MEDIA and IOCTL_STORAGE_LOAD_MEDIA control codes.

This project was done with MFC in Microsoft Visual C++ 6.0 and is compatable with Windows NT/2000/XP.

Before getting into the nitty gritty of how to open and close a CD-ROM drive (which isn't all that hard actually) I'm going to show you how to enumerate all CD-ROM devices on the system and display them. This part is really only applicable to this program or anything that will impliment this in the exact same way (but it's a good lesson in how to use CListCtrl).

First create a new MFCApp Wizard (exe) project. For the purposes of this project we will be using a a dialog based application without any context based help or any other extra stuff.

Open up the main dialog and add a List Control to the dialog. Right click the control and click 'Properties'. Click the 'Styles' tab and check the select the 'List' option in the 'View' drop down list and close the 'Properties' window. Now right click the List Control again and select 'Class Wizard'. In the window that appears click the 'Member Variables' tab and select the Control ID for the List Control you just created and then click the 'Add Variable' button. Enter the name of the variable and click 'OK'. You have now just created a CListCtrl which is mapped to the List Control you placed in the Dialog.

To add code to enumerate the CD-ROM drives go to the dialog class' OnInitDialog() function and add the following code before the return TRUE; statement.


CHAR lpszDrive[4];
INT iItem=1;

for (CHAR cDrive='A';cDrive<'Z';cDrive++)
{
    sprintf(lpszDrive,"%c:\\",cDrive);

    //gets the drive type, if its a CD-ROM insert it into the list
    if (GetDriveType(lpszDrive)==DRIVE_CDROM)
    {
        m_DriveList.InsertItem(iItem,lpszDrive);
        iItem++;
    }
}



m_DriveList is the name I used for the CListCtrl, replace that with whatever you used (from now on I will just assume you know what to replace with your own variable/class names).

Now we're going to get into the actual GUI stuff. In the dialog editor change the ID (right click the button and click 'Properties' and then enter in the new ID) of the default 'Cancel' button (this is because if we use the default ID then we will make it impossible to properly close the program). Double click the 'OK' button and the 'Add Member Function' and click 'OK' to add a function to handle a click event to the 'OK' button. In the OnOK() function add the following code (make sure to remove the call to CDialog::OnOK() at the end).


void CCDDriveControlDlg::OnOK() 
{
    //get the position of the first selected item
    POSITION pos=m_DriveList.GetFirstSelectedItemPosition();

    //if there is a selected item
    if (pos)
    {
        //while there are selected items
        while (pos)
        {
            //get the list item number of the next selected item
            int iItem=m_DriveList.GetNextSelectedItem(pos);

            CHAR lpszDrive[4];

            //get the drive letter from the selected items text
            m_DriveList.GetItemText(iItem,0,lpszDrive,4);

            //open the drive
            if (!EjectMedia(lpszDrive[0]))
            {
                MessageBox("Could not open CD Drive.","Error",MB_OK);
            }
        }
    }
}



Now double click the 'Cancel' button and click 'OK' in the Add Member Function window and add the following code to the new function.


void CCDDriveControlDlg::OnButtonClose() 
{
    //get the position of the first selected item
    POSITION pos=m_DriveList.GetFirstSelectedItemPosition();

    //if there is a selected item
    if (pos)
    {
        //while there are selected items

        while (pos)
        {
            //get the list item number of the next selected item
            int iItem=m_DriveList.GetNextSelectedItem(pos);

            CHAR lpszDrive[4];

            //get the drive letter from the selected items text
            m_DriveList.GetItemText(iItem,0,lpszDrive,4);

            //close the drive
            if (!LoadMedia(lpszDrive[0]))
            {
                MessageBox("Could not close CD Drive.","Error",MB_OK);
            }
        }
    }    
}



At this point you can rename the 'OK' and 'Cancel' buttons if you'd like (I did, but that doesn't mean you have to).

Now for the meat of the project. The EjectMedia() and LoadMedia() functions.

First the EjectMedia() function.


BOOL EjectMedia(DWORD dwDrive)
{
    HANDLE hDevice;
    CHAR lpszDeviceName[7];
    DWORD dwBytesReturned;
    DWORD dwError;
    BOOL bResult;

    //take the drive letter and put it in the format used in CreateFile
    sprintf(lpszDeviceName,"\\\\.\\%c:",dwDrive);

    //get a handle to the device, the parameters used here must be used in order for this to work
    hDevice=CreateFile(lpszDeviceName,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);

    //if for some reason we couldn't get a handle to the device we will try again using slightly different parameters for CreateFile
    if (hDevice==INVALID_HANDLE_VALUE)
    {
        SetLastError(NO_ERROR);

        hDevice=CreateFile(lpszDeviceName,GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
    }

    dwError=GetLastError();

    //if we have a valid handle to a device call the DeviceIoControl API function using the IOCTL_STORAGE_EJECT_MEDIA control code
    if ((hDevice!=INVALID_HANDLE_VALUE)&&(dwError==NO_ERROR))
    {
        bResult=DeviceIoControl(hDevice,IOCTL_STORAGE_EJECT_MEDIA,0,0,0,0,&dwBytesReturned,0);
    }
    else
    {
        bResult=FALSE;
    }

    //close the handle
    if (hDevice!=INVALID_HANDLE_VALUE)
    {
        CloseHandle(hDevice);
    }

    return bResult;
}




BOOL LoadMedia(DWORD dwDrive)
{
    HANDLE hDevice;
    CHAR lpszDeviceName[7];
    DWORD dwBytesReturned;
    DWORD dwError;
    BOOL bResult;

    //take the drive letter and put it in the format used in CreateFile
    sprintf(lpszDeviceName,"\\\\.\\%c:",dwDrive);

    //get a handle to the device, the parameters used here must be used in order for this to work

    hDevice=CreateFile(lpszDeviceName,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);

    //if for some reason we couldn't get a handle to the device we will try again using slightly different parameters for CreateFile
    if (hDevice==INVALID_HANDLE_VALUE)
    {
        SetLastError(NO_ERROR);

        hDevice=CreateFile(lpszDeviceName,GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
    }

    dwError=GetLastError();

    //if we have a valid handle to a device call the DeviceIoControl API function using the IOCTL_STORAGE_LOAD_MEDIA control code
    if ((hDevice!=INVALID_HANDLE_VALUE)&&(dwError==NO_ERROR))
    {
        bResult=DeviceIoControl(hDevice,IOCTL_STORAGE_LOAD_MEDIA,0,0,0,0,&dwBytesReturned,0);
    }
    else
    {
        bResult=FALSE;
    }

    //close the handle
    if (hDevice!=INVALID_HANDLE_VALUE)
    {
        CloseHandle(hDevice);
    }

    return bResult;
}


Add the above functions to the end of the source file for the dialog and #include stdio.h and winioctl.h in the stdafx.h file.
Digg Digg It!     Del.icio.us Del.icio.us     Reddit Reddit     StumbleUpon StumbleIt     Newsvine Newsvine     Furl Furl     BlinkList BlinkList

Rate Rate this tutorial
Comment Current Comments
by maceve maceve on Monday, May 17th 2004 at 01:52 AM

Hello, By any chance do you know how to open the cd drive with Java programming. I am doing this project for my Computer Science class and i will apreciate it if you could tell me ow or knew anybody that could help me. I got another programm but it doesnt get it in java. It says that win32 does not exist. I will really appreciate it if you could help me. Thanks

by huhh on Monday, May 31st 2004 at 05:13 AM

damn, the downloadable source doesnt work!! THE ZIPFILE IS CORRUPTED!

by Crap!!! on Friday, August 6th 2004 at 12:14 PM

The zipfile is no longer there!!! Please fix the link.

by STEPHEN OGUGU on Monday, February 14th 2005 at 06:57 AM

Thank you very much Mr. Sean For The good work you are diong and trying to explore to the public.As per the work I, i dont have any much option to the project appreciate whatever it's all about.I too have some taskful programs to be handled though i yet dont have a supportive link tosolving the proble.Please E-mail me so that i can be sure that my e-mail went through your script.Enjoy

by Elen on Monday, August 29th 2005 at 10:31 AM

Thanks! It is beautiful code. And how can I catch an event that eject or inject of my removable disk was occured?

by Kyle Little on Wednesday, November 16th 2005 at 11:35 AM

Im working on programming at tech school and i was wondering if well you could help me with some c++ programming. I am using it on linux so some of the windows types might not work but here goes.
I need to be able to write a program that takes 10 numbers puts them into a file then pules 10 more back out can you give me help just email me.

by Aneeshv on Saturday, December 3rd 2005 at 05:27 AM

hai hello this is verry helped me to understand about CD

by toan on Sunday, January 22nd 2006 at 08:37 AM

Dir Sir , I can not download the source of program, please sent me another?
thanks you very much.

by Justin on Monday, January 23rd 2006 at 03:22 PM

Hi- I am trying to figure out how to make my cd-rom drive open and or close using c++ (.net) could you give me a hand? Thanks
(smithju@gmail.com)

by jeet on Sunday, May 21st 2006 at 11:20 AM

how can we do this in java?Are there any built in classes.
If you can help please mail me.

by Kriz on Monday, July 17th 2006 at 04:11 PM

This snippet of code works fine. Good work Sean!

@jeet: Sorry, there is no native Java support for devices like a CD-ROM, because Java might be run on a system without any ejectable device (Cell phone, PDA, ect.). The only solution is to program a native DLL in Windows and use the JNI (Java Native Interface) technology to access such core functions of Windows. Don\'t forget that this solution will not be portable to Linux or Mac.

by Andrei on Thursday, September 14th 2006 at 10:48 AM

hi!
i tried the code in the 2005 version (visual 8), and i get some errors... is there any way you cand write another code that works on visual 8 too? please...
anyways... the program is great and easy to understant.
thank you

by thang on Tuesday, November 21st 2006 at 08:55 AM

I doing a project about eject cdrom by c(c++)
please send me source code about it
Thank you

by Inyong on Sunday, May 13th 2007 at 01:01 PM

How can we check the CDROM is eject or load??

by Manoj E.S. on Tuesday, December 4th 2007 at 12:47 PM

you deserve the 5star rating. really made things easy to control the cd drive. thanks a lot

by saeed on Thursday, May 22nd 2008 at 09:54 AM

i doing program to open cd drive in C .
please send me source code.
Thanks.

by Nitesh on Monday, June 30th 2008 at 02:15 AM

Dir Sir,
Could you tell me the way to open the Audio/video settings wizard on the click of button ok. I had tried with uccapi.dll, but it worked on implmenting pc but unable to open the page on other pc when installed the application on other pc and gives error "Error CoCreateInstance".

Thanx in Adv.

by Mark on Friday, July 4th 2008 at 10:03 AM

Hi Sean

I don't know if I'm 4 years too late and whether you still monitor this page, but I'm looking for a sequence of code that allow me to manipulate the speed at which the laser will track back and forth. I'm trying to build a film surface scanner for uni and thought that the mechanism thats in so many old broken cdrom drives would do the job.

Anyway if you or any others that view this post have any ideas of how to hack the controller and make this possible I'd love to hear.

Cheers

Mark

by Mark on Friday, July 4th 2008 at 10:03 AM

Hi Sean

I don't know if I'm 4 years too late and whether you still monitor this page, but I'm looking for a sequence of code that allow me to manipulate the speed at which the laser will track back and forth. I'm trying to build a film surface scanner for uni and thought that the mechanism thats in so many old broken cdrom drives would do the job.

Anyway if you or any others that view this post have any ideas of how to hack the controller and make this possible I'd love to hear.

Cheers

Mark

by elavarasan on Monday, December 1st 2008 at 09:31 AM

hai friends i want know that how to injuct a cd drive without touch it physiclly.... if you have any idea about this you just send me a reply ya.....


Comment Comment on this tutorial
Name: Email:
Message:
Comment Related Tutorials
There are no related tutorials.

Comment Related Source Code
There is no related source code.

Jobs C++ Job Search
My skills include:
Enter a City:

Select a State:


Advanced Search >>
Latest Tech Bargains

Advertisement

Free Magazine Subscriptions

Today's Pictures

Today's Video

Other Resources

Latest Download

Latest Icons