// 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)); }
public bool Start(bool showlog = true) { /* * // inside scputil * public static bool getUseExclusiveMode() * { * return m_Config.useExclusiveMode; // attached to hide DS4 controller * } */ HidGameControllers.isExclusiveMode = false; // getUseExclusiveMode(); /*if (showlog) * { * LogDebug(DS4WinWPF.Properties.Resources.SearchingController); * LogDebug(DS4Devices.isExclusiveMode ? DS4WinWPF.Properties.Resources.UsingExclusive : DS4WinWPF.Properties.Resources.UsingShared); * }*/ try { // Assign Initial Devices /*foreach (OutSlotDevice slotDevice in outputslotMan.OutputSlots) * { * if (slotDevice.CurrentReserveStatus == * OutSlotDevice.ReserveStatus.Permanent) * { * OutputDevice outDevice = EstablishOutDevice(0, slotDevice.PermanentType); * outputslotMan.DeferredPlugin(outDevice, -1, outputDevices, slotDevice.PermanentType); * } * }*/ HidGameControllers.FindControllers(); var devices = HidGameControllers.Devices.Values; //DS4LightBar.defaultLight = false; int i = 0; for (var devEnum = devices.GetEnumerator(); devEnum.MoveNext(); i++) { var device = devEnum.Current; /*if (showlog) * LogDebug(DS4WinWPF.Properties.Resources.FoundController + " " + device.GetMacAddress() + " (" + device.GetConnectionType() + ") (" + * device.DisplayName + ")");*/ Task task = new Task(() => { Thread.Sleep(5); // WarnExclusiveModeFailure(device); // just log in the UI }); task.Start(); //DS4Controllers[i] = device; //slotManager.AddController(device, i); /*device.Removal += this.On_DS4Removal; * device.Removal += DS4Devices.On_Removal; * device.SyncChange += this.On_SyncChange; * device.SyncChange += DS4Devices.UpdateSerial; * device.SerialChange += this.On_SerialChange; * device.ChargingChanged += CheckQuickCharge;*/ //device.LightBarColor = getMainColor(i); /*if (!getDInputOnly(i) && device.isSynced()) * { * //useDInputOnly[i] = false; * PluginOutDev(i, device); * * } * else * { * useDInputOnly[i] = true; * Global.activeOutDevType[i] = OutContType.None; * }*/ /*int tempIdx = i; * device.Report += (sender, e) => * { * this.On_Report(sender, e, tempIdx); * };*/ /*DualShock4Controller.ReportHandler<EventArgs> tempEvnt = (sender, args) => * { * DualShockPadMeta padDetail = new DualShockPadMeta(); * GetPadDetailForIdx(tempIdx, ref padDetail); * }; * device.MotionEvent = tempEvnt; * * if (_udpServer != null) * { * device.Report += tempEvnt; * }*/ // device.StartUpdate(); // TODO constructor already does this /* * if (showlog) * { * if (File.Exists(appdatapath + "\\Profiles\\" + ProfilePath[i] + ".xml")) * { * string prolog = DS4WinWPF.Properties.Resources.UsingProfile.Replace("*number*", (i + 1).ToString()).Replace("*Profile name*", ProfilePath[i]); * LogDebug(prolog); * AppLogger.LogToTray(prolog); * } * else * { * string prolog = DS4WinWPF.Properties.Resources.NotUsingProfile.Replace("*number*", (i + 1).ToString()); * LogDebug(prolog); * AppLogger.LogToTray(prolog); * } * } * * if (i >= 4) // out of Xinput devices! * break; */ } } catch (Exception exception) { System.Diagnostics.Debug.WriteLine($"{exception.Message}"); } //running = true; // TODO /* * runHotPlug = true; * ServiceStarted?.Invoke(this, EventArgs.Empty); * RunningChanged?.Invoke(this, EventArgs.Empty); */ return(true); }
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); } } } } } }