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);
}
}
}