Example #1
0
    /// <summary>
    /// </summary>
    /// <param name="aRawInputHandle"></param>
    /// <param name="aUsagePage"></param>
    /// <param name="aUsage"></param>
    /// <returns></returns>
    public static bool GetDeviceInfo(IntPtr hDevice, ref RID_DEVICE_INFO deviceInfo)
    {
      var success = true;
      var deviceInfoBuffer = IntPtr.Zero;
      try
      {
        //Get Device Info
        var deviceInfoSize = (uint) Marshal.SizeOf(typeof (RID_DEVICE_INFO));
        deviceInfoBuffer = Marshal.AllocHGlobal((int) deviceInfoSize);

        var res = Function.GetRawInputDeviceInfo(hDevice, Const.RIDI_DEVICEINFO, deviceInfoBuffer, ref deviceInfoSize);
        if (res <= 0)
        {
          Debug.WriteLine("WM_INPUT could not read device info: " + Marshal.GetLastWin32Error());
          return false;
        }

        //Cast our buffer
        deviceInfo = (RID_DEVICE_INFO) Marshal.PtrToStructure(deviceInfoBuffer, typeof (RID_DEVICE_INFO));
      }
      catch
      {
        Debug.WriteLine("GetRawInputData failed!");
        success = false;
      }
      finally
      {
        //Always executes, prevents memory leak
        Marshal.FreeHGlobal(deviceInfoBuffer);
      }


      return success;
    }
        /// <summary>
        /// </summary>
        /// <param name="aRawInputHandle"></param>
        /// <param name="aUsagePage"></param>
        /// <param name="aUsage"></param>
        /// <returns></returns>
        public static bool GetDeviceInfo(IntPtr hDevice, ref RID_DEVICE_INFO deviceInfo)
        {
            var success          = true;
            var deviceInfoBuffer = IntPtr.Zero;

            try
            {
                //Get Device Info
                var deviceInfoSize = (uint)Marshal.SizeOf(typeof(RID_DEVICE_INFO));
                deviceInfoBuffer = Marshal.AllocHGlobal((int)deviceInfoSize);

                var res = Function.GetRawInputDeviceInfo(hDevice, Const.RIDI_DEVICEINFO, deviceInfoBuffer, ref deviceInfoSize);
                if (res <= 0)
                {
                    Debug.WriteLine("WM_INPUT could not read device info: " + Marshal.GetLastWin32Error());
                    return(false);
                }

                //Cast our buffer
                deviceInfo = (RID_DEVICE_INFO)Marshal.PtrToStructure(deviceInfoBuffer, typeof(RID_DEVICE_INFO));
            }
            catch
            {
                Debug.WriteLine("GetRawInputData failed!");
                success = false;
            }
            finally
            {
                //Always executes, prevents memory leak
                Marshal.FreeHGlobal(deviceInfoBuffer);
            }


            return(success);
        }
Example #3
0
    /// <summary>
    ///   Initialize an HidEvent from a WM_INPUT message
    /// </summary>
    /// <param name="hRawInputDevice">
    ///   Device Handle as provided by RAWINPUTHEADER.hDevice, typically accessed as
    ///   rawinput.header.hDevice
    /// </param>
    public HidEvent(Message aMessage, HidEventRepeatDelegate aRepeatDelegate)
    {
      RepeatCount = 0;
      IsValid = false;
      IsKeyboard = false;
      IsGeneric = false;


      Time = DateTime.Now;
      OriginalTime = DateTime.Now;
      Timer = new Timer();
      Timer.Elapsed += (sender, e) => OnRepeatTimerElapsed(sender, e, this);
      Usages = new List<ushort>();
      OnHidEventRepeat += aRepeatDelegate;

      if (aMessage.Msg != Const.WM_INPUT)
      {
        //Has to be a WM_INPUT message
        return;
      }

      if (Macro.GET_RAWINPUT_CODE_WPARAM(aMessage.WParam) == Const.RIM_INPUT)
      {
        IsForeground = true;
      }
      else if (Macro.GET_RAWINPUT_CODE_WPARAM(aMessage.WParam) == Const.RIM_INPUTSINK)
      {
        IsForeground = false;
      }

      //Declare some pointers
      var rawInputBuffer = IntPtr.Zero;
      //My understanding is that this is basically our HID descriptor 
      var preParsedData = IntPtr.Zero;

      try
      {
        //Fetch raw input
        var rawInput = new RAWINPUT();
        if (!RawInput.GetRawInputData(aMessage.LParam, ref rawInput, ref rawInputBuffer))
        {
          return;
        }

        //Fetch device info
        var deviceInfo = new RID_DEVICE_INFO();
        if (!RawInput.GetDeviceInfo(rawInput.header.hDevice, ref deviceInfo))
        {
          return;
        }

        //Get various information about this HID device
        Device = new HidDevice(rawInput.header.hDevice);

        if (rawInput.header.dwType == Const.RIM_TYPEHID) //Check that our raw input is HID                        
        {
          IsGeneric = true;

          Debug.WriteLine("WM_INPUT source device is HID.");
          //Get Usage Page and Usage
          //Debug.WriteLine("Usage Page: 0x" + deviceInfo.hid.usUsagePage.ToString("X4") + " Usage ID: 0x" + deviceInfo.hid.usUsage.ToString("X4"));
          UsagePage = deviceInfo.hid.usUsagePage;
          UsageCollection = deviceInfo.hid.usUsage;

          preParsedData = RawInput.GetPreParsedData(rawInput.header.hDevice);

          if (
            !(rawInput.hid.dwSizeHid > 1
              //Make sure our HID msg size more than 1. In fact the first ushort is irrelevant to us for now
              && rawInput.hid.dwCount > 0)) //Check that we have at least one HID msg
          {
            return;
          }

          //Allocate a buffer for one HID input
          var hidInputReport = new byte[rawInput.hid.dwSizeHid];

          Debug.WriteLine("Raw input contains " + rawInput.hid.dwCount + " HID input report(s)");

          //For each HID input report in our raw input
          for (var i = 0; i < rawInput.hid.dwCount; i++)
          {
            //Compute the address from which to copy our HID input
            var hidInputOffset = 0;
            unsafe
            {
              var source = (byte*) rawInputBuffer;
              source += sizeof (RAWINPUTHEADER) + sizeof (RAWHID) + (rawInput.hid.dwSizeHid*i);
              hidInputOffset = (int) source;
            }

            //Copy HID input into our buffer
            Marshal.Copy(new IntPtr(hidInputOffset), hidInputReport, 0, (int) rawInput.hid.dwSizeHid);

            //Print HID input report in our debug output
            var hidDump = "HID input report: ";
            foreach (var b in hidInputReport)
            {
              hidDump += b.ToString("X2");
            }
            Debug.WriteLine(hidDump);

            //Proper parsing now
            uint usageCount = 1; //Assuming a single usage per input report. Is that correct?
            var usages = new USAGE_AND_PAGE[usageCount];
            var status = Function.HidP_GetUsagesEx(HIDP_REPORT_TYPE.HidP_Input, 0, usages, ref usageCount, preParsedData,
              hidInputReport, (uint) hidInputReport.Length);
            if (status != HidStatus.HIDP_STATUS_SUCCESS)
            {
              Log.Error("HID: Could not parse HID data!");
            }
            else
            {
              //Debug.WriteLine("UsagePage: 0x" + usages[0].UsagePage.ToString("X4"));
              //Debug.WriteLine("Usage: 0x" + usages[0].Usage.ToString("X4"));
              //Add this usage to our list
              Usages.Add(usages[0].Usage);
            }
          }
        }
        else if (rawInput.header.dwType == Const.RIM_TYPEMOUSE)
        {
          IsMouse = true;

          Debug.WriteLine("WM_INPUT source device is Mouse.");
          // do mouse handling...
        }
        else if (rawInput.header.dwType == Const.RIM_TYPEKEYBOARD)
        {
          IsKeyboard = true;

          Debug.WriteLine("WM_INPUT source device is Keyboard.");
          // do keyboard handling...
          Debug.WriteLine("Type: " + deviceInfo.keyboard.dwType);
          Debug.WriteLine("SubType: " + deviceInfo.keyboard.dwSubType);
          Debug.WriteLine("Mode: " + deviceInfo.keyboard.dwKeyboardMode);
          Debug.WriteLine("Number of function keys: " + deviceInfo.keyboard.dwNumberOfFunctionKeys);
          Debug.WriteLine("Number of indicators: " + deviceInfo.keyboard.dwNumberOfIndicators);
          Debug.WriteLine("Number of keys total: " + deviceInfo.keyboard.dwNumberOfKeysTotal);
        }
      }
      finally
      {
        //Always executed when leaving our try block
        Marshal.FreeHGlobal(rawInputBuffer);
        Marshal.FreeHGlobal(preParsedData);
      }

      //Start repeat timer if needed 
      if (IsButtonDown)
      {
        StartRepeatTimer(iRepeatDelay);
      }

      IsValid = true;
    }