# Is IDirectInput8::FindDevice totally broken on Windows 7?

I'm developing on Windows 7, and using DirectInput8 for my input needs.
I'm tracking gamepad additions and removals (that is, GUID_DEVINTERFACE_HID devices) using the DBT_DEVICEARRIVAL and DBT_DEVICEREMOVECOMPLETE messages, which works fine.

However, what I've come to find out is that no matter what I do, passing the received values from DBT_DEVICEARRIVAL to IDirectInput8's FindDevice method, it will always fail to identify the device, returning DIERR_DEVICENOTREG.

DirectInput still clearly knows about the device, because I can enumerate and create it just fine.
I've tried with three different gamepads, and the error persists, so it's not about that either.
I also tried passing some alternative interface GUIDs for the RegisterDeviceNotification call, didn't help.

So, has anyone else faced the same problem, and have you found a usable workaround?
I'm afraid I'll soon have to stoop down to re-enumerating all devices when something is added or removed, but I'll first give this question one last shot here.

EDIT: For the record, I've also tried pretty much every single HID API & SetupAPI function for alternative ways of figuring out the needed GUIDs, with zero success. So if you're facing the same problem as me, don't bother with that route. I'm pretty sure those GUIDs are made up by DirectInput itself somehow. Short of reverse engineering dinput8.dll, I'm truly out of ideas now.

• DirectInput is no longer recommended for use; it hasn't seen an update since 2002, well before Windows 7 was available, so it's quite possible and understandable that it doesn't work right under Windows 7. – user1430 Mar 19 '14 at 18:37
• Well, it's easy for Microsoft to recommend XInput in place of DirectInput, since XInput only supports their own XBOX controllers. The fact is that there is no substitute for DirectInput for supporting tens of thousands of legacy gamepads. – untitled8468927 Mar 26 '14 at 17:54
• That's fine (RawInput, the replacement, is definitely a bit of a pain), you just have to be willing to accept the fact that you are using what is effectively deprecated technology and you're likely to run into all sorts of compatibility issues on newer hardware/operating systems. – user1430 Mar 26 '14 at 20:13
• Yes, obviously. – untitled8468927 Mar 26 '14 at 20:18
• DirectInput8 on Windows 7 and Windows 8.x should work fine for HID (legacy) gamepads. The DirectInput headers and libs are in the Windows 8.x SDK, although it is a Win32 desktop only API (i.e. it's not available for Windows Store apps, Windows Phone 8, or Xbox One). The main thing we discourage is using DirectInput for keyboard and mouse input. While this was 'direct' back in the days of Windows 9x, it is any but "direct" for Windows XP or later. – Chuck Walbourn Jul 15 '14 at 6:53

I see the issue in a similar vein.

Regardless of which version of DirecitInput is used on a 64 bit system you get DIERR_DEVICENOTREG on calling lpDI->CreateDevice(*lpGUID, &lpDID, NULL) and I use GUIDs that lpDI->EnumDevices(0, dienumgetrval, name, DIEDFL_ATTACHEDONLY) has returned.

Doesn't matter if I use DirectInput8Create or older code. Same code on a 32 bit system appears to function. Of course, the previous version of this code still works and it links to DirectX 7 DLLs and the new version is all DX9 so I'm betting that's where things are busted.

Still looking for a work around as DirectInput is jettisonable long before DX9 is.

EDIT: Looks like it's only when run in the IDE that I get DIERR_DEVICENOTREG errors. Course that makes debugging stuff really a challenge but maybe there's a regsvr32 fix for the IDE (VS 2005): http://blogs.msdn.com/b/oldnewthing/archive/2011/02/10/10127054.aspx

EDIT2: Results are all over the place depending on whether you use Dinput8 or older stuff or 64 bit OSes (oddly win8.1 works well under all circumstances, go figure). But as near as I can tell quirky results seems to be limited to the mouse and keyboard and if you use the system kludges GUID_SysKeyboard or GUID_SysMouse instead of the GUIDs returned by the enumerator it works. But I'm not guaranteeing I don't have to put a WM_INPUT path and deal with RAWINPUT into the software before too long...

• This could use some formatting to make it more readable. Try separating into paragraphs and use backticks to do inline code. – Tom 'Blue' Piddock Mar 20 '14 at 1:50
• Well. I ended up creating an entire input library of my own, which does XInput, DirectInput & RawInput. I also "solved" the plug-and-play problem in DI by re-enumerating on PnP events. Take a look at the library, if you care: github.com/noorus/nil – untitled8468927 Mar 26 '14 at 18:04

I've faced the same problem sometimes. So far I couldn't find an workaround. But there's a solution, it may be complicated but it was worth ( well for me ). I've been using raw input ( Windows DDK is needed ), within the end, I had a little but powerfull and usefull framework.

In order to understand raw input I've been following a german tutorial:

http://zfx.info/viewtopic.php?t=2977&p=38152

If you don't understand german, then you could just rather follow MSDN with it's documention, even if it's harder at the beginning.

Finally found the solution after using the system GUID workaround but having people with international keyboards forced me to reexamine the issue. Turns out with earlier versions of DI when you enumerated devices you could take pointers to the GUIDs and they would still be good when you call CreateDevice. Turns out that's no longer the case. You actually have to copy the GUIDs away and then pass those copies.

• So you were trying to re-use the GUID pointer parameter to the callback function outside the scope of the callback? – Chuck Walbourn Jul 15 '14 at 6:52

In case someone is trying to find any clue. Try use GUID_DEVINTERFACE_HID for RegisterDeviceNotification() and use GUID_HIDClass for IDirectInput8::FindDevice().

IDirectInput8::FindDevice Method API document is not true any more

The application obtains the class GUID from the device arrival notification.