GetRawInputDeviceInfo returns wrong syntax of USB HID device name in Windows XP

raw-input, usb, winapi, windows

Solution

You are not doing anything wrong.

Just change the second character to `\` and you are set. What you see is the raw device path in its native form (`\??\...`). When you have the form `\\?\` that is a crutch MS invented to make long path names available on Win32 when NT arrived despite the limitation of the Win32 subsystem to the `\??` object directory.

Please read a few of the chapters of "Windows Internals" by Russinovich (any old edition will do) and use winobj.exe from Sysinternals to explore the object namespace of Windows to see what I'm talking about.

Side-note: when you call `CreateFile` the code in `kernel32.dll` will literally undo the suggested change and convert it back to its native form before the native functions get to see the path. So all you are doing with this is to make the Win32 layer understand the path.

Problem

I'm using `GetRawInputDeviceInfo` to get the device name of a USB HID device name. For some reason, when I run my code under Windows XP I get a device name which starts with `\??\` and not `\\?\`. This of course means, that when I try to use this device name (in `CreateFile` for example" it does not work. If I edit the device name and manually fix it to be `\\?\` everything works great. This does not happens in Windows 7. In Win7 everything works great. I also test for `GetLastError` after every API call and no errors occur. All my OS's are 32 bit and my project is compiling with unicode. Any suggestions what am I doing wrong?? Here's a code snippets from my console application which gets the device name. ``` nResult = GetRawInputDeviceInfo( pDeviceList[i].hDevice, RIDI_DEVICENAME, NULL, &nBufferSize ); if( nResult < 0 ) { cout << "ERR: Unable to get Device Name character count.." << endl; return false; } WCHAR* wcDeviceName = new WCHAR[ nBufferSize + 1 ]; if( wcDeviceName == NULL ) { cout << "ERR: Unable to allocate memory for Device Name.." << endl; return false; } nResult = GetRawInputDeviceInfo( pDeviceList[i].hDevice, RIDI_DEVICENAME, wcDeviceName, &nBufferSize ); if( nResult < 0 ) { cout << "ERR: Unable to get Device Name.." << endl; delete [] wcDeviceName; return false; } wcDeviceName[1]='\\'; //This is the manual fix for the device name in WinXP. How do I get rid of it???? pDesc->hHandle = CreateFile(wcDeviceName, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, NULL, NULL); ... ... ```

Original source