Click here to Skip to main content
Licence 
First Posted 8 Apr 2005
Views 32,229
Bookmarked 16 times

Intercept the insertion/removal of a CD/DVD

By | 8 Apr 2005 | Article
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

Member



Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
QuestionCopy of MS Article PinmemberMsftone9:11 20 Mar '07  
GeneralWM_DEVICECHANGE & IOMega ZIP Drive PinmemberJimmyO3:11 18 Jan '07  
Generalprevent windows from reading the CD/DVD PinmemberDarin.sh22:57 20 Aug '05  
GeneralCBuilder article Pinmemberyarp19:20 8 Apr '05  
GeneralRe: CBuilder article Pinmembershaman7421:01 14 Apr '05  
GeneralRe: CBuilder article Pinmemberyarp2:13 15 Apr '05  
GeneralGood job PinmemberJuha Silmujarvi6:49 8 Apr '05  

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.

Permalink | Advertise | Privacy | Mobile
Web04 | 2.5.120528.1 | Last Updated 8 Apr 2005
Article Copyright 2005 by shaman74
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid