RawInput.cs
author sl
Sat, 06 Dec 2014 23:34:02 +0100
changeset 29 7679a5ab194b
parent 22 8b2a3da54187
child 47 bd068db7779a
permissions -rw-r--r--
Adding HID handler.
sl@10
     1
using System;
sl@10
     2
using System.Runtime.InteropServices;
sl@10
     3
using System.Diagnostics;
sl@10
     4
sl@10
     5
sl@10
     6
namespace Win32
sl@10
     7
{
sl@17
     8
    /// <summary>
sl@17
     9
    /// Provide some utility functions for raw input handling.
sl@17
    10
    /// </summary>
sl@10
    11
    static class RawInput
sl@10
    12
    {
sl@10
    13
        /// <summary>
sl@10
    14
        /// 
sl@10
    15
        /// </summary>
sl@10
    16
        /// <param name="aRawInputHandle"></param>
sl@10
    17
        /// <param name="aRawInput"></param>
sl@10
    18
        /// <param name="rawInputBuffer">Caller must free up memory on the pointer using Marshal.FreeHGlobal</param>
sl@10
    19
        /// <returns></returns>
sl@10
    20
        public static bool GetRawInputData(IntPtr aRawInputHandle, ref RAWINPUT aRawInput, ref IntPtr rawInputBuffer)
sl@10
    21
        {
sl@10
    22
            bool success = true;
sl@10
    23
            rawInputBuffer = IntPtr.Zero;
sl@10
    24
sl@10
    25
            try
sl@10
    26
            {
sl@10
    27
                uint dwSize = 0;
sl@10
    28
                uint sizeOfHeader = (uint)Marshal.SizeOf(typeof(RAWINPUTHEADER));
sl@10
    29
sl@10
    30
                //Get the size of our raw input data.
sl@10
    31
                Win32.Function.GetRawInputData(aRawInputHandle, Const.RID_INPUT, IntPtr.Zero, ref dwSize, sizeOfHeader);
sl@10
    32
sl@10
    33
                //Allocate a large enough buffer
sl@10
    34
                 rawInputBuffer = Marshal.AllocHGlobal((int)dwSize);
sl@10
    35
sl@10
    36
                //Now read our RAWINPUT data
sl@10
    37
                if (Win32.Function.GetRawInputData(aRawInputHandle, Const.RID_INPUT, rawInputBuffer, ref dwSize, (uint)Marshal.SizeOf(typeof(RAWINPUTHEADER))) != dwSize)
sl@10
    38
                {
sl@10
    39
                    return false;
sl@10
    40
                }
sl@10
    41
sl@10
    42
                //Cast our buffer
sl@10
    43
                aRawInput = (RAWINPUT)Marshal.PtrToStructure(rawInputBuffer, typeof(RAWINPUT));
sl@10
    44
            }
sl@10
    45
            catch
sl@10
    46
            {
sl@10
    47
                Debug.WriteLine("GetRawInputData failed!");
sl@10
    48
                success = false;
sl@10
    49
            }
sl@10
    50
sl@10
    51
            return success;
sl@10
    52
        }
sl@10
    53
sl@10
    54
        /// <summary>
sl@10
    55
        /// 
sl@10
    56
        /// </summary>
sl@10
    57
        /// <param name="aRawInputHandle"></param>
sl@10
    58
        /// <param name="aUsagePage"></param>
sl@10
    59
        /// <param name="aUsage"></param>
sl@10
    60
        /// <returns></returns>
sl@10
    61
        public static bool GetDeviceInfo(IntPtr hDevice, ref RID_DEVICE_INFO deviceInfo)
sl@10
    62
        {
sl@10
    63
            bool success = true;
sl@10
    64
            IntPtr deviceInfoBuffer = IntPtr.Zero;
sl@10
    65
            try
sl@10
    66
            {
sl@10
    67
                //Get Device Info
sl@10
    68
                uint deviceInfoSize = (uint)Marshal.SizeOf(typeof(RID_DEVICE_INFO));
sl@10
    69
                deviceInfoBuffer = Marshal.AllocHGlobal((int)deviceInfoSize);
sl@10
    70
sl@23
    71
                int res = Win32.Function.GetRawInputDeviceInfo(hDevice, Const.RIDI_DEVICEINFO, deviceInfoBuffer, ref deviceInfoSize);
sl@10
    72
                if (res <= 0)
sl@10
    73
                {
sl@10
    74
                    Debug.WriteLine("WM_INPUT could not read device info: " + Marshal.GetLastWin32Error().ToString());
sl@10
    75
                    return false;
sl@10
    76
                }
sl@10
    77
sl@10
    78
                //Cast our buffer
sl@10
    79
                deviceInfo = (RID_DEVICE_INFO)Marshal.PtrToStructure(deviceInfoBuffer, typeof(RID_DEVICE_INFO));
sl@10
    80
            }
sl@10
    81
            catch
sl@10
    82
            {
sl@10
    83
                Debug.WriteLine("GetRawInputData failed!");
sl@10
    84
                success = false;
sl@10
    85
            }
sl@10
    86
            finally
sl@10
    87
            {
sl@10
    88
                //Always executes, prevents memory leak
sl@10
    89
                Marshal.FreeHGlobal(deviceInfoBuffer);
sl@10
    90
            }
sl@10
    91
sl@10
    92
            
sl@10
    93
            return success;
sl@10
    94
        }
sl@10
    95
sl@17
    96
        /// <summary>
sl@19
    97
        /// Fetch pre-parsed data corresponding to HID descriptor for the given HID device.
sl@17
    98
        /// </summary>
sl@17
    99
        /// <param name="device"></param>
sl@17
   100
        /// <returns></returns>
sl@17
   101
        public static IntPtr GetPreParsedData(IntPtr hDevice)
sl@17
   102
        {
sl@17
   103
            uint ppDataSize = 256;
sl@23
   104
            int result = Win32.Function.GetRawInputDeviceInfo(hDevice, Win32.Const.RIDI_PREPARSEDDATA, IntPtr.Zero, ref ppDataSize);
sl@17
   105
            if (result != 0)
sl@17
   106
            {
sl@17
   107
                Debug.WriteLine("Failed to get raw input pre-parsed data size" + result + Marshal.GetLastWin32Error());
sl@17
   108
                return IntPtr.Zero;
sl@17
   109
            }
sl@17
   110
sl@17
   111
            IntPtr ppData = Marshal.AllocHGlobal((int)ppDataSize);
sl@23
   112
            result = Win32.Function.GetRawInputDeviceInfo(hDevice, Win32.Const.RIDI_PREPARSEDDATA, ppData, ref ppDataSize);
sl@17
   113
            if (result <= 0)
sl@17
   114
            {
sl@17
   115
                Debug.WriteLine("Failed to get raw input pre-parsed data" + result + Marshal.GetLastWin32Error());
sl@17
   116
                return IntPtr.Zero;
sl@17
   117
            }
sl@17
   118
            return ppData;
sl@17
   119
        }
sl@17
   120
sl@22
   121
        /// <summary>
sl@22
   122
        /// 
sl@22
   123
        /// </summary>
sl@22
   124
        /// <param name="device"></param>
sl@22
   125
        /// <returns></returns>
sl@22
   126
        public static string GetDeviceName(IntPtr device)
sl@22
   127
        {
sl@22
   128
            uint deviceNameSize = 256;
sl@23
   129
            int result = Win32.Function.GetRawInputDeviceInfo(device, Win32.Const.RIDI_DEVICENAME, IntPtr.Zero, ref deviceNameSize);
sl@22
   130
            if (result != 0)
sl@22
   131
            {
sl@22
   132
                return string.Empty;
sl@22
   133
            }
sl@22
   134
sl@22
   135
            IntPtr deviceName = Marshal.AllocHGlobal((int)deviceNameSize * 2);  // size is the character count not byte count
sl@22
   136
            try
sl@22
   137
            {
sl@23
   138
                result = Win32.Function.GetRawInputDeviceInfo(device, Win32.Const.RIDI_DEVICENAME, deviceName, ref deviceNameSize);
sl@22
   139
                if (result > 0)
sl@22
   140
                {
sl@23
   141
                    return Marshal.PtrToStringAnsi(deviceName, result - 1); // -1 for NULL termination
sl@22
   142
                }
sl@22
   143
sl@22
   144
                return string.Empty;
sl@22
   145
            }
sl@22
   146
            finally
sl@22
   147
            {
sl@22
   148
                Marshal.FreeHGlobal(deviceName);
sl@22
   149
            }
sl@22
   150
        }
sl@22
   151
sl@17
   152
sl@10
   153
    }
sl@10
   154
}