GetRawInputDeviceInfo Function

The GetRawInputDeviceInfo function gets information about the raw input device.

Syntax

UINT GetRawInputDeviceInfo(      
    HANDLE hDevice,     UINT uiCommand,     LPVOID pData,     PUINT pcbSize );

Parameters

hDevice
[in] Handle to the raw input device. This comes from the lParam of the WM_INPUT message, from RAWINPUTHEADER.hDevice, or from GetRawInputDeviceList. It can also be NULL if an application inserts input data, for example, by using SendInput.
uiCommand
[in] Specifies what data will be returned in pData. It can be one of the following values.
RIDI_PREPARSEDDATA
pData points to the previously parsed data.
RIDI_DEVICENAME
pData points to a string that contains the device name.

For this uiCommand only, the value in pcbSize is the character count (not the byte count).

RIDI_DEVICEINFO
pData points to an RID_DEVICE_INFO structure.
pData
[in, out] Pointer to a buffer that contains the information specified by uiCommand. If uiCommand is RIDI_DEVICEINFO, set RID_DEVICE_INFO.cbSize to sizeof(RID_DEVICE_INFO) before calling GetRawInputDeviceInfo.
pcbSize
[in, out] Pointer to a variable that contains the size, in bytes, of the data in pData.

Return Value

If successful, this function returns a non-negative number indicating the number of bytes copied to pData.

If pData is not large enough for the data, the function returns -1. If pData is NULL, the function returns a value of zero. In both of these cases, pcbSize is set to the minimum size required for the pData buffer.

Call GetLastError to identify any other errors.

Function Information

Minimum DLL Versionuser32.dll
HeaderDeclared in Winuser.h, include Windows.h
Import libraryUser32.lib
Minimum operating systems Windows XP
UnicodeImplemented as ANSI and Unicode versions.

See Also

Tags :


Community Content

Đonny
Visual Basic 9 Declaration and Usage
<DllImport("User32.dll")> _
Public Function GetRawInputDeviceInfo(ByVal hDevice As IntPtr, ByVal uiCommand As DeviceInfoTypes, _
ByVal pData As IntPtr, ByRef pcbSize As UInteger) As Integer
End Function

This is the only signature I made to work. Classic Visual Basic API declaration using Declare didn't work for me thowing some exception about memory access violation. I was also unable to declare this function with 2 different signatures, one for RIDI_DEVICENAME, and other for RIDI_DEVICEINFO with pData as String or RID_DEVICE_INFO respectively. I still think that it should be possible using all the mershalling attributes.
Usage of this signature is little tricky, and hevily depends on RID_DEVICE_INFO declaration (see its documentation).
Firts DeviceInfoTypes:
Public Enum DeviceInfoTypes As UInteger
RIDI_PREPARSEDDATA = &H20000005
RIDI_DEVICENAME = &H20000007
RIDI_DEVICEINFO = &H2000000B
End Enum

And now usage:
Generally the function must be called twice.
  1. First for obtain size of memory that must be allocated for pData.
  2. Second to populate pData.
For RIDI_DEVICENAME use something like this:
Dim pcbSize = 0UI
Dim ret = GetRawInputDeviceInfo(DeviceHandle, DeviceInfoTypes.RIDI_DEVICENAME, IntPtr.Zero, pcbSize) 'Writes required memory size to pcbSize
If ret < 0 Then Throw New System.ComponentModel.Win32Exception 'It uatomatically obtains error message from the system
If pcbSize > 0 Then
Dim pData As IntPtr = Marshal.AllocHGlobal(CInt(pcbSize))'Allocate unmanaged memory
Try
ret = GetRawInputDeviceInfo(DeviceHandle, DeviceInfoTypes.RIDI_DEVICENAME, pData, pcbSize) 'Writes pointer to string to pData
If ret < 0 Then Throw New System.ComponentModel.Win32Exception 'It uatomatically obtains error message from the system
Dim deviceName$ = Marshal.PtrToStringAnsi(pData) 'Transfer string from unmamaged to managed memory
Return deviceName
Finally
Marshal.FreeHGlobal(pData) 'Do not forgett to dealocate the unmanaged memory
End Try
Else : Return ""

End If


For RIDI_DEVICEINFO the approach is similar, but you are dealing with structure instead of string. It is necessary do declare the RID_DEVICE_INFO structure in the same was as I have done (see RID_DEVICE_INFO docummentation for my post).
Dim Size As UInteger = 0UI
Dim ret = GetRawInputDeviceInfo(DeviceHandle, DeviceInfoTypes.RIDI_DEVICEINFO, IntPtr.Zero, Size) 'Writes required memory size to Size
If ret < 0 Then Throw New System.ComponentModel.Win32Exception 'It uatomatically obtains error message from the system
Dim Struct As RID_DEVICE_INFOStruct.cbSize = RID_DEVICE_INFO.Size 'This is required by GetRawInputDeviceInfo
'We must allocate at least the space required by our structure (even when function call may request less space because we will copy whole structure data from unmanaged memory to managed).
'We also must allocate at least the sapace required by function
'Note that exact structure size may vary from windows version to version. Newer versions can add members.
Dim SizeToAllocate = Math.Max(CInt(Size), RID_DEVICE_INFO.Size)
Dim pData As IntPtr = Marshal.AllocHGlobal(SizoToAllocate)
'Following line serves two purposes:
'Writes RID_DEVICE_INFO.Size to unmanaged memory, which is required by the function
'Initializes all other fields of RID_DEVICE_INFO to zero. This ensures that in case current Windows versions does not write all the fields we will not get random data.
Marshal.StructureToPtr(Struct, pData, False)
Try
ret = GetRawInputDeviceInfo(DeviceHandle, DeviceInfoTypes.RIDI_DEVICEINFO, pData, SizeToAllocate) 'Populates structure pointed by pData
If ret < 0 Then Throw New System.ComponentModel.Win32Exception 'It automatically obtains error message from the system
Struct = Marshal.PtrToStructure(pData, GetType(RID_DEVICE_INFO)) 'Copy structure back from unmanaged to managed memory. Thius requires SizeToAllocate to be at least RID_DEVICE_INFO.Size
Return Struct
Finally
Marshal.FreeHGlobal(pData) 'Do not forgett to dealocate unmanaged memory
End Try

Rolandas R.
Windows 7 bug
If you have HKLM\SYSTEM\CurrentControlSet\services\kbdclass\Parameters value ConnectMultiplePorts set to 1, the device name becomes reported as \\Device\KeyboardClass0, however in Windows 7 the name is \\evice\KeyboardClass0

ChGu
C# PInvoke
[DllImport("user32.dll")]
extern uint GetRawInputDeviceInfo(IntPtr hDevice,
uint uiCommand,
IntPtr pData,
                                  ref uint pcbSize);

dziman
RIDI_DEVICENAME
When RIDI_DEVICENAME is passed for the argument uiCommand, the return value is the character count, not the byte count as indicated in the return value section of the documentation.
Tags : contentbug

Page view tracker