I've been playing around with RegisterDeviceNotification() myself, and at first I was getting the same results.

My code is just a console app. At first, I created a "message only" window (by using HWND_MESSAGE as the parent). This received USB changes but not CD/DVD media changes. So then I made it a "real" window (hidden, top-most) and all of sudden I started getting CD/DVD media changes! Must have something to do with how windows are enumerated to recieve WM_DEVICECHANGE.

I also discovered that if autoplay is disabled at the driver level, then no media change notifications are delivered. It's a registry key you'll want check: http://www.microsoft.com/technet/pro....mspx?mfr=true

Here's my code. It's not service oriented, but you can run it to see if device notifications are atleast working in a non-service app.
Code:
#define _WIN32_WINNT 0x0501
#include <windows.h>
#include <dbt.h>

#include <iostream>
#include <iomanip>
using namespace std;

#define USE_CDROM_GUID_ONLY

// this doesn't work for CD/DVD media change events
//#define USE_MESSAGE_ONLY_WINDOW 

//-----------------------------------------------------------------------------

LRESULT CALLBACK WinProc(HWND hwnd, UINT msg, 
                         WPARAM wParam, LPARAM lParam)
{
    if (msg == WM_DEVICECHANGE)
    {
        cout << "WM_DEVICECHANGE, wParam = 0x" 
             << setw(4) << hex << setfill('0') << int(wParam) << dec
             << endl;
    }//if
    else
        cout << "Got msg " << msg << ", " << int(wParam) 
             << ", " << int(lParam) << endl;
    return 1;
}//WinProc

//-----------------------------------------------------------------------------

int main()
{
    const char *className = "DevNotifyTest";

    WNDCLASSA wincl = {0};
    wincl.hInstance = GetModuleHandle(0);
    wincl.lpszClassName = className;
    wincl.lpfnWndProc = WinProc;

    if (!RegisterClassA(&wincl))
    {
        DWORD le = GetLastError();
        cout << "RegisterClassA() failed, le = " << le << endl;
        return 1;
    }//if

    HWND parent = 0;
#ifdef USE_MESSAGE_ONLY_WINDOW
    parent = HWND_MESSAGE;
#endif
    HWND hwnd = CreateWindowExA(WS_EX_TOPMOST, className, className, 
                                0, 0, 0, 0, 0, parent, 0, 0, 0);
    if (!hwnd)
    {
        DWORD le = GetLastError();
        cout << "CreateWindowExA() failed, le = " << le << endl;
        return 1;
    }//if

    GUID cdromDevIntGuid = 
        {0x53F56308, 0xB6BF, 0x11D0, 
            {0x94, 0xF2, 0x00, 0xA0, 0xC9, 0x1E, 0xFB, 0x8B}};

    DEV_BROADCAST_DEVICEINTERFACE_A notifyFilter = {0};
    notifyFilter.dbcc_size = sizeof(notifyFilter);
    notifyFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
    notifyFilter.dbcc_classguid = cdromDevIntGuid;

    HDEVNOTIFY hDevNotify =  
        RegisterDeviceNotificationA(hwnd, &notifyFilter, 
#ifndef USE_CDROM_GUID_ONLY
                                    DEVICE_NOTIFY_ALL_INTERFACE_CLASSES | 
#endif
                                    DEVICE_NOTIFY_WINDOW_HANDLE);
    if (!hDevNotify)
    {
        DWORD le = GetLastError();
        cout << "RegisterDeviceNotificationA() failed, le = " << le << endl;
        return 1;
    }//if

    MSG msg;
    for (;;) // ctrl-c to exit ;)
    {
        BOOL bRet = GetMessage(&msg, hwnd, 0, 0);
        if ((bRet == 0) || (bRet == -1))
            break;

        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }//while

    return 0;
}//main
gg