andrius
andrius

Reputation: 106

Usb hid device insert/removal detection winapi

I have created winapi application witch uses other .exe via createprocess to get/set reports. And now I need some kind of way to detect that this USB HID device was plugged/unplugged from computer when application is running. Hardest part of it is that in that app I know just VID and PID and I don't have any handles to that USB HID device. is there any way to solve this problem or I first need handle of the device?

Edit

If anyone is interested why I need it. I want to disable/enable controls of my app when i plug and unplug device.

Upvotes: 1

Views: 2346

Answers (2)

RbMm
RbMm

Reputation: 33774

at first you must register own window for receive WM_DEVICECHANGE message with DBT_DEVICEARRIVAL and DBT_DEVICEREMOVECOMPLETE for GUID_DEVINTERFACE_USB_DEVICE with RegisterDeviceNotification - windows will be not send this notification without registration!

case WM_CREATE:

    DEV_BROADCAST_DEVICEINTERFACE NotificationFilter = { 
        sizeof(DEV_BROADCAST_DEVICEINTERFACE), 
        DBT_DEVTYP_DEVICEINTERFACE,
        0,
        GUID_DEVINTERFACE_USB_DEVICE
    };

    if (!(_Handle = RegisterDeviceNotification(hwnd, &NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE)))
    {
        return -1;
    }
    break;

and unregister on destroy:

case WM_DESTROY:
    if (_Handle) UnregisterDeviceNotification(_Handle);
    break;

after this you will be receive notification. if

I know just VID and PID

you can search for L"#VID_????&PID_????#" in dbcc_name (where in place ? your actual vid and pidvalues)

case WM_DEVICECHANGE:
    switch (wParam)
    {
    case DBT_DEVICEREMOVECOMPLETE:
    case DBT_DEVICEARRIVAL:
        {
            PDEV_BROADCAST_DEVICEINTERFACE p = (PDEV_BROADCAST_DEVICEINTERFACE)lParam;
            if (p->dbcc_devicetype == DBT_DEVTYP_DEVICEINTERFACE &&
                p->dbcc_classguid == GUID_DEVINTERFACE_USB_DEVICE)
            {
                DbgPrint("%S\n", p->dbcc_name);
                if (wcsstr(p->dbcc_name, L"#VID_****&PID_****#"))
                {

                    DbgPrint("%s\n", wParam == DBT_DEVICEARRIVAL ? "arrival" : "removal");
                }
            }
        }
        break;
    }
    break;

Upvotes: 4

nikau6
nikau6

Reputation: 971

Windows sends to all top-level windows the WM_DEVICECHANGE message when new devices or media becomes availables. Checks for the event DBT_DEVICEARRIVAL in wParam. With the event DBT_DEVICEARRIVAL lParam can be converted to a DEV_BROADCAST_HDR structure. When this is done, you check dbch_devicetype from DEV_BROADCAST_HDR, and convert lParam again to DEV_BROADCAST_HANDLE, or DEV_BROADCAST_VOLUME if dbch_devicetype is equal to DBT_DEVTYP_HANDLEor DEV_BROADCAST_VOLUME, I'm not sure to remember which one.

Upvotes: 3

Related Questions