using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows.Forms; using DTS.Common.DASResource; using DTS.Common.Utilities.Logging; namespace DTS.DASLib.DASFactory { internal class WinUSBHandling : WindowsNotification { /// /// Timeout in milliseconds to connect an WinUSB device /// public int ConnectWinUSBTimeout { get; set; } private IDeviceSetup deviceHandler { get; set; } public WinUSBHandling(DASFactory _factory, UpdateFinishedEventHandler _SerialUpdateFinished, IDeviceSetup _deviceHandler, BlockingCollection> queueActionPerDevice) : base(_factory, _SerialUpdateFinished, _deviceHandler.GetGuid(), queueActionPerDevice) { deviceHandler = _deviceHandler; ConnectWinUSBTimeout = 60000; // 1000 ms } #region WinUSB WinProc's /// /// This gets called whenever a WinUSB devices connects /// /// The windows message protected override void NotificationDeviceArrived(ref Message m) { try { // \\?\hid#vid_1cb9&pid_0002#6&29dd55fe&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030} APILogger.LogString("WinUSBArrived: A device has been connected"); EnqueueConnect(); } catch (Exception ex) { APILogger.Log("MessageBox", Strings.DASFactory_WinUSBArrivedFailed, ex); } finally { APILogger.LogString("WinUSBArrived: Exit"); } } /// /// This gets called whenever a WinUSB devices disconnectes /// /// The windows message protected override void NotificationDeviceRemoved(ref Message m) { try { APILogger.LogString("WinUSBRemoved: A device has been disconnected"); EnqueueDisconnect(); } catch (Exception ex) { APILogger.Log("MessageBox", Strings.DASFactory_WinUSBRemovedFailed, ex); } finally { APILogger.LogString("WinUSBRemoved: Exit"); } } #endregion #region Connect /// /// Throw an exception if currently connected WinUSB devices contains duplicate dev paths. /// private void CheckForConnectedWinUSBDups() { // get a list of units currently connected thru WINUSB var ConnectedWinUSBDevices = GetListOfConnectedDevices(); if (ConnectedWinUSBDevices.Count != ConnectedWinUSBDevices.Distinct().Count()) { var dupList = new StringBuilder(); foreach (var s in ConnectedWinUSBDevices) { dupList.AppendLine(s); } var msg = "CheckForConnectedWinUSBDups: Connected WinUSB contain duplicates" + Environment.NewLine + dupList; APILogger.LogString(msg); throw new Exception("CheckForConnectedWinUSBDups: Connected WinUSB contain duplicates"); } } private List GetListOfConnectedDevices() { var newNames = new List(); var AllWinUSBDevicePathNames = new string[128]; try { // Fill an array with the device path names of all attached HIDs. if (!MyDeviceManagement.FindDeviceFromGuid(deviceHandler.GetGuid(), ref AllWinUSBDevicePathNames)) { return newNames; } } catch { return newNames; } // loop thru the array and copy the new ones (that actually contain something) // over to the list newNames foreach (var t in AllWinUSBDevicePathNames) { if (string.IsNullOrEmpty(t)) continue; // protect against windows giving us more than one of the same if (newNames.Find(str => str.Equals(t, StringComparison.OrdinalIgnoreCase)) == null) { // no, we haven't added it yet so do it now newNames.Add(t); } } return newNames; } public override void UpdateConnectedDevices() { ConnectNewDevices(delegate { // make sure the connected ones are OK CheckForConnectedWinUSBDups(); // get a list of units currently connected thru WINUSB return GetListOfConnectedDevices(); }, GetConnectedStrings, () => deviceHandler.GetICommunication(), comm => deviceHandler.GetIConnectedDevice(comm), deviceHandler.GetDASType(), deviceHandler, ConnectWinUSBTimeout); } #endregion #region Disconnect public override void UpdateDisconnectedDevices() { DisconnectRemovedDevices(GetListOfConnectedDevices, dev => deviceHandler.IsCorrectType(dev), dev => deviceHandler.GetICommunication(dev), deviceHandler.GetDASType(), ConnectWinUSBTimeout); } #endregion public override void UpdateDeviceSetups() { deviceHandler.SetHandler(this); } } }