/// <summary> /// A convenient function for getting all raw input devices. /// This method will get all devices, including virtual devices- /// For remote desktop and any other device driver that's registered as such a device. /// </summary> /// <returns></returns> public static IEnumerable <RawInputDeviceInformation> GetAllDevices() { uint deviceCount = 0; uint dwSize = (uint)Marshal.SizeOf(typeof(RawInputDeviceList)); // First call the system routine with a null pointer // for the array to get the size needed for the list uint retValue = GetRawInputDeviceList(null, ref deviceCount, dwSize); // If anything but zero is returned, the call failed, so return a null list if (0 != retValue || deviceCount <= 0) { yield break; } // Now allocate an array of the specified number of entries RawInputDeviceList[] deviceList = new RawInputDeviceList[deviceCount]; // Now make the call again, using the array retValue = GetRawInputDeviceList(deviceList, ref deviceCount, dwSize); if (retValue == uint.MaxValue) { throw new Win32Exception("Exception when calling GetRawInputDeviceList"); } foreach (var rawInputDeviceList in deviceList) { yield return(GetDeviceInformation(rawInputDeviceList.Handle)); } }
// Source: www.pinvoke.net // A convenient function for getting all raw input devices. // This method will get all devices, including virtual devices // For remote desktop and any other device driver that's registered // as such a device. public static RawInputDeviceList[] GetAllRawDevices() { uint deviceCount = 0; uint dwSize = (uint)Marshal.SizeOf(typeof(RawInputDeviceList)); // First call the system routine with a null pointer // for the array to get the size needed for the list uint retValue = Win32MinimalWrap.GetRawInputDeviceList(null, ref deviceCount, dwSize); // If anything but zero is returned, the call failed, so return a null list if (0 != retValue) { return(null); } // Now allocate an array of the specified number of entries var deviceList = new RawInputDeviceList[deviceCount]; // Now make the call again, using the array retValue = Win32MinimalWrap.GetRawInputDeviceList(deviceList, ref deviceCount, dwSize); // Free up the memory we first got the information into as // it is no longer needed, since the structures have been // copied to the deviceList array. //IntPtr pRawInputDeviceList = Marshal.AllocHGlobal((int)(dwSize * deviceCount)); //Marshal.FreeHGlobal(pRawInputDeviceList); // Finally, return the filled in list return(deviceList); }
/// <summary> /// Enumerates the Raw Input Devices and places their corresponding RawInputDevice structures into a List<string> /// We just filter to remove Keyboard devices and keep Mouse + HID devices /// </summary> private void GetRawInputDevices() { uint deviceCount = 0; var dwSize = (Marshal.SizeOf(typeof(RawInputDeviceList))); if (Win32API.GetRawInputDeviceList(IntPtr.Zero, ref deviceCount, (uint)dwSize) == 0) { var pRawInputDeviceList = Marshal.AllocHGlobal((int)(dwSize * deviceCount)); Win32API.GetRawInputDeviceList(pRawInputDeviceList, ref deviceCount, (uint)dwSize); for (var i = 0; i < deviceCount; i++) { // On Window 8 64bit when compiling against .Net > 3.5 using .ToInt32 you will generate an arithmetic overflow. Leave as it is for 32bit/64bit applications RawInputDeviceList rid = (RawInputDeviceList)Marshal.PtrToStructure(new IntPtr((pRawInputDeviceList.ToInt64() + (dwSize * i))), typeof(RawInputDeviceList)); RawInputController c = new RawInputController(rid.hDevice, rid.dwType); if (c.DeviceType == RawInputDeviceType.RIM_TYPEHID || c.DeviceType == RawInputDeviceType.RIM_TYPEMOUSE) { _Controllers.Add(c); } } Marshal.FreeHGlobal(pRawInputDeviceList); return; } throw new Win32Exception(Marshal.GetLastWin32Error()); }
public static RawInputDeviceList[] GetDeviceList() { int count = WinRawInput.DeviceCount; RawInputDeviceList[] ridl = new RawInputDeviceList[count]; for (int i = 0; i < count; i++) { ridl[i] = new RawInputDeviceList(); } Functions.GetRawInputDeviceList(ridl, ref count, API.RawInputDeviceListSize); return(ridl); }
private static string GetDeviceName(RawInputDeviceList dev) { int size = 0; Functions.GetRawInputDeviceInfo(dev.Device, RawInputDeviceInfoEnum.DEVICENAME, IntPtr.Zero, ref size); IntPtr name_ptr = Marshal.AllocHGlobal((IntPtr)size); Functions.GetRawInputDeviceInfo(dev.Device, RawInputDeviceInfoEnum.DEVICENAME, name_ptr, ref size); string name = Marshal.PtrToStringAnsi(name_ptr); Marshal.FreeHGlobal(name_ptr); return(name); }
private static string DescriptionFromInputList(RawInputDeviceList deviceList) { return(String.Format("-> {0} [{1}]", deviceList.Type, deviceList.hDevice)); }
public void RefreshDevices() { lock (UpdateLock) { for (int i = 0; i < keyboards.Count; i++) { KeyboardState state = keyboards[i]; state.IsConnected = false; keyboards[i] = state; } int count = WinRawInput.DeviceCount; RawInputDeviceList[] ridl = new RawInputDeviceList[count]; for (int i = 0; i < count; i++) { ridl[i] = new RawInputDeviceList(); } Functions.GetRawInputDeviceList(ridl, ref count, API.RawInputDeviceListSize); // Discover keyboard devices: foreach (RawInputDeviceList dev in ridl) { ContextHandle id = new ContextHandle(dev.Device); if (rawids.ContainsKey(id)) { // Device already registered, mark as connected KeyboardState state = keyboards[rawids[id]]; state.IsConnected = true; keyboards[rawids[id]] = state; continue; } string name = GetDeviceName(dev); if (name.ToLower().Contains("root")) { // This is a terminal services device, skip it. continue; } else if (dev.Type == RawInputDeviceType.KEYBOARD || dev.Type == RawInputDeviceType.HID) { // This is a keyboard or USB keyboard device. In the latter case, discover if it really is a // keyboard device by qeurying the registry. RegistryKey regkey = GetRegistryKey(name); if (regkey == null) { continue; } string deviceDesc = (string)regkey.GetValue("DeviceDesc"); string deviceClass = (string)regkey.GetValue("Class"); string deviceClassGUID = (string)regkey.GetValue("ClassGUID"); // for windows 8 support via osuTK issue 3198 // making a guess at backwards compatability. Not sure what older windows returns in these cases... if (deviceClass == null || deviceClass.Equals(string.Empty)) { RegistryKey classGUIDKey = Registry.LocalMachine.OpenSubKey(@"SYSTEM\CurrentControlSet\Control\Class\" + deviceClassGUID); deviceClass = classGUIDKey != null ? (string)classGUIDKey.GetValue("Class") : string.Empty; } if (String.IsNullOrEmpty(deviceDesc)) { Debug.Print("[Warning] Failed to retrieve device description, skipping this device."); continue; } else { deviceDesc = deviceDesc.Substring(deviceDesc.LastIndexOf(';') + 1); } if (!String.IsNullOrEmpty(deviceClass) && deviceClass.ToLower().Equals("keyboard")) { // Register the keyboard: RawInputDeviceInfo info = new RawInputDeviceInfo(); int devInfoSize = API.RawInputDeviceInfoSize; Functions.GetRawInputDeviceInfo(dev.Device, RawInputDeviceInfoEnum.DEVICEINFO, info, ref devInfoSize); //KeyboardDevice kb = new KeyboardDevice(); //kb.Description = deviceDesc; //kb.NumberOfLeds = info.Device.Keyboard.NumberOfIndicators; //kb.NumberOfFunctionKeys = info.Device.Keyboard.NumberOfFunctionKeys; //kb.NumberOfKeys = info.Device.Keyboard.NumberOfKeysTotal; //kb.DeviceID = dev.Device; RegisterKeyboardDevice(window, deviceDesc); KeyboardState state = new KeyboardState(); state.IsConnected = true; keyboards.Add(state); names.Add(deviceDesc); rawids.Add(new ContextHandle(dev.Device), keyboards.Count - 1); } } } } }
public void EnumerateDevices() { lock (lockObject) { DeviceList.Clear(); uint deviceCount = 0; int dwSize = Marshal.SizeOf(typeof(RawInputDeviceList)); if (Win32.GetRawInputDeviceList(IntPtr.Zero, ref deviceCount, (uint)dwSize) == 0) { IntPtr pRawInputDeviceList = Marshal.AllocHGlobal((int)(dwSize * deviceCount)); Win32.GetRawInputDeviceList(pRawInputDeviceList, ref deviceCount, (uint)dwSize); for (int i = 0; i < deviceCount; i++) { uint pcbSize = 0; // On Window 8 64bit when compiling against .Net > 3.5 using .ToInt32 you will generate an arithmetic overflow. Leave as it is for 32bit/64bit applications RawInputDeviceList rid = (RawInputDeviceList)Marshal.PtrToStructure(new IntPtr(pRawInputDeviceList.ToInt64() + (dwSize * i)), typeof(RawInputDeviceList)); Win32.GetRawInputDeviceInfo(rid.Device, RawInputDeviceInfo.RIDI_DEVICENAME, IntPtr.Zero, ref pcbSize); if (pcbSize <= 0) { continue; } IntPtr pData = Marshal.AllocHGlobal((int)pcbSize); Win32.GetRawInputDeviceInfo(rid.Device, RawInputDeviceInfo.RIDI_DEVICENAME, pData, ref pcbSize); string deviceName = Marshal.PtrToStringAnsi(pData); if (rid.Type == (uint)DeviceType.Keyboard && deviceName.Length > 0 && deviceName.Count(x => x == '#') >= 2) { try { string[] split = deviceName.Substring(4).Split('#'); string classCode = split[0]; // ACPI (Class code) string subClassCode = split[1]; // PNP0303 (SubClass code) string protocolCode = split[2]; // 3&13c0b0c5&0 (Protocol code) RegistryKey deviceKey = Registry.LocalMachine.OpenSubKey($@"System\CurrentControlSet\Enum\{classCode}\{subClassCode}\{protocolCode}"); string deviceDesc = deviceKey.GetValue("DeviceDesc").ToString(); deviceDesc = deviceDesc.Substring(deviceDesc.IndexOf(';') + 1); KeyPressEvent deviceInfo = new KeyPressEvent { DeviceName = Marshal.PtrToStringAnsi(pData), DeviceHandle = rid.Device, Description = deviceDesc, }; if (!DeviceList.ContainsKey(rid.Device)) { DeviceList.Add(rid.Device, deviceInfo); } } catch (Exception) { } // Ignore error and try next device. } Marshal.FreeHGlobal(pData); } Marshal.FreeHGlobal(pRawInputDeviceList); return; } } throw new Win32Exception(Marshal.GetLastWin32Error()); }