[Win32] Can't get HID device information list

Started by
6 comments, last by Colin Jeanne 16 years, 11 months ago
This cute thing be my code :
#define _WIN32_IE	0x0601
#define _WIN32_WINNT	0x0501
#include <cstdlib>
#include <iostream>
#include <windows.h>

int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInst, LPSTR szParam, int nFunster)
{
	// Get number of devices
	RAWINPUTDEVICELIST ridl[100];
	UINT uiNumDevices;
	UINT uiMemReserved;
	uiNumDevices = GetRawInputDeviceList(ridl, &uiMemReserved, sizeof(RAWINPUTDEVICELIST));
	cout << "Device num. : " << uiNumDevices << endl;
	cout << "Memory rsv. : " << uiMemReserved << endl << endl << endl;

	// Get device informations
	RID_DEVICE_INFO rdi;
	RID_DEVICE_INFO_HID hid;
	rdi.cbSize	= (DWORD)	sizeof(RID_DEVICE_INFO);
	rdi.dwType	= (DWORD)	RIM_TYPEHID;
	for (int i=0; i<uiNumDevices; i++)
	{
		cout << "DEVICE " << i << "\n";
		cout << "--------\n";
		UINT cbSize;
		CHAR szDeviceName[100];
		GetRawInputDeviceInfo(ridl.hDevice, RIDI_DEVICENAME, szDeviceName, &cbSize);
		cout << "Device name : " << szDeviceName << endl;
		GetRawInputDeviceInfo(ridl.hDevice, RIDI_DEVICEINFO, &rdi, &cbSize);
		cout << "Vendor ID   : " << (DWORD) hid.dwVendorId << "\n";
		cout << "Product ID  : " << (DWORD) hid.dwProductId << "\n";
		cout << "Version     : " << (DWORD) hid.dwVersionNumber << "\n";
		cout << "Usage page  : " << (USHORT) hid.usUsagePage << "\n";
		cout << "Usage       : " << (USHORT) hid.usUsage << "\n\n\n";
	}

	cout << "\n\n";
	system("PAUSE");
	return EXIT_SUCCESS;
}

And this be its output :
Device num. : 5
Memory rsv. : 1703961


DEVICE 0
--------
Device name : ↑¯É|ó☺
Vendor ID   : 60
Product ID  : 6
Version     : 2089952568
Usage page  : 24
Usage       : 0


DEVICE 1
--------
Device name : ↑¯É|ó☺
Vendor ID   : 60
Product ID  : 6
Version     : 2089952568
Usage page  : 24
Usage       : 0


DEVICE 2
--------
Device name : ↑¯É|ó☺
Vendor ID   : 60
Product ID  : 6
Version     : 2089952568
Usage page  : 24
Usage       : 0


DEVICE 3
--------
Device name : ↑¯É|ó☺
Vendor ID   : 60
Product ID  : 6
Version     : 2089952568
Usage page  : 24
Usage       : 0


DEVICE 4
--------
Device name : ↑¯É|ó☺
Vendor ID   : 60
Product ID  : 6
Version     : 2089952568
Usage page  : 24
Usage       : 0


Press any key to continue . . .
Device names are not regular strings, data fields are all same. What's wrong with my code? Help me please...
Advertisement
You need to check for error returns from your calls to GetRawInputDeviceList and GetRawInputDeviceInfo. Specifically, see this MSDN article for details on handling errors from GetRawInputDeviceInfo. Based on the symptoms you describe, the call is failing and you're just writing garbage memory to the screen.

In general, when calling an API function, always check for errors. You want your program to barf at the first sign that something might be wrong. The sooner you know that something has failed, the easier it is to figure out what exactly is going on. In this particular case, checking for errors from GetRawInputDeviceInfo would immediately highlight the cause of the problem.

Also, always initialize your variables before passing them into an API function. For example, whenever I need to pass a raw string buffer into an API, I use this trick:

// Not such a good plan:char buffer[512];APIFunction(buffer, sizeof(buffer));// If APIFunction() fails, buffer just has crap in it!// Better plan:char buffer[512] = "ERROR - buffer not filled by APIFunction";APIFunction(buffer, sizeof(buffer));// Now if APIFunction() fails, I immediately see it

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

I used GetLastError() to check for errors.

Both
GetRawInputDeviceInfo(ridl.hDevice, RIDI_DEVICENAME, szDeviceName, &cbSize);
and
GetRawInputDeviceInfo(ridl.hDevice, RIDI_DEVICEINFO, &rdi, &cbSize);
return this error :
Error code	: 998Error text	: Invalid access to memory location.Error const	: ERROR_NOACCESS

How can I get rid of this error?
Review the documentation of the function. You need to set cbSize before passing it in.

CHAR szDeviceName[100];UINT cbSize = sizeof(szDeviceName);GetRawInputDeviceInfo(ridl.hDevice, RIDI_DEVICENAME, szDeviceName, &cbSize);...cbSize = sizeof(rdi);GetRawInputDeviceInfo(ridl.hDevice, RIDI_DEVICEINFO, &rdi, &cbSize);
Quote:Original post by Colin Jeanne
Review the documentation of the function. You need to set cbSize before passing it in.

CHAR szDeviceName[100];UINT cbSize = sizeof(szDeviceName);GetRawInputDeviceInfo(ridl.hDevice, RIDI_DEVICENAME, szDeviceName, &cbSize);...cbSize = sizeof(rdi);GetRawInputDeviceInfo(ridl.hDevice, RIDI_DEVICEINFO, &rdi, &cbSize);

I corrected that error.

New error is :
Error code	: 122Error text	: The data area passed to a system call is too small.Error const	: ERROR_INSUFFICIENT_BUFFER

But this time only
GetRawInputDeviceInfo(ridl.hDevice, RIDI_DEVICENAME, szDeviceName, &cbSize);
returns this error, not
GetRawInputDeviceInfo(ridl.hDevice, RIDI_DEVICEINFO, &rdi, &cbSize);
this one.

What a mess, isn't it?
My guess then is that you're using MSVC++ 2005 and that Unicode is enabled. To fix this error do this

const UINT numChars = 100;TCHAR szDeviceName[numChars];UINT cbSize = numChars;GetRawInputDeviceInfo(ridl.hDevice, RIDI_DEVICENAME, szDeviceName, &cbSize);


If GetRawInputDeviceInfo() returns -1 as a result of this call, make szDeviceName larger. Or, alternatively, first call this function with pData as NULL. The returned value of cbSize will then be the number of characters that szDeviceName needs to be.
I have just realized that szDeviceName is an input parameter of the GetRawInputDeviceInfo() function.

But how can I retrieve device names that I don't know in the first place?
GetRawInputDeviceList() function only returns the following informations about the HID devices :
1) Number of devices
2) Handle for each device
3) Type of the devices (mouse, keyboard or HID)

Can I use handle of devices to get their names? Or what else?
From my understanding of the function, GetRawInputDeviceInfo() will fill szDeviceName with the device's name.

This topic is closed to new replies.

Advertisement