Пример #1
0
        // TODO why do I need this?
        private static bool IsRealDS4(HidDevice hidGameController)
        {
            string deviceInstanceId = HidGameControllers.DevicePathToInstanceId(hidGameController.DevicePath);
            string numberForUI      = HidGameControllers.GetDeviceProperty(
                deviceInstanceId,
                NativeMethods.DEVPKEY_Device_UINumber
                );

            return(string.IsNullOrEmpty(numberForUI));
        }
Пример #2
0
        public static void FindControllers()
        {
            lock (HidGameControllers.devices)             // TODO will this be called by multiple threads? why?
            {
                var hidGameControllers = HidGameControllers.EnumerateHidControllersMatching(vendorIdProductIdInfoArray: HidGameControllers.dualShock4CompatibleDevices);
                hidGameControllers = hidGameControllers
                                     .Where(hidController => IsRealDS4(hidController))
                                     .OrderBy <HidDevice, ConnectionType>((HidDevice hidGameController) =>
                {                         // Sort Bluetooth first in case USB is also connected on the same controller.
                    return(DualShock4Controller.HidConnectionType(hidGameController));
                });

                var tempHidGameControllers = hidGameControllers.ToList();                 // TODO it's already an IEnumerable, why tolist()?? Just to create a copy? Why creating a copy?
                // TODO purgeHiddenExclusiveDevices();
                tempHidGameControllers.AddRange(HidGameControllers.disabledDevices);
                int    hidGameControllersCount = tempHidGameControllers.Count();
                string devicePlural            = "device" + (hidGameControllersCount == 0 || hidGameControllersCount > 1 ? "s" : "");
                //Log.LogToGui("Found " + hidGameControllersCount + " possible " + devicePlural + ". Examining " + devicePlural + ".", false);

                for (int i = 0; i < hidGameControllersCount; i++)
                //foreach (HidDevice hDevice in hDevices)
                {
                    var tempHidGameController = tempHidGameControllers[i];
                    if (tempHidGameController.Description == "HID-compliant vendor-defined device")
                    {
                        continue;                         // ignore the Nacon Revolution Pro programming interface
                    }

                    if (HidGameControllers.devicePaths.Contains(tempHidGameController.DevicePath))
                    {
                        continue;                         // BT/USB endpoint already opened once
                    }

                    if (!tempHidGameController.IsOpen)
                    {
                        tempHidGameController.OpenDevice(HidGameControllers.isExclusiveMode);
                        if (!tempHidGameController.IsOpen && HidGameControllers.isExclusiveMode)
                        {
                            try
                            {
                                // Check if running with elevated permissions // FIXME why check this at each iteration??
                                WindowsIdentity  identity  = WindowsIdentity.GetCurrent();
                                WindowsPrincipal principal = new WindowsPrincipal(identity);
                                bool             elevated  = principal.IsInRole(WindowsBuiltInRole.Administrator);

                                if (!elevated)
                                {
                                    // Tell the client to launch routine to re-enable a device
                                    RequestElevationArgs eleArgs = new RequestElevationArgs(HidGameControllers.DevicePathToInstanceId(tempHidGameController.DevicePath));
                                    RequestElevation?.Invoke(eleArgs);
                                    if (eleArgs.StatusCode == RequestElevationArgs.STATUS_SUCCESS)
                                    {
                                        tempHidGameController.OpenDevice(HidGameControllers.isExclusiveMode);
                                    }
                                }
                                else
                                {
                                    HidGameControllers.ReEnableDevice(HidGameControllers.DevicePathToInstanceId(tempHidGameController.DevicePath));
                                    tempHidGameController.OpenDevice(HidGameControllers.isExclusiveMode);
                                }
                            }
                            catch (Exception)
                            {
                                // FIXME log this!
                            }
                        }

                        // TODO in exclusive mode, try to hold both open when both are connected
                        if (HidGameControllers.isExclusiveMode && !tempHidGameController.IsOpen)
                        {
                            tempHidGameController.OpenDevice(isExclusive: false);
                        }
                    }

                    if (tempHidGameController.IsOpen)
                    {
                        string serial      = tempHidGameController.ReadSerial();
                        bool   validSerial = !serial.Equals(HidDevice.blankSerial);
                        if (validSerial && deviceSerials.Contains(serial))
                        {
                            // happens when the BT endpoint already is open and the USB is plugged into the same host
                            if (HidGameControllers.isExclusiveMode && tempHidGameController.IsExclusive &&
                                !HidGameControllers.disabledDevices.Contains(tempHidGameController))
                            {
                                // Grab reference to exclusively opened HidDevice so device
                                // stays hidden to other processes
                                HidGameControllers.disabledDevices.Add(tempHidGameController);
                                //DevicePaths.Add(tempHidGameController.DevicePath);
                            }

                            continue;
                        }
                        else
                        {
                            var vendorIdProductIdInfo = dualShock4CompatibleDevices.Single(
                                x => x.vendorId == tempHidGameController.Attributes.VendorId &&
                                x.productId == tempHidGameController.Attributes.ProductId
                                );

                            var ds4Device = new DualShock4Controller(tempHidGameController, vendorIdProductIdInfo.name, vendorIdProductIdInfo.featureSet);
                            //ds4Device.Removal += On_Removal;
                            if (!ds4Device.ExitOutputThread)
                            {
                                HidGameControllers.devices.Add(tempHidGameController.DevicePath, ds4Device);
                                HidGameControllers.devicePaths.Add(tempHidGameController.DevicePath);
                                HidGameControllers.deviceSerials.Add(serial);
                            }
                        }
                    }
                }
            }
        }