Click here to Skip to main content
15,886,664 members
Articles / Programming Languages / C++
Article

Intercept the insertion/removal of a CD/DVD

Rate me:
Please Sign up or sign in to vote.
3.37/5 (11 votes)
8 Apr 20051 min read 44.7K   16   7
How to intercept a new media in the drive, using WM_DEVICECHANGE message.

Introduction

While working (with Borland C++), I've found myself in the trouble of wiritng write an application that reacts to the insertion/removal of a media (CD/DVD) in one of the PC's drives.

The Event

After some surfing on the web, I found that the best way to do this was to use a handler to a specific Windows message, WM_DEVICECHANGE, that is sent by the system when a medium is inserted or removed, as specified in an MSDN page.

The Handler

I've used the WindosProc function to override the default message handler of the application, WndProc, to manage the WM_DEVICECHANGE message. The first thing to do is to redirect the WindowProc function to our message handler, called FormWndProc.

C++
WindowProc=FormWndProc;

The function is defined as:

C++
void __fastcall TFormSpyMsg::FormWndProc(Messages::TMessage &Message)
{
    switch (Message.Msg)
    {
        case WM_DEVICECHANGE:
            handle_WM_DEVICECHANGE(Message);
            break;
        default:
            WndProc(Message);
  }
}

It writes down the handler and is used to handle the WM_DEVICEMESSAGE message. To manage both cases, insertion and removal, we have to understand the parameters of the message we receive, specified in TMessage.LParam. This is a pointer to a DEV_BROADCAST_HDR structure:

C++
typedef struct DEV_BROADCAST_HDR 
{
    DWORD dbch_size;
    DWORD dbch_devicetype;
    DWORD dbch_reserved;
} 
DEV_BROADCAST_HDR, 
*PDEV_BROADCAST_HDR;

The media type is defined in dbch_devicetype. With another cast, from PDEV_BROADCAST_HDR to PDEV_BROADCAST_VOLUME, we could retrieve the flags that identify the media, lpdbv -> dbcv_flags. The identifier of the drive that has been changed is specified in lpdbv ->dbcv_unitmask. To decode this value, I've used a function found on the MSDN page:

char FirstDriveFromMask (ULONG unitmask)
{
    char i;
    for (i = 0; i < 26; ++i)
    {
        if (unitmask & 0x1) break;
        unitmask = unitmask >> 1;
    }
    return (i + 'A');
}

The handler is coded below:

C++
void TFormSpyMsg::handle_WM_DEVICECHANGE(TMessage Msg)
{
    PDEV_BROADCAST_HDR lpdb = (PDEV_BROADCAST_HDR)Msg.LParam;
    AnsiString smsg;
    char drive;

    switch(Msg.WParam)
    {
        case DBT_DEVICEARRIVAL:
            if (lpdb -> dbch_devicetype == DBT_DEVTYP_VOLUME)
            {
                PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME)lpdb;
                if (lpdbv -> dbcv_flags & DBTF_MEDIA)
                {
                    drive = FirstDriveFromMask(lpdbv ->dbcv_unitmask);
                    smsg = "Device inserte in drive " + 
                        AnsiString(drive);
                    Memo1->Lines->Add(smsg);
                }
            }
            break;
        case DBT_DEVICEREMOVECOMPLETE:
            if (lpdb -> dbch_devicetype == DBT_DEVTYP_VOLUME)
            {
                PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME)lpdb;
                if (lpdbv -> dbcv_flags & DBTF_MEDIA)
                {
                    drive = FirstDriveFromMask(lpdbv ->dbcv_unitmask);
                    smsg = "Device removed from drive " + 
                    AnsiString(drive);
                    Memo1->Lines->Add(smsg);
                }
            }
            break;
        default: ;
    }
}

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
Web Developer
Italy Italy
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionCopy of MS Article Pin
Msftone20-Mar-07 9:11
Msftone20-Mar-07 9:11 
nit pick on why this article is here but this is really the same article and code from

http://support.microsoft.com/kb/163503

and the MSDN article referenced within the article..

Confused | :confused:

---
maximum 500 characters

GeneralWM_DEVICECHANGE & IOMega ZIP Drive Pin
JimmyO18-Jan-07 3:11
JimmyO18-Jan-07 3:11 
Generalprevent windows from reading the CD/DVD Pin
Darin.sh20-Aug-05 22:57
Darin.sh20-Aug-05 22:57 
GeneralCBuilder article Pin
yarp8-Apr-05 19:20
yarp8-Apr-05 19:20 
GeneralRe: CBuilder article Pin
shaman7414-Apr-05 21:01
shaman7414-Apr-05 21:01 
GeneralRe: CBuilder article Pin
yarp15-Apr-05 2:13
yarp15-Apr-05 2:13 
GeneralGood job Pin
Juha Silmujarvi8-Apr-05 6:49
Juha Silmujarvi8-Apr-05 6:49 

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.