/// <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));
            }
        }
Exemple #2
0
        // 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);
        }
Exemple #3
0
        /// <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());
        }
Exemple #4
0
        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);
        }
Exemple #5
0
        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);
        }
Exemple #6
0
 private static string DescriptionFromInputList(RawInputDeviceList deviceList)
 {
     return(String.Format("-> {0} [{1}]", deviceList.Type, deviceList.hDevice));
 }
Exemple #7
0
        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());
        }