Click here to Skip to main content
Click here to Skip to main content

Intercept the insertion/removal of a CD/DVD

, 8 Apr 2005
Rate this:
Please Sign up or sign in to vote.
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.

WindowProc=FormWndProc;

The function is defined as:

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:

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:

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

About the Author

shaman74
Web Developer
Italy Italy
No Biography provided

Comments and Discussions

 
QuestionCopy of MS Article PinmemberMsftone20-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 PinmemberJimmyO18-Jan-07 3:11 
Generalprevent windows from reading the CD/DVD PinmemberDarin.sh20-Aug-05 22:57 
GeneralCBuilder article Pinmemberyarp8-Apr-05 19:20 
GeneralRe: CBuilder article Pinmembershaman7414-Apr-05 21:01 
GeneralRe: CBuilder article Pinmemberyarp15-Apr-05 2:13 
GeneralGood job PinmemberJuha Silmujarvi8-Apr-05 6:49 

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

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

| Advertise | Privacy | Mobile
Web04 | 2.8.140721.1 | Last Updated 8 Apr 2005
Article Copyright 2005 by shaman74
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid