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