Detecting input device arrival/removal on Windows XP

This isn’t a patch and actually contains no SDL code at all, but it
should be useful to anyone who wants to implement hotplug support for
SDL on Windows.

I’ve figured out a method to detect when devices are plugged in or
removed on Windows XP.
If someone has a better way, please reply.

I would just use WM_INPUT_DEVICE_CHANGE, but it only works on Vista and up.

WM_DEVICECHANGE is really designed mainly for storage devices with
removable media, so DBT_DEVICEARRIVAL and DBT_DEVICEREMOVECOMPLETE
aren’t so useful as one might expect either, but Windows does send a
WM_DEVICECHANGE message with an undocumented wParam of 0x0007 whenever
a USB device is inserted or removed. If you wait a bit after
receiving this message (quarter second works), then call
GetRawInputDeviceList(), you can get an up to date list of available
input devices. If a device is unplugged, then plugged back in, you
can check if it’s the same device by comparing the device name
returned by GetRawInputDeviceInfo() (with RIDI_DEVICENAME as the
second parameter).

Of course, you could just poll using GetRawInputDeviceList(), but
would be quite a bit slower.

Source attached for test program. Run it and plug or unplug a USB
mouse, joystick or keyboard to see what happens.
-------------- next part --------------
A non-text attachment was scrubbed…
Name: main.cpp
Type: application/octet-stream
Size: 8587 bytes
Desc: not available
URL: http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20090906/4d2de950/attachment.obj

2009/9/6 Kenneth Bull <@Kenneth_Bull>:

Source attached for test program. ?Run it and plug or unplug a USB
mouse, joystick or keyboard to see what happens.

A few notes on the program’s output:

for a line like this:
00C806BF: ??\HID#Vid_050d&Pid_007a#7&1ecee3a2&0&0000#{378de44c-56ef-11d1-bc8c-00a0c91405dd}
Mouse

The first part is the device handle acquired through GetRawInputDeviceList()

The second part (starting with ??\ and ending in a GUID) is the device name.
I kinda suspect you can pass the name to CreateFile, but I haven’t tried it yet
??\HID USB devices
??\ACPI PS/2 devices
??\Root System devices which combine input from several separate devices
Devices of the same type have the same GUID:
{378de44c-56ef-11d1-bc8c-00a0c91405dd} for mouse,
{884b96c3-56ef-11d1-bc8c-00a0c91405dd} for keyboard,
{4d1e55b2-f16f-11cf-88cb-001111000030} for HID (tested with Logitech
Dual Action gamepad and SideWinder USB gamepad)
I expect other gamepads would have the same GUID, but actual joysticks
or other HID devices may not.
You may be able to use these GUIDs with RegisterDeviceNotification()
to get more specific information for a particular device type.

The third part is the type of device.
This will be Keyboard, Mouse or HID. Game controllers show up as HID.

2009/9/6 Kenneth Bull <@Kenneth_Bull>:

If someone has a better way, please reply.

WM_DEVICECHANGE is really designed mainly for storage devices with
removable media, so DBT_DEVICEARRIVAL and DBT_DEVICEREMOVECOMPLETE
aren’t so useful as one might expect either, but Windows does send a
WM_DEVICECHANGE message with an undocumented wParam of 0x0007 whenever
a USB device is inserted or removed.

0x0007 is documented, it’s defined as DBT_DEVNODES_CHANGED
See http://msdn.microsoft.com/en-us/library/aa363211(VS.85).aspx

Also, using these:
const GUID LOCAL__GUID_DEVINTERFACE_HID = {0x4D1E55B2, 0xF16F, 0x11CF,
0x88, 0xCB, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30};
const GUID LOCAL__GUID_DEVINTERFACE_MOUSE = {0x378DE44C, 0x56EF,
0x11D1, 0xBC, 0x8C, 0x00, 0xA0, 0xC9, 0x14, 0x05, 0xDD};
const GUID LOCAL__GUID_DEVINTERFACE_KEYBOARD = {0x884b96c3, 0x56ef,
0x11d1, 0xbc, 0x8c, 0x00, 0xa0, 0xc9, 0x14, 0x05, 0xdd};
with RegisterDeviceNotification() makes DBT_DEVICEARRIVAL and
DBT_DEVICEREMOVECOMPLETE work.
See http://msdn.microsoft.com/en-us/library/aa363432(VS.85).aspx and
http://blogs.msdn.com/doronh/archive/2006/02/15/532679.aspx for more
info.

Anyway… I’ll stop spamming the list now…

Cool stuff, thanks!On Sun, Sep 6, 2009 at 2:55 AM, Kenneth Bull wrote:

2009/9/6 Kenneth Bull :

If someone has a better way, please reply.

WM_DEVICECHANGE is really designed mainly for storage devices with
removable media, so DBT_DEVICEARRIVAL and DBT_DEVICEREMOVECOMPLETE
aren’t so useful as one might expect either, but Windows does send a
WM_DEVICECHANGE message with an undocumented wParam of 0x0007 whenever
a USB device is inserted or removed.

0x0007 is documented, it’s defined as DBT_DEVNODES_CHANGED
See http://msdn.microsoft.com/en-us/library/aa363211(VS.85).aspxhttp://msdn.microsoft.com/en-us/library/aa363211(VS.85).aspx

Also, using these:
const GUID LOCAL__GUID_DEVINTERFACE_HID = {0x4D1E55B2, 0xF16F, 0x11CF,
0x88, 0xCB, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30};
const GUID LOCAL__GUID_DEVINTERFACE_MOUSE = {0x378DE44C, 0x56EF,
0x11D1, 0xBC, 0x8C, 0x00, 0xA0, 0xC9, 0x14, 0x05, 0xDD};
const GUID LOCAL__GUID_DEVINTERFACE_KEYBOARD = {0x884b96c3, 0x56ef,
0x11d1, 0xbc, 0x8c, 0x00, 0xa0, 0xc9, 0x14, 0x05, 0xdd};
with RegisterDeviceNotification() makes DBT_DEVICEARRIVAL and
DBT_DEVICEREMOVECOMPLETE work.
See http://msdn.microsoft.com/en-us/library/aa363432(VS.85).aspxhttp://msdn.microsoft.com/en-us/library/aa363432(VS.85).aspxand
http://blogs.msdn.com/doronh/archive/2006/02/15/532679.aspx for more
info.

Anyway… I’ll stop spamming the list now…


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


-Sam Lantinga, Founder and President, Galaxy Gameworks LLC

Here’s a revised version. I’m still working on this stuff.
-------------- next part --------------
A non-text attachment was scrubbed…
Name: main.cpp
Type: application/octet-stream
Size: 11821 bytes
Desc: not available
URL: http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20090907/44792ab7/attachment.obj